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

        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([
            '/vendor/lib/vndk-ext/libRS.so', '/vendor/lib64/vndk-ext/libRS.so'
        ], self._get_paths_from_nodes(vndk.vndk_vnd_ext))
    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)