Merge "GoogleBenchmarkTest: Add "benchmark-filter" option."
diff --git a/device_build_interfaces/com/android/tradefed/device/TestDeviceOptions.java b/device_build_interfaces/com/android/tradefed/device/TestDeviceOptions.java
index 0d10607..e3d7de1 100644
--- a/device_build_interfaces/com/android/tradefed/device/TestDeviceOptions.java
+++ b/device_build_interfaces/com/android/tradefed/device/TestDeviceOptions.java
@@ -176,11 +176,6 @@
private File mAvdConfigFile = null;
@Option(
- name = "gce-driver-config-test-resource-name",
- description = "Test resource name of the config to use to launch GCE devices.")
- private String mAvdConfigTestResourceName;
-
- @Option(
name = "gce-driver-service-account-json-key-path",
description = "path to the service account json key location.")
private File mJsonKeyFile = null;
@@ -549,11 +544,6 @@
mAvdConfigFile = avdConfigFile;
}
- /** Return the Gce Avd config test resource name to start the instance. */
- public String getAvdConfigTestResourceName() {
- return mAvdConfigTestResourceName;
- }
-
/** @return the service account json key file. */
public File getServiceAccountJsonKeyFile() {
return mJsonKeyFile;
diff --git a/src/com/android/tradefed/build/BuildInfo.java b/src/com/android/tradefed/build/BuildInfo.java
index 4d42ea0..2069b2a 100644
--- a/src/com/android/tradefed/build/BuildInfo.java
+++ b/src/com/android/tradefed/build/BuildInfo.java
@@ -215,7 +215,6 @@
setBuildFlavor(build.getBuildFlavor());
setBuildBranch(build.getBuildBranch());
setTestTag(build.getTestTag());
- setTestResourceBuild(build.isTestResourceBuild());
}
protected MultiMap<String, String> getAttributesMultiMap() {
@@ -681,32 +680,9 @@
buildFile.getVersion());
}
}
- // Test resource
- buildInfo.setTestResourceBuild(protoBuild.getIsTestResource());
return buildInfo;
}
- /**
- * Get test resource from a list of builds.
- *
- * @param testResourceBuildInfos An list of {@link IBuildInfo}.
- * @param testResourceName the test resource name
- * @return the test resource file.
- */
- public static File getTestResource(
- List<IBuildInfo> testResourceBuildInfos, String testResourceName) {
- if (testResourceBuildInfos == null) {
- return null;
- }
- for (IBuildInfo buildInfo : testResourceBuildInfos) {
- File testResourceFile = buildInfo.getFile(testResourceName);
- if (testResourceFile != null) {
- return testResourceFile;
- }
- }
- return null;
- }
-
/** {@inheritDoc} */
@Override
public Set<File> getRemoteFiles() {
diff --git a/src/com/android/tradefed/build/GCSTestResourceProvider.java b/src/com/android/tradefed/build/GCSTestResourceProvider.java
deleted file mode 100644
index aabbeb2..0000000
--- a/src/com/android/tradefed/build/GCSTestResourceProvider.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 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.android.tradefed.build;
-
-import com.android.tradefed.build.gcs.GCSDownloaderHelper;
-import com.android.tradefed.config.Option;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-/** Download test resource from GCS. */
-public class GCSTestResourceProvider implements IBuildProvider {
-
- @Option(
- name = "test-resource",
- description =
- "GCS files as test resources that are required for the test."
- + "Key is the identity of the test resource."
- + "Value is a gs://bucket/path/to/file format GCS path.")
- private Map<String, String> mTestResources = new HashMap<>();
-
- private IBuildInfo mBuildInfo;
- private GCSDownloaderHelper mDownloaderHelper = null;
-
- @Override
- public IBuildInfo getBuild() throws BuildRetrievalError {
- mBuildInfo = new BuildInfo();
- mBuildInfo.setTestResourceBuild(true);
- fetchTestResources();
- return mBuildInfo;
- }
-
- private void fetchTestResources() throws BuildRetrievalError {
- for (Map.Entry<String, String> entry : mTestResources.entrySet()) {
- fetchTestResource(entry.getKey(), entry.getValue());
- }
- }
-
- private void fetchTestResource(String key, String value) throws BuildRetrievalError {
- File localFile = getHelper().fetchTestResource(value);
- mBuildInfo.setFile(key, localFile, "");
- }
-
- @Override
- public void cleanUp(IBuildInfo info) {
- info.cleanUp();
- }
-
- /** Returns the {@link GCSDownloaderHelper} that downloads from GCS buckets. */
- @VisibleForTesting
- GCSDownloaderHelper getHelper() {
- if (mDownloaderHelper == null) {
- mDownloaderHelper = new GCSDownloaderHelper();
- }
- return mDownloaderHelper;
- }
-}
diff --git a/src/com/android/tradefed/device/NativeDevice.java b/src/com/android/tradefed/device/NativeDevice.java
index fd00a3c..cc5b8d6 100644
--- a/src/com/android/tradefed/device/NativeDevice.java
+++ b/src/com/android/tradefed/device/NativeDevice.java
@@ -447,8 +447,7 @@
String propValue = getProperty(propName);
if (propValue != null) {
return propValue;
- } else if (TestDeviceState.FASTBOOT.equals(getDeviceState()) &&
- fastbootVar != null) {
+ } else if (isStateBootloaderOrFastbootd() && fastbootVar != null) {
CLog.i("%s for device %s is null, re-querying in fastboot", description,
getSerialNumber());
return getFastbootVariable(fastbootVar);
@@ -2936,11 +2935,11 @@
throws DeviceNotAvailableException, UnsupportedOperationException {
rebootIntoFastbootInternal(false);
}
-
+
/**
* Reboots the device into bootloader or fastbootd mode.
*
- * @param isBootloader: true to boot the device into bootloader mode, false to boot the device
+ * @param isBootloader true to boot the device into bootloader mode, false to boot the device
* into fastbootd mode.
* @throws DeviceNotAvailableException if connection with device is lost and cannot be
* recovered.
@@ -2948,7 +2947,7 @@
private void rebootIntoFastbootInternal(boolean isBootloader)
throws DeviceNotAvailableException {
final RebootMode mode =
- isBootloader ? RebootMode.REBOOT_INTO_BOOTLOADER : RebootMode.REBOOT_INTO_FASTBOOT;
+ isBootloader ? RebootMode.REBOOT_INTO_BOOTLOADER : RebootMode.REBOOT_INTO_FASTBOOTD;
if (!mFastbootEnabled) {
throw new UnsupportedOperationException(
String.format("Fastboot is not available and cannot reboot into %s", mode));
@@ -2958,13 +2957,14 @@
CLog.i(
"Rebooting device %s in state %s into %s",
getSerialNumber(), getDeviceState(), mode);
- if (TestDeviceState.FASTBOOT.equals(getDeviceState())) {
+ if (isStateBootloaderOrFastbootd()) {
CLog.i("device %s already in fastboot. Rebooting anyway", getSerialNumber());
executeFastbootCommand(String.format("reboot-%s", mode));
} else {
CLog.i("Booting device %s into %s", getSerialNumber(), mode);
doAdbReboot(mode, null);
}
+
if (!mStateMonitor.waitForDeviceBootloader(mOptions.getFastbootTimeout())) {
recoverDeviceFromBootloader();
}
@@ -3120,7 +3120,7 @@
protected enum RebootMode {
REBOOT_FULL(""),
REBOOT_USERSPACE("userspace"),
- REBOOT_INTO_FASTBOOT("fastboot"),
+ REBOOT_INTO_FASTBOOTD("fastboot"),
REBOOT_INTO_BOOTLOADER("bootloader"),
REBOOT_INTO_SIDELOAD("sideload"),
REBOOT_INTO_SIDELOAD_AUTO_REBOOT("sideload-auto-reboot"),
@@ -3161,8 +3161,8 @@
// Track Tradefed reboot time
mLastTradefedRebootTime = System.currentTimeMillis();
- if (TestDeviceState.FASTBOOT == getDeviceState()) {
- CLog.i("device %s in fastboot. Rebooting to userspace.", getSerialNumber());
+ if (isStateBootloaderOrFastbootd()) {
+ CLog.i("device %s in %s. Rebooting to userspace.", getSerialNumber(), getDeviceState());
executeFastbootCommand("reboot");
} else {
if (mOptions.shouldDisableReboot()) {
@@ -3730,7 +3730,7 @@
if (!deviceState.equals(getDeviceState())) {
// disable state changes while fastboot lock is held, because issuing fastboot command
// will disrupt state
- if (getDeviceState().equals(TestDeviceState.FASTBOOT) && mFastbootLock.isLocked()) {
+ if (isStateBootloaderOrFastbootd() && mFastbootLock.isLocked()) {
return;
}
mState = deviceState;
@@ -4869,7 +4869,7 @@
if (getIDevice() instanceof StubDevice) {
return null;
}
- if (TestDeviceState.FASTBOOT.equals(getDeviceState())) {
+ if (isStateBootloaderOrFastbootd()) {
return null;
}
try {
diff --git a/src/com/android/tradefed/device/WaitDeviceRecovery.java b/src/com/android/tradefed/device/WaitDeviceRecovery.java
index 66d25c3..e163025 100644
--- a/src/com/android/tradefed/device/WaitDeviceRecovery.java
+++ b/src/com/android/tradefed/device/WaitDeviceRecovery.java
@@ -120,10 +120,13 @@
// ensure bootloader state is updated
monitor.waitForDeviceBootloaderStateUpdate();
- if (monitor.getDeviceState().equals(TestDeviceState.FASTBOOT)) {
- Log.i(LOG_TAG, String.format(
- "Found device %s in fastboot but expected online. Rebooting...",
- monitor.getSerialNumber()));
+ TestDeviceState state = monitor.getDeviceState();
+ if (TestDeviceState.FASTBOOT.equals(state) || TestDeviceState.FASTBOOTD.equals(state)) {
+ Log.i(
+ LOG_TAG,
+ String.format(
+ "Found device %s in %s but expected online. Rebooting...",
+ monitor.getSerialNumber(), state));
// TODO: retry if failed
getRunUtil().runTimedCmd(mFastbootWaitTime, mFastbootPath, "-s",
monitor.getSerialNumber(), "reboot");
diff --git a/src/com/android/tradefed/device/cloud/GceManager.java b/src/com/android/tradefed/device/cloud/GceManager.java
index 3e6a77d..4ef0434 100644
--- a/src/com/android/tradefed/device/cloud/GceManager.java
+++ b/src/com/android/tradefed/device/cloud/GceManager.java
@@ -15,7 +15,6 @@
*/
package com.android.tradefed.device.cloud;
-import com.android.tradefed.build.BuildInfo;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.command.remote.DeviceDescriptor;
import com.android.tradefed.device.TestDeviceOptions;
@@ -71,7 +70,6 @@
private DeviceDescriptor mDeviceDescriptor;
private TestDeviceOptions mDeviceOptions;
private IBuildInfo mBuildInfo;
- private List<IBuildInfo> mTestResourceBuildInfos;
private String mGceInstanceName = null;
private String mGceHost = null;
@@ -83,17 +81,12 @@
* @param deviceDesc The {@link DeviceDescriptor} that will be associated with the GCE device.
* @param deviceOptions A {@link TestDeviceOptions} associated with the device.
* @param buildInfo A {@link IBuildInfo} describing the gce build to start.
- * @param testResourceBuildInfos A list {@link IBuildInfo} describing test resources
*/
public GceManager(
- DeviceDescriptor deviceDesc,
- TestDeviceOptions deviceOptions,
- IBuildInfo buildInfo,
- List<IBuildInfo> testResourceBuildInfos) {
+ DeviceDescriptor deviceDesc, TestDeviceOptions deviceOptions, IBuildInfo buildInfo) {
mDeviceDescriptor = deviceDesc;
mDeviceOptions = deviceOptions;
mBuildInfo = buildInfo;
- mTestResourceBuildInfos = testResourceBuildInfos;
if (!deviceOptions.allowGceCmdTimeoutOverride()) {
return;
@@ -117,13 +110,22 @@
}
}
+ /** @deprecated Use other constructors, we keep this temporarily for backward compatibility. */
+ @Deprecated
+ public GceManager(
+ DeviceDescriptor deviceDesc,
+ TestDeviceOptions deviceOptions,
+ IBuildInfo buildInfo,
+ List<IBuildInfo> testResourceBuildInfos) {
+ this(deviceDesc, deviceOptions, buildInfo);
+ }
+
/**
* Ctor, variation that can be used to provide the GCE instance name to use directly.
*
* @param deviceDesc The {@link DeviceDescriptor} that will be associated with the GCE device.
* @param deviceOptions A {@link TestDeviceOptions} associated with the device
* @param buildInfo A {@link IBuildInfo} describing the gce build to start.
- * @param testResourceBuildInfos A list {@link IBuildInfo} describing test resources
* @param gceInstanceName The instance name to use.
* @param gceHost The host name or ip of the instance to use.
*/
@@ -131,10 +133,9 @@
DeviceDescriptor deviceDesc,
TestDeviceOptions deviceOptions,
IBuildInfo buildInfo,
- List<IBuildInfo> testResourceBuildInfos,
String gceInstanceName,
String gceHost) {
- this(deviceDesc, deviceOptions, buildInfo, testResourceBuildInfos);
+ this(deviceDesc, deviceOptions, buildInfo);
mGceInstanceName = gceInstanceName;
mGceHost = gceHost;
}
@@ -729,10 +730,6 @@
@VisibleForTesting
File getAvdConfigFile() {
- if (getTestDeviceOptions().getAvdConfigTestResourceName() != null) {
- return BuildInfo.getTestResource(
- mTestResourceBuildInfos, getTestDeviceOptions().getAvdConfigTestResourceName());
- }
return getTestDeviceOptions().getAvdConfigFile();
}
diff --git a/src/com/android/tradefed/device/cloud/ManagedRemoteDevice.java b/src/com/android/tradefed/device/cloud/ManagedRemoteDevice.java
index f196cfe..282c9bd 100644
--- a/src/com/android/tradefed/device/cloud/ManagedRemoteDevice.java
+++ b/src/com/android/tradefed/device/cloud/ManagedRemoteDevice.java
@@ -79,7 +79,7 @@
// First get the options
TestDeviceOptions options = getOptions();
// We create a brand new GceManager each time to ensure clean state.
- mGceHandler = new GceManager(getDeviceDescriptor(), options, info, testResourceBuildInfos);
+ mGceHandler = new GceManager(getDeviceDescriptor(), options, info);
getGceHandler().logStableHostImageInfos(info);
setFastbootEnabled(false);
diff --git a/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDevice.java b/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDevice.java
index d0c2875..641fe31 100644
--- a/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDevice.java
+++ b/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDevice.java
@@ -91,9 +91,7 @@
mGceAvd = null;
mGceSshMonitor = null;
// We create a brand new GceManager each time to ensure clean state.
- mGceHandler =
- new GceManager(
- getDeviceDescriptor(), getOptions(), info, testResourceBuildInfos);
+ mGceHandler = new GceManager(getDeviceDescriptor(), getOptions(), info);
getGceHandler().logStableHostImageInfos(info);
setFastbootEnabled(false);
diff --git a/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollector.java b/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollector.java
index 3bbf52e..6b5fa18 100644
--- a/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollector.java
+++ b/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollector.java
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
@@ -121,9 +122,11 @@
return;
}
for (String key : mKeys) {
- Entry<String, File> pulledMetrics = pullMetricFile(key, currentMetrics);
- if (pulledMetrics != null) {
- processMetricFile(pulledMetrics.getKey(), pulledMetrics.getValue(), data);
+ Map<String, File> pulledMetrics = pullMetricFile(key, currentMetrics);
+
+ // Process all the metric files that matched the key pattern.
+ for (Map.Entry<String, File> entry : pulledMetrics.entrySet()) {
+ processMetricFile(entry.getKey(), entry.getValue(), data);
}
}
@@ -137,8 +140,9 @@
}
- private Entry<String, File> pullMetricFile(
+ private Map<String, File> pullMetricFile(
String pattern, final Map<String, String> currentMetrics) {
+ Map<String, File> matchedFiles = new HashMap<>();
Pattern p = Pattern.compile(pattern);
for (Entry<String, String> entry : currentMetrics.entrySet()) {
if (p.matcher(entry.getKey()).find()) {
@@ -153,8 +157,9 @@
if (mCleanUp) {
device.deleteFile(entry.getValue());
}
- // Return the actual key and the file associated
- return new SimpleEntry<String, File>(entry.getKey(), attemptPull);
+ // Store all the keys that matches the pattern and the corresponding
+ // files pulled from the device.
+ matchedFiles.put(entry.getKey(), attemptPull);
}
} catch (DeviceNotAvailableException e) {
CLog.e(
@@ -165,9 +170,13 @@
}
}
}
- // Not a hard failure, just nice to know
- CLog.d("Could not find a device file associated to pattern '%s'.", pattern);
- return null;
+
+ if (matchedFiles.isEmpty()) {
+ // Not a hard failure, just nice to know
+ CLog.d("Could not find a device file associated to pattern '%s'.", pattern);
+
+ }
+ return matchedFiles;
}
/**
diff --git a/src/com/android/tradefed/invoker/InvocationExecution.java b/src/com/android/tradefed/invoker/InvocationExecution.java
index a1dcecf..395fe6e 100644
--- a/src/com/android/tradefed/invoker/InvocationExecution.java
+++ b/src/com/android/tradefed/invoker/InvocationExecution.java
@@ -18,7 +18,6 @@
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log.LogLevel;
import com.android.tradefed.build.BuildInfo;
-import com.android.tradefed.build.BuildInfoKey;
import com.android.tradefed.build.BuildInfoKey.BuildInfoFileKey;
import com.android.tradefed.build.BuildRetrievalError;
import com.android.tradefed.build.IBuildInfo;
@@ -42,6 +41,7 @@
import com.android.tradefed.invoker.logger.InvocationMetricLogger.InvocationMetricKey;
import com.android.tradefed.invoker.logger.TfObjectTracker;
import com.android.tradefed.invoker.shard.IShardHelper;
+import com.android.tradefed.invoker.shard.TestsPoolPoller;
import com.android.tradefed.log.ITestLogger;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ByteArrayInputStreamSource;
@@ -157,7 +157,6 @@
// TODO: remove build update when reporting is done on context
updateBuild(info, config);
linkExternalDirs(info, testInfo);
- info.setTestResourceBuild(config.isDeviceConfiguredFake(currentDeviceName));
if (config.getCommandOptions().shouldUseReplicateSetup()) {
buildReplicat = info;
@@ -172,7 +171,6 @@
}
throw e;
}
- createSharedResources(testInfo);
setBinariesVersion(testInfo.getContext());
return true;
}
@@ -585,7 +583,9 @@
// Handle the no-retry use case
if (!decision.isAutoRetryEnabled()
|| RetryStrategy.NO_RETRY.equals(decision.getRetryStrategy())
- || test instanceof ITestSuite) {
+ || test instanceof ITestSuite
+ // TODO: Handle auto-retry in local-sharding for non-suite
+ || test instanceof TestsPoolPoller) {
runTest(config, info, listener, test);
remainingTests.remove(test);
continue;
@@ -869,39 +869,6 @@
return null;
}
- /** Populate the shared resources directory for all non-resource build */
- private void createSharedResources(TestInformation testInfo) {
- List<IBuildInfo> infos = testInfo.getContext().getBuildInfos();
- if (infos.size() <= 1) {
- return;
- }
- try {
- for (IBuildInfo info : infos) {
- if (info.isTestResourceBuild()) {
- // Create a reception sub-folder for each build info resource to avoid mixing
- String name =
- String.format(
- "%s_%s_%s",
- info.getBuildBranch(),
- info.getBuildId(),
- info.getBuildFlavor());
- File buildDir = FileUtil.createTempDir(name, testInfo.dependenciesFolder());
- for (BuildInfoFileKey key : BuildInfoKey.SHARED_KEY) {
- File f = info.getFile(key);
- if (f == null) {
- continue;
- }
- File subDir = new File(buildDir, f.getName());
- FileUtil.symlinkFile(f, subDir);
- }
- }
- }
- } catch (IOException e) {
- CLog.e("Failed to create the shared resources dir.");
- CLog.e(e);
- }
- }
-
private void setBinariesVersion(IInvocationContext context) {
String version = getAdbVersion();
if (version != null) {
diff --git a/src/com/android/tradefed/result/suite/XmlSuiteResultFormatter.java b/src/com/android/tradefed/result/suite/XmlSuiteResultFormatter.java
index d6a4be6..772075b 100644
--- a/src/com/android/tradefed/result/suite/XmlSuiteResultFormatter.java
+++ b/src/com/android/tradefed/result/suite/XmlSuiteResultFormatter.java
@@ -98,6 +98,7 @@
private static final String MODULE_TAG = "Module";
private static final String MODULES_DONE_ATTR = "modules_done";
private static final String MODULES_TOTAL_ATTR = "modules_total";
+ private static final String MODULES_NOT_DONE_REASON = "Reason";
private static final String NAME_ATTR = "name";
private static final String OS_ARCH_ATTR = "os_arch";
private static final String OS_NAME_ATTR = "os_name";
@@ -297,6 +298,15 @@
NS, PASS_ATTR, Integer.toString(module.getNumTestsInState(TestStatus.PASSED)));
serializer.attribute(NS, TOTAL_TESTS_ATTR, Integer.toString(module.getNumTests()));
+ if (!isDone) {
+ String message = module.getRunFailureMessage();
+ if (message == null) {
+ message = "Run was incomplete. Some tests might not have finished.";
+ }
+ serializer.startTag(NS, MODULES_NOT_DONE_REASON);
+ serializer.attribute(NS, MESSAGE_ATTR, message);
+ serializer.endTag(NS, MODULES_NOT_DONE_REASON);
+ }
serializeTestCases(serializer, module.getTestResults());
serializer.endTag(NS, MODULE_TAG);
}
@@ -603,6 +613,13 @@
module.testRunStarted(moduleId, totalTests);
// TestCase level information parsing
while (parser.nextTag() == XmlPullParser.START_TAG) {
+ // If a reason for not done exists, handle it.
+ if (parser.getName().equals(MODULES_NOT_DONE_REASON)) {
+ parser.require(XmlPullParser.START_TAG, NS, MODULES_NOT_DONE_REASON);
+ parser.nextTag();
+ parser.require(XmlPullParser.END_TAG, NS, MODULES_NOT_DONE_REASON);
+ continue;
+ }
parser.require(XmlPullParser.START_TAG, NS, CASE_TAG);
String className = parser.getAttributeValue(NS, NAME_ATTR);
// Test level information parsing
diff --git a/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java b/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
index 9edbd10..31ffcc6 100644
--- a/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
+++ b/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
@@ -222,15 +222,14 @@
* Extracts and returns splits for the specified apks.
*
* @param testInfo the {@link TestInformation}
- * @param apksName The name of the apks file to extract splits from.
+ * @param moduleFile The module file to extract the splits from.
* @return a File[] containing the splits.
* @throws TargetSetupError if bundletool cannot be found or device spec file fails to generate.
*/
- private File[] getSplitsForApks(TestInformation testInfo, String apksName)
+ private File[] getSplitsForApks(TestInformation testInfo, File moduleFile)
throws TargetSetupError {
initBundletoolUtil(testInfo);
initDeviceSpecFilePath(testInfo.getDevice());
- File moduleFile = getLocalPathForFilename(testInfo, apksName);
File splitsDir =
getBundletoolUtil()
.extractSplitsFromApks(
@@ -274,7 +273,7 @@
}
String modulePackageName = "";
if (moduleFile.getName().endsWith(SPLIT_APKS_SUFFIX)) {
- File[] splits = getSplitsForApks(testInfo, moduleFileName);
+ File[] splits = getSplitsForApks(testInfo, moduleFile);
if (splits == null) {
// Bundletool failed to extract splits.
CLog.w(
@@ -437,7 +436,7 @@
throws TargetSetupError, DeviceNotAvailableException {
File apks = getLocalPathForFilename(testInfo, apksName);
// Rename the extracted files and add the file to filename list.
- File[] splits = getSplitsForApks(testInfo, apks.getName());
+ File[] splits = getSplitsForApks(testInfo, apks);
ITestDevice device = testInfo.getDevice();
if (splits.length == 0) {
throw new TargetSetupError(
@@ -471,7 +470,7 @@
for (String moduleFileName : testAppFileNames) {
File moduleFile = getLocalPathForFilename(testInfo, moduleFileName);
if (moduleFileName.endsWith(SPLIT_APKS_SUFFIX)) {
- File[] splits = getSplitsForApks(testInfo, moduleFileName);
+ File[] splits = getSplitsForApks(testInfo, moduleFile);
String splitsArgs = createInstallArgsForSplit(splits, device);
mSplitsInstallArgs.add(splitsArgs);
} else {
diff --git a/test_framework/com/android/tradefed/targetprep/RunHostScriptTargetPreparer.java b/test_framework/com/android/tradefed/targetprep/RunHostScriptTargetPreparer.java
new file mode 100644
index 0000000..0245523
--- /dev/null
+++ b/test_framework/com/android/tradefed/targetprep/RunHostScriptTargetPreparer.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2020 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.android.tradefed.targetprep;
+
+import com.android.tradefed.config.GlobalConfiguration;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.IDeviceManager;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.ExecutionFiles.FilesKey;
+import com.android.tradefed.invoker.TestInformation;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.IRunUtil;
+import com.android.tradefed.util.RunUtil;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nullable;
+
+/**
+ * Target preparer which executes a script before running a test. The script can reference the
+ * device's serial number using the ANDROID_SERIAL environment variable.
+ */
+@OptionClass(alias = "run-host-script")
+public class RunHostScriptTargetPreparer extends BaseTargetPreparer {
+
+ @Option(name = "script-file", description = "Path to the script to execute.")
+ private String mScriptPath = null;
+
+ @Option(name = "work-dir", description = "Working directory to use when executing script.")
+ private File mWorkDir = null;
+
+ @Option(name = "script-timeout", description = "Script execution timeout.")
+ private Duration mTimeout = Duration.ofMinutes(1L);
+
+ private IRunUtil mRunUtil;
+
+ @Override
+ public void setUp(TestInformation testInfo)
+ throws TargetSetupError, BuildError, DeviceNotAvailableException {
+ if (mScriptPath == null) {
+ CLog.w("No script to execute.");
+ return;
+ }
+ ITestDevice device = testInfo.getDevice();
+
+ // Find script and verify it exists and is executable
+ File scriptFile = findScriptFile(testInfo);
+ if (scriptFile == null || !scriptFile.isFile()) {
+ throw new TargetSetupError(
+ String.format("File %s not found.", mScriptPath), device.getDeviceDescriptor());
+ }
+ if (!scriptFile.canExecute()) {
+ scriptFile.setExecutable(true);
+ }
+
+ // Set working directory and environment variables
+ getRunUtil().setWorkingDir(mWorkDir);
+ getRunUtil().setEnvVariable("ANDROID_SERIAL", device.getSerialNumber());
+ setPathVariable(testInfo);
+
+ // Execute script and handle result
+ CommandResult result =
+ getRunUtil().runTimedCmd(mTimeout.toMillis(), scriptFile.getAbsolutePath());
+ switch (result.getStatus()) {
+ case SUCCESS:
+ CLog.i("Script executed successfully, stdout = [%s].", result.getStdout());
+ break;
+ case FAILED:
+ throw new TargetSetupError(
+ String.format(
+ "Script execution failed, stdout = [%s], stderr = [%s].",
+ result.getStdout(), result.getStderr()),
+ device.getDeviceDescriptor());
+ case TIMED_OUT:
+ throw new TargetSetupError(
+ "Script execution timed out.", device.getDeviceDescriptor());
+ case EXCEPTION:
+ throw new TargetSetupError(
+ String.format(
+ "Exception during script execution, stdout = [%s], stderr = [%s].",
+ result.getStdout(), result.getStderr()),
+ device.getDeviceDescriptor());
+ }
+ }
+
+ /** @return {@link IRunUtil} instance to use */
+ @VisibleForTesting
+ IRunUtil getRunUtil() {
+ if (mRunUtil == null) {
+ mRunUtil = new RunUtil();
+ }
+ return mRunUtil;
+ }
+
+ /** @return {@link IDeviceManager} instance used to fetch the configured adb/fastboot paths */
+ @VisibleForTesting
+ IDeviceManager getDeviceManager() {
+ return GlobalConfiguration.getDeviceManagerInstance();
+ }
+
+ /** Find the script file to execute. */
+ @Nullable
+ private File findScriptFile(TestInformation testInfo) {
+ File scriptFile = new File(mScriptPath);
+ if (scriptFile.isAbsolute()) {
+ return scriptFile;
+ }
+ // Try to find the script in the working directory if it was set
+ if (mWorkDir != null) {
+ scriptFile = new File(mWorkDir, mScriptPath);
+ if (scriptFile.isFile()) {
+ return scriptFile;
+ }
+ }
+ // Otherwise, search for it in the test information
+ try {
+ return testInfo.getDependencyFile(mScriptPath, false);
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ }
+
+ /** Update $PATH if necessary to use consistent adb and fastboot binaries. */
+ private void setPathVariable(TestInformation testInfo) {
+ List<String> paths = new ArrayList<>();
+ // Use the test's adb binary or the globally defined one
+ File adbBinary = testInfo.executionFiles().get(FilesKey.ADB_BINARY);
+ if (adbBinary == null) {
+ String adbPath = getDeviceManager().getAdbPath();
+ if (!adbPath.equals("adb")) { // ignore default binary
+ adbBinary = new File(adbPath);
+ }
+ }
+ if (adbBinary != null && adbBinary.isFile()) {
+ paths.add(adbBinary.getParentFile().getAbsolutePath());
+ }
+ // Use the globally defined fastboot binary
+ String fastbootPath = getDeviceManager().getFastbootPath();
+ if (!fastbootPath.equals("fastboot")) { // ignore default binary
+ File fastbootBinary = new File(fastbootPath);
+ if (fastbootBinary.isFile()) {
+ paths.add(fastbootBinary.getParentFile().getAbsolutePath());
+ }
+ }
+ // Prepend additional paths to the PATH variable
+ if (!paths.isEmpty()) {
+ String separator = System.getProperty("path.separator");
+ paths.add(System.getenv("PATH"));
+ String path = paths.stream().distinct().collect(Collectors.joining(separator));
+ CLog.d("Using updated $PATH: %s", path);
+ getRunUtil().setEnvVariable("PATH", path);
+ }
+ }
+}
diff --git a/test_framework/com/android/tradefed/testtype/GTestListener.java b/test_framework/com/android/tradefed/testtype/GTestListener.java
index c967d06..38c6498 100644
--- a/test_framework/com/android/tradefed/testtype/GTestListener.java
+++ b/test_framework/com/android/tradefed/testtype/GTestListener.java
@@ -22,8 +22,10 @@
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.result.proto.TestRecordProto.FailureStatus;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
@@ -32,6 +34,7 @@
*/
final class GTestListener extends ResultForwarder {
+ private static final int MAX_PARTIAL_SET_SIZE = 20;
private Set<TestDescription> mTests = new HashSet<>();
private Set<TestDescription> mDuplicateTests = new HashSet<>();
@@ -50,11 +53,19 @@
@Override
public void testRunEnded(long elapsedTime, HashMap<String, Metric> runMetrics) {
if (!mDuplicateTests.isEmpty()) {
- FailureDescription error =
- FailureDescription.create(
- String.format(
- "The following tests ran more than once: %s.",
- mDuplicateTests));
+ StringBuilder errorMessage = new StringBuilder();
+ errorMessage.append(
+ String.format("%s tests ran more than once.", mDuplicateTests.size()));
+ if (mDuplicateTests.size() > MAX_PARTIAL_SET_SIZE) {
+ List<TestDescription> partialDuplicateSet = new ArrayList<>(mDuplicateTests);
+ while (partialDuplicateSet.size() > MAX_PARTIAL_SET_SIZE) {
+ partialDuplicateSet.remove(0);
+ }
+ errorMessage.append(String.format(" Partial list: %s", partialDuplicateSet));
+ } else {
+ errorMessage.append(String.format(" Full list: %s", mDuplicateTests));
+ }
+ FailureDescription error = FailureDescription.create(errorMessage.toString());
error.setFailureStatus(FailureStatus.TEST_FAILURE);
super.testRunFailed(error);
}
diff --git a/tests/src/com/android/tradefed/UnitTests.java b/tests/src/com/android/tradefed/UnitTests.java
index 3dabdfc..101caa8 100644
--- a/tests/src/com/android/tradefed/UnitTests.java
+++ b/tests/src/com/android/tradefed/UnitTests.java
@@ -23,7 +23,6 @@
import com.android.tradefed.build.DeviceBuildInfoTest;
import com.android.tradefed.build.DeviceFolderBuildInfoTest;
import com.android.tradefed.build.FileDownloadCacheTest;
-import com.android.tradefed.build.GCSTestResourceProviderTest;
import com.android.tradefed.build.LocalDeviceBuildProviderTest;
import com.android.tradefed.build.OtaZipfileBuildProviderTest;
import com.android.tradefed.clearcut.ClearcutClientTest;
@@ -236,6 +235,7 @@
import com.android.tradefed.targetprep.RootTargetPreparerTest;
import com.android.tradefed.targetprep.RunCommandTargetPreparerTest;
import com.android.tradefed.targetprep.RunHostCommandTargetPreparerTest;
+import com.android.tradefed.targetprep.RunHostScriptTargetPreparerTest;
import com.android.tradefed.targetprep.StopServicesSetupTest;
import com.android.tradefed.targetprep.SwitchUserTargetPreparerTest;
import com.android.tradefed.targetprep.SystemUpdaterDeviceFlasherTest;
@@ -415,7 +415,6 @@
DeviceBuildDescriptorTest.class,
DeviceFolderBuildInfoTest.class,
FileDownloadCacheTest.class,
- GCSTestResourceProviderTest.class,
LocalDeviceBuildProviderTest.class,
OtaZipfileBuildProviderTest.class,
@@ -676,6 +675,7 @@
RootTargetPreparerTest.class,
RunCommandTargetPreparerTest.class,
RunHostCommandTargetPreparerTest.class,
+ RunHostScriptTargetPreparerTest.class,
StopServicesSetupTest.class,
SystemUpdaterDeviceFlasherTest.class,
TargetSetupErrorTest.class,
diff --git a/tests/src/com/android/tradefed/build/BuildInfoTest.java b/tests/src/com/android/tradefed/build/BuildInfoTest.java
index 1f7b1a0..9eed940 100644
--- a/tests/src/com/android/tradefed/build/BuildInfoTest.java
+++ b/tests/src/com/android/tradefed/build/BuildInfoTest.java
@@ -28,14 +28,12 @@
import com.android.tradefed.util.SerializationUtil;
import org.junit.After;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.File;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -211,28 +209,4 @@
assertTrue(deserialized.getRemoteFiles().contains(new File(file)));
}
}
-
- /** Test {@link BuildInfo#getTestResource(List, String)} */
- @Test
- public void testGetTestResource() {
- List<IBuildInfo> buildInfos = new ArrayList<IBuildInfo>();
- BuildInfo testResourceBuild = new BuildInfo();
- testResourceBuild.setTestResourceBuild(true);
- File testResourceFile = new File("test-resource1");
- testResourceBuild.setFile("test-resource1", testResourceFile, "");
- buildInfos.add(testResourceBuild);
- File file = BuildInfo.getTestResource(buildInfos, "test-resource1");
- Assert.assertEquals(testResourceFile, file);
- }
-
- /** Test {@link BuildInfo#getTestResource(List, String)} */
- @Test
- public void testGetTestResource_notExist() {
- List<IBuildInfo> buildInfos = new ArrayList<IBuildInfo>();
- BuildInfo testResourceBuild = new BuildInfo();
- testResourceBuild.setTestResourceBuild(true);
- buildInfos.add(testResourceBuild);
- File file = BuildInfo.getTestResource(buildInfos, "test-resource1");
- Assert.assertNull(file);
- }
}
diff --git a/tests/src/com/android/tradefed/build/GCSTestResourceProviderTest.java b/tests/src/com/android/tradefed/build/GCSTestResourceProviderTest.java
deleted file mode 100644
index ad93333..0000000
--- a/tests/src/com/android/tradefed/build/GCSTestResourceProviderTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2018 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.android.tradefed.build;
-
-import com.android.tradefed.build.gcs.GCSDownloaderHelper;
-import com.android.tradefed.config.OptionSetter;
-import com.android.tradefed.util.FileUtil;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.File;
-import java.io.IOException;
-
-/** Unit test for {@link GCSTestResourceProvider}. */
-@RunWith(JUnit4.class)
-public class GCSTestResourceProviderTest {
-
- private static final String TEST_RESOURCE1 = "gs://b/this/is/a/file1.txt";
- private static final String TEST_RESOURCE2 = "gs://b/this/is/a/file2.txt";
-
- private File mRoot;
- private GCSTestResourceProvider mTestResourceProvider;
-
- @Before
- public void setUp() throws Exception {
- mRoot = FileUtil.createTempDir(GCSTestResourceProviderTest.class.getSimpleName());
- mTestResourceProvider =
- new GCSTestResourceProvider() {
- @Override
- GCSDownloaderHelper getHelper() {
- return new GCSDownloaderHelper() {
- @Override
- public File fetchTestResource(String gsPath)
- throws BuildRetrievalError {
- try {
- File f = FileUtil.createTempFile("test-gcs-file", "txt");
- FileUtil.writeToFile(gsPath, f);
- return f;
- } catch (IOException e) {
- throw new BuildRetrievalError(e.getMessage(), e);
- }
- }
- };
- }
- };
- OptionSetter setter = new OptionSetter(mTestResourceProvider);
- setter.setOptionValue("test-resource", "key1", TEST_RESOURCE1);
- setter.setOptionValue("test-resource", "key2", TEST_RESOURCE2);
- }
-
- @After
- public void tearDown() {
- FileUtil.recursiveDelete(mRoot);
- }
-
- @Test
- public void testGetBuild() throws Exception {
- IBuildInfo buildInfo = mTestResourceProvider.getBuild();
- File file1 = buildInfo.getFile("key1");
- File file2 = buildInfo.getFile("key2");
- Assert.assertEquals(TEST_RESOURCE1, FileUtil.readStringFromFile(file1));
- Assert.assertEquals(TEST_RESOURCE2, FileUtil.readStringFromFile(file2));
- mTestResourceProvider.cleanUp(buildInfo);
- Assert.assertFalse(file1.exists());
- Assert.assertFalse(file2.exists());
- }
-}
diff --git a/tests/src/com/android/tradefed/device/cloud/GceManagerTest.java b/tests/src/com/android/tradefed/device/cloud/GceManagerTest.java
index f3bdced..cae19ce 100644
--- a/tests/src/com/android/tradefed/device/cloud/GceManagerTest.java
+++ b/tests/src/com/android/tradefed/device/cloud/GceManagerTest.java
@@ -40,7 +40,6 @@
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.After;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -79,7 +78,7 @@
mOptions.setAvdDriverBinary(mAvdBinary);
mOptions.setAvdConfigFile(mAvdBinary);
mGceManager =
- new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null) {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo) {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -249,7 +248,7 @@
setter.setOptionValue("gce-driver-param", "--emulator-build-id");
setter.setOptionValue("gce-driver-param", "EMULATOR_BUILD_ID");
mGceManager =
- new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null) {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo) {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -331,7 +330,7 @@
// Boot-time on Acloud params will be overridden by TF option.
setter.setOptionValue("allow-gce-boot-timeout-override", "false");
mGceManager =
- new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null) {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo) {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -418,7 +417,7 @@
OptionSetter setter = new OptionSetter(mOptions);
setter.setOptionValue("allow-gce-boot-timeout-override", "true");
mGceManager =
- new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null) {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo) {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -475,7 +474,7 @@
OptionSetter setter = new OptionSetter(mOptions);
setter.setOptionValue("allow-gce-boot-timeout-override", "true");
mGceManager =
- new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null) {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo) {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -517,7 +516,7 @@
OptionSetter setter = new OptionSetter(mOptions);
setter.setOptionValue("allow-gce-boot-timeout-override", "true");
mGceManager =
- new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null) {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo) {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -572,8 +571,7 @@
@Test
public void testShutdownGce() throws Exception {
mGceManager =
- new GceManager(
- mMockDeviceDesc, mOptions, mMockBuildInfo, null, "instance1", "host1") {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, "instance1", "host1") {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -611,8 +609,7 @@
OptionSetter setter = new OptionSetter(mOptions);
setter.setOptionValue("wait-gce-teardown", "false");
mGceManager =
- new GceManager(
- mMockDeviceDesc, mOptions, mMockBuildInfo, null, "instance1", "host1") {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, "instance1", "host1") {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -645,8 +642,7 @@
@Test
public void testShutdownGce_withJsonKeyFile() throws Exception {
mGceManager =
- new GceManager(
- mMockDeviceDesc, mOptions, mMockBuildInfo, null, "instance1", "host1") {
+ new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, "instance1", "host1") {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -854,7 +850,7 @@
setter.setOptionValue("allow-gce-boot-timeout-override", "true");
DeviceDescriptor desc = null;
mGceManager =
- new GceManager(desc, mOptions, mMockBuildInfo, null) {
+ new GceManager(desc, mOptions, mMockBuildInfo) {
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
@@ -916,28 +912,6 @@
EasyMock.verify(mMockRunUtil);
}
- /**
- * Test {@link GceManager#getAvdConfigFile()} while using test resource.
- *
- * @throws Exception
- */
- @Test
- public void testGetAvdConfigFile_testResource() throws Exception {
- OptionSetter setter = new OptionSetter(mOptions);
- setter.setOptionValue("gce-driver-config-test-resource-name", "device.config");
-
- BuildInfo testResourceBuild = new BuildInfo();
- testResourceBuild.setTestResourceBuild(true);
- File configFile = new File("device.config");
- testResourceBuild.setFile("device.config", configFile, "");
- List<IBuildInfo> testResourceBuildInfos = new ArrayList<>();
- testResourceBuildInfos.add(testResourceBuild);
-
- mGceManager =
- new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, testResourceBuildInfos);
- Assert.assertEquals(configFile, mGceManager.getAvdConfigFile());
- }
-
@Test
public void testUpdateTimeout() throws Exception {
OptionSetter setter = new OptionSetter(mOptions);
@@ -945,7 +919,7 @@
mOptions.getGceDriverParams().add("--boot-timeout");
mOptions.getGceDriverParams().add("900");
assertEquals(1800000L, mOptions.getGceCmdTimeout());
- mGceManager = new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null);
+ mGceManager = new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo);
assertEquals(1080000L, mOptions.getGceCmdTimeout());
}
@@ -958,7 +932,7 @@
mOptions.getGceDriverParams().add("--boot-timeout");
mOptions.getGceDriverParams().add("450");
assertEquals(1800000L, mOptions.getGceCmdTimeout());
- mGceManager = new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null);
+ mGceManager = new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo);
// The last specified boot-timeout is used.
assertEquals(630000L, mOptions.getGceCmdTimeout());
}
@@ -970,7 +944,7 @@
mOptions.getGceDriverParams().add("--someargs");
mOptions.getGceDriverParams().add("900");
assertEquals(1800000L, mOptions.getGceCmdTimeout());
- mGceManager = new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo, null);
+ mGceManager = new GceManager(mMockDeviceDesc, mOptions, mMockBuildInfo);
assertEquals(1800000L, mOptions.getGceCmdTimeout());
}
}
diff --git a/tests/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDeviceTest.java b/tests/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDeviceTest.java
index 6fa4e2b..e8d0219 100644
--- a/tests/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDeviceTest.java
+++ b/tests/src/com/android/tradefed/device/cloud/RemoteAndroidVirtualDeviceTest.java
@@ -174,10 +174,7 @@
@Override
GceManager getGceHandler() {
return new GceManager(
- getDeviceDescriptor(),
- new TestDeviceOptions(),
- mMockBuildInfo,
- null) {
+ getDeviceDescriptor(), new TestDeviceOptions(), mMockBuildInfo) {
@Override
protected List<String> buildGceCmd(
File reportFile, IBuildInfo b, String ipDevice) {
diff --git a/tests/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollectorTest.java b/tests/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollectorTest.java
index 27e9203..ec04f22 100644
--- a/tests/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollectorTest.java
+++ b/tests/src/com/android/tradefed/device/metric/FilePullerDeviceMetricCollectorTest.java
@@ -95,6 +95,35 @@
}
/**
+ * Test when a multiple file is found matching the matching key, then pulled and {@link
+ * FilePullerDeviceMetricCollector#processMetricFile(String, File, DeviceMetricData)} is called
+ * multiple times.
+ */
+ @Test
+ public void testPullMultipleMatchingKeyInMetrics() throws Exception {
+ OptionSetter setter = new OptionSetter(mFilePuller);
+ setter.setOptionValue("pull-pattern-keys", "coverageFile");
+ HashMap<String, Metric> currentMetrics = new HashMap<>();
+ currentMetrics.put("coverageFile", TfMetricProtoUtil.stringToMetric("/data/coverage1"));
+ currentMetrics.put("coverageFileAnother",
+ TfMetricProtoUtil.stringToMetric("/data/coverage2"));
+
+ Mockito.when(mMockDevice.pullFile(Mockito.eq("/data/coverage1")))
+ .thenReturn(new File("fake1"));
+ Mockito.when(mMockDevice.pullFile(Mockito.eq("/data/coverage2")))
+ .thenReturn(new File("fake2"));
+
+ mFilePuller.testRunStarted("fakeRun", 5);
+ mFilePuller.testRunEnded(500, currentMetrics);
+
+ Mockito.verify(mMockListener)
+ .testLog(Mockito.eq("coverageFile"), Mockito.eq(LogDataType.TEXT), Mockito.any());
+ Mockito.verify(mMockListener)
+ .testLog(Mockito.eq("coverageFileAnother"), Mockito.eq(LogDataType.TEXT),
+ Mockito.any());
+ }
+
+ /**
* Test when a file is found matching the key using a pattern matching, then pulled and {@link
* FilePullerDeviceMetricCollector#processMetricFile(String, File, DeviceMetricData)} is called.
*/
diff --git a/tests/src/com/android/tradefed/invoker/InvocationExecutionTest.java b/tests/src/com/android/tradefed/invoker/InvocationExecutionTest.java
index 8b84e35..4d743ac 100644
--- a/tests/src/com/android/tradefed/invoker/InvocationExecutionTest.java
+++ b/tests/src/com/android/tradefed/invoker/InvocationExecutionTest.java
@@ -24,10 +24,6 @@
import static org.mockito.Mockito.verify;
import com.android.tradefed.build.BuildInfo;
-import com.android.tradefed.build.BuildRetrievalError;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IBuildProvider;
-import com.android.tradefed.build.StubBuildProvider;
import com.android.tradefed.config.Configuration;
import com.android.tradefed.config.DeviceConfigurationHolder;
import com.android.tradefed.config.IConfiguration;
@@ -55,7 +51,6 @@
import com.android.tradefed.targetprep.multi.IMultiTargetPreparer;
import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.testtype.suite.TestSuiteStub;
-import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IDisableable;
import org.easymock.EasyMock;
@@ -66,7 +61,6 @@
import org.mockito.InOrder;
import org.mockito.Mockito;
-import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -86,7 +80,6 @@
private ILogSaver mLogSaver;
private ITestInvocationListener mMockListener;
private ILogSaverListener mMockLogListener;
- private ITestDevice mMockDevice;
private ITestLogger mMockLogger;
@Before
@@ -99,7 +92,6 @@
mMockListener = mock(ITestInvocationListener.class);
mMockLogListener = mock(ILogSaverListener.class);
mMockLogger = mock(ITestLogger.class);
- mMockDevice = EasyMock.createMock(ITestDevice.class);
// Reset the counters
TestBaseMetricCollector.sTotalInit = 0;
RemoteTestCollector.sTotalInit = 0;
@@ -562,68 +554,4 @@
inOrder.verify(stub1).isDisabled();
inOrder.verify(stub1).tearDown(testInfo, exception);
}
-
- /** Ensure we create the shared folder from the resource build. */
- @Test
- public void testFetchBuild_createSharedFolder() throws Throwable {
- mExec =
- new InvocationExecution() {
- @Override
- protected String getAdbVersion() {
- return "1";
- }
- };
- EasyMock.expect(mMockDevice.getSerialNumber()).andStubReturn("serial");
- mMockDevice.setRecovery(EasyMock.anyObject());
- EasyMock.expectLastCall().times(2);
-
- List<IDeviceConfiguration> listDeviceConfig = new ArrayList<>();
- DeviceConfigurationHolder holder = new DeviceConfigurationHolder("device1");
- IBuildProvider provider = new StubBuildProvider();
- holder.addSpecificConfig(provider);
- mContext.addAllocatedDevice("device1", mMockDevice);
- listDeviceConfig.add(holder);
-
- DeviceConfigurationHolder holder2 = new DeviceConfigurationHolder("device2", true);
- IBuildProvider provider2 =
- new StubBuildProvider() {
- @Override
- public IBuildInfo getBuild() throws BuildRetrievalError {
- IBuildInfo info = super.getBuild();
- info.setBuildId("1234");
- info.setBuildBranch("branch");
- info.setBuildFlavor("flavor");
- return info;
- }
- };
- holder2.addSpecificConfig(provider2);
- mContext.addAllocatedDevice("device2", mMockDevice);
- listDeviceConfig.add(holder2);
-
- mConfig.setDeviceConfigList(listDeviceConfig);
- File tmpWorkDir = FileUtil.createTempDir("invocation-execution-shared-test");
- TestInformation testInfo =
- TestInformation.newBuilder()
- .setInvocationContext(mContext)
- .setDependenciesFolder(tmpWorkDir)
- .build();
- // Download
- EasyMock.replay(mMockDevice);
- assertTrue(mExec.fetchBuild(testInfo, mConfig, null, mMockListener));
- EasyMock.verify(mMockDevice);
-
- List<IBuildInfo> builds = mContext.getBuildInfos();
- try {
- assertEquals(2, builds.size());
- assertEquals(1, tmpWorkDir.listFiles().length);
- // The resource build was linked to dependencies
- assertTrue(tmpWorkDir.listFiles()[0].getName().startsWith("branch_1234_flavor"));
- } finally {
- for (IBuildInfo info : builds) {
- info.cleanUp();
- }
- FileUtil.recursiveDelete(tmpWorkDir);
- }
- assertTrue(mContext.getAttributes().containsKey(InvocationExecution.JAVA_VERSION_KEY));
- }
}
diff --git a/tests/src/com/android/tradefed/invoker/TestInvocationMultiTest.java b/tests/src/com/android/tradefed/invoker/TestInvocationMultiTest.java
index 9257c88..1eb26ee 100644
--- a/tests/src/com/android/tradefed/invoker/TestInvocationMultiTest.java
+++ b/tests/src/com/android/tradefed/invoker/TestInvocationMultiTest.java
@@ -130,7 +130,6 @@
mProvider1 = EasyMock.createMock(IBuildProvider.class);
holder1.addSpecificConfig(mProvider1);
EasyMock.expect(mMockConfig.getDeviceConfigByName("device1")).andStubReturn(holder1);
- EasyMock.expect(mMockConfig.isDeviceConfiguredFake("device1")).andReturn(false);
mDevice1.setOptions(EasyMock.anyObject());
mDevice1.setRecovery(EasyMock.anyObject());
diff --git a/tests/src/com/android/tradefed/invoker/TestInvocationTest.java b/tests/src/com/android/tradefed/invoker/TestInvocationTest.java
index 8f4044c..1925909 100644
--- a/tests/src/com/android/tradefed/invoker/TestInvocationTest.java
+++ b/tests/src/com/android/tradefed/invoker/TestInvocationTest.java
@@ -242,8 +242,6 @@
EasyMock.expect(mMockBuildInfo.getBuildFlavor()).andStubReturn("flavor");
EasyMock.expect(mMockBuildInfo.getProperties()).andStubReturn(new HashSet<>());
EasyMock.expect(mMockBuildInfo.isTestResourceBuild()).andStubReturn(false);
- mMockBuildInfo.setTestResourceBuild(EasyMock.anyBoolean());
- EasyMock.expectLastCall().anyTimes();
// always expect logger initialization and cleanup calls
mMockLogRegistry.registerLogger(mMockLogger);
diff --git a/tests/src/com/android/tradefed/result/suite/XmlSuiteResultFormatterTest.java b/tests/src/com/android/tradefed/result/suite/XmlSuiteResultFormatterTest.java
index 7eb74c6..647db0b 100644
--- a/tests/src/com/android/tradefed/result/suite/XmlSuiteResultFormatterTest.java
+++ b/tests/src/com/android/tradefed/result/suite/XmlSuiteResultFormatterTest.java
@@ -16,6 +16,7 @@
package com.android.tradefed.result.suite;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -184,6 +185,62 @@
assertEquals(holder.runResults.size(), mResultHolder.runResults.size());
}
+ @Test
+ public void testFailuresReporting_notDone() throws Exception {
+ mResultHolder.context = mContext;
+
+ List<TestRunResult> runResults = new ArrayList<>();
+ runResults.add(createFakeResult("module1", 2, 1, 0, 0));
+ runResults.get(0).testRunFailed("Failed module");
+ mResultHolder.runResults = runResults;
+
+ Map<String, IAbi> modulesAbi = new HashMap<>();
+ modulesAbi.put("module1", new Abi("armeabi-v7a", "32"));
+ mResultHolder.modulesAbi = modulesAbi;
+
+ mResultHolder.completeModules = 2;
+ mResultHolder.totalModules = 1;
+ mResultHolder.passedTests = 2;
+ mResultHolder.failedTests = 1;
+ mResultHolder.startTime = 0L;
+ mResultHolder.endTime = 10L;
+ File res = mFormatter.writeResults(mResultHolder, mResultDir);
+ String content = FileUtil.readStringFromFile(res);
+
+ assertXmlContainsNode(content, "Result/Module");
+ assertXmlContainsAttribute(content, "Result/Module", "done", "false");
+ assertXmlContainsNode(content, "Result/Module/Reason");
+ assertXmlContainsAttribute(content, "Result/Module/TestCase", "name", "com.class.module1");
+ assertXmlContainsAttribute(
+ content, "Result/Module/TestCase/Test", "name", "module1.method0");
+ assertXmlContainsAttribute(
+ content, "Result/Module/TestCase/Test", "name", "module1.method1");
+ // Check that failures are showing in the xml for the test cases
+ assertXmlContainsAttribute(
+ content, "Result/Module/TestCase/Test", "name", "module1.failed0");
+ assertXmlContainsAttribute(content, "Result/Module/TestCase/Test", "result", "fail");
+ assertXmlContainsAttribute(
+ content, "Result/Module/TestCase/Test/Failure", "message", "module1 failed.");
+ assertXmlContainsValue(
+ content,
+ "Result/Module/TestCase/Test/Failure/StackTrace",
+ XmlSuiteResultFormatter.sanitizeXmlContent("module1 failed.\nstack\nstack\0"));
+ // Test that we can read back the informations
+ SuiteResultHolder holder = mFormatter.parseResults(mResultDir, false);
+ assertEquals(holder.completeModules, mResultHolder.completeModules);
+ assertEquals(holder.totalModules, mResultHolder.totalModules);
+ assertEquals(holder.passedTests, mResultHolder.passedTests);
+ assertEquals(holder.failedTests, mResultHolder.failedTests);
+ assertEquals(holder.startTime, mResultHolder.startTime);
+ assertEquals(holder.endTime, mResultHolder.endTime);
+ assertEquals(
+ holder.modulesAbi.get("armeabi-v7a module1"),
+ mResultHolder.modulesAbi.get("module1"));
+ assertEquals(1, holder.runResults.size());
+ TestRunResult result = new ArrayList<>(holder.runResults).get(0);
+ assertFalse(result.isRunComplete());
+ }
+
/** Test that assumption failures and ignored tests are correctly reported in the xml. */
@Test
public void testAssumptionFailures_Ignore_Reporting() throws Exception {
diff --git a/tests/src/com/android/tradefed/targetprep/RunHostScriptTargetPreparerTest.java b/tests/src/com/android/tradefed/targetprep/RunHostScriptTargetPreparerTest.java
new file mode 100644
index 0000000..4125fa1
--- /dev/null
+++ b/tests/src/com/android/tradefed/targetprep/RunHostScriptTargetPreparerTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2020 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.android.tradefed.targetprep;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.android.tradefed.config.ConfigurationException;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.device.IDeviceManager;
+import com.android.tradefed.invoker.ExecutionFiles.FilesKey;
+import com.android.tradefed.invoker.TestInformation;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.IRunUtil;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+/** Unit test for {@link RunHostScriptTargetPreparer}. */
+@RunWith(JUnit4.class)
+public final class RunHostScriptTargetPreparerTest {
+
+ private static final String DEVICE_SERIAL = "DEVICE_SERIAL";
+
+ @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private TestInformation mTestInfo;
+
+ @Mock private IRunUtil mRunUtil;
+ @Mock private IDeviceManager mDeviceManager;
+ private RunHostScriptTargetPreparer mPreparer;
+ private OptionSetter mOptionSetter;
+ private File mWorkDir;
+ private File mScriptFile;
+
+ @Before
+ public void setUp() throws IOException, ConfigurationException {
+ // Initialize preparer and test information
+ mPreparer =
+ new RunHostScriptTargetPreparer() {
+ @Override
+ IRunUtil getRunUtil() {
+ return mRunUtil;
+ }
+
+ @Override
+ IDeviceManager getDeviceManager() {
+ return mDeviceManager;
+ }
+ };
+ mOptionSetter = new OptionSetter(mPreparer);
+ when(mTestInfo.getDevice().getSerialNumber()).thenReturn(DEVICE_SERIAL);
+ when(mTestInfo.executionFiles().get(any(FilesKey.class))).thenReturn(null);
+
+ // Create temporary working directory and script file
+ mWorkDir = FileUtil.createTempDir(this.getClass().getSimpleName());
+ mScriptFile = File.createTempFile("script", ".sh", mWorkDir);
+
+ // Default to default adb/fastboot paths
+ when(mDeviceManager.getAdbPath()).thenReturn("adb");
+ when(mDeviceManager.getFastbootPath()).thenReturn("fastboot");
+
+ // Default to successful execution
+ CommandResult result = new CommandResult(CommandStatus.SUCCESS);
+ when(mRunUtil.runTimedCmd(anyLong(), any())).thenReturn(result);
+ }
+
+ @After
+ public void tearDown() {
+ FileUtil.recursiveDelete(mWorkDir);
+ }
+
+ @Test
+ public void testSetUp() throws Exception {
+ mOptionSetter.setOptionValue("script-file", mScriptFile.getAbsolutePath());
+ mOptionSetter.setOptionValue("script-timeout", "10");
+ // Verify environment, timeout, and script path
+ mPreparer.setUp(mTestInfo);
+ verify(mRunUtil).setEnvVariable("ANDROID_SERIAL", DEVICE_SERIAL);
+ verify(mRunUtil, never()).setEnvVariable(eq("PATH"), any()); // uses default PATH
+ verify(mRunUtil).runTimedCmd(10L, mScriptFile.getAbsolutePath());
+ // Verify that script is executable
+ assertTrue(mScriptFile.canExecute());
+ }
+
+ @Test
+ public void testSetUp_workingDir() throws Exception {
+ mOptionSetter.setOptionValue("work-dir", mWorkDir.getAbsolutePath());
+ mOptionSetter.setOptionValue("script-file", mScriptFile.getName()); // relative
+ // Verify that the working directory is set and script's path is resolved
+ mPreparer.setUp(mTestInfo);
+ verify(mRunUtil).setWorkingDir(mWorkDir);
+ verify(mRunUtil).runTimedCmd(anyLong(), eq(mScriptFile.getAbsolutePath()));
+ }
+
+ @Test
+ public void testSetUp_findFile() throws Exception {
+ mOptionSetter.setOptionValue("script-file", mScriptFile.getName()); // relative
+ when(mTestInfo.getDependencyFile(any(), anyBoolean())).thenReturn(mScriptFile);
+ // Verify that the script is found in the test information
+ mPreparer.setUp(mTestInfo);
+ verify(mRunUtil).runTimedCmd(anyLong(), eq(mScriptFile.getAbsolutePath()));
+ }
+
+ @Test(expected = TargetSetupError.class)
+ public void testSetUp_fileNotFound() throws Exception {
+ mOptionSetter.setOptionValue("script-file", "unknown.sh");
+ mPreparer.setUp(mTestInfo);
+ }
+
+ @Test(expected = TargetSetupError.class)
+ public void testSetUp_executionError() throws Exception {
+ mOptionSetter.setOptionValue("script-file", mScriptFile.getAbsolutePath());
+ CommandResult result = new CommandResult(CommandStatus.FAILED);
+ when(mRunUtil.runTimedCmd(anyLong(), any())).thenReturn(result);
+ mPreparer.setUp(mTestInfo);
+ }
+
+ @Test
+ public void testSetUp_pathVariable() throws Exception {
+ mOptionSetter.setOptionValue("script-file", mScriptFile.getAbsolutePath());
+ // Create and set dummy adb binary
+ Path adbDir = Files.createTempDirectory(mWorkDir.toPath(), "adb");
+ File adbBinary = File.createTempFile("adb", ".sh", adbDir.toFile());
+ when(mTestInfo.executionFiles().get(eq(FilesKey.ADB_BINARY))).thenReturn(adbBinary);
+ // Create and set dummy fastboot binary
+ Path fastbootDir = Files.createTempDirectory(mWorkDir.toPath(), "fastboot");
+ File fastbootBinary = File.createTempFile("fastboot", ".sh", fastbootDir.toFile());
+ when(mDeviceManager.getFastbootPath()).thenReturn(fastbootBinary.getAbsolutePath());
+ // Verify that binary paths were prepended to the path variable
+ String separator = System.getProperty("path.separator");
+ String expectedPath = adbDir + separator + fastbootDir + separator + System.getenv("PATH");
+ mPreparer.setUp(mTestInfo);
+ verify(mRunUtil).setEnvVariable("PATH", expectedPath);
+ }
+}
diff --git a/tests/src/com/android/tradefed/testtype/GTestListenerTest.java b/tests/src/com/android/tradefed/testtype/GTestListenerTest.java
index 392ee75..d05f3fb 100644
--- a/tests/src/com/android/tradefed/testtype/GTestListenerTest.java
+++ b/tests/src/com/android/tradefed/testtype/GTestListenerTest.java
@@ -96,7 +96,7 @@
String moduleName = "testWithDuplicateTests";
String testClass = "testClass";
String testName1 = "testName1";
- String duplicateTestsMessage = "The following tests ran more than once: ";
+ String duplicateTestsMessage = "1 tests ran more than once. Full list:";
TestDescription testId1 = new TestDescription(testClass, testName1);
mMockListener.testRunStarted(EasyMock.eq(moduleName), EasyMock.eq(2));