diff --git a/tools/fs_config/README b/tools/fs_config/README index c50c0560f..d884e3276 100644 --- a/tools/fs_config/README +++ b/tools/fs_config/README @@ -124,3 +124,19 @@ For OEMs wishing to use the define AIDs in their native code, one can access the file like so: 1. In your C code just #include "generated_oem_aid.h" and start using the declared identifiers. 2. In your Makefile add this static library like so: LOCAL_STATIC_LIBRARIES := liboemaids + +Unit Tests: + +From within the fs_config directory, unit tests can be executed like so: +$ python -m unittest test_fs_config_generator.Tests +............. +---------------------------------------------------------------------- +Ran 13 tests in 0.004s + +OK + +One could also use nose if they would like: +$ nose2 + +To add new tests, simply add a test_ method to the test class. It will automatically +get picked up and added to the test suite. diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py index d46db9fad..86096574d 100755 --- a/tools/fs_config/fs_config_generator.py +++ b/tools/fs_config/fs_config_generator.py @@ -158,6 +158,12 @@ class AID(object): friendly = identifier[len(AID.PREFIX):].lower() self.friendly = AID._fixup_friendly(friendly) + def __eq__(self, other): + + return self.identifier == other.identifier \ + and self.value == other.value and self.found == other.found \ + and self.normalized_value == other.normalized_value + @staticmethod def is_friendly(name): """Determines if an AID is a freindly name or C define. @@ -218,6 +224,12 @@ class FSConfig(object): self.path = path self.filename = filename + def __eq__(self, other): + + return self.mode == other.mode and self.user == other.user \ + and self.group == other.group and self.caps == other.caps \ + and self.path == other.path and self.filename == other.filename + class AIDHeaderParser(object): """Parses an android_filesystem_config.h file. diff --git a/tools/fs_config/test_fs_config_generator.py b/tools/fs_config/test_fs_config_generator.py new file mode 100755 index 000000000..a911aaee0 --- /dev/null +++ b/tools/fs_config/test_fs_config_generator.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python +"""Unit test suite for the fs_config_genertor.py tool.""" + +import tempfile +import textwrap +import unittest + +from fs_config_generator import AID +from fs_config_generator import AIDHeaderParser +from fs_config_generator import FSConfigFileParser +from fs_config_generator import FSConfig +from fs_config_generator import Utils + + +# Disable protected access so we can test class internal +# methods. Also, disable invalid-name as some of the +# class method names are over length. +# pylint: disable=protected-access,invalid-name +class Tests(unittest.TestCase): + """Test class for unit tests""" + + def test_is_overlap(self): + """Test overlap detection helper""" + + self.assertTrue(AIDHeaderParser._is_overlap((0, 1), (1, 2))) + + self.assertTrue(AIDHeaderParser._is_overlap((0, 100), (90, 200))) + + self.assertTrue(AIDHeaderParser._is_overlap((20, 50), (1, 101))) + + self.assertFalse(AIDHeaderParser._is_overlap((0, 100), (101, 200))) + + self.assertFalse(AIDHeaderParser._is_overlap((-10, 0), (10, 20))) + + def test_in_any_range(self): + """Test if value in range""" + + self.assertFalse(Utils.in_any_range(50, [(100, 200), (1, 2), (1, 1)])) + self.assertFalse(Utils.in_any_range(250, [(100, 200), (1, 2), (1, 1)])) + + self.assertTrue(Utils.in_any_range(100, [(100, 200), (1, 2), (1, 1)])) + self.assertTrue(Utils.in_any_range(200, [(100, 200), (1, 2), (1, 1)])) + self.assertTrue(Utils.in_any_range(150, [(100, 200)])) + + def test_aid(self): + """Test AID class constructor""" + + aid = AID('AID_FOO_BAR', '0xFF', 'myfakefile') + self.assertEquals(aid.identifier, 'AID_FOO_BAR') + self.assertEquals(aid.value, '0xFF') + self.assertEquals(aid.found, 'myfakefile') + self.assertEquals(aid.normalized_value, '255') + self.assertEquals(aid.friendly, 'foo_bar') + + aid = AID('AID_MEDIA_EX', '1234', 'myfakefile') + self.assertEquals(aid.identifier, 'AID_MEDIA_EX') + self.assertEquals(aid.value, '1234') + self.assertEquals(aid.found, 'myfakefile') + self.assertEquals(aid.normalized_value, '1234') + self.assertEquals(aid.friendly, 'mediaex') + + def test_aid_header_parser_good(self): + """Test AID Header Parser good input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + #define AID_FOO 1000 + #define AID_BAR 1001 + #define SOMETHING "something" + #define AID_OEM_RESERVED_START 2900 + #define AID_OEM_RESERVED_END 2999 + #define AID_OEM_RESERVED_1_START 7000 + #define AID_OEM_RESERVED_1_END 8000 + """)) + temp_file.flush() + + parser = AIDHeaderParser(temp_file.name) + oem_ranges = parser.oem_ranges + aids = parser.aids + + self.assertTrue((2900, 2999) in oem_ranges) + self.assertFalse((5000, 6000) in oem_ranges) + + for aid in aids: + self.assertTrue(aid.normalized_value in ['1000', '1001']) + self.assertFalse(aid.normalized_value in ['1', '2', '3']) + + def test_aid_header_parser_good_unordered(self): + """Test AID Header Parser good unordered input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + #define AID_FOO 1000 + #define AID_OEM_RESERVED_1_END 8000 + #define AID_BAR 1001 + #define SOMETHING "something" + #define AID_OEM_RESERVED_END 2999 + #define AID_OEM_RESERVED_1_START 7000 + #define AID_OEM_RESERVED_START 2900 + """)) + temp_file.flush() + + parser = AIDHeaderParser(temp_file.name) + oem_ranges = parser.oem_ranges + aids = parser.aids + + self.assertTrue((2900, 2999) in oem_ranges) + self.assertFalse((5000, 6000) in oem_ranges) + + for aid in aids: + self.assertTrue(aid.normalized_value in ['1000', '1001']) + self.assertFalse(aid.normalized_value in ['1', '2', '3']) + + def test_aid_header_parser_bad_aid(self): + """Test AID Header Parser bad aid input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + #define AID_FOO "bad" + """)) + temp_file.flush() + + with self.assertRaises(SystemExit): + AIDHeaderParser(temp_file.name) + + def test_aid_header_parser_bad_oem_range(self): + """Test AID Header Parser bad oem range input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + #define AID_OEM_RESERVED_START 2900 + #define AID_OEM_RESERVED_END 1800 + """)) + temp_file.flush() + + with self.assertRaises(SystemExit): + AIDHeaderParser(temp_file.name) + + def test_aid_header_parser_bad_oem_range_no_end(self): + """Test AID Header Parser bad oem range (no end) input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + #define AID_OEM_RESERVED_START 2900 + """)) + temp_file.flush() + + with self.assertRaises(SystemExit): + AIDHeaderParser(temp_file.name) + + def test_aid_header_parser_bad_oem_range_no_start(self): + """Test AID Header Parser bad oem range (no start) input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + #define AID_OEM_RESERVED_END 2900 + """)) + temp_file.flush() + + with self.assertRaises(SystemExit): + AIDHeaderParser(temp_file.name) + + def test_aid_header_parser_bad_oem_range_mismatch_start_end(self): + """Test AID Header Parser bad oem range mismatched input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + #define AID_OEM_RESERVED_START 2900 + #define AID_OEM_RESERVED_2_END 2900 + """)) + temp_file.flush() + + with self.assertRaises(SystemExit): + AIDHeaderParser(temp_file.name) + + def test_fs_config_file_parser_good(self): + """Test FSConfig Parser good input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + [/system/bin/file] + user: AID_FOO + group: AID_SYSTEM + mode: 0777 + caps: BLOCK_SUSPEND + + [/vendor/path/dir/] + user: AID_FOO + group: AID_SYSTEM + mode: 0777 + caps: 0 + + [AID_OEM1] + # 5001 in base16 + value: 0x1389 + """)) + temp_file.flush() + + parser = FSConfigFileParser([temp_file.name], [(5000, 5999)]) + files = parser.files + dirs = parser.dirs + aids = parser.aids + + self.assertEquals(len(files), 1) + self.assertEquals(len(dirs), 1) + self.assertEquals(len(aids), 1) + + aid = aids[0] + fcap = files[0] + dcap = dirs[0] + + self.assertEqual(fcap, + FSConfig('0777', 'AID_FOO', 'AID_SYSTEM', + '(1ULL << CAP_BLOCK_SUSPEND)', + '/system/bin/file', temp_file.name)) + + self.assertEqual(dcap, + FSConfig('0777', 'AID_FOO', 'AID_SYSTEM', '(0)', + '/vendor/path/dir/', temp_file.name)) + + self.assertEqual(aid, AID('AID_OEM1', '0x1389', temp_file.name)) + + def test_fs_config_file_parser_bad(self): + """Test FSConfig Parser bad input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + [/system/bin/file] + caps: BLOCK_SUSPEND + """)) + temp_file.flush() + + with self.assertRaises(SystemExit): + FSConfigFileParser([temp_file.name], [(5000, 5999)]) + + def test_fs_config_file_parser_bad_aid_range(self): + """Test FSConfig Parser bad aid range value input file""" + + with tempfile.NamedTemporaryFile() as temp_file: + temp_file.write( + textwrap.dedent(""" + [AID_OEM1] + value: 25 + """)) + temp_file.flush() + + with self.assertRaises(SystemExit): + FSConfigFileParser([temp_file.name], [(5000, 5999)])