blob: aa62ca4be97350546532aa0ec150f95ef0991c60 [file] [log] [blame]
/*
* 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);
}
}