/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.coretests; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import junit.framework.Test; import junit.framework.TestResult; import junit.framework.TestSuite; import junit.textui.ResultPrinter; import junit.textui.TestRunner; /** * A special TestRunner implementation that is able to filter out annotated * tests and handles our known failures properly (expects them to fail). * Handy when running the Core Libraries tests on Android, the bare-metal * Dalvik VM, or the RI. */ public class CoreTestRunner extends TestRunner { /** * Reflects our environment. */ private static boolean IS_DALVIK = "Dalvik".equals( System.getProperty("java.vm.name")); /** * Defines the default flags for running on Dalvik. */ private static final int DEFAULT_FLAGS_DALVIK = CoreTestSuite.RUN_ANDROID_ONLY | CoreTestSuite.RUN_NORMAL_TESTS | CoreTestSuite.RUN_KNOWN_FAILURES | CoreTestSuite.RUN_SIDE_EFFECTS | CoreTestSuite.INVERT_KNOWN_FAILURES; /** * Defines the default flags for running on an RI. */ private static final int DEFAULT_FLAGS_NON_DALVIK = CoreTestSuite.RUN_NORMAL_TESTS | CoreTestSuite.RUN_KNOWN_FAILURES | CoreTestSuite.RUN_SIDE_EFFECTS; /** * Holds the flags specified by the user on the command line. */ private int fFlags; /** * Holds the timeout value specified by the user on the command line. */ private int fTimeout; private int fStep = 1; /** * The path to write XML reports to, or {@code null} for no reports. */ private String xmlReportsDirectory; /** * Creates a new instance of our CoreTestRunner. */ public CoreTestRunner() { super(); } @Override protected TestResult createTestResult() { return new CoreTestResult(fFlags, fTimeout); } protected ResultPrinter createPrinter() { return new CoreTestPrinter(System.out, fFlags); } /** * Provides our main entry point. */ public static void main(String args[]) { Logger.global.setLevel(Level.OFF); System.out.println( "--------------------------------------------------"); System.out.println("Android Core Libraries Test Suite"); System.out.println("Version 1.0"); System.out.println( "Copyright (c) 2009 The Android Open Source Project"); System.out.println(""); CoreTestRunner testRunner = new CoreTestRunner(); try { TestResult r = testRunner.start(args); System.out.println( "--------------------------------------------------"); if (!r.wasSuccessful()) { System.exit(FAILURE_EXIT); } else { System.exit(SUCCESS_EXIT); } } catch(Exception e) { System.err.println(e.getMessage()); System.exit(EXCEPTION_EXIT); } } @Override public TestResult doRun(Test suite, boolean wait) { setPrinter(createPrinter()); /* * Make sure the original suite is unreachable after we have * created the new one, so GC can dispose terminated tests. */ CoreTestSuite coreTestSuite = new CoreTestSuite(suite, fFlags, fStep, null); XmlReportPrinter xmlReportPrinter = xmlReportsDirectory != null ? new XmlReportPrinter(coreTestSuite) : null; TestResult result = super.doRun(coreTestSuite, wait); if (xmlReportPrinter != null) { System.out.print("Printing XML Reports... "); xmlReportPrinter.setResults(result); int numFiles = xmlReportPrinter.generateReports(xmlReportsDirectory); System.out.println(numFiles + " files written."); } return result; } /** * Prints a help screen on the console. */ private void showHelp() { System.out.println("Usage: run-core-tests [OPTION]... [TEST]..."); System.out.println(); System.out.println("Where each TEST is a class name, optionally followed"); System.out.println("by \"#\" and a method name, and each OPTION is one of"); System.out.println("the following:"); System.out.println(); System.out.println(" --include-all"); System.out.println(" --exclude-all"); System.out.println(" --include-android-only"); System.out.println(" --exclude-android-only"); System.out.println(" --include-broken-tests"); System.out.println(" --exclude-broken-tests"); System.out.println(" --include-known-failures"); System.out.println(" --exclude-known-failures"); System.out.println(" --include-normal-tests"); System.out.println(" --exclude-normal-tests"); System.out.println(" --include-side-effects"); System.out.println(" --exclude-side-effects"); System.out.println(); System.out.println(" --known-failures-must-fail"); System.out.println(" --known-failures-must-pass"); System.out.println(" --timeout <seconds>"); // System.out.println(" --find-side-effect <test>"); System.out.println(" --isolate-all"); System.out.println(" --isolate-none"); System.out.println(" --verbose"); System.out.println(" --xml-reports-directory <path>"); System.out.println(" --help"); System.out.println(); System.out.println("Default parameters are:"); System.out.println(); if (IS_DALVIK) { System.out.println(" --include-android-only"); System.out.println(" --exclude-broken-tests"); System.out.println(" --include-known-failures"); System.out.println(" --include-normal-tests"); System.out.println(" --include-side-effects"); System.out.println(" --known-failures-must-fail"); } else { System.out.println(" --exclude-android-only"); System.out.println(" --exclude-broken-tests"); System.out.println(" --include-known-failures"); System.out.println(" --include-normal-tests"); System.out.println(" --include-side-effects"); System.out.println(" --known-failures-must-pass"); } System.out.println(); } /** * Tries to create a Test instance from the given strings. The strings might * either specify a class only or a class plus a method name, separated by * a "#". */ private Test createTest(List<String> testCases) throws Exception { TestSuite result = new TestSuite(); for (String testCase : testCases) { int p = testCase.indexOf("#"); if (p != -1) { String testName = testCase.substring(p + 1); testCase = testCase.substring(0, p); result.addTest(TestSuite.createTest(Class.forName(testCase), testName)); } else { result.addTest(getTest(testCase)); } } return result; } @Override protected TestResult start(String args[]) throws Exception { List<String> testNames = new ArrayList<String>(); // String victimName = null; boolean wait = false; if (IS_DALVIK) { fFlags = DEFAULT_FLAGS_DALVIK; } else { fFlags = DEFAULT_FLAGS_NON_DALVIK; } for (int i= 0; i < args.length; i++) { if (args[i].startsWith("--")) { if (args[i].equals("--wait")) { wait = true; } else if (args[i].equals("--include-all")) { fFlags = fFlags | CoreTestSuite.RUN_ALL_TESTS; } else if (args[i].equals("--exclude-all")) { fFlags = fFlags & ~CoreTestSuite.RUN_ALL_TESTS; } else if (args[i].equals("--include-android-only")) { fFlags = fFlags | CoreTestSuite.RUN_ANDROID_ONLY; } else if (args[i].equals("--exclude-android-only")) { fFlags = fFlags & ~CoreTestSuite.RUN_ANDROID_ONLY; } else if (args[i].equals("--include-broken-tests")) { fFlags = fFlags | CoreTestSuite.RUN_BROKEN_TESTS; } else if (args[i].equals("--exclude-broken-tests")) { fFlags = fFlags & ~CoreTestSuite.RUN_BROKEN_TESTS; } else if (args[i].equals("--include-known-failures")) { fFlags = fFlags | CoreTestSuite.RUN_KNOWN_FAILURES; } else if (args[i].equals("--exclude-known-failures")) { fFlags = fFlags & ~CoreTestSuite.RUN_KNOWN_FAILURES; } else if (args[i].equals("--include-normal-tests")) { fFlags = fFlags | CoreTestSuite.RUN_NORMAL_TESTS; } else if (args[i].equals("--exclude-normal-tests")) { fFlags = fFlags & ~CoreTestSuite.RUN_NORMAL_TESTS; } else if (args[i].equals("--include-side-effects")) { fFlags = fFlags | CoreTestSuite.RUN_SIDE_EFFECTS; } else if (args[i].equals("--exclude-side-effects")) { fFlags = fFlags & ~CoreTestSuite.RUN_SIDE_EFFECTS; } else if (args[i].equals("--known-failures-must-fail")) { fFlags = fFlags | CoreTestSuite.INVERT_KNOWN_FAILURES; } else if (args[i].equals("--known-failures-must-pass")) { fFlags = fFlags & ~CoreTestSuite.INVERT_KNOWN_FAILURES; } else if (args[i].equals("--timeout")) { fTimeout = Integer.parseInt(args[++i]); } else if (args[i].equals("--reverse")) { fFlags = fFlags | CoreTestSuite.REVERSE; } else if (args[i].equals("--step")) { fStep = Integer.parseInt(args[++i]); } else if (args[i].equals("--isolate-all")) { fFlags = (fFlags | CoreTestSuite.ISOLATE_ALL) & ~CoreTestSuite.ISOLATE_NONE; } else if (args[i].equals("--isolate-none")) { fFlags = (fFlags | CoreTestSuite.ISOLATE_NONE) & ~CoreTestSuite.ISOLATE_ALL; } else if (args[i].equals("--verbose")) { fFlags = fFlags | CoreTestSuite.VERBOSE; // } else if (args[i].equals("--find-side-effect")) { // victimName = args[++i]; } else if (args[i].equals("--dry-run")) { fFlags = fFlags | CoreTestSuite.DRY_RUN; } else if (args[i].equals("--xml-reports-directory")) { xmlReportsDirectory = args[++i]; } else if (args[i].equals("--help")) { showHelp(); System.exit(1); } else { unknownArgument(args[i]); } } else if (args[i].startsWith("-")) { unknownArgument(args[i]); } else { testNames.add(args[i]); } } if (IS_DALVIK) { System.out.println("Using Dalvik VM version " + System.getProperty("java.vm.version")); } else { System.out.println("Using Java VM version " + System.getProperty("java.version")); } System.out.println(); try { return doRun(createTest(testNames), wait); } catch(Exception e) { e.printStackTrace(); throw new Exception("Could not create and run test suite: " + e); } } private static void unknownArgument(String arg) { System.err.println("Unknown argument " + arg + ", try --help"); System.exit(1); } }