17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 3f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert * Copyright (C) 1996-2015, International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test; 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ByteArrayOutputStream; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.CharArrayWriter; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.IOException; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.OutputStream; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.PrintStream; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.PrintWriter; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.Writer; 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.reflect.Field; 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.reflect.InvocationTargetException; 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.reflect.Method; 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.text.DecimalFormat; 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.text.NumberFormat; 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.ArrayList; 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Arrays; 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Comparator; 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.HashMap; 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.List; 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale; 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Map; 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Map.Entry; 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.MissingResourceException; 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Random; 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.TreeMap; 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZone; 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale; 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * TestFmwk is a base class for tests that can be run conveniently from the 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * command line as well as under the Java test harness. 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sub-classes implement a set of methods named Test <something>. Each of these 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * methods performs some test. Test methods should indicate errors by calling 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * either err or errln. This will increment the errorCount field and may 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * optionally print a message to the log. Debugging information may also be 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * added to the log via the log and logln methods. These methods will add their 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * arguments to the log only if the test is being run in verbose mode. 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class TestFmwk extends AbstractTestLog { 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The default time zone for all of our tests. Used in Target.run(); 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private final static TimeZone defaultTimeZone = TimeZone.getTimeZone("America/Los_Angeles"); 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The default locale used for all of our tests. Used in Target.run(); 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private final static Locale defaultLocale = Locale.US; 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final class TestFmwkException extends Exception { 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * For serialization 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long serialVersionUID = -3051148210247229194L; 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestFmwkException(String msg) { 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(msg); 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static final class ICUTestError extends RuntimeException { 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * For serialization 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long serialVersionUID = 6170003850185143046L; 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ICUTestError(String msg) { 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(msg); 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Handling exception thrown during text execution (not including 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // RuntimeException thrown by errln). 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void handleException(Throwable e){ 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Throwable ex = e.getCause(); 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if(ex == null){ 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ex = e; 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ex instanceof OutOfMemoryError) { 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Once OOM happens, it does not make sense to run 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // the rest of test cases. 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new RuntimeException(ex); 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ex instanceof ICUTestError) { 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // ICUTestError is one produced by errln. 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // We don't need to include useless stack trace information for 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // such case. 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return; 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ex instanceof ExceptionInInitializerError){ 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ex = ((ExceptionInInitializerError)ex).getException(); 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //Stack trace 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CharArrayWriter caw = new CharArrayWriter(); 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PrintWriter pw = new PrintWriter(caw); 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ex.printStackTrace(pw); 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.close(); 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String msg = caw.toString(); 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //System.err.println("TF handleException msg: " + msg); 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ex instanceof MissingResourceException || ex instanceof NoClassDefFoundError || 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert msg.indexOf("java.util.MissingResourceException") >= 0) { 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.warnings || params.nodata) { 113f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert warnln(ex.toString() + '\n' + msg); 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 115f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert errln(ex.toString() + '\n' + msg); 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 117a53a69a88b9accc4d1b0e996601d199f1755dc87Yoshito Umaoka } else { 118f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert errln(ex.toString() + '\n' + msg); 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // use this instead of new random so we get a consistent seed 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // for our tests 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Random createRandom() { 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new Random(params.seed); 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * A test that has no test methods itself, but instead runs other tests. 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This overrides methods are getTargets and getSubtest from TestFmwk. 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If you want the default behavior, pass an array of class names and an 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * optional description to the constructor. The named classes must extend 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * TestFmwk. If a provided name doesn't include a ".", package name is 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * prefixed to it (the package of the current test is used if none was 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * provided in the constructor). The resulting full name is used to 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * instantiate an instance of the class using the default constructor. 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Class names are resolved to classes when getTargets or getSubtest is 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * called. This allows instances of TestGroup to be compiled and run without 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * all the targets they would normally invoke being available. 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static abstract class TestGroup extends TestFmwk { 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String defaultPackage; 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String[] names; 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String description; 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Class[] tests; // deferred init 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructor that takes a default package name and a list of class 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * names. Adopts and modifies the classname list 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TestGroup(String defaultPackage, String[] classnames, 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String description) { 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (classnames == null) { 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalStateException("classnames must not be null"); 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (defaultPackage == null) { 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert defaultPackage = getClass().getPackage().getName(); 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert defaultPackage = defaultPackage + "."; 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.defaultPackage = defaultPackage; 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.names = classnames; 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.description = description; 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructor that takes a list of class names and a description, and 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * uses the package for this class as the default package. 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TestGroup(String[] classnames, String description) { 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this(null, classnames, description); 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructor that takes a list of class names, and uses the package 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for this class as the default package. 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TestGroup(String[] classnames) { 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this(null, classnames, null); 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String getDescription() { 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return description; 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Target getTargets(String targetName) { 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Target target = null; 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (targetName != null) { 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert finishInit(); // hmmm, want to get subtest without initializing 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // all tests 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestFmwk test = getSubtest(targetName); 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (test != null) { 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target = test.new ClassTarget(); 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target = this.new Target(targetName); 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (TestFmwkException e) { 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target = this.new Target(targetName); 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (params.doRecurse()) { 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert finishInit(); 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean groupOnly = params.doRecurseGroupsOnly(); 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = names.length; --i >= 0;) { 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Target newTarget = null; 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Class cls = tests[i]; 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (cls == null) { // hack no warning for missing tests 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.warnings) { 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newTarget = this.new Target(names[i]); 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestFmwk test = getSubtest(i, groupOnly); 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (test != null) { 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newTarget = test.new ClassTarget(); 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (groupOnly) { 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newTarget = this.new EmptyTarget(names[i]); 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newTarget = this.new Target(names[i]); 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (newTarget != null) { 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newTarget.setNext(target); 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target = newTarget; 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return target; 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TestFmwk getSubtest(String testName) throws TestFmwkException { 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert finishInit(); 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < names.length; ++i) { 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (names[i].equalsIgnoreCase(testName)) { // allow 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // case-insensitive 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // matching 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getSubtest(i, false); 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new TestFmwkException(testName); 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private TestFmwk getSubtest(int i, boolean groupOnly) { 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Class cls = tests[i]; 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (cls != null) { 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (groupOnly && !TestGroup.class.isAssignableFrom(cls)) { 2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestFmwk subtest = (TestFmwk) cls.newInstance(); 2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert subtest.params = params; 2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return subtest; 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (InstantiationException e) { 2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalStateException(e.getMessage()); 2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (IllegalAccessException e) { 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalStateException(e.getMessage()); 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void finishInit() { 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (tests == null) { 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tests = new Class[names.length]; 2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < names.length; ++i) { 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String name = names[i]; 2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (name.indexOf('.') == -1) { 2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert name = defaultPackage + name; 2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Class cls = Class.forName(name); 2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!TestFmwk.class.isAssignableFrom(cls)) { 2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalStateException("class " + name 2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " does not extend TestFmwk"); 2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tests[i] = cls; 2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert names[i] = getClassTargetName(cls); 2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (ClassNotFoundException e) { 2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // leave tests[i] null and name as classname 2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The default target is invalid. 2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public class Target { 3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Target next; 3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final String name; 3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Target(String name) { 3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.name = name; 3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Target setNext(Target next) { 3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.next = next; 3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Target getNext() { 3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return next; 3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Target append(Target targets) { 3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Target t = this; 3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while(t.next != null) { 3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t = t.next; 3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t.next = targets; 3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void run() throws Exception { 3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int f = filter(); 3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (f == -1) { 3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++params.invalidCount; 3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Locale.setDefault(defaultLocale); 3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone.setDefault(defaultTimeZone); 3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!validate()) { 3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.writeTestInvalid(name, params.nodata); 3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.push(name, getDescription(), f == 1); 3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert execute(); 3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.pop(); 3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int filter() { 3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.filter(name); 3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean validate() { 3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String getDescription() { 3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void execute() throws Exception{ 3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public class EmptyTarget extends Target { 3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public EmptyTarget(String name) { 3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(name); 3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean validate() { 3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public class MethodTarget extends Target { 3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Method testMethod; 3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public MethodTarget(String name, Method method) { 3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(name); 3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testMethod = method; 3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean validate() { 3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return testMethod != null && validateMethod(name); 3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String getDescription() { 3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getMethodDescription(name); 3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void execute() throws Exception{ 3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.inDocMode()) { 3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // nothing to execute 3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (!params.stack.included) { 3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++params.invalidCount; 3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Object[] NO_ARGS = new Object[0]; 3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++params.testCount; 3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert init(); 3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testMethod.invoke(TestFmwk.this, NO_ARGS); 3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (IllegalAccessException e) { 3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Can't access test method " + testMethod.getName()); 3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (Exception e) { 4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert handleException(e); 4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // If non-exhaustive, check if the method target 4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // takes excessive time. 4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.inclusion <= 5) { 4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double deltaSec = (double)(System.currentTimeMillis() - params.stack.millis)/1000; 4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (deltaSec > params.maxTargetSec) { 4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.timeLog == null) { 4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.timeLog = new StringBuffer(); 4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.stack.appendPath(params.timeLog); 4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.timeLog.append(" (" + deltaSec + "s" + ")\n"); 4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String getStackTrace(InvocationTargetException e) { 4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ByteArrayOutputStream bs = new ByteArrayOutputStream(); 4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PrintStream ps = new PrintStream(bs); 4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert e.getTargetException().printStackTrace(ps); 4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return bs.toString(); 4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public class ClassTarget extends Target { 4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String targetName; 4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public ClassTarget() { 4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this(null); 4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public ClassTarget(String targetName) { 4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(getClassTargetName(TestFmwk.this.getClass())); 4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.targetName = targetName; 4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean validate() { 4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return TestFmwk.this.validate(); 4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String getDescription() { 4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return TestFmwk.this.getDescription(); 4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void execute() throws Exception { 4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.indentLevel++; 4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Target target = randomize(getTargets(targetName)); 4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (target != null) { 4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target.run(); 4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target = target.next; 4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.indentLevel--; 4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Target randomize(Target t) { 4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (t != null && t.getNext() != null) { 4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ArrayList list = new ArrayList(); 4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (t != null) { 4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert list.add(t); 4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t = t.getNext(); 4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Target[] arr = (Target[]) list.toArray(new Target[list.size()]); 4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (true) { // todo - add to params? 4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // different jvms return class methods in different orders, 4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // so we sort them (always, and then randomize them, so that 4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // forcing a seed will also work across jvms). 4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Arrays.sort(arr, new Comparator() { 4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int compare(Object lhs, Object rhs) { 4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // sort in reverse order, later we link up in 4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // forward order 4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ((Target) rhs).name 4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .compareTo(((Target) lhs).name); 4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }); 4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // t is null to start, ends up as first element 4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // (arr[arr.length-1]) 4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < arr.length; ++i) { 4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t = arr[i].setNext(t); // relink in forward order 4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.random != null) { 4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t = null; // reset t to null 4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Random r = params.random; 4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = arr.length; --i >= 1;) { 4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int x = r.nextInt(i + 1); 4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t = arr[x].setNext(t); 4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert arr[x] = arr[i]; 4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t = arr[0].setNext(t); // new first element 4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return t; 5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------ 5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Everything below here is boilerplate code that makes it possible 5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // to add a new test by simply adding a function to an existing class 5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //------------------------------------------------------------------------ 5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TestFmwk() { 5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void init() throws Exception{ 5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Parse arguments into a TestParams object and a collection of target 5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * paths. If there was an error parsing the TestParams, print usage and exit 5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * with -1. Otherwise, call resolveTarget(TestParams, String) for each path, 5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and run the returned target. After the last test returns, if prompt is 5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * set, prompt and wait for input from stdin. Finally, exit with number of 5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * errors. 5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This method never returns, since it always exits with System.exit(); 5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void run(String[] args) { 5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert System.exit(run(args, new PrintWriter(System.out))); 5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Like run(String[]) except this allows you to specify the error log. 5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Unlike run(String[]) this returns the error code as a result instead of 5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * calling System.exit(). 5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int run(String[] args, PrintWriter log) { 5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean prompt = false; 5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int wx = 0; 5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < args.length; ++i) { 5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String arg = args[i]; 5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (arg.equals("-p") || arg.equals("-prompt")) { 5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert prompt = true; 5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (wx < i) { 5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert args[wx] = arg; 5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert wx++; 5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (wx < args.length) { 5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert args[wx++] = null; 5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestParams localParams = TestParams.create(args, log); 5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (localParams == null) { 5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return -1; 5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int errorCount = runTests(localParams, args); 5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (localParams.seed != 0) { 5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("-random:" + localParams.seed); 5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.flush(); 5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (localParams.timeLog != null && localParams.timeLog.length() > 0) { 5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("\nTest cases taking excessive time (>" + 5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.maxTargetSec + "s):"); 5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println(localParams.timeLog.toString()); 5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (localParams.knownIssues != null) { 5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("\nKnown Issues:"); 5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (Entry<String, List<String>> entry : localParams.knownIssues.entrySet()) { 5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String ticketLink = entry.getKey(); 5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("[" + ticketLink + "]"); 5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String line : entry.getValue()) { 5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println(" - " + line); 5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (localParams.errorSummary != null && localParams.errorSummary.length() > 0) { 5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("\nError summary:"); 5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println(localParams.errorSummary.toString()); 5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (errorCount > 0) { 5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("\n<< " + errorCount+ " TEST(S) FAILED >>"); 5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("\n<< ALL TESTS PASSED >>"); 5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (prompt) { 5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert System.out.println("Hit RETURN to exit..."); 5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert System.out.flush(); 5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert System.in.read(); 5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (IOException e) { 5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.println("Exception: " + e.toString() + e.getMessage()); 5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert localParams.log.flush(); 6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return errorCount; 6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int runTests(TestParams _params, String[] tests) { 6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int ec = 0; 6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer summary = null; 6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (tests.length == 0 || tests[0] == null) { // no args 6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert _params.init(); 6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert resolveTarget(_params).run(); 6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ec = _params.errorCount; 6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < tests.length ; ++i) { 6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (tests[i] == null) continue; 6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (i > 0) { 6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert _params.log.println(); 6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert _params.init(); 6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert resolveTarget(_params, tests[i]).run(); 6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ec += _params.errorCount; 6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (_params.errorSummary != null && _params.errorSummary.length() > 0) { 6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (summary == null) { 6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert summary = new StringBuffer(); 6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert summary.append("\nTest Root: " + tests[i] + "\n"); 6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert summary.append(_params.errorSummary()); 6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert _params.errorSummary = summary; 6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (Exception e) { 638f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert // We should normally not get here because 639f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert // MethodTarget.execute() calls handleException(). 6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ec++; 641f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert _params.log.println("\nencountered a test failure, exiting\n" + e); 642f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert e.printStackTrace(_params.log); 6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ec; 6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a ClassTarget for this test. Params is set on this test. 6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Target resolveTarget(TestParams paramsArg) { 6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.params = paramsArg; 6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new ClassTarget(); 6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Resolve a path from this test to a target. If this test has subtests, and 6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the path contains '/', the portion before the '/' is resolved to a 6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * subtest, until the path is consumed or the test has no subtests. Returns 6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * a ClassTarget created using the resolved test and remaining path (which 6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * ought to be null or a method name). Params is set on the target's test. 6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Target resolveTarget(TestParams paramsArg, String targetPath) { 6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestFmwk test = this; 6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert test.params = paramsArg; 6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (targetPath != null) { 6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (targetPath.length() == 0) { 6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert targetPath = null; 6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int p = 0; 6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int e = targetPath.length(); 6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // trim all leading and trailing '/' 6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (targetPath.charAt(p) == '/') { 6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++p; 6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (e > p && targetPath.charAt(e - 1) == '/') { 6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert --e; 6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (p > 0 || e < targetPath.length()) { 6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert targetPath = targetPath.substring(p, e - p); 6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert p = 0; 6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert e = targetPath.length(); 6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (;;) { 6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int n = targetPath.indexOf('/'); 6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String prefix = n == -1 ? targetPath : targetPath 6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .substring(0, n); 6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestFmwk subtest = test.getSubtest(prefix); 6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (subtest == null) { 6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert test = subtest; 6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (n == -1) { 7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert targetPath = null; 7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert targetPath = targetPath.substring(n + 1); 7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (TestFmwkException ex) { 7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return test.new Target(targetPath); 7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return test.new ClassTarget(targetPath); 7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return true if we can run this test (allows test to inspect jvm, 7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * environment, params before running) 7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean validate() { 7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return the targets for this test. If targetName is null, return all 7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * targets, otherwise return a target for just that name. The returned 7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * target can be null. 7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The default implementation returns a MethodTarget for each public method 7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * of the object's class whose name starts with "Test" or "test". 7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Target getTargets(String targetName) { 7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getClassTargets(getClass(), targetName); 7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Target getClassTargets(Class cls, String targetName) { 7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (cls == null) { 7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Target target = null; 7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (targetName != null) { 7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Method method = cls.getMethod(targetName, (Class[])null); 7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target = new MethodTarget(targetName, method); 7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (NoSuchMethodException e) { 7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!inheritTargets()) { 7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new Target(targetName); // invalid target 7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (SecurityException e) { 7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.doMethods()) { 7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Method[] methods = cls.getDeclaredMethods(); 7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = methods.length; --i >= 0;) { 7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String name = methods[i].getName(); 7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (name.startsWith("Test") || name.startsWith("test")) { 7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert target = new MethodTarget(name, methods[i]) 7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .setNext(target); 7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (inheritTargets()) { 7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Target parentTarget = getClassTargets(cls.getSuperclass(), targetName); 7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (parentTarget == null) { 7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return target; 7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (target == null) { 7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return parentTarget; 7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return parentTarget.append(target); 7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return target; 7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean inheritTargets() { 7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String getDescription() { 7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean validateMethod(String name) { 7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected String getMethodDescription(String name) { 7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // method tests have no subtests, group tests override 7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TestFmwk getSubtest(String prefix) throws TestFmwkException { 7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean isVerbose() { 8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.verbose; 8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean noData() { 8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.nodata; 8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean isTiming() { 8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.timing < Long.MAX_VALUE; 8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean isMemTracking() { 8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.memusage; 8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 0 = fewest tests, 5 is normal build, 10 is most tests 8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int getInclusion() { 8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.inclusion; 8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean isModularBuild() { 8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.warnings; 8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean isQuick() { 8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.inclusion == 0; 8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void msg(String message, int level, boolean incCount, boolean newln) { 8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.msg(message, level, incCount, newln); 8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static final String ICU_TRAC_URL = "http://bugs.icu-project.org/trac/ticket/"; 8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static final String CLDR_TRAC_URL = "http://unicode.org/cldr/trac/ticket/"; 8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static final String CLDR_TICKET_PREFIX = "cldrbug:"; 8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Log the known issue. 8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This method returns true unless -prop:logKnownIssue=no is specified 8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in the argument list. 8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param ticket A ticket number string. For an ICU ticket, use numeric characters only, 8467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * such as "10245". For a CLDR ticket, use prefix "cldrbug:" followed by ticket number, 8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * such as "cldrbug:5013". 8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param comment Additional comment, or null 8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return true unless -prop:logKnownIssue=no is specified in the test command line argument. 8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean logKnownIssue(String ticket, String comment) { 8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!getBooleanProperty("logKnownIssue", true)) { 8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer descBuf = new StringBuffer(); 8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.stack.appendPath(descBuf); 8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (comment != null && comment.length() > 0) { 8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert descBuf.append(" (" + comment + ")"); 8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String description = descBuf.toString(); 8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String ticketLink = "Unknown Ticket"; 8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ticket != null && ticket.length() > 0) { 8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isCldr = false; 8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ticket = ticket.toLowerCase(Locale.ENGLISH); 8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ticket.startsWith(CLDR_TICKET_PREFIX)) { 8687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isCldr = true; 8697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ticket = ticket.substring(CLDR_TICKET_PREFIX.length()); 8707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ticketLink = (isCldr ? CLDR_TRAC_URL : ICU_TRAC_URL) + ticket; 8727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.knownIssues == null) { 8757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.knownIssues = new TreeMap<String, List<String>>(); 8767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> lines = params.knownIssues.get(ticketLink); 8787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (lines == null) { 8797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert lines = new ArrayList<String>(); 8807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.knownIssues.put(ticketLink, lines); 8817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!lines.contains(description)) { 8837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert lines.add(description); 8847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 8877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int getErrorCount() { 8907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.errorCount; 8917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getProperty(String key) { 8947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String val = null; 8957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (key != null && key.length() > 0 && params.props != null) { 8967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert val = (String)params.props.get(key.toLowerCase()); 8977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return val; 8997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean getBooleanProperty(String key, boolean defVal) { 9027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String s = getProperty(key); 9037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (s != null) { 9047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (s.equalsIgnoreCase("yes") || s.equals("true")) { 9057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 9067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (s.equalsIgnoreCase("no") || s.equalsIgnoreCase("false")) { 9087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 9097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return defVal; 9127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TimeZone safeGetTimeZone(String id) { 9157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone tz = TimeZone.getTimeZone(id); 9167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (tz == null) { 9177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // should never happen 9187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("FAIL: TimeZone.getTimeZone(" + id + ") => null"); 9197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!tz.getID().equals(id)) { 9217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert warnln("FAIL: TimeZone.getTimeZone(" + id + ") => " + tz.getID()); 9227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return tz; 9247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 9277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Print a usage message for this test class. 9287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 9297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void usage() { 9307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usage(new PrintWriter(System.out), getClass().getName()); 9317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static void usage(PrintWriter pw, String className) { 9347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println("Usage: " + className + " option* target*"); 9357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(); 9367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println("Options:"); 9377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -d[escribe] Print a short descriptive string for this test and all"); 9387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" listed targets."); 9397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -e<n> Set exhaustiveness from 0..10. Default is 0, fewest tests.\n" 9407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " To run all tests, specify -e10. Giving -e with no <n> is\n" 9417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " the same as -e5."); 9427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -filter:<str> Only tests matching filter will be run or listed.\n" 9437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " <str> is of the form ['^']text[','['^']text].\n" 9447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " Each string delimited by ',' is a separate filter argument.\n" 9457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " If '^' is prepended to an argument, its matches are excluded.\n" 9467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " Filtering operates on test groups as well as tests, if a test\n" 9477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " group is included, all its subtests that are not excluded will\n" 9487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " be run. Examples:\n" 9497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " -filter:A -- only tests matching A are run. If A matches a group,\n" 9507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " all subtests of this group are run.\n" 9517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " -filter:^A -- all tests except those matching A are run. If A matches\n" 9527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " a group, no subtest of that group will be run.\n" 9537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " -filter:A,B,^C,^D -- tests matching A or B and not C and not D are run\n" 9547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " Note: Filters are case insensitive."); 9557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -h[elp] Print this help text and exit."); 956f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert pw.println(" -hex Display non-ASCII characters in hexadecimal format"); 9577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -l[ist] List immediate targets of this test"); 9587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -la, -listAll List immediate targets of this test, and all subtests"); 9597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -le, -listExaustive List all subtests and targets"); 9607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // don't know how to get useful numbers for memory usage using java API 9617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // calls 9627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // pw.println(" -m[emory] print memory usage and force gc for 9637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // each test"); 964f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert pw.println(" -n[othrow] Message on test failure rather than exception.\n" 965f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert + " This is the default behavior and has no effects on ICU 55+."); 9667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -p[rompt] Prompt before exiting"); 9677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -prop:<key>=<value> Set optional property used by this test"); 9687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -q[uiet] Do not show warnings"); 9697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -r[andom][:<n>] If present, randomize targets. If n is present,\n" 9707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " use it as the seed. If random is not set, targets will\n" 9717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " be in alphabetical order to ensure cross-platform consistency."); 9727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -s[ilent] No output except error summary or exceptions."); 9737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -tfilter:<str> Transliterator Test filter of ids."); 9747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -t[ime]:<n> Print elapsed time only for tests exceeding n milliseconds."); 9757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -v[erbose] Show log messages"); 976f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert pw.println(" -u[nicode] Don't escape error or log messages (Default on ICU 55+)"); 9777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -w[arning] Continue in presence of warnings, and disable missing test warnings."); 9787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" -nodata | -nd Do not warn if resource data is not present."); 9797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(); 9807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" If a list or describe option is provided, no tests are run."); 9817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(); 9827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println("Targets:"); 9837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" If no target is specified, all targets for this test are run."); 9847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" If a target contains no '/' characters, and matches a target"); 9857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" of this test, the target is run. Otherwise, the part before the"); 9867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" '/' is used to match a subtest, which then evaluates the"); 9877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" remainder of the target as above. Target matching is case-insensitive."); 9887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(); 9897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.println(" If multiple targets are provided, each is executed in order."); 9907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pw.flush(); 9917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String hex(char[] s){ 9937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer result = new StringBuffer(); 9947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < s.length; ++i) { 9957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (i != 0) result.append(','); 9967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append(hex(s[i])); 9977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result.toString(); 9997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String hex(byte[] s){ 10017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer result = new StringBuffer(); 10027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < s.length; ++i) { 10037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (i != 0) result.append(','); 10047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append(hex(s[i])); 10057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result.toString(); 10077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String hex(char ch) { 10097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer result = new StringBuffer(); 10107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String foo = Integer.toString(ch, 16).toUpperCase(); 10117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = foo.length(); i < 4; ++i) { 10127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append('0'); 10137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result + foo; 10157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String hex(int ch) { 10187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer result = new StringBuffer(); 10197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String foo = Integer.toString(ch, 16).toUpperCase(); 10207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = foo.length(); i < 4; ++i) { 10217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append('0'); 10227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result + foo; 10247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String hex(CharSequence s) { 10277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder result = new StringBuilder(); 10287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < s.length(); ++i) { 10297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (i != 0) 10307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append(','); 10317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append(hex(s.charAt(i))); 10327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result.toString(); 10347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String prettify(CharSequence s) { 10377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder result = new StringBuilder(); 10387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int ch; 10397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < s.length(); i += Character.charCount(ch)) { 10407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ch = Character.codePointAt(s, i); 10417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ch > 0xfffff) { 10427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append("\\U00"); 10437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append(hex(ch)); 10447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (ch > 0xffff) { 10457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append("\\U000"); 10467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append(hex(ch)); 10477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (ch < 0x20 || 0x7e < ch) { 10487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append("\\u"); 10497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append(hex(ch)); 10507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 10517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.append((char) ch); 10527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result.toString(); 10567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static java.util.GregorianCalendar cal; 10597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 10617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a Date given a year, month, and day of month. This is similar to 10627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * new Date(y-1900, m, d). It uses the default time zone at the time this 10637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * method is first called. 10647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 10657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param year 10667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * use 2000 for 2000, unlike new Date() 10677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param month 10687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * use Calendar.JANUARY etc. 10697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param dom 10707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * day of month, 1-based 10717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a Date object for the given y/m/d 10727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 10737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected static synchronized java.util.Date getDate(int year, int month, 10747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int dom) { 10757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (cal == null) { 10767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal = new java.util.GregorianCalendar(); 10777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.clear(); 10797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.set(year, month, dom); 10807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return cal.getTime(); 10817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static class NullWriter extends PrintWriter { 10847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public NullWriter() { 10857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(System.out, false); 10867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void write(int c) { 10887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void write(char[] buf, int off, int len) { 10907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void write(String s, int off, int len) { 10927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void println() { 10947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static class ASCIIWriter extends PrintWriter { 10987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private StringBuffer buffer = new StringBuffer(); 10997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Characters that we think are printable but that escapeUnprintable 11017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // doesn't 11027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final String PRINTABLES = "\t\n\r"; 11037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public ASCIIWriter(Writer w, boolean autoFlush) { 11057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(w, autoFlush); 11067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public ASCIIWriter(OutputStream os, boolean autoFlush) { 11097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super(os, autoFlush); 11107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void write(int c) { 11137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert synchronized (lock) { 11147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buffer.setLength(0); 11157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (PRINTABLES.indexOf(c) < 0 11167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && TestUtil.escapeUnprintable(buffer, c)) { 11177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super.write(buffer.toString()); 11187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 11197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super.write(c); 11207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void write(char[] buf, int off, int len) { 11257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert synchronized (lock) { 11267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buffer.setLength(0); 11277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int limit = off + len; 11287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (off < limit) { 11297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int c = UTF16Util.charAt(buf, 0, buf.length, off); 11307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert off += UTF16Util.getCharCount(c); 11317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (PRINTABLES.indexOf(c) < 0 11327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && TestUtil.escapeUnprintable(buffer, c)) { 11337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super.write(buffer.toString()); 11347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buffer.setLength(0); 11357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 11367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super.write(c); 11377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void write(String s, int off, int len) { 11437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert write(s.substring(off, off + len).toCharArray(), 0, len); 11447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // filters 11487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // match against the entire hierarchy 11497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // A;B;!C;!D --> (A ||B) && (!C && !D) 11507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // positive, negative, unknown matches 11517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // positive -- known to be included, negative- known to be excluded 11527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // positive only if no excludes, and matches at least one include, if any 11537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // negative only if matches at least one exclude 11547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // otherwise, we wait 11557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static class TestParams { 11577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean prompt; 11587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean verbose; 11597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean quiet; 11607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int listlevel; 11617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean describe; 11627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean warnings; 11637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean nodata; 11647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public long timing = 0; 11657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean memusage; 11667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int inclusion; 11677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String filter; 11687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public long seed; 11697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String tfilter; // for transliterator tests 11707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public State stack; 11727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1173a53a69a88b9accc4d1b0e996601d199f1755dc87Yoshito Umaoka public StringBuffer errorSummary = new StringBuffer(); 11747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private StringBuffer timeLog; 11757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Map<String, List<String>> knownIssues; 11767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PrintWriter log; 11787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int indentLevel; 11797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private boolean needLineFeed; 11807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private boolean suppressIndent; 11817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int errorCount; 11827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int warnCount; 11837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int invalidCount; 11847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int testCount; 11857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private NumberFormat tformat; 11867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Random random; 11877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int maxTargetSec = 10; 11887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public HashMap props; 11897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private TestParams() { 11917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 11937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static TestParams create(String arglist, PrintWriter log) { 11947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String[] args = null; 11957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (arglist != null && arglist.length() > 0) { 11967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert args = arglist.split("\\s"); 11977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 11987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return create(args, log); 11997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 12007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 12017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 12027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Create a TestParams from a list of arguments. If successful, return the params object, 12037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * else return null. Error messages will be reported on errlog if it is not null. 12047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Arguments and values understood by this method will be removed from the args array 12057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and existing args will be shifted down, to be filled by nulls at the end. 12067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param args the list of arguments 12077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param log the error log, or null if no error log is desired 12087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the new TestParams object, or null if error 12097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 12107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static TestParams create(String[] args, PrintWriter log) { 12117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TestParams params = new TestParams(); 12127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1213f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert if (log == null) { 12147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.log = new NullWriter(); 1215f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } else { 1216f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert params.log = log; 12177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 12187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 12197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean usageError = false; 12207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String filter = null; 12217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String fmt = "#,##0.000s"; 12227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int wx = 0; // write argets. 12237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (args != null) { 12247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < args.length; i++) { 12257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String arg = args[i]; 12267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (arg == null || arg.length() == 0) { 12277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 12287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 12297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (arg.charAt(0) == '-') { 12307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert arg = arg.toLowerCase(); 12317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (arg.equals("-verbose") || arg.equals("-v")) { 12327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.verbose = true; 12337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.quiet = false; 12347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-quiet") || arg.equals("-q")) { 12357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.quiet = true; 12367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.verbose = false; 1237f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } else if (arg.equals("-hex")) { 1238f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert params.log = new ASCIIWriter(log, true); 12397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-help") || arg.equals("-h")) { 12407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usageError = true; 12417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-warning") || arg.equals("-w")) { 12427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.warnings = true; 12437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-nodata") || arg.equals("-nd")) { 12447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.nodata = true; 12457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-list") || arg.equals("-l")) { 12467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.listlevel = 1; 12477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-listall") || arg.equals("-la")) { 12487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.listlevel = 2; 12497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-listexaustive") || arg.equals("-le")) { 12507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.listlevel = 3; 12517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-memory") || arg.equals("-m")) { 12527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.memusage = true; 12537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-nothrow") || arg.equals("-n")) { 1254a53a69a88b9accc4d1b0e996601d199f1755dc87Yoshito Umaoka // Default since ICU 55. This option has no effects. 12557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.equals("-describe") || arg.equals("-d")) { 12567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.describe = true; 12577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-r")) { 12587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String s = null; 12597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int n = arg.indexOf(':'); 12607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (n != -1) { 12617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert s = arg.substring(n + 1); 12627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert arg = arg.substring(0, n); 12637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 12647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 12657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (arg.equals("-r") || arg.equals("-random")) { 12667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (s == null) { 12677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.seed = System.currentTimeMillis(); 12687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 12697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.seed = Long.parseLong(s); 12707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 12717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 12727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println("*** Error: unrecognized argument: " + arg); 12737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usageError = true; 12747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 12757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 12767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-e")) { 12777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // see above 12787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.inclusion = (arg.length() == 2) 12797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ? 5 12807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert : Integer.parseInt(arg.substring(2)); 12817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.inclusion < 0 || params.inclusion > 10) { 12827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usageError = true; 12837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 12847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 12857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-tfilter:")) { 12867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.tfilter = arg.substring(8); 12877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-time") || arg.startsWith("-t")) { 12887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long val = 0; 12897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int inx = arg.indexOf(':'); 12907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (inx > 0) { 12917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String num = arg.substring(inx + 1); 12927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 12937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert val = Long.parseLong(num); 12947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (Exception e) { 12957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println("*** Error: could not parse time threshold '" 12967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + num + "'"); 12977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usageError = true; 12987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 12997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.timing = val; 13027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (val <= 10) { 13037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fmt = "#,##0.000s"; 13047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (val <= 100) { 13057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fmt = "#,##0.00s"; 13067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (val <= 1000) { 13077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fmt = "#,##0.0s"; 13087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-filter:")) { 13107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String temp = arg.substring(8).toLowerCase(); 13117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert filter = filter == null ? temp : filter + "," + temp; 13127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-f:")) { 13137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String temp = arg.substring(3).toLowerCase(); 13147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert filter = filter == null ? temp : filter + "," + temp; 13157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-s")) { 13167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.log = new NullWriter(); 13177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-u")) { 13187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.log instanceof ASCIIWriter) { 13197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.log = log; 13207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (arg.startsWith("-prop:")) { 13227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String temp = arg.substring(6); 13237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int eql = temp.indexOf('='); 13247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (eql <= 0) { 13257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println("*** Error: could not parse custom property '" + arg + "'"); 13267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usageError = true; 13277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 13287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (params.props == null) { 13307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.props = new HashMap(); 13317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.props.put(temp.substring(0, eql), temp.substring(eql+1)); 13337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 13347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println("*** Error: unrecognized argument: " 13357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + args[i]); 13367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usageError = true; 13377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 13387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 13407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert args[wx++] = arg; // shift down 13417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (wx < args.length) { 13457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert args[wx++] = null; 13467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.tformat = new DecimalFormat(fmt); 13507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (usageError) { 13527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert usage(log, "TestAll"); 13537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 13547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (filter != null) { 13577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.filter = filter.toLowerCase(); 13587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert params.init(); 13617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params; 13637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String errorSummary() { 13667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return errorSummary == null ? "" : errorSummary.toString(); 13677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void init() { 13707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert indentLevel = 0; 13717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert needLineFeed = false; 13727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert suppressIndent = false; 13737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errorCount = 0; 13747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert warnCount = 0; 13757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert invalidCount = 0; 13767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testCount = 0; 13777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert random = seed == 0 ? null : new Random(seed); 13787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 13797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public class State { 13817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert State link; 13827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String name; 13837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer buffer; 13847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int level; 13857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int ec; 13867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int wc; 13877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int ic; 13887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int tc; 13897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean flushed; 13907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean included; 13917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long mem; 13927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long millis; 13937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 13947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public State(State link, String name, boolean included) { 13957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.link = link; 13967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.name = name; 13977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (link == null) { 13987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.level = 0; 13997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.included = included; 14007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 14017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.level = link.level + 1; 14027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.included = included || link.included; 14037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.ec = errorCount; 14057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.wc = warnCount; 14067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.ic = invalidCount; 14077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.tc = testCount; 14087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (link == null || this.included) { 14107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert flush(); 14117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert mem = getmem(); 14147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert millis = System.currentTimeMillis(); 14157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert void flush() { 14187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!flushed) { 14197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (link != null) { 14207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert link.flush(); 14217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert indent(level); 14247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(name); 14257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.flush(); 14267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert flushed = true; 14287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert needLineFeed = true; 14307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert void appendPath(StringBuffer buf) { 14347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (this.link != null) { 14357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.link.appendPath(buf); 14367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buf.append('/'); 14377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buf.append(name); 14397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void push(String name, String description, boolean included) { 14437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (inDocMode() && describe && description != null) { 14447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert name += ": " + description; 14457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stack = new State(stack, name, included); 14477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void pop() { 14507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (stack != null) { 14517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert writeTestResult(); 14527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stack = stack.link; 14537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean inDocMode() { 14577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return describe || listlevel != 0; 14587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean doMethods() { 14617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return !inDocMode() || listlevel == 3 14627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert || (indentLevel == 1 && listlevel > 0); 14637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean doRecurse() { 14667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return !inDocMode() || listlevel > 1 14677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert || (indentLevel == 1 && listlevel > 0); 14687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean doRecurseGroupsOnly() { 14717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return inDocMode() 14727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && (listlevel == 2 || (indentLevel == 1 && listlevel > 0)); 14737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 14757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // return 0, -1, or 1 14767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 1: run this test 14777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 0: might run this test, no positive include or exclude on this group 14787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // -1: exclude this test 14797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int filter(String testName) { 14807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int result = 0; 14817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (filter == null) { 14827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result = 1; 14837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 14847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean noIncludes = true; 14857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean noExcludes = filter.indexOf('^') == -1; 14867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testName = testName.toLowerCase(); 14877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int ix = 0; 14887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (ix < filter.length()) { 14897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int nix = filter.indexOf(',', ix); 14907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (nix == -1) { 14917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert nix = filter.length(); 14927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (filter.charAt(ix) == '^') { 14947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (testName.indexOf(filter.substring(ix + 1, nix)) != -1) { 14957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result = -1; 14967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 14977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 14987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 14997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert noIncludes = false; 15007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (testName.indexOf(filter.substring(ix, nix)) != -1) { 15017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result = 1; 15027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (noExcludes) { 15037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 15047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ix = nix + 1; 15097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (result == 0 && noIncludes) { 15117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result = 1; 15127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // System.out.println("filter: " + testName + " returns: " + 15157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // result); 15167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 15177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 15207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Log access. 15217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param msg The string message to write 15227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 15237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void write(String msg) { 15247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert write(msg, false); 15257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void writeln(String msg) { 15287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert write(msg, true); 15297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void write(String msg, boolean newln) { 15327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!suppressIndent) { 15337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (needLineFeed) { 15347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(); 15357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert needLineFeed = false; 15367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(spaces.substring(0, indentLevel * 2)); 15387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(msg); 15407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (newln) { 15417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(); 15427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.flush(); 15447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert suppressIndent = !newln; 15457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void msg(String message, int level, boolean incCount, 15487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean newln) { 15497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int oldLevel = level; 15507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (level == WARN && (!warnings && !nodata)){ 15517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// level = ERR; 15527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 15537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (incCount) { 15557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (level == WARN) { 15567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert warnCount++; 15577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// invalidCount++; 15587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (level == ERR) { 15597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errorCount++; 15607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // should roll indentation stuff into log ??? 15647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (verbose || level > (quiet ? WARN : LOG)) { 15657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!suppressIndent) { 15667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert indent(indentLevel + 1); 15677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final String[] MSGNAMES = {"", "Warning: ", "Error: "}; 15687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(MSGNAMES[oldLevel]); 15697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String testLocation = sourceLocation(); 15727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert message = testLocation + message; 15737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(message); 15747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (newln) { 15757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(); 15767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.flush(); 15787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (level == ERR) { 15817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!suppressIndent && errorSummary != null && stack !=null 15827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && (errorCount == stack.ec + 1)) { 15837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stack.appendPath(errorSummary); 15847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errorSummary.append("\n"); 15857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert suppressIndent = !newln; 15897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 15917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void writeTestInvalid(String name, boolean nodataArg) { 15927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // msg("***" + name + "*** not found or not valid.", WARN, true, 15937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // true); 15947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (inDocMode()) { 15957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!warnings) { 15967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (stack != null) { 15977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stack.flush(); 15987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 15997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(" *** Target not found or not valid."); 16007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.flush(); 16017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert needLineFeed = false; 16027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 16047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if(!nodataArg){ 16057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert msg("Test " + name + " not found or not valid.", WARN, true, 16067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert true); 16077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long getmem() { 16127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long newmem = 0; 16137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (memusage) { 16147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Runtime rt = Runtime.getRuntime(); 16157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long lastmem = Long.MAX_VALUE; 16167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert do { 16177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert rt.gc(); 16187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert rt.gc(); 16197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 16207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Thread.sleep(50); 16217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (Exception e) { 16227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 16237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert lastmem = newmem; 16257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert newmem = rt.totalMemory() - rt.freeMemory(); 16267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } while (newmem < lastmem); 16277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return newmem; 16297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void writeTestResult() { 16327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (inDocMode()) { 16337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (needLineFeed) { 16347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(); 16357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.flush(); 16367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert needLineFeed = false; 16387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return; 16397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long dmem = getmem() - stack.mem; 16427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long dtime = System.currentTimeMillis() - stack.millis; 16437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int testDelta = testCount - stack.tc; 16457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (testDelta == 0) { 1646f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert if (stack.included) { 1647f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert stack.flush(); 1648f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert indent(indentLevel); 1649f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert log.println("} (0s) Empty"); 1650f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 16517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return; 16527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int errorDelta = errorCount - stack.ec; 16557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int warnDelta = warnCount - stack.wc; 16567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int invalidDelta = invalidCount - stack.ic; 16577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stack.flush(); 16597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!needLineFeed) { 16617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert indent(indentLevel); 16627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print("}"); 16637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert needLineFeed = false; 16657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (memusage || dtime >= timing) { 16677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(" ("); 16687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (memusage) { 16697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print("dmem: " + dmem); 16707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (dtime >= timing) { 16727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (memusage) { 16737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(", "); 16747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(tformat.format(dtime / 1000f)); 16767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(")"); 16787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 16807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (errorDelta != 0) { 16817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(" FAILED (" 16827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + errorDelta 16837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " failure(s)" 16847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ((warnDelta != 0) ? ", " + warnDelta 16857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " warning(s)" : "") 16867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ((invalidDelta != 0) ? ", " + invalidDelta 16877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " test(s) skipped)" : ")")); 16887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (warnDelta != 0) { 16897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(" ALERT (" 16907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + warnDelta 16917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " warning(s)" 16927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ((invalidDelta != 0) ? ", " + invalidDelta 16937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " test(s) skipped)" : ")")); 16947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (invalidDelta != 0) { 16957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(" Qualified (" + invalidDelta + " test(s) skipped)"); 16967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 16977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(" Passed"); 16987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 16997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 17017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private final void indent(int distance) { 17027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean idm = inDocMode(); 17037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (needLineFeed) { 17047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (idm) { 17057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(); 17067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 17077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.println(" {"); 17087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert needLineFeed = false; 17107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 17127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print(spaces.substring(0, distance * (idm ? 3 : 2))); 17137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 17147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (idm) { 17157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert log.print("-- "); 17167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 17207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getTranslitTestFilter() { 17217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return params.tfilter; 17227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 17247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 17257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return the target name for a test class. This is either the end of the 17267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * class name, or if the class declares a public static field 17277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * CLASS_TARGET_NAME, the value of that field. 17287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 17297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static String getClassTargetName(Class testClass) { 17307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String name = testClass.getName(); 17317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 17327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Field f = testClass.getField("CLASS_TARGET_NAME"); 17337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert name = (String) f.get(null); 17347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (IllegalAccessException e) { 17357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalStateException( 17367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "static field CLASS_TARGET_NAME must be accessible"); 17377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (NoSuchFieldException e) { 17387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int n = Math.max(name.lastIndexOf('.'), name.lastIndexOf('$')); 17397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (n != -1) { 17407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert name = name.substring(n + 1); 17417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return name; 17447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 17467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 17477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Check the given array to see that all the strings in the expected array 17487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * are present. 17497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 17507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param msg 17517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * string message, for log output 17527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param array 17537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * array of strings to check 17547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param expected 17557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * array of strings we expect to see, or null 17567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the length of 'array', or -1 on error 17577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 17587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int checkArray(String msg, String array[], String expected[]) { 17597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int explen = (expected != null) ? expected.length : 0; 17607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!(explen >= 0 && explen < 31)) { // [sic] 31 not 32 17617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Internal error"); 17627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return -1; 17637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int i = 0; 17657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer buf = new StringBuffer(); 17667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int seenMask = 0; 17677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (; i < array.length; ++i) { 17687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String s = array[i]; 17697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (i != 0) 17707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buf.append(", "); 17717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buf.append(s); 17727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // check expected list 17737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int j = 0, bit = 1; j < explen; ++j, bit <<= 1) { 17747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ((seenMask & bit) == 0) { 17757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (s.equals(expected[j])) { 17767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert seenMask |= bit; 17777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Ok: \"" + s + "\" seen"); 17787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(msg + " = [" + buf + "] (" + i + ")"); 17837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // did we see all expected strings? 17847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (((1 << explen) - 1) != seenMask) { 17857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int j = 0, bit = 1; j < expected.length; ++j, bit <<= 1) { 17867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ((seenMask & bit) == 0) { 17877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("\"" + expected[j] + "\" not seen"); 17887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return array.length; 17927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 17937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 17947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 17957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Check the given array to see that all the locales in the expected array 17967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * are present. 17977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 17987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param msg 17997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * string message, for log output 18007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param array 18017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * array of locales to check 18027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param expected 18037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * array of locales names we expect to see, or null 18047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the length of 'array' 18057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 18067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int checkArray(String msg, Locale array[], String expected[]) { 18077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String strs[] = new String[array.length]; 18087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < array.length; ++i) 18097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert strs[i] = array[i].toString(); 18107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return checkArray(msg, strs, expected); 18117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 18147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Check the given array to see that all the locales in the expected array 18157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * are present. 18167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 18177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param msg 18187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * string message, for log output 18197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param array 18207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * array of locales to check 18217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param expected 18227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * array of locales names we expect to see, or null 18237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the length of 'array' 18247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 18257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected int checkArray(String msg, ULocale array[], String expected[]) { 18267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String strs[] = new String[array.length]; 18277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < array.length; ++i) 18287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert strs[i] = array[i].toString(); 18297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return checkArray(msg, strs, expected); 18307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // JUnit-like assertions. 18337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertTrue(String message, boolean condition) { 18357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(condition, message, "true", null); 18367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertFalse(String message, boolean condition) { 18397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(!condition, message, "false", null); 18407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertEquals(String message, boolean expected, 18437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean actual) { 18447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(expected == actual, message, String 18457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .valueOf(expected), String.valueOf(actual)); 18467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertEquals(String message, long expected, long actual) { 18497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(expected == actual, message, String 18507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .valueOf(expected), String.valueOf(actual)); 18517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // do NaN and range calculations to precision of float, don't rely on 18547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // promotion to double 18557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertEquals(String message, float expected, 18567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert float actual, double error) { 18577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean result = Float.isInfinite(expected) 18587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ? expected == actual 18597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert : !(Math.abs(expected - actual) > error); // handles NaN 18607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(result, message, String.valueOf(expected) 18617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + (error == 0 ? "" : " (within " + error + ")"), String 18627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .valueOf(actual)); 18637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertEquals(String message, double expected, 18667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double actual, double error) { 18677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean result = Double.isInfinite(expected) 18687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ? expected == actual 18697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert : !(Math.abs(expected - actual) > error); // handles NaN 18707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(result, message, String.valueOf(expected) 18717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + (error == 0 ? "" : " (within " + error + ")"), String 18727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .valueOf(actual)); 18737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected <T> boolean assertEquals(String message, T[] expected, T[] actual) { 18767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Use toString on a List to get useful, readable messages 18777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String expectedString = expected == null ? "null" : Arrays.asList(expected).toString(); 18787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String actualString = actual == null ? "null" : Arrays.asList(actual).toString(); 18797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return assertEquals(message, expectedString, actualString); 18807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertEquals(String message, Object expected, 18837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object actual) { 18847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean result = expected == null ? actual == null : expected 18857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .equals(actual); 18867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(result, message, stringFor(expected), 18877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringFor(actual)); 18887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertNotEquals(String message, Object expected, 18917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object actual) { 18927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean result = !(expected == null ? actual == null : expected 18937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .equals(actual)); 18947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(result, message, stringFor(expected), 18957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringFor(actual), "not equal to", true); 18967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 18977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 18987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertSame(String message, Object expected, Object actual) { 18997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(expected == actual, message, stringFor(expected), 19007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringFor(actual), "==", false); 19017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertNotSame(String message, Object expected, 19047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object actual) { 19057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(expected != actual, message, stringFor(expected), 19067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringFor(actual), "!=", true); 19077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertNull(String message, Object actual) { 19107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(actual == null, message, null, stringFor(actual)); 19117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean assertNotNull(String message, Object actual) { 19147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(actual != null, message, null, stringFor(actual), 19157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "!=", true); 19167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void fail() { 19197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert fail(""); 19207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void fail(String message) { 19237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (message == null) { 19247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert message = ""; 19257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!message.equals("")) { 19277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert message = ": " + message; 19287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln(sourceLocation() + message); 19307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private boolean handleAssert(boolean result, String message, 19337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String expected, String actual) { 19347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return handleAssert(result, message, expected, actual, null, false); 19357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean handleAssert(boolean result, String message, 19387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Object expected, Object actual, String relation, boolean flip) { 19397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!result || isVerbose()) { 19407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (message == null) { 19417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert message = ""; 19427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!message.equals("")) { 19447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert message = ": " + message; 19457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert relation = relation == null ? ", got " : " " + relation + " "; 19477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (result) { 19487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("OK " + message + ": " 19497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + (flip ? expected + relation + actual : expected)); 19507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 19517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // assert must assume errors are true errors and not just warnings 19527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // so cannot warnln here 19537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln( message 19547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ": expected" 19557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + (flip ? relation + expected : " " + expected 19567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + (actual != null ? relation + actual : ""))); 19577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 19607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private final String stringFor(Object obj) { 19637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (obj == null) { 19647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return "null"; 19657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (obj instanceof String) { 19677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return "\"" + obj + '"'; 19687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return obj.getClass().getName() + "<" + obj + ">"; 19707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Return the source code location of the caller located callDepth frames up the stack. 19737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String sourceLocation() { 19747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Walk up the stack to the first call site outside this file 19757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StackTraceElement[] st = new Throwable().getStackTrace(); 19767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < st.length; ++i) { 19777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String source = st[i].getFileName(); 19787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!source.equals("TestFmwk.java") && !source.equals("AbstractTestLog.java")) { 19797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return "(" + st[i].getFileName() + ":" + st[i].getLineNumber() + ") "; 19807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new InternalError(); 19837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // End JUnit-like assertions 19877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // PrintWriter support 19897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PrintWriter getErrorLogPrintWriter() { 19917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new PrintWriter(new TestLogWriter(this, TestLog.ERR)); 19927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PrintWriter getLogPrintWriter() { 19957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new PrintWriter(new TestLogWriter(this, TestLog.LOG)); 19967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 19977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 19987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // end PrintWriter support 19997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 20007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected TestParams params = null; 20017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 20027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private final static String spaces = " "; 20037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 20047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 2005