• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tradefed.testtype.suite;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assert.fail;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26 
27 import com.android.ddmlib.IDevice;
28 import com.android.tradefed.build.BuildInfoKey.BuildInfoFileKey;
29 import com.android.tradefed.build.IDeviceBuildInfo;
30 import com.android.tradefed.config.Configuration;
31 import com.android.tradefed.config.ConfigurationDef;
32 import com.android.tradefed.config.ConfigurationDescriptor;
33 import com.android.tradefed.config.ConfigurationException;
34 import com.android.tradefed.config.ConfigurationFactory;
35 import com.android.tradefed.config.IConfiguration;
36 import com.android.tradefed.config.OptionSetter;
37 import com.android.tradefed.device.DeviceNotAvailableException;
38 import com.android.tradefed.device.ITestDevice;
39 import com.android.tradefed.error.HarnessRuntimeException;
40 import com.android.tradefed.invoker.IInvocationContext;
41 import com.android.tradefed.invoker.InvocationContext;
42 import com.android.tradefed.invoker.TestInformation;
43 import com.android.tradefed.testtype.Abi;
44 import com.android.tradefed.testtype.HostTest;
45 import com.android.tradefed.testtype.IAbi;
46 import com.android.tradefed.testtype.IAbiReceiver;
47 import com.android.tradefed.testtype.IRemoteTest;
48 import com.android.tradefed.testtype.StubTest;
49 import com.android.tradefed.util.AbiUtils;
50 import com.android.tradefed.util.FileUtil;
51 import com.android.tradefed.util.ZipUtil;
52 import com.android.tradefed.util.testmapping.TestInfo;
53 import com.android.tradefed.util.testmapping.TestMapping;
54 import com.android.tradefed.util.testmapping.TestOption;
55 
56 import org.junit.Before;
57 import org.junit.Rule;
58 import org.junit.Test;
59 import org.junit.rules.TemporaryFolder;
60 import org.junit.runner.RunWith;
61 import org.junit.runners.JUnit4;
62 import org.mockito.Mock;
63 import org.mockito.Mockito;
64 import org.mockito.MockitoAnnotations;
65 
66 import java.io.File;
67 import java.io.IOException;
68 import java.io.InputStream;
69 import java.nio.file.Paths;
70 import java.util.Arrays;
71 import java.util.Collection;
72 import java.util.HashMap;
73 import java.util.HashSet;
74 import java.util.LinkedHashMap;
75 import java.util.LinkedHashSet;
76 import java.util.List;
77 import java.util.Map;
78 import java.util.Map.Entry;
79 import java.util.Set;
80 
81 /** Unit tests for {@link TestMappingSuiteRunner}. */
82 @RunWith(JUnit4.class)
83 public class TestMappingSuiteRunnerTest {
84 
85     @Rule public TemporaryFolder mTempFolder = new TemporaryFolder();
86 
87     private static final String ABI_1 = "arm64-v8a";
88     private static final String ABI_2 = "armeabi-v7a";
89     private static final String DISABLED_PRESUBMIT_TESTS = "disabled-presubmit-tests";
90     private static final String EMPTY_CONFIG = "empty";
91     private static final String TEST_CONFIG_NAME = "test";
92     private static final String TEST_DATA_DIR = "testdata";
93     private static final String TEST_MAPPING = "TEST_MAPPING";
94     private static final String TEST_MAPPINGS_ZIP = "test_mappings.zip";
95 
96     private TestMappingSuiteRunner mRunner;
97     private OptionSetter mOptionSetter;
98     private OptionSetter mMainlineOptionSetter;
99     private TestMappingSuiteRunner mRunner2;
100     private TestMappingSuiteRunner mMainlineRunner;
101     @Mock IDeviceBuildInfo mBuildInfo;
102     @Mock ITestDevice mMockDevice;
103     private TestInformation mTestInfo;
104     private IConfiguration mStubMainConfiguration;
105 
106     private static final String TEST_MAINLINE_CONFIG =
107             "<configuration description=\"Runs a stub tests part of some suite\">\n"
108                 + "    <option name=\"config-descriptor:metadata\" key=\"mainline-param\""
109                 + " value=\"mod1.apk\" />    <option name=\"config-descriptor:metadata\""
110                 + " key=\"mainline-param\" value=\"mod2.apk\" />    <option"
111                 + " name=\"config-descriptor:metadata\" key=\"mainline-param\""
112                 + " value=\"mod1.apk+mod2.apk\" />    <option name=\"config-descriptor:metadata\""
113                 + " key=\"mainline-param\" value=\"mod1.apk+mod2.apk+mod3.apk\" />    <test"
114                 + " class=\"com.android.tradefed.testtype.HostTest\" />\n"
115                 + "</configuration>";
116 
117     @Before
setUp()118     public void setUp() throws Exception {
119         MockitoAnnotations.initMocks(this);
120 
121         mRunner = new AbiTestMappingSuite();
122         mRunner.setBuild(mBuildInfo);
123         mRunner.setDevice(mMockDevice);
124         mRunner.setSkipjarLoading(false);
125 
126         mOptionSetter = new OptionSetter(mRunner);
127         mOptionSetter.setOptionValue("suite-config-prefix", "suite");
128 
129         mRunner2 = new FakeTestMappingSuiteRunner();
130         mRunner2.setBuild(mBuildInfo);
131         mRunner2.setDevice(mMockDevice);
132         mRunner2.setSkipjarLoading(false);
133 
134         mMainlineRunner = new FakeMainlineTMSR();
135         mMainlineRunner.setBuild(mBuildInfo);
136         mMainlineRunner.setDevice(mMockDevice);
137         mStubMainConfiguration = new Configuration("stub", "stub");
138         mMainlineRunner.setConfiguration(mStubMainConfiguration);
139         mMainlineOptionSetter = new OptionSetter(mMainlineRunner);
140 
141         IInvocationContext context = new InvocationContext();
142         context.addAllocatedDevice(ConfigurationDef.DEFAULT_DEVICE_NAME, mMockDevice);
143         context.addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, mBuildInfo);
144         mTestInfo = TestInformation.newBuilder().setInvocationContext(context).build();
145 
146         when(mBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
147         when(mBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
148         when(mMockDevice.getProperty(Mockito.any())).thenReturn(ABI_1);
149         when(mMockDevice.getProperty(Mockito.any())).thenReturn(ABI_2);
150         when(mMockDevice.getIDevice()).thenReturn(mock(IDevice.class));
151         when(mMockDevice.getFoldableStates()).thenReturn(new HashSet<>());
152     }
153 
154     /**
155      * Test TestMappingSuiteRunner that hardcodes the abis to avoid failures related to running the
156      * tests against a particular abi build of tradefed.
157      */
158     public static class AbiTestMappingSuite extends TestMappingSuiteRunner {
159 
160         @Override
getAbis(ITestDevice device)161         public Set<IAbi> getAbis(ITestDevice device) throws DeviceNotAvailableException {
162             Set<IAbi> abis = new LinkedHashSet<>();
163             abis.add(new Abi(ABI_1, AbiUtils.getBitness(ABI_1)));
164             abis.add(new Abi(ABI_2, AbiUtils.getBitness(ABI_2)));
165             return abis;
166         }
167     }
168 
169     /** Test TestMappingSuiteRunner that create a fake IConfiguration with fake a test object. */
170     public static class FakeTestMappingSuiteRunner extends TestMappingSuiteRunner {
171         @Override
getAbis(ITestDevice device)172         public Set<IAbi> getAbis(ITestDevice device) throws DeviceNotAvailableException {
173             Set<IAbi> abis = new HashSet<>();
174             abis.add(new Abi(ABI_1, AbiUtils.getBitness(ABI_1)));
175             abis.add(new Abi(ABI_2, AbiUtils.getBitness(ABI_2)));
176             return abis;
177         }
178 
179         @Override
loadingStrategy( Set<IAbi> abis, List<File> testsDirs, String suitePrefix, String suiteTag)180         public LinkedHashMap<String, IConfiguration> loadingStrategy(
181                 Set<IAbi> abis, List<File> testsDirs, String suitePrefix, String suiteTag) {
182             LinkedHashMap<String, IConfiguration> testConfig = new LinkedHashMap<>();
183             try {
184                 IConfiguration config =
185                         ConfigurationFactory.getInstance()
186                                 .createConfigurationFromArgs(new String[] {EMPTY_CONFIG});
187                 config.setTest(new StubTest());
188                 config.getConfigurationDescription().setModuleName(TEST_CONFIG_NAME);
189                 testConfig.put(TEST_CONFIG_NAME, config);
190             } catch (ConfigurationException e) {
191                 throw new RuntimeException(e);
192             }
193             return testConfig;
194         }
195     }
196 
197     /** Test TestMappingSuiteRunner that create a fake IConfiguration with fake a test object. */
198     public static class FakeMainlineTMSR extends TestMappingSuiteRunner {
199         @Override
getAbis(ITestDevice device)200         public Set<IAbi> getAbis(ITestDevice device) throws DeviceNotAvailableException {
201             Set<IAbi> abis = new HashSet<>();
202             abis.add(new Abi(ABI_1, AbiUtils.getBitness(ABI_1)));
203             return abis;
204         }
205     }
206 
207     /**
208      * Test for {@link TestMappingSuiteRunner#loadTests()} that the configuration is created with
209      * the remote test timeout information and the hash code of each IRemoteTest object with the
210      * corresponding test mapping's path.
211      */
212     @Test
testLoadTestsWhenRemoteTestTimeoutIsSet()213     public void testLoadTestsWhenRemoteTestTimeoutIsSet() throws Exception {
214         File tempDir = null;
215         try {
216             mOptionSetter.setOptionValue("test-mapping-test-group", "postsubmit");
217             mOptionSetter.setOptionValue(
218                     RemoteTestTimeOutEnforcer.REMOTE_TEST_TIMEOUT_OPTION, "15m");
219 
220             tempDir = FileUtil.createTempDir("test_mapping");
221 
222             File srcDir = FileUtil.createTempDir("src", tempDir);
223             String srcFile =
224                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
225             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
226             FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
227 
228             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
229             resourceStream = this.getClass().getResourceAsStream(srcFile);
230             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
231             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
232             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
233             resourceStream = this.getClass().getResourceAsStream(srcFile);
234             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
235 
236             List<File> filesToZip =
237                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
238             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
239             ZipUtil.createZip(filesToZip, zipFile);
240 
241             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
242             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
243             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
244             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
245 
246             mRunner.setBuild(mockBuildInfo);
247 
248             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
249 
250             for (IConfiguration config : configMap.values()) {
251                 ConfigurationDescriptor configDesc = config.getConfigurationDescription();
252                 assertEquals(
253                         configDesc
254                                 .getMetaData(RemoteTestTimeOutEnforcer.REMOTE_TEST_TIMEOUT_OPTION)
255                                 .get(0),
256                         "PT15M");
257                 for (IRemoteTest test : config.getTests()) {
258                     assertNotNull(configDesc.getMetaData(Integer.toString(test.hashCode())));
259                 }
260             }
261         } finally {
262             FileUtil.recursiveDelete(tempDir);
263         }
264     }
265 
266     /**
267      * Test for {@link TestMappingSuiteRunner#loadTests()} to fail when both options include-filter
268      * and test-mapping-test-group are set.
269      */
270     @Test(expected = RuntimeException.class)
testLoadTests_conflictTestGroup()271     public void testLoadTests_conflictTestGroup() throws Exception {
272         mOptionSetter.setOptionValue("include-filter", "test1");
273         mOptionSetter.setOptionValue("test-mapping-test-group", "group");
274         mRunner.loadTests();
275     }
276 
277     /**
278      * Test for {@link TestMappingSuiteRunner#loadTests()} to fail when both options include-filter
279      * and test-mapping-path are set.
280      */
281     @Test(expected = RuntimeException.class)
testLoadTests_conflictOptions()282     public void testLoadTests_conflictOptions() throws Exception {
283         mOptionSetter.setOptionValue("include-filter", "test1");
284         mOptionSetter.setOptionValue("test-mapping-path", "path1");
285         mRunner.loadTests();
286     }
287 
288     /** Test for {@link TestMappingSuiteRunner#loadTests()} to fail when no test option is set. */
289     @Test(expected = RuntimeException.class)
testLoadTests_noOption()290     public void testLoadTests_noOption() throws Exception {
291         mRunner.loadTests();
292     }
293 
294     /**
295      * Test for {@link TestMappingSuiteRunner#loadTests()} to fail when option test-mapping-keyword
296      * is used but test-mapping-test-group is not set.
297      */
298     @Test(expected = RuntimeException.class)
testLoadTests_conflictKeyword()299     public void testLoadTests_conflictKeyword() throws Exception {
300         mOptionSetter.setOptionValue("include-filter", "test1");
301         mOptionSetter.setOptionValue("test-mapping-keyword", "key1");
302         mRunner.loadTests();
303     }
304 
305     /**
306      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests from test_mappings.zip.
307      */
308     @Test
testLoadTests_testMappingsZip()309     public void testLoadTests_testMappingsZip() throws Exception {
310         File tempDir = null;
311         try {
312             mOptionSetter.setOptionValue("test-mapping-test-group", "postsubmit");
313 
314             tempDir = FileUtil.createTempDir("test_mapping");
315 
316             File srcDir = FileUtil.createTempDir("src", tempDir);
317             String srcFile =
318                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
319             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
320             FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
321 
322             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
323             resourceStream = this.getClass().getResourceAsStream(srcFile);
324             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
325             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
326             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
327             resourceStream = this.getClass().getResourceAsStream(srcFile);
328             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
329 
330             List<File> filesToZip =
331                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
332             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
333             ZipUtil.createZip(filesToZip, zipFile);
334 
335             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
336             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
337             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
338             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
339 
340             mRunner.setBuild(mockBuildInfo);
341 
342             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
343 
344             assertEquals(4, configMap.size());
345             assertTrue(configMap.containsKey(ABI_1 + " suite/stub1"));
346             assertTrue(configMap.containsKey(ABI_1 + " suite/stub2"));
347             assertTrue(configMap.containsKey(ABI_2 + " suite/stub1"));
348             assertTrue(configMap.containsKey(ABI_2 + " suite/stub2"));
349 
350             // Confirm test sources are stored in test's ConfigurationDescription.
351             Map<String, Integer> testSouceCount = new HashMap<>();
352             testSouceCount.put("suite/stub1", 1);
353             testSouceCount.put("suite/stub2", 1);
354 
355             for (IConfiguration config : configMap.values()) {
356                 assertTrue(testSouceCount.containsKey(config.getName()));
357                 assertEquals(
358                         testSouceCount.get(config.getName()).intValue(),
359                         config.getConfigurationDescription()
360                                 .getMetaData(TestMapping.TEST_SOURCES)
361                                 .size());
362             }
363         } finally {
364             FileUtil.recursiveDelete(tempDir);
365         }
366     }
367 
368     /**
369      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests matching keywords
370      * setting from test_mappings.zip.
371      */
372     @Test
testLoadTests_testMappingsZipFoundTestsWithKeywords()373     public void testLoadTests_testMappingsZipFoundTestsWithKeywords() throws Exception {
374         File tempDir = null;
375         try {
376             mOptionSetter.setOptionValue("test-mapping-keyword", "key_1");
377             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
378 
379             tempDir = FileUtil.createTempDir("test_mapping");
380 
381             File srcDir = FileUtil.createTempDir("src", tempDir);
382             String srcFile =
383                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
384             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
385             FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
386 
387             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
388             resourceStream = this.getClass().getResourceAsStream(srcFile);
389             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
390             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
391             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
392             resourceStream = this.getClass().getResourceAsStream(srcFile);
393             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
394 
395             List<File> filesToZip =
396                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
397             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
398             ZipUtil.createZip(filesToZip, zipFile);
399 
400             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
401             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
402             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
403             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
404 
405             mRunner.setBuild(mockBuildInfo);
406 
407             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
408 
409             // Only suite/stub2 should be listed as it contains key_1 in keywords.
410             assertTrue(mRunner.getIncludeFilter().contains("suite/stub2"));
411 
412             assertEquals(2, configMap.size());
413             assertTrue(configMap.containsKey(ABI_1 + " suite/stub2"));
414             assertTrue(configMap.containsKey(ABI_2 + " suite/stub2"));
415 
416             // Confirm test sources are stored in test's ConfigurationDescription.
417             // Only the test in test_mapping_1 has keywords matched, so there should be only 1 test
418             // source for the test.
419             Map<String, Integer> testSouceCount = new HashMap<>();
420             testSouceCount.put("suite/stub2", 1);
421 
422             for (IConfiguration config : configMap.values()) {
423                 assertTrue(testSouceCount.containsKey(config.getName()));
424                 assertEquals(
425                         testSouceCount.get(config.getName()).intValue(),
426                         config.getConfigurationDescription()
427                                 .getMetaData(TestMapping.TEST_SOURCES)
428                                 .size());
429             }
430         } finally {
431             FileUtil.recursiveDelete(tempDir);
432         }
433     }
434 
435     /**
436      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests matching keywords
437      * setting from test_mappings.zip and no test should be found.
438      */
439     @Test(expected = RuntimeException.class)
testLoadTests_testMappingsZipFailWithKeywords()440     public void testLoadTests_testMappingsZipFailWithKeywords() throws Exception {
441         File tempDir = null;
442         try {
443             mOptionSetter.setOptionValue("test-mapping-keyword", "key_2");
444             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
445 
446             tempDir = FileUtil.createTempDir("test_mapping");
447 
448             File srcDir = FileUtil.createTempDir("src", tempDir);
449             String srcFile =
450                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
451             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
452             FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
453 
454             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
455             resourceStream = this.getClass().getResourceAsStream(srcFile);
456             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
457             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
458             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
459             resourceStream = this.getClass().getResourceAsStream(srcFile);
460             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
461 
462             List<File> filesToZip =
463                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
464             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
465             ZipUtil.createZip(filesToZip, zipFile);
466 
467             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
468             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
469             when(mockBuildInfo.getTestsDir()).thenReturn(new File("non-existing-dir"));
470             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
471 
472             mRunner.setBuild(mockBuildInfo);
473 
474             // No test should be found with keyword key_2, loadTests method shall raise
475             // RuntimeException.
476             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
477         } finally {
478             FileUtil.recursiveDelete(tempDir);
479         }
480     }
481 
482     /**
483      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading host tests from
484      * test_mappings.zip.
485      */
486     @Test
testLoadTests_testMappingsZipHostTests()487     public void testLoadTests_testMappingsZipHostTests() throws Exception {
488         File tempDir = null;
489         try {
490             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
491 
492             tempDir = FileUtil.createTempDir("test_mapping");
493 
494             File srcDir = FileUtil.createTempDir("src", tempDir);
495             String srcFile =
496                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
497             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
498             FileUtil.saveResourceFile(resourceStream, tempDir, DISABLED_PRESUBMIT_TESTS);
499 
500             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
501             resourceStream = this.getClass().getResourceAsStream(srcFile);
502             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
503             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
504             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
505             resourceStream = this.getClass().getResourceAsStream(srcFile);
506             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
507 
508             List<File> filesToZip =
509                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
510             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
511             ZipUtil.createZip(filesToZip, zipFile);
512 
513             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
514             when(mockBuildInfo.getFile(BuildInfoFileKey.HOST_LINKED_DIR)).thenReturn(null);
515             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
516             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
517 
518             mRunner.setBuild(mockBuildInfo);
519 
520             mRunner.setPrioritizeHostConfig(true);
521             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
522 
523             // Test configs in test_mapping_1 doesn't exist, but should be listed in
524             // include-filters.
525             assertTrue(mRunner.getIncludeFilter().contains("test1"));
526             assertEquals(1, mRunner.getIncludeFilter().size());
527         } finally {
528             FileUtil.recursiveDelete(tempDir);
529         }
530     }
531 
532     /**
533      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests from test_mappings.zip
534      * and run with shard.
535      */
536     @Test
testLoadTests_shard()537     public void testLoadTests_shard() throws Exception {
538         File tempDir = null;
539         try {
540             mOptionSetter.setOptionValue("test-mapping-test-group", "postsubmit");
541 
542             tempDir = FileUtil.createTempDir("test_mapping");
543 
544             File srcDir = FileUtil.createTempDir("src", tempDir);
545             String srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
546             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
547             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
548             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
549             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
550             resourceStream = this.getClass().getResourceAsStream(srcFile);
551             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
552 
553             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
554             ZipUtil.createZip(srcDir, zipFile);
555 
556             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
557             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
558             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
559             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
560             when(mockBuildInfo.getRemoteFiles()).thenReturn(null);
561 
562             mTestInfo
563                     .getContext()
564                     .addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, mockBuildInfo);
565 
566             Collection<IRemoteTest> tests = mRunner.split(2, mTestInfo);
567             assertEquals(4, tests.size());
568             verify(mockBuildInfo, times(1)).getRemoteFiles();
569         } finally {
570             FileUtil.recursiveDelete(tempDir);
571         }
572     }
573 
574     /**
575      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests from test_mappings.zip
576      * and run with shard, and no test is split due to exclude-filter.
577      */
578     @Test
testLoadTests_shardNoTest()579     public void testLoadTests_shardNoTest() throws Exception {
580         File tempDir = null;
581         try {
582             tempDir = FileUtil.createTempDir("test_mapping");
583 
584             File srcDir = FileUtil.createTempDir("src", tempDir);
585             String srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
586             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
587             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
588             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
589             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
590             resourceStream = this.getClass().getResourceAsStream(srcFile);
591             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
592 
593             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
594             ZipUtil.createZip(srcDir, zipFile);
595 
596             mOptionSetter.setOptionValue("test-mapping-test-group", "postsubmit");
597             mOptionSetter.setOptionValue("test-mapping-path", srcDir.getName());
598             mOptionSetter.setOptionValue("exclude-filter", "suite/stub1");
599 
600             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
601             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
602             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
603             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
604 
605             mTestInfo
606                     .getContext()
607                     .addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, mockBuildInfo);
608 
609             Collection<IRemoteTest> tests = mRunner.split(2, mTestInfo);
610             assertEquals(null, tests);
611             assertEquals(2, mRunner.getIncludeFilter().size());
612         } finally {
613             FileUtil.recursiveDelete(tempDir);
614         }
615     }
616 
617     /** Test for {@link TestMappingSuiteRunner#loadTests()} to fail when no test is found. */
618     @Test(expected = RuntimeException.class)
testLoadTests_noTest()619     public void testLoadTests_noTest() throws Exception {
620         File tempDir = null;
621         try {
622             mOptionSetter.setOptionValue("test-mapping-test-group", "none-exist");
623 
624             tempDir = FileUtil.createTempDir("test_mapping");
625 
626             File srcDir = FileUtil.createTempDir("src", tempDir);
627 
628             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
629             ZipUtil.createZip(srcDir, zipFile);
630 
631             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
632             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
633             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
634 
635             mRunner.setBuild(mockBuildInfo);
636 
637             mRunner.loadTests();
638         } finally {
639             FileUtil.recursiveDelete(tempDir);
640         }
641     }
642 
643     /**
644      * Test for {@link TestMappingSuiteRunner#loadTests()} that when a test config supports
645      * IAbiReceiver, multiple instances of the config are queued up.
646      */
647     @Test
testLoadTestsForMultiAbi()648     public void testLoadTestsForMultiAbi() throws Exception {
649         mOptionSetter.setOptionValue("include-filter", "suite/stubAbi");
650 
651         LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
652         assertEquals(2, configMap.size());
653         assertTrue(configMap.containsKey(ABI_1 + " suite/stubAbi"));
654         assertTrue(configMap.containsKey(ABI_2 + " suite/stubAbi"));
655     }
656 
657     /**
658      * Test for {@link TestMappingSuiteRunner#loadTests()} that when force-test-mapping-module is
659      * specified, tests would be filtered.
660      */
661     @Test
testLoadTestsWithModule()662     public void testLoadTestsWithModule() throws Exception {
663         File tempDir = null;
664         try {
665             mOptionSetter.setOptionValue("test-mapping-test-group", "postsubmit");
666             mOptionSetter.setOptionValue("force-test-mapping-module", "suite/stub1");
667 
668             tempDir = FileUtil.createTempDir("test_mapping");
669 
670             File srcDir = FileUtil.createTempDir("src", tempDir);
671             String srcFile =
672                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
673             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
674             FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
675 
676             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
677             resourceStream = this.getClass().getResourceAsStream(srcFile);
678             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
679             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
680             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
681             resourceStream = this.getClass().getResourceAsStream(srcFile);
682             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
683 
684             List<File> filesToZip =
685                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
686             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
687             ZipUtil.createZip(filesToZip, zipFile);
688 
689             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
690             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
691             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
692             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
693 
694             mRunner.setBuild(mockBuildInfo);
695 
696             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
697             assertEquals(2, configMap.size());
698             assertTrue(configMap.containsKey(ABI_1 + " suite/stub1"));
699             assertTrue(configMap.containsKey(ABI_2 + " suite/stub1"));
700         } finally {
701             FileUtil.recursiveDelete(tempDir);
702         }
703     }
704 
705     /**
706      * Test for {@link TestMappingSuiteRunner#loadTests()} that when multi force-test-mapping-module
707      * are specified, tests would be filtered.
708      */
709     @Test
testLoadTestsWithMultiModules()710     public void testLoadTestsWithMultiModules() throws Exception {
711         File tempDir = null;
712         try {
713             mOptionSetter.setOptionValue("test-mapping-test-group", "postsubmit");
714             mOptionSetter.setOptionValue("force-test-mapping-module", "suite/stub1");
715             mOptionSetter.setOptionValue("force-test-mapping-module", "suite/stub2");
716 
717             tempDir = FileUtil.createTempDir("test_mapping");
718 
719             File srcDir = FileUtil.createTempDir("src", tempDir);
720             String srcFile =
721                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
722             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
723             FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
724 
725             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
726             resourceStream = this.getClass().getResourceAsStream(srcFile);
727             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
728             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
729             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
730             resourceStream = this.getClass().getResourceAsStream(srcFile);
731             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
732 
733             List<File> filesToZip =
734                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
735             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
736             ZipUtil.createZip(filesToZip, zipFile);
737 
738             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
739             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
740             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
741             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
742 
743             mRunner.setBuild(mockBuildInfo);
744 
745             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
746             assertEquals(4, configMap.size());
747             assertTrue(configMap.containsKey(ABI_1 + " suite/stub1"));
748             assertTrue(configMap.containsKey(ABI_1 + " suite/stub2"));
749             assertTrue(configMap.containsKey(ABI_2 + " suite/stub1"));
750             assertTrue(configMap.containsKey(ABI_2 + " suite/stub2"));
751         } finally {
752             FileUtil.recursiveDelete(tempDir);
753         }
754     }
755 
756     /**
757      * Test for {@link TestMappingSuiteRunner#getTestInfos(Set, String)} that when a module is
758      * specified, tests would be still found correctly.
759      */
760     @Test
testGetTestInfos()761     public void testGetTestInfos() throws Exception {
762         Set<TestInfo> testInfos = new HashSet<>();
763         testInfos.add(createTestInfo("test", "path"));
764         testInfos.add(createTestInfo("test", "path2"));
765         testInfos.add(createTestInfo("test2", "path2"));
766 
767         assertEquals(2, mRunner.getTestInfos(testInfos, "test").size());
768         assertEquals(1, mRunner.getTestInfos(testInfos, "test2").size());
769     }
770 
771     /**
772      * Test for {@link TestMappingSuiteRunner#dedupTestInfos(File, Set)} that tests with the same
773      * test options would be filtered out.
774      */
775     @Test
testDedupTestInfos()776     public void testDedupTestInfos() throws Exception {
777         Set<TestInfo> testInfos = new HashSet<>();
778         testInfos.add(createTestInfo("test", "path"));
779         testInfos.add(createTestInfo("test", "path2"));
780         assertEquals(1, mRunner.dedupTestInfos(new File("anything"), testInfos).size());
781 
782         TestInfo anotherInfo = new TestInfo("test", "folder3", false);
783         anotherInfo.addOption(new TestOption("include-filter", "value1"));
784         testInfos.add(anotherInfo);
785         assertEquals(2, mRunner.dedupTestInfos(new File("anything"), testInfos).size());
786 
787         // Aggregate the test-mapping sources with the same test options.
788         TestInfo anotherInfo2 = new TestInfo("test", "folder4", false);
789         anotherInfo2.addOption(new TestOption("include-filter", "value1"));
790         TestInfo anotherInfo3 = new TestInfo("test", "folder5", false);
791         anotherInfo3.addOption(new TestOption("include-filter", "value1"));
792         testInfos.clear();
793         testInfos = new HashSet<>(Arrays.asList(anotherInfo, anotherInfo2, anotherInfo3));
794         Set<TestInfo> dedupTestInfos = mRunner.dedupTestInfos(new File("anything"), testInfos);
795         assertEquals(1, dedupTestInfos.size());
796         TestInfo dedupTestInfo = dedupTestInfos.iterator().next();
797         Set<String> expected_sources =
798                 new HashSet<>(Arrays.asList("folder3", "folder4", "folder5"));
799         assertEquals(expected_sources, dedupTestInfo.getSources());
800     }
801 
802     /**
803      * Test for {@link TestMappingSuiteRunner#getTestSources(Set)} that test sources would be found
804      * correctly.
805      */
806     @Test
testGetTestSources()807     public void testGetTestSources() throws Exception {
808         Set<TestInfo> testInfos = new HashSet<>();
809         testInfos.add(createTestInfo("test", "path"));
810         testInfos.add(createTestInfo("test", "path2"));
811         List<String> results = mRunner.getTestSources(testInfos);
812         assertEquals(2, results.size());
813     }
814 
815     /**
816      * Test for {@link TestMappingSuiteRunner#parseOptions(TestInfo)} that the test options are
817      * injected correctly.
818      */
819     @Test
testParseOptions()820     public void testParseOptions() throws Exception {
821         TestInfo info = createTestInfo("test", "path");
822         mRunner.parseOptions(info);
823         assertEquals(1, mRunner.getIncludeFilter().size());
824         assertEquals(1, mRunner.getExcludeFilter().size());
825     }
826 
827     /**
828      * Test for {@link TestMappingSuiteRunner#createIndividualTests(Set, IConfiguration, IAbi)} that
829      * IRemoteTest object are created according to the test infos with different test options.
830      */
831     @Test
testCreateIndividualTestsWithDifferentTestInfos()832     public void testCreateIndividualTestsWithDifferentTestInfos() throws Exception {
833         IConfiguration config =
834                 ConfigurationFactory.getInstance()
835                         .createConfigurationFromArgs(new String[] {EMPTY_CONFIG});
836         config.setTest(new StubTest());
837         config.getConfigurationDescription().setModuleName(TEST_CONFIG_NAME);
838         Set<TestInfo> testInfos = new HashSet<>();
839         testInfos.add(createTestInfo("test", "path"));
840         testInfos.add(createTestInfo("test2", "path"));
841         assertEquals(2, mRunner2.createIndividualTests(testInfos, config, null).size());
842         assertEquals(1, mRunner2.getIncludeFilter().size());
843         assertEquals(1, mRunner2.getExcludeFilter().size());
844     }
845 
846     /**
847      * Test for {@link TestMappingSuiteRunner#createIndividualTests(Set, IConfiguration, IAbi)} that
848      * IRemoteTest object are created according to the test infos with multiple test options.
849      */
850     @Test
testCreateIndividualTestsWithDifferentTestOptions()851     public void testCreateIndividualTestsWithDifferentTestOptions() throws Exception {
852         IConfiguration config =
853                 ConfigurationFactory.getInstance()
854                         .createConfigurationFromArgs(new String[] {EMPTY_CONFIG});
855         config.setTest(new StubTest());
856         config.getConfigurationDescription().setModuleName(TEST_CONFIG_NAME);
857         Set<TestInfo> testInfos = new HashSet<>();
858         testInfos.add(createTestInfo("test", "path"));
859         TestInfo info = new TestInfo("test", "path", false);
860         info.addOption(new TestOption("include-filter", "include-filter"));
861         testInfos.add(info);
862         assertEquals(2, mRunner2.createIndividualTests(testInfos, config, null).size());
863         assertEquals(1, mRunner2.getIncludeFilter().size());
864         assertEquals(0, mRunner2.getExcludeFilter().size());
865     }
866 
867     /**
868      * Test for {@link TestMappingSuiteRunner#createIndividualTests(Set, IConfiguration, IAbi)} that
869      * IRemoteTest object are created according to the test infos with multiple test options and top
870      * level exclude-filter tests.
871      */
872     @Test
testCreateIndividualTestsWithExcludeFilterFromTFCommandLine()873     public void testCreateIndividualTestsWithExcludeFilterFromTFCommandLine() throws Exception {
874         IConfiguration config =
875                 ConfigurationFactory.getInstance()
876                         .createConfigurationFromArgs(new String[] {EMPTY_CONFIG});
877         config.setTest(new StubTest());
878         // Inject top level exclude-filter test options into runner
879         mRunner2.setExcludeFilter(new HashSet<>(Arrays.asList("some-exclude-filter")));
880         config.getConfigurationDescription().setModuleName(TEST_CONFIG_NAME);
881         Set<TestInfo> testInfos = new HashSet<>();
882         testInfos.add(createTestInfo("test", "path"));
883         TestInfo info = new TestInfo("test", "path", false);
884         info.addOption(new TestOption("include-filter", "include-filter"));
885         testInfos.add(info);
886         assertEquals(2, mRunner2.createIndividualTests(testInfos, config, null).size());
887         assertEquals(1, mRunner2.getIncludeFilter().size());
888         // Ensure exclude filter are kept
889         assertEquals(1, mRunner2.getExcludeFilter().size());
890     }
891 
892     @Test
testLoadTests_moduleDifferentoptions()893     public void testLoadTests_moduleDifferentoptions() throws Exception {
894         File tempDir = null;
895         try {
896             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
897 
898             tempDir = FileUtil.createTempDir("test_mapping");
899 
900             File srcDir = FileUtil.createTempDir("src", tempDir);
901             String srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
902             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
903             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
904             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
905             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
906             resourceStream = this.getClass().getResourceAsStream(srcFile);
907             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
908 
909             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
910             ZipUtil.createZip(srcDir, zipFile);
911 
912             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
913             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
914             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
915             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
916             when(mockBuildInfo.getBuildBranch()).thenReturn("branch");
917             when(mockBuildInfo.getBuildFlavor()).thenReturn("flavor");
918             when(mockBuildInfo.getBuildId()).thenReturn("id");
919 
920             IInvocationContext mContext = new InvocationContext();
921             mContext.addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, mockBuildInfo);
922             mRunner.setInvocationContext(mContext);
923             mRunner.setBuild(mockBuildInfo);
924 
925             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
926             assertEquals(2, configMap.size());
927             assertTrue(configMap.keySet().contains("armeabi-v7a suite/stub1"));
928             assertTrue(configMap.keySet().contains("arm64-v8a suite/stub1"));
929 
930             for (Entry<String, IConfiguration> config : configMap.entrySet()) {
931                 IConfiguration currentConfig = config.getValue();
932                 IAbi abi = currentConfig.getConfigurationDescription().getAbi();
933                 // Ensure that all the subtests abi match the module abi
934                 for (IRemoteTest test : currentConfig.getTests()) {
935                     if (test instanceof IAbiReceiver) {
936                         assertEquals(abi, ((IAbiReceiver) test).getAbi());
937                     }
938                 }
939             }
940         } finally {
941             FileUtil.recursiveDelete(tempDir);
942         }
943     }
944 
945     /**
946      * Test for {@link TestMappingSuiteRunner#loadTests()} that IRemoteTest object are created
947      * according to the test infos with multiple test options.
948      */
949     @Test
testLoadTestsForMainline()950     public void testLoadTestsForMainline() throws Exception {
951         File tempDir = null;
952         File tempTestsDir = null;
953         try {
954             tempDir = FileUtil.createTempDir("test_mapping");
955             tempTestsDir = FileUtil.createTempDir("test_mapping_testcases");
956 
957             File zipFile = createMainlineTestMappingZip(tempDir);
958             createMainlineModuleConfig(tempTestsDir.getAbsolutePath());
959 
960             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
961             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
962             when(mockBuildInfo.getTestsDir()).thenReturn(tempTestsDir);
963             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
964             when(mockBuildInfo.getBuildBranch()).thenReturn("branch");
965             when(mockBuildInfo.getBuildFlavor()).thenReturn("flavor");
966             when(mockBuildInfo.getBuildId()).thenReturn("id");
967 
968             IInvocationContext mContext = new InvocationContext();
969             mContext.addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, mockBuildInfo);
970             mMainlineRunner.setInvocationContext(mContext);
971             mMainlineRunner.setBuild(mockBuildInfo);
972 
973             mMainlineOptionSetter.setOptionValue("enable-mainline-parameterized-modules", "true");
974             mMainlineOptionSetter.setOptionValue("skip-loading-config-jar", "true");
975             mMainlineOptionSetter.setOptionValue("test-mapping-test-group", "mainline-presubmit");
976             LinkedHashMap<String, IConfiguration> configMap = mMainlineRunner.loadTests();
977 
978             assertEquals(3, configMap.size());
979             assertTrue(configMap.containsKey(ABI_1 + " test[mod1.apk]"));
980             assertTrue(configMap.containsKey(ABI_1 + " test[mod2.apk]"));
981             assertTrue(configMap.containsKey(ABI_1 + " test[mod1.apk+mod2.apk]"));
982             HostTest test = (HostTest) configMap.get(ABI_1 + " test[mod1.apk]").getTests().get(0);
983             assertTrue(test.getIncludeFilters().contains("test-filter"));
984 
985             test = (HostTest) configMap.get(ABI_1 + " test[mod2.apk]").getTests().get(0);
986             assertTrue(test.getIncludeFilters().contains("test-filter2"));
987 
988             test = (HostTest) configMap.get(ABI_1 + " test[mod1.apk+mod2.apk]").getTests().get(0);
989             assertTrue(test.getIncludeFilters().isEmpty());
990             assertEquals(1, test.getExcludeAnnotations().size());
991             assertEquals("test-annotation", test.getExcludeAnnotations().iterator().next());
992         } finally {
993             FileUtil.recursiveDelete(tempDir);
994             FileUtil.recursiveDelete(tempTestsDir);
995         }
996     }
997 
998     /**
999      * Test for {@link TestMappingSuiteRunner#createIndividualTests(Set, IConfiguration, IAbi)} that
1000      * IRemoteTest object are created according to the test infos with the same test options and
1001      * name.
1002      */
1003     @Test
testCreateIndividualTestsWithSameTestInfos()1004     public void testCreateIndividualTestsWithSameTestInfos() throws Exception {
1005         IConfiguration config =
1006                 ConfigurationFactory.getInstance()
1007                         .createConfigurationFromArgs(new String[] {EMPTY_CONFIG});
1008         Set<TestInfo> testInfos = new HashSet<>();
1009         testInfos.add(createTestInfo("test", "path"));
1010         testInfos.add(createTestInfo("test", "path"));
1011         assertEquals(1, mRunner2.createIndividualTests(testInfos, config, null).size());
1012         assertEquals(1, mRunner2.getIncludeFilter().size());
1013         assertEquals(1, mRunner2.getExcludeFilter().size());
1014     }
1015 
1016     /**
1017      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests from test_mappings.zip
1018      * with ignore-test-mapping-imports flag.
1019      */
1020     @Test
testLoadTests_testMappingsIncludeImports()1021     public void testLoadTests_testMappingsIncludeImports() throws Exception {
1022         File tempDir = null;
1023         try {
1024             mOptionSetter.setOptionValue("ignore-test-mapping-imports", "false");
1025             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
1026             mOptionSetter.setOptionValue("test-mapping-path", "path2/path3");
1027 
1028             tempDir = FileUtil.createTempDir("test_mapping");
1029             File path1 = new File(tempDir.getAbsolutePath() + "/path1");
1030             path1.mkdir();
1031             String srcFile =
1032                     File.separator + TEST_DATA_DIR + File.separator + "test_mapping_with_import_1";
1033             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
1034             FileUtil.saveResourceFile(resourceStream, path1, TEST_MAPPING);
1035 
1036             File path2 = new File(tempDir.getAbsolutePath() + "/path2");
1037             path2.mkdir();
1038             srcFile =
1039                     File.separator + TEST_DATA_DIR + File.separator + "test_mapping_with_import_2";
1040             resourceStream = this.getClass().getResourceAsStream(srcFile);
1041             FileUtil.saveResourceFile(resourceStream, path2, TEST_MAPPING);
1042 
1043             File path3 = new File(path2.getAbsolutePath() + "/path3");
1044             path3.mkdir();
1045             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
1046             resourceStream = this.getClass().getResourceAsStream(srcFile);
1047             FileUtil.saveResourceFile(resourceStream, path3, TEST_MAPPING);
1048 
1049             srcFile = File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
1050             resourceStream = this.getClass().getResourceAsStream(srcFile);
1051             FileUtil.saveResourceFile(resourceStream, tempDir, DISABLED_PRESUBMIT_TESTS);
1052             List<File> filesToZip =
1053                     Arrays.asList(path1, path2, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
1054 
1055             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
1056             ZipUtil.createZip(filesToZip, zipFile);
1057 
1058             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1059             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1060             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1061             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1062             mRunner.setBuild(mockBuildInfo);
1063             mRunner.setPrioritizeHostConfig(true);
1064 
1065             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
1066             assertEquals(3, mRunner.getIncludeFilter().size());
1067             assertTrue(mRunner.getIncludeFilter().contains("import-test1"));
1068             assertTrue(mRunner.getIncludeFilter().contains("import-test2"));
1069             assertTrue(mRunner.getIncludeFilter().contains("test1"));
1070         } finally {
1071             FileUtil.recursiveDelete(tempDir);
1072         }
1073     }
1074 
1075     /**
1076      * Test for {@link TestMappingSuiteRunner#filterByAllowedTestLists(Set)} for filtering tests
1077      * from a list of allowed test lists.
1078      */
1079     @Test
testFilterByAllowedTestLists()1080     public void testFilterByAllowedTestLists() throws Exception {
1081         File tempDir = null;
1082         try {
1083             mOptionSetter.setOptionValue("test-mapping-allowed-tests-list", "test-list.zip");
1084 
1085             tempDir = FileUtil.createTempDir("test_lists");
1086             File listFile = Paths.get(tempDir.getAbsolutePath(), "test-list").toFile();
1087             FileUtil.writeToFile("test1.config\n", listFile);
1088             FileUtil.writeToFile("dir/test2.config", listFile, true);
1089 
1090             List<File> filesToZip = Arrays.asList(listFile);
1091             File zipFile = Paths.get(tempDir.getAbsolutePath(), "test-list.zip").toFile();
1092             ZipUtil.createZip(filesToZip, zipFile);
1093 
1094             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1095             when(mockBuildInfo.getFile("test-list.zip")).thenReturn(zipFile);
1096             mRunner.setBuild(mockBuildInfo);
1097 
1098             Set<TestInfo> testInfos = new HashSet<>();
1099             TestInfo test1 = createTestInfo("test1", "path");
1100             testInfos.add(test1);
1101             TestInfo test2 = createTestInfo("test2", "path");
1102             testInfos.add(test2);
1103             testInfos.add(createTestInfo("test3", "path"));
1104 
1105             testInfos = mRunner.filterByAllowedTestLists(mockBuildInfo, testInfos);
1106             assertEquals(2, testInfos.size());
1107             assertTrue(testInfos.contains(test1));
1108             assertTrue(testInfos.contains(test2));
1109         } finally {
1110             FileUtil.recursiveDelete(tempDir);
1111         }
1112     }
1113 
1114     @Test
testLoadTests_WithCollisionAdditionalTestMappingZip()1115     public void testLoadTests_WithCollisionAdditionalTestMappingZip() throws Exception {
1116         File tempDir = null;
1117         try {
1118             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
1119             mOptionSetter.setOptionValue("additional-test-mapping-zip", "extra-zip");
1120 
1121             tempDir = FileUtil.createTempDir("test_mapping");
1122             File zipFile = createTestMappingZip(tempDir);
1123 
1124             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1125             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1126             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1127             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1128             when(mockBuildInfo.getFile("extra-zip")).thenReturn(zipFile);
1129             mRunner.setBuild(mockBuildInfo);
1130 
1131             mRunner.loadTests();
1132             fail("Should have thrown an exception.");
1133         } catch (HarnessRuntimeException expected) {
1134             // expected
1135             assertTrue(expected.getMessage().contains("Collision of Test Mapping file"));
1136         } finally {
1137             FileUtil.recursiveDelete(tempDir);
1138         }
1139     }
1140 
1141     /**
1142      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests when full run is
1143      * forced.
1144      */
1145     @Test
testLoadTests_ForceFullRun()1146     public void testLoadTests_ForceFullRun() throws Exception {
1147         File tempDir = null;
1148         try {
1149             mOptionSetter.setOptionValue("test-mapping-test-group", "postsubmit");
1150             mOptionSetter.setOptionValue("force-full-run", "true");
1151 
1152             tempDir = FileUtil.createTempDir("test_mapping");
1153 
1154             File srcDir = FileUtil.createTempDir("src", tempDir);
1155             String srcFile =
1156                     File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
1157             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
1158             FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
1159 
1160             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
1161             resourceStream = this.getClass().getResourceAsStream(srcFile);
1162             FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
1163             File subDir = FileUtil.createTempDir("sub_dir", srcDir);
1164             srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
1165             resourceStream = this.getClass().getResourceAsStream(srcFile);
1166             FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
1167 
1168             List<File> filesToZip =
1169                     Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
1170             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
1171             ZipUtil.createZip(filesToZip, zipFile);
1172 
1173             mOptionSetter.setOptionValue("test-mapping-path", srcDir.getName());
1174 
1175             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1176             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1177             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1178             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1179             mRunner.setBuild(mockBuildInfo);
1180             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
1181             assertEquals(4, configMap.size());
1182 
1183         } finally {
1184             FileUtil.recursiveDelete(tempDir);
1185         }
1186     }
1187 
1188     @Test
testLoadTests_WithoutCollisionAdditionalTestMappingZip()1189     public void testLoadTests_WithoutCollisionAdditionalTestMappingZip() throws Exception {
1190         File tempDir = null;
1191         File tempDir2 = null;
1192         try {
1193             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
1194             mOptionSetter.setOptionValue("additional-test-mapping-zip", "extra-zip");
1195 
1196             tempDir = FileUtil.createTempDir("test_mapping");
1197             tempDir2 = FileUtil.createTempDir("test_mapping");
1198             File zipFile = createTestMappingZip(tempDir);
1199             File zipFile2 = createTestMappingZip(tempDir2);
1200 
1201             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1202             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1203             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1204             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1205             when(mockBuildInfo.getFile("extra-zip")).thenReturn(zipFile2);
1206             mRunner.setBuild(mockBuildInfo);
1207 
1208             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
1209             assertEquals(2, configMap.size());
1210             verify(mockBuildInfo, times(1)).getFile(TEST_MAPPINGS_ZIP);
1211             verify(mockBuildInfo, times(1)).getFile("extra-zip");
1212         } finally {
1213             FileUtil.recursiveDelete(tempDir);
1214             FileUtil.recursiveDelete(tempDir2);
1215         }
1216     }
1217 
1218     @Test
testLoadTests_WithMissingAdditionalTestMappingZips()1219     public void testLoadTests_WithMissingAdditionalTestMappingZips() throws Exception {
1220         File tempDir = null;
1221         try {
1222             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
1223             mOptionSetter.setOptionValue("additional-test-mapping-zip", "extra-zip");
1224 
1225             tempDir = FileUtil.createTempDir("test_mapping");
1226             File zipFile = createTestMappingZip(tempDir);
1227 
1228             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1229             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1230             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1231             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1232             when(mockBuildInfo.getFile("extra-zip")).thenReturn(null);
1233             mRunner.setBuild(mockBuildInfo);
1234             mRunner.loadTests();
1235             fail("Should have thrown an exception.");
1236         } catch (HarnessRuntimeException expected) {
1237             // expected
1238             assertEquals(
1239                 "Missing extra-zip in the BuildInfo file.", expected.getMessage());
1240         } finally {
1241             FileUtil.recursiveDelete(tempDir);
1242         }
1243     }
1244 
1245     /**
1246      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests with checking modified
1247      * files matched file patterns.
1248      */
1249     @Test
testLoadTestsWithFilePatternsExample1()1250     public void testLoadTestsWithFilePatternsExample1() throws Exception {
1251         // Test directory structure:
1252         // ├── a/TEST_MAPPING (File patterns: *.java)
1253         // └── b/TEST_MAPPING (No file patterns)
1254         File tempDir = null;
1255         try {
1256             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
1257             mOptionSetter.setOptionValue("test-mapping-path", "a");
1258             mOptionSetter.setOptionValue("test-mapping-path", "b");
1259             mOptionSetter.setOptionValue("test-mapping-matched-pattern-paths", "a/b.java");
1260             mOptionSetter.setOptionValue(
1261                     "test-mapping-matched-pattern-paths", "a/BroadcastQueueImpl.java");
1262 
1263             tempDir = FileUtil.createTempDir("test_mapping");
1264             File subDir_a = new File(tempDir.getAbsolutePath() + File.separator + "a");
1265             subDir_a.mkdir();
1266             String srcFile =
1267                     File.separator
1268                             + TEST_DATA_DIR
1269                             + File.separator
1270                             + "test_mapping_with_file_patterns_java";
1271             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
1272             FileUtil.saveResourceFile(resourceStream, subDir_a, TEST_MAPPING);
1273             File subDir_b = new File(tempDir.getAbsolutePath() + File.separator + "b");
1274             subDir_b.mkdir();
1275             srcFile =
1276                     File.separator
1277                             + TEST_DATA_DIR
1278                             + File.separator
1279                             + "test_mapping_with_no_file_patterns";
1280             resourceStream = this.getClass().getResourceAsStream(srcFile);
1281             FileUtil.saveResourceFile(resourceStream, subDir_b, TEST_MAPPING);
1282 
1283             List<File> filesToZip = Arrays.asList(subDir_a, subDir_b);
1284             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
1285             ZipUtil.createZip(filesToZip, zipFile);
1286 
1287             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1288             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1289             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1290             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1291             mRunner.setBuild(mockBuildInfo);
1292 
1293             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
1294             assertEquals(3, mRunner.getIncludeFilter().size());
1295             assertTrue(mRunner.getIncludeFilter().contains("test_java"));
1296             assertTrue(mRunner.getIncludeFilter().contains("Broadcast_java"));
1297             assertTrue(mRunner.getIncludeFilter().contains("test_no_pattern"));
1298 
1299         } finally {
1300             FileUtil.recursiveDelete(tempDir);
1301         }
1302     }
1303 
1304     /**
1305      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests with checking modified
1306      * files matched file patterns.
1307      */
1308     @Test
testLoadTestsWithFilePatternsExample2()1309     public void testLoadTestsWithFilePatternsExample2() throws Exception {
1310         // Test directory structure:
1311         // ├── a/TEST_MAPPING (File patterns: *.java)
1312         // ├── a/b/TEST_MAPPING (File patterns: *.txt)
1313         // └── a/c/TEST_MAPPING (No file patterns)
1314         File tempDir = null;
1315         try {
1316             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
1317             mOptionSetter.setOptionValue("test-mapping-path", "a/b");
1318             mOptionSetter.setOptionValue("test-mapping-path", "a/c");
1319             mOptionSetter.setOptionValue("test-mapping-matched-pattern-paths", "a/c.java");
1320             mOptionSetter.setOptionValue("test-mapping-matched-pattern-paths", "a/b/d.txt");
1321 
1322             tempDir = FileUtil.createTempDir("test_mapping");
1323             File subDir_a = new File(tempDir.getAbsolutePath() + File.separator + "a");
1324             subDir_a.mkdir();
1325             String srcFile =
1326                     File.separator
1327                             + TEST_DATA_DIR
1328                             + File.separator
1329                             + "test_mapping_with_file_patterns_java";
1330             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
1331             FileUtil.saveResourceFile(resourceStream, subDir_a, TEST_MAPPING);
1332             File subDir_b = new File(subDir_a.getAbsolutePath() + File.separator + "b");
1333             subDir_b.mkdir();
1334             srcFile =
1335                     File.separator
1336                             + TEST_DATA_DIR
1337                             + File.separator
1338                             + "test_mapping_with_file_patterns_txt";
1339             resourceStream = this.getClass().getResourceAsStream(srcFile);
1340             FileUtil.saveResourceFile(resourceStream, subDir_b, TEST_MAPPING);
1341             File subDir_c = new File(subDir_a.getAbsolutePath() + File.separator + "c");
1342             subDir_c.mkdir();
1343             srcFile =
1344                     File.separator
1345                             + TEST_DATA_DIR
1346                             + File.separator
1347                             + "test_mapping_with_no_file_patterns";
1348             resourceStream = this.getClass().getResourceAsStream(srcFile);
1349             FileUtil.saveResourceFile(resourceStream, subDir_c, TEST_MAPPING);
1350 
1351             List<File> filesToZip = Arrays.asList(subDir_a);
1352             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
1353             ZipUtil.createZip(filesToZip, zipFile);
1354 
1355             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1356             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1357             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1358             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1359             mRunner.setBuild(mockBuildInfo);
1360 
1361             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
1362             assertEquals(3, mRunner.getIncludeFilter().size());
1363             assertTrue(mRunner.getIncludeFilter().contains("test_java"));
1364             assertTrue(mRunner.getIncludeFilter().contains("test_txt"));
1365             assertTrue(mRunner.getIncludeFilter().contains("test_no_pattern"));
1366 
1367         } finally {
1368             FileUtil.recursiveDelete(tempDir);
1369         }
1370     }
1371 
1372     /**
1373      * Test for {@link TestMappingSuiteRunner#loadTests()} for loading tests with checking modified
1374      * files matched file patterns.
1375      */
1376     @Test
testLoadTestsWithFilePatternsExample3()1377     public void testLoadTestsWithFilePatternsExample3() throws Exception {
1378         // Test directory structure:
1379         // ├── a/TEST_MAPPING (File patterns: *.java)
1380         // ├── a/b/TEST_MAPPING (No file patterns)
1381         // ├── a/b/c/TEST_MAPPING (File patterns: *.txt)
1382         // └── a/b/c/d/TEST_MAPPING (No file patterns)
1383         File tempDir = null;
1384         try {
1385             mOptionSetter.setOptionValue("test-mapping-test-group", "presubmit");
1386             mOptionSetter.setOptionValue("test-mapping-path", "a/b/c/d");
1387             mOptionSetter.setOptionValue("test-mapping-matched-pattern-paths", "a/b/c/d/e.java");
1388             mOptionSetter.setOptionValue("test-mapping-matched-pattern-paths", "a/b/c/d.txt");
1389 
1390             tempDir = FileUtil.createTempDir("test_mapping");
1391             File subDir_a = new File(tempDir.getAbsolutePath() + File.separator + "a");
1392             subDir_a.mkdir();
1393             String srcFile =
1394                     File.separator
1395                             + TEST_DATA_DIR
1396                             + File.separator
1397                             + "test_mapping_with_file_patterns_java";
1398             InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
1399             FileUtil.saveResourceFile(resourceStream, subDir_a, TEST_MAPPING);
1400             File subDir_b = new File(subDir_a.getAbsolutePath() + File.separator + "b");
1401             subDir_b.mkdir();
1402             srcFile =
1403                     File.separator
1404                             + TEST_DATA_DIR
1405                             + File.separator
1406                             + "test_mapping_with_no_file_patterns";
1407             resourceStream = this.getClass().getResourceAsStream(srcFile);
1408             FileUtil.saveResourceFile(resourceStream, subDir_b, TEST_MAPPING);
1409             File subDir_c = new File(subDir_b.getAbsolutePath() + File.separator + "c");
1410             subDir_c.mkdir();
1411             srcFile =
1412                     File.separator
1413                             + TEST_DATA_DIR
1414                             + File.separator
1415                             + "test_mapping_with_file_patterns_txt";
1416             resourceStream = this.getClass().getResourceAsStream(srcFile);
1417             FileUtil.saveResourceFile(resourceStream, subDir_c, TEST_MAPPING);
1418             File subDir_d = new File(subDir_c.getAbsolutePath() + File.separator + "d");
1419             subDir_d.mkdir();
1420             srcFile =
1421                     File.separator
1422                             + TEST_DATA_DIR
1423                             + File.separator
1424                             + "test_mapping_with_no_file_patterns";
1425             resourceStream = this.getClass().getResourceAsStream(srcFile);
1426             FileUtil.saveResourceFile(resourceStream, subDir_d, TEST_MAPPING);
1427 
1428             List<File> filesToZip = Arrays.asList(subDir_a);
1429             File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
1430             ZipUtil.createZip(filesToZip, zipFile);
1431 
1432             IDeviceBuildInfo mockBuildInfo = mock(IDeviceBuildInfo.class);
1433             when(mockBuildInfo.getFile(BuildInfoFileKey.TARGET_LINKED_DIR)).thenReturn(null);
1434             when(mockBuildInfo.getTestsDir()).thenReturn(mTempFolder.newFolder());
1435             when(mockBuildInfo.getFile(TEST_MAPPINGS_ZIP)).thenReturn(zipFile);
1436             mRunner.setBuild(mockBuildInfo);
1437 
1438             LinkedHashMap<String, IConfiguration> configMap = mRunner.loadTests();
1439             assertEquals(3, mRunner.getIncludeFilter().size());
1440             assertTrue(mRunner.getIncludeFilter().contains("test_java"));
1441             assertTrue(mRunner.getIncludeFilter().contains("test_txt"));
1442             assertTrue(mRunner.getIncludeFilter().contains("test_no_pattern"));
1443 
1444         } finally {
1445             FileUtil.recursiveDelete(tempDir);
1446         }
1447     }
1448 
1449     /** Helper to create specific test infos. */
createTestInfo(String name, String source)1450     private TestInfo createTestInfo(String name, String source) {
1451         TestInfo info = new TestInfo(name, source, false);
1452         info.addOption(new TestOption("include-filter", name));
1453         info.addOption(new TestOption("exclude-filter", name));
1454         info.addOption(new TestOption("other", name));
1455         return info;
1456     }
1457 
1458     /** Helper to create test_mappings.zip for Mainline. */
createMainlineTestMappingZip(File tempDir)1459     private File createMainlineTestMappingZip(File tempDir) throws IOException {
1460         File srcDir = FileUtil.createTempDir("src", tempDir);
1461         String srcFile = File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
1462         InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
1463         FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
1464 
1465         srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_with_mainline";
1466         resourceStream = this.getClass().getResourceAsStream(srcFile);
1467         FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
1468         File subDir = FileUtil.createTempDir("sub_dir", srcDir);
1469         srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
1470         resourceStream = this.getClass().getResourceAsStream(srcFile);
1471         FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
1472 
1473         List<File> filesToZip = Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
1474         File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
1475         ZipUtil.createZip(filesToZip, zipFile);
1476 
1477         return zipFile;
1478     }
1479 
1480     /** Helper to create test_mappings.zip. */
createTestMappingZip(File tempDir)1481     private File createTestMappingZip(File tempDir) throws IOException {
1482         File srcDir = FileUtil.createTempDir("src", tempDir);
1483         String srcFile = File.separator + TEST_DATA_DIR + File.separator + DISABLED_PRESUBMIT_TESTS;
1484         InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
1485         FileUtil.saveResourceFile(resourceStream, srcDir, DISABLED_PRESUBMIT_TESTS);
1486 
1487         srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
1488         resourceStream = this.getClass().getResourceAsStream(srcFile);
1489         FileUtil.saveResourceFile(resourceStream, srcDir, TEST_MAPPING);
1490         File subDir = FileUtil.createTempDir("sub_dir", srcDir);
1491         srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_2";
1492         resourceStream = this.getClass().getResourceAsStream(srcFile);
1493         FileUtil.saveResourceFile(resourceStream, subDir, TEST_MAPPING);
1494 
1495         List<File> filesToZip = Arrays.asList(srcDir, new File(tempDir, DISABLED_PRESUBMIT_TESTS));
1496         File zipFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPINGS_ZIP).toFile();
1497         ZipUtil.createZip(filesToZip, zipFile);
1498 
1499         return zipFile;
1500     }
1501 
1502     /** Helper to create module config with parameterized mainline modules. */
createMainlineModuleConfig(String tempTestsDir)1503     private File createMainlineModuleConfig(String tempTestsDir) throws IOException {
1504         File moduleConfig = new File(tempTestsDir, "test" + SuiteModuleLoader.CONFIG_EXT);
1505         FileUtil.writeToFile(TEST_MAINLINE_CONFIG, moduleConfig);
1506         return moduleConfig;
1507     }
1508 }
1509