Home | History | Annotate | Download | only in test
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /*
      5  *******************************************************************************
      6  * Copyright (C) 1996-2015, International Business Machines Corporation and    *
      7  * others. All Rights Reserved.                                                *
      8  *******************************************************************************
      9  */
     10 package android.icu.dev.test;
     11 
     12 import java.lang.reflect.Constructor;
     13 import java.lang.reflect.Method;
     14 import java.lang.reflect.Modifier;
     15 import java.security.Policy;
     16 import java.util.ArrayList;
     17 import java.util.Arrays;
     18 import java.util.List;
     19 import java.util.Locale;
     20 import java.util.Map;
     21 import java.util.Properties;
     22 import java.util.Random;
     23 import java.util.TreeMap;
     24 
     25 import org.junit.After;
     26 import org.junit.Assert;
     27 import org.junit.Before;
     28 
     29 import android.icu.util.TimeZone;
     30 import android.icu.util.ULocale;
     31 
     32 /**
     33  * TestFmwk is a base class for tests that can be run conveniently from the
     34  * command line as well as under the Java test harness.
     35  * <p>
     36  * Sub-classes implement a set of methods named Test <something>. Each of these
     37  * methods performs some test. Test methods should indicate errors by calling
     38  * either err or errln. This will increment the errorCount field and may
     39  * optionally print a message to the log. Debugging information may also be
     40  * added to the log via the log and logln methods. These methods will add their
     41  * arguments to the log only if the test is being run in verbose mode.
     42  */
     43 abstract public class TestFmwk extends AbstractTestLog {
     44     /**
     45      * The default time zone for all of our tests. Used in @Before
     46      */
     47     private final static TimeZone defaultTimeZone = TimeZone.getTimeZone("America/Los_Angeles");
     48 
     49     /**
     50      * The default locale used for all of our tests. Used in @Before
     51      */
     52     private final static Locale defaultLocale = Locale.US;
     53 
     54     private static final String EXHAUSTIVENESS = "ICU.exhaustive";
     55     private static final int DEFAULT_EXHAUSTIVENESS = 0;
     56     private static final int MAX_EXHAUSTIVENESS = 10;
     57 
     58     private static final String LOGGING_LEVEL = "ICU.logging";
     59     private static final int DEFAULT_LOGGING_LEVEL = 0;
     60     private static final int MAX_LOGGING_LEVEL = 3;
     61 
     62     public static final int LOGGING_NONE = 0;
     63     public static final int LOGGING_WARN = 1;
     64     public static final int LOGGING_INFO = 2;
     65     public static final int LOGGING_DEBUG = 3;
     66 
     67     private static final String SEED = "ICU.seed";
     68     private static final String SECURITY_POLICY = "ICU.securitypolicy";
     69 
     70     private static final TestParams testParams;
     71     static {
     72         testParams = TestParams.create();
     73     }
     74 
     75     protected TestFmwk() {
     76     }
     77 
     78     @Before
     79     public void testInitialize() {
     80         Locale.setDefault(defaultLocale);
     81         TimeZone.setDefault(defaultTimeZone);
     82 
     83         if (getParams().testSecurityManager != null) {
     84             System.setSecurityManager(getParams().testSecurityManager);
     85         }
     86     }
     87 
     88     @After
     89     public void testTeardown() {
     90         if (getParams().testSecurityManager != null) {
     91             System.setSecurityManager(getParams().originalSecurityManager);
     92         }
     93     }
     94 
     95     private static TestParams getParams() {
     96         //return paramsReference.get();
     97         return testParams;
     98     }
     99 
    100     protected static boolean isVerbose() {
    101         return getParams().getLoggingLevel() >= LOGGING_INFO;
    102     }
    103 
    104     /**
    105      * 0 = fewest tests, 5 is normal build, 10 is most tests
    106      */
    107     protected static int getExhaustiveness() {
    108         return getParams().inclusion;
    109     }
    110 
    111     protected static boolean isQuick() {
    112         return getParams().getInclusion() == 0;
    113     }
    114 
    115     // use this instead of new random so we get a consistent seed
    116     // for our tests
    117     protected Random createRandom() {
    118         return new Random(getParams().getSeed());
    119     }
    120 
    121     /**
    122      * Integer Random number generator, produces positive int values.
    123      * Similar to C++ std::minstd_rand, with the same algorithm & constants.
    124      * Provided for compatibility with ICU4C.
    125      * Get & set of the seed allows for reproducible monkey tests.
    126      */
    127     protected class ICU_Rand {
    128         private int fLast;
    129 
    130         public ICU_Rand(int seed) {
    131             seed(seed);
    132         }
    133 
    134         public int next() {
    135             fLast = (int)((fLast * 48271L) % 2147483647L);
    136             return fLast;
    137         }
    138 
    139         public void seed(int seed) {
    140             if (seed <= 0) {
    141                 seed = 1;
    142             }
    143             seed %= 2147483647;   // = 0x7FFFFFFF
    144             fLast = seed > 0 ? seed : 1;
    145         }
    146 
    147         public int getSeed() {
    148             return fLast;
    149         }
    150 
    151     }
    152 
    153     static final String ICU_TRAC_URL = "http://bugs.icu-project.org/trac/ticket/";
    154     static final String CLDR_TRAC_URL = "http://unicode.org/cldr/trac/ticket/";
    155     static final String CLDR_TICKET_PREFIX = "cldrbug:";
    156 
    157     /**
    158      * Log the known issue.
    159      * This method returns true unless -prop:logKnownIssue=no is specified
    160      * in the argument list.
    161      *
    162      * @param ticket A ticket number string. For an ICU ticket, use numeric characters only,
    163      * such as "10245". For a CLDR ticket, use prefix "cldrbug:" followed by ticket number,
    164      * such as "cldrbug:5013".
    165      * @param comment Additional comment, or null
    166      * @return true unless -prop:logKnownIssue=no is specified in the test command line argument.
    167      */
    168     protected static boolean logKnownIssue(String ticket, String comment) {
    169         if (!getBooleanProperty("logKnownIssue", true)) {
    170             return false;
    171         }
    172 
    173         StringBuffer descBuf = new StringBuffer();
    174         // TODO(junit) : what to do about this?
    175         //getParams().stack.appendPath(descBuf);
    176         if (comment != null && comment.length() > 0) {
    177             descBuf.append(" (" + comment + ")");
    178         }
    179         String description = descBuf.toString();
    180 
    181         String ticketLink = "Unknown Ticket";
    182         if (ticket != null && ticket.length() > 0) {
    183             boolean isCldr = false;
    184             ticket = ticket.toLowerCase(Locale.ENGLISH);
    185             if (ticket.startsWith(CLDR_TICKET_PREFIX)) {
    186                 isCldr = true;
    187                 ticket = ticket.substring(CLDR_TICKET_PREFIX.length());
    188             }
    189             ticketLink = (isCldr ? CLDR_TRAC_URL : ICU_TRAC_URL) + ticket;
    190         }
    191 
    192         if (getParams().knownIssues == null) {
    193             getParams().knownIssues = new TreeMap<String, List<String>>();
    194         }
    195         List<String> lines = getParams().knownIssues.get(ticketLink);
    196         if (lines == null) {
    197             lines = new ArrayList<String>();
    198             getParams().knownIssues.put(ticketLink, lines);
    199         }
    200         if (!lines.contains(description)) {
    201             lines.add(description);
    202         }
    203 
    204         return true;
    205     }
    206 
    207     protected static String getProperty(String key) {
    208         return getParams().getProperty(key);
    209     }
    210 
    211     protected static boolean getBooleanProperty(String key) {
    212         return getParams().getBooleanProperty(key);
    213     }
    214 
    215     protected static boolean getBooleanProperty(String key, boolean defVal) {
    216         return getParams().getBooleanProperty(key, defVal);
    217     }
    218 
    219     protected static int getIntProperty(String key, int defVal) {
    220         return getParams().getIntProperty(key, defVal);
    221     }
    222 
    223     protected static int getIntProperty(String key, int defVal, int maxVal) {
    224         return getParams().getIntProperty(key, defVal, maxVal);
    225     }
    226 
    227     protected static TimeZone safeGetTimeZone(String id) {
    228         TimeZone tz = TimeZone.getTimeZone(id);
    229         if (tz == null) {
    230             // should never happen
    231             errln("FAIL: TimeZone.getTimeZone(" + id + ") => null");
    232         }
    233         if (!tz.getID().equals(id)) {
    234             warnln("FAIL: TimeZone.getTimeZone(" + id + ") => " + tz.getID());
    235         }
    236         return tz;
    237     }
    238 
    239 
    240     // Utility Methods
    241 
    242     protected static String hex(char[] s){
    243         StringBuffer result = new StringBuffer();
    244         for (int i = 0; i < s.length; ++i) {
    245             if (i != 0) result.append(',');
    246             result.append(hex(s[i]));
    247         }
    248         return result.toString();
    249     }
    250 
    251     protected static String hex(byte[] s){
    252         StringBuffer result = new StringBuffer();
    253         for (int i = 0; i < s.length; ++i) {
    254             if (i != 0) result.append(',');
    255             result.append(hex(s[i]));
    256         }
    257         return result.toString();
    258     }
    259 
    260     protected static String hex(char ch) {
    261         StringBuffer result = new StringBuffer();
    262         String foo = Integer.toString(ch, 16).toUpperCase();
    263         for (int i = foo.length(); i < 4; ++i) {
    264             result.append('0');
    265         }
    266         return result + foo;
    267     }
    268 
    269     protected static String hex(int ch) {
    270         StringBuffer result = new StringBuffer();
    271         String foo = Integer.toString(ch, 16).toUpperCase();
    272         for (int i = foo.length(); i < 4; ++i) {
    273             result.append('0');
    274         }
    275         return result + foo;
    276     }
    277 
    278     protected static String hex(CharSequence s) {
    279         StringBuilder result = new StringBuilder();
    280         for (int i = 0; i < s.length(); ++i) {
    281             if (i != 0)
    282                 result.append(',');
    283             result.append(hex(s.charAt(i)));
    284         }
    285         return result.toString();
    286     }
    287 
    288     protected static String prettify(CharSequence s) {
    289         StringBuilder result = new StringBuilder();
    290         int ch;
    291         for (int i = 0; i < s.length(); i += Character.charCount(ch)) {
    292             ch = Character.codePointAt(s, i);
    293             if (ch > 0xfffff) {
    294                 result.append("\\U00");
    295                 result.append(hex(ch));
    296             } else if (ch > 0xffff) {
    297                 result.append("\\U000");
    298                 result.append(hex(ch));
    299             } else if (ch < 0x20 || 0x7e < ch) {
    300                 result.append("\\u");
    301                 result.append(hex(ch));
    302             } else {
    303                 result.append((char) ch);
    304             }
    305 
    306         }
    307         return result.toString();
    308     }
    309 
    310     private static java.util.GregorianCalendar cal;
    311 
    312     /**
    313      * Return a Date given a year, month, and day of month. This is similar to
    314      * new Date(y-1900, m, d). It uses the default time zone at the time this
    315      * method is first called.
    316      *
    317      * @param year
    318      *            use 2000 for 2000, unlike new Date()
    319      * @param month
    320      *            use Calendar.JANUARY etc.
    321      * @param dom
    322      *            day of month, 1-based
    323      * @return a Date object for the given y/m/d
    324      */
    325     protected static synchronized java.util.Date getDate(int year, int month,
    326             int dom) {
    327         if (cal == null) {
    328             cal = new java.util.GregorianCalendar();
    329         }
    330         cal.clear();
    331         cal.set(year, month, dom);
    332         return cal.getTime();
    333     }
    334 
    335     private static class TestParams {
    336 
    337         private int inclusion;
    338         private long seed;
    339         private int loggingLevel;
    340 
    341         private String policyFileName;
    342         private SecurityManager testSecurityManager;
    343         private SecurityManager originalSecurityManager;
    344 
    345         private Map<String, List<String>> knownIssues;
    346 
    347         private Properties props;
    348 
    349 
    350         private TestParams() {
    351         }
    352 
    353         static TestParams create() {
    354             TestParams params = new TestParams();
    355             Properties props = System.getProperties();
    356             params.parseProperties(props);
    357             return params;
    358         }
    359 
    360         private void parseProperties(Properties props) {
    361             this.props = props;
    362 
    363             inclusion = getIntProperty(EXHAUSTIVENESS, DEFAULT_EXHAUSTIVENESS, MAX_EXHAUSTIVENESS);
    364             seed = getLongProperty(SEED, System.currentTimeMillis());
    365             loggingLevel = getIntProperty(LOGGING_LEVEL, DEFAULT_LOGGING_LEVEL, MAX_LOGGING_LEVEL);
    366 
    367             policyFileName = getProperty(SECURITY_POLICY);
    368             if (policyFileName != null) {
    369                 String originalPolicyFileName = System.getProperty("java.security.policy");
    370                 originalSecurityManager = System.getSecurityManager();
    371                 System.setProperty("java.security.policy", policyFileName);
    372                 Policy.getPolicy().refresh();
    373                 testSecurityManager = new SecurityManager();
    374                 System.setProperty("java.security.policy", originalPolicyFileName==null ? "" : originalPolicyFileName);
    375             }
    376         }
    377 
    378         public String getProperty(String key) {
    379             String val = null;
    380             if (key != null && key.length() > 0) {
    381                 val = props.getProperty(key);
    382             }
    383             return val;
    384         }
    385 
    386         public boolean getBooleanProperty(String key) {
    387             return getBooleanProperty(key, false);
    388         }
    389 
    390         public boolean getBooleanProperty(String key, boolean defVal) {
    391             String s = getProperty(key);
    392             if (s == null) {
    393                 return defVal;
    394             }
    395             if (s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("true") || s.equals("1")) {
    396                 return true;
    397             }
    398             return false;
    399         }
    400 
    401         public int getIntProperty(String key, int defVal) {
    402             return getIntProperty(key, defVal, -1);
    403         }
    404 
    405         public int getIntProperty(String key, int defVal, int maxVal) {
    406             String s = getProperty(key);
    407             if (s == null) {
    408                 return defVal;
    409             }
    410             return (maxVal == -1) ? Integer.valueOf(s) : Math.max(Integer.valueOf(s), maxVal);
    411         }
    412 
    413         public long getLongProperty(String key, long defVal) {
    414             String s = getProperty(key);
    415             if (s == null) {
    416                 return defVal;
    417             }
    418             return Long.valueOf(s);
    419         }
    420 
    421         public int getInclusion() {
    422             return inclusion;
    423         }
    424 
    425         public long getSeed() {
    426             return seed;
    427         }
    428 
    429         public int getLoggingLevel() {
    430             return loggingLevel;
    431         }
    432     }
    433 
    434     /**
    435      * Check the given array to see that all the strings in the expected array
    436      * are present.
    437      *
    438      * @param msg
    439      *            string message, for log output
    440      * @param array
    441      *            array of strings to check
    442      * @param expected
    443      *            array of strings we expect to see, or null
    444      * @return the length of 'array', or -1 on error
    445      */
    446     protected static int checkArray(String msg, String array[], String expected[]) {
    447         int explen = (expected != null) ? expected.length : 0;
    448         if (!(explen >= 0 && explen < 31)) { // [sic] 31 not 32
    449             errln("Internal error");
    450             return -1;
    451         }
    452         int i = 0;
    453         StringBuffer buf = new StringBuffer();
    454         int seenMask = 0;
    455         for (; i < array.length; ++i) {
    456             String s = array[i];
    457             if (i != 0)
    458                 buf.append(", ");
    459             buf.append(s);
    460             // check expected list
    461             for (int j = 0, bit = 1; j < explen; ++j, bit <<= 1) {
    462                 if ((seenMask & bit) == 0) {
    463                     if (s.equals(expected[j])) {
    464                         seenMask |= bit;
    465                         logln("Ok: \"" + s + "\" seen");
    466                     }
    467                 }
    468             }
    469         }
    470         logln(msg + " = [" + buf + "] (" + i + ")");
    471         // did we see all expected strings?
    472         if (((1 << explen) - 1) != seenMask) {
    473             for (int j = 0, bit = 1; j < expected.length; ++j, bit <<= 1) {
    474                 if ((seenMask & bit) == 0) {
    475                     errln("\"" + expected[j] + "\" not seen");
    476                 }
    477             }
    478         }
    479         return array.length;
    480     }
    481 
    482     /**
    483      * Check the given array to see that all the locales in the expected array
    484      * are present.
    485      *
    486      * @param msg
    487      *            string message, for log output
    488      * @param array
    489      *            array of locales to check
    490      * @param expected
    491      *            array of locales names we expect to see, or null
    492      * @return the length of 'array'
    493      */
    494     protected static int checkArray(String msg, Locale array[], String expected[]) {
    495         String strs[] = new String[array.length];
    496         for (int i = 0; i < array.length; ++i) {
    497             strs[i] = array[i].toString();
    498         }
    499         return checkArray(msg, strs, expected);
    500     }
    501 
    502     /**
    503      * Check the given array to see that all the locales in the expected array
    504      * are present.
    505      *
    506      * @param msg
    507      *            string message, for log output
    508      * @param array
    509      *            array of locales to check
    510      * @param expected
    511      *            array of locales names we expect to see, or null
    512      * @return the length of 'array'
    513      */
    514     protected static int checkArray(String msg, ULocale array[], String expected[]) {
    515         String strs[] = new String[array.length];
    516         for (int i = 0; i < array.length; ++i) {
    517             strs[i] = array[i].toString();
    518         }
    519         return checkArray(msg, strs, expected);
    520     }
    521 
    522     // JUnit-like assertions.
    523 
    524     protected static boolean assertTrue(String message, boolean condition) {
    525         return handleAssert(condition, message, "true", null);
    526     }
    527 
    528     protected static boolean assertFalse(String message, boolean condition) {
    529         return handleAssert(!condition, message, "false", null);
    530     }
    531 
    532     protected static boolean assertEquals(String message, boolean expected,
    533             boolean actual) {
    534         return handleAssert(expected == actual, message, String
    535                 .valueOf(expected), String.valueOf(actual));
    536     }
    537 
    538     protected static boolean assertEquals(String message, long expected, long actual) {
    539         return handleAssert(expected == actual, message, String
    540                 .valueOf(expected), String.valueOf(actual));
    541     }
    542 
    543     // do NaN and range calculations to precision of float, don't rely on
    544     // promotion to double
    545     protected static boolean assertEquals(String message, float expected,
    546             float actual, double error) {
    547         boolean result = Float.isInfinite(expected)
    548                 ? expected == actual
    549                 : !(Math.abs(expected - actual) > error); // handles NaN
    550         return handleAssert(result, message, String.valueOf(expected)
    551                 + (error == 0 ? "" : " (within " + error + ")"), String
    552                 .valueOf(actual));
    553     }
    554 
    555     protected static boolean assertEquals(String message, double expected,
    556             double actual, double error) {
    557         boolean result = Double.isInfinite(expected)
    558                 ? expected == actual
    559                 : !(Math.abs(expected - actual) > error); // handles NaN
    560         return handleAssert(result, message, String.valueOf(expected)
    561                 + (error == 0 ? "" : " (within " + error + ")"), String
    562                 .valueOf(actual));
    563     }
    564 
    565     protected static <T> boolean assertEquals(String message, T[] expected, T[] actual) {
    566         // Use toString on a List to get useful, readable messages
    567         String expectedString = expected == null ? "null" : Arrays.asList(expected).toString();
    568         String actualString = actual == null ? "null" : Arrays.asList(actual).toString();
    569         return assertEquals(message, expectedString, actualString);
    570     }
    571 
    572     protected static boolean assertEquals(String message, Object expected,
    573             Object actual) {
    574         boolean result = expected == null ? actual == null : expected
    575                 .equals(actual);
    576         return handleAssert(result, message, stringFor(expected),
    577                 stringFor(actual));
    578     }
    579 
    580     protected static boolean assertNotEquals(String message, Object expected,
    581             Object actual) {
    582         boolean result = !(expected == null ? actual == null : expected
    583                 .equals(actual));
    584         return handleAssert(result, message, stringFor(expected),
    585                 stringFor(actual), "not equal to", true);
    586     }
    587 
    588     protected boolean assertSame(String message, Object expected, Object actual) {
    589         return handleAssert(expected == actual, message, stringFor(expected),
    590                 stringFor(actual), "==", false);
    591     }
    592 
    593     protected static boolean assertNotSame(String message, Object expected,
    594             Object actual) {
    595         return handleAssert(expected != actual, message, stringFor(expected),
    596                 stringFor(actual), "!=", true);
    597     }
    598 
    599     protected static boolean assertNull(String message, Object actual) {
    600         return handleAssert(actual == null, message, null, stringFor(actual));
    601     }
    602 
    603     protected static boolean assertNotNull(String message, Object actual) {
    604         return handleAssert(actual != null, message, null, stringFor(actual),
    605                 "!=", true);
    606     }
    607 
    608     protected static void fail() {
    609         fail("");
    610     }
    611 
    612     protected static void fail(String message) {
    613         if (message == null) {
    614             message = "";
    615         }
    616         if (!message.equals("")) {
    617             message = ": " + message;
    618         }
    619         errln(sourceLocation() + message);
    620     }
    621 
    622     private static boolean handleAssert(boolean result, String message,
    623             String expected, String actual) {
    624         return handleAssert(result, message, expected, actual, null, false);
    625     }
    626 
    627     public static boolean handleAssert(boolean result, String message,
    628             Object expected, Object actual, String relation, boolean flip) {
    629         if (!result || isVerbose()) {
    630             if (message == null) {
    631                 message = "";
    632             }
    633             if (!message.equals("")) {
    634                 message = ": " + message;
    635             }
    636             relation = relation == null ? ", got " : " " + relation + " ";
    637             if (result) {
    638                 logln("OK " + message + ": "
    639                         + (flip ? expected + relation + actual : expected));
    640             } else {
    641                 // assert must assume errors are true errors and not just warnings
    642                 // so cannot warnln here
    643                 errln(  message
    644                         + ": expected"
    645                         + (flip ? relation + expected : " " + expected
    646                                 + (actual != null ? relation + actual : "")));
    647             }
    648         }
    649         return result;
    650     }
    651 
    652     private static final String stringFor(Object obj) {
    653         if (obj == null) {
    654             return "null";
    655         }
    656         if (obj instanceof String) {
    657             return "\"" + obj + '"';
    658         }
    659         return obj.getClass().getName() + "<" + obj + ">";
    660     }
    661 
    662     // Return the source code location of the caller located callDepth frames up the stack.
    663     protected static String sourceLocation() {
    664         // Walk up the stack to the first call site outside this file
    665         for (StackTraceElement st : new Throwable().getStackTrace()) {
    666             String source = st.getFileName();
    667             if (source != null && !source.equals("TestFmwk.java") && !source.equals("AbstractTestLog.java")) {
    668                 String methodName = st.getMethodName();
    669                 if (methodName != null &&
    670                        (methodName.startsWith("Test") || methodName.startsWith("test") || methodName.equals("main"))) {
    671                     return "(" + source + ":" + st.getLineNumber() + ") ";
    672                 }
    673             }
    674         }
    675         throw new InternalError();
    676     }
    677 
    678     protected static boolean checkDefaultPrivateConstructor(String fullyQualifiedClassName) throws Exception {
    679         return checkDefaultPrivateConstructor(Class.forName(fullyQualifiedClassName));
    680     }
    681 
    682     protected static boolean checkDefaultPrivateConstructor(Class<?> classToBeTested) throws Exception {
    683         Constructor<?> constructor = classToBeTested.getDeclaredConstructor();
    684 
    685         // Check that the constructor is private.
    686         boolean isPrivate = Modifier.isPrivate(constructor.getModifiers());
    687 
    688         // Call the constructor for coverage.
    689         constructor.setAccessible(true);
    690         constructor.newInstance();
    691 
    692         if (!isPrivate) {
    693             errln("Default private constructor for class: " + classToBeTested.getName() + " is not private.");
    694         }
    695         return isPrivate;
    696     }
    697 
    698     /**
    699      * Tests the toString method on a private or hard-to-reach class.  Assumes constructor of the class does not
    700      * take any arguments.
    701      * @param fullyQualifiedClassName
    702      * @return The output of the toString method.
    703      * @throws Exception
    704      */
    705     protected static String invokeToString(String fullyQualifiedClassName) throws Exception {
    706         return invokeToString(fullyQualifiedClassName, new Class<?>[]{}, new Object[]{});
    707     }
    708 
    709     /**
    710      * Tests the toString method on a private or hard-to-reach class.  Assumes constructor of the class does not
    711      * take any arguments.
    712      * @param classToBeTested
    713      * @return The output of the toString method.
    714      * @throws Exception
    715      */
    716     protected static String invokeToString(Class<?> classToBeTested) throws Exception {
    717         return invokeToString(classToBeTested, new Class<?>[]{}, new Object[]{});
    718     }
    719 
    720     /**
    721      * Tests the toString method on a private or hard-to-reach class.  Allows you to specify the argument types for
    722      * the constructor.
    723      * @param fullyQualifiedClassName
    724      * @return The output of the toString method.
    725      * @throws Exception
    726      */
    727     protected static String invokeToString(String fullyQualifiedClassName,
    728             Class<?>[] constructorParamTypes, Object[] constructorParams) throws Exception {
    729         return invokeToString(Class.forName(fullyQualifiedClassName), constructorParamTypes, constructorParams);
    730     }
    731 
    732     /**
    733      * Tests the toString method on a private or hard-to-reach class.  Allows you to specify the argument types for
    734      * the constructor.
    735      * @param classToBeTested
    736      * @return The output of the toString method.
    737      * @throws Exception
    738      */
    739     protected static String invokeToString(Class<?> classToBeTested,
    740             Class<?>[] constructorParamTypes, Object[] constructorParams) throws Exception {
    741         Constructor<?> constructor = classToBeTested.getDeclaredConstructor(constructorParamTypes);
    742         constructor.setAccessible(true);
    743         Object obj = constructor.newInstance(constructorParams);
    744         Method toStringMethod = classToBeTested.getDeclaredMethod("toString");
    745         toStringMethod.setAccessible(true);
    746         return (String) toStringMethod.invoke(obj);
    747     }
    748 
    749 
    750     // End JUnit-like assertions
    751 
    752     // TODO (sgill): added to keep errors away
    753     /* (non-Javadoc)
    754      * @see android.icu.dev.test.TestLog#msg(java.lang.String, int, boolean, boolean)
    755      */
    756     //@Override
    757     protected static void msg(String message, int level, boolean incCount, boolean newln) {
    758         if (level == TestLog.WARN || level == TestLog.ERR) {
    759             Assert.fail(message);
    760         }
    761         // TODO(stuartg): turned off - causing OOM running under ant
    762 //        while (level > 0) {
    763 //            System.out.print(" ");
    764 //            level--;
    765 //        }
    766 //        System.out.print(message);
    767 //        if (newln) {
    768 //            System.out.println();
    769 //        }
    770     }
    771 
    772 }
    773