Merge changes If02db179,Ic24aa25e,Icf205d03,I9856b08f,I6fc9fcef, ...

* changes:
  vndk-def: Refine test_command_deps_insight
  vndk-def: Fix trivial pylint errors
  vndk-def: Unhide a test case
  vndk-def: Fix deprecated warning in unittest
  vndk-def: Cleanup import pylint errors
  vndk-def: Fix spacing errors found by pylint
  vndk-def: Separate methods with two empty lines
  vndk-def: Cleanup dep-graph
  vndk-def: Mark --output as a required argument
This commit is contained in:
Logan Chien
2019-01-04 06:05:18 +00:00
committed by Gerrit Code Review
18 changed files with 628 additions and 465 deletions

View File

@@ -1,39 +1,52 @@
#!/usr/bin/env python3
import os
# pylint: disable=unused-import,import-error
import sys
try:
from tempfile import TemporaryDirectory
except ImportError:
import shutil
import tempfile
class TemporaryDirectory(object):
def __init__(self, suffix='', prefix='tmp', dir=None):
# pylint: disable=redefined-builtin
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:
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):
from io import StringIO
@@ -45,6 +58,8 @@ try:
from unittest.mock import patch
except ImportError:
import contextlib
@contextlib.contextmanager
def patch(target, mock):
obj, attr = target.rsplit('.')
@@ -55,3 +70,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)

99
vndk/tools/definition-tool/tests/ndk_toolchain.py Executable file → Normal file
View File

