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 #!/usr/bin/env python3
import os # pylint: disable=unused-import,import-error
import sys import sys
try: try:
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
except ImportError: except ImportError:
import shutil import shutil
import tempfile import tempfile
class TemporaryDirectory(object): class TemporaryDirectory(object):
def __init__(self, suffix='', prefix='tmp', dir=None): def __init__(self, suffix='', prefix='tmp', dir=None):
# pylint: disable=redefined-builtin
self.name = tempfile.mkdtemp(suffix, prefix, dir) self.name = tempfile.mkdtemp(suffix, prefix, dir)
def __del__(self): def __del__(self):
self.cleanup() self.cleanup()
def __enter__(self): def __enter__(self):
return self.name return self.name
def __exit__(self, exc, value, tb): def __exit__(self, exc, value, tb):
self.cleanup() self.cleanup()
def cleanup(self): def cleanup(self):
if self.name: if self.name:
shutil.rmtree(self.name) shutil.rmtree(self.name)
self.name = None self.name = None
if sys.version_info >= (3, 0): if sys.version_info >= (3, 0):
from os import makedirs from os import makedirs
else: else:
import os
def makedirs(path, exist_ok): def makedirs(path, exist_ok):
if exist_ok and os.path.exists(path): if exist_ok and os.path.exists(path):
return return
return os.makedirs(path) os.makedirs(path)
if sys.version_info >= (3, 0): if sys.version_info >= (3, 0):
from io import StringIO from io import StringIO
@@ -45,6 +58,8 @@ try:
from unittest.mock import patch from unittest.mock import patch
except ImportError: except ImportError:
import contextlib import contextlib
@contextlib.contextmanager @contextlib.contextmanager
def patch(target, mock): def patch(target, mock):
obj, attr = target.rsplit('.') obj, attr = target.rsplit('.')
@@ -55,3 +70,20 @@ except ImportError:
yield yield
finally: finally:
setattr(obj, attr, original_value) 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 from __future__ import print_function
import argparse
import collections import collections
import os import os
import re import re
import subprocess import subprocess
import sys import sys
def detect_ndk_dir(): def detect_ndk_dir():
ndk_dir = os.getenv('NDK') ndk_dir = os.getenv('NDK')
if not ndk_dir: if not ndk_dir:
@@ -28,6 +28,7 @@ error:'''
return ndk_dir return ndk_dir
def detect_api_level(ndk_dir): def detect_api_level(ndk_dir):
try: try:
apis = [] apis = []
@@ -42,6 +43,7 @@ def detect_api_level(ndk_dir):
except IOError: except IOError:
raise ValueError('failed to find latest api') raise ValueError('failed to find latest api')
def detect_host(): def detect_host():
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
return 'linux-x86_64' return 'linux-x86_64'
@@ -49,15 +51,19 @@ def detect_host():
return 'darwin-x86_64' return 'darwin-x86_64'
raise NotImplementedError('unknown host platform') raise NotImplementedError('unknown host platform')
def get_gcc_dir(ndk_dir, arch, host): def get_gcc_dir(ndk_dir, arch, host):
return os.path.join(ndk_dir, 'toolchains', arch, 'prebuilt', host) return os.path.join(ndk_dir, 'toolchains', arch, 'prebuilt', host)
def get_clang_dir(ndk_dir, host): def get_clang_dir(ndk_dir, host):
return os.path.join(ndk_dir, 'toolchains', 'llvm', 'prebuilt', host) return os.path.join(ndk_dir, 'toolchains', 'llvm', 'prebuilt', host)
def get_platform_dir(ndk_dir, api, subdirs): def get_platform_dir(ndk_dir, api, subdirs):
return os.path.join(ndk_dir, 'platforms', api, *subdirs) return os.path.join(ndk_dir, 'platforms', api, *subdirs)
class Target(object): class Target(object):
def __init__(self, name, triple, cflags, ldflags, gcc_toolchain_dir, def __init__(self, name, triple, cflags, ldflags, gcc_toolchain_dir,
clang_dir, ndk_include, ndk_lib): clang_dir, ndk_include, ndk_lib):
@@ -71,6 +77,7 @@ class Target(object):
self.ndk_include = ndk_include self.ndk_include = ndk_include
self.ndk_lib = ndk_lib self.ndk_lib = ndk_lib
def check_paths(self): def check_paths(self):
def check_path(path): def check_path(path):
if os.path.exists(path): if os.path.exists(path):
@@ -79,7 +86,7 @@ class Target(object):
return False return False
ld_exeutable = os.path.join( 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(self.gcc_toolchain_dir)
success &= check_path(ld_exeutable) success &= check_path(ld_exeutable)
@@ -88,6 +95,7 @@ class Target(object):
success &= check_path(self.ndk_lib) success &= check_path(self.ndk_lib)
return success return success
def compile(self, obj_file, src_file, cflags): def compile(self, obj_file, src_file, cflags):
clang = os.path.join(self.clang_dir, 'bin', 'clang') clang = os.path.join(self.clang_dir, 'bin', 'clang')
@@ -100,6 +108,7 @@ class Target(object):
cmd.extend(self.target_cflags) cmd.extend(self.target_cflags)
subprocess.check_call(cmd) subprocess.check_call(cmd)
def link(self, out_file, obj_files, ldflags): def link(self, out_file, obj_files, ldflags):
if '-shared' in ldflags: if '-shared' in ldflags:
crtbegin = os.path.join(self.ndk_lib, 'crtbegin_so.o') crtbegin = os.path.join(self.ndk_lib, 'crtbegin_so.o')
@@ -124,6 +133,7 @@ class Target(object):
cmd.append('-Wl,-pie') cmd.append('-Wl,-pie')
subprocess.check_call(cmd) subprocess.check_call(cmd)
def create_targets(ndk_dir=None, api=None, host=None): def create_targets(ndk_dir=None, api=None, host=None):
if ndk_dir is None: if ndk_dir is None:
ndk_dir = detect_ndk_dir() ndk_dir = detect_ndk_dir()
@@ -135,68 +145,47 @@ def create_targets(ndk_dir=None, api=None, host=None):
targets = collections.OrderedDict() targets = collections.OrderedDict()
targets['arm'] = Target( targets['arm'] = Target(
'arm', 'arm-linux-androideabi', [],[], 'arm', 'arm-linux-androideabi', [], [],
get_gcc_dir(ndk_dir, 'arm-linux-androideabi-4.9', host), get_gcc_dir(ndk_dir, 'arm-linux-androideabi-4.9', host),
get_clang_dir(ndk_dir, 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', 'include']),
get_platform_dir(ndk_dir, api, ['arch-arm', 'usr', 'lib'])) get_platform_dir(ndk_dir, api, ['arch-arm', 'usr', 'lib']))
targets['arm64'] = Target( targets['arm64'] = Target(
'arm64', 'aarch64-linux-android', [], [], 'arm64', 'aarch64-linux-android', [], [],
get_gcc_dir(ndk_dir, 'aarch64-linux-android-4.9', host), get_gcc_dir(ndk_dir, 'aarch64-linux-android-4.9', host),
get_clang_dir(ndk_dir, 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', 'include']),
get_platform_dir(ndk_dir, api, ['arch-arm64', 'usr', 'lib'])) get_platform_dir(ndk_dir, api, ['arch-arm64', 'usr', 'lib']))
targets['x86'] = Target( targets['x86'] = Target(
'x86', 'i686-linux-android', ['-m32'], ['-m32'], 'x86', 'i686-linux-android', ['-m32'], ['-m32'],
get_gcc_dir(ndk_dir, 'x86-4.9', host), get_gcc_dir(ndk_dir, 'x86-4.9', host),
get_clang_dir(ndk_dir, 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', 'include']),
get_platform_dir(ndk_dir, api, ['arch-x86', 'usr', 'lib'])) get_platform_dir(ndk_dir, api, ['arch-x86', 'usr', 'lib']))
targets['x86_64'] = Target( targets['x86_64'] = Target(
'x86_64', 'x86_64-linux-android', ['-m64'], ['-m64'], 'x86_64', 'x86_64-linux-android', ['-m64'], ['-m64'],
get_gcc_dir(ndk_dir, 'x86_64-4.9', host), get_gcc_dir(ndk_dir, 'x86_64-4.9', host),
get_clang_dir(ndk_dir, 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', 'include']),
get_platform_dir(ndk_dir, api, ['arch-x86_64', 'usr', 'lib64'])) get_platform_dir(ndk_dir, api, ['arch-x86_64', 'usr', 'lib64']))
targets['mips'] = Target( targets['mips'] = Target(
'mips', 'mipsel-linux-android', [], [], 'mips', 'mipsel-linux-android', [], [],
get_gcc_dir(ndk_dir, 'mipsel-linux-android-4.9', host), get_gcc_dir(ndk_dir, 'mipsel-linux-android-4.9', host),
get_clang_dir(ndk_dir, 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', 'include']),
get_platform_dir(ndk_dir, api, ['arch-mips', 'usr', 'lib'])) get_platform_dir(ndk_dir, api, ['arch-mips', 'usr', 'lib']))
targets['mips64'] = Target( targets['mips64'] = Target(
'mips64', 'mips64el-linux-android', 'mips64', 'mips64el-linux-android',
['-march=mips64el', '-mcpu=mips64r6'], ['-march=mips64el', '-mcpu=mips64r6'],
['-march=mips64el', '-mcpu=mips64r6'], ['-march=mips64el', '-mcpu=mips64r6'],
get_gcc_dir(ndk_dir, 'mips64el-linux-android-4.9', host), get_gcc_dir(ndk_dir, 'mips64el-linux-android-4.9', host),
get_clang_dir(ndk_dir, 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', 'include']),
get_platform_dir(ndk_dir, api, ['arch-mips64', 'usr', 'lib64'])) get_platform_dir(ndk_dir, api, ['arch-mips64', 'usr', 'lib64']))
return targets 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 from __future__ import print_function
import os
import sys
import unittest 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 ( from vndk_definition_tool import (
DepsInsightCommand, ModuleInfo, PT_SYSTEM, PT_VENDOR) DepsInsightCommand, ModuleInfo, PT_SYSTEM, PT_VENDOR)
from utils import GraphBuilder
from .compat import StringIO, patch
from .utils import GraphBuilder
class DepsInsightCommandTest(unittest.TestCase): class DepsInsightCommandTest(unittest.TestCase):
@@ -48,41 +45,63 @@ class DepsInsightCommandTest(unittest.TestCase):
def test_serialize_data_with_all_deps(self): def test_serialize_data_with_all_deps(self):
"""compute_degenerated_vndk() should not remove bad dependencies from # compute_degenerated_vndk() should not remove bad dependencies from
the output of deps-insight. This test checks the existance of bad # the output of deps-insight. This test checks the existance of bad
dependencies.""" # dependencies.
gb = GraphBuilder() gb = GraphBuilder()
libfwk = gb.add_lib32(PT_SYSTEM, 'libfwk')
libvndk = gb.add_lib32(PT_SYSTEM, 'libvndk', libsystem = gb.add_lib32(PT_SYSTEM, 'libsystem')
dt_needed=['libvnd_bad.so'], extra_dir='vndk')
libvndk_sp = gb.add_lib32(PT_SYSTEM, 'libutils', libsystem2 = gb.add_lib32(
dt_needed=['libvnd_bad.so'], PT_SYSTEM, 'libsystem2', dt_needed=['libsystem.so'])
extra_dir='vndk-sp')
libvnd = gb.add_lib32(PT_VENDOR, 'libvnd', libvndk = gb.add_lib32(
dt_needed=['libvndk.so', 'libutils.so']) PT_SYSTEM, 'libvndk', dt_needed=['libvendor_bad.so'],
libvnd_bad = gb.add_lib32(PT_VENDOR, 'libvnd_bad', extra_dir='vndk-sp') 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() gb.resolve()
with patch('sys.stderr', StringIO()): with patch('sys.stderr', StringIO()):
vndk_sets = gb.graph.compute_degenerated_vndk(set(), None) vndk_sets = gb.graph.compute_degenerated_vndk(set(), None)
self.assertNotIn(libvnd_bad, libvndk.deps_good) self.assertNotIn(libvendor_bad, libvndk.deps_good)
self.assertNotIn(libvnd_bad, libvndk_sp.deps_good)
strs, mods = DepsInsightCommand.serialize_data( 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) 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) # libvendor
self.assertIn(libvnd_bad.path, deps) 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.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 os
import subprocess import subprocess
import sys
import unittest import unittest
import zipfile 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 vndk_definition_tool import DexFileReader, UnicodeSurrogateDecodeError
from .compat import TemporaryDirectory
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
INPUT_DIR = os.path.join(SCRIPT_DIR, 'testdata', 'test_dex_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')) 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 # Low surrogate does not come after high surrogate
with self.assertRaises(UnicodeSurrogateDecodeError): with self.assertRaises(UnicodeSurrogateDecodeError):
b'\xed\xa0\x81\x40'.decode('mutf-8') b'\xed\xa0\x81\x40'.decode('mutf-8')
@@ -122,7 +120,3 @@ class DexFileTest(unittest.TestCase):
self.assertIn(b'world', strs) self.assertIn(b'world', strs)
self.assertIn(b'foo', strs) self.assertIn(b'foo', strs)
self.assertIn(b'bar', 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 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 tempfile
import unittest import unittest
from compat import StringIO
from vndk_definition_tool import Elf_Sym, ELF from vndk_definition_tool import Elf_Sym, ELF
from .compat import StringIO
class ElfSymTest(unittest.TestCase): class ElfSymTest(unittest.TestCase):
def setUp(self): def setUp(self):
self.sym_local = Elf_Sym(0, 0, 4, 0, 0, 1) 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_weak = Elf_Sym(0, 0, 4, 33, 0, 1)
self.sym_undef = Elf_Sym(0, 0, 4, 16, 0, 0) self.sym_undef = Elf_Sym(0, 0, 4, 16, 0, 0)
def test_is_local(self): def test_is_local(self):
self.assertTrue(self.sym_local.is_local) self.assertTrue(self.sym_local.is_local)
self.assertFalse(self.sym_global.is_local) self.assertFalse(self.sym_global.is_local)
self.assertFalse(self.sym_weak.is_local) self.assertFalse(self.sym_weak.is_local)
def test_is_global(self): def test_is_global(self):
self.assertFalse(self.sym_local.is_global) self.assertFalse(self.sym_local.is_global)
self.assertTrue(self.sym_global.is_global) self.assertTrue(self.sym_global.is_global)
self.assertFalse(self.sym_weak.is_global) self.assertFalse(self.sym_weak.is_global)
def test_is_weak(self): def test_is_weak(self):
self.assertFalse(self.sym_local.is_weak) self.assertFalse(self.sym_local.is_weak)
self.assertFalse(self.sym_global.is_weak) self.assertFalse(self.sym_global.is_weak)
self.assertTrue(self.sym_weak.is_weak) self.assertTrue(self.sym_weak.is_weak)
def test_is_undef(self): def test_is_undef(self):
self.assertFalse(self.sym_global.is_undef) self.assertFalse(self.sym_global.is_undef)
self.assertTrue(self.sym_undef.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.ELFCLASS32, ELF.get_ei_class_from_name('32'))
self.assertEqual(ELF.ELFCLASS64, ELF.get_ei_class_from_name('64')) self.assertEqual(ELF.ELFCLASS64, ELF.get_ei_class_from_name('64'))
def test_get_ei_data_from_name(self): def test_get_ei_data_from_name(self):
self.assertEqual(ELF.ELFDATA2LSB, self.assertEqual(ELF.ELFDATA2LSB,
ELF.get_ei_data_from_name('Little-Endian')) ELF.get_ei_data_from_name('Little-Endian'))
self.assertEqual(ELF.ELFDATA2MSB, self.assertEqual(ELF.ELFDATA2MSB,
ELF.get_ei_data_from_name('Big-Endian')) ELF.get_ei_data_from_name('Big-Endian'))
def test_get_e_machine_from_name(self): def test_get_e_machine_from_name(self):
self.assertEqual(0, ELF.get_e_machine_from_name('EM_NONE')) self.assertEqual(0, ELF.get_e_machine_from_name('EM_NONE'))
self.assertEqual(3, ELF.get_e_machine_from_name('EM_386')) 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(62, ELF.get_e_machine_from_name('EM_X86_64'))
self.assertEqual(183, ELF.get_e_machine_from_name('EM_AARCH64')) self.assertEqual(183, ELF.get_e_machine_from_name('EM_AARCH64'))
def test_repr(self): def test_repr(self):
elf = ELF() elf = ELF()
self.assertEqual(elf, eval(repr(elf))) self.assertEqual(elf, eval(repr(elf)))
@@ -67,6 +72,7 @@ class ELFTest(unittest.TestCase):
dt_needed=['c', 'd'], exported_symbols={'e', 'f', 'g'}) dt_needed=['c', 'd'], exported_symbols={'e', 'f', 'g'})
self.assertEqual(elf, eval(repr(elf))) self.assertEqual(elf, eval(repr(elf)))
def test_class_name(self): def test_class_name(self):
self.assertEqual('None', ELF().elf_class_name) self.assertEqual('None', ELF().elf_class_name)
@@ -80,6 +86,7 @@ class ELFTest(unittest.TestCase):
self.assertFalse(elf.is_32bit) self.assertFalse(elf.is_32bit)
self.assertTrue(elf.is_64bit) self.assertTrue(elf.is_64bit)
def test_endianness(self): def test_endianness(self):
self.assertEqual('None', ELF().elf_data_name) self.assertEqual('None', ELF().elf_data_name)
self.assertEqual('Little-Endian', self.assertEqual('Little-Endian',
@@ -87,6 +94,7 @@ class ELFTest(unittest.TestCase):
self.assertEqual('Big-Endian', self.assertEqual('Big-Endian',
ELF(None, ELF.ELFDATA2MSB).elf_data_name) ELF(None, ELF.ELFDATA2MSB).elf_data_name)
def test_machine_name(self): def test_machine_name(self):
self.assertEqual('EM_NONE', ELF(e_machine=0).elf_machine_name) self.assertEqual('EM_NONE', ELF(e_machine=0).elf_machine_name)
self.assertEqual('EM_386', ELF(e_machine=3).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_X86_64', ELF(e_machine=62).elf_machine_name)
self.assertEqual('EM_AARCH64', ELF(e_machine=183).elf_machine_name) self.assertEqual('EM_AARCH64', ELF(e_machine=183).elf_machine_name)
def test_dt_rpath_runpath(self): def test_dt_rpath_runpath(self):
elf = ELF() elf = ELF()
self.assertEqual([], elf.dt_rpath) self.assertEqual([], elf.dt_rpath)
@@ -104,6 +113,7 @@ class ELFTest(unittest.TestCase):
self.assertEqual(['a'], elf.dt_rpath) self.assertEqual(['a'], elf.dt_rpath)
self.assertEqual(['b'], elf.dt_runpath) self.assertEqual(['b'], elf.dt_runpath)
def test_dump(self): def test_dump(self):
elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, ['a'], ['b'], elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, ['a'], ['b'],
['libc.so', 'libm.so'], {'hello', 'world'}, {'d', 'e'}) ['libc.so', 'libm.so'], {'hello', 'world'}, {'d', 'e'})
@@ -130,6 +140,7 @@ class ELFTest(unittest.TestCase):
'IMP_SYMBOL\te\n', 'IMP_SYMBOL\te\n',
actual_output) actual_output)
def test_parse_dump_file(self): def test_parse_dump_file(self):
data = ('EI_CLASS\t64\n' data = ('EI_CLASS\t64\n'
'EI_DATA\t\tLittle-Endian\n' 'EI_DATA\t\tLittle-Endian\n'
@@ -190,6 +201,7 @@ class ELFJniLibTest(unittest.TestCase):
elf = ELF(dt_needed=['libc.so']) elf = ELF(dt_needed=['libc.so'])
self.assertFalse(elf.is_jni_lib()) self.assertFalse(elf.is_jni_lib())
def test_jni_symbols(self): def test_jni_symbols(self):
elf = ELF(imported_symbols={'JNI_CreateJavaVM'}) elf = ELF(imported_symbols={'JNI_CreateJavaVM'})
self.assertTrue(elf.is_jni_lib()) self.assertTrue(elf.is_jni_lib())
@@ -208,7 +220,3 @@ class ELFJniLibTest(unittest.TestCase):
elf = ELF(exported_symbols={'printf'}) elf = ELF(exported_symbols={'printf'})
self.assertFalse(elf.is_jni_lib()) 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 from __future__ import print_function
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import unittest import unittest
from vndk_definition_tool import ELFLinkData, PT_SYSTEM, PT_VENDOR 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_needed_dep(self.w)
self.z.add_dlopen_dep(self.w) self.z.add_dlopen_dep(self.w)
def test_add_dep_and_accessors(self): def test_add_dep_and_accessors(self):
self.assertIn(self.y, self.x.deps_needed_all) self.assertIn(self.y, self.x.deps_needed_all)
self.assertIn(self.x, self.y.users_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.z, self.x.deps_needed_all)
self.assertNotIn(self.x, self.z.users_needed_all) self.assertNotIn(self.x, self.z.users_needed_all)
def test_remove_dep(self): def test_remove_dep(self):
self.assertIn(self.y, self.x.deps_needed_all) self.assertIn(self.y, self.x.deps_needed_all)
self.assertIn(self.x, self.y.users_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.y, self.x.deps_needed)
self.assertNotIn(self.x, self.y.users_needed) self.assertNotIn(self.x, self.y.users_needed)
def test_num_deps(self): def test_num_deps(self):
self.assertEqual(2, self.x.num_deps) self.assertEqual(2, self.x.num_deps)
self.assertEqual(0, self.y.num_deps) self.assertEqual(0, self.y.num_deps)
@@ -60,6 +59,7 @@ class ELFLinkDataTest(unittest.TestCase):
# NEEDED and DLOPEN are counted twice. # NEEDED and DLOPEN are counted twice.
self.assertEqual(2, self.z.num_deps) self.assertEqual(2, self.z.num_deps)
def test_num_users(self): def test_num_users(self):
self.assertEqual(0, self.x.num_users) self.assertEqual(0, self.x.num_users)
self.assertEqual(1, self.y.num_users) self.assertEqual(1, self.y.num_users)
@@ -69,22 +69,26 @@ class ELFLinkDataTest(unittest.TestCase):
# NEEDED and DLOPEN are counted twice. # NEEDED and DLOPEN are counted twice.
self.assertEqual(2, self.w.num_users) self.assertEqual(2, self.w.num_users)
def test_has_dep(self): def test_has_dep(self):
self.assertTrue(self.x.has_dep(self.y)) self.assertTrue(self.x.has_dep(self.y))
self.assertTrue(self.x.has_dep(self.z)) self.assertTrue(self.x.has_dep(self.z))
self.assertFalse(self.x.has_dep(self.x)) self.assertFalse(self.x.has_dep(self.x))
self.assertFalse(self.x.has_dep(self.w)) self.assertFalse(self.x.has_dep(self.w))
def test_has_user(self): def test_has_user(self):
self.assertTrue(self.y.has_user(self.x)) self.assertTrue(self.y.has_user(self.x))
self.assertTrue(self.z.has_user(self.x)) self.assertTrue(self.z.has_user(self.x))
self.assertFalse(self.x.has_user(self.x)) self.assertFalse(self.x.has_user(self.x))
self.assertFalse(self.w.has_user(self.x)) self.assertFalse(self.w.has_user(self.x))
def test_is_system_lib(self): def test_is_system_lib(self):
self.assertTrue(self.x.is_system_lib()) self.assertTrue(self.x.is_system_lib())
self.assertFalse(self.v.is_system_lib()) self.assertFalse(self.v.is_system_lib())
def test_get_dep_linked_symbols(self): def test_get_dep_linked_symbols(self):
self.x.linked_symbols['c'] = self.y self.x.linked_symbols['c'] = self.y
self.x.linked_symbols['b'] = self.y self.x.linked_symbols['b'] = self.y
@@ -100,7 +104,3 @@ class ELFLinkDataTest(unittest.TestCase):
self.assertEqual(['w', 'x', 'y', 'z'], self.assertEqual(['w', 'x', 'y', 'z'],
self.x.get_dep_linked_symbols(self.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 #!/usr/bin/env python3
import os
import re import re
import sys
import tempfile 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 ( 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(TestCase):
class ELFLinkerTest(unittest.TestCase):
def _create_normal_graph(self): def _create_normal_graph(self):
gb = GraphBuilder() gb = GraphBuilder()
@@ -102,7 +95,6 @@ class ELFLinkerTest(unittest.TestCase):
def test_deps(self): def test_deps(self):
gb = self._create_normal_graph() gb = self._create_normal_graph()
graph = gb.graph
# Check the dependencies of libc.so. # Check the dependencies of libc.so.
node = gb.graph.get_lib('/system/lib/libc.so') node = gb.graph.get_lib('/system/lib/libc.so')
@@ -323,6 +315,7 @@ class ELFLinkerTest(unittest.TestCase):
# Create generic reference. # Create generic reference.
class MockGenericRefs(object): class MockGenericRefs(object):
# pylint: disable=too-few-public-methods
def classify_lib(self, lib): def classify_lib(self, lib):
if 'libllvm_vendor' in lib.path: if 'libllvm_vendor' in lib.path:
return GenericRefs.NEW_LIB return GenericRefs.NEW_LIB
@@ -393,36 +386,36 @@ class ELFLinkerTest(unittest.TestCase):
libc_32, libc_64 = gb.add_multilib(PT_SYSTEM, 'libc') libc_32, libc_64 = gb.add_multilib(PT_SYSTEM, 'libc')
libvndk_a_32, libvndk_a_64 = gb.add_multilib( libvndk_a_32, libvndk_a_64 = gb.add_multilib(
PT_SYSTEM, 'libvndk_a', extra_dir='vndk-28', PT_SYSTEM, 'libvndk_a', extra_dir='vndk-28',
dt_needed=['libc.so', 'libvndk_b.so', 'libvndk_sp_b.so']) dt_needed=['libc.so', 'libvndk_b.so', 'libvndk_sp_b.so'])
libvndk_b_32, libvndk_b_64 = gb.add_multilib( libvndk_b_32, libvndk_b_64 = gb.add_multilib(
PT_SYSTEM, 'libvndk_b', extra_dir='vndk-28', PT_SYSTEM, 'libvndk_b', extra_dir='vndk-28',
dt_needed=['libc.so', 'libvndk_sp_b.so']) dt_needed=['libc.so', 'libvndk_sp_b.so'])
libvndk_c_32, libvndk_c_64 = gb.add_multilib( libvndk_c_32, libvndk_c_64 = gb.add_multilib(
PT_VENDOR, 'libvndk_c', extra_dir='vndk-28', PT_VENDOR, 'libvndk_c', extra_dir='vndk-28',
dt_needed=['libc.so', 'libvndk_d.so', 'libvndk_sp_d.so']) dt_needed=['libc.so', 'libvndk_d.so', 'libvndk_sp_d.so'])
libvndk_d_32, libvndk_d_64 = gb.add_multilib( libvndk_d_32, libvndk_d_64 = gb.add_multilib(
PT_VENDOR, 'libvndk_d', extra_dir='vndk-28', PT_VENDOR, 'libvndk_d', extra_dir='vndk-28',
dt_needed=['libc.so', 'libvndk_sp_d.so']) dt_needed=['libc.so', 'libvndk_sp_d.so'])
libvndk_sp_a_32, libvndk_sp_a_64 = gb.add_multilib( libvndk_sp_a_32, libvndk_sp_a_64 = gb.add_multilib(
PT_SYSTEM, 'libvndk_sp_a', extra_dir='vndk-sp-28', PT_SYSTEM, 'libvndk_sp_a', extra_dir='vndk-sp-28',
dt_needed=['libc.so', 'libvndk_sp_b.so']) dt_needed=['libc.so', 'libvndk_sp_b.so'])
libvndk_sp_b_32, libvndk_sp_b_64 = gb.add_multilib( libvndk_sp_b_32, libvndk_sp_b_64 = gb.add_multilib(
PT_SYSTEM, 'libvndk_sp_b', extra_dir='vndk-sp-28', PT_SYSTEM, 'libvndk_sp_b', extra_dir='vndk-sp-28',
dt_needed=['libc.so']) dt_needed=['libc.so'])
libvndk_sp_c_32, libvndk_sp_c_64 = gb.add_multilib( libvndk_sp_c_32, libvndk_sp_c_64 = gb.add_multilib(
PT_VENDOR, 'libvndk_sp_c', extra_dir='vndk-sp-28', PT_VENDOR, 'libvndk_sp_c', extra_dir='vndk-sp-28',
dt_needed=['libc.so', 'libvndk_sp_d.so']) dt_needed=['libc.so', 'libvndk_sp_d.so'])
libvndk_sp_d_32, libvndk_sp_d_64 = gb.add_multilib( libvndk_sp_d_32, libvndk_sp_d_64 = gb.add_multilib(
PT_VENDOR, 'libvndk_sp_d', extra_dir='vndk-sp-28', PT_VENDOR, 'libvndk_sp_d', extra_dir='vndk-sp-28',
dt_needed=['libc.so']) dt_needed=['libc.so'])
gb.resolve(VNDKLibDir.create_from_version('28'), '28') 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) 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): def test_add_dlopen_deps(self):
gb = GraphBuilder() gb = GraphBuilder()
liba = gb.add_lib32(PT_SYSTEM, 'liba') liba = gb.add_lib32(PT_SYSTEM, 'liba')
@@ -548,8 +541,8 @@ class ELFLinkerDlopenDepsTest(unittest.TestCase):
def test_add_dlopen_deps_error(self): def test_add_dlopen_deps_error(self):
gb = GraphBuilder() gb = GraphBuilder()
liba = gb.add_lib32(PT_SYSTEM, 'liba') gb.add_lib32(PT_SYSTEM, 'liba')
libb = gb.add_lib32(PT_SYSTEM, 'libb') gb.add_lib32(PT_SYSTEM, 'libb')
gb.resolve() gb.resolve()
with tempfile.NamedTemporaryFile(mode='w') as tmp_file: with tempfile.NamedTemporaryFile(mode='w') as tmp_file:
@@ -560,11 +553,7 @@ class ELFLinkerDlopenDepsTest(unittest.TestCase):
with patch('sys.stderr', stderr): with patch('sys.stderr', stderr):
gb.graph.add_dlopen_deps(tmp_file.name) gb.graph.add_dlopen_deps(tmp_file.name)
self.assertRegexpMatches( self.assertRegex(
stderr.getvalue(), stderr.getvalue(),
'error:' + re.escape(tmp_file.name) + ':1: ' + 'error:' + re.escape(tmp_file.name) + ':1: ' +
'Failed to add dlopen dependency from .* to .*\\.\n') 'Failed to add dlopen dependency from .* to .*\\.\n')
if __name__ == '__main__':
unittest.main()

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 from __future__ import print_function
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import unittest import unittest
from vndk_definition_tool import ELFResolver from vndk_definition_tool import ELFResolver
class ELFResolverTest(unittest.TestCase): class ELFResolverTest(unittest.TestCase):
def setUp(self): def setUp(self):
lib_set = { lib_set = {
@@ -24,50 +21,51 @@ class ELFResolverTest(unittest.TestCase):
self.resolver = ELFResolver(lib_set, ['/system/lib', '/vendor/lib']) self.resolver = ELFResolver(lib_set, ['/system/lib', '/vendor/lib'])
def test_get_candidates(self): def test_get_candidates(self):
r = self.resolver r = self.resolver
self.assertEqual( self.assertEqual(
['/system/lib/libx.so', '/vendor/lib/libx.so'], ['/system/lib/libx.so', '/vendor/lib/libx.so'],
list(r.get_candidates('/system/lib/libreq.so', 'libx.so'))) list(r.get_candidates('/system/lib/libreq.so', 'libx.so')))
self.assertEqual( self.assertEqual(
['/C/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'], ['/C/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'],
list(r.get_candidates('/system/lib/libreq.so', 'libx.so', list(r.get_candidates('/system/lib/libreq.so', 'libx.so', ['/C'])))
['/C'])))
self.assertEqual( self.assertEqual(
['/C/libx.so', '/D/libx.so', '/system/lib/libx.so', ['/C/libx.so', '/D/libx.so', '/system/lib/libx.so',
'/vendor/lib/libx.so'], '/vendor/lib/libx.so'],
list(r.get_candidates('/system/lib/libreq.so', 'libx.so', list(r.get_candidates('/system/lib/libreq.so', 'libx.so',
['/C', '/D']))) ['/C', '/D'])))
self.assertEqual( self.assertEqual(
['/E/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'], ['/E/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'],
list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None, list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None,
['/E']))) ['/E'])))
self.assertEqual( self.assertEqual(
['/E/libx.so', '/F/libx.so', '/system/lib/libx.so', ['/E/libx.so', '/F/libx.so', '/system/lib/libx.so',
'/vendor/lib/libx.so'], '/vendor/lib/libx.so'],
list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None, list(r.get_candidates('/system/lib/libreq.so', 'libx.so', None,
['/E', '/F']))) ['/E', '/F'])))
self.assertEqual( self.assertEqual(
['/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so', ['/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so',
'/system/lib/libx.so', '/vendor/lib/libx.so'], '/system/lib/libx.so', '/vendor/lib/libx.so'],
list(r.get_candidates('/system/lib/libreq.so', 'libx.so', list(r.get_candidates('/system/lib/libreq.so', 'libx.so',
['/C', '/D'], ['/E', '/F']))) ['/C', '/D'], ['/E', '/F'])))
# Test app-specific search paths. # Test app-specific search paths.
self.assertEqual( self.assertEqual(
['/system/app/example/lib/armeabi-v7a/libx.so', ['/system/app/example/lib/armeabi-v7a/libx.so',
'/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so', '/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so',
'/system/lib/libx.so', '/vendor/lib/libx.so'], '/system/lib/libx.so', '/vendor/lib/libx.so'],
list(r.get_candidates( list(r.get_candidates(
'/system/app/example/lib/armeabi-v7a/libreq.so', '/system/app/example/lib/armeabi-v7a/libreq.so',
'libx.so', 'libx.so',
['/C', '/D'], ['/E', '/F']))) ['/C', '/D'], ['/E', '/F'])))
def test_resolve(self): def test_resolve(self):
r = self.resolver r = self.resolver
@@ -76,23 +74,19 @@ class ELFResolverTest(unittest.TestCase):
self.assertEqual(None, r.resolve('/system/lib/libreq.so', 'libe.so')) self.assertEqual(None, r.resolve('/system/lib/libreq.so', 'libe.so'))
self.assertEqual( self.assertEqual(
'e', 'e',
r.resolve('/system/lib/libreq.so', 'libe.so', r.resolve('/system/lib/libreq.so', 'libe.so',
dt_rpath=['/system/lib/hw'])) dt_rpath=['/system/lib/hw']))
self.assertEqual( self.assertEqual(
'e', 'e',
r.resolve('/system/lib/libreq.so', 'libe.so', r.resolve('/system/lib/libreq.so', 'libe.so',
dt_runpath=['/system/lib/hw'])) dt_runpath=['/system/lib/hw']))
self.assertEqual( self.assertEqual(
'a2', 'a2',
r.resolve('/system/lib/libreq.so', 'liba.so', r.resolve('/system/lib/libreq.so', 'liba.so',
dt_rpath=['/vendor/lib'])) dt_rpath=['/vendor/lib']))
self.assertEqual( self.assertEqual(
'a2', 'a2',
r.resolve('/system/lib/libreq.so', 'liba.so', r.resolve('/system/lib/libreq.so', 'liba.so',
dt_runpath=['/vendor/lib'])) dt_runpath=['/vendor/lib']))
if __name__ == '__main__':
unittest.main()

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

@@ -2,23 +2,20 @@
from __future__ import print_function from __future__ import print_function
import argparse
import collections
import difflib
import os import os
import re import re
import subprocess import subprocess
import sys import sys
import unittest import unittest
from compat import TemporaryDirectory, makedirs from .compat import TemporaryDirectory, makedirs
import ndk_toolchain from .ndk_toolchain import create_targets
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
VNDK_DEF_TOOL = os.path.join(SCRIPT_DIR, '..', 'vndk_definition_tool.py') 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') EXPECTED_DIR = os.path.join(SCRIPT_DIR, 'testdata', 'test_elfdump', 'expected')
test_dir_base = None test_dir_base = None
@@ -31,7 +28,7 @@ def run_elf_dump(path):
class ELFDumpTest(unittest.TestCase): class ELFDumpTest(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.targets = ndk_toolchain.create_targets() cls.targets = create_targets()
if test_dir_base: if test_dir_base:
cls.test_dir_base = test_dir_base cls.test_dir_base = test_dir_base
@@ -41,11 +38,13 @@ class ELFDumpTest(unittest.TestCase):
cls._build_fixtures(cls.target_name) cls._build_fixtures(cls.target_name)
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
if not test_dir_base: if not test_dir_base:
cls.tmp_dir.cleanup() cls.tmp_dir.cleanup()
@classmethod @classmethod
def _build_fixtures(cls, target_name): def _build_fixtures(cls, target_name):
target = cls.targets[target_name] target = cls.targets[target_name]
@@ -97,6 +96,7 @@ class ELFDumpTest(unittest.TestCase):
['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib', ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib',
'-Wl,--enable-new-dtags']) '-Wl,--enable-new-dtags'])
def _remove_size_lines(self, lines): def _remove_size_lines(self, lines):
"""Remove file size information because they may vary.""" """Remove file size information because they may vary."""
prefixes = ( prefixes = (
@@ -109,6 +109,7 @@ class ELFDumpTest(unittest.TestCase):
patt = re.compile('|'.join('(?:' + re.escape(x) +')' for x in prefixes)) patt = re.compile('|'.join('(?:' + re.escape(x) +')' for x in prefixes))
return [line for line in lines if not patt.match(line)] return [line for line in lines if not patt.match(line)]
def _assert_equal_to_file(self, expected_file_name, actual): def _assert_equal_to_file(self, expected_file_name, actual):
actual = actual.splitlines(True) actual = actual.splitlines(True)
expected_file_path = os.path.join(self.expected_dir, expected_file_name) 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.assertEqual(self._remove_size_lines(expected),
self._remove_size_lines(actual)) self._remove_size_lines(actual))
def _test_main_out(self): def _test_main_out(self):
out_file = os.path.join(self.test_dir, 'main.out') out_file = os.path.join(self.test_dir, 'main.out')
self._assert_equal_to_file('main.out.txt', run_elf_dump(out_file)) self._assert_equal_to_file('main.out.txt', run_elf_dump(out_file))
def _test_libtest(self, expected_file_name, lib_name): def _test_libtest(self, expected_file_name, lib_name):
lib_file = os.path.join(self.test_dir, 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)) 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 class_name = 'ELFDumpTest_' + target_name
globals()[class_name] = type( globals()[class_name] = type(
class_name, (ELFDumpTest,), class_name, (ELFDumpTest,),
dict(test_main=test_main, dict(test_main=test_main,
test_libtest=test_libtest, test_libtest=test_libtest,
test_libtest_rpath=test_libtest_rpath, test_libtest_rpath=test_libtest_rpath,
test_libtest_rpath_multi=test_libtest_rpath_multi, test_libtest_rpath_multi=test_libtest_rpath_multi,
test_libtest_runpath=test_libtest_runpath, test_libtest_runpath=test_libtest_runpath,
test_libtest_runpath_multi=test_libtest_runpath_multi, test_libtest_runpath_multi=test_libtest_runpath_multi,
target_name=target_name)) target_name=target_name))
for target in ('arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'): for target in ('arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'):
create_target_test(target) 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 from __future__ import print_function
import os import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import argparse
import unittest import unittest
from compat import TemporaryDirectory, makedirs
from vndk_definition_tool import GenericRefs from vndk_definition_tool import GenericRefs
@@ -17,11 +12,13 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
class MockELF(object): class MockELF(object):
# pylint: disable=too-few-public-methods
def __init__(self, exported_symbols): def __init__(self, exported_symbols):
self.exported_symbols = exported_symbols self.exported_symbols = exported_symbols
class MockLib(object): class MockLib(object):
# pylint: disable=too-few-public-methods
def __init__(self, path, exported_symbols): def __init__(self, path, exported_symbols):
self.path = path self.path = path
self.elf = MockELF(exported_symbols) self.elf = MockELF(exported_symbols)
@@ -39,6 +36,7 @@ class GenericRefsTest(unittest.TestCase):
self.ref.add('/system/lib64/libm.so', self.ref.add('/system/lib64/libm.so',
MockELF({'cos', 'sin', 'tan'})) MockELF({'cos', 'sin', 'tan'}))
def test_create_from_sym_dir(self): def test_create_from_sym_dir(self):
input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs') input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs')
@@ -60,6 +58,7 @@ class GenericRefsTest(unittest.TestCase):
self.assertEqual({'cos', 'sin', 'tan'}, self.assertEqual({'cos', 'sin', 'tan'},
g.refs['/system/lib64/libm.so'].exported_symbols) g.refs['/system/lib64/libm.so'].exported_symbols)
def test_classify_lib(self): def test_classify_lib(self):
libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'}) libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
libc_sup = MockLib('/system/lib/libc.so', libc_sup = MockLib('/system/lib/libc.so',
@@ -75,6 +74,7 @@ class GenericRefsTest(unittest.TestCase):
self.ref.classify_lib(libc_eq)) self.ref.classify_lib(libc_eq))
self.assertEqual(GenericRefs.NEW_LIB, self.ref.classify_lib(libfoo)) self.assertEqual(GenericRefs.NEW_LIB, self.ref.classify_lib(libfoo))
def test_is_equivalent_lib(self): def test_is_equivalent_lib(self):
libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'}) libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
libc_sup = MockLib('/system/lib/libc.so', libc_sup = MockLib('/system/lib/libc.so',
@@ -87,12 +87,9 @@ class GenericRefsTest(unittest.TestCase):
self.assertTrue(self.ref.is_equivalent_lib(libc_eq)) self.assertTrue(self.ref.is_equivalent_lib(libc_eq))
def test_has_same_name_lib(self): def test_has_same_name_lib(self):
self.assertTrue(self.ref.has_same_name_lib( self.assertTrue(self.ref.has_same_name_lib(
MockLib('/vendor/lib/libc.so', {}))) MockLib('/vendor/lib/libc.so', {})))
self.assertFalse(self.ref.has_same_name_lib( self.assertFalse(self.ref.has_same_name_lib(
MockLib('/vendor/lib/lib_does_not_exist.so', {}))) 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 from __future__ import print_function
import os import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import unittest import unittest
from vndk_definition_tool import ModuleInfo from vndk_definition_tool import ModuleInfo
@@ -18,6 +15,7 @@ class ModuleInfoTest(unittest.TestCase):
m = ModuleInfo.load_from_path_or_default(None) m = ModuleInfo.load_from_path_or_default(None)
self.assertEqual([], m.get_module_path('/system/lib64/libA.so')) self.assertEqual([], m.get_module_path('/system/lib64/libA.so'))
def test_get_module_path(self): def test_get_module_path(self):
json_path = os.path.join(SCRIPT_DIR, 'testdata', 'test_module_info', json_path = os.path.join(SCRIPT_DIR, 'testdata', 'test_module_info',
'module-info.json') 'module-info.json')
@@ -33,8 +31,4 @@ class ModuleInfoTest(unittest.TestCase):
m.get_module_path('/system/lib64/hw/libC.so')) m.get_module_path('/system/lib64/hw/libC.so'))
self.assertEqual( 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__':
unittest.main()

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 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 tempfile
import unittest import unittest
from compat import StringIO
from vndk_definition_tool import TaggedDict, TaggedPathDict, TaggedLibDict, \ from vndk_definition_tool import TaggedDict, TaggedPathDict, TaggedLibDict, \
NUM_PARTITIONS, PT_SYSTEM, PT_VENDOR NUM_PARTITIONS, PT_SYSTEM, PT_VENDOR
from .compat import StringIO
_TEST_DATA = '''Path,Tag _TEST_DATA = '''Path,Tag
/system/lib/lib_ll_ndk.so,ll-ndk /system/lib/lib_ll_ndk.so,ll-ndk
@@ -103,37 +100,38 @@ class TaggedPathDictTest(unittest.TestCase):
tagged_paths = TaggedPathDict() tagged_paths = TaggedPathDict()
self.assertEqual( self.assertEqual(
['/system/lib/libc.so'], ['/system/lib/libc.so'],
list(tagged_paths._enumerate_paths('/system/lib/libc.so'))) list(tagged_paths._enumerate_paths('/system/lib/libc.so')))
self.assertEqual( self.assertEqual(
['/system/lib/libc.so', '/system/lib64/libc.so'], ['/system/lib/libc.so', '/system/lib64/libc.so'],
list(tagged_paths._enumerate_paths('/system/${LIB}/libc.so'))) list(tagged_paths._enumerate_paths('/system/${LIB}/libc.so')))
self.assertEqual( self.assertEqual(
['/system/lib/vndk/libutils.so', ['/system/lib/vndk/libutils.so',
'/system/lib64/vndk/libutils.so'], '/system/lib64/vndk/libutils.so'],
list(tagged_paths._enumerate_paths( list(tagged_paths._enumerate_paths(
'/system/${LIB}/vndk${VNDK_VER}/libutils.so'))) '/system/${LIB}/vndk${VNDK_VER}/libutils.so')))
tagged_paths = TaggedPathDict(['current', '27', '28']) tagged_paths = TaggedPathDict(['current', '27', '28'])
self.assertEqual( self.assertEqual(
['/system/lib/vndk/libutils.so', ['/system/lib/vndk/libutils.so',
'/system/lib64/vndk/libutils.so', '/system/lib64/vndk/libutils.so',
'/system/lib/vndk-27/libutils.so', '/system/lib/vndk-27/libutils.so',
'/system/lib64/vndk-27/libutils.so', '/system/lib64/vndk-27/libutils.so',
'/system/lib/vndk-28/libutils.so', '/system/lib/vndk-28/libutils.so',
'/system/lib64/vndk-28/libutils.so'], '/system/lib64/vndk-28/libutils.so'],
list(tagged_paths._enumerate_paths( list(tagged_paths._enumerate_paths(
'/system/${LIB}/vndk${VNDK_VER}/libutils.so'))) '/system/${LIB}/vndk${VNDK_VER}/libutils.so')))
self.assertEqual( self.assertEqual(
['/system/lib/vndk/libutils.so', ['/system/lib/vndk/libutils.so',
'/system/lib/vndk-27/libutils.so', '/system/lib/vndk-27/libutils.so',
'/system/lib/vndk-28/libutils.so'], '/system/lib/vndk-28/libutils.so'],
list(tagged_paths._enumerate_paths( list(tagged_paths._enumerate_paths(
'/system/lib/vndk${VNDK_VER}/libutils.so'))) '/system/lib/vndk${VNDK_VER}/libutils.so')))
def test_load_from_csv_empty(self): def test_load_from_csv_empty(self):
try: try:
@@ -218,8 +216,8 @@ class TaggedPathDictTest(unittest.TestCase):
self.assertEqual('vndk_sp_indirect', self.assertEqual('vndk_sp_indirect',
d.get_path_tag('/system/lib/lib_vndk_sp_indirect.so')) d.get_path_tag('/system/lib/lib_vndk_sp_indirect.so'))
self.assertEqual( self.assertEqual(
'vndk_sp_indirect_private', 'vndk_sp_indirect_private',
d.get_path_tag('/system/lib/lib_vndk_sp_indirect_private.so')) 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('vndk', d.get_path_tag('/system/lib/lib_vndk.so'))
self.assertEqual('fwk_only', self.assertEqual('fwk_only',
d.get_path_tag('/system/lib/lib_fwk_only.so')) d.get_path_tag('/system/lib/lib_fwk_only.so'))
@@ -368,17 +366,19 @@ class MockELFGraph(object):
def __init__(self): def __init__(self):
self.lib_pt = [dict() for i in range(NUM_PARTITIONS)] self.lib_pt = [dict() for i in range(NUM_PARTITIONS)]
def add(self, path): def add(self, path):
partition = PT_VENDOR if path.startswith('/vendor') else PT_SYSTEM partition = PT_VENDOR if path.startswith('/vendor') else PT_SYSTEM
lib = MockELFLinkData(path) lib = MockELFLinkData(path)
self.lib_pt[partition][path] = lib self.lib_pt[partition][path] = lib
return lib return lib
def compute_sp_lib(self, generic_refs=None): def compute_sp_lib(self, generic_refs=None):
vendor_libs = self.lib_pt[PT_VENDOR].values() vendor_libs = self.lib_pt[PT_VENDOR].values()
return MockSPLibResult( 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.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_dep.so' in v.path))
class TaggedLibDictTest(unittest.TestCase): 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 = self.graph.add('/system/lib/lib_ll_ndk.so')
self.lib_ll_ndk_indirect = \ 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 = self.graph.add('/system/lib/lib_vndk_sp.so')
self.lib_vndk_sp_indirect = \ 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.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') 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.lib_vnd_only = self.graph.add('/vendor/lib/lib_vnd_only.so')
self.tagged_libs = TaggedLibDict.create_from_graph( self.tagged_libs = TaggedLibDict.create_from_graph(
self.graph, self.tagged_paths) self.graph, self.tagged_paths)
def test_create_from_graph(self): def test_create_from_graph(self):
@@ -456,7 +456,3 @@ class TaggedLibDictTest(unittest.TestCase):
self.assertEqual('fwk_only', tag) self.assertEqual('fwk_only', tag)
tag = d.get_path_tag(MockELFLinkData('/vendor/lib/unknown.so')) tag = d.get_path_tag(MockELFLinkData('/vendor/lib/unknown.so'))
self.assertEqual('vnd_only', tag) 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 from __future__ import print_function
import os from vndk_definition_tool import (PT_SYSTEM, PT_VENDOR)
import sys
import unittest
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from .compat import StringIO, TestCase, patch
from .utils import GraphBuilder
from compat import StringIO, patch
from vndk_definition_tool import (ELF, ELFLinker, PT_SYSTEM, PT_VENDOR)
from utils import GraphBuilder
class ELFLinkerVNDKTest(unittest.TestCase): class ELFLinkerVNDKTest(TestCase):
def test_normalize_partition_tags_bad_vendor_deps(self): def test_normalize_partition_tags_bad_vendor_deps(self):
"""Check whether normalize_partition_tags() hides the dependencies from """Check whether normalize_partition_tags() hides the dependencies from
the system partition to the vendor partition if the dependencies are the system partition to the vendor partition if the dependencies are
@@ -31,10 +26,10 @@ class ELFLinkerVNDKTest(unittest.TestCase):
with patch('sys.stderr', stderr): with patch('sys.stderr', stderr):
gb.graph.normalize_partition_tags(set(), None) gb.graph.normalize_partition_tags(set(), None)
self.assertRegexpMatches( self.assertRegex(
stderr.getvalue(), stderr.getvalue(),
'error: .*: system exe/lib must not depend on vendor lib .*. ' 'error: .*: system exe/lib must not depend on vendor lib .*. '
'Assume such dependency does not exist.') 'Assume such dependency does not exist.')
self.assertNotIn(libvnd, libfwk.deps_needed) self.assertNotIn(libvnd, libfwk.deps_needed)
self.assertNotIn(libfwk, libvnd.users_needed) self.assertNotIn(libfwk, libvnd.users_needed)
@@ -74,7 +69,7 @@ class ELFLinkerVNDKTest(unittest.TestCase):
"""Check the computation of vndk without generic references.""" """Check the computation of vndk without generic references."""
gb = GraphBuilder() 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 = gb.add_lib32(PT_SYSTEM, 'libvndk', extra_dir='vndk')
libvndk_sp = gb.add_lib32(PT_SYSTEM, 'libutils', extra_dir='vndk-sp') libvndk_sp = gb.add_lib32(PT_SYSTEM, 'libutils', extra_dir='vndk-sp')
libvnd = gb.add_lib32(PT_VENDOR, 'libvnd', libvnd = gb.add_lib32(PT_VENDOR, 'libvnd',
@@ -94,15 +89,17 @@ class ELFLinkerVNDKTest(unittest.TestCase):
"""Check the computation of vndk without generic references.""" """Check the computation of vndk without generic references."""
gb = GraphBuilder() gb = GraphBuilder()
libfwk = gb.add_lib32(PT_SYSTEM, 'libfwk')
libvndk = gb.add_lib32(PT_SYSTEM, 'libvndk', libvndk = gb.add_lib32(
dt_needed=['libvnd_bad.so'], extra_dir='vndk') PT_SYSTEM, 'libvndk', dt_needed=['libvnd_bad.so'],
libvndk_sp = gb.add_lib32(PT_SYSTEM, 'libutils', extra_dir='vndk')
dt_needed=['libvnd_bad.so'],
extra_dir='vndk-sp') libvndk_sp = gb.add_lib32(
libvnd = gb.add_lib32(PT_VENDOR, 'libvnd', PT_SYSTEM, 'libutils', dt_needed=['libvnd_bad.so'],
dt_needed=['libvndk.so', 'libutils.so']) extra_dir='vndk-sp')
libvnd_bad = gb.add_lib32(PT_VENDOR, 'libvnd_bad', extra_dir='vndk-sp') libvnd_bad = gb.add_lib32(PT_VENDOR, 'libvnd_bad', extra_dir='vndk-sp')
gb.resolve() gb.resolve()
self.assertIn(libvnd_bad, libvndk.deps_all) self.assertIn(libvnd_bad, libvndk.deps_all)
@@ -136,7 +133,3 @@ class ELFLinkerVNDKTest(unittest.TestCase):
self.assertIn(libEGL_chipset, vndk_sets.sp_hal) self.assertIn(libEGL_chipset, vndk_sets.sp_hal)
self.assertNotIn(libEGL_chipset, vndk_sets.ll_ndk_indirect) 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 os
import posixpath import posixpath
import sys
import unittest 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 .compat import StringIO
from vndk_definition_tool import ELF, VNDKLibDir
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 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): def test_create_vndk_sp_dir_name(self):
self.assertEqual( self.assertEqual(
'vndk-sp', VNDKLibDir.create_vndk_sp_dir_name('current')) 'vndk-sp', VNDKLibDir.create_vndk_sp_dir_name('current'))
self.assertEqual( 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): def test_create_vndk_dir_name(self):
self.assertEqual( self.assertEqual(
'vndk', VNDKLibDir.create_vndk_dir_name('current')) 'vndk', VNDKLibDir.create_vndk_dir_name('current'))
self.assertEqual( 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): def test_extract_vndk_version_from_name(self):
self.assertEqual( self.assertEqual(
'current', VNDKLibDir.extract_version_from_name('vndk')) 'current', VNDKLibDir.extract_version_from_name('vndk'))
self.assertEqual( self.assertEqual(
'current', VNDKLibDir.extract_version_from_name('vndk-sp')) 'current', VNDKLibDir.extract_version_from_name('vndk-sp'))
self.assertEqual( self.assertEqual(
'28', VNDKLibDir.extract_version_from_name('vndk-28')) '28', VNDKLibDir.extract_version_from_name('vndk-28'))
self.assertEqual( self.assertEqual(
'28', VNDKLibDir.extract_version_from_name('vndk-sp-28')) '28', VNDKLibDir.extract_version_from_name('vndk-sp-28'))
self.assertEqual( self.assertEqual(
'p', VNDKLibDir.extract_version_from_name('vndk-p')) 'p', VNDKLibDir.extract_version_from_name('vndk-p'))
self.assertEqual( 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): def test_extract_vndk_version_from_path(self):
ans = VNDKLibDir.extract_version_from_path( ans = VNDKLibDir.extract_version_from_path(
'/system/lib64/vndk/libexample.so') '/system/lib64/vndk/libexample.so')
self.assertEqual('current', ans) self.assertEqual('current', ans)
ans = VNDKLibDir.extract_version_from_path( ans = VNDKLibDir.extract_version_from_path(
'/system/lib64/vndk-sp/libexample.so') '/system/lib64/vndk-sp/libexample.so')
self.assertEqual('current', ans) self.assertEqual('current', ans)
ans = VNDKLibDir.extract_version_from_path( ans = VNDKLibDir.extract_version_from_path(
'/system/lib64/vndk-28/libexample.so') '/system/lib64/vndk-28/libexample.so')
self.assertEqual('28', ans) self.assertEqual('28', ans)
ans = VNDKLibDir.extract_version_from_path( ans = VNDKLibDir.extract_version_from_path(
'/system/lib64/vndk-sp-28/libexample.so') '/system/lib64/vndk-sp-28/libexample.so')
self.assertEqual('28', ans) self.assertEqual('28', ans)
ans = VNDKLibDir.extract_version_from_path( ans = VNDKLibDir.extract_version_from_path(
'/system/lib64/vndk-p/libexample.so') '/system/lib64/vndk-p/libexample.so')
self.assertEqual('p', ans) self.assertEqual('p', ans)
ans = VNDKLibDir.extract_version_from_path( ans = VNDKLibDir.extract_version_from_path(
'/system/lib64/vndk-sp-p/libexample.so') '/system/lib64/vndk-sp-p/libexample.so')
self.assertEqual('p', ans) self.assertEqual('p', ans)
ans = VNDKLibDir.extract_version_from_path( 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) self.assertEqual('p', ans)
ans = VNDKLibDir.extract_version_from_path( ans = VNDKLibDir.extract_version_from_path(
'/system/lib64/libexample.so') '/system/lib64/libexample.so')
self.assertEqual(None, ans) self.assertEqual(None, ans)
def test_is_in_vndk_sp_dir(self): 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/liba.so'))
self.assertFalse( 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( 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( 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( 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( 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): def test_is_in_vndk_dir(self):
self.assertFalse(VNDKLibDir.is_in_vndk_dir('/system/lib/liba.so')) 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/liba.so'))
self.assertTrue( 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( 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( 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( 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): def test_create_vndk_search_paths(self):
@@ -126,7 +124,7 @@ class VNDKLibDirTest(unittest.TestCase):
] ]
vndk_sp_dirs, vndk_dirs = \ 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_sp, vndk_sp_dirs)
self.assertEqual(expected_vndk, vndk_dirs) self.assertEqual(expected_vndk, vndk_dirs)
@@ -139,35 +137,34 @@ class VNDKLibDirTest(unittest.TestCase):
def test_create_from_dirs_unversioned(self): def test_create_from_dirs_unversioned(self):
input_dir = os.path.join( input_dir = os.path.join(
SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', 'vndk_unversioned')
'vndk_unversioned')
vndk_lib_dirs = VNDKLibDir.create_from_dirs( vndk_lib_dirs = VNDKLibDir.create_from_dirs(
[os.path.join(input_dir, 'system')], [os.path.join(input_dir, 'system')],
[os.path.join(input_dir, 'vendor')]) [os.path.join(input_dir, 'vendor')])
self.assertIn('current', vndk_lib_dirs) self.assertIn('current', vndk_lib_dirs)
def test_create_from_dirs_versioned(self): def test_create_from_dirs_versioned(self):
input_dir = os.path.join( 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( vndk_lib_dirs = VNDKLibDir.create_from_dirs(
[os.path.join(input_dir, 'system')], [os.path.join(input_dir, 'system')],
[os.path.join(input_dir, 'vendor')]) [os.path.join(input_dir, 'vendor')])
self.assertIn('28', vndk_lib_dirs) self.assertIn('28', vndk_lib_dirs)
def test_create_from_dirs_versioned_multiple(self): def test_create_from_dirs_versioned_multiple(self):
input_dir = os.path.join( input_dir = os.path.join(
SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir',
'vndk_versioned_multiple') 'vndk_versioned_multiple')
vndk_lib_dirs = VNDKLibDir.create_from_dirs( vndk_lib_dirs = VNDKLibDir.create_from_dirs(
[os.path.join(input_dir, 'system')], [os.path.join(input_dir, 'system')],
[os.path.join(input_dir, 'vendor')]) [os.path.join(input_dir, 'vendor')])
self.assertIn('28', vndk_lib_dirs) self.assertIn('28', vndk_lib_dirs)
self.assertIn('29', 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): def test_create_from_dirs_versioned_32bit_only(self):
input_dir = os.path.join( 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( vndk_lib_dirs = VNDKLibDir.create_from_dirs(
[os.path.join(input_dir, 'system')], [os.path.join(input_dir, 'system')],
[os.path.join(input_dir, 'vendor')]) [os.path.join(input_dir, 'vendor')])
self.assertIn('28', vndk_lib_dirs) self.assertIn('28', vndk_lib_dirs)
@@ -196,8 +193,8 @@ class VNDKLibDirTest(unittest.TestCase):
def test_get_ro_vndk_version(self): def test_get_ro_vndk_version(self):
input_dir = os.path.join( input_dir = os.path.join(
SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir', SCRIPT_DIR, 'testdata', 'test_vndk_lib_dir',
'vndk_versioned_multiple') 'vndk_versioned_multiple')
vendor_dirs = [os.path.join(input_dir, 'vendor')] vendor_dirs = [os.path.join(input_dir, 'vendor')]
@@ -206,22 +203,17 @@ class VNDKLibDirTest(unittest.TestCase):
def test_sorted_versions(self): def test_sorted_versions(self):
self.assertEqual( self.assertEqual(
['20', '10', '2', '1'], ['20', '10', '2', '1'],
VNDKLibDir.sorted_version(['1', '2', '10', '20'])) VNDKLibDir.sorted_version(['1', '2', '10', '20']))
self.assertEqual( self.assertEqual(
['b', 'a', '20', '10', '2', '1'], ['b', 'a', '20', '10', '2', '1'],
VNDKLibDir.sorted_version(['1', '2', '10', '20', 'a', 'b'])) VNDKLibDir.sorted_version(['1', '2', '10', '20', 'a', 'b']))
self.assertEqual( self.assertEqual(
['a', '10b', '10', '2', '1'], ['a', '10b', '10', '2', '1'],
VNDKLibDir.sorted_version(['1', '2', '10', 'a', '10b'])) VNDKLibDir.sorted_version(['1', '2', '10', 'a', '10b']))
self.assertEqual( self.assertEqual(
['current', 'd', 'a', '10', '1'], ['current', 'd', 'a', '10', '1'],
VNDKLibDir.sorted_version(['1', '10', 'a', 'd', 'current'])) VNDKLibDir.sorted_version(['1', '10', 'a', 'd', 'current']))
if __name__ == '__main__':
unittest.main()

View File

@@ -1,13 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from vndk_definition_tool import (ELF, ELFLinker, PT_SYSTEM, PT_VENDOR)
from compat import StringIO
from vndk_definition_tool import (
ELF, ELFLinker, PT_SYSTEM, PT_VENDOR, VNDKLibDir)
class GraphBuilder(object): class GraphBuilder(object):
@@ -16,16 +11,19 @@ class GraphBuilder(object):
PT_VENDOR: 'vendor', PT_VENDOR: 'vendor',
} }
_LIB_DIRS = { _LIB_DIRS = {
ELF.ELFCLASS32: 'lib', ELF.ELFCLASS32: 'lib',
ELF.ELFCLASS64: 'lib64', ELF.ELFCLASS64: 'lib64',
} }
def __init__(self): def __init__(self):
self.graph = ELFLinker() 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): extra_dir=None):
"""Create and add a shared library to ELFLinker.""" """Create and add a shared library to ELFLinker."""
@@ -37,27 +35,30 @@ class GraphBuilder(object):
path = os.path.join(lib_dir, name + '.so') path = os.path.join(lib_dir, name + '.so')
elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed, elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed,
exported_symbols=exported_symbols, exported_symbols=set(exported_symbols),
imported_symbols=imported_symbols) imported_symbols=set(imported_symbols))
lib = self.graph.add_lib(partition, path, elf) lib = self.graph.add_lib(partition, path, elf)
setattr(self, name + '_' + elf.elf_class_name, lib) setattr(self, name + '_' + elf.elf_class_name, lib)
return 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): extra_dir=None):
return self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed, return self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed,
exported_symbols, imported_symbols, extra_dir) 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): extra_dir=None):
return self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed, return self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed,
exported_symbols, imported_symbols, extra_dir) 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): extra_dir=None):
"""Add 32-bit / 64-bit shared libraries to ELFLinker.""" """Add 32-bit / 64-bit shared libraries to ELFLinker."""
return ( return (
@@ -67,6 +68,7 @@ class GraphBuilder(object):
exported_symbols, imported_symbols, extra_dir) exported_symbols, imported_symbols, extra_dir)
) )
def resolve(self, vndk_lib_dirs=None, ro_vndk_version=None): def resolve(self, vndk_lib_dirs=None, ro_vndk_version=None):
if vndk_lib_dirs is not None: if vndk_lib_dirs is not None:
self.graph.vndk_lib_dirs = vndk_lib_dirs self.graph.vndk_lib_dirs = vndk_lib_dirs

File diff suppressed because it is too large Load Diff