From 8969d7398a73fe3af5b01e2488e3697189e76490 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 17:00:50 +0800 Subject: [PATCH 1/9] vndk-def: Mark --output as a required argument This command marks `--output` as a required argument for various subcommands. Test: ./vndk_definition_tool.py deps-insight # see better error message Change-Id: Ie60e186287beea7e701ab740fcf8c2959bfaec36 --- vndk/tools/definition-tool/vndk_definition_tool.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py index 98c623558..d70c6f428 100755 --- a/vndk/tools/definition-tool/vndk_definition_tool.py +++ b/vndk/tools/definition-tool/vndk_definition_tool.py @@ -2859,9 +2859,8 @@ class CreateGenericRefCommand(Command): def add_argparser_options(self, parser): parser.add_argument('dir') - parser.add_argument( - '--output', '-o', metavar='PATH', required=True, - help='output directory') + parser.add_argument('-o', '--output', required=True, + help='output directory') def main(self, args): root = os.path.abspath(args.dir) @@ -3210,7 +3209,8 @@ class DepsInsightCommand(VNDKCommandBase): parser.add_argument('--module-info') - parser.add_argument('--output', '-o', help='output directory') + parser.add_argument('-o', '--output', required=True, + help='output directory') @staticmethod def serialize_data(libs, vndk_lib, module_info): @@ -3748,7 +3748,8 @@ class DepGraphCommand(ELFGraphCommand): def add_argparser_options(self, parser): super(DepGraphCommand, self).add_argparser_options(parser) - parser.add_argument('--output', '-o', help='output directory') + parser.add_argument('-o', '--output', required=True, + help='output directory') def _get_tag_from_lib(self, lib, tagged_paths): tag_hierarchy = dict() From d7867edc4f1cdb176ce2f142dee2bbaae83bc68f Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 17:35:14 +0800 Subject: [PATCH 2/9] vndk-def: Cleanup dep-graph This commit cleans the code for `dep-graph` command. Test: ./vndk_definition_tool.py dep-graph --system ... --vendor ... Change-Id: Ib902d6d4015a5add89f4bed39088ba42310ccbc2 --- .../definition-tool/vndk_definition_tool.py | 87 +++++++++++-------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py index d70c6f428..4e29986de 100755 --- a/vndk/tools/definition-tool/vndk_definition_tool.py +++ b/vndk/tools/definition-tool/vndk_definition_tool.py @@ -2877,7 +2877,7 @@ class CreateGenericRefCommand(Command): class ELFGraphCommand(Command): - def add_argparser_options(self, parser): + def add_argparser_options(self, parser, is_tag_file_required=None): parser.add_argument( '--load-extra-deps', action='append', help='load extra module dependencies') @@ -2922,7 +2922,9 @@ class ELFGraphCommand(Command): '--no-unzip-files', action='store_false', dest='unzip_files', help='do not scan ELF files in zip files') - parser.add_argument('--tag-file', help='lib tag file') + parser.add_argument( + '--tag-file', required=is_tag_file_required, + help='lib tag file') def get_generic_refs_from_args(self, args): if args.load_generic_refs: @@ -3743,53 +3745,66 @@ class DumpDexStringCommand(Command): class DepGraphCommand(ELFGraphCommand): def __init__(self): super(DepGraphCommand, self).__init__( - 'dep-graph', help='Show the eligible dependencies graph') + 'dep-graph', help='Visualize violating dependencies with HTML') + def add_argparser_options(self, parser): - super(DepGraphCommand, self).add_argparser_options(parser) + super(DepGraphCommand, self).add_argparser_options( + parser, is_tag_file_required=True) parser.add_argument('-o', '--output', required=True, help='output directory') - def _get_tag_from_lib(self, lib, tagged_paths): - tag_hierarchy = dict() + + @staticmethod + def _create_tag_hierarchy(): + hierarchy = dict() for tag in TaggedPathDict.TAGS: if tag in {'sp_hal', 'sp_hal_dep', 'vnd_only'}: - tag_hierarchy[tag] = 'vendor.private.{}'.format(tag) + hierarchy[tag] = 'vendor.private.{}'.format(tag) else: vendor_visible = TaggedPathDict.is_tag_visible('vnd_only', tag) pub = 'public' if vendor_visible else 'private' - tag_hierarchy[tag] = 'system.{}.{}'.format(pub, tag) + hierarchy[tag] = 'system.{}.{}'.format(pub, tag) + return hierarchy - return tag_hierarchy[tagged_paths.get_path_tag(lib.path)] - def _check_if_allowed(self, my_tag, other_tag): - my = my_tag.split('.') - other = other_tag.split('.') - if my[0] == 'system' and other[0] == 'vendor': - return False - if my[0] == 'vendor' and other[0] == 'system' \ - and other[1] == 'private': + @staticmethod + def _get_lib_tag(hierarchy, tagged_paths, lib): + return hierarchy[tagged_paths.get_path_tag(lib.path)] + + + @staticmethod + def _is_dep_allowed(user_tag, dep_tag): + user_partition, _, _ = user_tag.split('.') + dep_partition, dep_visibility, _ = dep_tag.split('.') + if user_partition == 'system' and dep_partition == 'vendor': return False + if user_partition == 'vendor' and dep_partition == 'system': + if dep_visibility == 'private': + return False return True + def _get_dep_graph(self, graph, tagged_paths): + hierarchy = self._create_tag_hierarchy() + + # Build data and violate_libs. data = [] - violate_libs = dict() - system_libs = graph.lib_pt[PT_SYSTEM].values() - vendor_libs = graph.lib_pt[PT_VENDOR].values() - for lib in itertools.chain(system_libs, vendor_libs): - tag = self._get_tag_from_lib(lib, tagged_paths) - violate_count = 0 + violate_libs = collections.defaultdict(list) + + for lib in graph.all_libs(): + lib_tag = self._get_lib_tag(hierarchy, tagged_paths, lib) lib_item = { 'name': lib.path, - 'tag': tag, + 'tag': lib_tag, 'depends': [], 'violates': [], } + violate_count = 0 for dep in lib.deps_all: - if self._check_if_allowed( - tag, self._get_tag_from_lib(dep, tagged_paths)): + dep_tag = self._get_lib_tag(hierarchy, tagged_paths, dep) + if self._is_dep_allowed(lib_tag, dep_tag): lib_item['depends'].append(dep.path) else: lib_item['violates'].append([ @@ -3797,22 +3812,22 @@ class DepGraphCommand(ELFGraphCommand): violate_count += 1 lib_item['violate_count'] = violate_count if violate_count > 0: - if not tag in violate_libs: - violate_libs[tag] = [] - violate_libs[tag].append((lib.path, violate_count)) + violate_libs[lib_tag].append((lib.path, violate_count)) data.append(lib_item) + + # Sort data and violate_libs. + data.sort( + key=lambda lib_item: (lib_item['tag'], lib_item['violate_count'])) + for libs in violate_libs.values(): + libs.sort(key=lambda violate_item: violate_item[1], reverse=True) + return data, violate_libs - def main(self, args): - _, graph, tagged_paths, vndk_lib_dirs = self.create_from_args(args) - tagged_paths = TaggedPathDict.create_from_csv_path( - args.tag_file, vndk_lib_dirs) + def main(self, args): + _, graph, tagged_paths, _ = self.create_from_args(args) + data, violate_libs = self._get_dep_graph(graph, tagged_paths) - data.sort(key=lambda lib_item: (lib_item['tag'], - lib_item['violate_count'])) - for libs in violate_libs.values(): - libs.sort(key=lambda libs: libs[1], reverse=True) makedirs(args.output, exist_ok=True) script_dir = os.path.dirname(os.path.abspath(__file__)) From 64c28f7422950f5684e446722bcf188483505407 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 17:48:34 +0800 Subject: [PATCH 3/9] vndk-def: Separate methods with two empty lines This commit adds several empty lines to the file so that all method definitions in `vndk_definition_tool.py` are separated by two empty lines. Test: n/a Change-Id: I5976dec4ba73a80a29693bfa92fcaf5ecceace9d --- vndk/tools/definition-tool/tests/compat.py | 10 ++ .../definition-tool/tests/ndk_toolchain.py | 13 ++ vndk/tools/definition-tool/tests/run.py | 1 + vndk/tools/definition-tool/tests/test_elf.py | 15 ++ .../tests/test_elf_link_data.py | 8 + .../tests/test_elf_resolver.py | 2 + .../definition-tool/tests/test_elfdump.py | 6 + .../tests/test_generic_refs.py | 4 + .../definition-tool/tests/test_module_info.py | 1 + vndk/tools/definition-tool/tests/utils.py | 7 + .../definition-tool/vndk_definition_tool.py | 164 ++++++++++++++++++ 11 files changed, 231 insertions(+) diff --git a/vndk/tools/definition-tool/tests/compat.py b/vndk/tools/definition-tool/tests/compat.py index 9f418539d..7fcbc2e93 100644 --- a/vndk/tools/definition-tool/tests/compat.py +++ b/vndk/tools/definition-tool/tests/compat.py @@ -3,30 +3,37 @@ import os import sys + try: from tempfile import TemporaryDirectory except ImportError: import shutil import tempfile + class TemporaryDirectory(object): def __init__(self, suffix='', prefix='tmp', dir=None): self.name = tempfile.mkdtemp(suffix, prefix, dir) + def __del__(self): self.cleanup() + def __enter__(self): return self.name + def __exit__(self, exc, value, tb): self.cleanup() + def cleanup(self): if self.name: shutil.rmtree(self.name) self.name = None + if sys.version_info >= (3, 0): from os import makedirs else: @@ -35,6 +42,7 @@ else: return return os.makedirs(path) + if sys.version_info >= (3, 0): from io import StringIO else: @@ -45,6 +53,8 @@ try: from unittest.mock import patch except ImportError: import contextlib + + @contextlib.contextmanager def patch(target, mock): obj, attr = target.rsplit('.') diff --git a/vndk/tools/definition-tool/tests/ndk_toolchain.py b/vndk/tools/definition-tool/tests/ndk_toolchain.py index 8ad9144ce..485b1b85c 100755 --- a/vndk/tools/definition-tool/tests/ndk_toolchain.py +++ b/vndk/tools/definition-tool/tests/ndk_toolchain.py @@ -9,6 +9,7 @@ import re import subprocess import sys + def detect_ndk_dir(): ndk_dir = os.getenv('NDK') if not ndk_dir: @@ -28,6 +29,7 @@ error:''' return ndk_dir + def detect_api_level(ndk_dir): try: apis = [] @@ -42,6 +44,7 @@ def detect_api_level(ndk_dir): except IOError: raise ValueError('failed to find latest api') + def detect_host(): if sys.platform.startswith('linux'): return 'linux-x86_64' @@ -49,15 +52,19 @@ def detect_host(): return 'darwin-x86_64' raise NotImplementedError('unknown host platform') + def get_gcc_dir(ndk_dir, arch, host): return os.path.join(ndk_dir, 'toolchains', arch, 'prebuilt', host) + def get_clang_dir(ndk_dir, host): return os.path.join(ndk_dir, 'toolchains', 'llvm', 'prebuilt', host) + def get_platform_dir(ndk_dir, api, subdirs): return os.path.join(ndk_dir, 'platforms', api, *subdirs) + class Target(object): def __init__(self, name, triple, cflags, ldflags, gcc_toolchain_dir, clang_dir, ndk_include, ndk_lib): @@ -71,6 +78,7 @@ class Target(object): self.ndk_include = ndk_include self.ndk_lib = ndk_lib + def check_paths(self): def check_path(path): if os.path.exists(path): @@ -88,6 +96,7 @@ class Target(object): success &= check_path(self.ndk_lib) return success + def compile(self, obj_file, src_file, cflags): clang = os.path.join(self.clang_dir, 'bin', 'clang') @@ -100,6 +109,7 @@ class Target(object): cmd.extend(self.target_cflags) subprocess.check_call(cmd) + def link(self, out_file, obj_files, ldflags): if '-shared' in ldflags: crtbegin = os.path.join(self.ndk_lib, 'crtbegin_so.o') @@ -124,6 +134,7 @@ class Target(object): cmd.append('-Wl,-pie') subprocess.check_call(cmd) + def create_targets(ndk_dir=None, api=None, host=None): if ndk_dir is None: ndk_dir = detect_ndk_dir() @@ -180,6 +191,7 @@ def create_targets(ndk_dir=None, api=None, host=None): return targets + def main(): parser = argparse.ArgumentParser( description='Dry-run NDK toolchain detection') @@ -198,5 +210,6 @@ def main(): print('succeed') + if __name__ == '__main__': main() diff --git a/vndk/tools/definition-tool/tests/run.py b/vndk/tools/definition-tool/tests/run.py index 2d2352bf5..2837d5cef 100755 --- a/vndk/tools/definition-tool/tests/run.py +++ b/vndk/tools/definition-tool/tests/run.py @@ -4,6 +4,7 @@ import argparse import os import unittest + def main(): parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='store_true') diff --git a/vndk/tools/definition-tool/tests/test_elf.py b/vndk/tools/definition-tool/tests/test_elf.py index a45fb5816..160911d0e 100755 --- a/vndk/tools/definition-tool/tests/test_elf.py +++ b/vndk/tools/definition-tool/tests/test_elf.py @@ -12,6 +12,7 @@ import unittest from compat import StringIO from vndk_definition_tool import Elf_Sym, ELF + class ElfSymTest(unittest.TestCase): def setUp(self): self.sym_local = Elf_Sym(0, 0, 4, 0, 0, 1) @@ -19,21 +20,25 @@ class ElfSymTest(unittest.TestCase): self.sym_weak = Elf_Sym(0, 0, 4, 33, 0, 1) self.sym_undef = Elf_Sym(0, 0, 4, 16, 0, 0) + def test_is_local(self): self.assertTrue(self.sym_local.is_local) self.assertFalse(self.sym_global.is_local) self.assertFalse(self.sym_weak.is_local) + def test_is_global(self): self.assertFalse(self.sym_local.is_global) self.assertTrue(self.sym_global.is_global) self.assertFalse(self.sym_weak.is_global) + def test_is_weak(self): self.assertFalse(self.sym_local.is_weak) self.assertFalse(self.sym_global.is_weak) self.assertTrue(self.sym_weak.is_weak) + def test_is_undef(self): self.assertFalse(self.sym_global.is_undef) self.assertTrue(self.sym_undef.is_undef) @@ -44,12 +49,14 @@ class ELFTest(unittest.TestCase): self.assertEqual(ELF.ELFCLASS32, ELF.get_ei_class_from_name('32')) self.assertEqual(ELF.ELFCLASS64, ELF.get_ei_class_from_name('64')) + def test_get_ei_data_from_name(self): self.assertEqual(ELF.ELFDATA2LSB, ELF.get_ei_data_from_name('Little-Endian')) self.assertEqual(ELF.ELFDATA2MSB, ELF.get_ei_data_from_name('Big-Endian')) + def test_get_e_machine_from_name(self): self.assertEqual(0, ELF.get_e_machine_from_name('EM_NONE')) self.assertEqual(3, ELF.get_e_machine_from_name('EM_386')) @@ -58,6 +65,7 @@ class ELFTest(unittest.TestCase): self.assertEqual(62, ELF.get_e_machine_from_name('EM_X86_64')) self.assertEqual(183, ELF.get_e_machine_from_name('EM_AARCH64')) + def test_repr(self): elf = ELF() self.assertEqual(elf, eval(repr(elf))) @@ -67,6 +75,7 @@ class ELFTest(unittest.TestCase): dt_needed=['c', 'd'], exported_symbols={'e', 'f', 'g'}) self.assertEqual(elf, eval(repr(elf))) + def test_class_name(self): self.assertEqual('None', ELF().elf_class_name) @@ -80,6 +89,7 @@ class ELFTest(unittest.TestCase): self.assertFalse(elf.is_32bit) self.assertTrue(elf.is_64bit) + def test_endianness(self): self.assertEqual('None', ELF().elf_data_name) self.assertEqual('Little-Endian', @@ -87,6 +97,7 @@ class ELFTest(unittest.TestCase): self.assertEqual('Big-Endian', ELF(None, ELF.ELFDATA2MSB).elf_data_name) + def test_machine_name(self): self.assertEqual('EM_NONE', ELF(e_machine=0).elf_machine_name) self.assertEqual('EM_386', ELF(e_machine=3).elf_machine_name) @@ -95,6 +106,7 @@ class ELFTest(unittest.TestCase): self.assertEqual('EM_X86_64', ELF(e_machine=62).elf_machine_name) self.assertEqual('EM_AARCH64', ELF(e_machine=183).elf_machine_name) + def test_dt_rpath_runpath(self): elf = ELF() self.assertEqual([], elf.dt_rpath) @@ -104,6 +116,7 @@ class ELFTest(unittest.TestCase): self.assertEqual(['a'], elf.dt_rpath) self.assertEqual(['b'], elf.dt_runpath) + def test_dump(self): elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, ['a'], ['b'], ['libc.so', 'libm.so'], {'hello', 'world'}, {'d', 'e'}) @@ -130,6 +143,7 @@ class ELFTest(unittest.TestCase): 'IMP_SYMBOL\te\n', actual_output) + def test_parse_dump_file(self): data = ('EI_CLASS\t64\n' 'EI_DATA\t\tLittle-Endian\n' @@ -190,6 +204,7 @@ class ELFJniLibTest(unittest.TestCase): elf = ELF(dt_needed=['libc.so']) self.assertFalse(elf.is_jni_lib()) + def test_jni_symbols(self): elf = ELF(imported_symbols={'JNI_CreateJavaVM'}) self.assertTrue(elf.is_jni_lib()) diff --git a/vndk/tools/definition-tool/tests/test_elf_link_data.py b/vndk/tools/definition-tool/tests/test_elf_link_data.py index e850307da..98ae69243 100755 --- a/vndk/tools/definition-tool/tests/test_elf_link_data.py +++ b/vndk/tools/definition-tool/tests/test_elf_link_data.py @@ -25,6 +25,7 @@ class ELFLinkDataTest(unittest.TestCase): self.z.add_needed_dep(self.w) self.z.add_dlopen_dep(self.w) + def test_add_dep_and_accessors(self): self.assertIn(self.y, self.x.deps_needed_all) self.assertIn(self.x, self.y.users_needed_all) @@ -36,6 +37,7 @@ class ELFLinkDataTest(unittest.TestCase): self.assertNotIn(self.z, self.x.deps_needed_all) self.assertNotIn(self.x, self.z.users_needed_all) + def test_remove_dep(self): self.assertIn(self.y, self.x.deps_needed_all) self.assertIn(self.x, self.y.users_needed_all) @@ -51,6 +53,7 @@ class ELFLinkDataTest(unittest.TestCase): self.assertNotIn(self.y, self.x.deps_needed) self.assertNotIn(self.x, self.y.users_needed) + def test_num_deps(self): self.assertEqual(2, self.x.num_deps) self.assertEqual(0, self.y.num_deps) @@ -60,6 +63,7 @@ class ELFLinkDataTest(unittest.TestCase): # NEEDED and DLOPEN are counted twice. self.assertEqual(2, self.z.num_deps) + def test_num_users(self): self.assertEqual(0, self.x.num_users) self.assertEqual(1, self.y.num_users) @@ -69,22 +73,26 @@ class ELFLinkDataTest(unittest.TestCase): # NEEDED and DLOPEN are counted twice. self.assertEqual(2, self.w.num_users) + def test_has_dep(self): self.assertTrue(self.x.has_dep(self.y)) self.assertTrue(self.x.has_dep(self.z)) self.assertFalse(self.x.has_dep(self.x)) self.assertFalse(self.x.has_dep(self.w)) + def test_has_user(self): self.assertTrue(self.y.has_user(self.x)) self.assertTrue(self.z.has_user(self.x)) self.assertFalse(self.x.has_user(self.x)) self.assertFalse(self.w.has_user(self.x)) + def test_is_system_lib(self): self.assertTrue(self.x.is_system_lib()) self.assertFalse(self.v.is_system_lib()) + def test_get_dep_linked_symbols(self): self.x.linked_symbols['c'] = self.y self.x.linked_symbols['b'] = self.y diff --git a/vndk/tools/definition-tool/tests/test_elf_resolver.py b/vndk/tools/definition-tool/tests/test_elf_resolver.py index 29973e302..30bab9f7c 100755 --- a/vndk/tools/definition-tool/tests/test_elf_resolver.py +++ b/vndk/tools/definition-tool/tests/test_elf_resolver.py @@ -10,6 +10,7 @@ import unittest from vndk_definition_tool import ELFResolver + class ELFResolverTest(unittest.TestCase): def setUp(self): lib_set = { @@ -24,6 +25,7 @@ class ELFResolverTest(unittest.TestCase): self.resolver = ELFResolver(lib_set, ['/system/lib', '/vendor/lib']) + def test_get_candidates(self): r = self.resolver diff --git a/vndk/tools/definition-tool/tests/test_elfdump.py b/vndk/tools/definition-tool/tests/test_elfdump.py index 2c0b2305d..c738fd8da 100755 --- a/vndk/tools/definition-tool/tests/test_elfdump.py +++ b/vndk/tools/definition-tool/tests/test_elfdump.py @@ -41,11 +41,13 @@ class ELFDumpTest(unittest.TestCase): cls._build_fixtures(cls.target_name) + @classmethod def tearDownClass(cls): if not test_dir_base: cls.tmp_dir.cleanup() + @classmethod def _build_fixtures(cls, target_name): target = cls.targets[target_name] @@ -97,6 +99,7 @@ class ELFDumpTest(unittest.TestCase): ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib', '-Wl,--enable-new-dtags']) + def _remove_size_lines(self, lines): """Remove file size information because they may vary.""" prefixes = ( @@ -109,6 +112,7 @@ class ELFDumpTest(unittest.TestCase): patt = re.compile('|'.join('(?:' + re.escape(x) +')' for x in prefixes)) return [line for line in lines if not patt.match(line)] + def _assert_equal_to_file(self, expected_file_name, actual): actual = actual.splitlines(True) expected_file_path = os.path.join(self.expected_dir, expected_file_name) @@ -117,10 +121,12 @@ class ELFDumpTest(unittest.TestCase): self.assertEqual(self._remove_size_lines(expected), self._remove_size_lines(actual)) + def _test_main_out(self): out_file = os.path.join(self.test_dir, 'main.out') self._assert_equal_to_file('main.out.txt', run_elf_dump(out_file)) + def _test_libtest(self, expected_file_name, lib_name): lib_file = os.path.join(self.test_dir, lib_name) self._assert_equal_to_file(expected_file_name, run_elf_dump(lib_file)) diff --git a/vndk/tools/definition-tool/tests/test_generic_refs.py b/vndk/tools/definition-tool/tests/test_generic_refs.py index c887d19d6..349debca5 100755 --- a/vndk/tools/definition-tool/tests/test_generic_refs.py +++ b/vndk/tools/definition-tool/tests/test_generic_refs.py @@ -39,6 +39,7 @@ class GenericRefsTest(unittest.TestCase): 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') @@ -60,6 +61,7 @@ class GenericRefsTest(unittest.TestCase): 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', @@ -75,6 +77,7 @@ class GenericRefsTest(unittest.TestCase): 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', @@ -87,6 +90,7 @@ class GenericRefsTest(unittest.TestCase): self.assertTrue(self.ref.is_equivalent_lib(libc_eq)) + def test_has_same_name_lib(self): self.assertTrue(self.ref.has_same_name_lib( MockLib('/vendor/lib/libc.so', {}))) diff --git a/vndk/tools/definition-tool/tests/test_module_info.py b/vndk/tools/definition-tool/tests/test_module_info.py index 2da17b40d..f36edb09d 100755 --- a/vndk/tools/definition-tool/tests/test_module_info.py +++ b/vndk/tools/definition-tool/tests/test_module_info.py @@ -18,6 +18,7 @@ class ModuleInfoTest(unittest.TestCase): m = ModuleInfo.load_from_path_or_default(None) self.assertEqual([], m.get_module_path('/system/lib64/libA.so')) + def test_get_module_path(self): json_path = os.path.join(SCRIPT_DIR, 'testdata', 'test_module_info', 'module-info.json') diff --git a/vndk/tools/definition-tool/tests/utils.py b/vndk/tools/definition-tool/tests/utils.py index 6c61a3467..c241dc577 100644 --- a/vndk/tools/definition-tool/tests/utils.py +++ b/vndk/tools/definition-tool/tests/utils.py @@ -16,14 +16,17 @@ class GraphBuilder(object): PT_VENDOR: 'vendor', } + _LIB_DIRS = { ELF.ELFCLASS32: 'lib', ELF.ELFCLASS64: 'lib64', } + def __init__(self): self.graph = ELFLinker() + def add_lib(self, partition, klass, name, dt_needed=[], exported_symbols=set(), imported_symbols=set(), extra_dir=None): @@ -44,18 +47,21 @@ class GraphBuilder(object): setattr(self, name + '_' + elf.elf_class_name, lib) return lib + def add_lib32(self, partition, name, dt_needed=[], exported_symbols=set(), imported_symbols=set(), extra_dir=None): return self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed, exported_symbols, imported_symbols, extra_dir) + def add_lib64(self, partition, name, dt_needed=[], exported_symbols=set(), imported_symbols=set(), extra_dir=None): return self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed, exported_symbols, imported_symbols, extra_dir) + def add_multilib(self, partition, name, dt_needed=[], exported_symbols=set(), imported_symbols=set(), extra_dir=None): @@ -67,6 +73,7 @@ class GraphBuilder(object): exported_symbols, imported_symbols, extra_dir) ) + def resolve(self, vndk_lib_dirs=None, ro_vndk_version=None): if vndk_lib_dirs is not None: self.graph.vndk_lib_dirs = vndk_lib_dirs diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py index 4e29986de..996e5b20d 100755 --- a/vndk/tools/definition-tool/vndk_definition_tool.py +++ b/vndk/tools/definition-tool/vndk_definition_tool.py @@ -314,22 +314,27 @@ class Elf_Sym(collections.namedtuple( SHN_UNDEF = 0 + @property def st_bind(self): return self.st_info >> 4 + @property def is_local(self): return self.st_bind == Elf_Sym.STB_LOCAL + @property def is_global(self): return self.st_bind == Elf_Sym.STB_GLOBAL + @property def is_weak(self): return self.st_bind == Elf_Sym.STB_WEAK + @property def is_undef(self): return self.st_shndx == Elf_Sym.SHN_UNDEF @@ -381,6 +386,7 @@ class ELF(object): EM_X86_64 = 62 EM_AARCH64 = 183 + def _create_elf_machines(d): elf_machine_ids = {} for key, value in d.items(): @@ -400,14 +406,17 @@ class ELF(object): return key raise KeyError(dst) + @staticmethod def get_ei_class_from_name(name): return ELF._dict_find_key_by_value(ELF._ELF_CLASS_NAMES, name) + @staticmethod def get_ei_data_from_name(name): return ELF._dict_find_key_by_value(ELF._ELF_DATA_NAMES, name) + @staticmethod def get_e_machine_from_name(name): return ELF._dict_find_key_by_value(ELF.ELF_MACHINES, name) @@ -440,41 +449,51 @@ class ELF(object): self.rw_seg_file_size = rw_seg_file_size self.rw_seg_mem_size = rw_seg_mem_size + def __repr__(self): args = (a + '=' + repr(getattr(self, a)) for a in self.__slots__) return 'ELF(' + ', '.join(args) + ')' + def __eq__(self, rhs): return all(getattr(self, a) == getattr(rhs, a) for a in self.__slots__) + @property def elf_class_name(self): return self._ELF_CLASS_NAMES.get(self.ei_class, 'None') + @property def elf_data_name(self): return self._ELF_DATA_NAMES.get(self.ei_data, 'None') + @property def elf_machine_name(self): return self.ELF_MACHINES.get(self.e_machine, str(self.e_machine)) + @property def is_32bit(self): return self.ei_class == ELF.ELFCLASS32 + @property def is_64bit(self): return self.ei_class == ELF.ELFCLASS64 + @property def sorted_exported_symbols(self): return sorted(list(self.exported_symbols)) + @property def sorted_imported_symbols(self): return sorted(list(self.imported_symbols)) + def dump(self, file=None): """Print parsed ELF information to the file""" file = file if file is not None else sys.stdout @@ -498,6 +517,7 @@ class ELF(object): for symbol in self.sorted_imported_symbols: print('IMP_SYMBOL\t' + symbol, file=file) + # Extract zero-terminated buffer slice. def _extract_zero_terminated_buf_slice(self, buf, offset): """Extract a zero-terminated buffer slice from the given offset""" @@ -506,6 +526,7 @@ class ELF(object): return buf[offset:] return buf[offset:end] + # Extract c-style interned string from the buffer. if sys.version_info >= (3, 0): def _extract_zero_terminated_str(self, buf, offset): @@ -517,6 +538,7 @@ class ELF(object): """Extract a c-style string from the given buffer and offset""" return intern(self._extract_zero_terminated_buf_slice(buf, offset)) + def _parse_from_buf_internal(self, buf): """Parse ELF image resides in the buffer""" @@ -695,6 +717,7 @@ class ELF(object): elif not ent.is_local: exp_symbols.add(symbol_name) + def _parse_from_buf(self, buf): """Parse ELF image resides in the buffer""" try: @@ -702,6 +725,7 @@ class ELF(object): except IndexError: raise ELFError('bad offset') + def _parse_from_file(self, path): """Parse ELF image from the file path""" with open(path, 'rb') as f: @@ -711,6 +735,7 @@ class ELF(object): with mmap(f.fileno(), st.st_size, access=ACCESS_READ) as image: self._parse_from_buf(image) + def _parse_from_dump_lines(self, path, lines): patt = re.compile('^([A-Za-z_]+)\t+(.*)$') for line_no, line in enumerate(lines): @@ -752,16 +777,19 @@ class ELF(object): print('error: {}: {}: unknown tag name: {}' .format(path, line_no + 1, key), file=sys.stderr) + def _parse_from_dump_file(self, path): """Load information from ELF dump file.""" with open(path, 'r') as f: self._parse_from_dump_lines(path, f) + def _parse_from_dump_buf(self, buf): """Load information from ELF dump buffer.""" self._parse_from_dump_lines(''.format(id(buf)), buf.splitlines()) + @staticmethod def load(path): """Create an ELF instance from the file path""" @@ -769,6 +797,7 @@ class ELF(object): elf._parse_from_file(path) return elf + @staticmethod def loads(buf): """Create an ELF instance from the buffer""" @@ -776,6 +805,7 @@ class ELF(object): elf._parse_from_buf(buf) return elf + @staticmethod def load_dump(path): """Create an ELF instance from a dump file path""" @@ -783,6 +813,7 @@ class ELF(object): elf._parse_from_dump_file(path) return elf + @staticmethod def load_dumps(buf): """Create an ELF instance from a dump file buffer""" @@ -790,6 +821,7 @@ class ELF(object): elf._parse_from_dump_buf(buf) return elf + def is_jni_lib(self): """Test whether the ELF file looks like a JNI library.""" for name in ['libnativehelper.so', 'libandroid_runtime.so']: @@ -1077,6 +1109,7 @@ class TaggedDict(object): _define_tag_constants(locals()) del _define_tag_constants + _TAG_ALIASES = { 'hl_ndk': 'fwk_only', # Treat HL-NDK as FWK-ONLY. 'sp_ndk': 'll_ndk', @@ -1094,6 +1127,7 @@ class TaggedDict(object): 'vndk_sp_private': 'vndk_sp_indirect_private', } + @classmethod def _normalize_tag(cls, tag): tag = tag.lower().replace('-', '_') @@ -1102,6 +1136,7 @@ class TaggedDict(object): raise ValueError('unknown lib tag ' + tag) return tag + _LL_NDK_VIS = {'ll_ndk', 'll_ndk_indirect'} _VNDK_SP_VIS = {'ll_ndk', 'vndk_sp', 'vndk_sp_indirect', 'vndk_sp_indirect_private', 'fwk_only_rs'} @@ -1134,10 +1169,12 @@ class TaggedDict(object): del _LL_NDK_VIS, _VNDK_SP_VIS, _FWK_ONLY_VIS, _SP_HAL_VIS + @classmethod def is_tag_visible(cls, from_tag, to_tag): return to_tag in cls._TAG_VISIBILITY[from_tag] + def __init__(self, vndk_lib_dirs=None): self._path_tag = dict() for tag in self.TAGS: @@ -1150,14 +1187,17 @@ class TaggedDict(object): self._vndk_suffixes = [VNDKLibDir.create_vndk_dir_suffix(version) for version in vndk_lib_dirs] + def add(self, tag, lib): lib_set = getattr(self, tag) lib_set.add(lib) self._path_tag[lib] = tag + def add_regex(self, tag, pattern): self._regex_patterns.append((re.compile(pattern), tag)) + def get_path_tag(self, lib): try: return self._path_tag[lib] @@ -1170,36 +1210,45 @@ class TaggedDict(object): return self.get_path_tag_default(lib) + def get_path_tag_default(self, lib): raise NotImplementedError() + def get_path_tag_bit(self, lib): return self.TAGS[self.get_path_tag(lib)] + def is_path_visible(self, from_lib, to_lib): return self.is_tag_visible(self.get_path_tag(from_lib), self.get_path_tag(to_lib)) + @staticmethod def is_ll_ndk(tag_bit): return bool(tag_bit & TaggedDict.LL_NDK) + @staticmethod def is_vndk_sp(tag_bit): return bool(tag_bit & TaggedDict.VNDK_SP) + @staticmethod def is_vndk_sp_indirect(tag_bit): return bool(tag_bit & TaggedDict.VNDK_SP_INDIRECT) + @staticmethod def is_vndk_sp_indirect_private(tag_bit): return bool(tag_bit & TaggedDict.VNDK_SP_INDIRECT_PRIVATE) + @staticmethod def is_fwk_only_rs(tag_bit): return bool(tag_bit & TaggedDict.FWK_ONLY_RS) + @staticmethod def is_sp_hal(tag_bit): return bool(tag_bit & TaggedDict.SP_HAL) @@ -1227,17 +1276,20 @@ class TaggedPathDict(TaggedDict): for row in reader: self.add(self._normalize_tag(row[tag_col]), row[path_col]) + @staticmethod def create_from_csv(fp, vndk_lib_dirs=None): d = TaggedPathDict(vndk_lib_dirs) d.load_from_csv(fp) return d + @staticmethod def create_from_csv_path(path, vndk_lib_dirs=None): with open(path, 'r') as fp: return TaggedPathDict.create_from_csv(fp, vndk_lib_dirs) + def _enumerate_paths_with_lib(self, pattern): if '${LIB}' in pattern: yield pattern.replace('${LIB}', 'lib') @@ -1245,6 +1297,7 @@ class TaggedPathDict(TaggedDict): else: yield pattern + def _enumerate_paths(self, pattern): if '${VNDK_VER}' not in pattern: for path in self._enumerate_paths_with_lib(pattern): @@ -1255,6 +1308,7 @@ class TaggedPathDict(TaggedDict): for path in self._enumerate_paths_with_lib(pattern_with_suffix): yield path + def add(self, tag, path): if path.startswith('[regex]'): super(TaggedPathDict, self).add_regex(tag, path[7:]) @@ -1262,6 +1316,7 @@ class TaggedPathDict(TaggedDict): for path in self._enumerate_paths(path): super(TaggedPathDict, self).add(tag, path) + def get_path_tag_default(self, path): return 'vnd_only' if path.startswith('/vendor') else 'fwk_only' @@ -1272,11 +1327,13 @@ class TaggedLibDict(object): for tag in TaggedDict.TAGS: setattr(self, tag, set()) + def add(self, tag, lib): lib_set = getattr(self, tag) lib_set.add(lib) self._path_tag[lib] = tag + @staticmethod def create_from_graph(graph, tagged_paths, generic_refs=None): d = TaggedLibDict() @@ -1294,12 +1351,14 @@ class TaggedLibDict(object): d.add('vnd_only', lib) return d + def get_path_tag(self, lib): try: return self._path_tag[lib] except KeyError: return self.get_path_tag_default(lib) + def get_path_tag_default(self, lib): return 'vnd_only' if lib.path.startswith('/vendor') else 'fwk_only' @@ -1672,6 +1731,7 @@ class ELFResolver(object): self.lib_set = lib_set self.default_search_path = default_search_path + def get_candidates(self, requester, name, dt_rpath=None, dt_runpath=None): # Search app-specific search paths. if _APP_DIR_PATTERNS.match(requester): @@ -1687,6 +1747,7 @@ class ELFResolver(object): for d in self.default_search_path: yield os.path.join(d, name) + def resolve(self, requester, name, dt_rpath=None, dt_runpath=None): for path in self.get_candidates(requester, name, dt_rpath, dt_runpath): try: @@ -1715,54 +1776,65 @@ class ELFLinkData(object): self.unresolved_dt_needed = [] self.linked_symbols = dict() + @property def is_ll_ndk(self): return TaggedDict.is_ll_ndk(self._tag_bit) + @property def is_vndk_sp(self): return TaggedDict.is_vndk_sp(self._tag_bit) + @property def is_vndk_sp_indirect(self): return TaggedDict.is_vndk_sp_indirect(self._tag_bit) + @property def is_vndk_sp_indirect_private(self): return TaggedDict.is_vndk_sp_indirect_private(self._tag_bit) + @property def is_fwk_only_rs(self): return TaggedDict.is_fwk_only_rs(self._tag_bit) + @property def is_sp_hal(self): return TaggedDict.is_sp_hal(self._tag_bit) + def add_needed_dep(self, dst): assert dst not in self.deps_needed_hidden assert self not in dst.users_needed_hidden self.deps_needed.add(dst) dst.users_needed.add(self) + def add_dlopen_dep(self, dst): assert dst not in self.deps_dlopen_hidden assert self not in dst.users_dlopen_hidden self.deps_dlopen.add(dst) dst.users_dlopen.add(self) + def hide_needed_dep(self, dst): self.deps_needed.remove(dst) dst.users_needed.remove(self) self.deps_needed_hidden.add(dst) dst.users_needed_hidden.add(self) + def hide_dlopen_dep(self, dst): self.deps_dlopen.remove(dst) dst.users_dlopen.remove(self) self.deps_dlopen_hidden.add(dst) dst.users_dlopen_hidden.add(self) + @property def num_deps(self): """Get the number of dependencies. If a library is linked by both @@ -1770,23 +1842,28 @@ class ELFLinkData(object): return (len(self.deps_needed) + len(self.deps_needed_hidden) + len(self.deps_dlopen) + len(self.deps_dlopen_hidden)) + @property def deps_all(self): return itertools.chain(self.deps_needed, self.deps_needed_hidden, self.deps_dlopen, self.deps_dlopen_hidden) + @property def deps_good(self): return itertools.chain(self.deps_needed, self.deps_dlopen) + @property def deps_needed_all(self): return itertools.chain(self.deps_needed, self.deps_needed_hidden) + @property def deps_dlopen_all(self): return itertools.chain(self.deps_dlopen, self.deps_dlopen_hidden) + @property def num_users(self): """Get the number of users. If a library is linked by both NEEDED and @@ -1794,34 +1871,42 @@ class ELFLinkData(object): return (len(self.users_needed) + len(self.users_needed_hidden) + len(self.users_dlopen) + len(self.users_dlopen_hidden)) + @property def users_all(self): return itertools.chain(self.users_needed, self.users_needed_hidden, self.users_dlopen, self.users_dlopen_hidden) + @property def users_good(self): return itertools.chain(self.users_needed, self.users_dlopen) + @property def users_needed_all(self): return itertools.chain(self.users_needed, self.users_needed_hidden) + @property def users_dlopen_all(self): return itertools.chain(self.users_dlopen, self.users_dlopen_hidden) + def has_dep(self, dst): return (dst in self.deps_needed or dst in self.deps_needed_hidden or dst in self.deps_dlopen or dst in self.deps_dlopen_hidden) + def has_user(self, dst): return (dst in self.users_needed or dst in self.users_needed_hidden or dst in self.users_dlopen or dst in self.users_dlopen_hidden) + def is_system_lib(self): return self.partition == PT_SYSTEM + def get_dep_linked_symbols(self, dep): symbols = set() for symbol, exp_lib in self.linked_symbols.items(): @@ -1829,6 +1914,7 @@ class ELFLinkData(object): symbols.add(symbol) return sorted(symbols) + def __lt__(self, rhs): return self.path < rhs.path @@ -1838,6 +1924,7 @@ def sorted_lib_path_list(libs): libs.sort() return libs + _VNDK_RESULT_FIELD_NAMES = ( 'll_ndk', 'll_ndk_indirect', 'vndk_sp', 'vndk_sp_unused', 'vndk_sp_indirect', @@ -1848,6 +1935,7 @@ _VNDK_RESULT_FIELD_NAMES = ( VNDKResult = defaultnamedtuple('VNDKResult', _VNDK_RESULT_FIELD_NAMES, set()) + _SIMPLE_VNDK_RESULT_FIELD_NAMES = ( 'vndk_sp', 'vndk_sp_ext', 'extra_vendor_libs') @@ -1859,12 +1947,15 @@ class ELFLibDict(defaultnamedtuple('ELFLibDict', ('lib32', 'lib64'), {})): def get_lib_dict(self, elf_class): return self[elf_class - 1] + def add(self, path, lib): self.get_lib_dict(lib.elf.ei_class)[path] = lib + def remove(self, lib): del self.get_lib_dict(lib.elf.ei_class)[lib.path] + def get(self, path, default=None): for lib_set in self: res = lib_set.get(path, None) @@ -1872,12 +1963,15 @@ class ELFLibDict(defaultnamedtuple('ELFLibDict', ('lib32', 'lib64'), {})): return res return default + def keys(self): return itertools.chain(self.lib32.keys(), self.lib64.keys()) + def values(self): return itertools.chain(self.lib32.values(), self.lib64.values()) + def items(self): return itertools.chain(self.lib32.items(), self.lib64.items()) @@ -1903,18 +1997,22 @@ class ELFLinker(object): self.ro_vndk_version = ro_vndk_version + def _add_lib_to_lookup_dict(self, lib): self.lib_pt[lib.partition].add(lib.path, lib) + def _remove_lib_from_lookup_dict(self, lib): self.lib_pt[lib.partition].remove(lib) + def add_lib(self, partition, path, elf): lib = ELFLinkData(partition, path, elf, self.tagged_paths.get_path_tag_bit(path)) self._add_lib_to_lookup_dict(lib) return lib + def add_dlopen_dep(self, src_path, dst_path): num_matches = 0 for elf_class in (ELF.ELFCLASS32, ELF.ELFCLASS64): @@ -1927,6 +2025,7 @@ class ELFLinker(object): raise ValueError('Failed to add dlopen dependency from {} to {}' .format(src_path, dst_path)) + def _get_libs_in_elf_class(self, elf_class, path): result = set() if '${LIB}' in path: @@ -1947,6 +2046,7 @@ class ELFLinker(object): result.add(lib) return result + def get_lib(self, path): for lib_set in self.lib_pt: lib = lib_set.get(path) @@ -1954,6 +2054,7 @@ class ELFLinker(object): return lib return None + def get_libs(self, paths, report_error=None): result = set() for path in paths: @@ -1966,23 +2067,27 @@ class ELFLinker(object): result.add(lib) return result + def all_libs(self): for lib_set in self.lib_pt: for lib in lib_set.values(): yield lib + def _compute_lib_dict(self, elf_class): res = dict() for lib_pt in self.lib_pt: res.update(lib_pt.get_lib_dict(elf_class)) return res + @staticmethod def _compile_path_matcher(root, subdirs): dirs = [os.path.normpath(os.path.join(root, i)) for i in subdirs] patts = ['(?:' + re.escape(i) + os.sep + ')' for i in dirs] return re.compile('|'.join(patts)) + def add_executables_in_dir(self, partition_name, partition, root, alter_partition, alter_subdirs, ignored_subdirs, scan_elf_files, unzip_files): @@ -2011,6 +2116,7 @@ class ELFLinker(object): else: self.add_lib(partition, short_path, elf) + def add_dlopen_deps(self, path): patt = re.compile('([^:]*):\\s*(.*)') with open(path, 'r') as dlopen_dep_file: @@ -2024,6 +2130,7 @@ class ELFLinker(object): print('error:{}:{}: {}.'.format(path, line_no, e), file=sys.stderr) + def _find_exported_symbol(self, symbol, libs): """Find the shared library with the exported symbol.""" for lib in libs: @@ -2031,6 +2138,7 @@ class ELFLinker(object): return lib return None + def _resolve_lib_imported_symbols(self, lib, imported_libs, generic_refs): """Resolve the imported symbols in a library.""" for symbol in lib.elf.imported_symbols: @@ -2044,6 +2152,7 @@ class ELFLinker(object): if not ref_lib or not symbol in ref_lib.exported_symbols: lib.imported_ext_symbols[imported_lib].add(symbol) + def _resolve_lib_dt_needed(self, lib, resolver): imported_libs = [] for dt_needed in lib.elf.dt_needed: @@ -2061,6 +2170,7 @@ class ELFLinker(object): imported_libs.append(dep) return imported_libs + def _resolve_lib_deps(self, lib, resolver, generic_refs): # Resolve DT_NEEDED entries. imported_libs = self._resolve_lib_dt_needed(lib, resolver) @@ -2076,6 +2186,7 @@ class ELFLinker(object): # Resolve imported symbols. self._resolve_lib_imported_symbols(lib, imported_libs, generic_refs) + def _resolve_lib_set_deps(self, lib_set, resolver, generic_refs): for lib in lib_set: self._resolve_lib_deps(lib, resolver, generic_refs) @@ -2088,6 +2199,7 @@ class ELFLinker(object): '/vendor/' + lib_dir, ] + def _get_vendor_search_paths(self, lib_dir, vndk_sp_dirs, vndk_dirs): vendor_lib_dirs = [ '/vendor/' + lib_dir + '/hw', @@ -2212,6 +2324,7 @@ class ELFLinker(object): return SPLibResult(sp_hal, sp_hal_dep, vndk_sp_hal, ll_ndk, ll_ndk_indirect, vndk_sp_both) + def normalize_partition_tags(self, sp_hals, generic_refs): def is_system_lib_or_sp_hal(lib): return lib.is_system_lib() or lib in sp_hals @@ -2237,6 +2350,7 @@ class ELFLinker(object): file=sys.stderr) lib.hide_dlopen_dep(dep) + @staticmethod def _parse_action_on_ineligible_lib(arg): follow = False @@ -2252,6 +2366,7 @@ class ELFLinker(object): raise ValueError('unknown action \"{}\"'.format(flag)) return (follow, warn) + def compute_degenerated_vndk(self, generic_refs, tagged_paths=None, action_ineligible_vndk_sp='warn', action_ineligible_vndk='warn'): @@ -2529,6 +2644,7 @@ class ELFLinker(object): vndk_sp_indirect_ext=vndk_sp_indirect_ext, extra_vendor_libs=extra_vendor_libs) + @staticmethod def _compute_closure(root_set, is_excluded, get_successors): closure = set(root_set) @@ -2543,6 +2659,7 @@ class ELFLinker(object): stack.append(succ) return closure + @classmethod def compute_deps_closure(cls, root_set, is_excluded, ignore_hidden_deps=False): @@ -2550,6 +2667,7 @@ class ELFLinker(object): (lambda x: x.deps_all) return cls._compute_closure(root_set, is_excluded, get_successors) + @classmethod def compute_users_closure(cls, root_set, is_excluded, ignore_hidden_users=False): @@ -2557,6 +2675,7 @@ class ELFLinker(object): (lambda x: x.users_all) return cls._compute_closure(root_set, is_excluded, get_successors) + @staticmethod def _create_internal(scan_elf_files, system_dirs, system_dirs_as_vendor, system_dirs_ignored, vendor_dirs, @@ -2591,6 +2710,7 @@ class ELFLinker(object): return graph + @staticmethod def create(system_dirs=None, system_dirs_as_vendor=None, system_dirs_ignored=None, vendor_dirs=None, @@ -2614,14 +2734,17 @@ class GenericRefs(object): EXPORT_SUPER_SET = 2 MODIFIED = 3 + def __init__(self): self.refs = dict() self._lib_names = set() + def add(self, path, elf): self.refs[path] = elf self._lib_names.add(os.path.basename(path)) + def _load_from_sym_dir(self, root): root = os.path.abspath(root) prefix_len = len(root) + 1 @@ -2633,24 +2756,28 @@ class GenericRefs(object): lib_path = '/' + path[prefix_len:-4] self.add(lib_path, ELF.load_dump(path)) + @staticmethod def create_from_sym_dir(root): result = GenericRefs() result._load_from_sym_dir(root) return result + def _load_from_image_dir(self, root, prefix): root = os.path.abspath(root) root_len = len(root) + 1 for path, elf in scan_elf_files(root): self.add(os.path.join(prefix, path[root_len:]), elf) + @staticmethod def create_from_image_dir(root, prefix): result = GenericRefs() result._load_from_image_dir(root, prefix) return result + def classify_lib(self, lib): ref_lib = self.refs.get(lib.path) if not ref_lib: @@ -2662,9 +2789,11 @@ class GenericRefs(object): return GenericRefs.EXPORT_SUPER_SET return GenericRefs.MODIFIED + def is_equivalent_lib(self, lib): return self.classify_lib(lib) == GenericRefs.EXPORT_EQUAL + def has_same_name_lib(self, lib): return os.path.basename(lib.path) in self._lib_names @@ -2802,13 +2931,16 @@ class ModuleInfo(object): self._mods = {installed_path: sorted(src_dirs) for installed_path, src_dirs in mods.items()} + def get_module_path(self, installed_path): return self._mods.get(installed_path, []) + @staticmethod def load(f): return ModuleInfo(json.load(f)) + @staticmethod def load_from_path_or_default(path): if not path: @@ -2838,9 +2970,11 @@ class ELFDumpCommand(Command): super(ELFDumpCommand, self).__init__( 'elfdump', help='Dump ELF .dynamic section') + def add_argparser_options(self, parser): parser.add_argument('path', help='path to an ELF file') + def main(self, args): try: ELF.load(args.path).dump() @@ -2856,12 +2990,14 @@ class CreateGenericRefCommand(Command): super(CreateGenericRefCommand, self).__init__( 'create-generic-ref', help='Create generic references') + def add_argparser_options(self, parser): parser.add_argument('dir') parser.add_argument('-o', '--output', required=True, help='output directory') + def main(self, args): root = os.path.abspath(args.dir) print(root) @@ -2926,6 +3062,7 @@ class ELFGraphCommand(Command): '--tag-file', required=is_tag_file_required, help='lib tag file') + def get_generic_refs_from_args(self, args): if args.load_generic_refs: return GenericRefs.create_from_sym_dir(args.load_generic_refs) @@ -2934,6 +3071,7 @@ class ELFGraphCommand(Command): args.aosp_system, '/system') return None + def _check_arg_dir_exists(self, arg_name, dirs): for path in dirs: if not os.path.exists(path): @@ -2945,10 +3083,12 @@ class ELFGraphCommand(Command): .format(path, arg_name), file=sys.stderr) sys.exit(1) + def check_dirs_from_args(self, args): self._check_arg_dir_exists('--system', args.system) self._check_arg_dir_exists('--vendor', args.vendor) + def create_from_args(self, args): self.check_dirs_from_args(args) @@ -2992,6 +3132,7 @@ class VNDKCommandBase(ELFGraphCommand): help='action when a vendor lib/exe uses fwk-only libs ' '(option: follow,warn,ignore)') + def create_from_args(self, args): """Create all essential data structures for VNDK computation.""" @@ -3012,6 +3153,7 @@ class VNDKCommand(VNDKCommandBase): super(VNDKCommand, self).__init__( 'vndk', help='Compute VNDK libraries set') + def add_argparser_options(self, parser): super(VNDKCommand, self).add_argparser_options(parser) @@ -3031,6 +3173,7 @@ class VNDKCommand(VNDKCommandBase): '--file-size-output', help='output file for calculated file sizes') + def _warn_incorrect_partition_lib_set(self, lib_set, partition, error_msg): for lib in lib_set.values(): if not lib.num_users: @@ -3038,6 +3181,7 @@ class VNDKCommand(VNDKCommandBase): if all((user.partition != partition for user in lib.users_all)): print(error_msg.format(lib.path), file=sys.stderr) + def _warn_incorrect_partition(self, graph): self._warn_incorrect_partition_lib_set( graph.lib_pt[PT_VENDOR], PT_VENDOR, @@ -3049,6 +3193,7 @@ class VNDKCommand(VNDKCommandBase): 'warning: {}: This is a framework library with vendor-only ' 'usages.') + @staticmethod def _extract_simple_vndk_result(vndk_result): field_name_tags = [ @@ -3069,6 +3214,7 @@ class VNDKCommand(VNDKCommandBase): getattr(results, tag).update(getattr(vndk_result, field_name)) return results + def _print_tags(self, vndk_lib, full, file=sys.stdout): if full: result_tags = _VNDK_RESULT_FIELD_NAMES @@ -3084,6 +3230,7 @@ class VNDKCommand(VNDKCommandBase): for lib in sorted_lib_path_list(libs): print(tag, lib, file=file) + def _print_make(self, vndk_lib, file=sys.stdout): def get_module_name(path): return os.path.splitext(os.path.basename(path))[0] @@ -3113,6 +3260,7 @@ class VNDKCommand(VNDKCommandBase): file.write(template) + def _print_file_size_output(self, graph, vndk_lib, file=sys.stderr): def collect_tags(lib): tags = [] @@ -3177,6 +3325,7 @@ class VNDKCommand(VNDKCommandBase): writer.writerow(SEPARATOR) writer.writerow(['Total', None] + calc_total_size(graph.all_libs())) + def main(self, args): generic_refs, graph, tagged_paths, _ = self.create_from_args(args) @@ -3206,6 +3355,7 @@ class DepsInsightCommand(VNDKCommandBase): super(DepsInsightCommand, self).__init__( 'deps-insight', help='Generate HTML to show dependencies') + def add_argparser_options(self, parser): super(DepsInsightCommand, self).add_argparser_options(parser) @@ -3214,6 +3364,7 @@ class DepsInsightCommand(VNDKCommandBase): parser.add_argument('-o', '--output', required=True, help='output directory') + @staticmethod def serialize_data(libs, vndk_lib, module_info): strs = [] @@ -3279,6 +3430,7 @@ class DepsInsightCommand(VNDKCommandBase): return (strs, mods) + def main(self, args): generic_refs, graph, tagged_paths, _ = self.create_from_args(args) @@ -3316,6 +3468,7 @@ class DepsCommand(ELFGraphCommand): super(DepsCommand, self).__init__( 'deps', help='Print binary dependencies for debugging') + def add_argparser_options(self, parser): super(DepsCommand, self).add_argparser_options(parser) @@ -3337,6 +3490,7 @@ class DepsCommand(ELFGraphCommand): parser.add_argument('--module-info') + def main(self, args): _, graph, _, _ = self.create_from_args(args) @@ -3399,6 +3553,7 @@ class DepsClosureCommand(ELFGraphCommand): super(DepsClosureCommand, self).__init__( 'deps-closure', help='Find transitive closure of dependencies') + def add_argparser_options(self, parser): super(DepsClosureCommand, self).add_argparser_options(parser) @@ -3417,6 +3572,7 @@ class DepsClosureCommand(ELFGraphCommand): parser.add_argument('--enumerate', action='store_true', help='print closure for each lib instead of union') + def print_deps_closure(self, root_libs, graph, is_excluded_libs, is_reverted, indent): if is_reverted: @@ -3464,11 +3620,13 @@ class DepsUnresolvedCommand(ELFGraphCommand): 'deps-unresolved', help='Show unresolved dt_needed entries or symbols') + def add_argparser_options(self, parser): super(DepsUnresolvedCommand, self).add_argparser_options(parser) parser.add_argument('--module-info') parser.add_argument('--path-filter') + def _dump_unresolved(self, lib, module_info, delimiter): if not lib.unresolved_symbols and not lib.unresolved_dt_needed: return @@ -3482,6 +3640,7 @@ class DepsUnresolvedCommand(ELFGraphCommand): for symbol in sorted(lib.unresolved_symbols): print('\tUNRESOLVED_SYMBOL:', symbol) + def main(self, args): _, graph, _, _ = self.create_from_args(args) module_info = ModuleInfo.load_from_path_or_default(args.module_info) @@ -3502,6 +3661,7 @@ class ApkDepsCommand(ELFGraphCommand): super(ApkDepsCommand, self).__init__( 'apk-deps', help='Print APK dependencies for debugging') + def main(self, args): _, graph, _, _ = self.create_from_args(args) @@ -3520,14 +3680,17 @@ class CheckDepCommandBase(ELFGraphCommand): super(CheckDepCommandBase, self).__init__(*args, **kwargs) self.delimiter = '' + def add_argparser_options(self, parser): super(CheckDepCommandBase, self).add_argparser_options(parser) parser.add_argument('--module-info') + def _print_delimiter(self): print(self.delimiter, end='') self.delimiter = '\n' + def _dump_dep(self, lib, bad_deps, module_info): self._print_delimiter() print(lib.path) @@ -3540,6 +3703,7 @@ class CheckDepCommandBase(ELFGraphCommand): for symbol in lib.get_dep_linked_symbols(dep): print('\t\t' + symbol) + def _dump_apk_dep(self, apk_path, bad_deps, module_info): self._print_delimiter() print(apk_path) From c7bf9936da7664832c2d1b1da22c8823f9a8e470 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 18:18:50 +0800 Subject: [PATCH 4/9] vndk-def: Fix spacing errors found by pylint This commit fixes several spacing errors (e.g. indention, and space-after-comma) that are found by pylint. Test: ./tests/run.py Change-Id: I830a9cddc91e21421b16c2a1d1a101c0beb7af62 --- .../definition-tool/tests/ndk_toolchain.py | 68 ++++++------ .../tests/test_command_deps_insight.py | 2 +- .../definition-tool/tests/test_elf_linker.py | 38 +++---- .../tests/test_elf_resolver.py | 78 ++++++------- .../definition-tool/tests/test_elfdump.py | 18 +-- .../definition-tool/tests/test_module_info.py | 2 +- .../definition-tool/tests/test_tagged_dict.py | 61 +++++----- vndk/tools/definition-tool/tests/test_vndk.py | 6 +- .../tests/test_vndk_lib_dir.py | 104 +++++++++--------- .../definition-tool/vndk_definition_tool.py | 18 +-- 10 files changed, 199 insertions(+), 196 deletions(-) diff --git a/vndk/tools/definition-tool/tests/ndk_toolchain.py b/vndk/tools/definition-tool/tests/ndk_toolchain.py index 485b1b85c..3411e4c85 100755 --- a/vndk/tools/definition-tool/tests/ndk_toolchain.py +++ b/vndk/tools/definition-tool/tests/ndk_toolchain.py @@ -87,7 +87,7 @@ class Target(object): return False ld_exeutable = os.path.join( - self.gcc_toolchain_dir, 'bin', self.target_triple + '-ld') + self.gcc_toolchain_dir, 'bin', self.target_triple + '-ld') success = check_path(self.gcc_toolchain_dir) success &= check_path(ld_exeutable) @@ -146,55 +146,55 @@ def create_targets(ndk_dir=None, api=None, host=None): targets = collections.OrderedDict() targets['arm'] = Target( - 'arm', 'arm-linux-androideabi', [],[], - get_gcc_dir(ndk_dir, 'arm-linux-androideabi-4.9', host), - get_clang_dir(ndk_dir, host), - get_platform_dir(ndk_dir, api, ['arch-arm', 'usr', 'include']), - get_platform_dir(ndk_dir, api, ['arch-arm', 'usr', 'lib'])) + 'arm', 'arm-linux-androideabi', [], [], + get_gcc_dir(ndk_dir, 'arm-linux-androideabi-4.9', host), + get_clang_dir(ndk_dir, host), + get_platform_dir(ndk_dir, api, ['arch-arm', 'usr', 'include']), + get_platform_dir(ndk_dir, api, ['arch-arm', 'usr', 'lib'])) targets['arm64'] = Target( - 'arm64', 'aarch64-linux-android', [], [], - get_gcc_dir(ndk_dir, 'aarch64-linux-android-4.9', host), - get_clang_dir(ndk_dir, host), - get_platform_dir(ndk_dir, api, ['arch-arm64', 'usr', 'include']), - get_platform_dir(ndk_dir, api, ['arch-arm64', 'usr', 'lib'])) + 'arm64', 'aarch64-linux-android', [], [], + get_gcc_dir(ndk_dir, 'aarch64-linux-android-4.9', host), + get_clang_dir(ndk_dir, host), + get_platform_dir(ndk_dir, api, ['arch-arm64', 'usr', 'include']), + get_platform_dir(ndk_dir, api, ['arch-arm64', 'usr', 'lib'])) targets['x86'] = Target( - 'x86', 'i686-linux-android', ['-m32'], ['-m32'], - get_gcc_dir(ndk_dir, 'x86-4.9', host), - get_clang_dir(ndk_dir, host), - get_platform_dir(ndk_dir, api, ['arch-x86', 'usr', 'include']), - get_platform_dir(ndk_dir, api, ['arch-x86', 'usr', 'lib'])) + 'x86', 'i686-linux-android', ['-m32'], ['-m32'], + get_gcc_dir(ndk_dir, 'x86-4.9', host), + get_clang_dir(ndk_dir, host), + get_platform_dir(ndk_dir, api, ['arch-x86', 'usr', 'include']), + get_platform_dir(ndk_dir, api, ['arch-x86', 'usr', 'lib'])) targets['x86_64'] = Target( - 'x86_64', 'x86_64-linux-android', ['-m64'], ['-m64'], - get_gcc_dir(ndk_dir, 'x86_64-4.9', host), - get_clang_dir(ndk_dir, host), - get_platform_dir(ndk_dir, api, ['arch-x86_64', 'usr', 'include']), - get_platform_dir(ndk_dir, api, ['arch-x86_64', 'usr', 'lib64'])) + 'x86_64', 'x86_64-linux-android', ['-m64'], ['-m64'], + get_gcc_dir(ndk_dir, 'x86_64-4.9', host), + get_clang_dir(ndk_dir, host), + get_platform_dir(ndk_dir, api, ['arch-x86_64', 'usr', 'include']), + get_platform_dir(ndk_dir, api, ['arch-x86_64', 'usr', 'lib64'])) targets['mips'] = Target( - 'mips', 'mipsel-linux-android', [], [], - get_gcc_dir(ndk_dir, 'mipsel-linux-android-4.9', host), - get_clang_dir(ndk_dir, host), - get_platform_dir(ndk_dir, api, ['arch-mips', 'usr', 'include']), - get_platform_dir(ndk_dir, api, ['arch-mips', 'usr', 'lib'])) + 'mips', 'mipsel-linux-android', [], [], + get_gcc_dir(ndk_dir, 'mipsel-linux-android-4.9', host), + get_clang_dir(ndk_dir, host), + get_platform_dir(ndk_dir, api, ['arch-mips', 'usr', 'include']), + get_platform_dir(ndk_dir, api, ['arch-mips', 'usr', 'lib'])) targets['mips64'] = Target( - 'mips64', 'mips64el-linux-android', - ['-march=mips64el', '-mcpu=mips64r6'], - ['-march=mips64el', '-mcpu=mips64r6'], - get_gcc_dir(ndk_dir, 'mips64el-linux-android-4.9', host), - get_clang_dir(ndk_dir, host), - get_platform_dir(ndk_dir, api, ['arch-mips64', 'usr', 'include']), - get_platform_dir(ndk_dir, api, ['arch-mips64', 'usr', 'lib64'])) + 'mips64', 'mips64el-linux-android', + ['-march=mips64el', '-mcpu=mips64r6'], + ['-march=mips64el', '-mcpu=mips64r6'], + get_gcc_dir(ndk_dir, 'mips64el-linux-android-4.9', host), + get_clang_dir(ndk_dir, host), + get_platform_dir(ndk_dir, api, ['arch-mips64', 'usr', 'include']), + get_platform_dir(ndk_dir, api, ['arch-mips64', 'usr', 'lib64'])) return targets def main(): parser = argparse.ArgumentParser( - description='Dry-run NDK toolchain detection') + description='Dry-run NDK toolchain detection') parser.add_argument('--ndk-dir') parser.add_argument('--api-level') parser.add_argument('--host') diff --git a/vndk/tools/definition-tool/tests/test_command_deps_insight.py b/vndk/tools/definition-tool/tests/test_command_deps_insight.py index d0b0bb198..7777826ff 100755 --- a/vndk/tools/definition-tool/tests/test_command_deps_insight.py +++ b/vndk/tools/definition-tool/tests/test_command_deps_insight.py @@ -71,7 +71,7 @@ class DepsInsightCommandTest(unittest.TestCase): self.assertNotIn(libvnd_bad, libvndk_sp.deps_good) strs, mods = DepsInsightCommand.serialize_data( - list(gb.graph.all_libs()), vndk_sets, ModuleInfo()) + list(gb.graph.all_libs()), vndk_sets, ModuleInfo()) deps = self._get_module_deps(strs, mods, libvndk.path) self.assertIn(libvnd_bad.path, deps) diff --git a/vndk/tools/definition-tool/tests/test_elf_linker.py b/vndk/tools/definition-tool/tests/test_elf_linker.py index 01038a06e..52f4a9145 100755 --- a/vndk/tools/definition-tool/tests/test_elf_linker.py +++ b/vndk/tools/definition-tool/tests/test_elf_linker.py @@ -393,36 +393,36 @@ class ELFLinkerTest(unittest.TestCase): libc_32, libc_64 = gb.add_multilib(PT_SYSTEM, 'libc') libvndk_a_32, libvndk_a_64 = gb.add_multilib( - PT_SYSTEM, 'libvndk_a', extra_dir='vndk-28', - dt_needed=['libc.so', 'libvndk_b.so', 'libvndk_sp_b.so']) + PT_SYSTEM, 'libvndk_a', extra_dir='vndk-28', + dt_needed=['libc.so', 'libvndk_b.so', 'libvndk_sp_b.so']) libvndk_b_32, libvndk_b_64 = gb.add_multilib( - PT_SYSTEM, 'libvndk_b', extra_dir='vndk-28', - dt_needed=['libc.so', 'libvndk_sp_b.so']) + PT_SYSTEM, 'libvndk_b', extra_dir='vndk-28', + dt_needed=['libc.so', 'libvndk_sp_b.so']) libvndk_c_32, libvndk_c_64 = gb.add_multilib( - PT_VENDOR, 'libvndk_c', extra_dir='vndk-28', - dt_needed=['libc.so', 'libvndk_d.so', 'libvndk_sp_d.so']) + PT_VENDOR, 'libvndk_c', extra_dir='vndk-28', + dt_needed=['libc.so', 'libvndk_d.so', 'libvndk_sp_d.so']) libvndk_d_32, libvndk_d_64 = gb.add_multilib( - PT_VENDOR, 'libvndk_d', extra_dir='vndk-28', - dt_needed=['libc.so', 'libvndk_sp_d.so']) + PT_VENDOR, 'libvndk_d', extra_dir='vndk-28', + dt_needed=['libc.so', 'libvndk_sp_d.so']) libvndk_sp_a_32, libvndk_sp_a_64 = gb.add_multilib( - PT_SYSTEM, 'libvndk_sp_a', extra_dir='vndk-sp-28', - dt_needed=['libc.so', 'libvndk_sp_b.so']) + PT_SYSTEM, 'libvndk_sp_a', extra_dir='vndk-sp-28', + dt_needed=['libc.so', 'libvndk_sp_b.so']) libvndk_sp_b_32, libvndk_sp_b_64 = gb.add_multilib( - PT_SYSTEM, 'libvndk_sp_b', extra_dir='vndk-sp-28', - dt_needed=['libc.so']) + PT_SYSTEM, 'libvndk_sp_b', extra_dir='vndk-sp-28', + dt_needed=['libc.so']) libvndk_sp_c_32, libvndk_sp_c_64 = gb.add_multilib( - PT_VENDOR, 'libvndk_sp_c', extra_dir='vndk-sp-28', - dt_needed=['libc.so', 'libvndk_sp_d.so']) + PT_VENDOR, 'libvndk_sp_c', extra_dir='vndk-sp-28', + dt_needed=['libc.so', 'libvndk_sp_d.so']) libvndk_sp_d_32, libvndk_sp_d_64 = gb.add_multilib( - PT_VENDOR, 'libvndk_sp_d', extra_dir='vndk-sp-28', - dt_needed=['libc.so']) + PT_VENDOR, 'libvndk_sp_d', extra_dir='vndk-sp-28', + dt_needed=['libc.so']) gb.resolve(VNDKLibDir.create_from_version('28'), '28') @@ -561,9 +561,9 @@ class ELFLinkerDlopenDepsTest(unittest.TestCase): gb.graph.add_dlopen_deps(tmp_file.name) self.assertRegexpMatches( - stderr.getvalue(), - 'error:' + re.escape(tmp_file.name) + ':1: ' + - 'Failed to add dlopen dependency from .* to .*\\.\n') + stderr.getvalue(), + 'error:' + re.escape(tmp_file.name) + ':1: ' + + 'Failed to add dlopen dependency from .* to .*\\.\n') if __name__ == '__main__': diff --git a/vndk/tools/definition-tool/tests/test_elf_resolver.py b/vndk/tools/definition-tool/tests/test_elf_resolver.py index 30bab9f7c..9ca0fd538 100755 --- a/vndk/tools/definition-tool/tests/test_elf_resolver.py +++ b/vndk/tools/definition-tool/tests/test_elf_resolver.py @@ -30,46 +30,46 @@ class ELFResolverTest(unittest.TestCase): r = self.resolver self.assertEqual( - ['/system/lib/libx.so', '/vendor/lib/libx.so'], - list(r.get_candidates('/system/lib/libreq.so', 'libx.so'))) + ['/system/lib/libx.so', '/vendor/lib/libx.so'], + list(r.get_candidates('/system/lib/libreq.so', 'libx.so'))) self.assertEqual( - ['/C/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'], - list(r.get_candidates('/system/lib/libreq.so', 'libx.so', - ['/C']))) + ['/C/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'], + list(r.get_candidates('/system/lib/libreq.so', 'libx.so', ['/C']))) self.assertEqual( - ['/C/libx.so', '/D/libx.so', '/system/lib/libx.so', - '/vendor/lib/libx.so'], - list(r.get_candidates('/system/lib/libreq.so', 'libx.so', - ['/C', '/D']))) + ['/C/libx.so', '/D/libx.so', '/system/lib/libx.so', + '/vendor/lib/libx.so'], + list(r.get_candidates('/system/lib/libreq.so', 'libx.so', + ['/C', '/D']))) self.assertEqual( - ['/E/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'], - list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None, - ['/E']))) + ['/E/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'], + list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None, + ['/E']))) self.assertEqual( - ['/E/libx.so', '/F/libx.so', '/system/lib/libx.so', - '/vendor/lib/libx.so'], - list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None, - ['/E', '/F']))) + ['/E/libx.so', '/F/libx.so', '/system/lib/libx.so', + '/vendor/lib/libx.so'], + list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None, + ['/E', '/F']))) self.assertEqual( - ['/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so', - '/system/lib/libx.so', '/vendor/lib/libx.so'], - list(r.get_candidates('/system/lib/libreq.so', 'libx.so', - ['/C', '/D'], ['/E', '/F']))) + ['/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so', + '/system/lib/libx.so', '/vendor/lib/libx.so'], + list(r.get_candidates('/system/lib/libreq.so', 'libx.so', + ['/C', '/D'], ['/E', '/F']))) # Test app-specific search paths. self.assertEqual( - ['/system/app/example/lib/armeabi-v7a/libx.so', - '/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so', - '/system/lib/libx.so', '/vendor/lib/libx.so'], - list(r.get_candidates( - '/system/app/example/lib/armeabi-v7a/libreq.so', - 'libx.so', - ['/C', '/D'], ['/E', '/F']))) + ['/system/app/example/lib/armeabi-v7a/libx.so', + '/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so', + '/system/lib/libx.so', '/vendor/lib/libx.so'], + list(r.get_candidates( + '/system/app/example/lib/armeabi-v7a/libreq.so', + 'libx.so', + ['/C', '/D'], ['/E', '/F']))) + def test_resolve(self): r = self.resolver @@ -78,22 +78,22 @@ class ELFResolverTest(unittest.TestCase): self.assertEqual(None, r.resolve('/system/lib/libreq.so', 'libe.so')) self.assertEqual( - 'e', - r.resolve('/system/lib/libreq.so', 'libe.so', - dt_rpath=['/system/lib/hw'])) + 'e', + r.resolve('/system/lib/libreq.so', 'libe.so', + dt_rpath=['/system/lib/hw'])) self.assertEqual( - 'e', - r.resolve('/system/lib/libreq.so', 'libe.so', - dt_runpath=['/system/lib/hw'])) + 'e', + r.resolve('/system/lib/libreq.so', 'libe.so', + dt_runpath=['/system/lib/hw'])) self.assertEqual( - 'a2', - r.resolve('/system/lib/libreq.so', 'liba.so', - dt_rpath=['/vendor/lib'])) + 'a2', + r.resolve('/system/lib/libreq.so', 'liba.so', + dt_rpath=['/vendor/lib'])) self.assertEqual( - 'a2', - r.resolve('/system/lib/libreq.so', 'liba.so', - dt_runpath=['/vendor/lib'])) + 'a2', + r.resolve('/system/lib/libreq.so', 'liba.so', + dt_runpath=['/vendor/lib'])) if __name__ == '__main__': diff --git a/vndk/tools/definition-tool/tests/test_elfdump.py b/vndk/tools/definition-tool/tests/test_elfdump.py index c738fd8da..888c2d246 100755 --- a/vndk/tools/definition-tool/tests/test_elfdump.py +++ b/vndk/tools/definition-tool/tests/test_elfdump.py @@ -18,7 +18,7 @@ import ndk_toolchain SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) VNDK_DEF_TOOL = os.path.join(SCRIPT_DIR, '..', 'vndk_definition_tool.py') -INPUT_DIR = os.path.join(SCRIPT_DIR ,'testdata', 'test_elfdump', 'input') +INPUT_DIR = os.path.join(SCRIPT_DIR, 'testdata', 'test_elfdump', 'input') EXPECTED_DIR = os.path.join(SCRIPT_DIR, 'testdata', 'test_elfdump', 'expected') test_dir_base = None @@ -155,14 +155,14 @@ def create_target_test(target_name): class_name = 'ELFDumpTest_' + target_name globals()[class_name] = type( - class_name, (ELFDumpTest,), - dict(test_main=test_main, - test_libtest=test_libtest, - test_libtest_rpath=test_libtest_rpath, - test_libtest_rpath_multi=test_libtest_rpath_multi, - test_libtest_runpath=test_libtest_runpath, - test_libtest_runpath_multi=test_libtest_runpath_multi, - target_name=target_name)) + class_name, (ELFDumpTest,), + dict(test_main=test_main, + test_libtest=test_libtest, + test_libtest_rpath=test_libtest_rpath, + test_libtest_rpath_multi=test_libtest_rpath_multi, + test_libtest_runpath=test_libtest_runpath, + test_libtest_runpath_multi=test_libtest_runpath_multi, + target_name=target_name)) for target in ('arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'): diff --git a/vndk/tools/definition-tool/tests/test_module_info.py b/vndk/tools/definition-tool/tests/test_module_info.py index f36edb09d..d44a9eb6f 100755 --- a/vndk/tools/definition-tool/tests/test_module_info.py +++ b/vndk/tools/definition-tool/tests/test_module_info.py @@ -34,7 +34,7 @@ class ModuleInfoTest(unittest.TestCase): m.get_module_path('/system/lib64/hw/libC.so')) self.assertEqual( - [], m.get_module_path('/system/lib64/libdoes_not_exist.so')) + [], m.get_module_path('/system/lib64/libdoes_not_exist.so')) if __name__ == '__main__': diff --git a/vndk/tools/definition-tool/tests/test_tagged_dict.py b/vndk/tools/definition-tool/tests/test_tagged_dict.py index 58ec396e3..9ca027141 100755 --- a/vndk/tools/definition-tool/tests/test_tagged_dict.py +++ b/vndk/tools/definition-tool/tests/test_tagged_dict.py @@ -103,37 +103,38 @@ class TaggedPathDictTest(unittest.TestCase): tagged_paths = TaggedPathDict() self.assertEqual( - ['/system/lib/libc.so'], - list(tagged_paths._enumerate_paths('/system/lib/libc.so'))) + ['/system/lib/libc.so'], + list(tagged_paths._enumerate_paths('/system/lib/libc.so'))) self.assertEqual( - ['/system/lib/libc.so', '/system/lib64/libc.so'], - list(tagged_paths._enumerate_paths('/system/${LIB}/libc.so'))) + ['/system/lib/libc.so', '/system/lib64/libc.so'], + list(tagged_paths._enumerate_paths('/system/${LIB}/libc.so'))) self.assertEqual( - ['/system/lib/vndk/libutils.so', - '/system/lib64/vndk/libutils.so'], - list(tagged_paths._enumerate_paths( - '/system/${LIB}/vndk${VNDK_VER}/libutils.so'))) + ['/system/lib/vndk/libutils.so', + '/system/lib64/vndk/libutils.so'], + list(tagged_paths._enumerate_paths( + '/system/${LIB}/vndk${VNDK_VER}/libutils.so'))) tagged_paths = TaggedPathDict(['current', '27', '28']) self.assertEqual( - ['/system/lib/vndk/libutils.so', - '/system/lib64/vndk/libutils.so', - '/system/lib/vndk-27/libutils.so', - '/system/lib64/vndk-27/libutils.so', - '/system/lib/vndk-28/libutils.so', - '/system/lib64/vndk-28/libutils.so'], - list(tagged_paths._enumerate_paths( - '/system/${LIB}/vndk${VNDK_VER}/libutils.so'))) + ['/system/lib/vndk/libutils.so', + '/system/lib64/vndk/libutils.so', + '/system/lib/vndk-27/libutils.so', + '/system/lib64/vndk-27/libutils.so', + '/system/lib/vndk-28/libutils.so', + '/system/lib64/vndk-28/libutils.so'], + list(tagged_paths._enumerate_paths( + '/system/${LIB}/vndk${VNDK_VER}/libutils.so'))) self.assertEqual( - ['/system/lib/vndk/libutils.so', - '/system/lib/vndk-27/libutils.so', - '/system/lib/vndk-28/libutils.so'], - list(tagged_paths._enumerate_paths( - '/system/lib/vndk${VNDK_VER}/libutils.so'))) + ['/system/lib/vndk/libutils.so', + '/system/lib/vndk-27/libutils.so', + '/system/lib/vndk-28/libutils.so'], + list(tagged_paths._enumerate_paths( + '/system/lib/vndk${VNDK_VER}/libutils.so'))) + def test_load_from_csv_empty(self): try: @@ -218,8 +219,8 @@ class TaggedPathDictTest(unittest.TestCase): self.assertEqual('vndk_sp_indirect', d.get_path_tag('/system/lib/lib_vndk_sp_indirect.so')) self.assertEqual( - 'vndk_sp_indirect_private', - d.get_path_tag('/system/lib/lib_vndk_sp_indirect_private.so')) + 'vndk_sp_indirect_private', + d.get_path_tag('/system/lib/lib_vndk_sp_indirect_private.so')) self.assertEqual('vndk', d.get_path_tag('/system/lib/lib_vndk.so')) self.assertEqual('fwk_only', d.get_path_tag('/system/lib/lib_fwk_only.so')) @@ -368,17 +369,19 @@ class MockELFGraph(object): def __init__(self): self.lib_pt = [dict() for i in range(NUM_PARTITIONS)] + def add(self, path): partition = PT_VENDOR if path.startswith('/vendor') else PT_SYSTEM lib = MockELFLinkData(path) self.lib_pt[partition][path] = lib return lib + def compute_sp_lib(self, generic_refs=None): vendor_libs = self.lib_pt[PT_VENDOR].values() return MockSPLibResult( - set(v for v in vendor_libs if 'lib_sp_hal.so' in v.path), - set(v for v in vendor_libs if 'lib_sp_hal_dep.so' in v.path)) + set(v for v in vendor_libs if 'lib_sp_hal.so' in v.path), + set(v for v in vendor_libs if 'lib_sp_hal_dep.so' in v.path)) class TaggedLibDictTest(unittest.TestCase): @@ -389,13 +392,13 @@ class TaggedLibDictTest(unittest.TestCase): self.lib_ll_ndk = self.graph.add('/system/lib/lib_ll_ndk.so') self.lib_ll_ndk_indirect = \ - self.graph.add('/system/lib/lib_ll_ndk_indirect.so') + self.graph.add('/system/lib/lib_ll_ndk_indirect.so') self.lib_vndk_sp = self.graph.add('/system/lib/lib_vndk_sp.so') self.lib_vndk_sp_indirect = \ - self.graph.add('/system/lib/lib_vndk_sp_indirect.so') + self.graph.add('/system/lib/lib_vndk_sp_indirect.so') self.lib_vndk_sp_indirect_private = \ - self.graph.add('/system/lib/lib_vndk_sp_indirect_private.so') + self.graph.add('/system/lib/lib_vndk_sp_indirect_private.so') self.lib_vndk = self.graph.add('/system/lib/lib_vndk.so') @@ -408,7 +411,7 @@ class TaggedLibDictTest(unittest.TestCase): self.lib_vnd_only = self.graph.add('/vendor/lib/lib_vnd_only.so') self.tagged_libs = TaggedLibDict.create_from_graph( - self.graph, self.tagged_paths) + self.graph, self.tagged_paths) def test_create_from_graph(self): diff --git a/vndk/tools/definition-tool/tests/test_vndk.py b/vndk/tools/definition-tool/tests/test_vndk.py index 196a15b9f..f8fafa51c 100755 --- a/vndk/tools/definition-tool/tests/test_vndk.py +++ b/vndk/tools/definition-tool/tests/test_vndk.py @@ -32,9 +32,9 @@ class ELFLinkerVNDKTest(unittest.TestCase): gb.graph.normalize_partition_tags(set(), None) self.assertRegexpMatches( - stderr.getvalue(), - 'error: .*: system exe/lib must not depend on vendor lib .*. ' - 'Assume such dependency does not exist.') + stderr.getvalue(), + 'error: .*: system exe/lib must not depend on vendor lib .*. ' + 'Assume such dependency does not exist.') self.assertNotIn(libvnd, libfwk.deps_needed) self.assertNotIn(libfwk, libvnd.users_needed) diff --git a/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py b/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py index 0a323e597..6eb1e5fc7 100755 --- a/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py +++ b/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py @@ -22,92 +22,92 @@ class VNDKLibDirTest(unittest.TestCase): def test_create_vndk_sp_dir_name(self): self.assertEqual( - 'vndk-sp', VNDKLibDir.create_vndk_sp_dir_name('current')) + 'vndk-sp', VNDKLibDir.create_vndk_sp_dir_name('current')) self.assertEqual( - 'vndk-sp-28', VNDKLibDir.create_vndk_sp_dir_name('28')) + 'vndk-sp-28', VNDKLibDir.create_vndk_sp_dir_name('28')) def test_create_vndk_dir_name(self): self.assertEqual( - 'vndk', VNDKLibDir.create_vndk_dir_name('current')) + 'vndk', VNDKLibDir.create_vndk_dir_name('current')) self.assertEqual( - 'vndk-28', VNDKLibDir.create_vndk_dir_name('28')) + 'vndk-28', VNDKLibDir.create_vndk_dir_name('28')) def test_extract_vndk_version_from_name(self): self.assertEqual( - 'current', VNDKLibDir.extract_version_from_name('vndk')) + 'current', VNDKLibDir.extract_version_from_name('vndk')) self.assertEqual( - 'current', VNDKLibDir.extract_version_from_name('vndk-sp')) + 'current', VNDKLibDir.extract_version_from_name('vndk-sp')) self.assertEqual( - '28', VNDKLibDir.extract_version_from_name('vndk-28')) + '28', VNDKLibDir.extract_version_from_name('vndk-28')) self.assertEqual( - '28', VNDKLibDir.extract_version_from_name('vndk-sp-28')) + '28', VNDKLibDir.extract_version_from_name('vndk-sp-28')) self.assertEqual( - 'p', VNDKLibDir.extract_version_from_name('vndk-p')) + 'p', VNDKLibDir.extract_version_from_name('vndk-p')) self.assertEqual( - 'p', VNDKLibDir.extract_version_from_name('vndk-sp-p')) + 'p', VNDKLibDir.extract_version_from_name('vndk-sp-p')) def test_extract_vndk_version_from_path(self): ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/vndk/libexample.so') + '/system/lib64/vndk/libexample.so') self.assertEqual('current', ans) ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/vndk-sp/libexample.so') + '/system/lib64/vndk-sp/libexample.so') self.assertEqual('current', ans) ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/vndk-28/libexample.so') + '/system/lib64/vndk-28/libexample.so') self.assertEqual('28', ans) ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/vndk-sp-28/libexample.so') + '/system/lib64/vndk-sp-28/libexample.so') self.assertEqual('28', ans) ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/vndk-p/libexample.so') + '/system/lib64/vndk-p/libexample.so') self.assertEqual('p', ans) ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/vndk-sp-p/libexample.so') + '/system/lib64/vndk-sp-p/libexample.so') self.assertEqual('p', ans) ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/vndk-sp-p/hw/libexample.so') + '/system/lib64/vndk-sp-p/hw/libexample.so') self.assertEqual('p', ans) ans = VNDKLibDir.extract_version_from_path( - '/system/lib64/libexample.so') + '/system/lib64/libexample.so') self.assertEqual(None, ans) def test_is_in_vndk_sp_dir(self): self.assertFalse(VNDKLibDir.is_in_vndk_sp_dir('/system/lib/liba.so')) self.assertFalse( - VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk/liba.so')) + VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk/liba.so')) self.assertFalse( - VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-28/liba.so')) + VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-28/liba.so')) self.assertFalse( - VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-spec/liba.so')) + VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-spec/liba.so')) self.assertTrue( - VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-sp/liba.so')) + VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-sp/liba.so')) self.assertTrue( - VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-sp-28/liba.so')) + VNDKLibDir.is_in_vndk_sp_dir('/system/lib/vndk-sp-28/liba.so')) def test_is_in_vndk_dir(self): self.assertFalse(VNDKLibDir.is_in_vndk_dir('/system/lib/liba.so')) self.assertTrue(VNDKLibDir.is_in_vndk_dir('/system/lib/vndk/liba.so')) self.assertTrue( - VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-28/liba.so')) + VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-28/liba.so')) self.assertTrue( - VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-spec/liba.so')) + VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-spec/liba.so')) self.assertFalse( - VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-sp/liba.so')) + VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-sp/liba.so')) self.assertFalse( - VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-sp-28/liba.so')) + VNDKLibDir.is_in_vndk_dir('/system/lib/vndk-sp-28/liba.so')) def test_create_vndk_search_paths(self): @@ -126,7 +126,7 @@ class VNDKLibDirTest(unittest.TestCase): ] vndk_sp_dirs, vndk_dirs = \ - VNDKLibDir.create_vndk_search_paths(lib_dir, version) + VNDKLibDir.create_vndk_search_paths(lib_dir, version) self.assertEqual(expected_vndk_sp, vndk_sp_dirs) self.assertEqual(expected_vndk, vndk_dirs) @@ -139,35 +139,34 @@ class VNDKLibDirTest(unittest.TestCase): def test_create_from_dirs_unversioned(self): input_dir = os.path.join( - SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', - 'vndk_unversioned') + SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', 'vndk_unversioned') vndk_lib_dirs = VNDKLibDir.create_from_dirs( - [os.path.join(input_dir, 'system')], - [os.path.join(input_dir, 'vendor')]) + [os.path.join(input_dir, 'system')], + [os.path.join(input_dir, 'vendor')]) self.assertIn('current', vndk_lib_dirs) def test_create_from_dirs_versioned(self): input_dir = os.path.join( - SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', 'vndk_versioned') + SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', 'vndk_versioned') vndk_lib_dirs = VNDKLibDir.create_from_dirs( - [os.path.join(input_dir, 'system')], - [os.path.join(input_dir, 'vendor')]) + [os.path.join(input_dir, 'system')], + [os.path.join(input_dir, 'vendor')]) self.assertIn('28', vndk_lib_dirs) def test_create_from_dirs_versioned_multiple(self): input_dir = os.path.join( - SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', - 'vndk_versioned_multiple') + SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', + 'vndk_versioned_multiple') vndk_lib_dirs = VNDKLibDir.create_from_dirs( - [os.path.join(input_dir, 'system')], - [os.path.join(input_dir, 'vendor')]) + [os.path.join(input_dir, 'system')], + [os.path.join(input_dir, 'vendor')]) self.assertIn('28', vndk_lib_dirs) self.assertIn('29', vndk_lib_dirs) @@ -175,11 +174,11 @@ class VNDKLibDirTest(unittest.TestCase): def test_create_from_dirs_versioned_32bit_only(self): input_dir = os.path.join( - SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', 'vndk_32') + SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', 'vndk_32') vndk_lib_dirs = VNDKLibDir.create_from_dirs( - [os.path.join(input_dir, 'system')], - [os.path.join(input_dir, 'vendor')]) + [os.path.join(input_dir, 'system')], + [os.path.join(input_dir, 'vendor')]) self.assertIn('28', vndk_lib_dirs) @@ -196,8 +195,8 @@ class VNDKLibDirTest(unittest.TestCase): def test_get_ro_vndk_version(self): input_dir = os.path.join( - SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', - 'vndk_versioned_multiple') + SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', + 'vndk_versioned_multiple') vendor_dirs = [os.path.join(input_dir, 'vendor')] @@ -206,21 +205,20 @@ class VNDKLibDirTest(unittest.TestCase): def test_sorted_versions(self): self.assertEqual( - ['20', '10', '2', '1'], - VNDKLibDir.sorted_version(['1', '2', '10', '20'])) + ['20', '10', '2', '1'], + VNDKLibDir.sorted_version(['1', '2', '10', '20'])) self.assertEqual( - ['b', 'a', '20', '10', '2', '1'], - VNDKLibDir.sorted_version(['1', '2', '10', '20', 'a', 'b'])) + ['b', 'a', '20', '10', '2', '1'], + VNDKLibDir.sorted_version(['1', '2', '10', '20', 'a', 'b'])) self.assertEqual( - ['a', '10b', '10', '2', '1'], - VNDKLibDir.sorted_version(['1', '2', '10', 'a', '10b'])) + ['a', '10b', '10', '2', '1'], + VNDKLibDir.sorted_version(['1', '2', '10', 'a', '10b'])) self.assertEqual( - ['current', 'd', 'a', '10', '1'], - VNDKLibDir.sorted_version(['1', '10', 'a', 'd', 'current'])) - + ['current', 'd', 'a', '10', '1'], + VNDKLibDir.sorted_version(['1', '10', 'a', 'd', 'current'])) if __name__ == '__main__': diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py index 996e5b20d..ea3ee662a 100755 --- a/vndk/tools/definition-tool/vndk_definition_tool.py +++ b/vndk/tools/definition-tool/vndk_definition_tool.py @@ -1926,21 +1926,23 @@ def sorted_lib_path_list(libs): _VNDK_RESULT_FIELD_NAMES = ( - 'll_ndk', 'll_ndk_indirect', - 'vndk_sp', 'vndk_sp_unused', 'vndk_sp_indirect', - 'vndk_sp_indirect_unused', 'vndk_sp_indirect_private', 'vndk', - 'vndk_indirect', 'fwk_only', 'fwk_only_rs', 'sp_hal', 'sp_hal_dep', - 'vnd_only', 'vndk_ext', 'vndk_sp_ext', 'vndk_sp_indirect_ext', - 'extra_vendor_libs') + 'll_ndk', 'll_ndk_indirect', + 'vndk_sp', 'vndk_sp_unused', 'vndk_sp_indirect', + 'vndk_sp_indirect_unused', 'vndk_sp_indirect_private', 'vndk', + 'vndk_indirect', 'fwk_only', 'fwk_only_rs', 'sp_hal', 'sp_hal_dep', + 'vnd_only', 'vndk_ext', 'vndk_sp_ext', 'vndk_sp_indirect_ext', + 'extra_vendor_libs') + VNDKResult = defaultnamedtuple('VNDKResult', _VNDK_RESULT_FIELD_NAMES, set()) _SIMPLE_VNDK_RESULT_FIELD_NAMES = ( - 'vndk_sp', 'vndk_sp_ext', 'extra_vendor_libs') + 'vndk_sp', 'vndk_sp_ext', 'extra_vendor_libs') + SimpleVNDKResult = defaultnamedtuple( - 'SimpleVNDKResult', _SIMPLE_VNDK_RESULT_FIELD_NAMES, set()) + 'SimpleVNDKResult', _SIMPLE_VNDK_RESULT_FIELD_NAMES, set()) class ELFLibDict(defaultnamedtuple('ELFLibDict', ('lib32', 'lib64'), {})): From eaacaac29de8cd22a4a1d4227a9f4f84b718e1fd Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 18:43:26 +0800 Subject: [PATCH 5/9] vndk-def: Cleanup import pylint errors Test: ./tests/run.sh Change-Id: I6fc9fcef8164fb1f795f5902d900f34e99b1228d --- vndk/tools/definition-tool/tests/compat.py | 4 ++- .../definition-tool/tests/ndk_toolchain.py | 24 -------------- vndk/tools/definition-tool/tests/run.py | 21 ------------ vndk/tools/definition-tool/tests/run.sh | 22 +++++++++++++ .../tests/test_command_deps_insight.py | 13 ++------ .../definition-tool/tests/test_dex_file.py | 10 ++---- vndk/tools/definition-tool/tests/test_elf.py | 11 ++----- .../tests/test_elf_link_data.py | 8 ----- .../definition-tool/tests/test_elf_linker.py | 16 ++-------- .../tests/test_elf_resolver.py | 8 ----- .../definition-tool/tests/test_elfdump.py | 32 ++----------------- .../tests/test_generic_refs.py | 9 ------ .../definition-tool/tests/test_module_info.py | 7 ---- .../definition-tool/tests/test_tagged_dict.py | 11 ++----- vndk/tools/definition-tool/tests/test_vndk.py | 13 ++------ .../tests/test_vndk_lib_dir.py | 10 ++---- vndk/tools/definition-tool/tests/utils.py | 7 +--- 17 files changed, 46 insertions(+), 180 deletions(-) mode change 100755 => 100644 vndk/tools/definition-tool/tests/ndk_toolchain.py delete mode 100755 vndk/tools/definition-tool/tests/run.py create mode 100755 vndk/tools/definition-tool/tests/run.sh mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_command_deps_insight.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_dex_file.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_elf.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_elf_link_data.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_elf_linker.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_elf_resolver.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_elfdump.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_generic_refs.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_module_info.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_tagged_dict.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_vndk.py mode change 100755 => 100644 vndk/tools/definition-tool/tests/test_vndk_lib_dir.py diff --git a/vndk/tools/definition-tool/tests/compat.py b/vndk/tools/definition-tool/tests/compat.py index 7fcbc2e93..71841ecf7 100644 --- a/vndk/tools/definition-tool/tests/compat.py +++ b/vndk/tools/definition-tool/tests/compat.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 -import os +# pylint: disable=unused-import,import-error + import sys @@ -37,6 +38,7 @@ except ImportError: if sys.version_info >= (3, 0): from os import makedirs else: + import os def makedirs(path, exist_ok): if exist_ok and os.path.exists(path): return diff --git a/vndk/tools/definition-tool/tests/ndk_toolchain.py b/vndk/tools/definition-tool/tests/ndk_toolchain.py old mode 100755 new mode 100644 index 3411e4c85..e040787dd --- a/vndk/tools/definition-tool/tests/ndk_toolchain.py +++ b/vndk/tools/definition-tool/tests/ndk_toolchain.py @@ -2,7 +2,6 @@ from __future__ import print_function -import argparse import collections import os import re @@ -190,26 +189,3 @@ def create_targets(ndk_dir=None, api=None, host=None): get_platform_dir(ndk_dir, api, ['arch-mips64', 'usr', 'lib64'])) return targets - - -def main(): - parser = argparse.ArgumentParser( - description='Dry-run NDK toolchain detection') - parser.add_argument('--ndk-dir') - parser.add_argument('--api-level') - parser.add_argument('--host') - args = parser.parse_args() - - targets = create_targets(args.ndk_dir, args.api_level, args.host) - - success = True - for name, target in targets.items(): - success &= target.check_paths() - if not success: - sys.exit(1) - - print('succeed') - - -if __name__ == '__main__': - main() diff --git a/vndk/tools/definition-tool/tests/run.py b/vndk/tools/definition-tool/tests/run.py deleted file mode 100755 index 2837d5cef..000000000 --- a/vndk/tools/definition-tool/tests/run.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os -import unittest - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--verbose', '-v', action='store_true') - args = parser.parse_args() - - verbosity = 2 if args.verbose else 1 - - loader = unittest.TestLoader() - tests = loader.discover(os.path.dirname(__file__), 'test_*.py') - runner = unittest.runner.TextTestRunner(verbosity=verbosity) - runner.run(tests) - -if __name__ == '__main__': - main() diff --git a/vndk/tools/definition-tool/tests/run.sh b/vndk/tools/definition-tool/tests/run.sh new file mode 100755 index 000000000..3a3114567 --- /dev/null +++ b/vndk/tools/definition-tool/tests/run.sh @@ -0,0 +1,22 @@ +#!/bin/bash -ex + +# +# Copyright (C) 2018 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +cd "$(dirname "$0")/.." + +python3 -m unittest discover "$@" +python -m unittest discover "$@" diff --git a/vndk/tools/definition-tool/tests/test_command_deps_insight.py b/vndk/tools/definition-tool/tests/test_command_deps_insight.py old mode 100755 new mode 100644 index 7777826ff..9e8332a55 --- a/vndk/tools/definition-tool/tests/test_command_deps_insight.py +++ b/vndk/tools/definition-tool/tests/test_command_deps_insight.py @@ -2,16 +2,13 @@ from __future__ import print_function -import os -import sys import unittest -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -from compat import StringIO, patch from vndk_definition_tool import ( DepsInsightCommand, ModuleInfo, PT_SYSTEM, PT_VENDOR) -from utils import GraphBuilder + +from .compat import StringIO, patch +from .utils import GraphBuilder class DepsInsightCommandTest(unittest.TestCase): @@ -82,7 +79,3 @@ class DepsInsightCommandTest(unittest.TestCase): users = self._get_module_users(strs, mods, libvnd_bad.path) self.assertIn(libvndk.path, users) self.assertIn(libvndk_sp.path, users) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_dex_file.py b/vndk/tools/definition-tool/tests/test_dex_file.py old mode 100755 new mode 100644 index fe2644fef..c558fa9ab --- a/vndk/tools/definition-tool/tests/test_dex_file.py +++ b/vndk/tools/definition-tool/tests/test_dex_file.py @@ -4,15 +4,13 @@ from __future__ import print_function import os import subprocess -import sys import unittest import zipfile -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -from compat import TemporaryDirectory from vndk_definition_tool import DexFileReader, UnicodeSurrogateDecodeError +from .compat import TemporaryDirectory + SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) INPUT_DIR = os.path.join(SCRIPT_DIR, 'testdata', 'test_dex_file') @@ -122,7 +120,3 @@ class DexFileTest(unittest.TestCase): self.assertIn(b'world', strs) self.assertIn(b'foo', strs) self.assertIn(b'bar', strs) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_elf.py b/vndk/tools/definition-tool/tests/test_elf.py old mode 100755 new mode 100644 index 160911d0e..035a1af54 --- a/vndk/tools/definition-tool/tests/test_elf.py +++ b/vndk/tools/definition-tool/tests/test_elf.py @@ -2,16 +2,13 @@ from __future__ import print_function -import os -import sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - import tempfile import unittest -from compat import StringIO from vndk_definition_tool import Elf_Sym, ELF +from .compat import StringIO + class ElfSymTest(unittest.TestCase): def setUp(self): @@ -223,7 +220,3 @@ class ELFJniLibTest(unittest.TestCase): elf = ELF(exported_symbols={'printf'}) self.assertFalse(elf.is_jni_lib()) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_elf_link_data.py b/vndk/tools/definition-tool/tests/test_elf_link_data.py old mode 100755 new mode 100644 index 98ae69243..7191919aa --- a/vndk/tools/definition-tool/tests/test_elf_link_data.py +++ b/vndk/tools/definition-tool/tests/test_elf_link_data.py @@ -2,10 +2,6 @@ from __future__ import print_function -import os -import sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - import unittest from vndk_definition_tool import ELFLinkData, PT_SYSTEM, PT_VENDOR @@ -108,7 +104,3 @@ class ELFLinkDataTest(unittest.TestCase): self.assertEqual(['w', 'x', 'y', 'z'], self.x.get_dep_linked_symbols(self.z)) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_elf_linker.py b/vndk/tools/definition-tool/tests/test_elf_linker.py old mode 100755 new mode 100644 index 52f4a9145..c553705d8 --- a/vndk/tools/definition-tool/tests/test_elf_linker.py +++ b/vndk/tools/definition-tool/tests/test_elf_linker.py @@ -1,20 +1,14 @@ #!/usr/bin/env python3 -import os import re -import sys import tempfile import unittest -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -from compat import StringIO, patch -from utils import GraphBuilder from vndk_definition_tool import ( - ELF, ELFLinker, GenericRefs, PT_SYSTEM, PT_VENDOR, VNDKLibDir) + ELF, GenericRefs, PT_SYSTEM, PT_VENDOR, VNDKLibDir) - -SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +from .compat import StringIO, patch +from .utils import GraphBuilder class ELFLinkerTest(unittest.TestCase): @@ -564,7 +558,3 @@ class ELFLinkerDlopenDepsTest(unittest.TestCase): stderr.getvalue(), 'error:' + re.escape(tmp_file.name) + ':1: ' + 'Failed to add dlopen dependency from .* to .*\\.\n') - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_elf_resolver.py b/vndk/tools/definition-tool/tests/test_elf_resolver.py old mode 100755 new mode 100644 index 9ca0fd538..f6257f5fb --- a/vndk/tools/definition-tool/tests/test_elf_resolver.py +++ b/vndk/tools/definition-tool/tests/test_elf_resolver.py @@ -2,10 +2,6 @@ from __future__ import print_function -import os -import sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - import unittest from vndk_definition_tool import ELFResolver @@ -94,7 +90,3 @@ class ELFResolverTest(unittest.TestCase): 'a2', r.resolve('/system/lib/libreq.so', 'liba.so', dt_runpath=['/vendor/lib'])) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_elfdump.py b/vndk/tools/definition-tool/tests/test_elfdump.py old mode 100755 new mode 100644 index 888c2d246..18db2fd96 --- a/vndk/tools/definition-tool/tests/test_elfdump.py +++ b/vndk/tools/definition-tool/tests/test_elfdump.py @@ -2,17 +2,14 @@ from __future__ import print_function -import argparse -import collections -import difflib import os import re import subprocess import sys import unittest -from compat import TemporaryDirectory, makedirs -import ndk_toolchain +from .compat import TemporaryDirectory, makedirs +from .ndk_toolchain import create_targets SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -31,7 +28,7 @@ def run_elf_dump(path): class ELFDumpTest(unittest.TestCase): @classmethod def setUpClass(cls): - cls.targets = ndk_toolchain.create_targets() + cls.targets = create_targets() if test_dir_base: cls.test_dir_base = test_dir_base @@ -167,26 +164,3 @@ def create_target_test(target_name): for target in ('arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'): create_target_test(target) - - -def main(): - # Parse command line arguments. - parser = argparse.ArgumentParser() - parser.add_argument('--test-dir', help='directory for temporary files') - parser.add_argument('--expected-dir', help='directory with expected output') - args, unittest_args = parser.parse_known_args() - - # Convert command line options. - global expected_dir - global test_dir_base - - if args.expected_dir: - expected_dir = args.expected_dir - if args.test_dir: - test_dir_base = args.test_dir - - # Run unit test. - unittest.main(argv=[sys.argv[0]] + unittest_args) - -if __name__ == '__main__': - main() diff --git a/vndk/tools/definition-tool/tests/test_generic_refs.py b/vndk/tools/definition-tool/tests/test_generic_refs.py old mode 100755 new mode 100644 index 349debca5..c3afeaecc --- a/vndk/tools/definition-tool/tests/test_generic_refs.py +++ b/vndk/tools/definition-tool/tests/test_generic_refs.py @@ -3,13 +3,8 @@ from __future__ import print_function import os -import sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -import argparse import unittest -from compat import TemporaryDirectory, makedirs from vndk_definition_tool import GenericRefs @@ -96,7 +91,3 @@ class GenericRefsTest(unittest.TestCase): MockLib('/vendor/lib/libc.so', {}))) self.assertFalse(self.ref.has_same_name_lib( MockLib('/vendor/lib/lib_does_not_exist.so', {}))) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_module_info.py b/vndk/tools/definition-tool/tests/test_module_info.py old mode 100755 new mode 100644 index d44a9eb6f..b9a7cdddd --- a/vndk/tools/definition-tool/tests/test_module_info.py +++ b/vndk/tools/definition-tool/tests/test_module_info.py @@ -3,9 +3,6 @@ from __future__ import print_function import os -import sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - import unittest from vndk_definition_tool import ModuleInfo @@ -35,7 +32,3 @@ class ModuleInfoTest(unittest.TestCase): self.assertEqual( [], m.get_module_path('/system/lib64/libdoes_not_exist.so')) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_tagged_dict.py b/vndk/tools/definition-tool/tests/test_tagged_dict.py old mode 100755 new mode 100644 index 9ca027141..1dce19b80 --- a/vndk/tools/definition-tool/tests/test_tagged_dict.py +++ b/vndk/tools/definition-tool/tests/test_tagged_dict.py @@ -2,17 +2,14 @@ from __future__ import print_function -import os -import sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - import tempfile import unittest -from compat import StringIO from vndk_definition_tool import TaggedDict, TaggedPathDict, TaggedLibDict, \ NUM_PARTITIONS, PT_SYSTEM, PT_VENDOR +from .compat import StringIO + _TEST_DATA = '''Path,Tag /system/lib/lib_ll_ndk.so,ll-ndk @@ -459,7 +456,3 @@ class TaggedLibDictTest(unittest.TestCase): self.assertEqual('fwk_only', tag) tag = d.get_path_tag(MockELFLinkData('/vendor/lib/unknown.so')) self.assertEqual('vnd_only', tag) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_vndk.py b/vndk/tools/definition-tool/tests/test_vndk.py old mode 100755 new mode 100644 index f8fafa51c..d85e2a2ed --- a/vndk/tools/definition-tool/tests/test_vndk.py +++ b/vndk/tools/definition-tool/tests/test_vndk.py @@ -2,15 +2,12 @@ from __future__ import print_function -import os -import sys import unittest -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from vndk_definition_tool import (PT_SYSTEM, PT_VENDOR) -from compat import StringIO, patch -from vndk_definition_tool import (ELF, ELFLinker, PT_SYSTEM, PT_VENDOR) -from utils import GraphBuilder +from .compat import StringIO, patch +from .utils import GraphBuilder class ELFLinkerVNDKTest(unittest.TestCase): @@ -136,7 +133,3 @@ class ELFLinkerVNDKTest(unittest.TestCase): self.assertIn(libEGL_chipset, vndk_sets.sp_hal) self.assertNotIn(libEGL_chipset, vndk_sets.ll_ndk_indirect) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py b/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py old mode 100755 new mode 100644 index 6eb1e5fc7..a1a2a8c29 --- a/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py +++ b/vndk/tools/definition-tool/tests/test_vndk_lib_dir.py @@ -2,13 +2,11 @@ import os import posixpath -import sys import unittest -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from vndk_definition_tool import VNDKLibDir -from compat import StringIO -from vndk_definition_tool import ELF, VNDKLibDir +from .compat import StringIO SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -219,7 +217,3 @@ class VNDKLibDirTest(unittest.TestCase): self.assertEqual( ['current', 'd', 'a', '10', '1'], VNDKLibDir.sorted_version(['1', '10', 'a', 'd', 'current'])) - - -if __name__ == '__main__': - unittest.main() diff --git a/vndk/tools/definition-tool/tests/utils.py b/vndk/tools/definition-tool/tests/utils.py index c241dc577..6f7d751f2 100644 --- a/vndk/tools/definition-tool/tests/utils.py +++ b/vndk/tools/definition-tool/tests/utils.py @@ -1,13 +1,8 @@ #!/usr/bin/env python3 import os -import sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -from compat import StringIO -from vndk_definition_tool import ( - ELF, ELFLinker, PT_SYSTEM, PT_VENDOR, VNDKLibDir) +from vndk_definition_tool import (ELF, ELFLinker, PT_SYSTEM, PT_VENDOR) class GraphBuilder(object): From 0b8758197f764c401956504e8ac43a90fb44a01d Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 19:44:39 +0800 Subject: [PATCH 6/9] vndk-def: Fix deprecated warning in unittest This commit adds a TestCase compatibility layer to support `assertRegex` and `assertNotRegex` in both Python 2.7 and 3.5. This removes a deprecated warning while running test cases with Python 3.5. Test: ./tests/run.sh Change-Id: I9856b08f18ae92d110f37f75d444f09692f08acf --- vndk/tools/definition-tool/tests/compat.py | 17 +++++++++++++++++ .../definition-tool/tests/test_elf_linker.py | 9 ++++----- vndk/tools/definition-tool/tests/test_vndk.py | 8 +++----- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/vndk/tools/definition-tool/tests/compat.py b/vndk/tools/definition-tool/tests/compat.py index 71841ecf7..a17ea9205 100644 --- a/vndk/tools/definition-tool/tests/compat.py +++ b/vndk/tools/definition-tool/tests/compat.py @@ -67,3 +67,20 @@ except ImportError: yield finally: setattr(obj, attr, original_value) + + +if sys.version_info >= (3, 2): + from unittest import TestCase +else: + import unittest + + + class TestCase(unittest.TestCase): + def assertRegex(self, text, expected_regex, msg=None): + # pylint: disable=deprecated-method + self.assertRegexpMatches(text, expected_regex, msg) + + + def assertNotRegex(self, text, unexpected_regex, msg=None): + # pylint: disable=deprecated-method + self.assertNotRegexpMatches(text, unexpected_regex, msg) diff --git a/vndk/tools/definition-tool/tests/test_elf_linker.py b/vndk/tools/definition-tool/tests/test_elf_linker.py index c553705d8..0316c9ba9 100644 --- a/vndk/tools/definition-tool/tests/test_elf_linker.py +++ b/vndk/tools/definition-tool/tests/test_elf_linker.py @@ -2,16 +2,15 @@ import re import tempfile -import unittest from vndk_definition_tool import ( ELF, GenericRefs, PT_SYSTEM, PT_VENDOR, VNDKLibDir) -from .compat import StringIO, patch +from .compat import StringIO, TestCase, patch from .utils import GraphBuilder -class ELFLinkerTest(unittest.TestCase): +class ELFLinkerTest(TestCase): def _create_normal_graph(self): gb = GraphBuilder() @@ -461,7 +460,7 @@ class ELFLinkerTest(unittest.TestCase): self.assertIn(libvndk_sp_d_64, libvndk_sp_c_64.deps_all) -class ELFLinkerDlopenDepsTest(unittest.TestCase): +class ELFLinkerDlopenDepsTest(TestCase): def test_add_dlopen_deps(self): gb = GraphBuilder() liba = gb.add_lib32(PT_SYSTEM, 'liba') @@ -554,7 +553,7 @@ class ELFLinkerDlopenDepsTest(unittest.TestCase): with patch('sys.stderr', stderr): gb.graph.add_dlopen_deps(tmp_file.name) - self.assertRegexpMatches( + self.assertRegex( stderr.getvalue(), 'error:' + re.escape(tmp_file.name) + ':1: ' + 'Failed to add dlopen dependency from .* to .*\\.\n') diff --git a/vndk/tools/definition-tool/tests/test_vndk.py b/vndk/tools/definition-tool/tests/test_vndk.py index d85e2a2ed..67268e9ae 100644 --- a/vndk/tools/definition-tool/tests/test_vndk.py +++ b/vndk/tools/definition-tool/tests/test_vndk.py @@ -2,15 +2,13 @@ from __future__ import print_function -import unittest - from vndk_definition_tool import (PT_SYSTEM, PT_VENDOR) -from .compat import StringIO, patch +from .compat import StringIO, TestCase, patch from .utils import GraphBuilder -class ELFLinkerVNDKTest(unittest.TestCase): +class ELFLinkerVNDKTest(TestCase): def test_normalize_partition_tags_bad_vendor_deps(self): """Check whether normalize_partition_tags() hides the dependencies from the system partition to the vendor partition if the dependencies are @@ -28,7 +26,7 @@ class ELFLinkerVNDKTest(unittest.TestCase): with patch('sys.stderr', stderr): gb.graph.normalize_partition_tags(set(), None) - self.assertRegexpMatches( + self.assertRegex( stderr.getvalue(), 'error: .*: system exe/lib must not depend on vendor lib .*. ' 'Assume such dependency does not exist.') From a9c0e3793571ca22cb10fc0cc173d589090afd9e Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 19:46:43 +0800 Subject: [PATCH 7/9] vndk-def: Unhide a test case This commit unhide a test case in `test_dex_file.py`. The test case was hidden because the same method name was redefined. Test: ./tests/run.sh # 124 test cases Change-Id: Icf205d03e1b8db4a896aeb01615fa4993e73b4ce --- vndk/tools/definition-tool/tests/test_dex_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vndk/tools/definition-tool/tests/test_dex_file.py b/vndk/tools/definition-tool/tests/test_dex_file.py index c558fa9ab..9c09ced86 100644 --- a/vndk/tools/definition-tool/tests/test_dex_file.py +++ b/vndk/tools/definition-tool/tests/test_dex_file.py @@ -40,7 +40,7 @@ class ModifiedUTF8Test(unittest.TestCase): b'\xed\xa0\x81\xed\xb0\x80'.decode('mutf-8')) - def test_decode(self): + def test_decode_exception(self): # Low surrogate does not come after high surrogate with self.assertRaises(UnicodeSurrogateDecodeError): b'\xed\xa0\x81\x40'.decode('mutf-8') From 2beb6cf22f77441f270419bcf020b30ef62a595a Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 20:26:54 +0800 Subject: [PATCH 8/9] vndk-def: Fix trivial pylint errors This commit fixes several trivial pylint errors: dangerous-default-value, inconsistent-return-statements, redefined-builtin, too-few-public-methods, and unused-variable. Test: ./tests/run.sh Change-Id: Ic24aa25e7a7aacb836f76538c7c232072e86e02e --- vndk/tools/definition-tool/tests/compat.py | 5 ++++- .../definition-tool/tests/test_elf_linker.py | 6 +++--- .../tests/test_generic_refs.py | 2 ++ vndk/tools/definition-tool/tests/test_vndk.py | 20 ++++++++++--------- vndk/tools/definition-tool/tests/utils.py | 20 +++++++++---------- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/vndk/tools/definition-tool/tests/compat.py b/vndk/tools/definition-tool/tests/compat.py index a17ea9205..898123721 100644 --- a/vndk/tools/definition-tool/tests/compat.py +++ b/vndk/tools/definition-tool/tests/compat.py @@ -14,6 +14,7 @@ except ImportError: class TemporaryDirectory(object): def __init__(self, suffix='', prefix='tmp', dir=None): + # pylint: disable=redefined-builtin self.name = tempfile.mkdtemp(suffix, prefix, dir) @@ -39,10 +40,12 @@ if sys.version_info >= (3, 0): from os import makedirs else: import os + + def makedirs(path, exist_ok): if exist_ok and os.path.exists(path): return - return os.makedirs(path) + os.makedirs(path) if sys.version_info >= (3, 0): diff --git a/vndk/tools/definition-tool/tests/test_elf_linker.py b/vndk/tools/definition-tool/tests/test_elf_linker.py index 0316c9ba9..ba2c9a85c 100644 --- a/vndk/tools/definition-tool/tests/test_elf_linker.py +++ b/vndk/tools/definition-tool/tests/test_elf_linker.py @@ -95,7 +95,6 @@ class ELFLinkerTest(TestCase): def test_deps(self): gb = self._create_normal_graph() - graph = gb.graph # Check the dependencies of libc.so. node = gb.graph.get_lib('/system/lib/libc.so') @@ -316,6 +315,7 @@ class ELFLinkerTest(TestCase): # Create generic reference. class MockGenericRefs(object): + # pylint: disable=too-few-public-methods def classify_lib(self, lib): if 'libllvm_vendor' in lib.path: return GenericRefs.NEW_LIB @@ -541,8 +541,8 @@ class ELFLinkerDlopenDepsTest(TestCase): def test_add_dlopen_deps_error(self): gb = GraphBuilder() - liba = gb.add_lib32(PT_SYSTEM, 'liba') - libb = gb.add_lib32(PT_SYSTEM, 'libb') + gb.add_lib32(PT_SYSTEM, 'liba') + gb.add_lib32(PT_SYSTEM, 'libb') gb.resolve() with tempfile.NamedTemporaryFile(mode='w') as tmp_file: diff --git a/vndk/tools/definition-tool/tests/test_generic_refs.py b/vndk/tools/definition-tool/tests/test_generic_refs.py index c3afeaecc..24481698a 100644 --- a/vndk/tools/definition-tool/tests/test_generic_refs.py +++ b/vndk/tools/definition-tool/tests/test_generic_refs.py @@ -12,11 +12,13 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) class MockELF(object): + # pylint: disable=too-few-public-methods def __init__(self, exported_symbols): self.exported_symbols = exported_symbols class MockLib(object): + # pylint: disable=too-few-public-methods def __init__(self, path, exported_symbols): self.path = path self.elf = MockELF(exported_symbols) diff --git a/vndk/tools/definition-tool/tests/test_vndk.py b/vndk/tools/definition-tool/tests/test_vndk.py index 67268e9ae..ac55f8f77 100644 --- a/vndk/tools/definition-tool/tests/test_vndk.py +++ b/vndk/tools/definition-tool/tests/test_vndk.py @@ -69,7 +69,7 @@ class ELFLinkerVNDKTest(TestCase): """Check the computation of vndk without generic references.""" gb = GraphBuilder() - libfwk = gb.add_lib32(PT_SYSTEM, 'libfwk') + gb.add_lib32(PT_SYSTEM, 'libfwk') libvndk = gb.add_lib32(PT_SYSTEM, 'libvndk', extra_dir='vndk') libvndk_sp = gb.add_lib32(PT_SYSTEM, 'libutils', extra_dir='vndk-sp') libvnd = gb.add_lib32(PT_VENDOR, 'libvnd', @@ -89,15 +89,17 @@ class ELFLinkerVNDKTest(TestCase): """Check the computation of vndk without generic references.""" gb = GraphBuilder() - libfwk = gb.add_lib32(PT_SYSTEM, 'libfwk') - libvndk = gb.add_lib32(PT_SYSTEM, 'libvndk', - dt_needed=['libvnd_bad.so'], extra_dir='vndk') - libvndk_sp = gb.add_lib32(PT_SYSTEM, 'libutils', - dt_needed=['libvnd_bad.so'], - extra_dir='vndk-sp') - libvnd = gb.add_lib32(PT_VENDOR, 'libvnd', - dt_needed=['libvndk.so', 'libutils.so']) + + libvndk = gb.add_lib32( + PT_SYSTEM, 'libvndk', dt_needed=['libvnd_bad.so'], + extra_dir='vndk') + + libvndk_sp = gb.add_lib32( + PT_SYSTEM, 'libutils', dt_needed=['libvnd_bad.so'], + extra_dir='vndk-sp') + libvnd_bad = gb.add_lib32(PT_VENDOR, 'libvnd_bad', extra_dir='vndk-sp') + gb.resolve() self.assertIn(libvnd_bad, libvndk.deps_all) diff --git a/vndk/tools/definition-tool/tests/utils.py b/vndk/tools/definition-tool/tests/utils.py index 6f7d751f2..27812333a 100644 --- a/vndk/tools/definition-tool/tests/utils.py +++ b/vndk/tools/definition-tool/tests/utils.py @@ -22,8 +22,8 @@ class GraphBuilder(object): self.graph = ELFLinker() - def add_lib(self, partition, klass, name, dt_needed=[], - exported_symbols=set(), imported_symbols=set(), + def add_lib(self, partition, klass, name, dt_needed=tuple(), + exported_symbols=tuple(), imported_symbols=tuple(), extra_dir=None): """Create and add a shared library to ELFLinker.""" @@ -35,30 +35,30 @@ class GraphBuilder(object): path = os.path.join(lib_dir, name + '.so') elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed, - exported_symbols=exported_symbols, - imported_symbols=imported_symbols) + exported_symbols=set(exported_symbols), + imported_symbols=set(imported_symbols)) lib = self.graph.add_lib(partition, path, elf) setattr(self, name + '_' + elf.elf_class_name, lib) return lib - def add_lib32(self, partition, name, dt_needed=[], - exported_symbols=set(), imported_symbols=set(), + def add_lib32(self, partition, name, dt_needed=tuple(), + exported_symbols=tuple(), imported_symbols=tuple(), extra_dir=None): return self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed, exported_symbols, imported_symbols, extra_dir) - def add_lib64(self, partition, name, dt_needed=[], - exported_symbols=set(), imported_symbols=set(), + def add_lib64(self, partition, name, dt_needed=tuple(), + exported_symbols=tuple(), imported_symbols=tuple(), extra_dir=None): return self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed, exported_symbols, imported_symbols, extra_dir) - def add_multilib(self, partition, name, dt_needed=[], - exported_symbols=set(), imported_symbols=set(), + def add_multilib(self, partition, name, dt_needed=tuple(), + exported_symbols=tuple(), imported_symbols=tuple(), extra_dir=None): """Add 32-bit / 64-bit shared libraries to ELFLinker.""" return ( From fec31ff38f0d19046ed98fd3cbd7b5b183677d24 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 3 Jan 2019 21:49:12 +0800 Subject: [PATCH 9/9] vndk-def: Refine test_command_deps_insight Test: ./tests/run.sh Change-Id: If02db179c58275af509a76e5f2cdebb1b39d1ea3 --- .../tests/test_command_deps_insight.py | 64 +++++++++++++------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/vndk/tools/definition-tool/tests/test_command_deps_insight.py b/vndk/tools/definition-tool/tests/test_command_deps_insight.py index 9e8332a55..37e7b4eaa 100644 --- a/vndk/tools/definition-tool/tests/test_command_deps_insight.py +++ b/vndk/tools/definition-tool/tests/test_command_deps_insight.py @@ -45,37 +45,63 @@ class DepsInsightCommandTest(unittest.TestCase): def test_serialize_data_with_all_deps(self): - """compute_degenerated_vndk() should not remove bad dependencies from - the output of deps-insight. This test checks the existance of bad - dependencies.""" + # compute_degenerated_vndk() should not remove bad dependencies from + # the output of deps-insight. This test checks the existance of bad + # dependencies. gb = GraphBuilder() - libfwk = gb.add_lib32(PT_SYSTEM, 'libfwk') - libvndk = gb.add_lib32(PT_SYSTEM, 'libvndk', - dt_needed=['libvnd_bad.so'], extra_dir='vndk') - libvndk_sp = gb.add_lib32(PT_SYSTEM, 'libutils', - dt_needed=['libvnd_bad.so'], - extra_dir='vndk-sp') - libvnd = gb.add_lib32(PT_VENDOR, 'libvnd', - dt_needed=['libvndk.so', 'libutils.so']) - libvnd_bad = gb.add_lib32(PT_VENDOR, 'libvnd_bad', extra_dir='vndk-sp') + + libsystem = gb.add_lib32(PT_SYSTEM, 'libsystem') + + libsystem2 = gb.add_lib32( + PT_SYSTEM, 'libsystem2', dt_needed=['libsystem.so']) + + libvndk = gb.add_lib32( + PT_SYSTEM, 'libvndk', dt_needed=['libvendor_bad.so'], + extra_dir='vndk') + + libvendor = gb.add_lib32( + PT_VENDOR, 'libvendor', dt_needed=['libvndk.so']) + + libvendor_bad = gb.add_lib32( + PT_VENDOR, 'libvendor_bad', extra_dir='vndk') + gb.resolve() with patch('sys.stderr', StringIO()): vndk_sets = gb.graph.compute_degenerated_vndk(set(), None) - self.assertNotIn(libvnd_bad, libvndk.deps_good) - self.assertNotIn(libvnd_bad, libvndk_sp.deps_good) + self.assertNotIn(libvendor_bad, libvndk.deps_good) strs, mods = DepsInsightCommand.serialize_data( list(gb.graph.all_libs()), vndk_sets, ModuleInfo()) + # libsystem + deps = self._get_module_deps(strs, mods, libsystem.path) + self.assertFalse(deps) + users = self._get_module_users(strs, mods, libsystem.path) + self.assertIn(libsystem2.path, users) + + # libsystem2 + deps = self._get_module_deps(strs, mods, libsystem2.path) + self.assertIn(libsystem.path, deps) + users = self._get_module_users(strs, mods, libsystem2.path) + self.assertFalse(users) + + # libvndk deps = self._get_module_deps(strs, mods, libvndk.path) - self.assertIn(libvnd_bad.path, deps) + self.assertIn(libvendor_bad.path, deps) + users = self._get_module_users(strs, mods, libvndk.path) + self.assertIn(libvendor.path, users) - deps = self._get_module_deps(strs, mods, libvndk_sp.path) - self.assertIn(libvnd_bad.path, deps) + # libvendor + deps = self._get_module_deps(strs, mods, libvendor.path) + self.assertIn(libvndk.path, deps) + users = self._get_module_users(strs, mods, libvendor.path) + self.assertFalse(users) - users = self._get_module_users(strs, mods, libvnd_bad.path) + # libvendor_bad + deps = self._get_module_deps(strs, mods, libvendor_bad.path) + self.assertFalse(deps) + users = self._get_module_users(strs, mods, libvendor_bad.path) self.assertIn(libvndk.path, users) - self.assertIn(libvndk_sp.path, users)