Home | History | Annotate | Download | only in fs_config
      1 #!/usr/bin/env python
      2 """Unit test suite for the fs_config_genertor.py tool."""
      3 
      4 import tempfile
      5 import textwrap
      6 import unittest
      7 
      8 from fs_config_generator import AID
      9 from fs_config_generator import AIDHeaderParser
     10 from fs_config_generator import FSConfigFileParser
     11 from fs_config_generator import FSConfig
     12 from fs_config_generator import Utils
     13 
     14 
     15 # Disable protected access so we can test class internal
     16 # methods. Also, disable invalid-name as some of the
     17 # class method names are over length.
     18 # pylint: disable=protected-access,invalid-name
     19 class Tests(unittest.TestCase):
     20     """Test class for unit tests"""
     21 
     22     def test_is_overlap(self):
     23         """Test overlap detection helper"""
     24 
     25         self.assertTrue(AIDHeaderParser._is_overlap((0, 1), (1, 2)))
     26 
     27         self.assertTrue(AIDHeaderParser._is_overlap((0, 100), (90, 200)))
     28 
     29         self.assertTrue(AIDHeaderParser._is_overlap((20, 50), (1, 101)))
     30 
     31         self.assertFalse(AIDHeaderParser._is_overlap((0, 100), (101, 200)))
     32 
     33         self.assertFalse(AIDHeaderParser._is_overlap((-10, 0), (10, 20)))
     34 
     35     def test_in_any_range(self):
     36         """Test if value in range"""
     37 
     38         self.assertFalse(Utils.in_any_range(50, [(100, 200), (1, 2), (1, 1)]))
     39         self.assertFalse(Utils.in_any_range(250, [(100, 200), (1, 2), (1, 1)]))
     40 
     41         self.assertTrue(Utils.in_any_range(100, [(100, 200), (1, 2), (1, 1)]))
     42         self.assertTrue(Utils.in_any_range(200, [(100, 200), (1, 2), (1, 1)]))
     43         self.assertTrue(Utils.in_any_range(150, [(100, 200)]))
     44 
     45     def test_aid(self):
     46         """Test AID class constructor"""
     47 
     48         aid = AID('AID_FOO_BAR', '0xFF', 'myfakefile')
     49         self.assertEquals(aid.identifier, 'AID_FOO_BAR')
     50         self.assertEquals(aid.value, '0xFF')
     51         self.assertEquals(aid.found, 'myfakefile')
     52         self.assertEquals(aid.normalized_value, '255')
     53         self.assertEquals(aid.friendly, 'foo_bar')
     54 
     55         aid = AID('AID_MEDIA_EX', '1234', 'myfakefile')
     56         self.assertEquals(aid.identifier, 'AID_MEDIA_EX')
     57         self.assertEquals(aid.value, '1234')
     58         self.assertEquals(aid.found, 'myfakefile')
     59         self.assertEquals(aid.normalized_value, '1234')
     60         self.assertEquals(aid.friendly, 'mediaex')
     61 
     62     def test_aid_header_parser_good(self):
     63         """Test AID Header Parser good input file"""
     64 
     65         with tempfile.NamedTemporaryFile() as temp_file:
     66             temp_file.write(
     67                 textwrap.dedent("""
     68                 #define AID_FOO 1000
     69                 #define AID_BAR 1001
     70                 #define SOMETHING "something"
     71                 #define AID_OEM_RESERVED_START 2900
     72                 #define AID_OEM_RESERVED_END   2999
     73                 #define AID_OEM_RESERVED_1_START  7000
     74                 #define AID_OEM_RESERVED_1_END    8000
     75             """))
     76             temp_file.flush()
     77 
     78             parser = AIDHeaderParser(temp_file.name)
     79             oem_ranges = parser.oem_ranges
     80             aids = parser.aids
     81 
     82             self.assertTrue((2900, 2999) in oem_ranges)
     83             self.assertFalse((5000, 6000) in oem_ranges)
     84 
     85             for aid in aids:
     86                 self.assertTrue(aid.normalized_value in ['1000', '1001'])
     87                 self.assertFalse(aid.normalized_value in ['1', '2', '3'])
     88 
     89     def test_aid_header_parser_good_unordered(self):
     90         """Test AID Header Parser good unordered input file"""
     91 
     92         with tempfile.NamedTemporaryFile() as temp_file:
     93             temp_file.write(
     94                 textwrap.dedent("""
     95                 #define AID_FOO 1000
     96                 #define AID_OEM_RESERVED_1_END    8000
     97                 #define AID_BAR 1001
     98                 #define SOMETHING "something"
     99                 #define AID_OEM_RESERVED_END   2999
    100                 #define AID_OEM_RESERVED_1_START  7000
    101                 #define AID_OEM_RESERVED_START 2900
    102             """))
    103             temp_file.flush()
    104 
    105             parser = AIDHeaderParser(temp_file.name)
    106             oem_ranges = parser.oem_ranges
    107             aids = parser.aids
    108 
    109             self.assertTrue((2900, 2999) in oem_ranges)
    110             self.assertFalse((5000, 6000) in oem_ranges)
    111 
    112             for aid in aids:
    113                 self.assertTrue(aid.normalized_value in ['1000', '1001'])
    114                 self.assertFalse(aid.normalized_value in ['1', '2', '3'])
    115 
    116     def test_aid_header_parser_bad_aid(self):
    117         """Test AID Header Parser bad aid input file"""
    118 
    119         with tempfile.NamedTemporaryFile() as temp_file:
    120             temp_file.write(
    121                 textwrap.dedent("""
    122                 #define AID_FOO "bad"
    123             """))
    124             temp_file.flush()
    125 
    126             with self.assertRaises(SystemExit):
    127                 AIDHeaderParser(temp_file.name)
    128 
    129     def test_aid_header_parser_bad_oem_range(self):
    130         """Test AID Header Parser bad oem range input file"""
    131 
    132         with tempfile.NamedTemporaryFile() as temp_file:
    133             temp_file.write(
    134                 textwrap.dedent("""
    135                 #define AID_OEM_RESERVED_START 2900
    136                 #define AID_OEM_RESERVED_END   1800
    137             """))
    138             temp_file.flush()
    139 
    140             with self.assertRaises(SystemExit):
    141                 AIDHeaderParser(temp_file.name)
    142 
    143     def test_aid_header_parser_bad_oem_range_no_end(self):
    144         """Test AID Header Parser bad oem range (no end) input file"""
    145 
    146         with tempfile.NamedTemporaryFile() as temp_file:
    147             temp_file.write(
    148                 textwrap.dedent("""
    149                 #define AID_OEM_RESERVED_START 2900
    150             """))
    151             temp_file.flush()
    152 
    153             with self.assertRaises(SystemExit):
    154                 AIDHeaderParser(temp_file.name)
    155 
    156     def test_aid_header_parser_bad_oem_range_no_start(self):
    157         """Test AID Header Parser bad oem range (no start) input file"""
    158 
    159         with tempfile.NamedTemporaryFile() as temp_file:
    160             temp_file.write(
    161                 textwrap.dedent("""
    162                 #define AID_OEM_RESERVED_END 2900
    163             """))
    164             temp_file.flush()
    165 
    166             with self.assertRaises(SystemExit):
    167                 AIDHeaderParser(temp_file.name)
    168 
    169     def test_aid_header_parser_bad_oem_range_mismatch_start_end(self):
    170         """Test AID Header Parser bad oem range mismatched input file"""
    171 
    172         with tempfile.NamedTemporaryFile() as temp_file:
    173             temp_file.write(
    174                 textwrap.dedent("""
    175                 #define AID_OEM_RESERVED_START 2900
    176                 #define AID_OEM_RESERVED_2_END 2900
    177             """))
    178             temp_file.flush()
    179 
    180             with self.assertRaises(SystemExit):
    181                 AIDHeaderParser(temp_file.name)
    182 
    183     def test_aid_header_parser_bad_duplicate_ranges(self):
    184         """Test AID Header Parser exits cleanly on duplicate AIDs"""
    185 
    186         with tempfile.NamedTemporaryFile() as temp_file:
    187             temp_file.write(
    188                 textwrap.dedent("""
    189                 #define AID_FOO 100
    190                 #define AID_BAR 100
    191             """))
    192             temp_file.flush()
    193 
    194             with self.assertRaises(SystemExit):
    195                 AIDHeaderParser(temp_file.name)
    196 
    197     def test_aid_header_parser_no_bad_aids(self):
    198         """Test AID Header Parser that it doesn't contain:
    199         Ranges, ie things the end with "_START" or "_END"
    200         AID_APP
    201         AID_USER
    202         For more details see:
    203           - https://android-review.googlesource.com/#/c/313024
    204           - https://android-review.googlesource.com/#/c/313169
    205         """
    206 
    207         with tempfile.NamedTemporaryFile() as temp_file:
    208             temp_file.write(
    209                 textwrap.dedent("""
    210                 #define AID_APP              10000 /* TODO: switch users over to AID_APP_START */
    211                 #define AID_APP_START        10000 /* first app user */
    212                 #define AID_APP_END          19999 /* last app user */
    213 
    214                 #define AID_CACHE_GID_START  20000 /* start of gids for apps to mark cached data */
    215                 #define AID_CACHE_GID_END    29999 /* end of gids for apps to mark cached data */
    216 
    217                 #define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
    218                 #define AID_SHARED_GID_END   59999 /* end of gids for apps in each user to share */
    219 
    220                 #define AID_ISOLATED_START   99000 /* start of uids for fully isolated sandboxed processes */
    221                 #define AID_ISOLATED_END     99999 /* end of uids for fully isolated sandboxed processes */
    222 
    223                 #define AID_USER            100000 /* TODO: switch users over to AID_USER_OFFSET */
    224                 #define AID_USER_OFFSET     100000 /* offset for uid ranges for each user */
    225             """))
    226             temp_file.flush()
    227 
    228             parser = AIDHeaderParser(temp_file.name)
    229             aids = parser.aids
    230 
    231             bad_aids = ['_START', '_END', 'AID_APP', 'AID_USER']
    232 
    233             for aid in aids:
    234                 self.assertFalse(
    235                     any(bad in aid.identifier for bad in bad_aids),
    236                     'Not expecting keywords "%s" in aids "%s"' %
    237                     (str(bad_aids), str([tmp.identifier for tmp in aids])))
    238 
    239     def test_fs_config_file_parser_good(self):
    240         """Test FSConfig Parser good input file"""
    241 
    242         with tempfile.NamedTemporaryFile() as temp_file:
    243             temp_file.write(
    244                 textwrap.dedent("""
    245                 [/system/bin/file]
    246                 user: AID_FOO
    247                 group: AID_SYSTEM
    248                 mode: 0777
    249                 caps: BLOCK_SUSPEND
    250 
    251                 [/vendor/path/dir/]
    252                 user: AID_FOO
    253                 group: AID_SYSTEM
    254                 mode: 0777
    255                 caps: 0
    256 
    257                 [AID_OEM1]
    258                 # 5001 in base16
    259                 value: 0x1389
    260             """))
    261             temp_file.flush()
    262 
    263             parser = FSConfigFileParser([temp_file.name], [(5000, 5999)])
    264             files = parser.files
    265             dirs = parser.dirs
    266             aids = parser.aids
    267 
    268             self.assertEquals(len(files), 1)
    269             self.assertEquals(len(dirs), 1)
    270             self.assertEquals(len(aids), 1)
    271 
    272             aid = aids[0]
    273             fcap = files[0]
    274             dcap = dirs[0]
    275 
    276             self.assertEqual(fcap,
    277                              FSConfig('0777', 'AID_FOO', 'AID_SYSTEM',
    278                                       '(1ULL << CAP_BLOCK_SUSPEND)',
    279                                       '/system/bin/file', temp_file.name))
    280 
    281             self.assertEqual(dcap,
    282                              FSConfig('0777', 'AID_FOO', 'AID_SYSTEM', '(0)',
    283                                       '/vendor/path/dir/', temp_file.name))
    284 
    285             self.assertEqual(aid, AID('AID_OEM1', '0x1389', temp_file.name))
    286 
    287     def test_fs_config_file_parser_bad(self):
    288         """Test FSConfig Parser bad input file"""
    289 
    290         with tempfile.NamedTemporaryFile() as temp_file:
    291             temp_file.write(
    292                 textwrap.dedent("""
    293                 [/system/bin/file]
    294                 caps: BLOCK_SUSPEND
    295             """))
    296             temp_file.flush()
    297 
    298             with self.assertRaises(SystemExit):
    299                 FSConfigFileParser([temp_file.name], [(5000, 5999)])
    300 
    301     def test_fs_config_file_parser_bad_aid_range(self):
    302         """Test FSConfig Parser bad aid range value input file"""
    303 
    304         with tempfile.NamedTemporaryFile() as temp_file:
    305             temp_file.write(
    306                 textwrap.dedent("""
    307                 [AID_OEM1]
    308                 value: 25
    309             """))
    310             temp_file.flush()
    311 
    312             with self.assertRaises(SystemExit):
    313                 FSConfigFileParser([temp_file.name], [(5000, 5999)])
    314