aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreasoncylee <easoncylee@google.com>2019-09-19 18:48:28 +0800
committereasoncylee <easoncylee@google.com>2019-10-08 09:19:39 +0800
commit3e1954cc4ec294bd6eeabbf687f95a9c367ea086 (patch)
tree694a2057e804afe93f08879a4fe8ac9d4cd385f9
parent2e3c27b74a903f647ed4e4bdd51d945c135fea01 (diff)
downloadtradefederation-3e1954cc4ec294bd6eeabbf687f95a9c367ea086.tar.gz
Run Test Mapping tests with different options inside a single suite.
Reason: This CL is to support TMSR running tests with different test options defined in TEST_MAPPING. Bug: 117880789 Test: unittests. Change-Id: I405eeeb353460e424d4df88d66ca40676e600da7
-rw-r--r--src/com/android/tradefed/testtype/suite/BaseTestSuite.java27
-rw-r--r--src/com/android/tradefed/testtype/suite/SuiteModuleLoader.java20
-rw-r--r--src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java238
-rw-r--r--src/com/android/tradefed/util/testmapping/TestMapping.java2
-rw-r--r--tests/src/com/android/tradefed/testtype/suite/SuiteModuleLoaderTest.java80
-rw-r--r--tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java201
-rw-r--r--tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java4
7 files changed, 479 insertions, 93 deletions
diff --git a/src/com/android/tradefed/testtype/suite/BaseTestSuite.java b/src/com/android/tradefed/testtype/suite/BaseTestSuite.java
index b2835469a..f43c7af3f 100644
--- a/src/com/android/tradefed/testtype/suite/BaseTestSuite.java
+++ b/src/com/android/tradefed/testtype/suite/BaseTestSuite.java
@@ -184,6 +184,7 @@ public class BaseTestSuite extends ITestSuite {
private SuiteModuleLoader mModuleRepo;
private Map<String, List<SuiteTestFilter>> mIncludeFiltersParsed = new HashMap<>();
private Map<String, List<SuiteTestFilter>> mExcludeFiltersParsed = new HashMap<>();
+ private List<File> mConfigPaths = new ArrayList<>();
/** {@inheritDoc} */
@Override
@@ -304,6 +305,12 @@ public class BaseTestSuite extends ITestSuite {
public LinkedHashMap<String, IConfiguration> loadingStrategy(
Set<IAbi> abis, List<File> testsDirs, String suitePrefix, String suiteTag) {
LinkedHashMap<String, IConfiguration> loadedConfigs = new LinkedHashMap<>();
+ // Load and return directly the specific config files.
+ if (!mConfigPaths.isEmpty()) {
+ CLog.d("Loading the specified configs and skip loading from the resources.");
+ return getModuleLoader().loadConfigsFromSpecifiedPaths(mConfigPaths, abis, suiteTag);
+ }
+
// Load configs that are part of the resources
if (!mSkipJarLoading) {
loadedConfigs.putAll(
@@ -360,6 +367,11 @@ public class BaseTestSuite extends ITestSuite {
mModuleArgs.addAll(moduleArgs);
}
+ /** Clear the stored module args out */
+ void clearModuleArgs() {
+ mModuleArgs.clear();
+ }
+
/** Add config patterns */
public void addConfigPatterns(List<String> patterns) {
mConfigPatterns.addAll(patterns);
@@ -463,6 +475,21 @@ public class BaseTestSuite extends ITestSuite {
mExcludeFiltersParsed.clear();
}
+ /**
+ * Add the config path for {@link SuiteModuleLoader} to limit the search loading
+ * configurations.
+ *
+ * @param configPath A {@code File} with the absolute path of the configuration.
+ */
+ void addConfigPaths(File configPath) {
+ mConfigPaths.add(configPath);
+ }
+
+ /** Clear the stored config paths out. */
+ void clearConfigPaths() {
+ mConfigPaths.clear();
+ }
+
/* Helper method designed to remove filters in a list not applicable to the given module */
private static void checkFilters(Set<String> filters, String moduleName) {
Set<String> cleanedFilters = new HashSet<String>();
diff --git a/src/com/android/tradefed/testtype/suite/SuiteModuleLoader.java b/src/com/android/tradefed/testtype/suite/SuiteModuleLoader.java
index 08dd62613..1884504fb 100644
--- a/src/com/android/tradefed/testtype/suite/SuiteModuleLoader.java
+++ b/src/com/android/tradefed/testtype/suite/SuiteModuleLoader.java
@@ -117,6 +117,20 @@ public class SuiteModuleLoader {
mExcludedModuleParameters = excludedParams;
}
+ /** Main loading of configurations, looking into the specified files */
+ public LinkedHashMap<String, IConfiguration> loadConfigsFromSpecifiedPaths(
+ List<File> listConfigFiles,
+ Set<IAbi> abis,
+ String suiteTag) {
+ LinkedHashMap<String, IConfiguration> toRun = new LinkedHashMap<>();
+ for (File configFile : listConfigFiles) {
+ toRun.putAll(
+ loadOneConfig(
+ configFile.getName(), configFile.getAbsolutePath(), abis, suiteTag));
+ }
+ return toRun;
+ }
+
/** Main loading of configurations, looking into a folder */
public LinkedHashMap<String, IConfiguration> loadConfigsFromDirectory(
List<File> testsDirs,
@@ -130,11 +144,7 @@ public class SuiteModuleLoader {
ConfigurationUtil.getConfigNamesFileFromDirs(suitePrefix, testsDirs, patterns));
// Ensure stable initial order of configurations.
Collections.sort(listConfigFiles);
- for (File configFile : listConfigFiles) {
- toRun.putAll(
- loadOneConfig(
- configFile.getName(), configFile.getAbsolutePath(), abis, suiteTag));
- }
+ toRun.putAll(loadConfigsFromSpecifiedPaths(listConfigFiles, abis, suiteTag));
return toRun;
}
diff --git a/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java b/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java
index b13ffa7a5..89d4545bc 100644
--- a/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java
+++ b/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java
@@ -19,12 +19,14 @@ import com.android.tradefed.config.ConfigurationDescriptor;
import com.android.tradefed.config.IConfiguration;
import com.android.tradefed.config.Option;
import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.util.testmapping.TestInfo;
import com.android.tradefed.util.testmapping.TestMapping;
import com.android.tradefed.util.testmapping.TestOption;
+import com.google.common.annotations.VisibleForTesting;
+import java.io.File;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -89,10 +91,10 @@ public class TestMappingSuiteRunner extends BaseTestSuite {
*/
@Override
public LinkedHashMap<String, IConfiguration> loadTests() {
- // Map between test names and a list of test sources for each test.
- Map<String, List<String>> testsInTestMapping = new HashMap<>();
-
Set<String> includeFilter = getIncludeFilter();
+ // Name of the tests
+ Set<String> testNames = new HashSet<>();
+ Set<TestInfo> testInfosToRun = new HashSet<>();
if (mTestGroup == null && includeFilter.isEmpty()) {
throw new RuntimeException(
"At least one of the options, --test-mapping-test-group or --include-filter, "
@@ -114,96 +116,184 @@ public class TestMappingSuiteRunner extends BaseTestSuite {
}
if (mTestGroup != null) {
- Set<TestInfo> testsToRun =
+ testInfosToRun =
TestMapping.getTests(
getBuildInfo(), mTestGroup, getPrioritizeHostConfig(), mKeywords);
if (!mTestModulesForced.isEmpty()) {
CLog.i("Filtering tests for the given names: %s", mTestModulesForced);
- testsToRun =
- testsToRun
+ testInfosToRun =
+ testInfosToRun
.stream()
.filter(testInfo -> mTestModulesForced.contains(testInfo.getName()))
.collect(Collectors.toSet());
}
- if (testsToRun.isEmpty()) {
+ if (testInfosToRun.isEmpty()) {
throw new RuntimeException(
String.format("No test found for the given group: %s.", mTestGroup));
}
-
- // Name of the tests
- Set<String> testNames = new HashSet<>();
-
- Set<String> mappingIncludeFilters = new HashSet<>();
- Set<String> mappingExcludeFilters = new HashSet<>();
-
- // module-arg options compiled from test options for each test.
- Set<String> moduleArgs = new HashSet<>();
- for (TestInfo test : testsToRun) {
- boolean hasIncludeFilters = false;
- for (TestOption option : test.getOptions()) {
- switch (option.getName()) {
- // Handle include and exclude filter at the suite level to hide each
- // test runner specific implementation and option names related to filtering
- case TEST_MAPPING_INCLUDE_FILTER:
- hasIncludeFilters = true;
- mappingIncludeFilters.add(
- String.format("%s %s", test.getName(), option.getValue()));
- break;
- case TEST_MAPPING_EXCLUDE_FILTER:
- mappingExcludeFilters.add(
- String.format("%s %s", test.getName(), option.getValue()));
- break;
- default:
- String moduleArg =
- String.format("%s:%s", test.getName(), option.getName());
- if (option.getValue() != null && !option.getValue().isEmpty()) {
- moduleArg = String.format("%s:%s", moduleArg, option.getValue());
- }
- moduleArgs.add(moduleArg);
- break;
- }
- }
- if (!hasIncludeFilters) {
- testNames.add(test.getName());
- }
+ for (TestInfo testInfo : testInfosToRun) {
+ testNames.add(testInfo.getName());
}
+ setIncludeFilter(testNames);
+ }
+
+ // load all the configurations with include-filter injected.
+ LinkedHashMap<String, IConfiguration> testConfigs = super.loadTests();
- if (mappingIncludeFilters.isEmpty()) {
- setIncludeFilter(testNames);
- } else {
- mappingIncludeFilters.addAll(testNames);
- setIncludeFilter(mappingIncludeFilters);
+ // Create and inject individual tests by calling super.loadTests() with each test info.
+ for (Map.Entry<String, IConfiguration> entry : testConfigs.entrySet()) {
+ List<IRemoteTest> allTests = new ArrayList<>();
+ IConfiguration moduleConfig = entry.getValue();
+ ConfigurationDescriptor configDescriptor =
+ moduleConfig.getConfigurationDescription();
+ String moduleName = configDescriptor.getModuleName();
+ String configPath = moduleConfig.getName();
+ Set<TestInfo> testInfos = getTestInfos(testInfosToRun, moduleName);
+ allTests.addAll(
+ createIndividualTests(
+ testInfos, configPath));
+ if (!allTests.isEmpty()) {
+ // Set back to IConfiguration only if IRemoteTests are created.
+ moduleConfig.setTests(allTests);
+ // Set test sources to ConfigurationDescriptor.
+ List<String> testSources = getTestSources(testInfos);
+ configDescriptor.addMetaData(TestMapping.TEST_SOURCES, testSources);
}
- if (!mappingExcludeFilters.isEmpty()) {
- setExcludeFilter(mappingExcludeFilters);
+ }
+ return testConfigs;
+ }
+
+ /**
+ * Create individual tests with test infos for a module.
+ *
+ * @param testInfos A {@code Set<TestInfo>} containing multiple test options.
+ * @param configPath A {@code String} of configuration path.
+ * @return The {@link List<IRemoteTest>} that are injected with the test options.
+ */
+ @VisibleForTesting
+ List<IRemoteTest> createIndividualTests(Set<TestInfo> testInfos, String configPath) {
+ List<IRemoteTest> tests = new ArrayList<>();
+ if (configPath == null) {
+ throw new RuntimeException(String.format("Configuration path is null."));
+ }
+ File configFie = new File(configPath);
+ if (!configFie.exists()) {
+ throw new RuntimeException(
+ String.format("Configuration path: %s doesn't exits.", configPath));
+ }
+ // De-duplicate test infos so that there won't be duplicate test options.
+ testInfos = dedupTestInfos(testInfos);
+ for (TestInfo testInfo : testInfos) {
+ // Clean up all the test options injected in SuiteModuleLoader.
+ super.cleanUpSuiteSetup();
+ super.clearModuleArgs();
+ clearConfigPaths();
+ // Set config path to BaseTestSuite to limit the search.
+ addConfigPaths(configFie);
+ // Inject the test options from each test info to SuiteModuleLoader.
+ parseOptions(testInfo);
+ LinkedHashMap<String, IConfiguration> config = super.loadTests();
+ for (Map.Entry<String, IConfiguration> entry : config.entrySet()) {
+ tests.addAll(entry.getValue().getTests());
}
- addModuleArgs(moduleArgs);
-
- for (TestInfo test : testsToRun) {
- List<String> testSources = null;
- // TODO(b/117880789): tests may not be grouped by name once that bug is fixed.
- // Update the dictionary with better keys.
- if (testsInTestMapping.containsKey(test.getName())) {
- testSources = testsInTestMapping.get(test.toString());
- } else {
- testSources = new ArrayList<String>();
- testsInTestMapping.put(test.getName(), testSources);
- }
- testSources.addAll(test.getSources());
+ }
+ return tests;
+ }
+
+ /**
+ * Get a list of path of TEST_MAPPING for a module.
+ *
+ * @param testInfos A {@code Set<TestInfo>} containing multiple test options.
+ * @return A {@code List<String>} of TEST_MAPPING path.
+ */
+ @VisibleForTesting
+ List<String> getTestSources(Set<TestInfo> testInfos) {
+ List<String> testSources = new ArrayList<>();
+ for (TestInfo testInfo : testInfos) {
+ testSources.addAll(testInfo.getSources());
+ }
+ return testSources;
+ }
+
+ /**
+ * Parse the test options for the test info.
+ *
+ * @param testInfo A {@code Set<TestInfo>} containing multiple test options.
+ */
+ @VisibleForTesting
+ void parseOptions(TestInfo testInfo) {
+ Set<String> mappingIncludeFilters = new HashSet<>();
+ Set<String> mappingExcludeFilters = new HashSet<>();
+ // module-arg options compiled from test options for each test.
+ Set<String> moduleArgs = new HashSet<>();
+ Set<String> testNames = new HashSet<>();
+ for (TestOption option : testInfo.getOptions()) {
+ switch (option.getName()) {
+ // Handle include and exclude filter at the suite level to hide each
+ // test runner specific implementation and option names related to filtering
+ case TEST_MAPPING_INCLUDE_FILTER:
+ mappingIncludeFilters.add(
+ String.format("%s %s", testInfo.getName(), option.getValue()));
+ break;
+ case TEST_MAPPING_EXCLUDE_FILTER:
+ mappingExcludeFilters.add(
+ String.format("%s %s", testInfo.getName(), option.getValue()));
+ break;
+ default:
+ String moduleArg =
+ String.format("%s:%s", testInfo.getName(), option.getName());
+ if (option.getValue() != null && !option.getValue().isEmpty()) {
+ moduleArg = String.format("%s:%s", moduleArg, option.getValue());
+ }
+ moduleArgs.add(moduleArg);
+ break;
}
}
- LinkedHashMap<String, IConfiguration> testConfigs = super.loadTests();
- for (Map.Entry<String, IConfiguration> entry : testConfigs.entrySet()) {
- ConfigurationDescriptor configDescriptor =
- entry.getValue().getConfigurationDescription();
- if (testsInTestMapping.containsKey(configDescriptor.getModuleName())) {
- configDescriptor.addMetaData(
- TestMapping.TEST_SOURCES,
- testsInTestMapping.get(configDescriptor.getModuleName()));
+ if (mappingIncludeFilters.isEmpty()) {
+ testNames.add(testInfo.getName());
+ setIncludeFilter(testNames);
+ } else {
+ setIncludeFilter(mappingIncludeFilters);
+ }
+ if (!mappingExcludeFilters.isEmpty()) {
+ setExcludeFilter(mappingExcludeFilters);
+ }
+ addModuleArgs(moduleArgs);
+ }
+
+ /**
+ * De-duplicate test infos with the same test options.
+ *
+ * @param testInfos A {@code Set<TestInfo>} containing multiple test options.
+ * @return A {@code Set<TestInfo>} of tests without duplicated test options.
+ */
+ @VisibleForTesting
+ Set<TestInfo> dedupTestInfos(Set<TestInfo> testInfos) {
+ Set<String> nameOptions = new HashSet<>();
+ Set<TestInfo> dedupTestInfos = new HashSet<>();
+ for (TestInfo testInfo : testInfos) {
+ String nameOption = testInfo.getName() + testInfo.getOptions().toString();
+ if (!nameOptions.contains(nameOption)) {
+ dedupTestInfos.add(testInfo);
+ nameOptions.add(nameOption);
}
}
+ return dedupTestInfos;
+ }
- return testConfigs;
+ /**
+ * Get the test infos for the given module name.
+ *
+ * @param testInfos A {@code Set<TestInfo>} containing multiple test options.
+ * @param moduleName A {@code String} name of a test module.
+ * @return A {@code Set<TestInfo>} of tests for a module.
+ */
+ @VisibleForTesting
+ Set<TestInfo> getTestInfos(Set<TestInfo> testInfos, String moduleName) {
+ return testInfos
+ .stream()
+ .filter(testInfo -> moduleName.equals(testInfo.getName()))
+ .collect(Collectors.toSet());
}
}
diff --git a/src/com/android/tradefed/util/testmapping/TestMapping.java b/src/com/android/tradefed/util/testmapping/TestMapping.java
index 8221d1eab..1b02e29a5 100644
--- a/src/com/android/tradefed/util/testmapping/TestMapping.java
+++ b/src/com/android/tradefed/util/testmapping/TestMapping.java
@@ -281,7 +281,7 @@ public class TestMapping {
FileUtil.recursiveDelete(testMappingsDir);
}
- return TestMapping.mergeTests(tests);
+ return tests;
}
/**
diff --git a/tests/src/com/android/tradefed/testtype/suite/SuiteModuleLoaderTest.java b/tests/src/com/android/tradefed/testtype/suite/SuiteModuleLoaderTest.java
index b5bbd8129..e2a23aebd 100644
--- a/tests/src/com/android/tradefed/testtype/suite/SuiteModuleLoaderTest.java
+++ b/tests/src/com/android/tradefed/testtype/suite/SuiteModuleLoaderTest.java
@@ -17,6 +17,7 @@ package com.android.tradefed.testtype.suite;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.android.tradefed.config.IConfiguration;
@@ -287,4 +288,83 @@ public class SuiteModuleLoaderTest {
assertEquals(
"NativeDnsAsyncTest#Async_Cancel", stubTest.getExcludeFilters().iterator().next());
}
+
+ /**
+ * Test that the configuration can be found if specifying specific path.
+ */
+ @Test
+ public void testLoadConfigsFromSpecifiedPaths_OneModule() throws Exception {
+ createModuleConfig("module1");
+ File module1 = new File(mTestsDir, "module1" + SuiteModuleLoader.CONFIG_EXT);
+
+ mRepo =
+ new SuiteModuleLoader(
+ new LinkedHashMap<String, List<SuiteTestFilter>>(),
+ new LinkedHashMap<String, List<SuiteTestFilter>>(),
+ new ArrayList<>(),
+ new ArrayList<>());
+
+ LinkedHashMap<String, IConfiguration> res =
+ mRepo.loadConfigsFromSpecifiedPaths(
+ Arrays.asList(module1), mAbis, null);
+ assertEquals(1, res.size());
+ assertNotNull(res.get("armeabi-v7a module1"));
+ }
+
+ /**
+ * Test that multiple configurations can be found if specifying specific paths.
+ */
+ @Test
+ public void testLoadConfigsFromSpecifiedPaths_MultipleModules() throws Exception {
+ createModuleConfig("module1");
+ File module1 = new File(mTestsDir, "module1" + SuiteModuleLoader.CONFIG_EXT);
+ createModuleConfig("module2");
+ File module2 = new File(mTestsDir, "module2" + SuiteModuleLoader.CONFIG_EXT);
+
+ mRepo =
+ new SuiteModuleLoader(
+ new LinkedHashMap<String, List<SuiteTestFilter>>(),
+ new LinkedHashMap<String, List<SuiteTestFilter>>(),
+ new ArrayList<>(),
+ new ArrayList<>());
+
+ LinkedHashMap<String, IConfiguration> res =
+ mRepo.loadConfigsFromSpecifiedPaths(
+ Arrays.asList(module1, module2), mAbis, null);
+ assertEquals(2, res.size());
+ assertNotNull(res.get("armeabi-v7a module1"));
+ assertNotNull(res.get("armeabi-v7a module2"));
+ }
+
+ /**
+ * Test that configuration can be found correctly if specifying specific paths but someone is
+ * excluded.
+ */
+ @Test
+ public void testLoadConfigsFromSpecifiedPaths_WithExcludeFilter() throws Exception {
+ createModuleConfig("module1");
+ File module1 = new File(mTestsDir, "module1" + SuiteModuleLoader.CONFIG_EXT);
+ createModuleConfig("module2");
+ File module2 = new File(mTestsDir, "module2" + SuiteModuleLoader.CONFIG_EXT);
+
+ Map<String, List<SuiteTestFilter>> excludeFilters = new LinkedHashMap<>();
+ SuiteTestFilter filter =
+ SuiteTestFilter.createFrom(
+ "armeabi-v7a module2");
+ excludeFilters.put("armeabi-v7a module2", Arrays.asList(filter));
+
+ mRepo =
+ new SuiteModuleLoader(
+ new LinkedHashMap<String, List<SuiteTestFilter>>(),
+ excludeFilters,
+ new ArrayList<>(),
+ new ArrayList<>());
+
+ LinkedHashMap<String, IConfiguration> res =
+ mRepo.loadConfigsFromSpecifiedPaths(
+ Arrays.asList(module1, module2), mAbis, null);
+ assertEquals(1, res.size());
+ assertNotNull(res.get("armeabi-v7a module1"));
+ assertNull(res.get("armeabi-v7a module2"));
+ }
}
diff --git a/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java b/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java
index b2028d87f..48b660061 100644
--- a/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java
+++ b/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertTrue;
import com.android.tradefed.build.BuildInfoKey.BuildInfoFileKey;
import com.android.tradefed.build.IDeviceBuildInfo;
+import com.android.tradefed.config.ConfigurationException;
+import com.android.tradefed.config.ConfigurationFactory;
import com.android.tradefed.config.IConfiguration;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.DeviceNotAvailableException;
@@ -31,8 +33,11 @@ import com.android.tradefed.testtype.StubTest;
import com.android.tradefed.util.AbiUtils;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.testmapping.TestInfo;
import com.android.tradefed.util.testmapping.TestMapping;
+import com.android.tradefed.util.testmapping.TestOption;
+import java.util.ArrayList;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
@@ -57,14 +62,17 @@ public class TestMappingSuiteRunnerTest {
private static final String ABI_1 = "arm64-v8a";
private static final String ABI_2 = "armeabi-v7a";
+ private static final String DISABLED_PRESUBMIT_TESTS = "disabled-presubmit-tests";
+ private static final String EMPTY_CONFIG = "empty";
private static final String NON_EXISTING_DIR = "non-existing-dir";
+ private static final String TEST_CONFIG_NAME = "test";
private static final String TEST_DATA_DIR = "testdata";
private static final String TEST_MAPPING = "TEST_MAPPING";
private static final String TEST_MAPPINGS_ZIP = "test_mappings.zip";
- private static final String DISABLED_PRESUBMIT_TESTS = "disabled-presubmit-tests";
private TestMappingSuiteRunner mRunner;
private OptionSetter mOptionSetter;
+ private TestMappingSuiteRunner mRunner2;
private IDeviceBuildInfo mBuildInfo;
private ITestDevice mMockDevice;
@@ -79,8 +87,13 @@ public class TestMappingSuiteRunnerTest {
mOptionSetter = new OptionSetter(mRunner);
mOptionSetter.setOptionValue("suite-config-prefix", "suite");
- EasyMock.expect(mBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).andReturn(null);
- EasyMock.expect(mBuildInfo.getTestsDir()).andReturn(new File(NON_EXISTING_DIR));
+ mRunner2 = new FakeTestMappingSuiteRunner();
+ mRunner2.setBuild(mBuildInfo);
+ mRunner2.setDevice(mMockDevice);
+
+ EasyMock.expect(mBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).andReturn(null)
+ .anyTimes();
+ EasyMock.expect(mBuildInfo.getTestsDir()).andReturn(new File(NON_EXISTING_DIR)).anyTimes();
EasyMock.expect(mMockDevice.getProperty(EasyMock.anyObject())).andReturn(ABI_1);
EasyMock.expect(mMockDevice.getProperty(EasyMock.anyObject())).andReturn(ABI_2);
EasyMock.replay(mBuildInfo, mMockDevice);
@@ -98,6 +111,43 @@ public class TestMappingSuiteRunnerTest {
abis.add(new Abi(ABI_2, AbiUtils.getBitness(ABI_2)));
return abis;
}
+
+ @Override
+ List<IRemoteTest> createIndividualTests(Set<TestInfo> testInfos, String configPath) {
+ IRemoteTest fakeTest = EasyMock.createMock(IRemoteTest.class);
+ return new ArrayList<>(Arrays.asList(fakeTest));
+ }
+ }
+
+ /**
+ * Test TestMappingSuiteRunner that create a fake IConfiguration with fake a test object.
+ */
+ public static class FakeTestMappingSuiteRunner extends TestMappingSuiteRunner {
+ @Override
+ public Set<IAbi> getAbis(ITestDevice device) throws DeviceNotAvailableException {
+ Set<IAbi> abis = new HashSet<>();
+ abis.add(new Abi(ABI_1, AbiUtils.getBitness(ABI_1)));
+ abis.add(new Abi(ABI_2, AbiUtils.getBitness(ABI_2)));
+ return abis;
+ }
+
+ @Override
+ public LinkedHashMap<String, IConfiguration> loadingStrategy(Set<IAbi> abis,
+ List<File> testsDirs, String suitePrefix, String suiteTag) {
+ LinkedHashMap<String, IConfiguration> testConfig = new LinkedHashMap<>();
+ try {
+ IConfiguration config =
+ ConfigurationFactory.getInstance()
+ .createConfigurationFromArgs(new String[] {EMPTY_CONFIG});
+ config.setTest(new StubTest());
+ config.getConfigurationDescription().setModuleName(TEST_CONFIG_NAME);
+ testConfig.put(TEST_CONFIG_NAME, config);
+
+ } catch (ConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+ return testConfig;
+ }
}
/**
@@ -174,13 +224,7 @@ public class TestMappingSuiteRunnerTest {
assertTrue(mRunner.getIncludeFilter().contains("test2"));
assertTrue(mRunner.getIncludeFilter().contains("instrument"));
assertTrue(mRunner.getIncludeFilter().contains("suite/stub1"));
- // Filters are applied directly
- assertTrue(mRunner.getExcludeFilter().contains("suite/stub1 filter.com"));
- assertTrue(mRunner.getIncludeFilter().contains("suite/stub2 filter.com"));
-
- // Check module-arg work as expected.
- StubTest test = (StubTest) configMap.get("arm64-v8a suite/stub2").getTests().get(0);
- assertTrue(test.getRunTest());
+ assertTrue(mRunner.getIncludeFilter().contains("suite/stub2"));
assertEquals(4, configMap.size());
assertTrue(configMap.containsKey(ABI_1 + " suite/stub1"));
@@ -575,4 +619,141 @@ public class TestMappingSuiteRunnerTest {
FileUtil.recursiveDelete(tempDir);
}
}
+
+ /**
+ * Test for {@link TestMappingSuiteRunner#getTestInfos(Set, String)} that when a module is
+ * specified, tests would be still found correctly.
+ */
+ @Test
+ public void testGetTestInfos() throws Exception {
+ Set<TestInfo> testInfos = new HashSet<>();
+ testInfos.add(createTestInfo("test", "path"));
+ testInfos.add(createTestInfo("test", "path2"));
+ testInfos.add(createTestInfo("test2", "path2"));
+
+ assertEquals(2, mRunner.getTestInfos(testInfos, "test").size());
+ assertEquals(1, mRunner.getTestInfos(testInfos, "test2").size());
+ }
+
+ /**
+ * Test for {@link TestMappingSuiteRunner#dedupTestInfos(Set)} that tests with the same test
+ * options would be filtered out.
+ */
+ @Test
+ public void testDedupTestInfos() throws Exception {
+ Set<TestInfo> testInfos = new HashSet<>();
+ testInfos.add(createTestInfo("test", "path"));
+ testInfos.add(createTestInfo("test", "path2"));
+ assertEquals(1, mRunner.dedupTestInfos(testInfos).size());
+
+ TestInfo anotherInfo = new TestInfo("test", "folder3", false);
+ anotherInfo.addOption(new TestOption("include-filter", "value1"));
+ testInfos.add(anotherInfo);
+ assertEquals(2, mRunner.dedupTestInfos(testInfos).size());
+ }
+
+ /**
+ * Test for {@link TestMappingSuiteRunner#getTestSources(Set)} that test sources would be found
+ * correctly.
+ */
+ @Test
+ public void testGetTestSources() throws Exception {
+ Set<TestInfo> testInfos = new HashSet<>();
+ testInfos.add(createTestInfo("test", "path"));
+ testInfos.add(createTestInfo("test", "path2"));
+ List<String> results = mRunner.getTestSources(testInfos);
+ assertEquals(2, results.size());
+ }
+
+ /**
+ * Test for {@link TestMappingSuiteRunner#parseOptions(TestInfo)} that the test options are
+ * injected correctly.
+ */
+ @Test
+ public void testParseOptions() throws Exception {
+ TestInfo info = createTestInfo("test", "path");
+ mRunner.parseOptions(info);
+ assertEquals(1, mRunner.getIncludeFilter().size());
+ assertEquals(1, mRunner.getExcludeFilter().size());
+ }
+
+ /**
+ * Test for {@link TestMappingSuiteRunner#createIndividualTests(Set, String)} that IRemoteTest
+ * object are created according to the test infos with different test options.
+ */
+ @Test
+ public void testCreateIndividualTestsWithDifferentTestInfos() throws Exception {
+ File tempDir = null;
+ try {
+ tempDir = FileUtil.createTempDir("tmp");
+ File moduleConfig = new File(tempDir, "module_name.config");
+ moduleConfig.createNewFile();
+ Set<TestInfo> testInfos = new HashSet<>();
+ testInfos.add(createTestInfo("test", "path"));
+ testInfos.add(createTestInfo("test2", "path"));
+ String configPath = moduleConfig.getAbsolutePath();
+ assertEquals(2, mRunner2.createIndividualTests(testInfos, configPath).size());
+ assertEquals(1, mRunner2.getIncludeFilter().size());
+ assertEquals(1, mRunner2.getExcludeFilter().size());
+ } finally {
+ FileUtil.recursiveDelete(tempDir);
+ }
+ }
+
+ /**
+ * Test for {@link TestMappingSuiteRunner#createIndividualTests(Set, String)} that IRemoteTest
+ * object are created according to the test infos with multiple test options.
+ */
+ @Test
+ public void testCreateIndividualTestsWithDifferentTestOptions() throws Exception {
+ File tempDir = null;
+ try {
+ tempDir = FileUtil.createTempDir("tmp");
+ File moduleConfig = new File(tempDir, "module_name.config");
+ moduleConfig.createNewFile();
+ Set<TestInfo> testInfos = new HashSet<>();
+ testInfos.add(createTestInfo("test", "path"));
+ TestInfo info = new TestInfo("test", "path", false);
+ info.addOption(new TestOption("include-filter", "include-filter"));
+ testInfos.add(info);
+ String configPath = moduleConfig.getAbsolutePath();
+ assertEquals(2, mRunner2.createIndividualTests(testInfos, configPath).size());
+ assertEquals(1, mRunner2.getIncludeFilter().size());
+ assertEquals(0, mRunner2.getExcludeFilter().size());
+ } finally {
+ FileUtil.recursiveDelete(tempDir);
+ }
+ }
+
+ /**
+ * Test for {@link TestMappingSuiteRunner#createIndividualTests(Set, String)} that IRemoteTest
+ * object are created according to the test infos with the same test options and name.
+ */
+ @Test
+ public void testCreateIndividualTestsWithSameTestInfos() throws Exception {
+ File tempDir = null;
+ try {
+ tempDir = FileUtil.createTempDir("tmp");
+ File moduleConfig = new File(tempDir, "module_name.config");
+ moduleConfig.createNewFile();
+ String configPath = moduleConfig.getAbsolutePath();
+ Set<TestInfo> testInfos = new HashSet<>();
+ testInfos.add(createTestInfo("test", "path"));
+ testInfos.add(createTestInfo("test", "path"));
+ assertEquals(1, mRunner2.createIndividualTests(testInfos, configPath).size());
+ assertEquals(1, mRunner2.getIncludeFilter().size());
+ assertEquals(1, mRunner2.getExcludeFilter().size());
+ } finally {
+ FileUtil.recursiveDelete(tempDir);
+ }
+ }
+
+ /** Helper to create specific test infos. */
+ private TestInfo createTestInfo(String name, String source) {
+ TestInfo info = new TestInfo(name, source, false);
+ info.addOption(new TestOption("include-filter", name));
+ info.addOption(new TestOption("exclude-filter", name));
+ info.addOption(new TestOption("other", name));
+ return info;
+ }
}
diff --git a/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java b/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java
index 8c53c17a6..0d69264eb 100644
--- a/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java
+++ b/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java
@@ -169,12 +169,10 @@ public class TestMappingTest {
assertEquals(0, tests.size());
tests = TestMapping.getTests(mockBuildInfo, "presubmit", true, null);
- assertEquals(1, tests.size());
+ assertEquals(2, tests.size());
Set<String> names = new HashSet<String>();
for (TestInfo test : tests) {
names.add(test.getName());
- // Make sure the tests for `test1` are merged and no option is kept.
- assertTrue(test.getOptions().isEmpty());
if (test.getName().equals("test1")) {
assertTrue(test.getHostOnly());
} else {