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)
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'])
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)
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))
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))