• 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 targets
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 = targets.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
80        # Link libtest-rpath-multi.so.
81        out_file = os.path.join(cls.test_dir, 'libtest-rpath-multi.so')
82        target.link(out_file, [obj_file],
83                    ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib'])
84
85        # Link libtest-runpath.so.
86        out_file = os.path.join(cls.test_dir, 'libtest-runpath.so')
87        target.link(out_file, [obj_file],
88                    ['-shared', '-lc', '-Wl,-rpath,$ORIGIN/../lib',
89                     '-Wl,--enable-new-dtags'])
90
91        # Link libtest-runpath-multi.so.
92        out_file = os.path.join(cls.test_dir, 'libtest-runpath-multi.so')
93        target.link(out_file, [obj_file],
94                    ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib',
95                     '-Wl,--enable-new-dtags'])
96
97    def _assert_equal_to_file(self, expected_file_name, actual):
98        actual = actual.splitlines(True)
99        expected_file_path = os.path.join(self.expected_dir, expected_file_name)
100        with open(expected_file_path, 'r') as f:
101            expected = f.readlines()
102        self.assertEqual(expected, actual)
103
104    def _test_main_out(self):
105        out_file = os.path.join(self.test_dir, 'main.out')
106        self._assert_equal_to_file('main.out.txt', run_elf_dump(out_file))
107
108    def _test_libtest(self, expected_file_name, lib_name):
109        lib_file = os.path.join(self.test_dir, lib_name)
110        self._assert_equal_to_file(expected_file_name, run_elf_dump(lib_file))
111
112
113def create_target_test(target_name):
114    def test_main(self):
115        self._test_main_out()
116
117    def test_libtest(self):
118        self._test_libtest('libtest.so.txt', 'libtest.so')
119
120    def test_libtest_rpath(self):
121        self._test_libtest('libtest-rpath.so.txt', 'libtest-rpath.so')
122
123    def test_libtest_rpath_multi(self):
124        self._test_libtest('libtest-rpath-multi.so.txt',
125                           'libtest-rpath-multi.so')
126
127    def test_libtest_runpath(self):
128        self._test_libtest('libtest-runpath.so.txt', 'libtest-runpath.so')
129
130    def test_libtest_runpath_multi(self):
131        self._test_libtest('libtest-runpath-multi.so.txt',
132                           'libtest-runpath-multi.so')
133
134    class_name = 'ELFDumpTest_' + target_name
135    globals()[class_name] = type(
136            class_name, (ELFDumpTest,),
137            dict(test_main=test_main,
138                 test_libtest=test_libtest,
139                 test_libtest_rpath=test_libtest_rpath,
140                 test_libtest_rpath_multi=test_libtest_rpath_multi,
141                 test_libtest_runpath=test_libtest_runpath,
142                 test_libtest_runpath_multi=test_libtest_runpath_multi,
143                 target_name=target_name))
144
145
146for target in ('arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'):
147    create_target_test(target)
148
149
150def main():
151    # Parse command line arguments.
152    parser = argparse.ArgumentParser()
153    parser.add_argument('--test-dir', help='directory for temporary files')
154    parser.add_argument('--expected-dir', help='directory with expected output')
155    args, unittest_args = parser.parse_known_args()
156
157    # Convert command line options.
158    global expected_dir
159    global test_dir_base
160
161    if args.expected_dir:
162        expected_dir = args.expected_dir
163    if args.test_dir:
164        test_dir_base = args.test_dir
165
166    # Run unit test.
167    unittest.main(argv=[sys.argv[0]] + unittest_args)
168
169if __name__ == '__main__':
170    main()
171