Merge "Add invocation timeout error"
diff --git a/src/com/android/tradefed/cluster/ClusterCommandScheduler.java b/src/com/android/tradefed/cluster/ClusterCommandScheduler.java
index 427ed39..2e09168 100644
--- a/src/com/android/tradefed/cluster/ClusterCommandScheduler.java
+++ b/src/com/android/tradefed/cluster/ClusterCommandScheduler.java
@@ -380,22 +380,22 @@
@Override
public void run() {
try {
- // check cluster command's status
+ // Check cluster command's status.
if (getClusterOptions().checkCommandState()) {
- ClusterCommand.State status =
+ ClusterCommandStatus commandStatus =
getClusterClient()
- .getCommandState(
+ .getCommandStatus(
mCommandTask.getRequestId(),
mCommandTask.getCommandId());
- if (ClusterCommand.State.CANCELED.equals(status)) {
- // TODO: retrieve cancel reason from TFC.
+ if (ClusterCommand.State.CANCELED.equals(commandStatus.getState())) {
String cause =
String.format(
"The cluster client %s has marked command "
- + "(requestId=%s, commandId=%s) canceled",
+ + "(requestId=%s, commandId=%s) canceled with reason: %s",
getClusterClient().getClass().getSimpleName(),
mCommandTask.getRequestId(),
- mCommandTask.getCommandId());
+ mCommandTask.getCommandId(),
+ commandStatus.getCancelReason());
CLog.w("Stop invocation due to: %s", cause);
Optional.ofNullable(getInvocationContext())
.map(IInvocationContext::getInvocationId)
diff --git a/src/com/android/tradefed/cluster/SubprocessConfigBuilder.java b/src/com/android/tradefed/cluster/SubprocessConfigBuilder.java
index a69dc86..4f76fc2 100644
--- a/src/com/android/tradefed/cluster/SubprocessConfigBuilder.java
+++ b/src/com/android/tradefed/cluster/SubprocessConfigBuilder.java
@@ -119,8 +119,12 @@
in = loader.getResourceAsStream(String.format("config/%s", mOriginalConfig));
}
if (in == null) {
+ File f = new File(mOriginalConfig);
+ if (!f.isAbsolute()) {
+ f = new File(mWorkDir, mOriginalConfig);
+ }
try {
- in = new FileInputStream(mOriginalConfig);
+ in = new FileInputStream(f);
} catch (FileNotFoundException e) {
throw new RuntimeException(
String.format("Could not find configuration '%s'", mOriginalConfig));
@@ -143,7 +147,7 @@
root.appendChild(reporter);
}
- File f = new File(mWorkDir, createConfigName(mOriginalConfig));
+ File f = new File(mWorkDir, mOriginalConfig);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
try {
Transformer transformer = transformerFactory.newTransformer();
diff --git a/src/com/android/tradefed/cluster/SubprocessReportingHelper.java b/src/com/android/tradefed/cluster/SubprocessReportingHelper.java
index e657226..4944859 100644
--- a/src/com/android/tradefed/cluster/SubprocessReportingHelper.java
+++ b/src/com/android/tradefed/cluster/SubprocessReportingHelper.java
@@ -42,7 +42,8 @@
private static final String REPORTER_JAR_NAME = "subprocess-results-reporter.jar";
private static final String CLASS_FILTER =
String.format(
- "(^%s|^%s|^%s|^%s|^%s).*class$",
+ "(^%s|^%s|^%s|^%s|^%s|^%s).*class$",
+ "ErrorIdentifier",
"LegacySubprocessResultsReporter",
"SubprocessTestResultsParser",
"SubprocessEventHelper",
diff --git a/src/com/android/tradefed/device/metric/FilePullerLogCollector.java b/src/com/android/tradefed/device/metric/FilePullerLogCollector.java
index 75cb203..5474433 100644
--- a/src/com/android/tradefed/device/metric/FilePullerLogCollector.java
+++ b/src/com/android/tradefed/device/metric/FilePullerLogCollector.java
@@ -42,9 +42,10 @@
String ext = FileUtil.getExtension(metricFile.getName()).toLowerCase();
if (".png".equals(ext)) {
type = LogDataType.PNG;
- }
- if (".pb".equals(ext)) {
+ } else if (".pb".equals(ext)) {
type = LogDataType.PB;
+ } else if (".mp4".equals(ext)) {
+ type = LogDataType.MP4;
}
testLog(metricFile.getName(), type, source);
}
diff --git a/src/com/android/tradefed/result/LogcatCrashResultForwarder.java b/src/com/android/tradefed/result/LogcatCrashResultForwarder.java
index 25d4e7b..8891069 100644
--- a/src/com/android/tradefed/result/LogcatCrashResultForwarder.java
+++ b/src/com/android/tradefed/result/LogcatCrashResultForwarder.java
@@ -107,7 +107,7 @@
}
error.setErrorMessage(errorMessage);
if (isCrash(errorMessage)) {
- error.setErrorIdentifier(DeviceErrorIdentifier.INSTRUMENATION_CRASH);
+ error.setErrorIdentifier(DeviceErrorIdentifier.INSTRUMENTATION_CRASH);
}
super.testRunFailed(error);
}
diff --git a/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java b/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
index ce4fabd..3c81407 100644
--- a/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
+++ b/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
@@ -158,7 +158,8 @@
String.format(
"Failed to activate %s on device %s.",
listApexInfo(failToActivateApex).toString(), device.getSerialNumber()),
- device.getDeviceDescriptor());
+ device.getDeviceDescriptor(),
+ DeviceErrorIdentifier.FAIL_ACTIVATE_APEX);
}
CLog.i("Train activation succeed.");
}
diff --git a/test_result_interfaces/com/android/tradefed/result/error/DeviceErrorIdentifier.java b/test_result_interfaces/com/android/tradefed/result/error/DeviceErrorIdentifier.java
index 150169c..72efb6a 100644
--- a/test_result_interfaces/com/android/tradefed/result/error/DeviceErrorIdentifier.java
+++ b/test_result_interfaces/com/android/tradefed/result/error/DeviceErrorIdentifier.java
@@ -24,13 +24,14 @@
// Device Errors: 520_001 ~ 530_000
// ********************************************************************************************
APK_INSTALLATION_FAILED(520_001, FailureStatus.DEPENDENCY_ISSUE),
+ FAIL_ACTIVATE_APEX(520_002, FailureStatus.DEPENDENCY_ISSUE),
AAPT_PARSER_FAILED(520_050, FailureStatus.DEPENDENCY_ISSUE),
SHELL_COMMAND_ERROR(520_100, FailureStatus.DEPENDENCY_ISSUE),
DEVICE_UNEXPECTED_RESPONSE(30_101, FailureStatus.DEPENDENCY_ISSUE),
- INSTRUMENATION_CRASH(520_200, FailureStatus.SYSTEM_UNDER_TEST_CRASHED),
+ INSTRUMENTATION_CRASH(520_200, FailureStatus.SYSTEM_UNDER_TEST_CRASHED),
FAILED_TO_LAUNCH_GCE(520_500, FailureStatus.LOST_SYSTEM_UNDER_TEST),
FAILED_TO_CONNECT_TO_GCE(520_501, FailureStatus.LOST_SYSTEM_UNDER_TEST),
diff --git a/tests/src/com/android/tradefed/cluster/ClusterCommandLauncherFuncTest.java b/tests/src/com/android/tradefed/cluster/ClusterCommandLauncherFuncTest.java
index 3bf18e0..0c7de73 100644
--- a/tests/src/com/android/tradefed/cluster/ClusterCommandLauncherFuncTest.java
+++ b/tests/src/com/android/tradefed/cluster/ClusterCommandLauncherFuncTest.java
@@ -15,6 +15,7 @@
*/
package com.android.tradefed.cluster;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -39,7 +40,9 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
@@ -52,8 +55,9 @@
public class ClusterCommandLauncherFuncTest {
private static final String LEGACY_TRADEFED_JAR = "/testdata/tradefed-prebuilt-cts-8.0_r21.jar";
- private static final String LEGACY_TRADEFED_COMMAND =
- "host --null-device --class com.android.tradefed.device.DeviceDiagTest";
+ private static final String LEGACY_TRADEFED_COMMAND = "fake.xml --null-device --run testRun PF";
+ private static final String LEGACY_TRADEFED_COMMAND_FOR_INVOCATION_FAILURE =
+ "fake.xml --null-device --fail-invocation-with-cause cause";
private File mRootDir;
private IConfiguration mConfiguration;
@@ -82,22 +86,50 @@
FileUtil.recursiveDelete(mRootDir);
}
- // @Ignore
@Test
public void testRun_withLegacyTradefed()
throws IOException, ConfigurationException, DeviceNotAvailableException {
File tfJar = new File(mRootDir, "tradefed.jar");
FileUtil.writeToFile(getClass().getResourceAsStream(LEGACY_TRADEFED_JAR), tfJar);
+ FileUtil.writeToFile(
+ getClass().getResourceAsStream("/config/tf/fake.xml"),
+ new File(mRootDir, "fake.xml"));
mOptionSetter.setOptionValue("cluster:env-var", "TF_PATH", mRootDir.getAbsolutePath());
mOptionSetter.setOptionValue("cluster:use-subprocess-reporting", "true");
mOptionSetter.setOptionValue("cluster:command-line", LEGACY_TRADEFED_COMMAND);
mLauncher.run(mTestInformation, mListener);
+ InOrder inOrder = Mockito.inOrder(mListener);
HashMap<String, MetricMeasurement.Metric> emptyMap = new HashMap<>();
- verify(mListener).testRunStarted(anyString(), anyInt(), anyInt(), anyLong());
- verify(mListener).testStarted(any(TestDescription.class), anyLong());
- verify(mListener).testEnded(any(TestDescription.class), anyLong(), eq(emptyMap));
- verify(mListener).testRunEnded(anyLong(), eq(emptyMap));
+ inOrder.verify(mListener).testRunStarted(eq("testRun"), anyInt(), anyInt(), anyLong());
+ inOrder.verify(mListener).testStarted(any(TestDescription.class), anyLong());
+ inOrder.verify(mListener).testEnded(any(TestDescription.class), anyLong(), eq(emptyMap));
+ inOrder.verify(mListener).testStarted(any(TestDescription.class), anyLong());
+ inOrder.verify(mListener).testFailed(any(TestDescription.class), anyString());
+ inOrder.verify(mListener).testEnded(any(TestDescription.class), anyLong(), eq(emptyMap));
+ inOrder.verify(mListener).testRunEnded(anyLong(), eq(emptyMap));
+ }
+
+ @Test
+ public void testRun_withLegacyTradefed_invocationFailed()
+ throws IOException, ConfigurationException, DeviceNotAvailableException {
+ File tfJar = new File(mRootDir, "tradefed.jar");
+ FileUtil.writeToFile(getClass().getResourceAsStream(LEGACY_TRADEFED_JAR), tfJar);
+ FileUtil.writeToFile(
+ getClass().getResourceAsStream("/config/tf/fake.xml"),
+ new File(mRootDir, "fake.xml"));
+ mOptionSetter.setOptionValue("cluster:env-var", "TF_PATH", mRootDir.getAbsolutePath());
+ mOptionSetter.setOptionValue("cluster:use-subprocess-reporting", "true");
+ mOptionSetter.setOptionValue(
+ "cluster:command-line", LEGACY_TRADEFED_COMMAND_FOR_INVOCATION_FAILURE);
+
+ try {
+ mLauncher.run(mTestInformation, mListener);
+ fail("RuntimeException should be thrown");
+ } catch (RuntimeException e) {
+ }
+
+ verify(mListener).invocationFailed(any(Throwable.class));
}
}
diff --git a/tests/src/com/android/tradefed/cluster/ClusterCommandSchedulerTest.java b/tests/src/com/android/tradefed/cluster/ClusterCommandSchedulerTest.java
index 0a20930..d4befb9 100644
--- a/tests/src/com/android/tradefed/cluster/ClusterCommandSchedulerTest.java
+++ b/tests/src/com/android/tradefed/cluster/ClusterCommandSchedulerTest.java
@@ -1421,8 +1421,8 @@
// command status is CANCELED
mMockClusterClient = Mockito.mock(IClusterClient.class, RETURNS_DEEP_STUBS);
- Mockito.when(mMockClusterClient.getCommandState(any(), any()))
- .thenReturn(ClusterCommand.State.CANCELED);
+ Mockito.when(mMockClusterClient.getCommandStatus(any(), any()))
+ .thenReturn(new ClusterCommandStatus(ClusterCommand.State.CANCELED, "Reason"));
// not stopped if check is disabled
mMockClusterOptions.setCheckCommandState(false);
@@ -1434,7 +1434,7 @@
heartbeat.run();
assertTrue(scheduler.wasStopInvocationCalled());
- Mockito.verify(mMockClusterClient, Mockito.times(1)).getCommandState(any(), any());
+ Mockito.verify(mMockClusterClient, Mockito.times(1)).getCommandStatus(any(), any());
}
/** Tests whether the heartbeat can determine the invocationId to stop. */
@@ -1450,8 +1450,8 @@
// command status is CANCELED
mMockClusterClient = Mockito.mock(IClusterClient.class, RETURNS_DEEP_STUBS);
- Mockito.when(mMockClusterClient.getCommandState(any(), any()))
- .thenReturn(ClusterCommand.State.CANCELED);
+ Mockito.when(mMockClusterClient.getCommandStatus(any(), any()))
+ .thenReturn(new ClusterCommandStatus(ClusterCommand.State.CANCELED, "Reason"));
// not stopped without invocation context
heartbeat.run();
@@ -1473,7 +1473,7 @@
heartbeat.run();
assertTrue(scheduler.wasStopInvocationCalled());
- Mockito.verify(mMockClusterClient, Mockito.times(4)).getCommandState(any(), any());
+ Mockito.verify(mMockClusterClient, Mockito.times(4)).getCommandStatus(any(), any());
}
/** Tests whether the heartbeat can determine the cluster command state. */