• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.compatibility.common.tradefed.targetprep;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
27 import com.android.tradefed.build.IBuildInfo;
28 import com.android.tradefed.build.VersionedFile;
29 import com.android.tradefed.config.ConfigurationDescriptor;
30 import com.android.tradefed.config.OptionSetter;
31 import com.android.tradefed.device.ITestDevice;
32 import com.android.tradefed.invoker.IInvocationContext;
33 import com.android.tradefed.invoker.InvocationContext;
34 import com.android.tradefed.invoker.TestInformation;
35 import com.android.tradefed.targetprep.TargetSetupError;
36 import com.android.tradefed.util.FileUtil;
37 
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.junit.runners.JUnit4;
42 import org.mockito.ArgumentCaptor;
43 import org.mockito.Mockito;
44 
45 import java.io.File;
46 import java.io.FileNotFoundException;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collection;
50 import java.util.HashMap;
51 import java.util.Map;
52 
53 /**
54  * Unit tests for {@link DynamicConfigPusher}.
55  */
56 @RunWith(JUnit4.class)
57 public class DynamicConfigPusherTest {
58     private static final String RESOURCE_DYNAMIC_CONFIG = "test-dynamic-config";
59     private static final String RUN_TESTS_AS_USER_KEY = "RUN_TESTS_AS_USER";
60     private DynamicConfigPusher mPreparer;
61     private ITestDevice mMockDevice;
62     private CompatibilityBuildHelper mMockBuildHelper;
63     private IBuildInfo mMockBuildInfo;
64     private IInvocationContext mModuleContext;
65     private TestInformation mTestInfo;
66 
67     @Before
setUp()68     public void setUp() {
69         mModuleContext = new InvocationContext();
70         mModuleContext.setConfigurationDescriptor(new ConfigurationDescriptor());
71         mPreparer = new DynamicConfigPusher();
72         mMockDevice = Mockito.mock(ITestDevice.class);
73         mMockBuildInfo = Mockito.mock(IBuildInfo.class);
74         mMockBuildHelper = new CompatibilityBuildHelper(mMockBuildInfo);
75         when(mMockDevice.getDeviceDescriptor()).thenReturn(null);
76         mModuleContext.addDeviceBuildInfo("device", mMockBuildInfo);
77         mModuleContext.addAllocatedDevice("device", mMockDevice);
78         mTestInfo = TestInformation.newBuilder().setInvocationContext(mModuleContext).build();
79     }
80 
81     /**
82      * Test getSuiteName from /test-suite-info.properties.
83      */
84     @Test
testGetSuiteName_fromTestSuiteInfo()85     public void testGetSuiteName_fromTestSuiteInfo() throws Exception {
86         mPreparer = new DynamicConfigPusher();
87         mPreparer.setInvocationContext(mModuleContext);
88 
89         assertNotNull(mPreparer.getSuiteName());
90     }
91 
92     /**
93      * Test getSuiteName from test-suite-tag.
94      */
95     @Test
testGetSuiteName_fromTestSuiteTag()96     public void testGetSuiteName_fromTestSuiteTag() throws Exception {
97         mPreparer = new DynamicConfigPusher();
98         mModuleContext
99                 .getConfigurationDescriptor()
100                 .setSuiteTags(Arrays.asList("cts", "cts-instant", "gts"));
101         mPreparer.setInvocationContext(mModuleContext);
102 
103         assertNotNull(mPreparer.getSuiteName());
104     }
105 
106     /**
107      * Test that when we look up resources locally, we search them from the build helper.
108      */
109     @Test
testLocalRead_fromDynamicConfigName()110     public void testLocalRead_fromDynamicConfigName() throws Exception {
111         OptionSetter setter = new OptionSetter(mPreparer);
112         setter.setOptionValue("config-filename", "config-test-name");
113         setter.setOptionValue("dynamic-config-name", "dynamic-config-test-name");
114         setter.setOptionValue("extract-from-resource", "false");
115 
116         File check = new File("anyfilewilldo");
117         mMockBuildHelper = new CompatibilityBuildHelper(mMockBuildInfo) {
118             @Override
119             public File getTestFile(String filename) throws FileNotFoundException {
120                 return check;
121             }
122         };
123 
124         File res = mPreparer.getLocalConfigFile(mMockBuildHelper, mMockDevice);
125         assertEquals(check, res);
126     }
127 
128     /**
129      * Test that when we look up resources locally, we search them from the build helper.
130      */
131     @Test
testLocalRead()132     public void testLocalRead() throws Exception {
133         OptionSetter setter = new OptionSetter(mPreparer);
134         setter.setOptionValue("config-filename", "config-test-name");
135         setter.setOptionValue("extract-from-resource", "false");
136 
137         File check = new File("anyfilewilldo");
138         mMockBuildHelper = new CompatibilityBuildHelper(mMockBuildInfo) {
139             @Override
140             public File getTestFile(String filename) throws FileNotFoundException {
141                 return check;
142             }
143         };
144 
145         File res = mPreparer.getLocalConfigFile(mMockBuildHelper, mMockDevice);
146         assertEquals(check, res);
147     }
148 
149     /**
150      * Test that when we look up resources locally, we search them from the build helper and throw
151      * if it's not found.
152      */
153     @Test
testLocalRead_fileNotFound()154     public void testLocalRead_fileNotFound() throws Exception {
155         OptionSetter setter = new OptionSetter(mPreparer);
156         setter.setOptionValue("config-filename", "config-test-name");
157         setter.setOptionValue("extract-from-resource", "false");
158 
159         mMockBuildHelper = new CompatibilityBuildHelper(mMockBuildInfo) {
160             @Override
161             public File getTestFile(String filename) throws FileNotFoundException {
162                 throw new FileNotFoundException("test");
163             }
164         };
165         try {
166             mPreparer.getLocalConfigFile(mMockBuildHelper, mMockDevice);
167             fail("Should have thrown an exception.");
168         } catch (TargetSetupError expected) {
169             // expected
170             assertEquals(
171                     "Cannot get local dynamic config file from test directory",
172                     expected.getMessage());
173         }
174     }
175 
176     /**
177      * Test when we try to unpack a resource but it does not exists.
178      */
179     @Test
testResourceRead_notFound()180     public void testResourceRead_notFound() throws Exception {
181         OptionSetter setter = new OptionSetter(mPreparer);
182         setter.setOptionValue("config-filename", "not-an-existing-resource-name");
183         setter.setOptionValue("extract-from-resource", "true");
184         try {
185             mPreparer.getLocalConfigFile(mMockBuildHelper, mMockDevice);
186             fail("Should have thrown an exception.");
187         } catch (TargetSetupError expected) {
188             // expected
189             assertEquals(
190                     "Fail to unpack 'not-an-existing-resource-name.dynamic' from resources",
191                     expected.getMessage());
192         }
193     }
194 
195     /**
196      * Test when we get a config from the resources.
197      */
198     @Test
testResourceRead()199     public void testResourceRead() throws Exception {
200         OptionSetter setter = new OptionSetter(mPreparer);
201         setter.setOptionValue("config-filename", RESOURCE_DYNAMIC_CONFIG);
202         setter.setOptionValue("extract-from-resource", "true");
203         File res = null;
204         try {
205             res = mPreparer.getLocalConfigFile(mMockBuildHelper, mMockDevice);
206             assertTrue(res.exists());
207             assertTrue(FileUtil.readStringFromFile(res).contains("<dynamicConfig>"));
208         } finally {
209             FileUtil.deleteFile(res);
210         }
211     }
212 
213     /**
214      * Test when we get a config from the resources under the alternative name.
215      */
216     @Test
testResourceRead_resourceFileName()217     public void testResourceRead_resourceFileName() throws Exception {
218         OptionSetter setter = new OptionSetter(mPreparer);
219         setter.setOptionValue("config-filename", "moduleName");
220         setter.setOptionValue("extract-from-resource", "true");
221         // Look up the file under that name instead of the config-filename
222         setter.setOptionValue("dynamic-resource-name", RESOURCE_DYNAMIC_CONFIG);
223         File res = null;
224         try {
225             res = mPreparer.getLocalConfigFile(mMockBuildHelper, mMockDevice);
226             assertTrue(res.exists());
227             assertTrue(FileUtil.readStringFromFile(res).contains("<dynamicConfig>"));
228         } finally {
229             FileUtil.deleteFile(res);
230         }
231     }
232 
233     @Test
testSetUp_usesRunTestsAsUserFromProperty()234     public void testSetUp_usesRunTestsAsUserFromProperty() throws Exception {
235         final File[] localConfig = new File[1];
236         OptionSetter setter = prepareSetupTestTarget(localConfig);
237         // Set target to DEVICE.
238         setter.setOptionValue("target", "device");
239 
240         int runTestsAsUserId = 101;
241         mTestInfo.properties().put(RUN_TESTS_AS_USER_KEY, String.valueOf(runTestsAsUserId));
242         when(mMockDevice.pushFile(Mockito.any(), Mockito.any(), Mockito.anyInt())).thenReturn(true);
243 
244         mPreparer.setUp(mTestInfo);
245 
246         verify(mMockDevice, Mockito.never()).getCurrentUser();
247         // pushFile() is called for the RUN_TESTS_AS_USER set in the TestInfo property.
248         verify(mMockDevice).pushFile(Mockito.any(), Mockito.any(), Mockito.eq(runTestsAsUserId));
249     }
250 
251     @Test
testSetUp_currentUser()252     public void testSetUp_currentUser() throws Exception {
253         final File[] localConfig = new File[1];
254         OptionSetter setter = prepareSetupTestTarget(localConfig);
255         // Set target to DEVICE.
256         setter.setOptionValue("target", "device");
257 
258         int currentUserId = 100;
259         when(mMockDevice.getCurrentUser()).thenReturn(currentUserId);
260         when(mMockDevice.pushFile(Mockito.any(), Mockito.any(), Mockito.anyInt())).thenReturn(true);
261 
262         mPreparer.setUp(mTestInfo);
263 
264         // pushFile() is called for the current user.
265         verify(mMockDevice).pushFile(Mockito.any(), Mockito.any(), Mockito.eq(currentUserId));
266     }
267 
268     /**
269      * Test an end-to-end usage of the dynamic config file from the jar.
270      */
271     @Test
testSetUp()272     public void testSetUp() throws Exception {
273         final File[] localConfig = new File[1];
274         prepareSetupTestTarget(localConfig);
275 
276         Map<String, String> attributes = new HashMap<>();
277         attributes.put(CompatibilityBuildHelper.SUITE_VERSION, "v1");
278         when(mMockBuildInfo.getBuildAttributes()).thenReturn(attributes);
279         Collection<VersionedFile> versionedFiles = new ArrayList<VersionedFile>();
280         when(mMockBuildInfo.getFiles()).thenReturn(versionedFiles);
281         mPreparer.setInvocationContext(mModuleContext);
282 
283         mPreparer.setUp(mTestInfo);
284         ArgumentCaptor<File> capture = ArgumentCaptor.forClass(File.class);
285         verify(mMockBuildInfo)
286                 .setFile(
287                         Mockito.contains("moduleName"),
288                         capture.capture(),
289                         Mockito.eq("DYNAMIC_CONFIG_FILE:moduleName"));
290         assertNotNull(localConfig[0]);
291         // Ensure that the extracted file was deleted.
292         assertFalse(localConfig[0].exists());
293         File dynamicFile = capture.getValue();
294         assertTrue(dynamicFile.exists());
295         FileUtil.deleteFile(dynamicFile);
296     }
297 
298     /**
299      * Prepares for running tests for DynamicConfigPusher#setUp method.
300      *
301      * @return an {@link OptionSetter} so that each test can override option valuses as necessary.
302      */
prepareSetupTestTarget(File[] localConfig)303     private OptionSetter prepareSetupTestTarget(File[] localConfig) throws Exception {
304         mPreparer =
305                 new DynamicConfigPusher() {
306                     @Override
307                     File mergeConfigFiles(
308                             File localConfigFile,
309                             String apfeConfigInJson,
310                             String moduleName,
311                             ITestDevice device)
312                             throws TargetSetupError {
313                         localConfig[0] = localConfigFile;
314                         return super.mergeConfigFiles(
315                                 localConfigFile, apfeConfigInJson, moduleName, device);
316                     }
317                 };
318         OptionSetter setter = new OptionSetter(mPreparer);
319         setter.setOptionValue("has-server-side-config", "false");
320         setter.setOptionValue("config-filename", "moduleName");
321         setter.setOptionValue("extract-from-resource", "true");
322         // Look up the file under that name instead of the config-filename
323         setter.setOptionValue("dynamic-resource-name", RESOURCE_DYNAMIC_CONFIG);
324 
325         return setter;
326     }
327 }
328