• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2
3from __future__ import print_function
4
5import argparse
6import collections
7import difflib
8import os
9import subprocess
10import sys
11import unittest
12
13from compat import TemporaryDirectory, makedirs
14import ndk_toolchain
15
16
17SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
18VNDK_DEF_TOOL = os.path.join(SCRIPT_DIR, '..', 'vndk_definition_tool.py')
19
20INPUT_DIR = os.path.join(SCRIPT_DIR ,'testdata', 'test_elfdump', 'input')
21EXPECTED_DIR = os.path.join(SCRIPT_DIR, 'testdata', 'test_elfdump', 'expected')
22test_dir_base = None
23
24
25def run_elf_dump(path):
26    cmd = [sys.executable, VNDK_DEF_TOOL, 'elfdump', path]
27    return subprocess.check_output(cmd, universal_newlines=True)
28
29
30class ELFDumpTest(unittest.TestCase):
31    @classmethod
32    def setUpClass(cls):
33        cls.targets = ndk_toolchain.create_targets()
34
35        if test_dir_base:
36            cls.test_dir_base = test_dir_base
37        else:
38            cls.tmp_dir = TemporaryDirectory()
39            cls.test_dir_base = cls.tmp_dir.name
40
41        cls._build_fixtures(cls.target_name)
42
43    @classmethod
44    def tearDownClass(cls):
45        if not test_dir_base:
46            cls.tmp_dir.cleanup()
47
48    @classmethod
49    def _build_fixtures(cls, target_name):
50        target = cls.targets[target_name]
51
52        cls.expected_dir = os.path.join(EXPECTED_DIR, target_name)
53        cls.test_dir = os.path.join(cls.test_dir_base, target_name)
54
55        makedirs(cls.test_dir, exist_ok=True)
56
57        # Compile main.o.
58        src_file = os.path.join(INPUT_DIR, 'main.c')
59        obj_file = os.path.join(cls.test_dir, 'main.o')
60        target.compile(obj_file, src_file, [])
61
62        # Link main.out.
63        out_file = os.path.join(cls.test_dir, 'main.out')
64        target.link(out_file, [obj_file], ['-ldl', '-lc', '-lstdc++'])
65
66        # Compile test.o.
67        src_file = os.path.join(INPUT_DIR, 'test.c')
68        obj_file = os.path.join(cls.test_dir, 'test.o')
69        target.compile(obj_file, src_file, [])
70
71        # Link libtest.so.
72        out_file = os.path.join(cls.test_dir, 'libtest.so')
73        target.link(out_file, [obj_file], ['-shared', '-lc'])
74
75        # Link libtest-rpath.so.
76        out_file = os.path.join(cls.test_dir, 'libtest-rpath.so')
77        target.link(out_file, [obj_file],
78                    ['-shared', '-lc', '-Wl,-rpath,$ORIGIN/../lib',
79                     '-Wl,--disable-new-dtags'])
80
81        # Link libtest-rpath-multi.so.
82        out_file = os.path.join(cls.test_dir, 'libtest-rpath-multi.so')
83        target.link(out_file, [obj_file],
84                    ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib',
85                     '-Wl,--disable-new-dtags'])
86
87        # Link libtest-runpath.so.
88        out_file = os.path.join(cls.test_dir, 'libtest-runpath.so')
89        target.link(out_file, [obj_file],
90                    ['-shared', '-lc', '-Wl,-rpath,$ORIGIN/../lib',
91                     '-Wl,--enable-new-dtags'])
92
93        # Link libtest-runpath-multi.so.
94        out_file = os.path.join(cls.test_dir, 'libtest-runpath-multi.so')
95        target.link(out_file, [obj_file],
96                    ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib',
97                     '-Wl,--enable-new-dtags'])
98
99    def _assert_equal_to_file(self, expected_file_name, actual):
100        actual = actual.splitlines(True)
101        expected_file_path = os.path.join(self.expected_dir, expected_file_name)
102        with open(expected_file_path, 'r') as f:
103            expected = f.readlines()
104        self.assertEqual(expected, actual)
105
106    def _test_main_out(self):
107        out_file = os.path.join(self.test_dir, 'main.out')
108        self._assert_equal_to_file('main.out.txt', run_elf_dump(out_file))
109
110    def _test_libtest(self, expected_file_name, lib_name):
111        lib_file = os.path.join(self.test_dir, lib_name)
112        self._assert_equal_to_file(expected_file_name, run_elf_dump(lib_file))
113
114
115def create_target_test(target_name):
116    def test_main(self):
117        self._test_main_out()
118
119    def test_libtest(self):
120        self._test_libtest('libtest.so.txt', 'libtest.so')
121
122    def test_libtest_rpath(self):
123        self._test_libtest('libtest-rpath.so.txt', 'libtest-rpath.so')
124
125    def test_libtest_rpath_multi(self):
126        self._test_libtest('libtest-rpath-multi.so.txt',
127                           'libtest-rpath-multi.so')
128
129    def test_libtest_runpath(self):
130        self._test_libtest('libtest-runpath.so.txt', 'libtest-runpath.so')
131
132    def test_libtest_runpath_multi(self):
133        self._test_libtest('libtest-runpath-multi.so.txt',
134                           'libtest-runpath-multi.so')
135
136    class_name = 'ELFDumpTest_' + target_name
137    globals()[class_name] = type(
138            class_name, (ELFDumpTest,),
139            dict(test_main=test_main,
140                 test_libtest=test_libtest,
141                 test_libtest_rpath=test_libtest_rpath,
142                 test_libtest_rpath_multi=test_libtest_rpath_multi,
143                 test_libtest_runpath=test_libtest_runpath,
144                 test_libtest_runpath_multi=test_libtest_runpath_multi,
145                 target_name=target_name))
146
147
148for target in ('arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'):
149    create_target_test(target)
150
151
152def main():
153    # Parse command line arguments.
154    parser = argparse.ArgumentParser()
155    parser.add_argument('--test-dir', help='directory for temporary files')
156    parser.add_argument('--expected-dir', help='directory with expected output')
157    args, unittest_args = parser.parse_known_args()
158
159    # Convert command line options.
160    global expected_dir
161    global test_dir_base
162
163    if args.expected_dir:
164        expected_dir = args.expected_dir
165    if args.test_dir:
166        test_dir_base = args.test_dir
167
168    # Run unit test.
169    unittest.main(argv=[sys.argv[0]] + unittest_args)
170
171if __name__ == '__main__':
172    main()
173