Commit 54b9408f authored by phoglund's avatar phoglund Committed by Commit bot

Revert of [Android] JUnit runner + gyp changes. (patchset #15 id:280001 of...

Revert of [Android] JUnit runner + gyp changes. (patchset #15 id:280001 of https://codereview.chromium.org/574433003/)

Reason for revert:
Speculative revert: Android test started flaking a ton after this landed. Affected targets androidwebview_instrumentation_tests, chromeshell_instrumentation_tests, contentshell_instrumentation_tests. This CL seems the most likely in the blamelist of https://build.chromium.org/p/chromium.linux/builders/Android%20Tests/builds/15905.

Original issue's description:
> [Android] JUnit runner + gyp changes.
>
> This adds Java code for running junit tests, as well as gyp targets for
> both runnable and non-runnable host-side JARs.
>
> BUG=316383
>
> Committed: https://crrev.com/2e56d4508e33de5fc60bbbb41c5a5d5534e88174
> Cr-Commit-Position: refs/heads/master@{#296340}

TBR=cjhopman@chromium.org,nyquist@chromium.org,aurimas@chromium.org,jbudorick@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=316383

Review URL: https://codereview.chromium.org/597123002

Cr-Commit-Position: refs/heads/master@{#296384}
parent 23c20f9e
......@@ -781,7 +781,6 @@
'../sandbox/sandbox.gyp:sandbox_linux_unittests_stripped',
'../sql/sql.gyp:sql_unittests',
'../sync/sync.gyp:sync_unit_tests',
'../testing/android/junit/junit_test.gyp:junit_unit_tests',
'../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
'../third_party/WebKit/public/all.gyp:*',
'../tools/android/android_tools.gyp:android_tools',
......
......@@ -12,8 +12,7 @@ import sys
from util import build_utils
from util import md5_check
def Jar(class_files, classes_dir, jar_path, manifest_file=None):
def Jar(class_files, classes_dir, jar_path):
jar_path = os.path.abspath(jar_path)
# The paths of the files in the jar will be the same as they are passed in to
......@@ -21,11 +20,7 @@ def Jar(class_files, classes_dir, jar_path, manifest_file=None):
# options.classes_dir so the .class file paths in the jar are correct.
jar_cwd = classes_dir
class_files_rel = [os.path.relpath(f, jar_cwd) for f in class_files]
jar_cmd = ['jar', 'cf0', jar_path]
if manifest_file:
jar_cmd[1] += 'm'
jar_cmd.append(os.path.abspath(manifest_file))
jar_cmd.extend(class_files_rel)
jar_cmd = ['jar', 'cf0', jar_path] + class_files_rel
record_path = '%s.md5.stamp' % jar_path
md5_check.CallAndRecordIfStale(
......@@ -39,14 +34,13 @@ def Jar(class_files, classes_dir, jar_path, manifest_file=None):
build_utils.Touch(jar_path, fail_if_missing=True)
def JarDirectory(classes_dir, excluded_classes, jar_path, manifest_file=None):
def JarDirectory(classes_dir, excluded_classes, jar_path):
class_files = build_utils.FindInDirectory(classes_dir, '*.class')
for exclude in excluded_classes:
class_files = filter(
lambda f: not fnmatch.fnmatch(f, exclude), class_files)
Jar(class_files, classes_dir, jar_path, manifest_file=manifest_file)
Jar(class_files, classes_dir, jar_path)
def main():
parser = optparse.OptionParser()
......@@ -58,12 +52,8 @@ def main():
options, _ = parser.parse_args()
if options.excluded_classes:
excluded_classes = build_utils.ParseGypList(options.excluded_classes)
else:
excluded_classes = []
JarDirectory(options.classes_dir,
excluded_classes,
build_utils.ParseGypList(options.excluded_classes),
options.jar_path)
if options.stamp:
......
......@@ -10,7 +10,6 @@ import os
import shutil
import re
import sys
import textwrap
from util import build_utils
from util import md5_check
......@@ -100,43 +99,6 @@ def DoJavac(
input_strings=javac_cmd)
_MAX_MANIFEST_LINE_LEN = 72
def CreateManifest(manifest_path, classpath, main_class=None):
"""Creates a manifest file with the given parameters.
This generates a manifest file that compiles with the spec found at
http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Manifest
Args:
manifest_path: The path to the manifest file that should be created.
classpath: The JAR files that should be listed on the manifest file's
classpath.
main_class: If present, the class containing the main() function.
"""
output = ['Manifest-Version: 1.0']
if main_class:
output.append('Main-Class: %s' % main_class)
if classpath:
sanitized_paths = []
for path in classpath:
sanitized_paths.append(os.path.basename(path.strip('"')))
output.append('Class-Path: %s' % ' '.join(sanitized_paths))
output.append('Created-By: ')
output.append('')
wrapper = textwrap.TextWrapper(break_long_words=True,
drop_whitespace=False,
subsequent_indent=' ',
width=_MAX_MANIFEST_LINE_LEN - 2)
output = '\r\n'.join(w for l in output for w in wrapper.wrap(l))
with open(manifest_path, 'w') as f:
f.write(output)
def main(argv):
colorama.init()
......@@ -177,17 +139,11 @@ def main(argv):
'--classes-dir',
help='Directory for compiled .class files.')
parser.add_option('--jar-path', help='Jar output path.')
parser.add_option(
'--main-class',
help='The class containing the main method.')
parser.add_option('--stamp', help='Path to touch on success.')
options, args = parser.parse_args(argv)
if options.main_class and not options.jar_path:
parser.error('--main-class requires --jar-path')
classpath = []
for arg in options.classpath:
classpath += build_utils.ParseGypList(arg)
......@@ -229,16 +185,9 @@ def main(argv):
java_files)
if options.jar_path:
if options.main_class:
manifest_file = os.path.join(temp_dir, 'manifest')
CreateManifest(manifest_file, classpath,
options.main_class)
else:
manifest_file = None
jar.JarDirectory(classes_dir,
build_utils.ParseGypList(options.jar_excluded_classes),
options.jar_path,
manifest_file=manifest_file)
options.jar_path)
if options.classes_dir:
# Delete the old classes directory. This ensures that all .class files in
......
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file is meant to be included into a target to provide a rule to build
# a JAR file for use on a host in a consistent manner.
#
# To use this, create a gyp target with the following form:
# {
# 'target_name': 'my_jar',
# 'type': 'none',
# 'variables': {
# 'src_paths': [
# 'path/to/directory',
# 'path/to/other/directory',
# 'path/to/individual_file.java',
# ...
# ],
# },
# 'includes': [ 'path/to/this/gypi/file' ],
# }
#
# Required variables:
# src_paths - A list of all paths containing java files that should be
# included in the jar. Paths can be either directories or files.
# Optional/automatic variables:
# excluded_src_paths - A list of all paths that should be excluded from
# the jar.
# generated_src_dirs - Directories containing additional .java files
# generated at build time.
# input_jars_paths - A list of paths to the jars that should be included
# in the classpath.
# main_class - The class containing the main() function that should be called
# when running the jar file.
# jar_excluded_classes - A list of .class files that should be excluded
# from the jar.
{
'dependencies': [
'<(DEPTH)/build/android/setup.gyp:build_output_dirs',
],
'variables': {
'classes_dir': '<(intermediate_dir)/classes',
'excluded_src_paths': [],
'generated_src_dirs': [],
'input_jars_paths': [],
'intermediate_dir': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)',
'jar_dir': '<(PRODUCT_DIR)/lib.java',
'jar_excluded_classes': [],
'jar_name': '<(_target_name).jar',
'jar_path': '<(jar_dir)/<(jar_name)',
'main_class%': '',
'stamp': '<(intermediate_dir)/jar.stamp',
},
'all_dependent_settings': {
'variables': {
'input_jars_paths': ['<(jar_path)']
},
},
'actions': [
{
'action_name': 'javac_<(_target_name)',
'message': 'Compiling <(_target_name) java sources',
'variables': {
'extra_options': [],
'java_sources': [ '<!@(find <@(src_paths) -name "*.java")' ],
'conditions': [
['"<(excluded_src_paths)" != ""', {
'java_sources!': ['<!@(find <@(excluded_src_paths) -name "*.java")']
}],
['"<(jar_excluded_classes)" != ""', {
'extra_options': ['--excluded-classes=<(jar_excluded_classes)']
}],
['">(main_class)" != ""', {
'extra_options': ['--main-class=>(main_class)']
}]
],
},
'inputs': [
'<(DEPTH)/build/android/gyp/util/build_utils.py',
'<(DEPTH)/build/android/gyp/javac.py',
'^@(java_sources)',
'>@(input_jars_paths)',
],
'outputs': [
'<(jar_path)',
'<(stamp)',
],
'action': [
'python', '<(DEPTH)/build/android/gyp/javac.py',
'--classpath=>(input_jars_paths)',
'--src-gendirs=>(generated_src_dirs)',
'--chromium-code=<(chromium_code)',
'--stamp=<(stamp)',
'--jar-path=<(jar_path)',
'<@(extra_options)',
'^@(java_sources)',
],
},
]
}
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file is meant to be included into a target to provide a rule to
# copy a prebuilt JAR for use on a host to the output directory.
#
# To use this, create a gyp target with the following form:
# {
# 'target_name': 'my_prebuilt_jar',
# 'type': 'none',
# 'variables': {
# 'jar_path': 'path/to/prebuilt.jar',
# },
# 'includes': [ 'path/to/this/gypi/file' ],
# }
#
# Required variables:
# jar_path - The path to the prebuilt jar.
{
'dependencies': [
],
'variables': {
'dest_path': '<(PRODUCT_DIR)/lib.java/<(_target_name).jar',
'src_path': '<(jar_path)',
},
'all_dependent_settings': {
'variables': {
'input_jars_paths': [
'<(dest_path)',
]
},
},
'actions': [
{
'action_name': 'copy_prebuilt_jar',
'message': 'Copy <(src_path) to <(dest_path)',
'inputs': [
'<(src_path)',
],
'outputs': [
'<(dest_path)',
],
'action': [
'python', '<(DEPTH)/build/cp.py', '<(src_path)', '<(dest_path)',
],
}
]
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.runner.Computer;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.Filterable;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
/**
* A Computer that logs the start and end of test cases googletest-style.
*/
public class GtestComputer extends Computer {
private final GtestLogger mLogger;
public GtestComputer(GtestLogger logger) {
mLogger = logger;
}
/**
* A wrapping Runner that logs the start and end of each test case.
*/
private class GtestSuiteRunner extends Runner implements Filterable {
private final Runner mRunner;
public GtestSuiteRunner(Runner contained) {
mRunner = contained;
}
public Description getDescription() {
return mRunner.getDescription();
}
public void run(RunNotifier notifier) {
long startTimeMillis = System.currentTimeMillis();
mLogger.testCaseStarted(mRunner.getDescription(),
mRunner.getDescription().testCount());
mRunner.run(notifier);
mLogger.testCaseFinished(mRunner.getDescription(),
mRunner.getDescription().testCount(),
System.currentTimeMillis() - startTimeMillis);
}
public void filter(Filter filter) throws NoTestsRemainException {
if (mRunner instanceof Filterable) {
((Filterable)mRunner).filter(filter);
}
}
}
/**
* Returns a suite of unit tests with each class runner wrapped by a
* GtestSuiteRunner.
*/
@Override
public Runner getSuite(final RunnerBuilder builder, Class<?>[] classes)
throws InitializationError {
return super.getSuite(
new RunnerBuilder() {
@Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
return new GtestSuiteRunner(builder.runnerForClass(testClass));
}
}, classes);
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Filters tests based on a googletest-style filter string.
*/
class GtestFilter extends Filter {
private final String mFilterString;
private final Set<Pattern> mPositiveRegexes;
private final Set<Pattern> mNegativeRegexes;
private static final Pattern ASTERISK = Pattern.compile("\\*");
private static final Pattern COLON = Pattern.compile(":");
private static final Pattern DASH = Pattern.compile("-");
private static final Pattern PERIOD = Pattern.compile("\\.");
/**
* Creates the filter and converts the provided googletest-style filter
* string into positive and negative regexes.
*/
public GtestFilter(String filterString) {
mFilterString = filterString;
mPositiveRegexes = new HashSet<Pattern>();
mNegativeRegexes = new HashSet<Pattern>();
String[] filterStrings = COLON.split(filterString);
for (String f : filterStrings) {
if (f.isEmpty()) continue;
String sanitized = PERIOD.matcher(f).replaceAll("\\\\.");
sanitized = ASTERISK.matcher(sanitized).replaceAll(".*");
int negIndex = sanitized.indexOf('-');
if (negIndex == 0) {
mNegativeRegexes.add(Pattern.compile(sanitized.substring(1)));
} else if (negIndex != -1) {
String[] c = DASH.split(sanitized, 2);
mPositiveRegexes.add(Pattern.compile(c[0]));
mNegativeRegexes.add(Pattern.compile(c[1]));
} else {
mPositiveRegexes.add(Pattern.compile(sanitized));
}
}
}
/**
* Determines whether or not a test with the provided description should
* run based on the configured positive and negative regexes.
*
* A test should run if:
* - it's just a class, OR
* - it doesn't match any of the negative regexes, AND
* - either:
* - there are no configured positive regexes, OR
* - it matches at least one of the positive regexes.
*/
@Override
public boolean shouldRun(Description description) {
if (description.getMethodName() == null) return true;
String gtestName = description.getClassName() + "." + description.getMethodName();
for (Pattern p : mNegativeRegexes) {
if (p.matcher(gtestName).matches()) return false;
}
if (mPositiveRegexes.isEmpty()) return true;
for (Pattern p : mPositiveRegexes) {
if (p.matcher(gtestName).matches()) return true;
}
return false;
}
/**
* Returns a description of this filter.
*/
@Override
public String describe() {
return "gtest-filter: " + mFilterString;
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import java.util.HashSet;
import java.util.Set;
/** A JUnit RunListener that emulates GTest output to the extent that it can.
*/
public class GtestListener extends RunListener {
private Set<Description> mFailedTests;
private final GtestLogger mLogger;
private long mRunStartTimeMillis;
private long mTestStartTimeMillis;
private int mTestsPassed;
private boolean mCurrentTestPassed;
public GtestListener(GtestLogger logger) {
mLogger = logger;
}
/** Called before any tests run.
*/
@Override
public void testRunStarted(Description d) throws Exception {
mLogger.testRunStarted(d.testCount());
mRunStartTimeMillis = System.currentTimeMillis();
mTestsPassed = 0;
mFailedTests = new HashSet<Description>();
mCurrentTestPassed = true;
}
/** Called after all tests run.
*/
@Override
public void testRunFinished(Result r) throws Exception {
long elapsedTimeMillis = System.currentTimeMillis() - mRunStartTimeMillis;
mLogger.testRunFinished(mTestsPassed, mFailedTests, elapsedTimeMillis);
}
/** Called when a test is about to start.
*/
@Override
public void testStarted(Description d) throws Exception {
mCurrentTestPassed = true;
mLogger.testStarted(d);
mTestStartTimeMillis = System.currentTimeMillis();
}
/** Called when a test has just finished.
*/
@Override
public void testFinished(Description d) throws Exception {
long testElapsedTimeMillis = System.currentTimeMillis() - mTestStartTimeMillis;
mLogger.testFinished(d, mCurrentTestPassed, testElapsedTimeMillis);
if (mCurrentTestPassed) {
++mTestsPassed;
} else {
mFailedTests.add(d);
}
}
/** Called when a test fails.
*/
@Override
public void testFailure(Failure f) throws Exception {
mCurrentTestPassed = false;
mLogger.testFailed(f);
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import java.io.PrintStream;
import java.util.Set;
/**
* Formats and logs test status information in googletest-style.
*/
public class GtestLogger {
private final PrintStream mOutputStream;
public GtestLogger(PrintStream outputStream) {
mOutputStream = outputStream;
}
/**
* Logs the start of an individual test.
*/
public void testStarted(Description test) {
mOutputStream.format("[ RUN ] %s.%s", test.getClassName(), test.getMethodName());
mOutputStream.println();
}
/**
* Logs a test failure.
*/
public void testFailed(Failure f) {
if (f.getException() != null) {
f.getException().printStackTrace(mOutputStream);
}
}
/**
* Logs the end of an individual test.
*/
public void testFinished(Description test, boolean passed, long elapsedTimeMillis) {
if (passed) {
mOutputStream.format("[ OK ] %s.%s (%d ms)",
test.getClassName(), test.getMethodName(), elapsedTimeMillis);
} else {
mOutputStream.format("[ FAILED ] %s.%s (%d ms)",
test.getClassName(), test.getMethodName(), elapsedTimeMillis);
}
mOutputStream.println();
}
/**
* Logs the start of a test case.
*/
public void testCaseStarted(Description test, int testCount) {
mOutputStream.format("[----------] Run %d test cases from %s", testCount,
test.getClassName());
mOutputStream.println();
}
/**
* Logs the end of a test case.
*/
public void testCaseFinished(Description test, int testCount,
long elapsedTimeMillis) {
mOutputStream.format("[----------] Run %d test cases from %s (%d ms)",
testCount, test.getClassName(), elapsedTimeMillis);
mOutputStream.println();
mOutputStream.println();
}
/**
* Logs the start of a test run.
*/
public void testRunStarted(int testCount) {
mOutputStream.format("[==========] Running %d tests.", testCount);
mOutputStream.println();
mOutputStream.println("[----------] Global test environment set-up.");
mOutputStream.println();
}
/**
* Logs the end of a test run.
*/
public void testRunFinished(int passedTestCount, Set<Description> failedTests,
long elapsedTimeMillis) {
int totalTestCount = passedTestCount + failedTests.size();
mOutputStream.println("[----------] Global test environment tear-down.");
mOutputStream.format("[==========] %d tests ran. (%d ms total)",
totalTestCount, elapsedTimeMillis);
mOutputStream.println();
mOutputStream.format("[ PASSED ] %d tests.", passedTestCount);
mOutputStream.println();
if (!failedTests.isEmpty()) {
mOutputStream.format("[ FAILED ] %d tests.", failedTests.size());
mOutputStream.println();
for (Description d : failedTests) {
mOutputStream.format("[ FAILED ] %s.%s", d.getClassName(), d.getMethodName());
mOutputStream.println();
}
mOutputStream.println();
}
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import java.util.HashSet;
import java.util.Set;
/**
* Parses command line arguments for JunitTestMain.
*/
public class JunitTestArgParser {
private final Set<String> mPackageFilters;
private final Set<Class<?>> mRunnerFilters;
private final Set<String> mGtestFilters;
public static JunitTestArgParser parse(String[] args) {
JunitTestArgParser parsed = new JunitTestArgParser();
for (int i = 0; i < args.length; ++i) {
if (args[i].startsWith("-")) {
String argName;
if (args[i].startsWith("-", 1)) {
argName = args[i].substring(2, args[i].length());
} else {
argName = args[i].substring(1, args[i].length());
}
try {
if ("package-filter".equals(argName)) {
// Read the command line argument after the flag.
parsed.addPackageFilter(args[++i]);
} else if ("runner-filter".equals(argName)) {
// Read the command line argument after the flag.
parsed.addRunnerFilter(Class.forName(args[++i]));
} else if ("gtest-filter".equals(argName)) {
// Read the command line argument after the flag.
parsed.addGtestFilter(args[++i]);
} else {
System.out.println("Ignoring flag: \"" + argName + "\"");
}
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("No value specified for argument \"" + argName + "\"");
System.exit(1);
} catch (ClassNotFoundException e) {
System.err.println("Class not found. (" + e.toString() + ")");
System.exit(1);
}
} else {
System.out.println("Ignoring argument: \"" + args[i] + "\"");
}
}
return parsed;
}
private JunitTestArgParser() {
mPackageFilters = new HashSet<String>();
mRunnerFilters = new HashSet<Class<?>>();
mGtestFilters = new HashSet<String>();
}
public Set<String> getPackageFilters() {
return mPackageFilters;
}
public Set<Class<?>> getRunnerFilters() {
return mRunnerFilters;
}
public Set<String> getGtestFilters() {
return mGtestFilters;
}
private void addPackageFilter(String packageFilter) {
mPackageFilters.add(packageFilter);
}
private void addRunnerFilter(Class<?> runnerFilter) {
mRunnerFilters.add(runnerFilter);
}
private void addGtestFilter(String gtestFilter) {
mGtestFilters.add(gtestFilter);
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
/**
* Runs tests based on JUnit from the classpath on the host JVM based on the
* provided filter configurations.
*/
public final class JunitTestMain {
private static final String CLASS_FILE_EXT = ".class";
private static final Pattern COLON = Pattern.compile(":");
private static final Pattern FORWARD_SLASH = Pattern.compile("/");
private JunitTestMain() {
}
/**
* Finds all classes on the class path annotated with RunWith.
*/
public static Class[] findClassesFromClasspath() {
String[] jarPaths = COLON.split(System.getProperty("java.class.path"));
LinkedList<Class> classes = new LinkedList<Class>();
for (String jp : jarPaths) {
try {
JarFile jf = new JarFile(jp);
for (Enumeration<JarEntry> eje = jf.entries(); eje.hasMoreElements();) {
JarEntry je = eje.nextElement();
String cn = je.getName();
if (!cn.endsWith(CLASS_FILE_EXT) || cn.indexOf('$') != -1) {
continue;
}
cn = cn.substring(0, cn.length() - CLASS_FILE_EXT.length());
cn = FORWARD_SLASH.matcher(cn).replaceAll(".");
Class<?> c = classOrNull(cn);
if (c != null && c.isAnnotationPresent(RunWith.class)) {
classes.push(c);
}
}
jf.close();
} catch (IOException e) {
System.err.println("Error while reading classes from " + jp);
}
}
return classes.toArray(new Class[classes.size()]);
}
private static Class<?> classOrNull(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
System.err.println("Class not found: " + className);
} catch (NoClassDefFoundError e) {
System.err.println("Class definition not found: " + className);
} catch (Exception e) {
System.err.println("Other exception while reading class: " + className);
}
return null;
}
public static void main(String[] args) {
JunitTestArgParser parser = JunitTestArgParser.parse(args);
JUnitCore core = new JUnitCore();
GtestLogger logger = new GtestLogger(System.out);
core.addListener(new GtestListener(logger));
Class[] classes = findClassesFromClasspath();
Request testRequest = Request.classes(new GtestComputer(logger), classes);
for (String packageFilter : parser.getPackageFilters()) {
testRequest = testRequest.filterWith(new PackageFilter(packageFilter));
}
for (Class<?> runnerFilter : parser.getRunnerFilters()) {
testRequest = testRequest.filterWith(new RunnerFilter(runnerFilter));
}
for (String gtestFilter : parser.getGtestFilters()) {
testRequest = testRequest.filterWith(new GtestFilter(gtestFilter));
}
System.exit(core.run(testRequest).wasSuccessful() ? 0 : 1);
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
/**
* Filters tests based on the package.
*/
class PackageFilter extends Filter {
private final String mFilterString;
/**
* Creates the filter.
*/
public PackageFilter(String filterString) {
mFilterString = filterString;
}
/**
* Determines whether or not a test with the provided description should
* run based on its package.
*/
@Override
public boolean shouldRun(Description description) {
return description.getTestClass().getPackage().getName().equals(mFilterString);
}
/**
* Returns a description of this filter.
*/
@Override
public String describe() {
return "package-filter: " + mFilterString;
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.manipulation.Filter;
/**
* Filters tests based on the Runner class annotating the test class.
*/
class RunnerFilter extends Filter {
private final Class<?> mRunnerClass;
/**
* Creates the filter.
*/
public RunnerFilter(Class<?> runnerClass) {
mRunnerClass = runnerClass;
}
/**
* Determines whether or not a test with the provided description should
* run based on the Runner class annotating the test class.
*/
@Override
public boolean shouldRun(Description description) {
Class<?> c = description.getTestClass();
return c != null && c.isAnnotationPresent(RunWith.class)
&& c.getAnnotation(RunWith.class).value() == mRunnerClass;
}
/**
* Returns a description of this filter.
*/
@Override
public String describe() {
return "runner-filter: " + mRunnerClass.getName();
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.manipulation.Filter;
import org.junit.runners.BlockJUnit4ClassRunner;
/**
* Unit tests for GtestFilter.
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class GtestFilterTest {
@Test
public void testDescription() {
Filter filterUnderTest = new GtestFilter("TestClass.*");
Assert.assertEquals("gtest-filter: TestClass.*", filterUnderTest.describe());
}
@Test
public void testNoFilter() {
Filter filterUnderTest = new GtestFilter("");
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
}
@Test
public void testPositiveFilterExplicit() {
Filter filterUnderTest = new GtestFilter("TestClass.testMethod");
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
}
@Test
public void testPositiveFilterClassRegex() {
Filter filterUnderTest = new GtestFilter("TestClass.*");
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
}
@Test
public void testNegativeFilterExplicit() {
Filter filterUnderTest = new GtestFilter("-TestClass.testMethod");
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
}
@Test
public void testNegativeFilterClassRegex() {
Filter filterUnderTest = new GtestFilter("-TestClass.*");
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
}
@Test
public void testPositiveAndNegativeFilter() {
Filter filterUnderTest = new GtestFilter("TestClass.*-TestClass.testMethod");
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
}
@Test
public void testMultiplePositiveFilters() {
Filter filterUnderTest = new GtestFilter(
"TestClass.otherTestMethod:OtherTestClass.otherTestMethod");
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "otherTestMethod")));
}
@Test
public void testMultipleFiltersPositiveAndNegative() {
Filter filterUnderTest = new GtestFilter("TestClass.*:-TestClass.testMethod");
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "testMethod")));
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription("TestClass", "otherTestMethod")));
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("OtherTestClass", "testMethod")));
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
/**
* Unit tests for GtestLogger.
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class GtestLoggerTest {
@Test
public void testTestStarted() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
loggerUnderTest.testStarted(
Description.createTestDescription(GtestLoggerTest.class, "testTestStarted"));
Assert.assertEquals(
"[ RUN ] org.chromium.testing.local.GtestLoggerTest.testTestStarted\n",
actual.toString());
}
@Test
public void testTestFinishedPassed() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
loggerUnderTest.testFinished(
Description.createTestDescription(GtestLoggerTest.class, "testTestFinishedPassed"),
true, 123);
Assert.assertEquals(
"[ OK ] org.chromium.testing.local.GtestLoggerTest.testTestFinishedPassed" +
" (123 ms)\n",
actual.toString());
}
@Test
public void testTestFinishedFailed() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
loggerUnderTest.testFinished(
Description.createTestDescription(GtestLoggerTest.class, "testTestFinishedPassed"),
false, 123);
Assert.assertEquals(
"[ FAILED ] org.chromium.testing.local.GtestLoggerTest.testTestFinishedPassed" +
" (123 ms)\n",
actual.toString());
}
@Test
public void testTestCaseStarted() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
loggerUnderTest.testCaseStarted(
Description.createSuiteDescription(GtestLoggerTest.class), 456);
Assert.assertEquals(
"[----------] Run 456 test cases from org.chromium.testing.local.GtestLoggerTest\n",
actual.toString());
}
@Test
public void testTestCaseFinished() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
loggerUnderTest.testCaseFinished(
Description.createSuiteDescription(GtestLoggerTest.class), 456, 123);
Assert.assertEquals(
"[----------] Run 456 test cases from org.chromium.testing.local.GtestLoggerTest" +
" (123 ms)\n\n",
actual.toString());
}
@Test
public void testTestRunStarted() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
loggerUnderTest.testRunStarted(1234);
Assert.assertEquals(
"[==========] Running 1234 tests.\n" +
"[----------] Global test environment set-up.\n\n",
actual.toString());
}
@Test
public void testTestRunFinishedNoFailures() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
loggerUnderTest.testRunFinished(1234, new HashSet<Description>(), 4321);
Assert.assertEquals(
"[----------] Global test environment tear-down.\n" +
"[==========] 1234 tests ran. (4321 ms total)\n" +
"[ PASSED ] 1234 tests.\n",
actual.toString());
}
@Test
public void testTestRunFinishedWithFailures() {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
Set<Description> failures = new TreeSet<Description>(new DescriptionComparator());
failures.add(Description.createTestDescription(
"GtestLoggerTest", "testTestRunFinishedNoFailures"));
failures.add(Description.createTestDescription(
"GtestLoggerTest", "testTestRunFinishedWithFailures"));
loggerUnderTest.testRunFinished(1232, failures, 4312);
Assert.assertEquals(
"[----------] Global test environment tear-down.\n" +
"[==========] 1234 tests ran. (4312 ms total)\n" +
"[ PASSED ] 1232 tests.\n" +
"[ FAILED ] 2 tests.\n" +
"[ FAILED ] GtestLoggerTest.testTestRunFinishedNoFailures\n" +
"[ FAILED ] GtestLoggerTest.testTestRunFinishedWithFailures\n" +
"\n",
actual.toString());
}
private static class DescriptionComparator implements Comparator<Description>, Serializable {
@Override
public int compare(Description o1, Description o2) {
return toGtestStyleString(o1).compareTo(toGtestStyleString(o2));
}
private static String toGtestStyleString(Description d) {
return d.getClassName() + "." + d.getMethodName();
}
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.manipulation.Filter;
import org.junit.runners.BlockJUnit4ClassRunner;
/**
* Unit tests for PackageFilter.
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class PackageFilterTest {
@Test
public void testDescription() {
Filter filterUnderTest = new PackageFilter("test.package");
Assert.assertEquals("package-filter: test.package", filterUnderTest.describe());
}
@Test
public void testNoFilter() {
Filter filterUnderTest = new PackageFilter("");
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription(PackageFilterTest.class, "testNoFilter")));
}
@Test
public void testFilterHit() {
Filter filterUnderTest = new PackageFilter("org.chromium.testing.local");
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription(PackageFilterTest.class, "testWithFilter")));
}
@Test
public void testFilterMiss() {
Filter filterUnderTest = new PackageFilter("org.chromium.native_test");
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription(PackageFilterTest.class, "testWithFilter")));
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.testing.local;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.manipulation.Filter;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Suite;
/**
* Unit tests for RunnerFilter.
*/
@RunWith(BlockJUnit4ClassRunner.class)
public class RunnerFilterTest {
@Test
public void testDescription() {
Filter filterUnderTest = new RunnerFilter(BlockJUnit4ClassRunner.class);
Assert.assertEquals("runner-filter: org.junit.runners.BlockJUnit4ClassRunner",
filterUnderTest.describe());
}
@Test
public void testNoFilter() {
Filter filterUnderTest = new RunnerFilter(null);
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription(RunnerFilterTest.class, "testNoFilter")));
}
@Test
public void testFilterHit() {
Filter filterUnderTest = new RunnerFilter(BlockJUnit4ClassRunner.class);
Assert.assertTrue(filterUnderTest.shouldRun(
Description.createTestDescription(RunnerFilterTest.class, "testFilterHit")));
}
@Test
public void testFilterMiss() {
Filter filterUnderTest = new RunnerFilter(Suite.class);
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription(RunnerFilterTest.class, "testFilterMiss")));
}
@Test
public void testClassNotFound() {
Filter filterUnderTest = new RunnerFilter(BlockJUnit4ClassRunner.class);
Assert.assertFalse(filterUnderTest.shouldRun(
Description.createTestDescription("FakeTestClass", "fakeTestMethod")));
}
}
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'targets': [
{
'target_name': 'junit_test_support',
'type': 'none',
'dependencies': [
'../../../third_party/junit/junit.gyp:junit_jar',
],
'variables': {
'src_paths': [
'java/src',
],
},
'includes': [
'../../../build/host_jar.gypi',
],
},
{
'target_name': 'junit_unit_tests',
'type': 'none',
'dependencies': [
'junit_test_support',
],
'variables': {
'main_class': 'org.chromium.testing.local.JunitTestMain',
'src_paths': [
'javatests/src',
],
},
'includes': [
'../../../build/host_jar.gypi',
],
},
],
}
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'targets': [
{
'target_name': 'hamcrest_jar',
'type': 'none',
'variables': {
'jar_path': 'src/lib/hamcrest-core-1.3.jar',
},
'includes': [
'../../build/host_prebuilt_jar.gypi',
]
},
{
'target_name': 'junit_jar',
'type': 'none',
'dependencies': [
'hamcrest_jar',
],
'variables': {
'src_paths': [ 'src/src/main/java' ],
},
'includes': [
'../../build/host_jar.gypi',
],
},
],
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment