Replicate retry logic in external factory
Avoid using compatibilitytest as entry point for the retry
logic.
Provide a new retry.xml configuration to use retry.
Test: run retry --retry <id>
Bug: 36337428
Change-Id: Id67bc92ca4b2536ddf94fc0ba24305b47695a7fe
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
index c0483e2..fc329af 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
@@ -676,7 +676,6 @@
void setupFilters() throws DeviceNotAvailableException {
if (mRetrySessionId != null) {
// Load the invocation result
- IInvocationResult result = null;
RetryFilterHelper helper = new RetryFilterHelper(mBuildHelper, mRetrySessionId);
helper.validateBuildFingerprint(mDevice);
helper.setAllOptionsFrom(this);
@@ -775,4 +774,18 @@
public void setCollectTestsOnly(boolean collectTestsOnly) {
mCollectTestsOnly = collectTestsOnly;
}
+
+ /**
+ * Sets include-filters for the compatibility test
+ */
+ public void setIncludeFilter(Set<String> includeFilters) {
+ mIncludeFilters.addAll(includeFilters);
+ }
+
+ /**
+ * Sets exclude-filters for the compatibility test
+ */
+ public void setExcludeFilter(Set<String> excludeFilters) {
+ mExcludeFilters.addAll(excludeFilters);
+ }
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
new file mode 100644
index 0000000..f47363e
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2017 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.compatibility.common.tradefed.testtype.retry;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
+import com.android.compatibility.common.tradefed.util.RetryFilterHelper;
+import com.android.compatibility.common.tradefed.util.RetryType;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.ConfigurationException;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.suite.checker.ISystemStatusChecker;
+import com.android.tradefed.suite.checker.ISystemStatusCheckerReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.IRemoteTest;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Runner that creates a {@link CompatibilityTest} to re-run some previous results.
+ * Only the 'cts' plan is supported.
+ * TODO: explore other new way to build the retry (instead of relying on one massive pair of
+ * include/exclude filters)
+ */
+@OptionClass(alias = "compatibility")
+public class RetryFactoryTest implements IRemoteTest, IDeviceTest, IBuildReceiver,
+ ISystemStatusCheckerReceiver {
+
+ /**
+ * Mirror the {@link CompatibilityTest} options in order to pass them to the Helper.
+ */
+ public static final String RETRY_OPTION = "retry";
+ @Option(name = RETRY_OPTION,
+ shortName = 'r',
+ description = "retry a previous session's failed and not executed tests.",
+ mandatory = true)
+ private Integer mRetrySessionId = null;
+
+ @Option(name = CompatibilityTest.SUBPLAN_OPTION,
+ description = "the subplan to run",
+ importance = Importance.IF_UNSET)
+ protected String mSubPlan;
+
+ @Option(name = CompatibilityTest.INCLUDE_FILTER_OPTION,
+ description = "the include module filters to apply.",
+ importance = Importance.ALWAYS)
+ protected Set<String> mIncludeFilters = new HashSet<>();
+
+ @Option(name = CompatibilityTest.EXCLUDE_FILTER_OPTION,
+ description = "the exclude module filters to apply.",
+ importance = Importance.ALWAYS)
+ protected Set<String> mExcludeFilters = new HashSet<>();
+
+ @Option(name = CompatibilityTest.ABI_OPTION,
+ shortName = 'a',
+ description = "the abi to test.",
+ importance = Importance.IF_UNSET)
+ protected String mAbiName = null;
+
+ @Option(name = CompatibilityTest.MODULE_OPTION,
+ shortName = 'm',
+ description = "the test module to run.",
+ importance = Importance.IF_UNSET)
+ protected String mModuleName = null;
+
+ @Option(name = CompatibilityTest.TEST_OPTION,
+ shortName = CompatibilityTest.TEST_OPTION_SHORT_NAME,
+ description = "the test run.",
+ importance = Importance.IF_UNSET)
+ protected String mTestName = null;
+
+ @Option(name = CompatibilityTest.RETRY_TYPE_OPTION,
+ description = "used with " + CompatibilityTest.RETRY_OPTION + ", retry tests"
+ + " of a certain status. Possible values include \"failed\" and \"not_executed\".",
+ importance = Importance.IF_UNSET)
+ protected RetryType mRetryType = null;
+
+ private List<ISystemStatusChecker> mStatusCheckers;
+ private IBuildInfo mBuildInfo;
+ private ITestDevice mDevice;
+
+ @Override
+ public void setSystemStatusChecker(List<ISystemStatusChecker> systemCheckers) {
+ mStatusCheckers = systemCheckers;
+ }
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mBuildInfo = buildInfo;
+ }
+
+ @Override
+ public void setDevice(ITestDevice device) {
+ mDevice = device;
+ }
+
+ @Override
+ public ITestDevice getDevice() {
+ return mDevice;
+ }
+
+ /**
+ * Build a CompatibilityTest with appropriate filters to run only the tests of interests.
+ */
+ @Override
+ public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+ // Create a compatibility test and set it to run only what we want.
+ CompatibilityTest test = new CompatibilityTest();
+
+ CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuildInfo);
+ RetryFilterHelper helper = new RetryFilterHelper(buildHelper, mRetrySessionId);
+ helper.validateBuildFingerprint(mDevice);
+ helper.setAllOptionsFrom(this);
+ helper.setCommandLineOptionsFor(test);
+ helper.setCommandLineOptionsFor(this);
+ helper.populateRetryFilters();
+
+ try {
+ OptionSetter setter = new OptionSetter(test);
+ setter.setOptionValue("compatibility:test-arg",
+ "com.android.tradefed.testtype.AndroidJUnitTest:rerun-from-file:true");
+ setter.setOptionValue("compatibility:test-arg",
+ "com.android.tradefed.testtype.AndroidJUnitTest:fallback-to-serial-rerun:"
+ + "false");
+ } catch (ConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+
+ test.setIncludeFilter(helper.getIncludeFilters());
+ test.setExcludeFilter(helper.getExcludeFilters());
+ test.setDevice(mDevice);
+ test.setBuild(mBuildInfo);
+ test.setSystemStatusChecker(mStatusCheckers);
+ // clean the helper
+ helper.tearDown();
+ // run the retry run.
+ test.run(listener);
+ }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
index 4ff3953..e6771d3 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
@@ -19,8 +19,8 @@
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.compatibility.common.tradefed.result.SubPlanHelper;
import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
-import com.android.compatibility.common.tradefed.testtype.ModuleRepo;
import com.android.compatibility.common.tradefed.testtype.ISubPlan;
+import com.android.compatibility.common.tradefed.testtype.ModuleRepo;
import com.android.compatibility.common.util.IInvocationResult;
import com.android.compatibility.common.util.LightInvocationResult;
import com.android.compatibility.common.util.ResultHandler;
@@ -33,7 +33,6 @@
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.util.ArrayUtil;
import java.io.FileNotFoundException;
@@ -127,7 +126,7 @@
/**
* Set a single option on this instance of RetryFilterHelper
- * @throws {@link ConfigurationException} if the option cannot be set.
+ * @throw {@link ConfigurationException} if the option cannot be set.
*/
public void setOption(String option, String value) throws ConfigurationException {
OptionSetter setter = new OptionSetter(this);
diff --git a/tools/cts-tradefed/res/config/retry.xml b/tools/cts-tradefed/res/config/retry.xml
new file mode 100644
index 0000000..c4a7ced
--- /dev/null
+++ b/tools/cts-tradefed/res/config/retry.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<configuration description="Runs a retry of a previous CTS session.">
+
+ <device_recovery class="com.android.tradefed.device.WaitDeviceRecovery" />
+ <build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
+ <test class="com.android.compatibility.common.tradefed.testtype.retry.RetryFactoryTest" />
+ <logger class="com.android.tradefed.log.FileLogger">
+ <option name="log-level-display" value="WARN" />
+ </logger>
+
+ <include name="cts-preconditions" />
+ <include name="cts-system-checkers" />
+ <include name="cts-known-failures" />
+
+ <option name="plan" value="cts-retry" />
+ <option name="test-tag" value="cts" />
+ <option name="skip-device-info" value="true" />
+ <option name="enable-root" value="false" />
+
+ <result_reporter class="com.android.compatibility.common.tradefed.result.ConsoleReporter" />
+ <result_reporter class="com.android.compatibility.common.tradefed.result.ResultReporter" />
+
+ <template-include name="reporters" default="basic-reporters" />
+
+ <!-- Include additional test metadata output. -->
+ <template-include name="metadata-reporters" default="empty" />
+
+</configuration>