1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.coretests; 17 18 import java.util.ArrayList; 19 import java.util.List; 20 import java.util.logging.Level; 21 import java.util.logging.Logger; 22 23 import junit.framework.Test; 24 import junit.framework.TestResult; 25 import junit.framework.TestSuite; 26 import junit.textui.ResultPrinter; 27 import junit.textui.TestRunner; 28 29 /** 30 * A special TestRunner implementation that is able to filter out annotated 31 * tests and handles our known failures properly (expects them to fail). 32 * Handy when running the Core Libraries tests on Android, the bare-metal 33 * Dalvik VM, or the RI. 34 */ 35 public class CoreTestRunner extends TestRunner { 36 37 /** 38 * Reflects our environment. 39 */ 40 private static boolean IS_DALVIK = "Dalvik".equals( 41 System.getProperty("java.vm.name")); 42 43 /** 44 * Defines the default flags for running on Dalvik. 45 */ 46 private static final int DEFAULT_FLAGS_DALVIK = 47 CoreTestSuite.RUN_ANDROID_ONLY | 48 CoreTestSuite.RUN_NORMAL_TESTS | 49 CoreTestSuite.RUN_KNOWN_FAILURES | 50 CoreTestSuite.RUN_SIDE_EFFECTS | 51 CoreTestSuite.INVERT_KNOWN_FAILURES; 52 53 /** 54 * Defines the default flags for running on an RI. 55 */ 56 private static final int DEFAULT_FLAGS_NON_DALVIK = 57 CoreTestSuite.RUN_NORMAL_TESTS | 58 CoreTestSuite.RUN_KNOWN_FAILURES | 59 CoreTestSuite.RUN_SIDE_EFFECTS; 60 61 /** 62 * Holds the flags specified by the user on the command line. 63 */ 64 private int fFlags; 65 66 /** 67 * Holds the timeout value specified by the user on the command line. 68 */ 69 private int fTimeout; 70 71 private int fStep = 1; 72 73 /** 74 * The path to write XML reports to, or {@code null} for no reports. 75 */ 76 private String xmlReportsDirectory; 77 78 /** 79 * Creates a new instance of our CoreTestRunner. 80 */ 81 public CoreTestRunner() { 82 super(); 83 } 84 85 @Override 86 protected TestResult createTestResult() { 87 return new CoreTestResult(fFlags, fTimeout); 88 } 89 90 protected ResultPrinter createPrinter() { 91 return new CoreTestPrinter(System.out, fFlags); 92 } 93 94 /** 95 * Provides our main entry point. 96 */ 97 public static void main(String args[]) { 98 Logger.global.setLevel(Level.OFF); 99 100 System.out.println( 101 "--------------------------------------------------"); 102 System.out.println("Android Core Libraries Test Suite"); 103 System.out.println("Version 1.0"); 104 System.out.println( 105 "Copyright (c) 2009 The Android Open Source Project"); 106 System.out.println(""); 107 108 CoreTestRunner testRunner = new CoreTestRunner(); 109 try { 110 TestResult r = testRunner.start(args); 111 112 System.out.println( 113 "--------------------------------------------------"); 114 115 if (!r.wasSuccessful()) { 116 System.exit(FAILURE_EXIT); 117 } else { 118 System.exit(SUCCESS_EXIT); 119 } 120 } catch(Exception e) { 121 System.err.println(e.getMessage()); 122 System.exit(EXCEPTION_EXIT); 123 } 124 125 } 126 127 @Override 128 public TestResult doRun(Test suite, boolean wait) { 129 setPrinter(createPrinter()); 130 131 /* 132 * Make sure the original suite is unreachable after we have 133 * created the new one, so GC can dispose terminated tests. 134 */ 135 CoreTestSuite coreTestSuite = new CoreTestSuite(suite, fFlags, fStep, null); 136 137 XmlReportPrinter xmlReportPrinter = xmlReportsDirectory != null 138 ? new XmlReportPrinter(coreTestSuite) 139 : null; 140 141 TestResult result = super.doRun(coreTestSuite, wait); 142 143 if (xmlReportPrinter != null) { 144 System.out.print("Printing XML Reports... "); 145 xmlReportPrinter.setResults(result); 146 int numFiles = xmlReportPrinter.generateReports(xmlReportsDirectory); 147 System.out.println(numFiles + " files written."); 148 } 149 150 return result; 151 } 152 153 /** 154 * Prints a help screen on the console. 155 */ 156 private void showHelp() { 157 System.out.println("Usage: run-core-tests [OPTION]... [TEST]..."); 158 System.out.println(); 159 System.out.println("Where each TEST is a class name, optionally followed"); 160 System.out.println("by \"#\" and a method name, and each OPTION is one of"); 161 System.out.println("the following:"); 162 System.out.println(); 163 System.out.println(" --include-all"); 164 System.out.println(" --exclude-all"); 165 System.out.println(" --include-android-only"); 166 System.out.println(" --exclude-android-only"); 167 System.out.println(" --include-broken-tests"); 168 System.out.println(" --exclude-broken-tests"); 169 System.out.println(" --include-known-failures"); 170 System.out.println(" --exclude-known-failures"); 171 System.out.println(" --include-normal-tests"); 172 System.out.println(" --exclude-normal-tests"); 173 System.out.println(" --include-side-effects"); 174 System.out.println(" --exclude-side-effects"); 175 System.out.println(); 176 System.out.println(" --known-failures-must-fail"); 177 System.out.println(" --known-failures-must-pass"); 178 System.out.println(" --timeout <seconds>"); 179 // System.out.println(" --find-side-effect <test>"); 180 System.out.println(" --isolate-all"); 181 System.out.println(" --isolate-none"); 182 System.out.println(" --verbose"); 183 System.out.println(" --xml-reports-directory <path>"); 184 System.out.println(" --help"); 185 System.out.println(); 186 System.out.println("Default parameters are:"); 187 System.out.println(); 188 189 if (IS_DALVIK) { 190 System.out.println(" --include-android-only"); 191 System.out.println(" --exclude-broken-tests"); 192 System.out.println(" --include-known-failures"); 193 System.out.println(" --include-normal-tests"); 194 System.out.println(" --include-side-effects"); 195 System.out.println(" --known-failures-must-fail"); 196 } else { 197 System.out.println(" --exclude-android-only"); 198 System.out.println(" --exclude-broken-tests"); 199 System.out.println(" --include-known-failures"); 200 System.out.println(" --include-normal-tests"); 201 System.out.println(" --include-side-effects"); 202 System.out.println(" --known-failures-must-pass"); 203 } 204 205 System.out.println(); 206 } 207 208 /** 209 * Tries to create a Test instance from the given strings. The strings might 210 * either specify a class only or a class plus a method name, separated by 211 * a "#". 212 */ 213 private Test createTest(List<String> testCases) throws Exception { 214 TestSuite result = new TestSuite(); 215 for (String testCase : testCases) { 216 int p = testCase.indexOf("#"); 217 if (p != -1) { 218 String testName = testCase.substring(p + 1); 219 testCase = testCase.substring(0, p); 220 221 result.addTest(TestSuite.createTest(Class.forName(testCase), testName)); 222 } else { 223 result.addTest(getTest(testCase)); 224 } 225 } 226 return result; 227 } 228 229 @Override 230 protected TestResult start(String args[]) throws Exception { 231 List<String> testNames = new ArrayList<String>(); 232 // String victimName = null; 233 234 boolean wait = false; 235 236 if (IS_DALVIK) { 237 fFlags = DEFAULT_FLAGS_DALVIK; 238 } else { 239 fFlags = DEFAULT_FLAGS_NON_DALVIK; 240 } 241 242 for (int i= 0; i < args.length; i++) { 243 if (args[i].startsWith("--")) { 244 if (args[i].equals("--wait")) { 245 wait = true; 246 } else if (args[i].equals("--include-all")) { 247 fFlags = fFlags | CoreTestSuite.RUN_ALL_TESTS; 248 } else if (args[i].equals("--exclude-all")) { 249 fFlags = fFlags & ~CoreTestSuite.RUN_ALL_TESTS; 250 } else if (args[i].equals("--include-android-only")) { 251 fFlags = fFlags | CoreTestSuite.RUN_ANDROID_ONLY; 252 } else if (args[i].equals("--exclude-android-only")) { 253 fFlags = fFlags & ~CoreTestSuite.RUN_ANDROID_ONLY; 254 } else if (args[i].equals("--include-broken-tests")) { 255 fFlags = fFlags | CoreTestSuite.RUN_BROKEN_TESTS; 256 } else if (args[i].equals("--exclude-broken-tests")) { 257 fFlags = fFlags & ~CoreTestSuite.RUN_BROKEN_TESTS; 258 } else if (args[i].equals("--include-known-failures")) { 259 fFlags = fFlags | CoreTestSuite.RUN_KNOWN_FAILURES; 260 } else if (args[i].equals("--exclude-known-failures")) { 261 fFlags = fFlags & ~CoreTestSuite.RUN_KNOWN_FAILURES; 262 } else if (args[i].equals("--include-normal-tests")) { 263 fFlags = fFlags | CoreTestSuite.RUN_NORMAL_TESTS; 264 } else if (args[i].equals("--exclude-normal-tests")) { 265 fFlags = fFlags & ~CoreTestSuite.RUN_NORMAL_TESTS; 266 } else if (args[i].equals("--include-side-effects")) { 267 fFlags = fFlags | CoreTestSuite.RUN_SIDE_EFFECTS; 268 } else if (args[i].equals("--exclude-side-effects")) { 269 fFlags = fFlags & ~CoreTestSuite.RUN_SIDE_EFFECTS; 270 } else if (args[i].equals("--known-failures-must-fail")) { 271 fFlags = fFlags | CoreTestSuite.INVERT_KNOWN_FAILURES; 272 } else if (args[i].equals("--known-failures-must-pass")) { 273 fFlags = fFlags & ~CoreTestSuite.INVERT_KNOWN_FAILURES; 274 } else if (args[i].equals("--timeout")) { 275 fTimeout = Integer.parseInt(args[++i]); 276 } else if (args[i].equals("--reverse")) { 277 fFlags = fFlags | CoreTestSuite.REVERSE; 278 } else if (args[i].equals("--step")) { 279 fStep = Integer.parseInt(args[++i]); 280 } else if (args[i].equals("--isolate-all")) { 281 fFlags = (fFlags | CoreTestSuite.ISOLATE_ALL) & 282 ~CoreTestSuite.ISOLATE_NONE; 283 } else if (args[i].equals("--isolate-none")) { 284 fFlags = (fFlags | CoreTestSuite.ISOLATE_NONE) & 285 ~CoreTestSuite.ISOLATE_ALL; 286 } else if (args[i].equals("--verbose")) { 287 fFlags = fFlags | CoreTestSuite.VERBOSE; 288 // } else if (args[i].equals("--find-side-effect")) { 289 // victimName = args[++i]; 290 } else if (args[i].equals("--dry-run")) { 291 fFlags = fFlags | CoreTestSuite.DRY_RUN; 292 } else if (args[i].equals("--xml-reports-directory")) { 293 xmlReportsDirectory = args[++i]; 294 } else if (args[i].equals("--help")) { 295 showHelp(); 296 System.exit(1); 297 } else { 298 unknownArgument(args[i]); 299 } 300 } else if (args[i].startsWith("-")) { 301 unknownArgument(args[i]); 302 } else { 303 testNames.add(args[i]); 304 } 305 } 306 307 if (IS_DALVIK) { 308 System.out.println("Using Dalvik VM version " + 309 System.getProperty("java.vm.version")); 310 } else { 311 System.out.println("Using Java VM version " + 312 System.getProperty("java.version")); 313 } 314 System.out.println(); 315 316 try { 317 return doRun(createTest(testNames), wait); 318 } 319 catch(Exception e) { 320 e.printStackTrace(); 321 throw new Exception("Could not create and run test suite: " + e); 322 } 323 } 324 325 private static void unknownArgument(String arg) { 326 System.err.println("Unknown argument " + arg + ", try --help"); 327 System.exit(1); 328 } 329 } 330