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