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