• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.server.signedconfig;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.fail;
22 
23 import static java.util.Collections.emptyMap;
24 import static java.util.Collections.emptySet;
25 
26 import android.util.ArrayMap;
27 
28 import androidx.test.runner.AndroidJUnit4;
29 
30 import com.google.common.collect.Sets;
31 
32 import org.json.JSONException;
33 import org.json.JSONObject;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 
37 import java.util.Arrays;
38 import java.util.Collections;
39 import java.util.Map;
40 import java.util.Set;
41 
42 
43 /**
44  * Tests for {@link SignedConfig}
45  */
46 @RunWith(AndroidJUnit4.class)
47 public class SignedConfigTest {
48 
setOf(String... values)49     private static Set<String> setOf(String... values) {
50         return Sets.newHashSet(values);
51     }
52 
mapOf(Object... keyValuePairs)53     private static <K, V> Map<K, V> mapOf(Object... keyValuePairs) {
54         if (keyValuePairs.length % 2 != 0) {
55             throw new IllegalArgumentException();
56         }
57         final int len = keyValuePairs.length / 2;
58         ArrayMap<K, V> m = new ArrayMap<>(len);
59         for (int i = 0; i < len;  ++i) {
60             m.put((K) keyValuePairs[i * 2], (V) keyValuePairs[(i * 2) + 1]);
61         }
62         return Collections.unmodifiableMap(m);
63 
64     }
65 
66 
67     @Test
testParsePerSdkConfigSdkMinMax()68     public void testParsePerSdkConfigSdkMinMax() throws JSONException, InvalidConfigException {
69         JSONObject json = new JSONObject("{\"min_sdk\":2, \"max_sdk\": 3, \"values\": {}}");
70         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, emptySet(),
71                 emptyMap());
72         assertThat(config.minSdk).isEqualTo(2);
73         assertThat(config.maxSdk).isEqualTo(3);
74     }
75 
76     @Test
testParsePerSdkConfigNoMinSdk()77     public void testParsePerSdkConfigNoMinSdk() throws JSONException {
78         JSONObject json = new JSONObject("{\"max_sdk\": 3, \"values\": {}}");
79         try {
80             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
81             fail("Expected InvalidConfigException or JSONException");
82         } catch (JSONException | InvalidConfigException e) {
83             // expected
84         }
85     }
86 
87     @Test
testParsePerSdkConfigNoMaxSdk()88     public void testParsePerSdkConfigNoMaxSdk() throws JSONException {
89         JSONObject json = new JSONObject("{\"min_sdk\": 1, \"values\": {}}");
90         try {
91             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
92             fail("Expected InvalidConfigException or JSONException");
93         } catch (JSONException | InvalidConfigException e) {
94             // expected
95         }
96     }
97 
98     @Test
testParsePerSdkConfigNoValues()99     public void testParsePerSdkConfigNoValues() throws JSONException {
100         JSONObject json = new JSONObject("{\"min_sdk\": 1, \"max_sdk\": 3}");
101         try {
102             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
103             fail("Expected InvalidConfigException or JSONException");
104         } catch (JSONException | InvalidConfigException e) {
105             // expected
106         }
107     }
108 
109     @Test
testParsePerSdkConfigSdkNullMinSdk()110     public void testParsePerSdkConfigSdkNullMinSdk() throws JSONException {
111         JSONObject json = new JSONObject("{\"min_sdk\":null, \"max_sdk\": 3, \"values\": {}}");
112         try {
113             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
114             fail("Expected InvalidConfigException or JSONException");
115         } catch (JSONException | InvalidConfigException e) {
116             // expected
117         }
118     }
119 
120     @Test
testParsePerSdkConfigSdkNullMaxSdk()121     public void testParsePerSdkConfigSdkNullMaxSdk() throws JSONException {
122         JSONObject json = new JSONObject("{\"min_sdk\":1, \"max_sdk\": null, \"values\": {}}");
123         try {
124             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
125             fail("Expected InvalidConfigException or JSONException");
126         } catch (JSONException | InvalidConfigException e) {
127             // expected
128         }
129     }
130 
131     @Test
testParsePerSdkConfigNullValues()132     public void testParsePerSdkConfigNullValues() throws JSONException {
133         JSONObject json = new JSONObject("{\"min_sdk\": 1, \"max_sdk\": 3, \"values\": null}");
134         try {
135             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
136             fail("Expected InvalidConfigException or JSONException");
137         } catch (JSONException | InvalidConfigException e) {
138             // expected
139         }
140     }
141 
142     @Test
testParsePerSdkConfigZeroValues()143     public void testParsePerSdkConfigZeroValues()
144             throws JSONException, InvalidConfigException {
145         JSONObject json = new JSONObject("{\"min_sdk\": 1, \"max_sdk\": 3, \"values\": {}}");
146         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
147                 emptyMap());
148         assertThat(config.values).hasSize(0);
149     }
150 
151     @Test
testParsePerSdkConfigSingleKey()152     public void testParsePerSdkConfigSingleKey()
153             throws JSONException, InvalidConfigException {
154         JSONObject json = new JSONObject(
155                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": \"1\"}}");
156         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
157                 emptyMap());
158         assertThat(config.values).containsExactly("a", "1");
159     }
160 
161     @Test
testParsePerSdkConfigSingleKeyNullValue()162     public void testParsePerSdkConfigSingleKeyNullValue()
163             throws JSONException, InvalidConfigException {
164         JSONObject json = new JSONObject(
165                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": null}}");
166         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
167                 emptyMap());
168         assertThat(config.values.keySet()).containsExactly("a");
169         assertThat(config.values.get("a")).isNull();
170     }
171 
172     @Test
testParsePerSdkConfigMultiKeys()173     public void testParsePerSdkConfigMultiKeys()
174             throws JSONException, InvalidConfigException {
175         JSONObject json = new JSONObject(
176                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": \"1\", \"c\": \"2\"}}");
177         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(
178                 json, setOf("a", "b", "c"), emptyMap());
179         assertThat(config.values).containsExactly("a", "1", "c", "2");
180     }
181 
182     @Test
testParsePerSdkConfigSingleKeyNotAllowed()183     public void testParsePerSdkConfigSingleKeyNotAllowed() throws JSONException {
184         JSONObject json = new JSONObject(
185                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": \"1\"}}");
186         try {
187             SignedConfig.parsePerSdkConfig(json, setOf("b"), emptyMap());
188             fail("Expected InvalidConfigException or JSONException");
189         } catch (JSONException | InvalidConfigException e) {
190             // expected
191         }
192     }
193 
194     @Test
testParsePerSdkConfigSingleKeyWithMap()195     public void testParsePerSdkConfigSingleKeyWithMap()
196             throws JSONException, InvalidConfigException {
197         JSONObject json = new JSONObject(
198                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": \"1\"}}");
199         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a"),
200                 mapOf("a", mapOf("1", "one")));
201         assertThat(config.values).containsExactly("a", "one");
202     }
203 
204     @Test
testParsePerSdkConfigSingleKeyWithMapInvalidValue()205     public void testParsePerSdkConfigSingleKeyWithMapInvalidValue() throws JSONException {
206         JSONObject json = new JSONObject(
207                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": \"2\"}}");
208         try {
209             SignedConfig.parsePerSdkConfig(json, setOf("b"), mapOf("a", mapOf("1", "one")));
210             fail("Expected InvalidConfigException");
211         } catch (InvalidConfigException e) {
212             // expected
213         }
214     }
215 
216     @Test
testParsePerSdkConfigMultiKeysWithMap()217     public void testParsePerSdkConfigMultiKeysWithMap()
218             throws JSONException, InvalidConfigException {
219         JSONObject json = new JSONObject(
220                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": \"1\", \"b\": \"1\"}}");
221         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
222                 mapOf("a", mapOf("1", "one")));
223         assertThat(config.values).containsExactly("a", "one", "b", "1");
224     }
225 
226     @Test
testParsePerSdkConfigSingleKeyWithMapToNull()227     public void testParsePerSdkConfigSingleKeyWithMapToNull()
228             throws JSONException, InvalidConfigException {
229         JSONObject json = new JSONObject(
230                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": \"1\"}}");
231         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a"),
232                 mapOf("a", mapOf("1", null)));
233         assertThat(config.values).containsExactly("a", null);
234     }
235 
236     @Test
testParsePerSdkConfigSingleKeyWithMapFromNull()237     public void testParsePerSdkConfigSingleKeyWithMapFromNull()
238             throws JSONException, InvalidConfigException {
239         assertThat(mapOf(null, "allitnil")).containsExactly(null, "allitnil");
240         assertThat(mapOf(null, "allitnil").containsKey(null)).isTrue();
241         JSONObject json = new JSONObject(
242                 "{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {\"a\": null}}");
243         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a"),
244                 mapOf("a", mapOf(null, "allitnil")));
245         assertThat(config.values).containsExactly("a", "allitnil");
246     }
247 
248     @Test
testParsePerSdkConfigValuesInvalid()249     public void testParsePerSdkConfigValuesInvalid() throws JSONException  {
250         JSONObject json = new JSONObject("{\"min_sdk\": 1, \"max_sdk\": 1,  \"values\": \"foo\"}");
251         try {
252             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
253             fail("Expected InvalidConfigException or JSONException");
254         } catch (JSONException | InvalidConfigException e) {
255             // expected
256         }
257     }
258 
259     @Test
testParsePerSdkConfigConfigEntryInvalid()260     public void testParsePerSdkConfigConfigEntryInvalid() throws JSONException {
261         JSONObject json = new JSONObject("{\"min_sdk\": 1, \"max_sdk\": 1,  \"values\": [1, 2]}");
262         try {
263             SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
264             fail("Expected InvalidConfigException or JSONException");
265         } catch (JSONException | InvalidConfigException e) {
266             // expected
267         }
268     }
269 
270     @Test
testParseVersion()271     public void testParseVersion() throws InvalidConfigException {
272         SignedConfig config = SignedConfig.parse(
273                 "{\"version\": 1, \"config\": []}", emptySet(), emptyMap());
274         assertThat(config.version).isEqualTo(1);
275     }
276 
277     @Test
testParseVersionInvalid()278     public void testParseVersionInvalid() {
279         try {
280             SignedConfig.parse("{\"version\": \"notanint\", \"config\": []}", emptySet(),
281                     emptyMap());
282             fail("Expected InvalidConfigException");
283         } catch (InvalidConfigException e) {
284             //expected
285         }
286     }
287 
288     @Test
testParseNoVersion()289     public void testParseNoVersion() {
290         try {
291             SignedConfig.parse("{\"config\": []}", emptySet(), emptyMap());
292             fail("Expected InvalidConfigException");
293         } catch (InvalidConfigException e) {
294             //expected
295         }
296     }
297 
298     @Test
testParseNoConfig()299     public void testParseNoConfig() {
300         try {
301             SignedConfig.parse("{\"version\": 1}", emptySet(), emptyMap());
302             fail("Expected InvalidConfigException");
303         } catch (InvalidConfigException e) {
304             //expected
305         }
306     }
307 
308     @Test
testParseConfigNull()309     public void testParseConfigNull() {
310         try {
311             SignedConfig.parse("{\"version\": 1, \"config\": null}", emptySet(), emptyMap());
312             fail("Expected InvalidConfigException");
313         } catch (InvalidConfigException e) {
314             //expected
315         }
316     }
317 
318     @Test
testParseVersionNull()319     public void testParseVersionNull() {
320         try {
321             SignedConfig.parse("{\"version\": null, \"config\": []}", emptySet(), emptyMap());
322             fail("Expected InvalidConfigException");
323         } catch (InvalidConfigException e) {
324             //expected
325         }
326     }
327 
328     @Test
testParseConfigInvalidEntry()329     public void testParseConfigInvalidEntry() {
330         try {
331             SignedConfig.parse("{\"version\": 1, \"config\": [{}]}", emptySet(), emptyMap());
332             fail("Expected InvalidConfigException");
333         } catch (InvalidConfigException e) {
334             //expected
335         }
336     }
337 
338     @Test
testParseSdkConfigSingle()339     public void testParseSdkConfigSingle() throws InvalidConfigException {
340         SignedConfig config = SignedConfig.parse(
341                 "{\"version\": 1, \"config\":[{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {}}]}",
342                 emptySet(), emptyMap());
343         assertThat(config.perSdkConfig).hasSize(1);
344     }
345 
346     @Test
testParseSdkConfigMultiple()347     public void testParseSdkConfigMultiple() throws InvalidConfigException {
348         SignedConfig config = SignedConfig.parse(
349                 "{\"version\": 1, \"config\":[{\"min_sdk\": 1, \"max_sdk\": 1, \"values\": {}}, "
350                         + "{\"min_sdk\": 2, \"max_sdk\": 2, \"values\": {}}]}", emptySet(),
351                 emptyMap());
352         assertThat(config.perSdkConfig).hasSize(2);
353     }
354 
355     @Test
testGetMatchingConfigFirst()356     public void testGetMatchingConfigFirst() {
357         SignedConfig.PerSdkConfig sdk1 = new SignedConfig.PerSdkConfig(
358                 1, 1, Collections.emptyMap());
359         SignedConfig.PerSdkConfig sdk2 = new SignedConfig.PerSdkConfig(
360                 2, 2, Collections.emptyMap());
361         SignedConfig config = new SignedConfig(0, Arrays.asList(sdk1, sdk2));
362         assertThat(config.getMatchingConfig(1)).isEqualTo(sdk1);
363     }
364 
365     @Test
testGetMatchingConfigSecond()366     public void testGetMatchingConfigSecond() {
367         SignedConfig.PerSdkConfig sdk1 = new SignedConfig.PerSdkConfig(
368                 1, 1, Collections.emptyMap());
369         SignedConfig.PerSdkConfig sdk2 = new SignedConfig.PerSdkConfig(
370                 2, 2, Collections.emptyMap());
371         SignedConfig config = new SignedConfig(0, Arrays.asList(sdk1, sdk2));
372         assertThat(config.getMatchingConfig(2)).isEqualTo(sdk2);
373     }
374 
375     @Test
testGetMatchingConfigInRange()376     public void testGetMatchingConfigInRange() {
377         SignedConfig.PerSdkConfig sdk13 = new SignedConfig.PerSdkConfig(
378                 1, 3, Collections.emptyMap());
379         SignedConfig.PerSdkConfig sdk46 = new SignedConfig.PerSdkConfig(
380                 4, 6, Collections.emptyMap());
381         SignedConfig config = new SignedConfig(0, Arrays.asList(sdk13, sdk46));
382         assertThat(config.getMatchingConfig(2)).isEqualTo(sdk13);
383     }
384     @Test
testGetMatchingConfigNoMatch()385     public void testGetMatchingConfigNoMatch() {
386         SignedConfig.PerSdkConfig sdk1 = new SignedConfig.PerSdkConfig(
387                 1, 1, Collections.emptyMap());
388         SignedConfig.PerSdkConfig sdk2 = new SignedConfig.PerSdkConfig(
389                 2, 2, Collections.emptyMap());
390         SignedConfig config = new SignedConfig(0, Arrays.asList(sdk1, sdk2));
391         assertThat(config.getMatchingConfig(3)).isNull();
392     }
393 
394 }
395