blob: ac222541a1e4c5f454cf8fb4f9c606f3919d17d2 [file] [log] [blame]
/*
* 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.testtype.suite;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.ConfigurationDef;
import com.android.tradefed.config.ConfigurationDescriptor;
import com.android.tradefed.config.ConfigurationException;
import com.android.tradefed.config.ConfigurationFactory;
import com.android.tradefed.config.IConfiguration;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceFoldableState;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.invoker.InvocationContext;
import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.targetprep.BaseTargetPreparer;
import com.android.tradefed.targetprep.InstallApexModuleTargetPreparer;
import com.android.tradefed.testtype.Abi;
import com.android.tradefed.testtype.IAbi;
import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.testtype.ITestFileFilterReceiver;
import com.android.tradefed.testtype.ITestFilterReceiver;
import com.android.tradefed.util.FileUtil;
import org.easymock.EasyMock;
import org.junit.After;
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;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** Unit tests for {@link SuiteModuleLoader}. */
@RunWith(JUnit4.class)
public class SuiteModuleLoaderTest {
private static final String TEST_CONFIG =
"<configuration description=\"Runs a stub tests part of some suite\">\n"
+ " <target_preparer class=\"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$PreparerInject\" />\n"
+ " <test class=\"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest"
+ "$TestInject\" />\n"
+ "</configuration>";
private static final String TEST_INSTANT_CONFIG =
"<configuration description=\"Runs a stub tests part of some suite\">\n"
+ " <option name=\"config-descriptor:metadata\" key=\"parameter\" value=\"instant_app\" />"
// Duplicate parameter should not have impact
+ " <option name=\"config-descriptor:metadata\" key=\"parameter\" value=\"instant_app\" />"
+ " <test class=\"com.android.tradefed.testtype.suite.TestSuiteStub\" />\n"
+ "</configuration>";
private static final String TEST_FOLDABLE_CONFIG =
"<configuration description=\"Runs a stub tests part of some suite\">\n"
+ " <option name=\"config-descriptor:metadata\" key=\"parameter\" value=\"all_foldable_states\" />"
+ " <test class=\"com.android.tradefed.testtype.suite.TestSuiteStub\" />\n"
+ "</configuration>";
private static final String TEST_MAINLINE_CONFIG =
"<configuration description=\"Runs a stub tests part of some suite\">\n"
+ " <option name=\"config-descriptor:metadata\" key=\"mainline-param\" value=\"mod1.apk\" />"
// Duplicate parameter should not have impact
+ " <option name=\"config-descriptor:metadata\" key=\"mainline-param\" value=\"mod2.apk\" />"
+ " <option name=\"config-descriptor:metadata\" key=\"mainline-param\" value=\"mod1.apk+mod2.apk\" />"
+ " <option name=\"config-descriptor:metadata\" key=\"mainline-param\" value=\"mod1.apk+mod2.apk\" />"
+ " <option name=\"config-descriptor:metadata\" key=\"mainline-param\" value=\"mod1.apk\" />"
+ " <test class=\"com.android.tradefed.testtype.suite.TestSuiteStub\" />\n"
+ "</configuration>";
private SuiteModuleLoader mRepo;
private File mTestsDir;
private Set<IAbi> mAbis;
private IInvocationContext mContext;
private IBuildInfo mMockBuildInfo;
@Before
public void setUp() throws Exception {
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
new ArrayList<>());
mTestsDir = FileUtil.createTempDir("suite-module-loader-tests");
mAbis = new HashSet<>();
mAbis.add(new Abi("armeabi-v7a", "32"));
mContext = new InvocationContext();
mMockBuildInfo = EasyMock.createMock(IBuildInfo.class);
EasyMock.expect(mMockBuildInfo.getBuildBranch()).andStubReturn("branch");
EasyMock.expect(mMockBuildInfo.getBuildFlavor()).andStubReturn("flavor");
EasyMock.expect(mMockBuildInfo.getBuildId()).andStubReturn("id");
EasyMock.replay(mMockBuildInfo);
mContext.addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, mMockBuildInfo);
}
@After
public void tearDown() {
FileUtil.recursiveDelete(mTestsDir);
}
private void createModuleConfig(String moduleName) throws IOException {
File module = new File(mTestsDir, moduleName + SuiteModuleLoader.CONFIG_EXT);
FileUtil.writeToFile(TEST_CONFIG, module);
}
private void createInstantModuleConfig(String moduleName) throws IOException {
File module = new File(mTestsDir, moduleName + SuiteModuleLoader.CONFIG_EXT);
FileUtil.writeToFile(TEST_INSTANT_CONFIG, module);
}
private void createFoldableModuleConfig(String moduleName) throws IOException {
File module = new File(mTestsDir, moduleName + SuiteModuleLoader.CONFIG_EXT);
FileUtil.writeToFile(TEST_FOLDABLE_CONFIG, module);
}
private void createMainlineModuleConfig(String moduleName) throws IOException {
File moduleConfig = new File(mTestsDir, moduleName + SuiteModuleLoader.CONFIG_EXT);
FileUtil.writeToFile(TEST_MAINLINE_CONFIG, moduleConfig);
}
@OptionClass(alias = "preparer-inject")
public static class PreparerInject extends BaseTargetPreparer {
@Option(name = "preparer-string")
public String preparer = null;
}
@OptionClass(alias = "test-inject")
public static class TestInject
implements IRemoteTest, ITestFileFilterReceiver, ITestFilterReceiver {
@Option(name = "simple-string")
public String test = null;
@Option(name = "empty-string")
public String testEmpty = null;
@Option(name = "alias-option")
public String testAlias = null;
@Option(name = "list-string")
public List<String> testList = new ArrayList<>();
@Option(name = "map-string")
public Map<String, String> testMap = new HashMap<>();
public File mIncludeTestFile;
public File mExcludeTestFile;
@Override
public void run(TestInformation testInfo, ITestInvocationListener listener)
throws DeviceNotAvailableException {}
@Override
public void setIncludeTestFile(File testFile) {
mIncludeTestFile = testFile;
}
@Override
public void setExcludeTestFile(File testFile) {
mExcludeTestFile = testFile;
}
@Override
public void addIncludeFilter(String filter) {
// NA
}
@Override
public void addAllIncludeFilters(Set<String> filters) {
// NA
}
@Override
public void addExcludeFilter(String filter) {
// NA
}
@Override
public void addAllExcludeFilters(Set<String> filters) {
// NA
}
@Override
public Set<String> getIncludeFilters() {
return null;
}
@Override
public Set<String> getExcludeFilters() {
return null;
}
@Override
public void clearIncludeFilters() {
// NA
}
@Override
public void clearExcludeFilters() {
// NA
}
}
/** Test an end-to-end injection of --module-arg. */
@Test
public void testInjectConfigOptions_moduleArgs() throws Exception {
List<String> moduleArgs = new ArrayList<>();
moduleArgs.add("module1[test]:simple-string:value1");
moduleArgs.add("module1[test]:empty-string:"); // value is the empty string
moduleArgs.add("module1[test]:list-string:value2");
moduleArgs.add("module1[test]:list-string:value3");
moduleArgs.add("module1[test]:list-string:set-option:moreoption");
moduleArgs.add("module1[test]:list-string:"); // value is the empty string
moduleArgs.add("module1[test]:map-string:set-option:=moreoption");
moduleArgs.add("module1[test]:map-string:empty-option:="); // value is the empty string
createModuleConfig("module1[test]");
Map<String, LinkedHashSet<SuiteTestFilter>> includeFilter = new LinkedHashMap<>();
SuiteTestFilter filter = SuiteTestFilter.createFrom("armeabi-v7a module1[test] test#test");
LinkedHashSet<SuiteTestFilter> mapFilters = new LinkedHashSet<>();
mapFilters.add(filter);
includeFilter.put("armeabi-v7a module1[test]", mapFilters);
mRepo =
new SuiteModuleLoader(
includeFilter,
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
moduleArgs);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertNotNull(res.get("armeabi-v7a module1[test]"));
IConfiguration config = res.get("armeabi-v7a module1[test]");
TestInject checker = (TestInject) config.getTests().get(0);
assertEquals("value1", checker.test);
assertEquals("", checker.testEmpty);
// Check list
assertTrue(checker.testList.size() == 4);
assertTrue(checker.testList.contains("value2"));
assertTrue(checker.testList.contains("value3"));
assertTrue(checker.testList.contains("set-option:moreoption"));
assertTrue(checker.testList.contains(""));
// Chech map
assertTrue(checker.testMap.size() == 2);
assertEquals("moreoption", checker.testMap.get("set-option"));
assertEquals("", checker.testMap.get("empty-option"));
// Check filters
assertNotNull(checker.mIncludeTestFile);
assertNull(checker.mExcludeTestFile);
assertTrue(checker.mIncludeTestFile.getName().contains("armeabi-v7a%20module1%5Btest%5"));
FileUtil.deleteFile(checker.mIncludeTestFile);
}
/** Test an end-to-end injection of --test-arg. */
@Test
public void testInjectConfigOptions_testArgs() throws Exception {
List<String> testArgs = new ArrayList<>();
// Value for ITargetPreparer
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$PreparerInject:"
+ "preparer-string:preparer");
// Values for IRemoteTest
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "simple-string:value1");
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "empty-string:"); // value is the empty string
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "list-string:value2");
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "list-string:value3");
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "list-string:set-option:moreoption");
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "list-string:"); // value is the empty string
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "map-string:set-option:=moreoption");
testArgs.add(
"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest$TestInject:"
+ "map-string:empty-option:="); // value is the empty string
createModuleConfig("module1");
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
testArgs,
new ArrayList<>());
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertNotNull(res.get("armeabi-v7a module1"));
IConfiguration config = res.get("armeabi-v7a module1");
PreparerInject preparer = (PreparerInject) config.getTargetPreparers().get(0);
assertEquals("preparer", preparer.preparer);
TestInject checker = (TestInject) config.getTests().get(0);
assertEquals("value1", checker.test);
assertEquals("", checker.testEmpty);
// Check list
assertTrue(checker.testList.size() == 4);
assertTrue(checker.testList.contains("value2"));
assertTrue(checker.testList.contains("value3"));
assertTrue(checker.testList.contains("set-option:moreoption"));
assertTrue(checker.testList.contains(""));
// Chech map
assertTrue(checker.testMap.size() == 2);
assertEquals("moreoption", checker.testMap.get("set-option"));
assertEquals("", checker.testMap.get("empty-option"));
}
@Test
public void testInjectConfigOptions_moduleArgs_alias() throws Exception {
List<String> moduleArgs = new ArrayList<>();
moduleArgs.add("module1:{test-inject}alias-option:value1");
createModuleConfig("module1");
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
moduleArgs);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertNotNull(res.get("armeabi-v7a module1"));
IConfiguration config = res.get("armeabi-v7a module1");
TestInject checker = (TestInject) config.getTests().get(0);
assertEquals("value1", checker.testAlias);
}
/**
* Test that if the base module is excluded in full, the filters of parameterized modules are
* still populated with the proper filters.
*/
@Test
public void testFilterParameterized() throws Exception {
Map<String, LinkedHashSet<SuiteTestFilter>> excludeFilters = new LinkedHashMap<>();
createInstantModuleConfig("basemodule");
SuiteTestFilter fullFilter = SuiteTestFilter.createFrom("armeabi-v7a basemodule");
LinkedHashSet<SuiteTestFilter> mapFilters = new LinkedHashSet<>();
mapFilters.add(fullFilter);
excludeFilters.put("armeabi-v7a basemodule", mapFilters);
SuiteTestFilter instantMethodFilter =
SuiteTestFilter.createFrom(
"armeabi-v7a basemodule[instant] NativeDnsAsyncTest#Async_Cancel");
LinkedHashSet<SuiteTestFilter> instantFilter = new LinkedHashSet<>();
instantFilter.add(instantMethodFilter);
excludeFilters.put("armeabi-v7a basemodule[instant]", instantFilter);
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
excludeFilters,
new ArrayList<>(),
new ArrayList<>());
mRepo.setParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(1, res.size());
// Full module was excluded completely
IConfiguration instantModule = res.get("armeabi-v7a basemodule[instant]");
assertNotNull(instantModule);
TestSuiteStub stubTest = (TestSuiteStub) instantModule.getTests().get(0);
assertEquals(1, stubTest.getExcludeFilters().size());
assertEquals(
"NativeDnsAsyncTest#Async_Cancel", stubTest.getExcludeFilters().iterator().next());
// Ensure that appropriate metadata are set on the module config descriptor
ConfigurationDescriptor descriptor = instantModule.getConfigurationDescription();
assertEquals(
1,
descriptor
.getAllMetaData()
.get(ConfigurationDescriptor.ACTIVE_PARAMETER_KEY)
.size());
assertEquals(
"instant",
descriptor
.getAllMetaData()
.getUniqueMap()
.get(ConfigurationDescriptor.ACTIVE_PARAMETER_KEY));
assertEquals("armeabi-v7a", descriptor.getAbi().getName());
}
@Test
public void testLoad_foldable() throws Exception {
Set<DeviceFoldableState> foldableStates = new LinkedHashSet<>();
foldableStates.add(new DeviceFoldableState(0, "DEFAULT"));
foldableStates.add(new DeviceFoldableState(1, "CLOSED"));
foldableStates.add(new DeviceFoldableState(2, "OPEN"));
Map<String, LinkedHashSet<SuiteTestFilter>> excludeFilters = new LinkedHashMap<>();
createFoldableModuleConfig("basemodule");
Set<String> excludeFilterString = new LinkedHashSet<>();
excludeFilterString.add("armeabi-v7a basemodule");
excludeFilterString.add(
"armeabi-v7a basemodule[foldable:1:CLOSED] NativeDnsAsyncTest#Async_Cancel");
// All foldable configs will get injected
excludeFilterString.add(
"armeabi-v7a basemodule[all_foldable_states] NativeDnsAsyncTest#test2");
SuiteModuleLoader.addFilters(excludeFilterString, excludeFilters, null, foldableStates);
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
excludeFilters,
new ArrayList<>(),
new ArrayList<>());
mRepo.setParameterizedModules(true);
mRepo.setFoldableStates(foldableStates);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(2, res.size());
// Full module was excluded completely, only foldable are created
IConfiguration foldable1 = res.get("armeabi-v7a basemodule[foldable:1:CLOSED]");
assertNotNull(foldable1);
TestSuiteStub stubTest = (TestSuiteStub) foldable1.getTests().get(0);
assertEquals(2, stubTest.getExcludeFilters().size());
Iterator<String> iteFilters = stubTest.getExcludeFilters().iterator();
assertEquals("NativeDnsAsyncTest#Async_Cancel", iteFilters.next());
assertEquals("NativeDnsAsyncTest#test2", iteFilters.next());
// Ensure that appropriate metadata are set on the module config descriptor
ConfigurationDescriptor descriptor = foldable1.getConfigurationDescription();
assertEquals(
1,
descriptor
.getAllMetaData()
.get(ConfigurationDescriptor.ACTIVE_PARAMETER_KEY)
.size());
assertEquals(
"foldable:1:CLOSED",
descriptor
.getAllMetaData()
.getUniqueMap()
.get(ConfigurationDescriptor.ACTIVE_PARAMETER_KEY));
assertEquals("armeabi-v7a", descriptor.getAbi().getName());
IConfiguration foldable2 = res.get("armeabi-v7a basemodule[foldable:2:OPEN]");
assertNotNull(foldable2);
TestSuiteStub stubTest2 = (TestSuiteStub) foldable2.getTests().get(0);
assertEquals(1, stubTest2.getExcludeFilters().size());
Iterator<String> iteFilters2 = stubTest2.getExcludeFilters().iterator();
assertEquals("NativeDnsAsyncTest#test2", iteFilters2.next());
ConfigurationDescriptor descriptor2 = foldable2.getConfigurationDescription();
assertEquals(
1,
descriptor2
.getAllMetaData()
.get(ConfigurationDescriptor.ACTIVE_PARAMETER_KEY)
.size());
assertEquals(
"foldable:2:OPEN",
descriptor2
.getAllMetaData()
.getUniqueMap()
.get(ConfigurationDescriptor.ACTIVE_PARAMETER_KEY));
assertEquals("armeabi-v7a", descriptor.getAbi().getName());
}
/**
* Test that if the base module is excluded in full, the filters of parameterized modules are
* still populated with the proper filters.
*/
@Test
public void testFilterParameterized_excludeFilter_parameter() throws Exception {
Map<String, LinkedHashSet<SuiteTestFilter>> excludeFilters = new LinkedHashMap<>();
createInstantModuleConfig("basemodule");
SuiteTestFilter fullFilter = SuiteTestFilter.createFrom("armeabi-v7a basemodule[instant]");
LinkedHashSet<SuiteTestFilter> mapFilter = new LinkedHashSet<>();
mapFilter.add(fullFilter);
excludeFilters.put("basemodule[instant]", mapFilter);
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
excludeFilters,
new ArrayList<>(),
new ArrayList<>());
mRepo.setParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(1, res.size());
// Full module was excluded completely
IConfiguration instantModule = res.get("armeabi-v7a basemodule[instant]");
assertNull(instantModule);
}
@Test
public void testFilterParameterized_includeFilter_base() throws Exception {
Map<String, LinkedHashSet<SuiteTestFilter>> includeFilters = new LinkedHashMap<>();
createInstantModuleConfig("basemodule");
SuiteTestFilter fullFilter = SuiteTestFilter.createFrom("armeabi-v7a basemodule");
LinkedHashSet<SuiteTestFilter> mapFilter = new LinkedHashSet<>();
mapFilter.add(fullFilter);
includeFilters.put("armeabi-v7a basemodule", mapFilter);
mRepo =
new SuiteModuleLoader(
includeFilters,
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
new ArrayList<>());
mRepo.setParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(1, res.size());
// Parameterized module was excluded completely
IConfiguration baseModule = res.get("armeabi-v7a basemodule");
assertNotNull(baseModule);
}
@Test
public void testFilterParameterized_includeFilter_param() throws Exception {
Map<String, LinkedHashSet<SuiteTestFilter>> includeFilters = new LinkedHashMap<>();
createInstantModuleConfig("basemodule");
SuiteTestFilter fullFilter = SuiteTestFilter.createFrom("armeabi-v7a basemodule[instant]");
LinkedHashSet<SuiteTestFilter> mapFilter = new LinkedHashSet<>();
mapFilter.add(fullFilter);
includeFilters.put("armeabi-v7a basemodule[instant]", mapFilter);
mRepo =
new SuiteModuleLoader(
includeFilters,
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
new ArrayList<>());
mRepo.setParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(1, res.size());
// Full module was excluded completely
IConfiguration instantModule = res.get("armeabi-v7a basemodule[instant]");
assertNotNull(instantModule);
}
@Test
public void testFilterParameterized_WithModuleArg() throws Exception {
List<String> moduleArgs = new ArrayList<>();
createInstantModuleConfig("basemodule");
moduleArgs.add("basemodule[instant]:exclude-annotation:test-annotation");
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
moduleArgs);
mRepo.setParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(2, res.size());
IConfiguration instantModule = res.get("armeabi-v7a basemodule[instant]");
assertNotNull(instantModule);
TestSuiteStub stubTest = (TestSuiteStub) instantModule.getTests().get(0);
assertEquals(2, stubTest.getExcludeAnnotations().size());
List<String> expected =
Arrays.asList("android.platform.test.annotations.AppModeFull", "test-annotation");
assertTrue(stubTest.getExcludeAnnotations().containsAll(expected));
}
/**
* 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, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<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, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<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, LinkedHashSet<SuiteTestFilter>> excludeFilters = new LinkedHashMap<>();
SuiteTestFilter filter =
SuiteTestFilter.createFrom(
"armeabi-v7a module2");
LinkedHashSet<SuiteTestFilter> mapFilter = new LinkedHashSet<>();
mapFilter.add(filter);
excludeFilters.put("armeabi-v7a module2", mapFilter);
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<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"));
}
/**
* Test deduplicate the given mainline parameters.
*/
@Test
public void testDedupMainlineParameters() throws Exception {
List<String> parameters = new ArrayList<>();
parameters.add("mod1.apk");
parameters.add("mod1.apk");
parameters.add("mod1.apk+mod2.apk");
parameters.add("mod1.apk+mod2.apk");
Set<String> results = mRepo.dedupMainlineParameters(parameters, "configName");
assertEquals(2, results.size());
boolean IsEqual = true;
for (String result : results) {
if (!(result.equals("mod1.apk") || result.equals("mod1.apk+mod2.apk"))) {
IsEqual = false;
}
}
assertTrue(IsEqual);
}
/**
* Test deduplicate the given mainline parameters with invalid spaces configured.
*/
@Test
public void testDedupMainlineParameters_WithSpaces() throws Exception {
List<String> parameters = new ArrayList<>();
parameters.add("mod1.apk");
parameters.add(" mod1.apk");
parameters.add("mod1.apk+mod2.apk ");
try {
mRepo.dedupMainlineParameters(parameters, "configName");
fail("Should have thrown an exception.");
} catch (ConfigurationException expected) {
// expected
assertTrue(expected.getMessage().contains("Illegal mainline module parameter:"));
}
}
/**
* Test deduplicate the given mainline parameters end with invalid extension.
*/
@Test
public void testDedupMainlineParameters_WithInvalidExtension() throws Exception {
List<String> parameters = new ArrayList<>();
parameters.add("mod1.apk");
parameters.add("mod1.apk+mod2.unknown");
try {
mRepo.dedupMainlineParameters(parameters, "configName");
fail("Should have thrown an exception.");
} catch (ConfigurationException expected) {
// expected
assertTrue(expected.getMessage().contains("Illegal mainline module parameter:"));
}
}
/**
* Test deduplicate the given mainline parameters end with invalid format.
*/
@Test
public void testDedupMainlineParameters_WithInvalidFormat() throws Exception {
List<String> parameters = new ArrayList<>();
parameters.add("mod1.apk");
parameters.add("+mod2.apex");
try {
mRepo.dedupMainlineParameters(parameters, "configName");
fail("Should have thrown an exception.");
} catch (ConfigurationException expected) {
// expected
assertTrue(expected.getMessage().contains("Illegal mainline module parameter:"));
}
}
/**
* Test deduplicate the given mainline parameter with duplicated modules configured.
*/
@Test
public void testDedupMainlineParameters_WithDuplicatedMainlineModules() throws Exception {
List<String> parameters = new ArrayList<>();
parameters.add("mod1.apk+mod1.apk");
try {
mRepo.dedupMainlineParameters(parameters, "configName");
fail("Should have thrown an exception.");
} catch (ConfigurationException expected) {
// expected
assertTrue(expected.getMessage().contains("Illegal mainline module parameter:"));
}
}
/**
* Test deduplicate the given mainline parameters are not configured in alphabetical order.
*/
@Test
public void testDedupMainlineParameters_ParameterNotInAlphabeticalOrder() throws Exception {
List<String> parameters = new ArrayList<>();
parameters.add("mod1.apk");
parameters.add("mod2.apex+mod1.apk");
try {
mRepo.dedupMainlineParameters(parameters, "configName");
fail("Should have thrown an exception.");
} catch (ConfigurationException expected) {
// expected
assertTrue(expected.getMessage().contains("Illegal mainline module parameter:"));
}
}
/**
* Test get the mainline parameters defined in the test config.
*/
@Test
public void testGetMainlineModuleParameters() throws Exception {
createMainlineModuleConfig("mainline_module");
IConfiguration config =
ConfigurationFactory.getInstance().createConfigurationFromArgs(
new String[] {mTestsDir.getAbsolutePath() + "/mainline_module.config"});
List<String> results = mRepo.getMainlineModuleParameters(config);
assertEquals(3, results.size());
boolean IsEqual = true;
for (String id : results) {
if (!(id.equals("mod1.apk") ||
id.equals("mod2.apk") ||
id.equals("mod1.apk+mod2.apk"))) {
IsEqual = false;
}
}
assertTrue(IsEqual);
}
/**
* Test that generate the correct IConfiguration objects based on the defined mainline modules.
*/
@Test
public void testLoadParameterizedMainlineModules() throws Exception {
createMainlineModuleConfig("basemodule");
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
new ArrayList<>());
mRepo.setInvocationContext(mContext);
mRepo.setMainlineParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(3, res.size());
IConfiguration module1 = res.get("armeabi-v7a basemodule[mod1.apk]");
assertNotNull(module1);
assertTrue(
module1.getTargetPreparers().get(0) instanceof InstallApexModuleTargetPreparer);
EasyMock.verify(mMockBuildInfo);
}
/**
* Test that generate the correct IConfiguration objects based on the defined mainline modules
* with given exclude-filter.
*/
@Test
public void testLoadParameterizedMainlineModule_WithFilters() throws Exception {
Map<String, LinkedHashSet<SuiteTestFilter>> excludeFilters = new LinkedHashMap<>();
createMainlineModuleConfig("basemodule");
SuiteTestFilter fullFilter = SuiteTestFilter.createFrom("armeabi-v7a basemodule");
LinkedHashSet<SuiteTestFilter> mapFilter = new LinkedHashSet<>();
mapFilter.add(fullFilter);
excludeFilters.put("armeabi-v7a basemodule", mapFilter);
SuiteTestFilter filter =
SuiteTestFilter.createFrom(
"armeabi-v7a basemodule[mod1.apk] class#method");
LinkedHashSet<SuiteTestFilter> mainlineFilter = new LinkedHashSet<>();
mainlineFilter.add(filter);
excludeFilters.put("armeabi-v7a basemodule[mod1.apk]", mainlineFilter);
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
excludeFilters,
new ArrayList<>(),
new ArrayList<>());
mRepo.setInvocationContext(mContext);
mRepo.setMainlineParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(3, res.size());
IConfiguration module1 = res.get("armeabi-v7a basemodule[mod1.apk]");
assertNotNull(module1);
TestSuiteStub stubTest = (TestSuiteStub) module1.getTests().get(0);
assertEquals(1, stubTest.getExcludeFilters().size());
assertEquals("class#method", stubTest.getExcludeFilters().iterator().next());
EasyMock.verify(mMockBuildInfo);
}
/**
* Test that generate the correct IConfiguration objects based on the defined mainline modules
* with given module args.
*/
@Test
public void testLoadParameterizedMainlineModule_WithModuleArgs() throws Exception {
List<String> moduleArgs = new ArrayList<>();
moduleArgs.add("basemodule[mod1.apk]:exclude-annotation:test-annotation");
createMainlineModuleConfig("basemodule");
mRepo =
new SuiteModuleLoader(
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new LinkedHashMap<String, LinkedHashSet<SuiteTestFilter>>(),
new ArrayList<>(),
moduleArgs);
mRepo.setInvocationContext(mContext);
mRepo.setMainlineParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(3, res.size());
IConfiguration module1 = res.get("armeabi-v7a basemodule[mod1.apk]");
assertNotNull(module1);
TestSuiteStub stubTest = (TestSuiteStub) module1.getTests().get(0);
assertEquals(1, stubTest.getExcludeAnnotations().size());
assertEquals("test-annotation", stubTest.getExcludeAnnotations().iterator().next());
EasyMock.verify(mMockBuildInfo);
}
/**
* Test that generate the correct IConfiguration objects based on the defined mainline modules
* with given include-filter and exclude-filter.
*/
@Test
public void testLoadParameterizedMainlineModules_WithMultipleFilters() throws Exception {
Map<String, LinkedHashSet<SuiteTestFilter>> includeFilters = new LinkedHashMap<>();
Map<String, LinkedHashSet<SuiteTestFilter>> excludeFilters = new LinkedHashMap<>();
createMainlineModuleConfig("basemodule");
SuiteTestFilter filter = SuiteTestFilter.createFrom("armeabi-v7a basemodule[mod1.apk]");
LinkedHashSet<SuiteTestFilter> mapFilter = new LinkedHashSet<>();
mapFilter.add(filter);
includeFilters.put("armeabi-v7a basemodule[mod1.apk]", mapFilter);
filter = SuiteTestFilter.createFrom("armeabi-v7a basemodule[[mod2.apk]]");
LinkedHashSet<SuiteTestFilter> mapFilter2 = new LinkedHashSet<>();
mapFilter2.add(filter);
excludeFilters.put("armeabi-v7a basemodule[mod2.apk]", mapFilter2);
mRepo =
new SuiteModuleLoader(
includeFilters,
excludeFilters,
new ArrayList<>(),
new ArrayList<>());
mRepo.setInvocationContext(mContext);
mRepo.setMainlineParameterizedModules(true);
List<String> patterns = new ArrayList<>();
patterns.add(".*.config");
patterns.add(".*.xml");
LinkedHashMap<String, IConfiguration> res =
mRepo.loadConfigsFromDirectory(
Arrays.asList(mTestsDir), mAbis, null, null, patterns);
assertEquals(1, res.size());
IConfiguration module1 = res.get("armeabi-v7a basemodule[mod1.apk]");
assertNotNull(module1);
module1 = res.get("armeabi-v7a basemodule[mod2.apk]");
assertNull(module1);
module1 = res.get("armeabi-v7a basemodule[mod1.apk+mod2.apk]");
assertNull(module1);
EasyMock.verify(mMockBuildInfo);
}
/**
* Test that the mainline parameter configured in the test config is valid.
*/
@Test
public void testIsValidMainlineParam() throws Exception {
assertTrue(mRepo.isValidMainlineParam("mod1.apk"));
assertTrue(mRepo.isValidMainlineParam("mod1.apk+mod2.apex"));
assertFalse(mRepo.isValidMainlineParam(" mod1.apk"));
assertFalse(mRepo.isValidMainlineParam("+mod1.apk"));
assertFalse(mRepo.isValidMainlineParam("mod1.apeks"));
assertFalse(mRepo.isValidMainlineParam("mod1.apk +mod2.apex"));
assertFalse(mRepo.isValidMainlineParam("mod1.apk+mod2.apex "));
}
/**
* Test that the mainline parameter configured in the test config is in alphabetical order.
*/
@Test
public void testIsInAlphabeticalOrder() throws Exception {
assertTrue(mRepo.isInAlphabeticalOrder("mod1.apk"));
assertTrue(mRepo.isInAlphabeticalOrder("mod1.apk+mod2.apex"));
assertFalse(mRepo.isInAlphabeticalOrder("mod2.apk+mod1.apex"));
assertFalse(mRepo.isInAlphabeticalOrder("mod1.apk+mod1.apk"));
assertTrue(mRepo.isInAlphabeticalOrder(
"com.android.cellbroadcast.apex+com.android.ipsec.apex+com.android.permission.apex")
);
assertFalse(mRepo.isInAlphabeticalOrder(
"com.android.permission.apex+com.android.ipsec.apex+com.android.cellbroadcast.apex")
);
}
}