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