• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2
3import os
4import unittest
5import sys
6import tempfile
7
8import_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
9import_path = os.path.abspath(os.path.join(import_path, 'utils'))
10sys.path.insert(1, import_path)
11
12from utils import (
13        AOSP_DIR, SOURCE_ABI_DUMP_EXT, TARGET_ARCHS, read_output_content,
14        run_abi_diff, run_header_abi_dumper)
15from module import Module
16from gen_all import make_and_copy_reference_dumps
17
18SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
19INPUT_DIR = os.path.join(SCRIPT_DIR, 'input')
20EXPECTED_DIR = os.path.join(SCRIPT_DIR, 'expected')
21REF_DUMP_DIR = os.path.join(SCRIPT_DIR,  'reference_dumps')
22
23class MyTest(unittest.TestCase):
24    @classmethod
25    def setUpClass(cls):
26        cls.maxDiff = None
27
28    def get_reference_dump_path(self, name, target_arch):
29        ref_dump_dir = os.path.join(REF_DUMP_DIR, target_arch)
30        ref_dump_path = os.path.join(ref_dump_dir,
31                                     name + SOURCE_ABI_DUMP_EXT)
32        return ref_dump_path
33
34    def run_and_compare(self, input_path, expected_path, cflags=[]):
35        with open(expected_path, 'r') as f:
36            expected_output = f.read()
37        actual_output = run_header_abi_dumper(input_path, True, cflags)
38        self.assertEqual(actual_output, expected_output)
39
40    def run_and_compare_name(self, name, cflags=[]):
41        input_path = os.path.join(INPUT_DIR, name)
42        expected_path = os.path.join(EXPECTED_DIR, name)
43        self.run_and_compare(input_path, expected_path, cflags)
44
45    def run_and_compare_name_cpp(self, name, cflags=[]):
46        self.run_and_compare_name(name, cflags + ['-x', 'c++', '-std=c++11'])
47
48    def run_and_compare_name_c_cpp(self, name, cflags=[]):
49        self.run_and_compare_name(name, cflags)
50        self.run_and_compare_name_cpp(name, cflags)
51
52    def run_and_compare_abi_diff(self, old_dump, new_dump, lib, arch,
53                                 expected_return_code, flags=[]) :
54        actual_output = run_abi_diff(old_dump, new_dump, arch, lib, flags)
55        self.assertEqual(actual_output, expected_return_code)
56
57    def prepare_and_run_abi_diff(self, old_ref_dump_path, new_ref_dump_path,
58                                 target_arch, expected_return_code, flags=[]):
59        self.run_and_compare_abi_diff(old_ref_dump_path, new_ref_dump_path,
60                                      'test', target_arch, expected_return_code,
61                                      flags)
62
63    def create_ref_dump(self, name, dir_name, target_arch):
64        module_bare = Module.get_test_module_by_name(name)
65        module = Module.mutate_module_for_arch(module_bare, target_arch)
66        return make_and_copy_reference_dumps(module, [],
67                                             dir_name)
68
69    def get_or_create_ref_dump(self, name, target_arch, dir_name, create):
70        if create == True:
71            return self.create_ref_dump(name, dir_name, target_arch)
72        return self.get_reference_dump_path(name, target_arch)
73
74    def prepare_and_run_abi_diff_all_archs(self, old_lib, new_lib,
75                                           expected_return_code, flags=[],
76                                           create_old=False, create_new=True):
77        with tempfile.TemporaryDirectory() as tmp:
78            for target_arch in TARGET_ARCHS:
79                old_ref_dump_path = self.get_or_create_ref_dump(old_lib,
80                                                                target_arch,
81                                                                tmp, create_old)
82                new_ref_dump_path = self.get_or_create_ref_dump(new_lib,
83                                                                target_arch,
84                                                                tmp, create_new)
85                self.prepare_and_run_abi_diff(old_ref_dump_path,
86                                              new_ref_dump_path, target_arch,
87                                              expected_return_code, flags)
88
89    def prepare_and_absolute_diff_all_archs(self, old_lib, new_lib,
90                                            flags=[], create=True):
91        with tempfile.TemporaryDirectory() as tmp:
92            for target_arch in TARGET_ARCHS:
93                old_ref_dump_path = self.get_or_create_ref_dump(old_lib,
94                                                                target_arch,
95                                                                tmp, False)
96                new_ref_dump_path = self.get_or_create_ref_dump(new_lib,
97                                                                target_arch,
98                                                                tmp, create)
99                self.assertEqual(
100                    read_output_content(old_ref_dump_path, AOSP_DIR),
101                    read_output_content(new_ref_dump_path, AOSP_DIR))
102
103    def test_func_decl_no_args(self):
104        self.run_and_compare_name_c_cpp('func_decl_no_args.h')
105
106    def test_func_decl_one_arg(self):
107        self.run_and_compare_name_c_cpp('func_decl_one_arg.h')
108
109    def test_func_decl_two_args(self):
110        self.run_and_compare_name_c_cpp('func_decl_two_args.h')
111
112    def test_func_decl_one_arg_ret(self):
113        self.run_and_compare_name_c_cpp('func_decl_one_arg_ret.h')
114
115    def test_example1(self):
116        self.run_and_compare_name_cpp('example1.h')
117        self.run_and_compare_name_cpp('example2.h')
118
119    def test_libc_and_cpp(self):
120        self.prepare_and_run_abi_diff_all_archs("libc_and_cpp", "libc_and_cpp",
121                                                 0)
122
123    def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct(self):
124        self.prepare_and_run_abi_diff_all_archs(
125            "libc_and_cpp", "libc_and_cpp_with_unused_struct", 0)
126
127    def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct_allow(self):
128        self.prepare_and_run_abi_diff_all_archs(
129            "libc_and_cpp", "libc_and_cpp_with_unused_struct", 0,
130            ["-allow-unreferenced-changes"])
131
132    def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct_check_all(self):
133        self.prepare_and_run_abi_diff_all_archs(
134            "libc_and_cpp", "libc_and_cpp_with_unused_struct", 1,
135            ['-check-all-apis'])
136
137    def test_libc_and_cpp_with_unused_struct_and_libc_and_cpp_with_unused_cstruct(self):
138        self.prepare_and_run_abi_diff_all_archs(
139            "libc_and_cpp_with_unused_struct",
140            "libc_and_cpp_with_unused_cstruct", 0,
141            ['-check-all-apis', '-allow-unreferenced-changes'])
142
143    def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct_check_all_advice(
144        self):
145        self.prepare_and_run_abi_diff_all_archs(
146            "libc_and_cpp", "libc_and_cpp_with_unused_struct", 0,
147            ['-check-all-apis', '-advice-only'])
148
149    def test_libgolden_cpp_return_type_diff(self):
150        self.prepare_and_run_abi_diff_all_archs(
151            "libgolden_cpp", "libgolden_cpp_return_type_diff", 8)
152
153    def test_libgolden_cpp_add_odr(self):
154        self.prepare_and_run_abi_diff_all_archs(
155            "libgolden_cpp", "libgolden_cpp_odr", 0,
156            ['-check-all-apis', '-allow-unreferenced-changes'])
157
158    def test_libgolden_cpp_add_function(self):
159        self.prepare_and_run_abi_diff_all_archs(
160            "libgolden_cpp", "libgolden_cpp_add_function", 4)
161
162    def test_libgolden_cpp_add_function_allow_extension(self):
163        self.prepare_and_run_abi_diff_all_archs(
164            "libgolden_cpp", "libgolden_cpp_add_function", 0,
165            ['-allow-extensions'])
166
167    def test_libgolden_cpp_add_function_and_elf_symbol(self):
168        self.prepare_and_run_abi_diff_all_archs(
169            "libgolden_cpp", "libgolden_cpp_add_function_and_unexported_elf",
170            4)
171
172    def test_libgolden_cpp_change_function_access(self):
173        self.prepare_and_run_abi_diff_all_archs(
174            "libgolden_cpp", "libgolden_cpp_change_function_access", 8)
175
176    def test_libgolden_cpp_add_global_variable(self):
177        self.prepare_and_run_abi_diff_all_archs(
178            "libgolden_cpp", "libgolden_cpp_add_global_variable", 4)
179
180    def test_libgolden_cpp_change_global_var_access(self):
181        self.prepare_and_run_abi_diff_all_archs(
182            "libgolden_cpp_add_global_variable",
183            "libgolden_cpp_add_global_variable_private", 8)
184
185    def test_libgolden_cpp_parameter_type_diff(self):
186        self.prepare_and_run_abi_diff_all_archs(
187            "libgolden_cpp", "libgolden_cpp_parameter_type_diff", 8)
188
189    def test_libgolden_cpp_with_vtable_diff(self):
190        self.prepare_and_run_abi_diff_all_archs("libgolden_cpp",
191                                                "libgolden_cpp_vtable_diff", 8)
192
193    def test_libgolden_cpp_member_diff_advice_only(self):
194        self.prepare_and_run_abi_diff_all_archs("libgolden_cpp",
195                                                "libgolden_cpp_member_diff",
196                                                 0, ['-advice-only'])
197
198    def test_libgolden_cpp_member_diff(self):
199        self.prepare_and_run_abi_diff_all_archs("libgolden_cpp",
200                                                "libgolden_cpp_member_diff", 8)
201
202    def test_libgolden_cpp_change_member_access(self):
203        self.prepare_and_run_abi_diff_all_archs(
204            "libgolden_cpp", "libgolden_cpp_change_member_access", 8)
205
206    def test_libgolden_cpp_enum_extended(self):
207        self.prepare_and_run_abi_diff_all_archs("libgolden_cpp",
208                                                "libgolden_cpp_enum_extended",
209                                                4)
210    def test_libgolden_cpp_enum_diff(self):
211        self.prepare_and_run_abi_diff_all_archs("libgolden_cpp",
212                                                "libgolden_cpp_enum_diff", 8)
213
214    def test_libgolden_cpp_fabricated_function_ast_removed_diff(self):
215        self.prepare_and_run_abi_diff_all_archs(
216            "libgolden_cpp_fabricated_function_ast_removed", "libgolden_cpp", 0,
217            [], False)
218
219    def test_libgolden_cpp_member_fake_diff(self):
220        self.prepare_and_run_abi_diff_all_archs(
221            "libgolden_cpp", "libgolden_cpp_member_fake_diff", 0)
222
223    def test_libgolden_cpp_member_integral_type_diff(self):
224        self.prepare_and_run_abi_diff_all_archs(
225            "libgolden_cpp", "libgolden_cpp_member_integral_type_diff", 8)
226
227    def test_libgolden_cpp_member_cv_diff(self):
228        self.prepare_and_run_abi_diff_all_archs(
229            "libgolden_cpp", "libgolden_cpp_member_cv_diff", 8)
230
231    def test_libgolden_cpp_unreferenced_elf_symbol_removed(self):
232        self.prepare_and_run_abi_diff_all_archs(
233            "libgolden_cpp",
234            "libgolden_cpp_unreferenced_elf_symbol_removed", 16)
235
236    def test_libreproducability(self):
237        self.prepare_and_absolute_diff_all_archs("libreproducability",
238                                                 "libreproducability")
239
240    def test_libgolden_cpp_member_name_changed(self):
241        self.prepare_and_run_abi_diff_all_archs(
242            "libgolden_cpp",
243            "libgolden_cpp_member_name_changed", 0)
244
245    def test_libgolden_cpp_member_function_pointer_changed(self):
246        self.prepare_and_run_abi_diff_all_archs(
247            "libgolden_cpp_function_pointer",
248            "libgolden_cpp_function_pointer_parameter_added", 8, [], False,
249            False)
250
251
252
253if __name__ == '__main__':
254    unittest.main()
255