OSDN Git Service

fs_config: add unit tests
authorWilliam Roberts <william.c.roberts@intel.com>
Sat, 19 Nov 2016 00:12:41 +0000 (16:12 -0800)
committerDan Albert <danalbert@google.com>
Wed, 30 Nov 2016 06:05:39 +0000 (22:05 -0800)
Add some initial unit tests.

The unit tests themselves are inlined into the tool and
can be executed by running the "test" commandlet.

Example:
$ python -m unittest test_fs_config_generator.Tests
.............
----------------------------------------------------------------------
Ran 13 tests in 0.004s

OK

Test: run the test commandlet and observe for failures.

Change-Id: I1bada385fa841fd50fa958997d440f1198e15198
Signed-off-by: William Roberts <william.c.roberts@intel.com>
tools/fs_config/README
tools/fs_config/fs_config_generator.py
tools/fs_config/test_fs_config_generator.py [new file with mode: 0755]

index c50c056..d884e32 100644 (file)
@@ -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_<xxx> method to the test class. It will automatically
+get picked up and added to the test suite.
index d46db9f..8609657 100755 (executable)
@@ -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 (executable)
index 0000000..a911aae
--- /dev/null
@@ -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)])