1 /*
2  * Copyright (C) 2017 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.assertTrue;
20 import static org.mockito.Mockito.doReturn;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.spy;
23 
24 import com.android.tradefed.build.DeviceBuildInfo;
25 import com.android.tradefed.build.IDeviceBuildInfo;
26 import com.android.tradefed.config.IConfiguration;
27 import com.android.tradefed.config.OptionSetter;
28 import com.android.tradefed.device.ITestDevice;
29 import com.android.tradefed.result.ITestInvocationListener;
30 import com.android.tradefed.targetprep.ITargetPreparer;
31 import com.android.tradefed.testtype.Abi;
32 import com.android.tradefed.testtype.IAbi;
33 import com.android.tradefed.testtype.IRemoteTest;
34 import com.android.tradefed.testtype.InstrumentationTest;
35 import com.android.tradefed.testtype.UiAutomatorTest;
36 import com.android.tradefed.util.AbiUtils;
37 import com.android.tradefed.util.FileUtil;
38 
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.junit.runners.JUnit4;
43 import java.io.File;
44 import java.io.IOException;
45 import java.util.ArrayList;
46 import java.util.HashSet;
47 import java.util.LinkedHashMap;
48 import java.util.List;
49 import java.util.Set;
50 
51 /** Unit tests for {@link AtestRunner}. */
52 @RunWith(JUnit4.class)
53 public class AtestRunnerTest {
54 
55     private static final String TEST_CONFIG =
56         "<configuration description=\"Runs a stub tests part of some suite\">\n"
57             + "    <test class=\"com.android.tradefed.testtype.suite.SuiteModuleLoaderTest"
58             + "$TestInject\" />\n"
59             + "</configuration>";
60 
61     private static final String ABI = "armeabi-v7a";
62     private static final String TEST_NAME_FMT = ABI + " %s";
63     private static final String INSTRUMENTATION_TEST_NAME =
64             String.format(TEST_NAME_FMT, "tf/instrumentation");
65 
66     private AtestRunner mSpyRunner;
67     private OptionSetter setter;
68     private IDeviceBuildInfo mBuildInfo;
69     private ITestDevice mMockDevice;
70     private String classA = "fully.qualified.classA";
71     private String classB = "fully.qualified.classB";
72     private String method1 = "method1";
73 
74     @Before
setUp()75     public void setUp() throws Exception {
76         mSpyRunner = spy(new AtestRunner());
77         mBuildInfo = spy(new DeviceBuildInfo());
78         mMockDevice = mock(ITestDevice.class);
79         mSpyRunner.setBuild(mBuildInfo);
80         mSpyRunner.setDevice(mMockDevice);
81 
82         // Hardcode the abis to avoid failures related to running the tests against a particular
83         // abi build of tradefed.
84         Set<IAbi> abis = new HashSet<>();
85         abis.add(new Abi(ABI, AbiUtils.getBitness(ABI)));
86         doReturn(abis).when(mSpyRunner).getAbis(mMockDevice);
87         doReturn(new File("some-dir")).when(mBuildInfo).getTestsDir();
88     }
89 
90     @Test
testLoadTests_one()91     public void testLoadTests_one() throws Exception {
92         setter = new OptionSetter(mSpyRunner);
93         setter.setOptionValue("suite-config-prefix", "tf");
94         setter.setOptionValue("include-filter", "tf/fake");
95         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
96         assertEquals(1, configMap.size());
97         assertTrue(configMap.containsKey(String.format(TEST_NAME_FMT, "tf/fake")));
98     }
99 
100     @Test
testLoadTests_two()101     public void testLoadTests_two() throws Exception {
102         setter = new OptionSetter(mSpyRunner);
103         setter.setOptionValue("suite-config-prefix", "tf");
104         setter.setOptionValue("include-filter", "tf/fake");
105         setter.setOptionValue("include-filter", "tf/func");
106         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
107         assertEquals(2, configMap.size());
108         assertTrue(configMap.containsKey(String.format(TEST_NAME_FMT, "tf/fake")));
109         assertTrue(configMap.containsKey(String.format(TEST_NAME_FMT, "tf/func")));
110     }
111 
112     @Test
testLoadTests_filter()113     public void testLoadTests_filter() throws Exception {
114         setter = new OptionSetter(mSpyRunner);
115         setter.setOptionValue("suite-config-prefix", "tf");
116         setter.setOptionValue("include-filter", "tf/uiautomator");
117         setter.setOptionValue("atest-include-filter", "tf/uiautomator:" + classA);
118         setter.setOptionValue("atest-include-filter", "tf/uiautomator:" + classB + "#" + method1);
119         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
120         assertEquals(1, configMap.size());
121         String testName = String.format(TEST_NAME_FMT, "tf/uiautomator");
122         assertTrue(configMap.containsKey(testName));
123         IConfiguration config = configMap.get(testName);
124         List<IRemoteTest> tests = config.getTests();
125         assertEquals(1, tests.size());
126         UiAutomatorTest test = (UiAutomatorTest) tests.get(0);
127         List<String> classFilters = new ArrayList<String>();
128         classFilters.add(classA);
129         classFilters.add(classB + "#" + method1);
130         assertEquals(classFilters, test.getClassNames());
131     }
132 
133     @Test
testLoadTests_WithTFConfigSpecified()134     public void testLoadTests_WithTFConfigSpecified() throws Exception {
135         setter = new OptionSetter(mSpyRunner);
136         setter.setOptionValue("suite-config-prefix", "suite");
137         setter.setOptionValue("tf-config-path", "suite/base-suite1");
138         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
139         assertEquals(1, configMap.size());
140         String testName = String.format(TEST_NAME_FMT, "suite/base-suite1");
141         assertTrue(configMap.containsKey(testName));
142     }
143 
144     @Test
testLoadTests_WithModuleAndTFConfigSpecified()145     public void testLoadTests_WithModuleAndTFConfigSpecified() throws Exception {
146         File tmpDir = FileUtil.createTempDir("some-dir");
147         String filePath = createModuleConfig(tmpDir, "TestModule");
148         try {
149             mSpyRunner.setupFilters(tmpDir);
150             setter = new OptionSetter(mSpyRunner);
151             setter.setOptionValue("suite-config-prefix", "suite");
152             setter.setOptionValue("tf-config-path", "suite/base-suite1");
153             setter.setOptionValue("module-config-path", filePath);
154             LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
155             assertEquals(2, configMap.size());
156             String testName = String.format(TEST_NAME_FMT, "TestModule");
157             assertTrue(configMap.containsKey(testName));
158             testName = String.format(TEST_NAME_FMT, "suite/base-suite1");
159             assertTrue(configMap.containsKey(testName));
160         } finally {
161             FileUtil.recursiveDelete(tmpDir);
162         }
163     }
164 
165     @Test
testLoadTests_WithModuleConfigSpecified()166     public void testLoadTests_WithModuleConfigSpecified() throws Exception {
167         File tmpDir = FileUtil.createTempDir("some-dir");
168         String filePath = createModuleConfig(tmpDir, "TestModule");
169         try {
170             mSpyRunner.setupFilters(tmpDir);
171             setter = new OptionSetter(mSpyRunner);
172             setter.setOptionValue("module-config-path", filePath);
173             LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
174             assertEquals(1, configMap.size());
175             String testName = String.format(TEST_NAME_FMT, "TestModule");
176             assertTrue(configMap.containsKey(testName));
177         } finally {
178             FileUtil.recursiveDelete(tmpDir);
179         }
180     }
181 
182     @Test
testLoadTests_ignoreFilter()183     public void testLoadTests_ignoreFilter() throws Exception {
184         setter = new OptionSetter(mSpyRunner);
185         setter.setOptionValue("suite-config-prefix", "suite");
186         setter.setOptionValue("include-filter", "suite/base-suite1");
187         setter.setOptionValue("atest-include-filter", "suite/base-suite1:" + classA);
188         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
189         assertEquals(1, configMap.size());
190         String testName = String.format(TEST_NAME_FMT, "suite/base-suite1");
191         assertTrue(configMap.containsKey(testName));
192         IConfiguration config = configMap.get(testName);
193         List<IRemoteTest> tests = config.getTests();
194         assertEquals(1, tests.size());
195         BaseTestSuite test = (BaseTestSuite) tests.get(0);
196         assertEquals(new HashSet<String>(), test.getIncludeFilter());
197     }
198 
199     @Test
testWaitForDebugger()200     public void testWaitForDebugger() throws Exception {
201         OptionSetter setter = new OptionSetter(mSpyRunner);
202         setter.setOptionValue("suite-config-prefix", "tf");
203         setter.setOptionValue("wait-for-debugger", "true");
204         setter.setOptionValue("include-filter", "tf/instrumentation");
205         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
206         assertEquals(1, configMap.size());
207         IConfiguration config = configMap.get(INSTRUMENTATION_TEST_NAME);
208         IRemoteTest test = config.getTests().get(0);
209         assertTrue(((InstrumentationTest) test).getDebug());
210     }
211 
212     @Test
testdisableTargetPreparers()213     public void testdisableTargetPreparers() throws Exception {
214         OptionSetter setter = new OptionSetter(mSpyRunner);
215         setter.setOptionValue("suite-config-prefix", "tf");
216         setter.setOptionValue("disable-target-preparers", "true");
217         setter.setOptionValue("include-filter", "tf/instrumentation");
218         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
219         assertEquals(1, configMap.size());
220         IConfiguration config = configMap.get(INSTRUMENTATION_TEST_NAME);
221         for (ITargetPreparer targetPreparer : config.getTargetPreparers()) {
222             assertTrue(targetPreparer.isDisabled());
223         }
224     }
225 
226     @Test
testdisableTargetPreparersUnset()227     public void testdisableTargetPreparersUnset() throws Exception {
228         OptionSetter setter = new OptionSetter(mSpyRunner);
229         setter.setOptionValue("suite-config-prefix", "tf");
230         setter.setOptionValue("include-filter", "tf/instrumentation");
231         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
232         assertEquals(1, configMap.size());
233         IConfiguration config = configMap.get(INSTRUMENTATION_TEST_NAME);
234         for (ITargetPreparer targetPreparer : config.getTargetPreparers()) {
235             assertTrue(!targetPreparer.isDisabled());
236         }
237     }
238 
239     @Test
testDisableTearDown()240     public void testDisableTearDown() throws Exception {
241         OptionSetter setter = new OptionSetter(mSpyRunner);
242         setter.setOptionValue("suite-config-prefix", "tf");
243         setter.setOptionValue("disable-teardown", "true");
244         setter.setOptionValue("include-filter", "tf/instrumentation");
245         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
246         IConfiguration config = configMap.get(INSTRUMENTATION_TEST_NAME);
247         for (ITargetPreparer targetPreparer : config.getTargetPreparers()) {
248             assertTrue(targetPreparer.isTearDownDisabled());
249         }
250     }
251 
252     @Test
testDisableTearDownUnset()253     public void testDisableTearDownUnset() throws Exception {
254         OptionSetter setter = new OptionSetter(mSpyRunner);
255         setter.setOptionValue("suite-config-prefix", "tf");
256         setter.setOptionValue("include-filter", "tf/instrumentation");
257         LinkedHashMap<String, IConfiguration> configMap = mSpyRunner.loadTests();
258         assertEquals(1, configMap.size());
259         IConfiguration config = configMap.get(INSTRUMENTATION_TEST_NAME);
260         for (ITargetPreparer targetPreparer : config.getTargetPreparers()) {
261             assertTrue(!targetPreparer.isTearDownDisabled());
262         }
263     }
264 
265     @Test
testCreateModuleListener()266     public void testCreateModuleListener() throws Exception {
267         OptionSetter setter = new OptionSetter(mSpyRunner);
268         setter.setOptionValue("subprocess-report-port", "55555");
269         List<ITestInvocationListener> listeners = mSpyRunner.createModuleListeners();
270         assertEquals(1, listeners.size());
271     }
272 
createModuleConfig(File dir, String moduleName)273     private String createModuleConfig(File dir, String moduleName) throws IOException {
274         File moduleConfig = new File(dir, moduleName + SuiteModuleLoader.CONFIG_EXT);
275         FileUtil.writeToFile(TEST_CONFIG, moduleConfig);
276         return moduleConfig.getAbsolutePath();
277     }
278 }
279