1#!/bin/sh
2""":" # Shell script (in docstring to appease pylint)
3# Find and invoke hermetic python3 interpreter
4. "`dirname $0`/../../../vendor/google/aosp/scripts/envsetup.sh"
5exec "$PY3" "$0" "$@"
6# Shell script end
7
8Command to run tests:
9  python3 -m unittest -v test_manifest_compiler
10"""
11
12import unittest
13
14import manifest_compiler
15
16TEST_UUID = "SAMPLE_UUID"
17TEST_PORT = "SAMPLE_PORT"
18TEST_SIZE = "SAMPLE_SIZE"
19
20class TestManifest(unittest.TestCase):
21    """Test with integer value as input to get_string"""
22
23    def test_get_string_1(self):
24        constants = {}
25        log = manifest_compiler.Log()
26        config_data = {"data": 1234}
27        data = manifest_compiler.get_string(config_data, "data", constants, log)
28        self.assertEqual(len(config_data), 0)
29        self.assertTrue(log.error_occurred())
30        self.assertIsNone(data)
31
32    def test_get_string_2(self):
33        """Test with valid uuid value as input to get_string"""
34        constants = {}
35        log = manifest_compiler.Log()
36        uuid = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
37        config_data = {"data": uuid}
38        data = manifest_compiler.get_string(config_data, "data", constants, log)
39        self.assertEqual(len(config_data), 0)
40        self.assertFalse(log.error_occurred())
41        self.assertEqual(data, uuid)
42
43    def test_get_string_3(self):
44        """Test with empty string"""
45        constants = {}
46        log = manifest_compiler.Log()
47        config_data = {"data": ""}
48        data = manifest_compiler.get_string(config_data, "data", constants, log)
49        self.assertEqual(len(config_data), 0)
50        self.assertFalse(log.error_occurred())
51        self.assertEqual(data, "")
52
53    def test_get_string_4(self):
54        """Test with empty config data and non optional field"""
55        constants = {}
56        log = manifest_compiler.Log()
57        config_data = {}
58        data = manifest_compiler.get_string(config_data, "data", constants, log)
59        self.assertEqual(len(config_data), 0)
60        self.assertTrue(log.error_occurred())
61        self.assertIsNone(data)
62
63    def test_get_string_5(self):
64        """Test with non-existing attribute which is optional"""
65        constants = {}
66        log = manifest_compiler.Log()
67        config_data = {}
68        data = manifest_compiler.get_string(config_data, "data", constants, log,
69                                            optional=True, default="")
70        self.assertFalse(log.error_occurred())
71        self.assertEqual(data, "")
72
73    def test_get_string_6(self):
74        """Test with empty config with required field"""
75        constants = {}
76        log = manifest_compiler.Log()
77        config_data = {}
78        data = manifest_compiler.get_string(config_data, "data", constants, log)
79        self.assertTrue(log.error_occurred())
80        self.assertIsNone(data)
81
82    def test_get_int_when_valid_values_given(self):
83        """Test get_int called with valid values"""
84        cases = [
85            ("string of integers", "4096", 4096),
86            ("integer value", 4096, 4096),
87            ("valid hex", "0X7f010000", 0X7f010000),
88        ]
89
90        for msg, int_value, expected_value in cases:
91            with self.subTest(msg, value=int_value,
92                              expected_value=expected_value):
93                constants = {}
94                log = manifest_compiler.Log()
95                config_data = {"data": int_value}
96                data = manifest_compiler.get_int(config_data, "data", constants,
97                                                 log)
98                self.assertEqual(len(config_data), 0)
99                self.assertFalse(log.error_occurred())
100                self.assertEqual(data, expected_value)
101
102    def test_get_int_when_invalid_values_given(self):
103        """Test get_int called with invalid values"""
104        cases = [
105            ("empty string", ""),
106            ("invalid hex", "0X7k010000"),
107            ("contain non-integer value", "123A7"),
108            ("boolean value", True),
109        ]
110
111        for msg, int_value in cases:
112            with self.subTest(msg, value=int_value):
113                constants = {}
114                log = manifest_compiler.Log()
115                config_data = {"data": int_value}
116                data = manifest_compiler.get_int(config_data, "data", constants,
117                                                 log)
118                self.assertEqual(len(config_data), 0)
119                self.assertTrue(log.error_occurred())
120                self.assertIsNone(data)
121
122    def test_get_int_missing_required_field(self):
123        """Test with empty config data and non optional field"""
124        constants = {}
125        log = manifest_compiler.Log()
126        config_data = {}
127        data = manifest_compiler.get_int(config_data, "data", constants, log)
128        self.assertTrue(log.error_occurred())
129        self.assertIsNone(data)
130
131    def test_get_int_missing_optional_field(self):
132        """Test with non-existing attribute which is optional field"""
133        constants = {}
134        log = manifest_compiler.Log()
135        config_data = {}
136        data = manifest_compiler.get_int(config_data, "data", constants, log,
137                                         optional=True)
138        self.assertFalse(log.error_occurred())
139        self.assertIsNone(data)
140
141    def test_get_int_missing_optional_field_with_default(self):
142        """Test with non-existing attribute, which is optional field and default
143        value given.
144        """
145        constants = {}
146        log = manifest_compiler.Log()
147        config_data = {}
148        data = manifest_compiler.get_int(config_data, "data", constants, log,
149                                         optional=True, default=0)
150        self.assertFalse(log.error_occurred())
151        self.assertEqual(data, 0)
152
153    def test_get_boolean_1(self):
154        """Test with valid boolean values"""
155        constants = {}
156        log = manifest_compiler.Log()
157        config_data = {"data": True}
158        data = manifest_compiler.get_boolean(config_data, "data", constants,
159                                             log)
160        self.assertFalse(log.error_occurred())
161        self.assertTrue(data)
162
163    def test_get_boolean_2(self):
164        """Test with invalid values"""
165        constants = {}
166        log = manifest_compiler.Log()
167        config_data = {"data": "True"}
168        data = manifest_compiler.get_boolean(config_data, "data", constants,
169                                             log)
170        self.assertTrue(log.error_occurred())
171        self.assertIsNone(data)
172
173    def test_get_boolean_3(self):
174        """Test with invalid values"""
175        constants = {}
176        log = manifest_compiler.Log()
177        config_data = {"data": 1}
178        data = manifest_compiler.get_boolean(config_data, "data", constants,
179                                             log)
180        self.assertTrue(log.error_occurred())
181        self.assertIsNone(data)
182
183    def test_get_boolean_4(self):
184        """Test with empty config data with non optional field"""
185        constants = {}
186        log = manifest_compiler.Log()
187        config_data = {}
188        data = manifest_compiler.get_boolean(config_data, "data", constants,
189                                             log)
190        self.assertTrue(log.error_occurred())
191        self.assertIsNone(data)
192
193    def test_get_boolean_5(self):
194        """ Test with non-existing attribute which is optional"""
195        constants = {}
196        log = manifest_compiler.Log()
197        config_data = {}
198        data = manifest_compiler.get_boolean(config_data, "data", constants,
199                                             log, optional=True, default=False)
200        self.assertFalse(log.error_occurred())
201        self.assertFalse(data)
202
203    def test_get_list_1(self):
204        """Test with valid value as list"""
205        log = manifest_compiler.Log()
206        sample_list = [1, 2, 3]
207        config_data = {"data": sample_list}
208        data = manifest_compiler.get_list(config_data, "data", log)
209        self.assertFalse(log.error_occurred())
210        self.assertEqual(data, sample_list)
211
212    def test_get_list_2(self):
213        """Test with non-existing attribute with optional field"""
214        log = manifest_compiler.Log()
215        config_data = {}
216        data = manifest_compiler.get_list(config_data, "data", log,
217                                          optional=True, default=[])
218        self.assertFalse(log.error_occurred())
219        self.assertEqual(data, [])
220
221    def test_get_list_3(self):
222        """Test with empty config data with required field"""
223        log = manifest_compiler.Log()
224        config_data = {}
225        data = manifest_compiler.get_list(config_data, "data", log)
226        self.assertTrue(log.error_occurred())
227        self.assertIsNone(data)
228
229    def test_get_list_4(self):
230        """Test with invalid value"""
231        log = manifest_compiler.Log()
232        config_data = {"data": 123}
233        manifest_compiler.get_list(config_data, "data", log, optional=True)
234        self.assertTrue(log.error_occurred())
235
236    def test_get_dict_1(self):
237        """Test with valid value as dict"""
238        log = manifest_compiler.Log()
239        sample_dict = {"attr": 1}
240        config_data = {"data": sample_dict}
241        data = manifest_compiler.get_dict(config_data, "data", log)
242        self.assertFalse(log.error_occurred())
243        self.assertEqual(data, sample_dict)
244
245    def test_get_dict_2(self):
246        """Test with non-existing attribute with optional field"""
247        log = manifest_compiler.Log()
248        config_data = {}
249        data = manifest_compiler.get_dict(config_data, "data", log,
250                                          optional=True, default={})
251        self.assertFalse(log.error_occurred())
252        self.assertEqual(data, {})
253
254    def test_get_dict_3(self):
255        """Test with empty config data with required field"""
256        log = manifest_compiler.Log()
257        config_data = {}
258        data = manifest_compiler.get_dict(config_data, "data", log)
259        self.assertTrue(log.error_occurred())
260        self.assertIsNone(data)
261
262    def test_get_dict_4(self):
263        """Test with invalid value"""
264        log = manifest_compiler.Log()
265        config_data = {"data": 123}
266        manifest_compiler.get_dict(config_data, "data", log, optional=True)
267        self.assertTrue(log.error_occurred())
268
269    def test_validate_uuid_1(self):
270        """Test with valid UUID with hex values"""
271        log = manifest_compiler.Log()
272        uuid_in = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
273        data = manifest_compiler.parse_uuid(uuid_in, log)
274        self.assertFalse(log.error_occurred())
275        self.assertEqual(data.hex(), uuid_in.replace("-", ""))
276
277    def test_validate_uuid_2(self):
278        """Test with invalid UUID containing one byte less"""
279        log = manifest_compiler.Log()
280        uuid = "902ace-5e5c-4cd8-ae54-87b88c22ddaf"
281        data = manifest_compiler.parse_uuid(uuid, log)
282        self.assertTrue(log.error_occurred())
283        self.assertIsNone(data)
284
285    def test_validate_uuid_3(self):
286        """Test with invalid number of bytes in UUID groups"""
287        log = manifest_compiler.Log()
288        uuid = "5f902ace5e-5c-4cd8-ae54-87b88c22ddaf"
289        data = manifest_compiler.parse_uuid(uuid, log)
290        self.assertTrue(log.error_occurred())
291        self.assertIsNone(data)
292
293    def test_validate_uuid_6(self):
294        """Test with valid UUID value but ungrouped"""
295        log = manifest_compiler.Log()
296        uuid = "5f902ace5e5c4cd8ae5487b88c22ddaf"
297        data = manifest_compiler.parse_uuid(uuid, log)
298        self.assertTrue(log.error_occurred())
299        self.assertIsNone(data)
300
301    def test_validate_uuid_7(self):
302        """Test with UUID containing invalid hex digits"""
303        log = manifest_compiler.Log()
304        uuid = "12345678-gggg-1222-3333-222111233222"
305        data = manifest_compiler.parse_uuid(uuid, log)
306        self.assertTrue(log.error_occurred())
307        self.assertIsNone(data)
308
309    def test_validate_uuid_8(self):
310        """Test with invalid UUID value"""
311        log = manifest_compiler.Log()
312        uuid = ""
313        data = manifest_compiler.parse_uuid(uuid, log)
314        self.assertTrue(log.error_occurred())
315        self.assertIsNone(data)
316
317    def test_validate_memory_size_1(self):
318        """Test with valid memory size"""
319        log = manifest_compiler.Log()
320        data = manifest_compiler.parse_memory_size(4096,
321                                                   manifest_compiler.MIN_STACK,
322                                                   log)
323        self.assertFalse(log.error_occurred())
324        self.assertEqual(data, 4096)
325
326    def test_validate_memory_size_2(self):
327        """Test with valid memory size"""
328        log = manifest_compiler.Log()
329        data = manifest_compiler.parse_memory_size(8192,
330                                                   manifest_compiler.MIN_STACK,
331                                                   log)
332        self.assertFalse(log.error_occurred())
333        self.assertEqual(data, 8192)
334
335    def test_validate_memory_size_3(self):
336        """Test flag controlling whether zero is valid or not"""
337        log = manifest_compiler.Log()
338
339        data = manifest_compiler.parse_memory_size(0,
340                                                   manifest_compiler.MIN_STACK,
341                                                   log, zero_is_ok=True)
342        self.assertFalse(log.error_occurred())
343        self.assertEqual(data, 0)
344
345        data = manifest_compiler.parse_memory_size(0,
346                                                   manifest_compiler.MIN_STACK,
347                                                   log, zero_is_ok=False)
348        self.assertTrue(log.error_occurred())
349        self.assertIsNone(data)
350
351    def test_validate_memory_size_4(self):
352        """Test with invalid memory size"""
353        log = manifest_compiler.Log()
354        data = manifest_compiler.parse_memory_size(-4096,
355                                                   manifest_compiler.MIN_STACK,
356                                                   log)
357        self.assertTrue(log.error_occurred())
358        self.assertIsNone(data)
359
360    def test_validate_memory_size_5(self):
361        """Test with invalid memory size"""
362        log = manifest_compiler.Log()
363        data = manifest_compiler.parse_memory_size(4095,
364                                                   manifest_compiler.MIN_STACK,
365                                                   log)
366        self.assertTrue(log.error_occurred())
367        self.assertIsNone(data)
368
369    def test_validate_memory_size_6(self):
370        """Test with invalid memory size"""
371        log = manifest_compiler.Log()
372        data = manifest_compiler.parse_memory_size(16777217,
373                                                   manifest_compiler.MIN_STACK,
374                                                   log)
375        self.assertTrue(log.error_occurred())
376        self.assertIsNone(data)
377
378    def test_validate_memory_size_7(self):
379        """Test with invalid memory size"""
380        log = manifest_compiler.Log()
381        data = manifest_compiler.parse_memory_size(1024,
382                                                   manifest_compiler.MIN_STACK,
383                                                   log)
384        self.assertTrue(log.error_occurred())
385        self.assertIsNone(data)
386
387    def test_validate_memory_size_8(self):
388        """Test with valid large integer value (2**32) as memory size"""
389        log = manifest_compiler.Log()
390        data = manifest_compiler.parse_memory_size(4294967296,
391                                                   manifest_compiler.MIN_STACK,
392                                                   log)
393        self.assertFalse(log.error_occurred())
394        self.assertEqual(data, 4294967296)
395
396    def test_parse_shadow_stack_size_1(self):
397        """Test with valid shadow stack size"""
398        log = manifest_compiler.Log()
399        data = manifest_compiler.parse_shadow_stack_size(4096, log)
400        self.assertFalse(log.error_occurred())
401        self.assertEqual(data, 4096)
402
403    def test_parse_shadow_stack_size_2(self):
404        """Test without shadow stack size"""
405        log = manifest_compiler.Log()
406        data = manifest_compiler.parse_shadow_stack_size(None, log)
407        self.assertFalse(log.error_occurred())
408        self.assertIsNone(data)
409
410    def test_parse_shadow_stack_size_3(self):
411        """Test with invalid shadow stack size"""
412        log = manifest_compiler.Log()
413        data = manifest_compiler.parse_shadow_stack_size(-1, log)
414        self.assertTrue(log.error_occurred())
415        self.assertIsNone(data)
416
417    def test_parse_shadow_stack_size_4(self):
418        """Test with invalid shadow stack size"""
419        log = manifest_compiler.Log()
420        data = manifest_compiler.parse_shadow_stack_size(1, log)
421        self.assertTrue(log.error_occurred())
422        self.assertIsNone(data)
423
424    def test_validate_mem_map_1(self):
425        """Test with a single memory mapping"""
426        constants = {}
427        mem_map_ref_data = [{"id": 1, "addr": 0x70000000, "size": 0x1000}]
428
429        mem_map_json_data = [{"id": 1, "addr": "0x70000000", "size": "0x1000"}]
430
431        log = manifest_compiler.Log()
432        mem_io_map_list = manifest_compiler.parse_mem_map(
433            mem_map_json_data, manifest_compiler.MEM_MAP, constants, log)
434        self.assertFalse(log.error_occurred())
435
436        for (memio_map, memio_ref_data) in zip(
437                mem_io_map_list, mem_map_ref_data):
438            self.assertEqual(memio_map.id, memio_ref_data["id"])
439            self.assertEqual(memio_map.addr, memio_ref_data["addr"])
440            self.assertEqual(memio_map.size, memio_ref_data["size"])
441
442    def test_validate_mem_map_2(self):
443        """Test with multiple memory mapping"""
444        constants = {}
445        mem_map_ref_data = [{"id": 1, "addr": 0x70000000, "size": 0x1000},
446                            {"id": 2, "addr": 0x70010000, "size": 0x100},
447                            {"id": 3, "addr": 0x70020000, "size": 0x4}]
448
449        mem_map_json_data = [{"id": 1, "addr": "0x70000000", "size": "0x1000"},
450                             {"id": 2, "addr": "0x70010000", "size": "0x100"},
451                             {"id": 3, "addr": "0x70020000", "size": "0x4"}]
452
453        log = manifest_compiler.Log()
454        mem_io_map_list = manifest_compiler.parse_mem_map(
455            mem_map_json_data, manifest_compiler.MEM_MAP, constants, log)
456        self.assertFalse(log.error_occurred())
457
458        for (memio_map, memio_ref_data) in zip(
459                mem_io_map_list, mem_map_ref_data):
460            self.assertEqual(memio_map.id, memio_ref_data["id"])
461            self.assertEqual(memio_map.addr, memio_ref_data["addr"])
462            self.assertEqual(memio_map.size, memio_ref_data["size"])
463
464    def test_validate_mem_map_3(self):
465        """Test with a unknown entry in memory mapping"""
466        constants = {}
467        mem_map_json_data = [{"id": 1, "addr": "0x70000000", "size": "0x1000",
468                              "offset": "0x70001000"}]
469
470        log = manifest_compiler.Log()
471        manifest_compiler.parse_mem_map(
472            mem_map_json_data, manifest_compiler.MEM_MAP, constants, log)
473        self.assertTrue(log.error_occurred())
474
475    def test_validate_mem_map_4(self):
476        """Test with a empty memory mapping entry"""
477        constants = {}
478        mem_map_json_data = []
479
480        log = manifest_compiler.Log()
481        mem_io_map_list = manifest_compiler.parse_mem_map(
482            mem_map_json_data, manifest_compiler.MEM_MAP, constants, log)
483        self.assertFalse(log.error_occurred())
484        self.assertFalse(mem_io_map_list)
485
486    def test_validate_mem_map_5(self):
487        """Test with a memory mapping entry with missing "size" field"""
488        constants = {}
489        mem_map_json_data = [{"id": 1, "addr": "0x70000000"}]
490
491        log = manifest_compiler.Log()
492        manifest_compiler.parse_mem_map(
493            mem_map_json_data, manifest_compiler.MEM_MAP, constants, log)
494        self.assertTrue(log.error_occurred())
495
496    def test_validate_mem_map_6(self):
497        """Test with a memory mapping entry with invalid JSON format. Pass
498        invalid list of JSON attributes
499        """
500        constants = {}
501        mem_map_json_data = ["id", 1, "addr", "0x70000000"]
502
503        log = manifest_compiler.Log()
504        manifest_compiler.parse_mem_map(
505            mem_map_json_data, manifest_compiler.MEM_MAP, constants, log)
506        self.assertTrue(log.error_occurred())
507
508    def test_validate_mem_map_7(self):
509        """Test with a memory mapping entry with invalid JSON format. Pass a
510        MEM_MAP JSON object instead of list of MEM_MAP JSON objects.
511        """
512        constants = {}
513        config_data = {manifest_compiler.MEM_MAP:
514                       {"id": 1, "addr": "0x70000000"}}
515
516        log = manifest_compiler.Log()
517        manifest_compiler.parse_mem_map(
518            manifest_compiler.get_list(
519                config_data, manifest_compiler.MEM_MAP, log,
520                optional=True),
521            manifest_compiler.MEM_MAP, constants, log)
522        self.assertTrue(log.error_occurred())
523
524    def test_validate_mem_map_8(self):
525        """Test duplicate mem_map ID fails"""
526        constants = {}
527        mem_map_json_data = [{"id": 1, "addr": "0x70000000", "size": "0x1000"},
528                             {"id": 1, "addr": "0x70010000", "size": "0x1000"}]
529
530        log = manifest_compiler.Log()
531        manifest_compiler.parse_mem_map(
532            mem_map_json_data, manifest_compiler.MEM_MAP, constants, log)
533        self.assertTrue(log.error_occurred())
534
535    def test_validate_mgmt_flags_1(self):
536        """Test with a valid management flags"""
537        constants = {}
538        mgmt_flags_ref_data = {
539            manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: True,
540            manifest_compiler.MGMT_FLAG_DEFERRED_START: True,
541            manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: True}
542        mgmt_flags_data = {
543            manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: True,
544            manifest_compiler.MGMT_FLAG_DEFERRED_START: True,
545            manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: True}
546
547        log = manifest_compiler.Log()
548        mgmt_flags = manifest_compiler.parse_mgmt_flags(
549            mgmt_flags_data, constants, log)
550        self.assertFalse(log.error_occurred())
551        self.assertEqual(mgmt_flags.restart_on_exit,
552                         mgmt_flags_ref_data[
553                             manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT])
554        self.assertEqual(mgmt_flags.deferred_start,
555                         mgmt_flags_ref_data[
556                             manifest_compiler.MGMT_FLAG_DEFERRED_START])
557        self.assertEqual(mgmt_flags.non_critical_app,
558                         mgmt_flags_ref_data[
559                             manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP])
560
561    def test_validate_mgmt_flags_2(self):
562        """Test with a valid management flags"""
563        constants = {}
564        mgmt_flags_ref_data = {
565            manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
566            manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
567            manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False}
568        mgmt_flags_data = {
569            manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
570            manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
571            manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False}
572
573        log = manifest_compiler.Log()
574        mgmt_flags = manifest_compiler.parse_mgmt_flags(
575            mgmt_flags_data, constants, log)
576        self.assertFalse(log.error_occurred())
577        self.assertEqual(mgmt_flags.restart_on_exit,
578                         mgmt_flags_ref_data[
579                             manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT])
580        self.assertEqual(mgmt_flags.deferred_start,
581                         mgmt_flags_ref_data[
582                             manifest_compiler.MGMT_FLAG_DEFERRED_START])
583        self.assertEqual(mgmt_flags.non_critical_app,
584                         mgmt_flags_ref_data[
585                             manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP])
586
587    def test_validate_mgmt_flags_3(self):
588        """Test with a valid management flags"""
589        constants = {}
590        mgmt_flags_ref_data = {
591            manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
592            manifest_compiler.MGMT_FLAG_DEFERRED_START: True,
593            manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False}
594        mgmt_flags_data = {
595            manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
596            manifest_compiler.MGMT_FLAG_DEFERRED_START: True,
597            manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False}
598
599        log = manifest_compiler.Log()
600        mgmt_flags = manifest_compiler.parse_mgmt_flags(
601            mgmt_flags_data, constants, log)
602        self.assertFalse(log.error_occurred())
603        self.assertEqual(mgmt_flags.restart_on_exit,
604                         mgmt_flags_ref_data[
605                             manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT])
606        self.assertEqual(mgmt_flags.deferred_start,
607                         mgmt_flags_ref_data[
608                             manifest_compiler.MGMT_FLAG_DEFERRED_START])
609        self.assertEqual(mgmt_flags.non_critical_app,
610                         mgmt_flags_ref_data[
611                             manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP])
612
613    def test_validate_mgmt_flags_4(self):
614        """Test with a management flags missing
615        manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT
616        """
617        constants = {}
618        mgmt_flags_data = {manifest_compiler.MGMT_FLAG_DEFERRED_START: True}
619
620        log = manifest_compiler.Log()
621        mgmt_flags = manifest_compiler.parse_mgmt_flags(
622            mgmt_flags_data, constants, log)
623        self.assertFalse(log.error_occurred())
624        self.assertIsNone(mgmt_flags.restart_on_exit)
625        self.assertTrue(mgmt_flags.deferred_start)
626        self.assertIsNone(mgmt_flags.non_critical_app)
627
628    def test_validate_mgmt_flags_5(self):
629        """Test with a empty management flags"""
630        constants = {}
631        mgmt_flags_data = {}
632
633        log = manifest_compiler.Log()
634        mgmt_flags = manifest_compiler.parse_mgmt_flags(
635            mgmt_flags_data, constants, log)
636        self.assertFalse(log.error_occurred())
637        self.assertIsNone(mgmt_flags.restart_on_exit)
638        self.assertIsNone(mgmt_flags.deferred_start)
639        self.assertIsNone(mgmt_flags.non_critical_app)
640
641    def test_validate_mgmt_flags_6(self):
642        """Test with a mgmt_flags as array of flags"""
643        constants = {}
644        config_data = {manifest_compiler.MGMT_FLAGS: [{
645            manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: True,
646            manifest_compiler.MGMT_FLAG_DEFERRED_START: True,
647            manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: True}]}
648
649        log = manifest_compiler.Log()
650        manifest_compiler.parse_mgmt_flags(
651            manifest_compiler.get_dict(
652                config_data, manifest_compiler.MGMT_FLAGS, log,
653                optional=True),
654            constants, log)
655        self.assertTrue(log.error_occurred())
656
657    def test_validate_start_port_1(self):
658        """Test with a single start_ports entry"""
659        constants_data = [{
660            "header": "test.h",
661            "constants": [{
662                "name": "LOADABLE_START_PORT",
663                "value": "com.android.trusty.appmgmt.loadable.start",
664                "type": "port"}]
665        }]
666        ref_data = [{
667            manifest_compiler.START_PORT_NAME:
668                "com.android.trusty.appmgmt.loadable.start",
669            manifest_compiler.START_PORT_FLAGS: {
670                manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
671                manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False}}]
672
673        port_conf_data = [{
674            manifest_compiler.START_PORT_NAME:
675                "LOADABLE_START_PORT",
676            manifest_compiler.START_PORT_FLAGS: {
677                manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
678                manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False}}]
679
680        log = manifest_compiler.Log()
681        conf_constants = manifest_compiler.extract_config_constants(
682            constants_data, log)
683        constants = manifest_compiler.index_constants(conf_constants)
684        start_ports_list = manifest_compiler.parse_app_start_ports(
685            port_conf_data, manifest_compiler.START_PORTS, constants, log)
686        self.assertFalse(log.error_occurred())
687
688        for (start_port, ref_port) in zip(
689                start_ports_list, ref_data):
690            self.assertEqual(start_port.name,
691                             ref_port[manifest_compiler.START_PORT_NAME])
692            ref_flags = ref_port[manifest_compiler.START_PORT_FLAGS]
693            self.assertEqual(
694                start_port.start_port_flags.allow_ta_connect,
695                ref_flags[manifest_compiler.START_PORT_ALLOW_TA_CONNECT])
696            self.assertEqual(
697                start_port.start_port_flags.allow_ns_connect,
698                ref_flags[manifest_compiler.START_PORT_ALLOW_NS_CONNECT])
699
700    def test_validate_start_port_2(self):
701        """Test with a  multiple start_ports entry"""
702        constants = {}
703        ref_data = [
704            {
705                manifest_compiler.START_PORT_NAME:
706                    "com.android.trusty.appmgmt.loadable.start",
707                manifest_compiler.START_PORT_FLAGS: {
708                    manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
709                    manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False
710                }
711            },
712            {
713                manifest_compiler.START_PORT_NAME:
714                    "com.android.trusty.appmgmt.portstartsrv.shutdown",
715                manifest_compiler.START_PORT_FLAGS: {
716                    manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
717                    manifest_compiler.START_PORT_ALLOW_NS_CONNECT: True
718                }
719            }]
720
721        port_conf_data = [
722            {
723                manifest_compiler.START_PORT_NAME:
724                    "com.android.trusty.appmgmt.loadable.start",
725                manifest_compiler.START_PORT_FLAGS: {
726                    manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
727                    manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False}
728            },
729            {
730                manifest_compiler.START_PORT_NAME:
731                    "com.android.trusty.appmgmt.portstartsrv.shutdown",
732                manifest_compiler.START_PORT_FLAGS: {
733                    manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
734                    manifest_compiler.START_PORT_ALLOW_NS_CONNECT: True}
735            }]
736
737        log = manifest_compiler.Log()
738        start_ports_list = manifest_compiler.parse_app_start_ports(
739            port_conf_data, manifest_compiler.START_PORTS, constants, log)
740        self.assertFalse(log.error_occurred())
741
742        for (start_port, ref_port) in zip(
743                start_ports_list, ref_data):
744            self.assertEqual(start_port.name,
745                             ref_port[manifest_compiler.START_PORT_NAME])
746            ref_port_flags = ref_port[manifest_compiler.START_PORT_FLAGS]
747            self.assertEqual(
748                start_port.start_port_flags.allow_ta_connect,
749                ref_port_flags[manifest_compiler.START_PORT_ALLOW_TA_CONNECT])
750            self.assertEqual(
751                start_port.start_port_flags.allow_ns_connect,
752                ref_port_flags[manifest_compiler.START_PORT_ALLOW_NS_CONNECT])
753
754    def test_validate_start_port_3(self):
755        """Test with a zero start_ports"""
756        constants = {}
757        start_ports_json_data = []
758
759        log = manifest_compiler.Log()
760        start_ports_list = manifest_compiler.parse_app_start_ports(
761            start_ports_json_data, manifest_compiler.START_PORTS,
762            constants, log)
763        self.assertFalse(log.error_occurred())
764        self.assertEqual(len(start_ports_list), 0)
765
766    def test_validate_start_port_4(self):
767        """Test with a unknown attribute in start_port entry"""
768        constants = {}
769        start_ports_json_data = [
770            {
771                manifest_compiler.START_PORT_NAME:
772                    "com.android.trusty.appmgmt.loadable.start",
773                manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
774                manifest_compiler.START_PORT_FLAGS: {
775                    manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
776                    manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False}
777            }]
778
779        log = manifest_compiler.Log()
780        manifest_compiler.parse_app_start_ports(
781            start_ports_json_data, manifest_compiler.START_PORTS,
782            constants, log)
783        self.assertTrue(log.error_occurred())
784
785    def test_validate_start_port_5(self):
786        """Test with a flags missing in start_port entry"""
787        constants = {}
788        start_ports_json_data = [
789            {
790                manifest_compiler.START_PORT_NAME:
791                    "com.android.trusty.appmgmt.loadable.start",
792            }]
793
794        log = manifest_compiler.Log()
795        manifest_compiler.parse_app_start_ports(
796            start_ports_json_data, manifest_compiler.START_PORTS,
797            constants, log)
798        self.assertTrue(log.error_occurred())
799
800    def test_validate_app_name_1(self):
801        log = manifest_compiler.Log()
802        manifest_compiler.parse_app_name("", log)
803        self.assertTrue(log.error_occurred())
804
805    def test_validate_app_name_2(self):
806        log = manifest_compiler.Log()
807        app_name = "test-app-name"
808        data = manifest_compiler.parse_app_name(app_name, log)
809        self.assertFalse(log.error_occurred())
810        self.assertEqual(data, app_name)
811
812    def test_validate_app_name_3(self):
813        log = manifest_compiler.Log()
814        app_name = "   test-app-name  "
815        data = manifest_compiler.parse_app_name(app_name, log)
816        self.assertFalse(log.error_occurred())
817        self.assertEqual(data, app_name.strip())
818
819    def test_manifest_valid_dict_1(self):
820        """Test with valid UUID with hex values and valid values for min_heap
821        and min_stack.
822        """
823        constants = {}
824        uuid_in = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
825        min_heap = 4096
826        min_stack = 4096
827        id_ = 1
828        addr = "0x70000000"
829        size = "0x1000"
830        default_app_name = "test_app"
831        mem_map_data = [{"id": id_, "addr": addr, "size": size}]
832        log = manifest_compiler.Log()
833
834        config_data = {
835            "uuid": uuid_in,
836            "min_heap": min_heap,
837            "min_stack": min_stack,
838            "mem_map": mem_map_data
839        }
840        manifest = manifest_compiler.parse_manifest_config(config_data,
841                                                           constants,
842                                                           default_app_name,
843                                                           log)
844        self.assertFalse(log.error_occurred())
845        self.assertIsNotNone(manifest)
846        self.assertEqual(manifest.uuid.hex(), uuid_in.replace("-", ""))
847        self.assertEqual(manifest.min_heap, min_heap)
848        self.assertEqual(manifest.min_stack, min_stack)
849        self.assertEqual(manifest.app_name, default_app_name)
850        for memio_map in manifest.mem_io_maps:
851            self.assertEqual(memio_map.id, id_)
852            self.assertEqual(memio_map.addr, int(addr, 0))
853            self.assertEqual(memio_map.size, int(size, 0))
854        self.assertFalse(manifest.mgmt_flags.restart_on_exit)
855        self.assertFalse(manifest.mgmt_flags.deferred_start)
856        self.assertFalse(manifest.mgmt_flags.non_critical_app)
857
858    def test_manifest_valid_dict_2(self):
859        """Test with valid UUID, min_heap, min_stack, and min_shadow stack."""
860        constants = {}
861        uuid_in = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
862        min_heap = 4096
863        min_stack = 4096
864        min_shadow_stack = 2 * min_stack
865        log = manifest_compiler.Log()
866
867        config_data = {
868            "uuid": uuid_in,
869            "min_heap": min_heap,
870            "min_stack": min_stack,
871            "min_shadow_stack": min_shadow_stack
872        }
873        manifest = manifest_compiler.parse_manifest_config(config_data,
874                                                           constants,
875                                                           "shadowy_test_app",
876                                                           log)
877        self.assertFalse(log.error_occurred())
878        self.assertIsNotNone(manifest)
879        self.assertEqual(manifest.min_stack, min_stack)
880        # we mainly care that we got the shadow stack size right
881        self.assertEqual(manifest.min_shadow_stack, min_shadow_stack)
882        # not to be confused with the regular stack
883        self.assertNotEqual(manifest.min_shadow_stack, manifest.min_stack)
884
885    def test_manifest_invalid_dict_2(self):
886        """Test with invalid value in config, UUID with integer value and string
887        values for min_stack.
888        """
889        constants = {}
890        log = manifest_compiler.Log()
891        default_app_name = "test"
892        config_data = {"uuid": 123, "app_name": "test", "min_heap": "4096",
893                       "min_stack": "8192"}
894        manifest = manifest_compiler.parse_manifest_config(config_data,
895                                                           constants,
896                                                           default_app_name,
897                                                           log)
898        self.assertEqual(len(config_data), 0)
899        self.assertTrue(log.error_occurred())
900        self.assertIsNone(manifest)
901
902    def test_manifest_invalid_dict_3(self):
903        """ Test with empty config."""
904        constants = {}
905        log = manifest_compiler.Log()
906        config_data = {}
907        default_app_name = "test"
908        manifest = manifest_compiler.parse_manifest_config(config_data,
909                                                           constants,
910                                                           default_app_name,
911                                                           log)
912        self.assertTrue(log.error_occurred())
913        self.assertIsNone(manifest)
914
915    def test_manifest_invalid_dict_4(self):
916        """Test with unknown entries"""
917        constants = {}
918        log = manifest_compiler.Log()
919        config_data = {"uuid": "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
920                       "min_heap": 4096, "min_stack": 4096, "max_heap": 234}
921        default_app_name = "test"
922        manifest = manifest_compiler.parse_manifest_config(config_data,
923                                                           constants,
924                                                           default_app_name,
925                                                           log)
926        self.assertNotEqual(len(config_data), 0)
927        self.assertTrue(log.error_occurred())
928        self.assertIsNone(manifest)
929
930    def test_const_config_1(self):
931        """Test constant config with port and uuid constants"""
932        uuid = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
933        port = "com.android.trusty.appmgmt.bootstartsrv"
934        constants_data = [
935            {
936                "header": "test_uuid.h",
937                "constants": [{"name": TEST_UUID,
938                               "value": uuid,
939                               "type": "uuid"}]
940            },
941            {
942                "header": "test_port.h",
943                "constants": [{"name": TEST_PORT,
944                               "value": port,
945                               "type": "port"}]
946            }
947        ]
948        log = manifest_compiler.Log()
949        config_data = {manifest_compiler.UUID: TEST_UUID,
950                       manifest_compiler.START_PORT_NAME: TEST_PORT}
951        conf_constants = manifest_compiler.extract_config_constants(
952            constants_data, log)
953        constants = manifest_compiler.index_constants(conf_constants)
954        data_uuid = manifest_compiler.get_string(
955            config_data, manifest_compiler.UUID, constants, log)
956        data_port = manifest_compiler.get_string(
957            config_data, manifest_compiler.START_PORT_NAME, constants, log)
958        self.assertEqual(len(config_data), 0)
959        self.assertFalse(log.error_occurred())
960        self.assertEqual(data_uuid.hex(), uuid.replace("-", ""))
961        self.assertEqual(data_port, port)
962
963    def test_const_config_2(self):
964        """Test constant config with unknown fields"""
965        uuid = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
966        port = "com.android.trusty.appmgmt.bootstartsrv"
967        constants_data = [
968            {
969                "header": "test_uuid.h",
970                "constants": [{"name": TEST_UUID,
971                               "value": uuid,
972                               "type": "uuid",
973                               "length": 16}]
974            },
975            {
976                "header": "test_port.h",
977                "constants": [{"name": TEST_PORT,
978                               "value": port,
979                               "type": "port",
980                               "size": 42}]
981            }
982        ]
983        log = manifest_compiler.Log()
984        manifest_compiler.extract_config_constants(constants_data, log)
985        self.assertTrue(log.error_occurred())
986
987    def test_const_config_3(self):
988        """Test constant config no constants"""
989        constants_data = [{"header": "test_uuid.h", "constants": []}]
990        log = manifest_compiler.Log()
991        manifest_compiler.extract_config_constants(constants_data, log)
992        self.assertFalse(log.error_occurred())
993
994    def test_const_config_4(self):
995        """Test constant config with missing header field"""
996        constants_data = [{"constants": []}]
997        log = manifest_compiler.Log()
998        manifest_compiler.extract_config_constants(constants_data, log)
999        self.assertTrue(log.error_occurred())
1000
1001    def test_const_config_5(self):
1002        """Test constant config with invalid const type for literal TEST_PORT"""
1003        uuid = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
1004        port = "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
1005        constants_data = [
1006            {
1007                "header": "test_uuid.h",
1008                "constants": [{"name": TEST_UUID,
1009                               "value": uuid,
1010                               "type": "uuid"}]
1011            },
1012            {
1013                "header": "test_port.h",
1014                "constants": [{"name": TEST_PORT,
1015                               "value": port,
1016                               "type": "uuid"}]
1017            }
1018        ]
1019        config_data = {manifest_compiler.START_PORT_NAME: TEST_PORT}
1020        log = manifest_compiler.Log()
1021        conf_constants = manifest_compiler.extract_config_constants(
1022            constants_data, log)
1023        constants = manifest_compiler.index_constants(conf_constants)
1024        self.assertFalse(log.error_occurred())
1025        manifest_compiler.get_string(config_data,
1026                                     manifest_compiler.START_PORT_NAME,
1027                                     constants, log)
1028        self.assertTrue(log.error_occurred())
1029
1030    def test_const_config_6(self):
1031        """Test constant config with constant value missing"""
1032        constants_data = [{
1033            "header": "test_port.h",
1034            "constants": [{
1035                "name": TEST_SIZE,
1036                "type": "int"}]
1037        }]
1038
1039        log = manifest_compiler.Log()
1040        manifest_compiler.extract_config_constants(constants_data, log)
1041        self.assertTrue(log.error_occurred())
1042
1043    def test_const_config_7(self):
1044        """Test constant config with int constant value"""
1045        test_value = 4096
1046        constants_data = [{
1047            "header": "test_consts.h",
1048            "constants": [{
1049                "name": TEST_SIZE,
1050                "value": test_value,
1051                "type": "int",
1052                "unsigned": True}]
1053        }]
1054        config_data = {manifest_compiler.MIN_HEAP: TEST_SIZE}
1055
1056        log = manifest_compiler.Log()
1057        conf_constants = manifest_compiler.extract_config_constants(
1058            constants_data, log)
1059        self.assertFalse(log.error_occurred())
1060        constants = manifest_compiler.index_constants(conf_constants)
1061        self.assertFalse(log.error_occurred())
1062        data = manifest_compiler.get_int(config_data,
1063                                         manifest_compiler.MIN_HEAP,
1064                                         constants, log)
1065        self.assertEqual(data, test_value)
1066        self.assertFalse(log.error_occurred())
1067
1068    def test_const_config_8(self):
1069        """ Test constant config with hexadecimal int constant value"""
1070        test_value = "0x1000"
1071        constants_data = [{
1072            "header": "test_consts.h",
1073            "constants": [{
1074                "name": TEST_SIZE,
1075                "value": test_value,
1076                "type": "int",
1077                "unsigned": True}]
1078        }]
1079        config_data = {manifest_compiler.MIN_HEAP: TEST_SIZE}
1080
1081        log = manifest_compiler.Log()
1082        conf_constants = manifest_compiler.extract_config_constants(
1083            constants_data, log)
1084        self.assertFalse(log.error_occurred())
1085        constants = manifest_compiler.index_constants(conf_constants)
1086        self.assertFalse(log.error_occurred())
1087        data = manifest_compiler.get_int(config_data,
1088                                         manifest_compiler.MIN_HEAP,
1089                                         constants, log)
1090        self.assertEqual(data, int(test_value, 0))
1091        self.assertFalse(log.error_occurred())
1092
1093    def test_const_config_9(self):
1094        """Test constant config with unsigned field missing in int type constant
1095        """
1096        test_value = "0x1000"
1097        constants_data = [{
1098            "header": "test_consts.h",
1099            "constants": [{
1100                "name": TEST_SIZE,
1101                "value": test_value,
1102                "type": "int"}]
1103        }]
1104
1105        log = manifest_compiler.Log()
1106        manifest_compiler.extract_config_constants(constants_data, log)
1107        self.assertTrue(log.error_occurred())
1108
1109    def test_const_config_10(self):
1110        """Test constant config with boolean field"""
1111        test_bool = "SAMPLE_BOOL"
1112        test_value = True
1113        constants_data = [{
1114            "header": "test_consts.h",
1115            "constants": [{
1116                "name": test_bool,
1117                "value": test_value,
1118                "type": "bool"}]
1119        }]
1120        config_data = {manifest_compiler.START_PORT_ALLOW_TA_CONNECT: test_bool}
1121
1122        log = manifest_compiler.Log()
1123        conf_constants = manifest_compiler.extract_config_constants(
1124            constants_data, log)
1125        self.assertFalse(log.error_occurred())
1126        constants = manifest_compiler.index_constants(conf_constants)
1127        self.assertFalse(log.error_occurred())
1128        data = manifest_compiler.get_boolean(
1129            config_data, manifest_compiler.START_PORT_ALLOW_TA_CONNECT,
1130            constants, log)
1131        self.assertEqual(data, test_value)
1132        self.assertFalse(log.error_occurred())
1133
1134    def test_manifest_valid_pack_1(self):
1135        """Test with valid UUID with hex values and
1136        valid values for min_heap and min_stack.
1137        Pack the manifest config data and unpack it and
1138        verify it with the expected values
1139        """
1140        # PLZ DON'T EDIT VALUES
1141        constants = {}
1142        log = manifest_compiler.Log()
1143
1144        # Reference JSON manifest data structure
1145        config_ref_data = {
1146            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1147            manifest_compiler.APP_NAME: "test-app-name",
1148            manifest_compiler.MIN_HEAP: 8192,
1149            manifest_compiler.MIN_STACK: 4096,
1150            manifest_compiler.MGMT_FLAGS: {
1151                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1152                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1153                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1154            },
1155            manifest_compiler.APPLOADER_FLAGS: {
1156                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1157            }
1158        }
1159
1160        # JSON manifest data structure
1161        config_data = {
1162            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1163            manifest_compiler.APP_NAME: "test-app-name",
1164            manifest_compiler.MIN_HEAP: 8192,
1165            manifest_compiler.MIN_STACK: 4096
1166        }
1167
1168        # Pack manifest config_data
1169        # Unpack the binary packed data to JSON text
1170        # Validate unpacked JSON text
1171        self.assertEqual(
1172            manifest_compiler.manifest_data_to_json(config_ref_data),
1173            manifest_compiler.unpack_binary_manifest_to_json(
1174                pack_manifest_config_data(
1175                    self, config_data, log, constants)))
1176
1177    def test_manifest_valid_pack_2(self):
1178        """Test with valid manifest config containing
1179        - UUID
1180        - min_heap and min_stack
1181        - memory mapping entries
1182        Pack the manifest config data and unpack it and
1183        verify it with the expected values
1184        """
1185        constants = {}
1186        log = manifest_compiler.Log()
1187
1188        # Reference JSON manifest data structure
1189        ref_config_data = {
1190            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1191            manifest_compiler.APP_NAME: "test",
1192            manifest_compiler.MIN_HEAP: 8192,
1193            manifest_compiler.MIN_STACK: 4096,
1194            manifest_compiler.MEM_MAP: [
1195                {"id": 1, "addr": "0x70000000", "size": "0x1000",
1196                 "type": "cached", "non_secure": False},
1197                {"id": 2, "addr": "0x70010000", "size": "0x100",
1198                 "type": "uncached", "non_secure": True},
1199                {"id": 3, "addr": "0x70020000", "size": "0x4",
1200                 "type": "uncached_device", "non_secure": False}],
1201            manifest_compiler.MGMT_FLAGS: {
1202                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1203                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1204                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1205            },
1206            manifest_compiler.APPLOADER_FLAGS: {
1207                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1208            }
1209        }
1210
1211        # JSON manifest data structure
1212        config_data = {
1213            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1214            manifest_compiler.MIN_HEAP: 8192,
1215            manifest_compiler.MIN_STACK: 4096,
1216            manifest_compiler.MEM_MAP: [
1217                {"id": 1, "addr": "0x70000000", "size": "0x1000",
1218                 "type": "cached", "non_secure": False},
1219                {"id": 2, "addr": "0x70010000", "size": "0x100",
1220                 "type": "uncached", "non_secure": True},
1221                {"id": 3, "addr": "0x70020000", "size": "0x4"}]
1222        }
1223
1224        # Pack manifest config_data
1225        # Unpack the binary packed data to JSON text
1226        # Validate unpacked JSON text
1227        self.assertEqual(
1228            manifest_compiler.manifest_data_to_json(ref_config_data),
1229            manifest_compiler.unpack_binary_manifest_to_json(
1230                pack_manifest_config_data(
1231                    self, config_data, log, constants)))
1232
1233    def test_manifest_valid_pack_3(self):
1234        """Test with valid manifest config containing
1235        - UUID
1236        - min_heap, min_stack, and min_shadow_stack
1237        - Management flags
1238        Pack the manifest config data and unpack it and
1239        verify it with the expected values
1240        """
1241        constants = {}
1242        log = manifest_compiler.Log()
1243
1244        # JSON manifest data structure
1245        config_data = {
1246            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1247            manifest_compiler.APP_NAME: "test",
1248            manifest_compiler.MIN_HEAP: 8192,
1249            manifest_compiler.MIN_STACK: 4096,
1250            manifest_compiler.MGMT_FLAGS: {
1251                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: True,
1252                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1253                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1254            },
1255            manifest_compiler.APPLOADER_FLAGS: {
1256                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1257            }
1258        }
1259
1260        # Pack manifest config_data
1261        # Unpack the binary packed data to JSON text
1262        # Validate unpacked JSON text
1263        self.assertEqual(
1264            manifest_compiler.manifest_data_to_json(config_data),
1265            manifest_compiler.unpack_binary_manifest_to_json(
1266                pack_manifest_config_data(
1267                    self, config_data, log, constants)))
1268
1269    def test_manifest_valid_pack_4(self):
1270        """Test with valid manifest config containing
1271        - UUID
1272        - min_heap and min_stack
1273        - start_ports
1274        Pack the manifest config data and unpack it and
1275        verify it with the expected values
1276        """
1277        constants = {}
1278        log = manifest_compiler.Log()
1279
1280        # Reference manifest data structure
1281        ref_config_data = {
1282            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1283            manifest_compiler.APP_NAME: "test",
1284            manifest_compiler.MIN_HEAP: 8192,
1285            manifest_compiler.MIN_STACK: 4096,
1286            manifest_compiler.START_PORTS: [
1287                {
1288                    manifest_compiler.START_PORT_NAME:
1289                        "com.android.trusty.appmgmt.loadable.start",
1290                    manifest_compiler.START_PORT_FLAGS: {
1291                        manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
1292                        manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False
1293                    }
1294                }
1295            ],
1296            manifest_compiler.MGMT_FLAGS: {
1297                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1298                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1299                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1300            },
1301            manifest_compiler.APPLOADER_FLAGS: {
1302                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1303            }
1304        }
1305
1306        # JSON manifest data structure
1307        config_data = {
1308            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1309            manifest_compiler.MIN_HEAP: 8192,
1310            manifest_compiler.MIN_STACK: 4096,
1311            manifest_compiler.START_PORTS: [
1312                {
1313                    manifest_compiler.START_PORT_NAME:
1314                        "com.android.trusty.appmgmt.loadable.start",
1315                    manifest_compiler.START_PORT_FLAGS: {
1316                        manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
1317                        manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False
1318                    }
1319                }
1320            ]
1321        }
1322
1323        # Pack manifest config_data
1324        # Unpack the binary packed data to JSON text
1325        # Validate unpacked JSON text
1326        self.assertEqual(
1327            manifest_compiler.manifest_data_to_json(ref_config_data),
1328            manifest_compiler.unpack_binary_manifest_to_json(
1329                pack_manifest_config_data(
1330                    self, config_data, log, constants)))
1331
1332    def test_manifest_valid_pack_5(self):
1333        """Test with valid manifest config with multiple constants configs
1334        - UUID
1335        - start_ports
1336        Pack the manifest config data and unpack it and
1337        verify it with the expected values
1338        """
1339        constants_data = [
1340            {
1341                "header": "port_constants.h",
1342                "constants": [{
1343                    "name": "LOADABLE_START_PORT",
1344                    "value": "com.android.trusty.appmgmt.loadable.start",
1345                    "type": "port"
1346                }]
1347            },
1348            {
1349                "header": "storage_constants.h",
1350                "constants": [{
1351                    "name": "STORAGE_UUID",
1352                    "value": "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1353                    "type": "uuid"
1354                }]
1355            }
1356        ]
1357
1358        log = manifest_compiler.Log()
1359
1360        # Reference manifest data structure
1361        ref_config_data = {
1362            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1363            manifest_compiler.APP_NAME: "test",
1364            manifest_compiler.MIN_HEAP: 8192,
1365            manifest_compiler.MIN_STACK: 4096,
1366            manifest_compiler.START_PORTS: [
1367                {
1368                    manifest_compiler.START_PORT_NAME:
1369                        "com.android.trusty.appmgmt.loadable.start",
1370                    manifest_compiler.START_PORT_FLAGS: {
1371                        manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
1372                        manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False
1373                    }
1374                }
1375            ],
1376            manifest_compiler.MGMT_FLAGS: {
1377                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1378                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1379                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1380            },
1381            manifest_compiler.APPLOADER_FLAGS: {
1382                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1383            }
1384        }
1385
1386        # JSON manifest data structure
1387        config_data = {
1388            manifest_compiler.UUID: "STORAGE_UUID",
1389            manifest_compiler.MIN_HEAP: 8192,
1390            manifest_compiler.MIN_STACK: 4096,
1391            manifest_compiler.START_PORTS: [
1392                {
1393                    manifest_compiler.START_PORT_NAME:
1394                        "LOADABLE_START_PORT",
1395                    manifest_compiler.START_PORT_FLAGS: {
1396                        manifest_compiler.START_PORT_ALLOW_TA_CONNECT: True,
1397                        manifest_compiler.START_PORT_ALLOW_NS_CONNECT: False
1398                    }
1399                }
1400            ]
1401        }
1402
1403        conf_constants = manifest_compiler.extract_config_constants(
1404            constants_data, log)
1405        constants = manifest_compiler.index_constants(conf_constants)
1406
1407        # Pack manifest config_data
1408        # Unpack the binary packed data to JSON text
1409        # Validate unpacked JSON text
1410        self.assertEqual(
1411            manifest_compiler.manifest_data_to_json(ref_config_data),
1412            manifest_compiler.unpack_binary_manifest_to_json(
1413                pack_manifest_config_data(
1414                    self, config_data, log, constants)))
1415
1416    def test_manifest_valid_pack_6(self):
1417        """Test with valid manifest config containing
1418        - UUID
1419        - min_heap and min_stack
1420        - pinned_cpu
1421        Pack the manifest config data and unpack it and
1422        verify it with the expected values
1423        """
1424        # PLZ DON'T EDIT VALUES
1425        constants = {}
1426        log = manifest_compiler.Log()
1427
1428        # Reference JSON manifest data structure
1429        config_ref_data = {
1430            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1431            manifest_compiler.APP_NAME: "test-app-name",
1432            manifest_compiler.MIN_HEAP: 8192,
1433            manifest_compiler.MIN_STACK: 4096,
1434            manifest_compiler.MGMT_FLAGS: {
1435                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1436                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1437                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1438            },
1439            manifest_compiler.APPLOADER_FLAGS: {
1440                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1441            },
1442            manifest_compiler.PINNED_CPU: 3
1443        }
1444
1445        # JSON manifest data structure
1446        config_data = {
1447            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1448            manifest_compiler.APP_NAME: "test-app-name",
1449            manifest_compiler.MIN_HEAP: 8192,
1450            manifest_compiler.MIN_STACK: 4096,
1451            manifest_compiler.PINNED_CPU: 3
1452        }
1453
1454        # Pack manifest config_data
1455        # Unpack the binary packed data to JSON text
1456        # Validate unpacked JSON text
1457        self.assertEqual(
1458            manifest_compiler.manifest_data_to_json(config_ref_data),
1459            manifest_compiler.unpack_binary_manifest_to_json(
1460                pack_manifest_config_data(
1461                    self, config_data, log, constants)))
1462
1463    def test_manifest_valid_pack_7(self):
1464        """Test with valid manifest config with a constants config containing
1465        - UUID
1466        - min_heap and min_stack
1467        - pinned_cpu
1468        Pack the manifest config data and unpack it and
1469        verify it with the expected values
1470        """
1471        constants_data = [{
1472            "header": "cpu_constants.h",
1473            "constants": [{
1474                "name": "CPU_NUM",
1475                "value": 3,
1476                "type": "int",
1477                "unsigned": True
1478            }]
1479        }]
1480
1481        log = manifest_compiler.Log()
1482
1483        # Reference JSON manifest data structure
1484        config_ref_data = {
1485            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1486            manifest_compiler.APP_NAME: "test-app-name",
1487            manifest_compiler.MIN_HEAP: 8192,
1488            manifest_compiler.MIN_STACK: 4096,
1489            manifest_compiler.MGMT_FLAGS: {
1490                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1491                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1492                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1493            },
1494            manifest_compiler.APPLOADER_FLAGS: {
1495                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1496            },
1497            manifest_compiler.PINNED_CPU: 3
1498        }
1499
1500        # JSON manifest data structure
1501        config_data = {
1502            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1503            manifest_compiler.APP_NAME: "test-app-name",
1504            manifest_compiler.MIN_HEAP: 8192,
1505            manifest_compiler.MIN_STACK: 4096,
1506            manifest_compiler.PINNED_CPU: "CPU_NUM"
1507        }
1508
1509        conf_constants = manifest_compiler.extract_config_constants(
1510            constants_data, log)
1511        constants = manifest_compiler.index_constants(conf_constants)
1512
1513        # Pack manifest config_data
1514        # Unpack the binary packed data to JSON text
1515        # Validate unpacked JSON text
1516        self.assertEqual(
1517            manifest_compiler.manifest_data_to_json(config_ref_data),
1518            manifest_compiler.unpack_binary_manifest_to_json(
1519                pack_manifest_config_data(
1520                    self, config_data, log, constants)))
1521
1522    def test_manifest_valid_pack_8(self):
1523        """Test with valid manifest config with a constants config containing
1524        - UUID
1525        - min_heap, min_stack, and min_shadow_stack
1526        - version
1527        Pack the manifest config data and unpack it and
1528        verify it with the expected values
1529        """
1530        constants_data = [{
1531            "header": "constants.h",
1532            "constants": [{
1533                "name": "VERSION",
1534                "value": 1,
1535                "type": "int",
1536                "unsigned": True
1537            },
1538                {
1539                    "name": "PAGE_SIZE",
1540                    "value": 4096,
1541                    "type": "int",
1542                    "unsigned": True
1543                }]
1544        }]
1545
1546        log = manifest_compiler.Log()
1547
1548        # Reference JSON manifest data structure
1549        config_ref_data = {
1550            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1551            manifest_compiler.APP_NAME: "test-app-name",
1552            manifest_compiler.MIN_HEAP: 8192,
1553            manifest_compiler.MIN_STACK: 4096,
1554            manifest_compiler.VERSION: 1,
1555            manifest_compiler.MIN_SHADOW_STACK: 4096,
1556            manifest_compiler.MGMT_FLAGS: {
1557                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1558                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1559                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1560            },
1561            manifest_compiler.APPLOADER_FLAGS: {
1562                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1563            }
1564        }
1565
1566        # JSON manifest data structure
1567        config_data = {
1568            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1569            manifest_compiler.APP_NAME: "test-app-name",
1570            manifest_compiler.MIN_HEAP: 8192,
1571            manifest_compiler.MIN_STACK: 4096,
1572            manifest_compiler.VERSION: "VERSION",
1573            manifest_compiler.MIN_SHADOW_STACK: "PAGE_SIZE",
1574        }
1575
1576        conf_constants = manifest_compiler.extract_config_constants(
1577            constants_data, log)
1578        constants = manifest_compiler.index_constants(conf_constants)
1579
1580        # Pack manifest config_data
1581        # Unpack the binary packed data to JSON text
1582        # Validate unpacked JSON text
1583        self.assertEqual(
1584            manifest_compiler.manifest_data_to_json(config_ref_data),
1585            manifest_compiler.unpack_binary_manifest_to_json(
1586                pack_manifest_config_data(
1587                    self, config_data, log, constants)))
1588
1589    def test_manifest_valid_pack_9(self):
1590        """Test with valid manifest config with a constants config containing
1591        - UUID
1592        - min_heap, min_stack
1593        - priority
1594        - apploader_flags
1595        Pack the manifest config data and unpack it and
1596        verify it with the expected values
1597        """
1598        constants_data = [{
1599            "header": "constants.h",
1600            "constants": [{
1601                "name": "REQUIRES_ENCRYPTION",
1602                "value": True,
1603                "type": "bool",
1604            }]
1605        }]
1606
1607        log = manifest_compiler.Log()
1608
1609        # Reference JSON manifest data structure
1610        config_ref_data = {
1611            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1612            manifest_compiler.APP_NAME: "test-app-name",
1613            manifest_compiler.MIN_HEAP: 8192,
1614            manifest_compiler.MIN_STACK: 4096,
1615            manifest_compiler.MGMT_FLAGS: {
1616                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1617                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1618                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1619            },
1620            manifest_compiler.PRIORITY: 10,
1621            manifest_compiler.APPLOADER_FLAGS: {
1622                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: True,
1623            }
1624        }
1625
1626        # JSON manifest data structure
1627        config_data = {
1628            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1629            manifest_compiler.APP_NAME: "test-app-name",
1630            manifest_compiler.MIN_HEAP: 8192,
1631            manifest_compiler.MIN_STACK: 4096,
1632            manifest_compiler.PRIORITY: 10,
1633            manifest_compiler.APPLOADER_FLAGS: {
1634                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION:
1635                    "REQUIRES_ENCRYPTION",
1636            }
1637        }
1638
1639        conf_constants = manifest_compiler.extract_config_constants(
1640            constants_data, log)
1641        constants = manifest_compiler.index_constants(conf_constants)
1642
1643        # Pack manifest config_data
1644        # Unpack the binary packed data to JSON text
1645        # Validate unpacked JSON text
1646        self.assertEqual(
1647            manifest_compiler.manifest_data_to_json(config_ref_data),
1648            manifest_compiler.unpack_binary_manifest_to_json(
1649                pack_manifest_config_data(
1650                    self, config_data, log, constants)))
1651
1652    def test_manifest_empty_priority(self):
1653        """Test with valid manifest config containing
1654        - UUID
1655        - min_heap and min_stack
1656        - pinned_cpu
1657        - priority empty
1658
1659        Pack the manifest config data and unpack it and
1660        verify it with the expected values
1661        """
1662        constants = {}
1663        log = manifest_compiler.Log()
1664
1665        # JSON manifest data structure
1666        config_data = {
1667            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1668            manifest_compiler.APP_NAME: "test-app-name",
1669            manifest_compiler.MIN_HEAP: 8192,
1670            manifest_compiler.MIN_STACK: 4096,
1671            manifest_compiler.PINNED_CPU: 3,
1672            manifest_compiler.PRIORITY: None,
1673        }
1674
1675        default_app_name = "test"
1676
1677        manifest = manifest_compiler.parse_manifest_config(
1678            config_data,
1679            constants,
1680            default_app_name,
1681            log
1682        )
1683        self.assertTrue(log.error_occurred())
1684        self.assertIsNone(manifest)
1685
1686    def test_manifest_good_version(self):
1687        """Test with valid manifest config containing
1688        - UUID
1689        - min_heap and min_stack
1690        - version
1691        - min_version
1692        - flags
1693
1694        Pack the manifest config data and unpack it and
1695        verify it with the expected values
1696        """
1697        constants = {}
1698        log = manifest_compiler.Log()
1699
1700        # JSON manifest data structure
1701        config_data = {
1702            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1703            manifest_compiler.APP_NAME: "test-app-name",
1704            manifest_compiler.MIN_HEAP: 8192,
1705            manifest_compiler.MIN_STACK: 4096,
1706            manifest_compiler.VERSION: 5,
1707            manifest_compiler.MIN_VERSION: 2,
1708            manifest_compiler.MGMT_FLAGS: {
1709                manifest_compiler.MGMT_FLAG_RESTART_ON_EXIT: False,
1710                manifest_compiler.MGMT_FLAG_DEFERRED_START: False,
1711                manifest_compiler.MGMT_FLAG_NON_CRITICAL_APP: False
1712            },
1713            manifest_compiler.APPLOADER_FLAGS: {
1714                manifest_compiler.APPLOADER_FLAGS_REQUIRES_ENCRYPTION: False,
1715            }
1716        }
1717
1718        # Pack manifest config_data
1719        # Unpack the binary packed data to JSON text
1720        # Validate unpacked JSON text
1721        self.assertEqual(
1722            manifest_compiler.manifest_data_to_json(config_data),
1723            manifest_compiler.unpack_binary_manifest_to_json(
1724                pack_manifest_config_data(
1725                    self, config_data, log, constants)))
1726
1727    def test_manifest_bad_version_1(self):
1728        """Test with valid manifest config containing
1729        - UUID
1730        - min_heap and min_stack
1731        - pinned_cpu
1732        - version empty
1733        - min_version
1734
1735        Pack the manifest config data and unpack it and
1736        verify it with the expected values
1737        """
1738        constants = {}
1739        log = manifest_compiler.Log()
1740
1741        # JSON manifest data structure
1742        config_data = {
1743            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1744            manifest_compiler.APP_NAME: "test-app-name",
1745            manifest_compiler.MIN_HEAP: 8192,
1746            manifest_compiler.MIN_STACK: 4096,
1747            manifest_compiler.VERSION: None,
1748            manifest_compiler.MIN_VERSION: 1,
1749        }
1750
1751        default_app_name = "test"
1752
1753        manifest = manifest_compiler.parse_manifest_config(
1754            config_data,
1755            constants,
1756            default_app_name,
1757            log
1758        )
1759        self.assertTrue(log.error_occurred())
1760        self.assertIsNone(manifest)
1761
1762    def test_manifest_bad_version_2(self):
1763        """Test with valid manifest config containing
1764        - UUID
1765        - min_heap and min_stack
1766        - pinned_cpu
1767        - version empty
1768        - min_version
1769
1770        Pack the manifest config data and unpack it and
1771        verify it with the expected values
1772        """
1773        constants = {}
1774        log = manifest_compiler.Log()
1775
1776        # JSON manifest data structure
1777        config_data = {
1778            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1779            manifest_compiler.APP_NAME: "test-app-name",
1780            manifest_compiler.MIN_HEAP: 8192,
1781            manifest_compiler.MIN_STACK: 4096,
1782            manifest_compiler.VERSION: 1,
1783            manifest_compiler.MIN_VERSION: 2,
1784        }
1785
1786        default_app_name = "test"
1787
1788        manifest = manifest_compiler.parse_manifest_config(
1789            config_data,
1790            constants,
1791            default_app_name,
1792            log
1793        )
1794        self.assertTrue(log.error_occurred())
1795        self.assertIsNone(manifest)
1796
1797    def test_manifest_overlay_1(self):
1798        """Test with two manifest configs (main + overlay)
1799        Main manifest contains the following entries
1800        - UUID, app_name
1801        - min_heap, min_stack
1802        - version
1803        - mem_maps with 2 entries
1804        Overlay manifest contains overlay min_heap
1805        and two more mem_maps entries, one of which is
1806        skipped as duplicate, another one is added to
1807        mem_maps from main manifest
1808
1809        Check correctness of merging procedure
1810        """
1811        log = manifest_compiler.Log()
1812
1813        # JSON manifest data structure
1814        main_manifest_data = {
1815            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1816            manifest_compiler.APP_NAME: "test-app-name",
1817            manifest_compiler.MIN_HEAP: 8192,
1818            manifest_compiler.MIN_STACK: 4096,
1819            manifest_compiler.VERSION: 1,
1820            manifest_compiler.MEM_MAP: [
1821                {"id": 1, "addr": "0x70000000", "size": "0x1000",
1822                 "type": "cached", "non_secure": False},
1823                {"id": 2, "addr": "0x70010000", "size": "0x100",
1824                 "type": "uncached", "non_secure": True}]
1825        }
1826        overlay_manifest_data = {
1827            manifest_compiler.MIN_HEAP: 1000,
1828            manifest_compiler.MEM_MAP: [
1829                {"id": 2, "addr": "0x70010000", "size": "0x100",
1830                 "type": "uncached", "non_secure": True},
1831                {"id": 3, "addr": "0x70020000", "size": "0x4"}]
1832        }
1833
1834        # Reference JSON manifest data structure
1835        manifest_ref_data = {
1836            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1837            manifest_compiler.APP_NAME: "test-app-name",
1838            manifest_compiler.MIN_HEAP: 1000, # from overlay
1839            manifest_compiler.MIN_STACK: 4096,
1840            manifest_compiler.VERSION: 1,
1841            manifest_compiler.MEM_MAP: [
1842                {"id": 1, "addr": "0x70000000", "size": "0x1000", # from main
1843                 "type": "cached", "non_secure": False},
1844                {"id": 2, "addr": "0x70010000", "size": "0x100", # from main
1845                 "type": "uncached", "non_secure": True},
1846                {"id": 3, "addr": "0x70020000", "size": "0x4"}] # from overlay
1847        }
1848
1849        merged_manifest_data = manifest_compiler.merge_manifest_dicts(
1850            [main_manifest_data, overlay_manifest_data], log)
1851
1852        self.assertFalse(log.error_occurred())
1853        self.assertEqual(
1854            manifest_compiler.manifest_data_to_json(manifest_ref_data),
1855            manifest_compiler.manifest_data_to_json(merged_manifest_data))
1856
1857    def test_manifest_overlay_2(self):
1858        """Test with two conflicting manifest configs (main + overlay)
1859        Manifest merge should fail because main and overlay
1860        manifests have different data types to merge.
1861        """
1862        log = manifest_compiler.Log()
1863
1864        # JSON manifest data structure
1865        main_manifest_data = {
1866            manifest_compiler.UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf",
1867            manifest_compiler.APP_NAME: "test-app-name",
1868            manifest_compiler.MIN_HEAP: 8192,
1869            manifest_compiler.MIN_STACK: 4096,
1870            manifest_compiler.VERSION: 1,
1871            manifest_compiler.MEM_MAP: [
1872                {"id": 1, "addr": "0x70000000", "size": "0x1000",
1873                 "type": "cached", "non_secure": False},
1874                {"id": 2, "addr": "0x70010000", "size": "0x100",
1875                 "type": "uncached", "non_secure": True}]
1876        }
1877        overlay_manifest_data = {
1878            manifest_compiler.MIN_HEAP: 1000,
1879            manifest_compiler.MEM_MAP: 25 # conflicting types, scalar vs list
1880        }
1881
1882        merged_manifest_data = manifest_compiler.merge_manifest_dicts(
1883            [main_manifest_data, overlay_manifest_data], log)
1884
1885        self.assertTrue(log.error_occurred())
1886        self.assertIsNone(merged_manifest_data)
1887
1888def pack_manifest_config_data(self, config_data, log, constants):
1889    # parse manifest JSON data
1890    default_app_name = "test"
1891    manifest = manifest_compiler.parse_manifest_config(config_data, constants,
1892                                                       default_app_name, log)
1893    self.assertFalse(log.error_occurred())
1894
1895    # pack manifest config data
1896    packed_data = manifest_compiler.pack_manifest_data(manifest)
1897    self.assertEqual(len(config_data), 0)
1898    self.assertFalse(log.error_occurred())
1899    self.assertIsNotNone(packed_data)
1900
1901    return packed_data
1902
1903
1904if __name__ == "__main__":
1905    unittest.main()
1906