1 /*
2  * Copyright (C) 2010 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 
17 package com.android.tradefed.targetprep;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 import org.junit.runners.JUnit4;
27 
28 import com.android.tradefed.targetprep.FlashingResourcesParser.AndroidInfo;
29 import com.android.tradefed.targetprep.FlashingResourcesParser.Constraint;
30 import com.android.tradefed.util.FileUtil;
31 import com.android.tradefed.util.MultiMap;
32 
33 import java.io.BufferedReader;
34 import java.io.File;
35 import java.io.IOException;
36 import java.io.StringReader;
37 import java.util.Collection;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 
42 /** Unit tests for {@link FlashingResourcesParser}. */
43 @RunWith(JUnit4.class)
44 public class FlashingResourcesParserTest {
45 
46     private static class Under3Chars implements Constraint {
47         @Override
shouldAccept(String item)48         public boolean shouldAccept(String item) {
49             return item.length() < 3;
50         }
51     }
52 
53     /**
54      * Test that {@link FlashingResourcesParser#parseAndroidInfo(BufferedReader, Map)} parses valid
55      * data correctly.
56      */
57     @Test
testParseAndroidInfo()58     public void testParseAndroidInfo() throws IOException {
59         final String validInfoData = "require board=board1|board2\n" + // valid
60                 "require version-bootloader=1.0.1\n" + // valid
61                 "cylon=blah\n" + // valid
62                 "blah"; // not valid
63         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
64         AndroidInfo fullInfo = FlashingResourcesParser.parseAndroidInfo(reader, null);
65         MultiMap<String, String> result = fullInfo.get(null);
66 
67         assertEquals(3, result.size());
68         List<String> boards = result.get(FlashingResourcesParser.BOARD_KEY);
69         assertEquals(2, boards.size());
70         assertEquals("board1", boards.get(0));
71         assertEquals("board2", boards.get(1));
72         List<String> bootloaders = result.get(FlashingResourcesParser.BOOTLOADER_VERSION_KEY);
73         assertEquals("1.0.1", bootloaders.get(0));
74     }
75 
76     /**
77      * Test that {@link FlashingResourcesParser#parseAndroidInfo(BufferedReader, Map)} parses valid
78      * data correctly.
79      */
80     @Test
testParseAndroidInfo_withConstraint()81     public void testParseAndroidInfo_withConstraint() throws IOException {
82         final String validInfoData = "require board=board1|board2\n" +
83                 "require version-bootloader=1.0.1\n" +
84                 "require version-baseband=abcde|fg|hijkl|m\n";
85         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
86         Map<String, Constraint> constraintMap = new HashMap<String, Constraint>(1);
87         constraintMap.put(FlashingResourcesParser.BASEBAND_VERSION_KEY, new Under3Chars());
88 
89         AndroidInfo fullInfo = FlashingResourcesParser.parseAndroidInfo(reader, constraintMap);
90         MultiMap<String, String> result = fullInfo.get(null);
91 
92         assertEquals(3, result.size());
93         List<String> boards = result.get(FlashingResourcesParser.BOARD_KEY);
94         assertEquals(2, boards.size());
95         assertEquals("board1", boards.get(0));
96         assertEquals("board2", boards.get(1));
97         List<String> bootloaders = result.get(FlashingResourcesParser.BOOTLOADER_VERSION_KEY);
98         assertEquals("1.0.1", bootloaders.get(0));
99         List<String> radios = result.get(FlashingResourcesParser.BASEBAND_VERSION_KEY);
100         assertEquals(2, radios.size());
101         assertEquals("fg", radios.get(0));
102         assertEquals("m", radios.get(1));
103     }
104 
105     /**
106      * Test that {@link FlashingResourcesParser#parseAndroidInfo(BufferedReader, Map)} parses valid
107      * data correctly.
108      *
109      * <p>When both 'require board=foo' and 'require product=bar' lines are present, the board line
110      * should supercede the product line
111      */
112     @Test
testParseAndroidInfo_boardAndProduct()113     public void testParseAndroidInfo_boardAndProduct() throws Exception {
114         final String validInfoData = "require product=alpha|beta\n" +
115                 "require board=gamma|delta";
116         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
117 
118         IFlashingResourcesParser parser = new FlashingResourcesParser(reader);
119         Collection<String> reqBoards = parser.getRequiredBoards();
120         assertEquals(2, reqBoards.size());
121         assertTrue(reqBoards.contains("gamma"));
122         assertTrue(reqBoards.contains("delta"));
123     }
124 
125     /**
126      * Test that {@link FlashingResourcesParser#parseAndroidInfo(BufferedReader, Map)} parses valid
127      * data correctly.
128      */
129     @Test
testParseAndroidInfo_onlyBoard()130     public void testParseAndroidInfo_onlyBoard() throws Exception {
131         final String validInfoData = "require board=gamma|delta";
132         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
133 
134         IFlashingResourcesParser parser = new FlashingResourcesParser(reader);
135         Collection<String> reqBoards = parser.getRequiredBoards();
136         assertEquals(2, reqBoards.size());
137         assertTrue(reqBoards.contains("gamma"));
138         assertTrue(reqBoards.contains("delta"));
139     }
140 
141     /**
142      * Test that {@link FlashingResourcesParser#parseAndroidInfo(BufferedReader, Map)} parses valid
143      * data correctly.
144      *
145      * <p>When only 'require product=bar' line is present, it should be passed out in lieu of the
146      * (missing) board line.
147      */
148     @Test
testParseAndroidInfo_onlyProduct()149     public void testParseAndroidInfo_onlyProduct() throws Exception {
150         final String validInfoData = "require product=alpha|beta";
151         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
152 
153         IFlashingResourcesParser parser = new FlashingResourcesParser(reader);
154         Collection<String> reqBoards = parser.getRequiredBoards();
155         assertEquals(2, reqBoards.size());
156         assertTrue(reqBoards.contains("alpha"));
157         assertTrue(reqBoards.contains("beta"));
158     }
159 
160     /**
161      * Test that {@link FlashingResourcesParser#parseAndroidInfo(BufferedReader, Map)} parses valid
162      * data correctly.
163      *
164      * <p>In particular, this tests that the "require-for-product:(productName)" requirement is
165      * parsed properly and causes the expected internal state.
166      */
167     @Test
testRequireForProduct_internalState()168     public void testRequireForProduct_internalState() throws Exception {
169         final String validInfoData =
170                 "require product=alpha|beta|gamma\n" +
171                 "require version-bootloader=1234\n" +
172                 "require-for-product:gamma " +
173                     "version-bootloader=istanbul|constantinople\n";
174         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
175 
176         // Verify parsing for the first line
177         AndroidInfo fullInfo = FlashingResourcesParser.parseAndroidInfo(reader, null);
178         // 1 for global reqs, 1 for gamma-specific reqs
179         assertEquals(2, fullInfo.size());
180 
181         MultiMap<String, String> globalReqs = fullInfo.get(null);
182         assertEquals(2, globalReqs.size());
183         List<String> products = globalReqs.get(FlashingResourcesParser.PRODUCT_KEY);
184         assertEquals(3, products.size());
185         assertEquals("alpha", products.get(0));
186         assertEquals("beta", products.get(1));
187         assertEquals("gamma", products.get(2));
188         List<String> bootloaders = globalReqs.get(FlashingResourcesParser.BOOTLOADER_VERSION_KEY);
189         assertEquals("1234", bootloaders.get(0));
190 
191         MultiMap<String, String> gammaReqs = fullInfo.get("gamma");
192         assertNotNull(gammaReqs);
193         assertEquals(1, gammaReqs.size());
194         List<String> gammaBoot = gammaReqs.get("version-bootloader");
195         assertEquals(2, gammaBoot.size());
196         assertEquals("istanbul", gammaBoot.get(0));
197         assertEquals("constantinople", gammaBoot.get(1));
198     }
199 
200     /**
201      * Test that {@link FlashingResourcesParser#parseAndroidInfo(BufferedReader, Map)} parses valid
202      * data correctly.
203      *
204      * <p>In particular, this tests that the "require-for-product:(productName)" requirement is
205      * parsed properly and causes the expected internal state.
206      */
207     @Test
testRequireForProduct_api()208     public void testRequireForProduct_api() throws Exception {
209         final String validInfoData =
210                 "require product=alpha|beta|gamma\n" +
211                 "require version-bootloader=1234\n" +
212                 "require-for-product:gamma " +
213                     "version-bootloader=istanbul|constantinople\n";
214         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
215         IFlashingResourcesParser parser = new FlashingResourcesParser(reader);
216         assertEquals("1234", parser.getRequiredImageVersion("version-bootloader"));
217         assertEquals("1234", parser.getRequiredImageVersion("version-bootloader", null));
218         assertEquals("1234", parser.getRequiredImageVersion("version-bootloader", "alpha"));
219         assertEquals("istanbul", parser.getRequiredImageVersion("version-bootloader", "gamma"));
220     }
221 
222     /**
223      * Test {@link FlashingResourcesParser#getBuildRequirements(File, Map)} when passed a file that
224      * is not a zip.
225      */
226     @Test
testGetBuildRequirements_notAZip()227     public void testGetBuildRequirements_notAZip() throws IOException {
228         File badFile = FileUtil.createTempFile("foo", ".zip");
229         try {
230             new FlashingResourcesParser(badFile);
231             fail("TargetSetupError not thrown");
232         } catch (TargetSetupError e) {
233             // expected
234         } finally {
235             badFile.delete();
236         }
237     }
238 
239     /**
240      * Test {@link FlashingResourcesParser#getRequiredImageVersion(String, String)} to make sure the
241      * latest version is returned when multiple valid version exist.
242      */
243     @Test
testGetRequiredImageVersion()244     public void testGetRequiredImageVersion() throws Exception {
245         final String validInfoData =
246             "require product=alpha|beta|gamma\n" +
247             "require version-bootloader=1234|5678|3456\n" +
248             "require-for-product:beta " +
249                 "version-bootloader=ABCD|CDEF|EFGH\n" +
250             "require-for-product:gamma " +
251                 "version-bootloader=efgh|cdef|abcd\n";
252         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
253         IFlashingResourcesParser parser = new FlashingResourcesParser(reader);
254         assertEquals("5678", parser.getRequiredImageVersion("version-bootloader"));
255         assertEquals("5678", parser.getRequiredImageVersion("version-bootloader", null));
256         assertEquals("5678", parser.getRequiredImageVersion("version-bootloader", "alpha"));
257         assertEquals("EFGH", parser.getRequiredImageVersion("version-bootloader", "beta"));
258         assertEquals("efgh", parser.getRequiredImageVersion("version-bootloader", "gamma"));
259         assertNull(parser.getRequiredImageVersion("version-baseband"));
260     }
261 
262     /**
263      * Test {@link FlashingResourcesParser#getRequiredImageVersion(String, String)} to make sure it
264      * returns null when the AndroidInfo file is empty.
265      */
266     @Test
testGetRequiredImageVersion_emptyAndroidInfo()267     public void testGetRequiredImageVersion_emptyAndroidInfo() throws Exception {
268         final String validInfoData = "";
269         BufferedReader reader = new BufferedReader(new StringReader(validInfoData));
270         IFlashingResourcesParser parser = new FlashingResourcesParser(reader);
271         assertNull(parser.getRequiredImageVersion("version-bootloader"));
272         assertNull(parser.getRequiredImageVersion("version-bootloader", "alpha"));
273         assertNull(parser.getRequiredImageVersion("version-bootloader", null));
274         assertNull(parser.getRequiredImageVersion("version-baseband"));
275         assertNull(parser.getRequiredImageVersion("version-baseband", "alpha"));
276         assertNull(parser.getRequiredImageVersion("version-baseband", null));
277     }
278 }
279