@@ -2,13 +2,13 @@
from __future__ import print_function
import argparse
import collections
import os
import re
import subprocess
import sys
def detect_ndk_dir():
ndk_dir = os.getenv('NDK')
if not ndk_dir:
@@ -28,6 +28,7 @@ error:'''
return ndk_dir
def detect_api_level(ndk_dir):
try:
apis = []
@@ -42,6 +43,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 +51,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 +77,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):
@@ -79,7 +86,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)
@@ -88,6 +95,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 +108,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 +133,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()
@@ -135,68 +145,47 @@ 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')
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()

View File

@@ -1,20 +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()

View File

@@ -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 "$@"

View File

@@ -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):
@@ -48,41 +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())
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)
if __name__ == '__main__':
unittest.main()

12
vndk/tools/definition-tool/tests/test_dex_file.py Executable file → Normal file
View File

@@ -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')
@@ -42,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')
@@ -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()

26
vndk/tools/definition-tool/tests/test_elf.py Executable file → Normal file
View File

@@ -2,16 +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 Elf_Sym, ELF
from .compat import StringIO
class ElfSymTest(unittest.TestCase):
def setUp(self):
self.sym_local = Elf_Sym(0, 0, 4, 0, 0, 1)
@@ -19,21 +17,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 +46,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 +62,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 +72,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 +86,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 +94,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 +103,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 +113,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 +140,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 +201,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())
@@ -208,7 +220,3 @@ class ELFJniLibTest(unittest.TestCase):
elf = ELF(exported_symbols={'printf'})
self.assertFalse(elf.is_jni_lib())
if __name__ == '__main__':
unittest.main()

16
vndk/tools/definition-tool/tests/test_elf_link_data.py Executable file → Normal file
View File

@@ -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
@@ -25,6 +21,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 +33,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 +49,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 +59,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 +69,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
@@ -100,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()

69
vndk/tools/definition-tool/tests/test_elf_linker.py Executable file → Normal file
View File

@@ -1,23 +1,16 @@
#!/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)
from .compat import StringIO, TestCase, patch
from .utils import GraphBuilder
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
class ELFLinkerTest(unittest.TestCase):
class ELFLinkerTest(TestCase):
def _create_normal_graph(self):
gb = GraphBuilder()
@@ -102,7 +95,6 @@ class ELFLinkerTest(unittest.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')
@@ -323,6 +315,7 @@ class ELFLinkerTest(unittest.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
@@ -393,36 +386,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')
@@ -467,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')
@@ -548,8 +541,8 @@ class ELFLinkerDlopenDepsTest(unittest.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:
@@ -560,11 +553,7 @@ class ELFLinkerDlopenDepsTest(unittest.TestCase):
with patch('sys.stderr', stderr):
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')
if __name__ == '__main__':
unittest.main()
self.assertRegex(
stderr.getvalue(),
'error:' + re.escape(tmp_file.name) + ':1: ' +
'Failed to add dlopen dependency from .* to .*\\.\n')

88
vndk/tools/definition-tool/tests/test_elf_resolver.py Executable file → Normal file
View File

@@ -2,14 +2,11 @@
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
class ELFResolverTest(unittest.TestCase):
def setUp(self):
lib_set = {
@@ -24,50 +21,51 @@ class ELFResolverTest(unittest.TestCase):
self.resolver = ELFResolver(lib_set, ['/system/lib', '/vendor/lib'])
def test_get_candidates(self):
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
@@ -76,23 +74,19 @@ 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']))
if __name__ == '__main__':
unittest.main()
'a2',
r.resolve('/system/lib/libreq.so', 'liba.so',
dt_runpath=['/vendor/lib']))

56
vndk/tools/definition-tool/tests/test_elfdump.py Executable file → Normal file
View File

@@ -2,23 +2,20 @@
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__))
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
@@ -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
@@ -41,11 +38,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 +96,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 +109,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 +118,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))
@@ -149,38 +152,15 @@ 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'):
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()

15
vndk/tools/definition-tool/tests/test_generic_refs.py Executable file → Normal file
View File

@@ -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
@@ -17,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)
@@ -39,6 +36,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 +58,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 +74,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,12 +87,9 @@ 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', {})))
self.assertFalse(self.ref.has_same_name_lib(
MockLib('/vendor/lib/lib_does_not_exist.so', {})))
if __name__ == '__main__':
unittest.main()

10
vndk/tools/definition-tool/tests/test_module_info.py Executable file → Normal file
View File

@@ -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
@@ -18,6 +15,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')
@@ -33,8 +31,4 @@ 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'))
if __name__ == '__main__':
unittest.main()
[], m.get_module_path('/system/lib64/libdoes_not_exist.so'))

72
vndk/tools/definition-tool/tests/test_tagged_dict.py Executable file → Normal file
View File

@@ -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
@@ -103,37 +100,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 +216,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 +366,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 +389,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 +408,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):
@@ -456,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()

45
vndk/tools/definition-tool/tests/test_vndk.py Executable file → Normal file
View File

@@ -2,18 +2,13 @@
from __future__ import print_function
import os
import sys
import unittest
from vndk_definition_tool import (PT_SYSTEM, PT_VENDOR)
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from compat import StringIO, patch
from vndk_definition_tool import (ELF, ELFLinker, PT_SYSTEM, PT_VENDOR)
from utils import GraphBuilder
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
@@ -31,10 +26,10 @@ class ELFLinkerVNDKTest(unittest.TestCase):
with patch('sys.stderr', stderr):
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.')
self.assertRegex(
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)
@@ -74,7 +69,7 @@ class ELFLinkerVNDKTest(unittest.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',
@@ -94,15 +89,17 @@ class ELFLinkerVNDKTest(unittest.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)
@@ -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()

114
vndk/tools/definition-tool/tests/test_vndk_lib_dir.py Executable file → Normal file
View File

@@ -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__))
@@ -22,92 +20,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 +124,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 +137,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 +172,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 +193,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,22 +203,17 @@ 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']))
if __name__ == '__main__':
unittest.main()
['current', 'd', 'a', '10', '1'],
VNDKLibDir.sorted_version(['1', '10', 'a', 'd', 'current']))

View File

@@ -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):
@@ -16,16 +11,19 @@ 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(),
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."""
@@ -37,27 +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 (
@@ -67,6 +68,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

File diff suppressed because it is too large Load Diff