Merge "Fix battery/temperature check when disabled" into pi-dev
diff --git a/src/com/android/tradefed/build/BuildInfo.java b/src/com/android/tradefed/build/BuildInfo.java
index 168f256..5aa54db 100644
--- a/src/com/android/tradefed/build/BuildInfo.java
+++ b/src/com/android/tradefed/build/BuildInfo.java
@@ -258,6 +258,12 @@
return null;
}
+ /** {@inheritDoc} */
+ @Override
+ public VersionedFile getVersionedFile(String name) {
+ return mVersionedFileMap.get(name);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/com/android/tradefed/build/IBuildInfo.java b/src/com/android/tradefed/build/IBuildInfo.java
index 732dee1..4470732 100644
--- a/src/com/android/tradefed/build/IBuildInfo.java
+++ b/src/com/android/tradefed/build/IBuildInfo.java
@@ -147,6 +147,17 @@
public File getFile(String name);
/**
+ * Helper method to retrieve a {@link VersionedFile} with a given name.
+ *
+ * @param name
+ * @return The versioned file or <code>null</code> if not found
+ */
+ public default VersionedFile getVersionedFile(String name) {
+ // Default implementation for project that don't extends BuildInfo class.
+ return null;
+ }
+
+ /**
* Returns all {@link VersionedFile}s stored in this {@link BuildInfo}.
*/
public Collection<VersionedFile> getFiles();
diff --git a/src/com/android/tradefed/build/OtaDeviceBuildInfo.java b/src/com/android/tradefed/build/OtaDeviceBuildInfo.java
index 79904c5..b413bde 100644
--- a/src/com/android/tradefed/build/OtaDeviceBuildInfo.java
+++ b/src/com/android/tradefed/build/OtaDeviceBuildInfo.java
@@ -183,6 +183,12 @@
return mBaselineBuild.getFile(name);
}
+ /** {@inheritDoc} */
+ @Override
+ public VersionedFile getVersionedFile(String name) {
+ return mBaselineBuild.getVersionedFile(name);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/com/android/tradefed/result/LogcatCrashResultForwarder.java b/src/com/android/tradefed/result/LogcatCrashResultForwarder.java
index ab6a546..1640626 100644
--- a/src/com/android/tradefed/result/LogcatCrashResultForwarder.java
+++ b/src/com/android/tradefed/result/LogcatCrashResultForwarder.java
@@ -90,7 +90,7 @@
/** Attempt to extract the crash from the logcat if the test was seen as started. */
private String extractCrashAndAddToMessage(String errorMessage, Long startTime) {
if (errorMessage.contains(ERROR_MESSAGE) && startTime != null) {
- mLogcatItem = extractLogcat(mDevice, mStartTime);
+ mLogcatItem = extractLogcat(mDevice, startTime);
errorMessage = addJavaCrashToString(mLogcatItem, errorMessage);
}
return errorMessage;
diff --git a/src/com/android/tradefed/result/TestDescription.java b/src/com/android/tradefed/result/TestDescription.java
index dfd1ca8..265167d 100644
--- a/src/com/android/tradefed/result/TestDescription.java
+++ b/src/com/android/tradefed/result/TestDescription.java
@@ -21,12 +21,18 @@
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/** Class representing information about a test case. */
public final class TestDescription implements Serializable {
+ /** Regex for method parameterized. For example: testName[0] */
+ public static final Pattern PARAMETERIZED_TEST_REGEX = Pattern.compile("(.*)?\\[(.*)\\]$");
+
private final String mClassName;
private final String mTestName;
+ private final String mTestNameNoParams;
private Annotation[] mAnnotations;
/**
@@ -42,6 +48,14 @@
mClassName = className;
mTestName = testName;
mAnnotations = new Annotation[0];
+
+ // If the method looks parameterized, track the base non-parameterized name.
+ Matcher m = PARAMETERIZED_TEST_REGEX.matcher(testName);
+ if (m.find()) {
+ mTestNameNoParams = m.group(1);
+ } else {
+ mTestNameNoParams = testName;
+ }
}
/**
@@ -90,11 +104,19 @@
return mClassName;
}
- /** Returns the name of the test. */
+ /**
+ * Returns the name of the test with the parameters, if it's parameterized test. Returns the
+ * regular test name if not a parameterized test.
+ */
public String getTestName() {
return mTestName;
}
+ /** Returns the name of the test without any parameters (if it's a parameterized method). */
+ public String getTestNameWithoutParams() {
+ return mTestNameNoParams;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparer.java b/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparer.java
index 7b52078..ec0c69e 100644
--- a/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparer.java
+++ b/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparer.java
@@ -16,6 +16,7 @@
package com.android.tradefed.targetprep.multi;
import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.build.VersionedFile;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
@@ -24,7 +25,6 @@
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.TargetSetupError;
-import java.io.File;
import java.util.HashSet;
import java.util.Set;
@@ -80,12 +80,12 @@
// Move the requested keys.
for (String key : mKeysToMove) {
- File toBeMoved = providerInfo.getFile(key);
+ VersionedFile toBeMoved = providerInfo.getVersionedFile(key);
if (toBeMoved == null) {
CLog.w("Key '%s' did not match any files, ignoring.", key);
continue;
}
- receiverInfo.setFile(key, toBeMoved, providerInfo.getBuildId());
+ receiverInfo.setFile(key, toBeMoved.getFile(), toBeMoved.getVersion());
}
}
}
diff --git a/src/com/android/tradefed/testtype/InstrumentationFileTest.java b/src/com/android/tradefed/testtype/InstrumentationFileTest.java
index dd120cf..07296d6 100644
--- a/src/com/android/tradefed/testtype/InstrumentationFileTest.java
+++ b/src/com/android/tradefed/testtype/InstrumentationFileTest.java
@@ -26,11 +26,15 @@
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.util.FileUtil;
+import com.google.common.annotations.VisibleForTesting;
+
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
/**
* Runs a set of instrumentation tests by specifying a list of line separated test classes and
@@ -44,8 +48,6 @@
// on device test folder location where the test file should be saved
private static final String ON_DEVICE_TEST_DIR_LOCATION = "/data/local/tmp/";
- // used to separate fully-qualified test case class name, and one of its methods
- private static final char METHOD_SEPARATOR = '#';
private InstrumentationTest mInstrumentationTest = null;
@@ -134,8 +136,17 @@
testFile = FileUtil.createTempFile(
"tf_testFile_" + InstrumentationFileTest.class.getCanonicalName(), ".txt");
try (BufferedWriter bw = new BufferedWriter(new FileWriter(testFile))) {
- for (TestDescription testToRun : tests) {
- bw.write(testToRun.getClassName() + METHOD_SEPARATOR + testToRun.getTestName());
+ // Remove parameterized tests to only re-run their base method.
+ Collection<TestDescription> uniqueMethods = createRerunSet(tests);
+
+ for (TestDescription testToRun : uniqueMethods) {
+ // We use getTestNameNoParams to avoid attempting re-running individual
+ // parameterized tests. Instead ask the base method to re-run them all.
+ bw.write(
+ String.format(
+ "%s#%s",
+ testToRun.getClassName(),
+ testToRun.getTestNameWithoutParams()));
bw.newLine();
}
CLog.d("Test file %s was successfully created", testFile.getAbsolutePath());
@@ -211,11 +222,25 @@
}
/**
+ * Returns a new collection of {@link TestDescription} where only one instance of each
+ * parameterized method is in the list.
+ */
+ private Collection<TestDescription> createRerunSet(Collection<TestDescription> tests) {
+ Map<String, TestDescription> uniqueMethods = new LinkedHashMap<>();
+ for (TestDescription test : tests) {
+ uniqueMethods.put(test.getTestNameWithoutParams(), test);
+ }
+ return uniqueMethods.values();
+ }
+
+ /**
* Util method to push file to a device. Exposed for unit testing.
+ *
* @return if file was pushed to the device successfully
* @throws DeviceNotAvailableException
*/
- boolean pushFileToTestDevice(File file, String destinationPath) throws DeviceNotAvailableException {
+ boolean pushFileToTestDevice(File file, String destinationPath)
+ throws DeviceNotAvailableException {
return mInstrumentationTest.getDevice().pushFile(file, destinationPath);
}
@@ -230,9 +255,8 @@
}
}
- /**
- * @return the {@link InstrumentationTest} to use. Exposed for unit testing.
- */
+ /** @return the {@link InstrumentationTest} to use. Exposed for unit testing. */
+ @VisibleForTesting
InstrumentationTest createInstrumentationTest() {
return new InstrumentationTest();
}
diff --git a/src/com/android/tradefed/testtype/junit4/BaseHostJUnit4Test.java b/src/com/android/tradefed/testtype/junit4/BaseHostJUnit4Test.java
index 20c8874..e63c668 100644
--- a/src/com/android/tradefed/testtype/junit4/BaseHostJUnit4Test.java
+++ b/src/com/android/tradefed/testtype/junit4/BaseHostJUnit4Test.java
@@ -162,10 +162,12 @@
* @param apkFileName The name of the apk file.
* @param grantPermission whether to pass the grant permission flag when installing the apk.
* @param userId the user id of the user where to install the apk.
+ * @param options extra options given to the install command
*/
- public final void installPackageAsUser(String apkFileName, boolean grantPermission, int userId)
+ public final void installPackageAsUser(
+ String apkFileName, boolean grantPermission, int userId, String... options)
throws DeviceNotAvailableException, TargetSetupError {
- installPackageAsUser(getDevice(), apkFileName, grantPermission, userId);
+ installPackageAsUser(getDevice(), apkFileName, grantPermission, userId, options);
}
/**
@@ -175,9 +177,14 @@
* @param apkFileName The name of the apk file.
* @param grantPermission whether to pass the grant permission flag when installing the apk.
* @param userId the user id of the user where to install the apk.
+ * @param options extra options given to the install command
*/
public final void installPackageAsUser(
- ITestDevice device, String apkFileName, boolean grantPermission, int userId)
+ ITestDevice device,
+ String apkFileName,
+ boolean grantPermission,
+ int userId,
+ String... options)
throws DeviceNotAvailableException, TargetSetupError {
SuiteApkInstaller installer = createSuiteApkInstaller();
// Force the apk clean up
@@ -188,6 +195,9 @@
installer.setUserId(userId);
installer.setShouldGrantPermission(grantPermission);
installer.setAbi(getAbi());
+ for (String option : options) {
+ installer.addInstallArg(option);
+ }
installer.setUp(device, mContext.getBuildInfo(device));
}
diff --git a/src/com/android/tradefed/testtype/suite/AtestRunner.java b/src/com/android/tradefed/testtype/suite/AtestRunner.java
index 6b45b2d..d2f2e46 100644
--- a/src/com/android/tradefed/testtype/suite/AtestRunner.java
+++ b/src/com/android/tradefed/testtype/suite/AtestRunner.java
@@ -21,19 +21,13 @@
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionCopier;
import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.result.SubprocessResultsReporter;
import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.testtype.Abi;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
import com.android.tradefed.testtype.InstrumentationTest;
import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.testtype.ITestFilterReceiver;
-import com.android.tradefed.util.AbiFormatter;
-import com.android.tradefed.util.AbiUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -66,13 +60,6 @@
private boolean mSkipTearDown = false;
@Option(
- name = "abi-name",
- description =
- "Abi to pass to tests that require an ABI. The device default will be used if not specified."
- )
- private String mabiName;
-
- @Option(
name = "subprocess-report-port",
description = "the port where to connect to send the" + "events."
)
@@ -89,8 +76,11 @@
@Override
public LinkedHashMap<String, IConfiguration> loadTests() {
+ // atest only needs to run on primary or specified abi.
+ if (getRequestedAbi() == null) {
+ setPrimaryAbiRun(true);
+ }
LinkedHashMap<String, IConfiguration> configMap = super.loadTests();
- IAbi abi = getAbi();
LinkedHashMap<String, HashSet<String>> includeFilters = getIncludeFilters();
for (IConfiguration testConfig : configMap.values()) {
if (mSkipSetUp || mSkipTearDown) {
@@ -99,7 +89,6 @@
if (mDebug) {
addDebugger(testConfig);
}
- setTestAbi(testConfig, abi);
// Inject include-filter to test.
HashSet<String> moduleFilters =
@@ -188,48 +177,6 @@
return listeners;
}
- /**
- * Helper to create the IAbi instance to pass to tests that implement IAbiReceiver.
- *
- * @return IAbi instance to use, may be null if not provided and device is unreachable.
- */
- private IAbi getAbi() {
- if (mabiName == null) {
- if (getDevice() == null) {
- return null;
- }
- try {
- mabiName = AbiFormatter.getDefaultAbi(getDevice(), "");
- } catch (DeviceNotAvailableException e) {
- return null;
- }
- }
- return new Abi(mabiName, AbiUtils.getBitness(mabiName));
- }
-
- /**
- * Set ABI of tests and target preparers that require it to default ABI of device.
- *
- * @param testConfig The configuration to set the ABI for.
- * @param abi The IAbi instance to pass to setAbi() of tests and target preparers.
- */
- private void setTestAbi(IConfiguration testConfig, IAbi abi) {
- if (abi == null) {
- return;
- }
- List<IRemoteTest> tests = testConfig.getTests();
- for (IRemoteTest test : tests) {
- if (test instanceof IAbiReceiver) {
- ((IAbiReceiver) test).setAbi(abi);
- }
- }
- for (ITargetPreparer targetPreparer : testConfig.getTargetPreparers()) {
- if (targetPreparer instanceof IAbiReceiver) {
- ((IAbiReceiver) targetPreparer).setAbi(abi);
- }
- }
- }
-
/** Helper to attach the debugger to any Instrumentation tests in the config. */
private void addDebugger(IConfiguration testConfig) {
for (IRemoteTest test : testConfig.getTests()) {
diff --git a/tests/src/com/android/tradefed/result/LogcatCrashResultForwarderTest.java b/tests/src/com/android/tradefed/result/LogcatCrashResultForwarderTest.java
index 6da958c..4a106a3 100644
--- a/tests/src/com/android/tradefed/result/LogcatCrashResultForwarderTest.java
+++ b/tests/src/com/android/tradefed/result/LogcatCrashResultForwarderTest.java
@@ -102,4 +102,47 @@
mReporter.testRunFailed("Something went wrong.");
EasyMock.verify(mMockListener, mMockDevice);
}
+
+ /**
+ * Test that if a crash is note detected at testFailed but later found at testRunFailed, we
+ * still add the extracted information to the failure.
+ */
+ @Test
+ @SuppressWarnings("MustBeClosedChecker")
+ public void testCaptureTestCrash_oneCrashingLogcatAfterTestEnded() {
+ mReporter = new LogcatCrashResultForwarder(mMockDevice, mMockListener);
+ TestDescription test = new TestDescription("com.class", "test");
+
+ mMockListener.testStarted(test, 0L);
+ String logcat =
+ "03-20 09:57:36.709 11 11 E AndroidRuntime: FATAL EXCEPTION: Thread-2\n"
+ + "03-20 09:57:36.709 11 11 E AndroidRuntime: Process: android.gesture.cts"
+ + ", PID: 11034\n"
+ + "03-20 09:57:36.709 11 11 E AndroidRuntime: java.lang.RuntimeException:"
+ + " Runtime\n"
+ + "03-20 09:57:36.709 11 11 E AndroidRuntime: at android.GestureTest$1"
+ + ".run(GestureTest.java:52)\n"
+ + "03-20 09:57:36.709 11 11 E AndroidRuntime: at java.lang.Thread.run"
+ + "(Thread.java:764)\n"
+ + "03-20 09:57:36.711 11 11 I TestRunner: started: testGetStrokesCount"
+ + "(android.gesture.cts.GestureTest)\n";
+
+ EasyMock.expect(mMockDevice.getLogcatSince(0L))
+ .andReturn(new ByteArrayInputStreamSource(logcat.getBytes()));
+ // No crash added at the point of testFailed.
+ mMockListener.testFailed(test, "Something went wrong.");
+ mMockListener.testEnded(test, 5L, new HashMap<String, String>());
+ // If a run failure comes with a crash detected, expect it to contain the additional stack.
+ mMockListener.testRunFailed(
+ EasyMock.contains(
+ "instrumentation failed. reason: 'Process crashed.'"
+ + "\nCrash Message:Runtime"));
+
+ EasyMock.replay(mMockListener, mMockDevice);
+ mReporter.testStarted(test, 0L);
+ mReporter.testFailed(test, "Something went wrong.");
+ mReporter.testEnded(test, 5L, new HashMap<String, String>());
+ mReporter.testRunFailed("instrumentation failed. reason: 'Process crashed.'");
+ EasyMock.verify(mMockListener, mMockDevice);
+ }
}
diff --git a/tests/src/com/android/tradefed/result/TestDescriptionTest.java b/tests/src/com/android/tradefed/result/TestDescriptionTest.java
index cf9290b..4a79d20 100644
--- a/tests/src/com/android/tradefed/result/TestDescriptionTest.java
+++ b/tests/src/com/android/tradefed/result/TestDescriptionTest.java
@@ -15,7 +15,9 @@
*/
package com.android.tradefed.result;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -54,6 +56,7 @@
"className", "testName", new TestAnnotation(), new TestAnnotation2());
assertEquals("className", mDescription.getClassName());
assertEquals("testName", mDescription.getTestName());
+ assertEquals("testName", mDescription.getTestNameWithoutParams());
assertEquals(2, mDescription.getAnnotations().size());
assertNotNull(mDescription.getAnnotation(TestAnnotation.class));
assertNotNull(mDescription.getAnnotation(TestAnnotation2.class));
@@ -68,4 +71,25 @@
assertEquals(0, mDescription.getAnnotations().size());
assertNull(mDescription.getAnnotation(TestAnnotation.class));
}
+
+ /** Create a {@link TestDescription} with a parameterized method. */
+ @Test
+ public void testCreateDescription_parameterized() {
+ mDescription = new TestDescription("className", "testName[0]");
+ assertEquals("className", mDescription.getClassName());
+ assertEquals("testName[0]", mDescription.getTestName());
+ assertEquals("testName", mDescription.getTestNameWithoutParams());
+
+ mDescription = new TestDescription("className", "testName[key=value]");
+ assertEquals("testName[key=value]", mDescription.getTestName());
+ assertEquals("testName", mDescription.getTestNameWithoutParams());
+
+ mDescription = new TestDescription("className", "testName[key=\"quoted value\"]");
+ assertEquals("testName[key=\"quoted value\"]", mDescription.getTestName());
+ assertEquals("testName", mDescription.getTestNameWithoutParams());
+
+ mDescription = new TestDescription("className", "testName[key:22]");
+ assertEquals("testName[key:22]", mDescription.getTestName());
+ assertEquals("testName", mDescription.getTestNameWithoutParams());
+ }
}
diff --git a/tests/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparerTest.java b/tests/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparerTest.java
index c9270d7..28003d3 100644
--- a/tests/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparerTest.java
+++ b/tests/src/com/android/tradefed/targetprep/multi/MergeMultiBuildTargetPreparerTest.java
@@ -68,16 +68,16 @@
setter.setOptionValue("dest-device", "device2");
setter.setOptionValue("key-to-copy", EXAMPLE_KEY);
- mMockInfo1.setFile(EXAMPLE_KEY, new File("fake"), "id1");
- assertEquals("id1", mMockInfo1.getTestsDirVersion());
+ mMockInfo1.setFile(EXAMPLE_KEY, new File("fake"), "some version");
+ assertEquals("some version", mMockInfo1.getTestsDirVersion());
assertNotNull(mMockInfo1.getFile(EXAMPLE_KEY));
assertNull(mMockInfo2.getFile(EXAMPLE_KEY));
mPreparer.setUp(mContext);
// Now mock info 2 has the file.
assertNotNull(mMockInfo2.getFile(EXAMPLE_KEY));
- // The build id of the provider build is set as the version.
- assertEquals("id1", mMockInfo2.getTestsDirVersion());
+ // The version of the provider build is preserved.
+ assertEquals("some version", mMockInfo2.getTestsDirVersion());
}
/**
diff --git a/tests/src/com/android/tradefed/testtype/InstrumentationFileTestTest.java b/tests/src/com/android/tradefed/testtype/InstrumentationFileTestTest.java
index 498cb62..52be0f0 100644
--- a/tests/src/com/android/tradefed/testtype/InstrumentationFileTestTest.java
+++ b/tests/src/com/android/tradefed/testtype/InstrumentationFileTestTest.java
@@ -85,7 +85,6 @@
/**
* Test normal run scenario with a single test.
*/
- @SuppressWarnings("unchecked")
public void testRun_singleSuccessfulTest() throws DeviceNotAvailableException,
ConfigurationException {
final Collection<TestDescription> testsList = new ArrayList<>(1);
@@ -101,8 +100,8 @@
listener.testRunStarted(TEST_PACKAGE_VALUE, 1);
listener.testStarted(TestDescription.convertToIdentifier(test));
listener.testEnded(
- TestDescription.convertToIdentifier(test), Collections.EMPTY_MAP);
- listener.testRunEnded(0, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test), Collections.emptyMap());
+ listener.testRunEnded(0, Collections.emptyMap());
return true;
}
};
@@ -142,7 +141,6 @@
/**
* Test re-run scenario when 1 out of 3 tests fails to complete but is successful after re-run
*/
- @SuppressWarnings("unchecked")
public void testRun_reRunOneFailedToCompleteTest()
throws DeviceNotAvailableException, ConfigurationException {
final Collection<TestDescription> testsList = new ArrayList<>(1);
@@ -163,8 +161,8 @@
listener.testRunStarted(TEST_PACKAGE_VALUE, 2);
listener.testStarted(TestDescription.convertToIdentifier(test1));
listener.testEnded(
- TestDescription.convertToIdentifier(test1), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test1), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
// second test started but never finished
listener.testStarted(TestDescription.convertToIdentifier(test2));
return true;
@@ -182,13 +180,13 @@
listener.testRunStarted(TEST_PACKAGE_VALUE, 2);
listener.testStarted(TestDescription.convertToIdentifier(test3));
listener.testEnded(
- TestDescription.convertToIdentifier(test3), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test3), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
// second test is rerun but completed successfully this time
listener.testStarted(TestDescription.convertToIdentifier(test2));
listener.testEnded(
- TestDescription.convertToIdentifier(test2), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test2), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
return true;
}
};
@@ -243,7 +241,6 @@
/**
* Test re-run scenario when 2 remaining tests fail to complete and need to be run serially
*/
- @SuppressWarnings("unchecked")
public void testRun_serialReRunOfTwoFailedToCompleteTests()
throws DeviceNotAvailableException, ConfigurationException {
final Collection<TestDescription> testsList = new ArrayList<>(1);
@@ -279,8 +276,8 @@
listener.testRunStarted(TEST_PACKAGE_VALUE, 1);
listener.testStarted(TestDescription.convertToIdentifier(test1));
listener.testEnded(
- TestDescription.convertToIdentifier(test1), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test1), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
return true;
}
};
@@ -296,8 +293,8 @@
listener.testRunStarted(TEST_PACKAGE_VALUE, 1);
listener.testStarted(TestDescription.convertToIdentifier(test2));
listener.testEnded(
- TestDescription.convertToIdentifier(test2), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test2), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
return true;
}
};
@@ -353,7 +350,6 @@
/**
* Test no serial re-run tests fail to complete.
*/
- @SuppressWarnings("unchecked")
public void testRun_noSerialReRun()
throws DeviceNotAvailableException, ConfigurationException {
final Collection<TestDescription> testsList = new ArrayList<>(1);
@@ -411,7 +407,6 @@
/**
* Test attempting times exceed max attempts.
*/
- @SuppressWarnings("unchecked")
public void testRun_exceedMaxAttempts()
throws DeviceNotAvailableException, ConfigurationException {
final ArrayList<TestDescription> testsList = new ArrayList<>(1);
@@ -441,8 +436,8 @@
// first test started and ended successfully
listener.testStarted(TestDescription.convertToIdentifier(test1));
listener.testEnded(
- TestDescription.convertToIdentifier(test1), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test1), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
// second test started but never finished
listener.testStarted(TestDescription.convertToIdentifier(test2));
// verify that the content of the testFile contains all expected tests
@@ -462,8 +457,8 @@
listener.testRunStarted(TEST_PACKAGE_VALUE, 5);
listener.testStarted(TestDescription.convertToIdentifier(test2));
listener.testEnded(
- TestDescription.convertToIdentifier(test2), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test2), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
// test3 started but never finished
listener.testStarted(TestDescription.convertToIdentifier(test3));
// verify that the content of the testFile contains all expected tests
@@ -483,8 +478,8 @@
listener.testRunStarted(TEST_PACKAGE_VALUE, 4);
listener.testStarted(TestDescription.convertToIdentifier(test3));
listener.testEnded(
- TestDescription.convertToIdentifier(test3), Collections.EMPTY_MAP);
- listener.testRunEnded(1, Collections.EMPTY_MAP);
+ TestDescription.convertToIdentifier(test3), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
// test4 started but never finished
listener.testStarted(TestDescription.convertToIdentifier(test4));
// verify that the content of the testFile contains all expected tests
@@ -543,6 +538,102 @@
assertEquals(mMockTestDevice, mMockITest.getDevice());
}
+ /** Test re-run a test instrumentation when some methods are parameterized. */
+ public void testRun_parameterized() throws DeviceNotAvailableException, ConfigurationException {
+ final Collection<TestDescription> testsList = new ArrayList<>();
+ final TestDescription test = new TestDescription("ClassFoo", "methodBar");
+ final TestDescription test1 = new TestDescription("ClassFoo", "paramMethod[0]");
+ final TestDescription test2 = new TestDescription("ClassFoo", "paramMethod[1]");
+ testsList.add(test);
+ testsList.add(test1);
+ testsList.add(test2);
+
+ // verify the mock listener is passed through to the runner, the first test pass
+ RunTestAnswer runTestResponse =
+ new RunTestAnswer() {
+ @Override
+ public Boolean answer(
+ IRemoteAndroidTestRunner runner, ITestRunListener listener) {
+ listener.testRunStarted(TEST_PACKAGE_VALUE, 3);
+ listener.testStarted(TestDescription.convertToIdentifier(test));
+ listener.testEnded(
+ TestDescription.convertToIdentifier(test), Collections.emptyMap());
+ listener.testStarted(TestDescription.convertToIdentifier(test1));
+ listener.testRunEnded(0, Collections.emptyMap());
+ return true;
+ }
+ };
+ setRunTestExpectations(runTestResponse);
+
+ RunTestAnswer secondRunAnswer =
+ new RunTestAnswer() {
+ @Override
+ public Boolean answer(
+ IRemoteAndroidTestRunner runner, ITestRunListener listener) {
+ // test2 started and ended successfully
+ listener.testRunStarted(TEST_PACKAGE_VALUE, 2);
+ listener.testStarted(TestDescription.convertToIdentifier(test1));
+ listener.testEnded(
+ TestDescription.convertToIdentifier(test1), Collections.emptyMap());
+ listener.testStarted(TestDescription.convertToIdentifier(test2));
+ listener.testEnded(
+ TestDescription.convertToIdentifier(test2), Collections.emptyMap());
+ listener.testRunEnded(1, Collections.emptyMap());
+ return true;
+ }
+ };
+ setRunTestExpectations(secondRunAnswer);
+
+ mInstrumentationFileTest =
+ new InstrumentationFileTest(mMockITest, testsList, true, -1) {
+ @Override
+ InstrumentationTest createInstrumentationTest() {
+ return mMockITest;
+ }
+
+ @Override
+ boolean pushFileToTestDevice(File file, String destinationPath)
+ throws DeviceNotAvailableException {
+ // simulate successful push and store created file
+ mTestFile = file;
+ // verify that the content of the testFile contains all expected tests
+ Collection<TestDescription> updatedList = new ArrayList<>();
+ updatedList.add(test);
+ updatedList.add(new TestDescription("ClassFoo", "paramMethod"));
+ verifyTestFile(updatedList);
+ return true;
+ }
+
+ @Override
+ void deleteTestFileFromDevice(String pathToFile)
+ throws DeviceNotAvailableException {
+ //ignore
+ }
+ };
+
+ // mock successful test run lifecycle for the first test
+ mMockListener.testRunStarted(TEST_PACKAGE_VALUE, 3);
+ mMockListener.testStarted(EasyMock.eq(test), EasyMock.anyLong());
+ mMockListener.testEnded(
+ EasyMock.eq(test), EasyMock.anyLong(), EasyMock.eq(new HashMap<String, Metric>()));
+ mMockListener.testStarted(EasyMock.eq(test1), EasyMock.anyLong());
+ mMockListener.testRunEnded(0, new HashMap<String, Metric>());
+
+ // Second run:
+ mMockListener.testRunStarted(TEST_PACKAGE_VALUE, 2);
+ mMockListener.testStarted(EasyMock.eq(test1), EasyMock.anyLong());
+ mMockListener.testEnded(
+ EasyMock.eq(test1), EasyMock.anyLong(), EasyMock.eq(new HashMap<String, Metric>()));
+ mMockListener.testStarted(EasyMock.eq(test2), EasyMock.anyLong());
+ mMockListener.testEnded(
+ EasyMock.eq(test2), EasyMock.anyLong(), EasyMock.eq(new HashMap<String, Metric>()));
+ mMockListener.testRunEnded(1, new HashMap<String, Metric>());
+
+ EasyMock.replay(mMockListener, mMockTestDevice);
+ mInstrumentationFileTest.run(mMockListener);
+ assertEquals(mMockTestDevice, mMockITest.getDevice());
+ }
+
/**
* Helper class that verifies tetFile's content match the expected list of test to be run
*