def test_compute_vndk_vnd_ext(self):
        class MockBannedLibs(object):
            def is_banned(self, name):
                return False

        generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_ext_ref')

        generic_refs = GenericRefs.create_from_dir(generic_refs_dir)

        input_dir = os.path.join(TESTDATA_DIR, 'vndk_vnd_ext')

        graph = ELFLinker.create_from_dump(
            system_dirs=[os.path.join(input_dir, 'system')],
            vendor_dirs=[os.path.join(input_dir, 'vendor')],
            generic_refs=generic_refs)

        vndk = graph.compute_vndk(sp_hals=set(),
                                  vndk_stable=set(),
                                  vndk_customized_for_system=set(),
                                  vndk_customized_for_vendor=set(),
                                  generic_refs=generic_refs,
                                  banned_libs=MockBannedLibs())

        self.assertEqual([
            '/system/lib/vndk/libRS.so', '/system/lib/vndk/libcutils.so',
            '/system/lib64/vndk/libRS.so', '/system/lib64/vndk/libcutils.so'
        ], self._get_paths_from_nodes(vndk.vndk_core))
        self.assertEqual([], self._get_paths_from_nodes(vndk.vndk_fwk_ext))
        self.assertEqual(['/system/lib/libRS.so', '/system/lib64/libRS.so'],
                         self._get_paths_from_nodes(vndk.vndk_vnd_ext))
 def setUp(self):
     self.ref = GenericRefs()
     self.ref.add('/system/lib/libc.so',
                  MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
     self.ref.add('/system/lib/libm.so',
                  MockELF({'cos', 'sin', 'tan'}))
     self.ref.add('/system/lib64/libc.so',
                  MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
     self.ref.add('/system/lib64/libm.so',
                  MockELF({'cos', 'sin', 'tan'}))
    def test_compute_vndk_inward_customization(self):
        class MockBannedLibs(object):
            def is_banned(self, name):
                return False

        generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_gr')

        generic_refs = GenericRefs.create_from_dir(generic_refs_dir)

        input_dir = os.path.join(TESTDATA_DIR, 'vndk_inward_customization')

        graph = ELFLinker.create_from_dump(
            system_dirs=[os.path.join(input_dir, 'system')],
            vendor_dirs=[os.path.join(input_dir, 'vendor')],
            generic_refs=generic_refs)

        # Make sure libjpeg.so was loaded from the input dir.
        libjpeg_32 = graph.get_lib('/system/lib/libjpeg.so')
        self.assertIsNotNone(libjpeg_32)
        libjpeg_64 = graph.get_lib('/system/lib64/libjpeg.so')
        self.assertIsNotNone(libjpeg_64)

        # Compute vndk sets and move libraries to the correct directories.
        vndk = graph.compute_vndk(sp_hals=set(),
                                  vndk_stable=set(),
                                  vndk_customized_for_system=set(),
                                  vndk_customized_for_vendor=set(),
                                  generic_refs=generic_refs,
                                  banned_libs=MockBannedLibs())

        # Check vndk-core libraries.
        self.assertEqual([
            '/system/lib/vndk/libRS.so', '/system/lib/vndk/libcutils.so',
            '/system/lib64/vndk/libRS.so', '/system/lib64/vndk/libcutils.so'
        ], self._get_paths_from_nodes(vndk.vndk_core))

        # Check vndk-indirect libraries.
        self.assertEqual(
            ['/system/lib/vndk/libjpeg.so', '/system/lib64/vndk/libjpeg.so'],
            self._get_paths_from_nodes(vndk.vndk_indirect))

        # Check libjpeg.so (inward-customization) has been renamed.
        self.assertIsNone(graph.get_lib('/system/lib/libjpeg.so'))
        self.assertIsNone(graph.get_lib('/system/lib64/libjpeg.so'))
        self.assertIs(libjpeg_32, graph.get_lib('/system/lib/vndk/libjpeg.so'))
        self.assertIs(libjpeg_64,
                      graph.get_lib('/system/lib64/vndk/libjpeg.so'))

        # Check the absence of vndk-ext libraries.
        self.assertEqual([], self._get_paths_from_nodes(vndk.vndk_fwk_ext))
        self.assertEqual([], self._get_paths_from_nodes(vndk.vndk_vnd_ext))
    def test_compute_vndk_indirect_ext(self):
        class MockBannedLibs(object):
            def is_banned(self, name):
                return False

        # This test case reveals a corner case that will break vndk-indirect
        # computation.  To reproduce the case, the following condition must be
        # satisfied:
        #
        # 1. libA depends on libB.
        # 2. libA is a vndk-fwk-ext.
        # 3. libB is an outward-customized vndk which depends on non-AOSP libC.
        #
        # Both AOSP libA and libB will be added to vndk-core.  But,
        # unfortunately, libA will be resolved to libB in vndk-fwk-ext and this
        # will break the vndk-indirect computation because libC is not in
        # generic references.

        generic_refs_dir = os.path.join(TESTDATA_DIR, 'vndk_indirect_ext_gr')

        generic_refs = GenericRefs.create_from_dir(generic_refs_dir)

        input_dir = os.path.join(TESTDATA_DIR, 'vndk_indirect_ext')

        graph = ELFLinker.create_from_dump(
            system_dirs=[os.path.join(input_dir, 'system')],
            vendor_dirs=[os.path.join(input_dir, 'vendor')],
            generic_refs=generic_refs)

        vndk = graph.compute_vndk(sp_hals=set(),
                                  vndk_stable=set(),
                                  vndk_customized_for_system=set(),
                                  vndk_customized_for_vendor=set(),
                                  generic_refs=generic_refs,
                                  banned_libs=MockBannedLibs())

        self.assertEqual([
            '/system/lib/vndk/libRS.so', '/system/lib/vndk/libcutils.so',
            '/system/lib64/vndk/libRS.so', '/system/lib64/vndk/libcutils.so'
        ], self._get_paths_from_nodes(vndk.vndk_core))

        self.assertEqual([
            '/system/lib/vndk/libRS_internal.so',
            '/system/lib64/vndk/libRS_internal.so'
        ], self._get_paths_from_nodes(vndk.vndk_indirect))

        self.assertEqual([
            '/system/lib/vndk-ext/libRS_internal.so',
            '/system/lib64/vndk-ext/libRS_internal.so'
        ], self._get_paths_from_nodes(vndk.vndk_fwk_ext))
    def _create_graph_gr(self, input_dir, generic_refs_dir):
        if not generic_refs_dir:
            generic_refs = None
        else:
            generic_refs_dir = os.path.join(TESTDATA_DIR, generic_refs_dir)
            generic_refs = GenericRefs.create_from_dir(generic_refs_dir)

        input_dir = os.path.join(TESTDATA_DIR, input_dir)

        graph = ELFLinker.create_from_dump(
                system_dirs=[os.path.join(input_dir, 'system')],
                vendor_dirs=[os.path.join(input_dir, 'vendor')],
                generic_refs=generic_refs)

        return (graph, generic_refs)
    def _create_graph_gr(self, input_dir, generic_refs_dir):
        if not generic_refs_dir:
            generic_refs = None
        else:
            generic_refs_dir = os.path.join(TESTDATA_DIR, generic_refs_dir)
            generic_refs = GenericRefs.create_from_sym_dir(generic_refs_dir)

        input_dir = os.path.join(TESTDATA_DIR, input_dir)

        graph = ELFLinker.create_from_dump(
            system_dirs=[os.path.join(input_dir, 'system')],
            vendor_dirs=[os.path.join(input_dir, 'vendor')],
            generic_refs=generic_refs)

        return (graph, generic_refs)
Example #7
0
    def test_create_from_dir(self):
        g = GenericRefs.create_from_dir(self.test_dir)
        self.assertEqual(4, len(g.refs))

        self.assertIn('/system/lib/libc.so', g.refs)
        self.assertIn('/system/lib/libm.so', g.refs)
        self.assertIn('/system/lib64/libc.so', g.refs)
        self.assertIn('/system/lib64/libm.so', g.refs)

        self.assertEqual(['fclose', 'fopen', 'fread', 'fwrite'],
                         g.refs['/system/lib/libc.so'])
        self.assertEqual(['fclose', 'fopen', 'fread', 'fwrite'],
                         g.refs['/system/lib64/libc.so'])

        self.assertEqual(['cos', 'sin', 'tan'], g.refs['/system/lib/libm.so'])
        self.assertEqual(['cos', 'sin', 'tan'],
                         g.refs['/system/lib64/libm.so'])
Example #8
0
    def test_create_from_sym_dir(self):
        input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs')

        g = GenericRefs.create_from_sym_dir(input_dir)
        self.assertEqual(4, len(g.refs))

        self.assertIn('/system/lib/libc.so', g.refs)
        self.assertIn('/system/lib/libm.so', g.refs)
        self.assertIn('/system/lib64/libc.so', g.refs)
        self.assertIn('/system/lib64/libm.so', g.refs)

        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib/libc.so'].exported_symbols)
        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib64/libc.so'].exported_symbols)

        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib/libm.so'].exported_symbols)
        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib64/libm.so'].exported_symbols)
    def test_create_from_dir(self):
        input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs')

        g = GenericRefs.create_from_dir(input_dir)
        self.assertEqual(4, len(g.refs))

        self.assertIn('/system/lib/libc.so', g.refs)
        self.assertIn('/system/lib/libm.so', g.refs)
        self.assertIn('/system/lib64/libc.so', g.refs)
        self.assertIn('/system/lib64/libm.so', g.refs)

        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib/libc.so'].exported_symbols)
        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib64/libc.so'].exported_symbols)

        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib/libm.so'].exported_symbols)
        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib64/libm.so'].exported_symbols)
Example #10
0
    def test_is_equivalent_lib(self):
        g = GenericRefs.create_from_dir(self.test_dir)

        class MockELF(object):
            def __init__(self, exported_symbols):
                self.exported_symbols = exported_symbols

        class MockLib(object):
            def __init__(self, path, exported_symbols):
                self.path = path
                self.elf = MockELF(exported_symbols)

        libc_sub = MockLib('/system/lib/libc.so', ['fclose', 'fopen', 'fread'])
        libc_sup = MockLib('/system/lib/libc.so',
                           ['fclose', 'fopen', 'fread', 'fwrite', 'open'])
        libc_eq = MockLib('/system/lib/libc.so',
                          ['fclose', 'fopen', 'fread', 'fwrite'])

        self.assertFalse(g.is_equivalent_lib(libc_sub))
        self.assertFalse(g.is_equivalent_lib(libc_sup))

        self.assertTrue(g.is_equivalent_lib(libc_eq))
Example #11
0
class GenericRefsTest(unittest.TestCase):
    def setUp(self):
        self.ref = GenericRefs()
        self.ref.add('/system/lib/libc.so',
                     MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
        self.ref.add('/system/lib/libm.so', MockELF({'cos', 'sin', 'tan'}))
        self.ref.add('/system/lib64/libc.so',
                     MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
        self.ref.add('/system/lib64/libm.so', MockELF({'cos', 'sin', 'tan'}))

    def test_create_from_sym_dir(self):
        input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs')

        g = GenericRefs.create_from_sym_dir(input_dir)
        self.assertEqual(4, len(g.refs))

        self.assertIn('/system/lib/libc.so', g.refs)
        self.assertIn('/system/lib/libm.so', g.refs)
        self.assertIn('/system/lib64/libc.so', g.refs)
        self.assertIn('/system/lib64/libm.so', g.refs)

        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib/libc.so'].exported_symbols)
        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib64/libc.so'].exported_symbols)

        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib/libm.so'].exported_symbols)
        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib64/libm.so'].exported_symbols)

    def test_classify_lib(self):
        libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
        libc_sup = MockLib('/system/lib/libc.so',
                           {'fclose', 'fopen', 'fread', 'fwrite', 'open'})
        libc_eq = MockLib('/system/lib/libc.so',
                          {'fclose', 'fopen', 'fread', 'fwrite'})
        libfoo = MockLib('/system/lib/libfoo.so', {})

        self.assertEqual(GenericRefs.MODIFIED, self.ref.classify_lib(libc_sub))
        self.assertEqual(GenericRefs.EXPORT_SUPER_SET,
                         self.ref.classify_lib(libc_sup))
        self.assertEqual(GenericRefs.EXPORT_EQUAL,
                         self.ref.classify_lib(libc_eq))
        self.assertEqual(GenericRefs.NEW_LIB, self.ref.classify_lib(libfoo))

    def test_is_equivalent_lib(self):
        libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
        libc_sup = MockLib('/system/lib/libc.so',
                           {'fclose', 'fopen', 'fread', 'fwrite', 'open'})
        libc_eq = MockLib('/system/lib/libc.so',
                          {'fclose', 'fopen', 'fread', 'fwrite'})

        self.assertFalse(self.ref.is_equivalent_lib(libc_sub))
        self.assertFalse(self.ref.is_equivalent_lib(libc_sup))

        self.assertTrue(self.ref.is_equivalent_lib(libc_eq))
class GenericRefsTest(unittest.TestCase):
    def setUp(self):
        self.ref = GenericRefs()
        self.ref.add('/system/lib/libc.so',
                     MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
        self.ref.add('/system/lib/libm.so',
                     MockELF({'cos', 'sin', 'tan'}))
        self.ref.add('/system/lib64/libc.so',
                     MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
        self.ref.add('/system/lib64/libm.so',
                     MockELF({'cos', 'sin', 'tan'}))

    def test_create_from_dir(self):
        input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs')

        g = GenericRefs.create_from_dir(input_dir)
        self.assertEqual(4, len(g.refs))

        self.assertIn('/system/lib/libc.so', g.refs)
        self.assertIn('/system/lib/libm.so', g.refs)
        self.assertIn('/system/lib64/libc.so', g.refs)
        self.assertIn('/system/lib64/libm.so', g.refs)

        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib/libc.so'].exported_symbols)
        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                         g.refs['/system/lib64/libc.so'].exported_symbols)

        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib/libm.so'].exported_symbols)
        self.assertEqual({'cos', 'sin', 'tan'},
                         g.refs['/system/lib64/libm.so'].exported_symbols)

    def test_classify_lib(self):
        libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
        libc_sup = MockLib('/system/lib/libc.so',
                           {'fclose', 'fopen', 'fread', 'fwrite', 'open'})
        libc_eq = MockLib('/system/lib/libc.so',
                          {'fclose', 'fopen', 'fread', 'fwrite'})
        libfoo = MockLib('/system/lib/libfoo.so', {})

        self.assertEqual(GenericRefs.MODIFIED, self.ref.classify_lib(libc_sub))
        self.assertEqual(GenericRefs.EXPORT_SUPER_SET,
                         self.ref.classify_lib(libc_sup))
        self.assertEqual(GenericRefs.EXPORT_EQUAL,
                         self.ref.classify_lib(libc_eq))
        self.assertEqual(GenericRefs.NEW_LIB, self.ref.classify_lib(libfoo))

    def test_is_equivalent_lib(self):
        libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
        libc_sup = MockLib('/system/lib/libc.so',
                           {'fclose', 'fopen', 'fread', 'fwrite', 'open'})
        libc_eq = MockLib('/system/lib/libc.so',
                          {'fclose', 'fopen', 'fread', 'fwrite'})

        self.assertFalse(self.ref.is_equivalent_lib(libc_sub))
        self.assertFalse(self.ref.is_equivalent_lib(libc_sup))

        self.assertTrue(self.ref.is_equivalent_lib(libc_eq))