blob: a14197b17529a1239750c544202200ca9043df76 [file] [log] [blame]
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +00001/*
2 * Copyright (C) 2019 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
17package com.android.server.integrity.parser;
18
19import static com.android.server.testutils.TestUtils.assertExpectException;
20
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +000021import static com.google.common.truth.Truth.assertThat;
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +000022
Song Pan75147d52019-11-19 00:57:46 +000023import android.content.integrity.AtomicFormula;
24import android.content.integrity.CompoundFormula;
25import android.content.integrity.Rule;
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +000026
27import org.junit.Test;
28import org.junit.runner.RunWith;
29import org.junit.runners.JUnit4;
30
31import java.io.ByteArrayInputStream;
32import java.io.InputStream;
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +000033import java.nio.charset.StandardCharsets;
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +000034import java.util.Arrays;
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +000035import java.util.Collections;
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +000036import java.util.HashMap;
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +000037import java.util.List;
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +000038import java.util.Map;
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +000039
40@RunWith(JUnit4.class)
41public class RuleXmlParserTest {
42
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +000043 @Test
Song Pan75147d52019-11-19 00:57:46 +000044 public void testXmlStream_validCompoundFormula() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +000045 Map<String, String> atomicFormulaAttrs = new HashMap<>();
46 atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +000047 atomicFormulaAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +000048 String ruleXmlCompoundFormula =
49 "<RL>"
50 + generateTagWithAttribute(
51 /* tag= */ "R",
52 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
53 /* closed= */ false)
54 + generateTagWithAttribute(
55 /* tag= */ "OF",
56 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
57 /* closed= */ false)
58 + generateTagWithAttribute(
59 /* tag= */ "AF", atomicFormulaAttrs, /* closed= */ true)
60 + "</OF>"
61 + "</R>"
62 + "</RL>";
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +000063 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +000064 InputStream inputStream = new ByteArrayInputStream(ruleXmlCompoundFormula.getBytes());
65 Rule expectedRule =
66 new Rule(
67 new CompoundFormula(
68 CompoundFormula.NOT,
69 Collections.singletonList(
70 new AtomicFormula.StringAtomicFormula(
71 AtomicFormula.PACKAGE_NAME,
72 "com.app.test",
73 /* isHashedValue= */ false))),
74 Rule.DENY);
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +000075
76 List<Rule> rules = xmlParser.parse(inputStream);
77
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +000078 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +000079 }
80
81 @Test
Song Pan75147d52019-11-19 00:57:46 +000082 public void testXmlString_validCompoundFormula_notConnector() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +000083 Map<String, String> packageNameAttrs = new HashMap<>();
84 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +000085 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +000086 String ruleXmlCompoundFormula =
87 "<RL>"
88 + generateTagWithAttribute(
89 /* tag= */ "R",
90 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
91 /* closed= */ false)
92 + generateTagWithAttribute(
93 /* tag= */ "OF",
94 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
95 /* closed= */ false)
96 + generateTagWithAttribute(
97 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
98 + "</OF>"
99 + "</R>"
100 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000101 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000102 Rule expectedRule =
103 new Rule(
104 new CompoundFormula(
105 CompoundFormula.NOT,
106 Collections.singletonList(
107 new AtomicFormula.StringAtomicFormula(
108 AtomicFormula.PACKAGE_NAME,
109 "com.app.test",
110 /* isHashedValue= */ false))),
111 Rule.DENY);
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000112
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000113 List<Rule> rules = xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000114
115 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
116 }
117
118 @Test
Song Pan75147d52019-11-19 00:57:46 +0000119 public void testXmlString_validCompoundFormula_andConnector() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000120 Map<String, String> packageNameAttrs = new HashMap<>();
121 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000122 packageNameAttrs.put("V", "com.app.test");
123 Map<String, String> appCertificateAttrs = new HashMap<>();
124 appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000125 appCertificateAttrs.put("V", "test_cert");
Song Pan75147d52019-11-19 00:57:46 +0000126 String ruleXmlCompoundFormula =
127 "<RL>"
128 + generateTagWithAttribute(
129 /* tag= */ "R",
130 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
131 /* closed= */ false)
132 + generateTagWithAttribute(
133 /* tag= */ "OF",
134 Collections.singletonMap("C", String.valueOf(CompoundFormula.AND)),
135 /* closed= */ false)
136 + generateTagWithAttribute(
137 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
138 + generateTagWithAttribute(
139 /* tag= */ "AF", appCertificateAttrs, /* closed= */ true)
140 + "</OF>"
141 + "</R>"
142 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000143 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000144 Rule expectedRule =
145 new Rule(
146 new CompoundFormula(
147 CompoundFormula.AND,
148 Arrays.asList(
149 new AtomicFormula.StringAtomicFormula(
150 AtomicFormula.PACKAGE_NAME,
151 "com.app.test",
152 /* isHashedValue= */ false),
153 new AtomicFormula.StringAtomicFormula(
154 AtomicFormula.APP_CERTIFICATE,
155 "test_cert",
156 /* isHashedValue= */ false))),
157 Rule.DENY);
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000158 List<Rule> rules = xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000159
160 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
161 }
162
163 @Test
Song Pan75147d52019-11-19 00:57:46 +0000164 public void testXmlString_validCompoundFormula_orConnector() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000165 Map<String, String> packageNameAttrs = new HashMap<>();
166 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000167 packageNameAttrs.put("V", "com.app.test");
168 Map<String, String> appCertificateAttrs = new HashMap<>();
169 appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000170 appCertificateAttrs.put("V", "test_cert");
Song Pan75147d52019-11-19 00:57:46 +0000171 String ruleXmlCompoundFormula =
172 "<RL>"
173 + generateTagWithAttribute(
174 /* tag= */ "R",
175 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
176 /* closed= */ false)
177 + generateTagWithAttribute(
178 /* tag= */ "OF",
179 Collections.singletonMap("C", String.valueOf(CompoundFormula.OR)),
180 /* closed= */ false)
181 + generateTagWithAttribute(
182 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
183 + generateTagWithAttribute(
184 /* tag= */ "AF", appCertificateAttrs, /* closed= */ true)
185 + "</OF>"
186 + "</R>"
187 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000188 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000189 Rule expectedRule =
190 new Rule(
191 new CompoundFormula(
192 CompoundFormula.OR,
193 Arrays.asList(
194 new AtomicFormula.StringAtomicFormula(
195 AtomicFormula.PACKAGE_NAME,
196 "com.app.test",
197 /* isHashedValue= */ false),
198 new AtomicFormula.StringAtomicFormula(
199 AtomicFormula.APP_CERTIFICATE,
200 "test_cert",
201 /* isHashedValue= */ false))),
202 Rule.DENY);
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000203
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000204 List<Rule> rules = xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000205
206 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
207 }
208
209 @Test
Song Pan75147d52019-11-19 00:57:46 +0000210 public void testXmlString_validCompoundFormula_differentTagOrder() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000211 Map<String, String> packageNameAttrs = new HashMap<>();
212 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
213 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000214 String ruleXmlCompoundFormula =
215 "<RL>"
216 + generateTagWithAttribute(
217 /* tag= */ "R",
218 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
219 /* closed= */ false)
220 + generateTagWithAttribute(
221 /* tag= */ "OF",
222 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
223 /* closed= */ false)
224 + generateTagWithAttribute(
225 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
226 + "</OF>"
227 + "</R>"
228 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000229 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000230 Rule expectedRule =
231 new Rule(
232 new CompoundFormula(
233 CompoundFormula.NOT,
234 Collections.singletonList(
235 new AtomicFormula.StringAtomicFormula(
236 AtomicFormula.PACKAGE_NAME,
237 "com.app.test",
238 /* isHashedValue= */ false))),
239 Rule.DENY);
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000240
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000241 List<Rule> rules = xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000242
243 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
244 }
245
246 @Test
Song Pan75147d52019-11-19 00:57:46 +0000247 public void testXmlString_invalidCompoundFormula_invalidNumberOfFormulas() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000248 Map<String, String> packageNameAttrs = new HashMap<>();
249 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000250 packageNameAttrs.put("V", "com.app.test");
251 Map<String, String> versionCodeAttrs = new HashMap<>();
252 versionCodeAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
253 versionCodeAttrs.put("O", String.valueOf(AtomicFormula.EQ));
254 versionCodeAttrs.put("V", "1");
Song Pan75147d52019-11-19 00:57:46 +0000255 String ruleXmlCompoundFormula =
256 "<RL>"
257 + generateTagWithAttribute(
258 /* tag= */ "R",
259 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
260 /* closed= */ false)
261 + generateTagWithAttribute(
262 /* tag= */ "OF",
263 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
264 /* closed= */ false)
265 + generateTagWithAttribute(
266 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
267 + generateTagWithAttribute(
268 /* tag= */ "AF", versionCodeAttrs, /* closed= */ true)
269 + "</OF>"
270 + "</R>"
271 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000272 RuleParser xmlParser = new RuleXmlParser();
273
274 assertExpectException(
275 RuleParseException.class,
276 /* expectedExceptionMessageRegex */ "Connector NOT must have 1 formula only",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000277 () -> xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000278 }
279
280 @Test
Song Pan75147d52019-11-19 00:57:46 +0000281 public void testXmlString_invalidCompoundFormula_invalidOperator() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000282 Map<String, String> packageNameAttrs = new HashMap<>();
283 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
284 packageNameAttrs.put("O", "INVALID_OPERATOR");
285 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000286 String ruleXmlCompoundFormula =
287 "<RL>"
288 + generateTagWithAttribute(
289 /* tag= */ "R",
290 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
291 /* closed= */ false)
292 + generateTagWithAttribute(
293 /* tag= */ "OF",
294 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
295 /* closed= */ false)
296 + generateTagWithAttribute(
297 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
298 + "</OF>"
299 + "</R>"
300 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000301 RuleParser xmlParser = new RuleXmlParser();
302
303 assertExpectException(
304 RuleParseException.class,
305 /* expectedExceptionMessageRegex */ "For input string: \"INVALID_OPERATOR\"",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000306 () -> xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000307 }
308
309 @Test
Song Pan75147d52019-11-19 00:57:46 +0000310 public void testXmlString_invalidCompoundFormula_invalidEffect() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000311 Map<String, String> packageNameAttrs = new HashMap<>();
312 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000313 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000314 String ruleXmlCompoundFormula =
315 "<RL>"
316 + generateTagWithAttribute(
317 /* tag= */ "R",
318 Collections.singletonMap("E", "INVALID_EFFECT"),
319 /* closed= */ false)
320 + generateTagWithAttribute(
321 /* tag= */ "OF",
322 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
323 /* closed= */ false)
324 + generateTagWithAttribute(
325 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
326 + "</OF>"
327 + "</R>"
328 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000329 RuleParser xmlParser = new RuleXmlParser();
330
331 assertExpectException(
332 RuleParseException.class,
333 /* expectedExceptionMessageRegex */ "For input string: \"INVALID_EFFECT\"",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000334 () -> xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000335 }
336
337 @Test
Song Pan75147d52019-11-19 00:57:46 +0000338 public void testXmlString_invalidCompoundFormula_invalidTags() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000339 Map<String, String> packageNameAttrs = new HashMap<>();
340 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000341 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000342 String ruleXmlCompoundFormula =
343 "<RL>"
344 + generateTagWithAttribute(
345 /* tag= */ "R",
346 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
347 /* closed= */ false)
348 + generateTagWithAttribute(
349 /* tag= */ "OF",
350 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
351 /* closed= */ false)
352 + generateTagWithAttribute(
353 /* tag= */ "InvalidAtomicFormula",
354 packageNameAttrs,
355 /* closed= */ true)
356 + "</OF>"
357 + "</R>"
358 + "</RL>";
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000359 RuleParser xmlParser = new RuleXmlParser();
360
361 assertExpectException(
362 RuleParseException.class,
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000363 /* expectedExceptionMessageRegex */ "Found unexpected tag: InvalidAtomicFormula",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000364 () -> xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000365 }
366
367 @Test
368 public void testXmlString_validAtomicFormula_stringValue() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000369 Map<String, String> packageNameAttrs = new HashMap<>();
370 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000371 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000372 String ruleXmlAtomicFormula =
373 "<RL>"
374 + generateTagWithAttribute(
375 /* tag= */ "R",
376 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
377 /* closed= */ false)
378 + generateTagWithAttribute(
379 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
380 + "</R>"
381 + "</RL>";
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000382 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000383 Rule expectedRule =
384 new Rule(
385 new AtomicFormula.StringAtomicFormula(
386 AtomicFormula.PACKAGE_NAME,
387 "com.app.test",
388 /* isHashedValue= */ false),
389 Rule.DENY);
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000390
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000391 List<Rule> rules = xmlParser.parse(ruleXmlAtomicFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000392
393 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
394 }
395
396 @Test
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000397 public void testXmlString_validAtomicFormula_integerValue() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000398 Map<String, String> versionCodeAttrs = new HashMap<>();
399 versionCodeAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
400 versionCodeAttrs.put("O", String.valueOf(AtomicFormula.EQ));
401 versionCodeAttrs.put("V", "1");
Song Pan75147d52019-11-19 00:57:46 +0000402 String ruleXmlAtomicFormula =
403 "<RL>"
404 + generateTagWithAttribute(
405 /* tag= */ "R",
406 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
407 /* closed= */ false)
408 + generateTagWithAttribute(
409 /* tag= */ "AF", versionCodeAttrs, /* closed= */ true)
410 + "</R>"
411 + "</RL>";
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000412 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000413 Rule expectedRule =
414 new Rule(
415 new AtomicFormula.IntAtomicFormula(
416 AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 1),
417 Rule.DENY);
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000418
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000419 List<Rule> rules = xmlParser.parse(ruleXmlAtomicFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000420
421 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
422 }
423
424 @Test
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000425 public void testXmlString_validAtomicFormula_booleanValue() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000426 Map<String, String> preInstalledAttrs = new HashMap<>();
427 preInstalledAttrs.put("K", String.valueOf(AtomicFormula.PRE_INSTALLED));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000428 preInstalledAttrs.put("V", "true");
Song Pan75147d52019-11-19 00:57:46 +0000429 String ruleXmlAtomicFormula =
430 "<RL>"
431 + generateTagWithAttribute(
432 /* tag= */ "R",
433 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
434 /* closed= */ false)
435 + generateTagWithAttribute(
436 /* tag= */ "AF", preInstalledAttrs, /* closed= */ true)
437 + "</R>"
438 + "</RL>";
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000439 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000440 Rule expectedRule =
441 new Rule(
442 new AtomicFormula.BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true),
443 Rule.DENY);
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000444
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000445 List<Rule> rules = xmlParser.parse(ruleXmlAtomicFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000446
447 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
448 }
449
450 @Test
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000451 public void testXmlString_validAtomicFormula_differentAttributeOrder() throws Exception {
452 Map<String, String> packageNameAttrs = new HashMap<>();
453 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
454 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000455 String ruleXmlAtomicFormula =
456 "<RL>"
457 + generateTagWithAttribute(
458 /* tag= */ "R",
459 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
460 /* closed= */ false)
461 + generateTagWithAttribute(
462 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
463 + "</R>"
464 + "</RL>";
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000465 RuleParser xmlParser = new RuleXmlParser();
Song Pan75147d52019-11-19 00:57:46 +0000466 Rule expectedRule =
467 new Rule(
468 new AtomicFormula.StringAtomicFormula(
469 AtomicFormula.PACKAGE_NAME,
470 "com.app.test",
471 /* isHashedValue= */ false),
472 Rule.DENY);
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000473
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000474 List<Rule> rules = xmlParser.parse(ruleXmlAtomicFormula.getBytes(StandardCharsets.UTF_8));
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000475
476 assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
477 }
478
479 @Test
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000480 public void testXmlString_invalidAtomicFormula_invalidAttribute() throws Exception {
481 Map<String, String> packageNameAttrs = new HashMap<>();
482 packageNameAttrs.put("BadKey", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000483 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000484 String ruleXmlAtomicFormula =
485 "<RL>"
486 + generateTagWithAttribute(
487 /* tag= */ "R",
488 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
489 /* closed= */ false)
490 + generateTagWithAttribute(
491 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
492 + "</R>"
493 + "</RL>";
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000494 RuleParser xmlParser = new RuleXmlParser();
495
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000496 assertExpectException(
497 RuleParseException.class,
Khaled Abdelmohsene39fa0f2019-11-25 17:24:22 +0000498 /* expectedExceptionMessageRegex */ "Found unexpected key: -1",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000499 () -> xmlParser.parse(ruleXmlAtomicFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000500 }
501
502 @Test
Khaled Abdelmohsene39fa0f2019-11-25 17:24:22 +0000503 public void testXmlString_invalidRule_invalidAttribute() throws Exception {
504 Map<String, String> packageNameAttrs = new HashMap<>();
505 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
506 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000507 String ruleXmlAtomicFormula =
508 "<RL>"
509 + generateTagWithAttribute(
510 /* tag= */ "R",
511 Collections.singletonMap("BadEffect", String.valueOf(Rule.DENY)),
512 /* closed= */ false)
513 + generateTagWithAttribute(
514 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
515 + "</R>"
516 + "</RL>";
Khaled Abdelmohsene39fa0f2019-11-25 17:24:22 +0000517 RuleParser xmlParser = new RuleXmlParser();
518 assertExpectException(
519 RuleParseException.class,
520 /* expectedExceptionMessageRegex */ "Unknown effect: -1",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000521 () -> xmlParser.parse(ruleXmlAtomicFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsene39fa0f2019-11-25 17:24:22 +0000522 }
523
524 @Test
Song Pan75147d52019-11-19 00:57:46 +0000525 public void testXmlString_invalidCompoundFormula_invalidAttribute() throws Exception {
Khaled Abdelmohsene39fa0f2019-11-25 17:24:22 +0000526 Map<String, String> packageNameAttrs = new HashMap<>();
527 packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
528 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000529 String ruleXmlCompoundFormula =
530 "<RL>"
531 + generateTagWithAttribute(
532 /* tag= */ "R",
533 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
534 /* closed= */ false)
535 + generateTagWithAttribute(
536 /* tag= */ "OF",
537 Collections.singletonMap(
538 "BadConnector", String.valueOf(CompoundFormula.NOT)),
539 /* closed= */ false)
540 + generateTagWithAttribute(
541 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
542 + "</OF>"
543 + "</R>"
544 + "</RL>";
Khaled Abdelmohsene39fa0f2019-11-25 17:24:22 +0000545 RuleParser xmlParser = new RuleXmlParser();
546 assertExpectException(
547 RuleParseException.class,
548 /* expectedExceptionMessageRegex */ "Unknown connector: -1",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000549 () -> xmlParser.parse(ruleXmlCompoundFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsene39fa0f2019-11-25 17:24:22 +0000550 }
551
552 @Test
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000553 public void testXmlString_invalidAtomicFormula() throws Exception {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000554 Map<String, String> packageNameAttrs = new HashMap<>();
555 packageNameAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
556 packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
557 packageNameAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000558 String ruleXmlAtomicFormula =
559 "<RL>"
560 + generateTagWithAttribute(
561 /* tag= */ "R",
562 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
563 /* closed= */ false)
564 + generateTagWithAttribute(
565 /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
566 + "</R>"
567 + "</RL>";
Khaled Abdelmohsen12b110e2019-11-05 17:24:48 +0000568 RuleParser xmlParser = new RuleXmlParser();
569
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000570 assertExpectException(
571 RuleParseException.class,
572 /* expectedExceptionMessageRegex */ "For input string: \"com.app.test\"",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000573 () -> xmlParser.parse(ruleXmlAtomicFormula.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +0000574 }
575
576 @Test
577 public void testXmlString_withNoRuleList() {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000578 Map<String, String> atomicFormulaAttrs = new HashMap<>();
579 atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000580 atomicFormulaAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000581 String ruleXmlWithNoRuleList =
582 generateTagWithAttribute(
583 /* tag= */ "R",
584 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
585 /* closed= */ false)
586 + generateTagWithAttribute(
587 /* tag= */ "OF",
588 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
589 /* closed= */ false)
590 + generateTagWithAttribute(
591 /* tag= */ "AF", atomicFormulaAttrs, /* closed= */ true)
592 + "</OF>"
593 + "</R>";
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +0000594 RuleParser xmlParser = new RuleXmlParser();
595
596 assertExpectException(
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000597 RuleParseException.class,
Khaled Abdelmohsen6d77f942019-11-12 16:47:01 +0000598 /* expectedExceptionMessageRegex */ "Rules must start with RuleList <RL> tag",
Khaled Abdelmohsen6ecfebc2019-12-03 15:00:49 +0000599 () -> xmlParser.parse(ruleXmlWithNoRuleList.getBytes(StandardCharsets.UTF_8)));
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +0000600 }
601
602 @Test
603 public void testXmlStream_withNoRuleList() {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000604 Map<String, String> atomicFormulaAttrs = new HashMap<>();
605 atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000606 atomicFormulaAttrs.put("V", "com.app.test");
Song Pan75147d52019-11-19 00:57:46 +0000607 String ruleXmlWithNoRuleList =
608 generateTagWithAttribute(
609 /* tag= */ "R",
610 Collections.singletonMap("E", String.valueOf(Rule.DENY)),
611 /* closed= */ false)
612 + generateTagWithAttribute(
613 /* tag= */ "OF",
614 Collections.singletonMap("C", String.valueOf(CompoundFormula.NOT)),
615 /* closed= */ false)
616 + generateTagWithAttribute(
617 /* tag= */ "AF", atomicFormulaAttrs, /* closed= */ true)
618 + "</OF>"
619 + "</R>";
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +0000620 InputStream inputStream = new ByteArrayInputStream(ruleXmlWithNoRuleList.getBytes());
621 RuleParser xmlParser = new RuleXmlParser();
622
623 assertExpectException(
Khaled Abdelmohsen21a96052019-11-06 12:23:22 +0000624 RuleParseException.class,
Khaled Abdelmohsen6d77f942019-11-12 16:47:01 +0000625 /* expectedExceptionMessageRegex */ "Rules must start with RuleList <RL> tag",
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +0000626 () -> xmlParser.parse(inputStream));
627 }
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000628
Song Pan75147d52019-11-19 00:57:46 +0000629 private String generateTagWithAttribute(
630 String tag, Map<String, String> attributeValues, boolean closed) {
Khaled Abdelmohsenb05d7062019-11-19 01:22:23 +0000631 StringBuilder res = new StringBuilder("<");
632 res.append(tag);
633 for (String attribute : attributeValues.keySet()) {
634 res.append(" ");
635 res.append(attribute);
636 res.append("=\"");
637 res.append(attributeValues.get(attribute));
638 res.append("\"");
639 }
640 res.append(closed ? " />" : ">");
641 return res.toString();
642 }
Khaled Abdelmohsen216109e2019-11-04 17:49:18 +0000643}