| Index: base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java
|
| diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java b/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c100a26f2ff1568dce136dc388c61b6802f348ea
|
| --- /dev/null
|
| +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java
|
| @@ -0,0 +1,271 @@
|
| +// Copyright 2015 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.base.test;
|
| +
|
| +import android.app.Instrumentation;
|
| +import android.content.Context;
|
| +import android.os.Bundle;
|
| +import android.os.SystemClock;
|
| +
|
| +import junit.framework.AssertionFailedError;
|
| +import junit.framework.TestCase;
|
| +import junit.framework.TestResult;
|
| +
|
| +import org.chromium.base.Log;
|
| +import org.chromium.base.test.util.CommandLineFlags;
|
| +import org.chromium.base.test.util.parameters.BaseParameter;
|
| +import org.chromium.base.test.util.parameters.Parameter;
|
| +import org.chromium.base.test.util.parameters.Parameterizable;
|
| +import org.chromium.base.test.util.parameters.ParameterizedTest;
|
| +
|
| +import java.io.PrintWriter;
|
| +import java.io.StringWriter;
|
| +import java.util.ArrayList;
|
| +import java.util.Arrays;
|
| +import java.util.List;
|
| +
|
| +/**
|
| + * A test result that can skip tests.
|
| + */
|
| +public class BaseTestResult extends TestResult {
|
| + private static final String TAG = "cr.base.test";
|
| +
|
| + private static final int SLEEP_INTERVAL = 50; // milliseconds
|
| + private static final int WAIT_DURATION = 5000; // milliseconds
|
| +
|
| + private Instrumentation mInstrumentation;
|
| + private final List<SkipCheck> mSkipChecks;
|
| +
|
| + /**
|
| + * Creates an instance of BaseTestResult.
|
| + */
|
| + public BaseTestResult(Instrumentation instrumentation) {
|
| + mSkipChecks = new ArrayList<SkipCheck>();
|
| + mInstrumentation = instrumentation;
|
| + }
|
| +
|
| + /**
|
| + * An interface for classes that check whether a test case should be skipped.
|
| + */
|
| + public interface SkipCheck {
|
| + /**
|
| + *
|
| + * Checks whether the given test case should be skipped.
|
| + *
|
| + * @param testCase The test case to check.
|
| + * @return Whether the test case should be skipped.
|
| + */
|
| + public boolean shouldSkip(TestCase testCase);
|
| + }
|
| +
|
| + /**
|
| + * Adds a check for whether a test should run.
|
| + *
|
| + * @param skipCheck The check to add.
|
| + */
|
| + public void addSkipCheck(SkipCheck skipCheck) {
|
| + mSkipChecks.add(skipCheck);
|
| + }
|
| +
|
| + protected boolean shouldSkip(final TestCase test) {
|
| + for (SkipCheck s : mSkipChecks) {
|
| + if (s.shouldSkip(test)) return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + @Override
|
| + protected void run(final TestCase test) {
|
| + if (shouldSkip(test)) {
|
| + startTest(test);
|
| +
|
| + Bundle skipResult = new Bundle();
|
| + skipResult.putString("class", test.getClass().getName());
|
| + skipResult.putString("test", test.getName());
|
| + skipResult.putBoolean("test_skipped", true);
|
| + mInstrumentation.sendStatus(0, skipResult);
|
| +
|
| + endTest(test);
|
| + } else {
|
| + try {
|
| + CommandLineFlags.setUp(
|
| + getTargetContext(),
|
| + test.getClass().getMethod(test.getName()));
|
| + } catch (NoSuchMethodException e) {
|
| + Log.e(TAG, "Unable to set up CommandLineFlags", e);
|
| + }
|
| +
|
| + if (test instanceof Parameterizable) {
|
| + try {
|
| + runParameterized(test);
|
| + } catch (ThreadDeath e) {
|
| + Log.e(TAG, "Parameterized test run failed: %s", e);
|
| + }
|
| + } else {
|
| + super.run(test);
|
| + }
|
| + }
|
| + }
|
| +
|
| + @SuppressWarnings("unchecked")
|
| + private <T extends TestCase & Parameterizable> void runParameterized(final TestCase test)
|
| + throws ThreadDeath {
|
| + final T testCase = (T) test;
|
| +
|
| + Parameter.Reader parameterReader = new Parameter.Reader(test);
|
| + testCase.setParameterReader(parameterReader);
|
| + List<ParameterizedTest> parameterizedTests = parameterReader.getParameterizedTests();
|
| + if (!parameterizedTests.isEmpty()) {
|
| +
|
| + // Start and prepare test.
|
| + startTest(testCase);
|
| + List<ParameterError> errors = new ArrayList<>();
|
| + List<ParameterError> failures = new ArrayList<>();
|
| + List<BaseParameter> availableParameters = new ArrayList<>();
|
| + availableParameters.addAll(testCase.getAvailableParameters());
|
| +
|
| + // Run the actual tests.
|
| + for (final ParameterizedTest parameterizedTest : parameterizedTests) {
|
| + parameterReader.setCurrentParameterizedTest(parameterizedTest);
|
| + try {
|
| + setUpParameters(testCase, availableParameters);
|
| + testCase.runBare();
|
| + tearDownParameters(testCase, availableParameters);
|
| + } catch (AssertionFailedError e) {
|
| + failures.add(new ParameterError(e, parameterizedTest));
|
| + } catch (ThreadDeath e) {
|
| + throw e;
|
| + } catch (Throwable e) {
|
| + errors.add(new ParameterError(e, parameterizedTest));
|
| + }
|
| + }
|
| +
|
| + // Generate failures and errors.
|
| + if (!failures.isEmpty()) {
|
| + addFailure(test, new ParameterizedTestFailure(failures));
|
| + }
|
| + if (!errors.isEmpty()) {
|
| + addError(test, new ParameterizedTestError(errors));
|
| + }
|
| +
|
| + // End test.
|
| + endTest(testCase);
|
| + } else {
|
| + super.run(test);
|
| + }
|
| + }
|
| +
|
| + private <T extends TestCase & Parameterizable> void setUpParameters(final T test,
|
| + List<BaseParameter> availableParameters) throws Exception {
|
| + Parameter.Reader parameterReader = new Parameter.Reader(test);
|
| + for (BaseParameter parameter : availableParameters) {
|
| + if (parameterReader.getParameter(parameter.getTag()) != null) {
|
| + parameter.setUp();
|
| + }
|
| + }
|
| + }
|
| +
|
| + private <T extends TestCase & Parameterizable> void tearDownParameters(final T test,
|
| + List<BaseParameter> availableParameters) throws Exception {
|
| + Parameter.Reader parameterReader = new Parameter.Reader(test);
|
| + for (BaseParameter parameter : availableParameters) {
|
| + if (parameterReader.getParameter(parameter.getTag()) != null) {
|
| + parameter.tearDown();
|
| + }
|
| + }
|
| + }
|
| +
|
| + private static class ParameterError {
|
| + private Throwable mThrowable;
|
| + private ParameterizedTest mParameterizedTest;
|
| +
|
| + public ParameterError(Throwable throwable, ParameterizedTest parameterizedTest) {
|
| + mThrowable = throwable;
|
| + mParameterizedTest = parameterizedTest;
|
| + }
|
| +
|
| + private Throwable getThrowable() {
|
| + return mThrowable;
|
| + }
|
| +
|
| + private ParameterizedTest getParameterizedTest() {
|
| + return mParameterizedTest;
|
| + }
|
| + }
|
| +
|
| + private static class ParameterizedTestFailure extends AssertionFailedError {
|
| + public ParameterizedTestFailure(List<ParameterError> failures) {
|
| + super(new ParameterizedTestError(failures).toString());
|
| + }
|
| + }
|
| +
|
| + private static class ParameterizedTestError extends Exception {
|
| + public List<ParameterError> mErrors;
|
| +
|
| + public ParameterizedTestError(List<ParameterError> errors) {
|
| + mErrors = errors;
|
| + }
|
| +
|
| + @Override
|
| + public String toString() {
|
| + StringBuffer buffer = new StringBuffer('\n');
|
| + for (ParameterError error : mErrors) {
|
| + List<Parameter> parameters =
|
| + Arrays.asList(error.getParameterizedTest().parameters());
|
| + if (!parameters.isEmpty()) {
|
| + StringBuffer parametersString = new StringBuffer();
|
| + for (int i = 0; i < parameters.size(); i++) {
|
| + parametersString.append(parameters.get(i).tag());
|
| + if (i != parameters.size() - 1) {
|
| + parametersString.append(',');
|
| + }
|
| + }
|
| + buffer.append(String.format("%s (with parameters %s)%n",
|
| + error.getThrowable().toString(), parametersString.toString()));
|
| + } else {
|
| + buffer.append(String.format("%s (with no parameters)%n",
|
| + error.getThrowable().toString()));
|
| + }
|
| + buffer.append(trace(error) + '\n');
|
| + }
|
| + return buffer.toString();
|
| + }
|
| +
|
| + /**
|
| + * @return the trace without the error message
|
| + */
|
| + private String trace(ParameterError error) {
|
| + StringWriter stringWriter = new StringWriter();
|
| + PrintWriter writer = new PrintWriter(stringWriter);
|
| + error.getThrowable().printStackTrace(writer);
|
| + StringBuffer buffer = stringWriter.getBuffer();
|
| + return buffer.toString().substring(buffer.toString().indexOf('\n') + 1);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Gets the target context.
|
| + *
|
| + * On older versions of Android, getTargetContext() may initially return null, so we have to
|
| + * wait for it to become available.
|
| + *
|
| + * @return The target {@link android.content.Context} if available; null otherwise.
|
| + */
|
| + public Context getTargetContext() {
|
| + Context targetContext = mInstrumentation.getTargetContext();
|
| + try {
|
| + long startTime = SystemClock.uptimeMillis();
|
| + // TODO(jbudorick): Convert this to CriteriaHelper once that moves to base/.
|
| + while (targetContext == null
|
| + && SystemClock.uptimeMillis() - startTime < WAIT_DURATION) {
|
| + Thread.sleep(SLEEP_INTERVAL);
|
| + targetContext = mInstrumentation.getTargetContext();
|
| + }
|
| + } catch (InterruptedException e) {
|
| + Log.e(TAG, "Interrupted while attempting to initialize the command line.");
|
| + }
|
| + return targetContext;
|
| + }
|
| +}
|
|
|