1#!/usr/bin/env python3 2 3import os 4import shutil 5import stat 6import subprocess 7import sys 8import tempfile 9import unittest 10 11import_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) 12import_path = os.path.abspath(os.path.join(import_path, 'utils')) 13sys.path.insert(1, import_path) 14 15from utils import (run_abi_diff, run_and_read_abi_diff, run_header_abi_dumper, 16 run_header_abi_linker) 17from module import Module 18 19 20SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) 21INPUT_DIR = os.path.join(SCRIPT_DIR, 'input') 22EXPECTED_DIR = os.path.join(SCRIPT_DIR, 'expected') 23EXPORTED_HEADER_DIRS = (INPUT_DIR,) 24REF_DUMP_DIR = os.path.join(SCRIPT_DIR, 'reference_dumps') 25 26 27def make_and_copy_dump(module, dump_dir): 28 dump_dir = os.path.join(dump_dir, module.arch) 29 os.makedirs(dump_dir, exist_ok=True) 30 dump_path = os.path.join(dump_dir, module.get_dump_name()) 31 module.make_dump(dump_path) 32 return dump_path 33 34 35def _read_output_content(dump_path): 36 with open(dump_path, 'r') as f: 37 return f.read() 38 39 40class HeaderCheckerTest(unittest.TestCase): 41 @classmethod 42 def setUpClass(cls): 43 cls.maxDiff = None 44 45 def setUp(self): 46 self.tmp_dir = None 47 48 def tearDown(self): 49 if self.tmp_dir: 50 self.tmp_dir.cleanup() 51 self.tmp_dir = None 52 53 def get_tmp_dir(self): 54 if not self.tmp_dir: 55 self.tmp_dir = tempfile.TemporaryDirectory() 56 return self.tmp_dir.name 57 58 def run_and_compare(self, input_path, expected_path, cflags=[]): 59 with open(expected_path, 'r') as f: 60 expected_output = f.read() 61 with tempfile.NamedTemporaryFile(dir=self.get_tmp_dir(), 62 delete=False) as f: 63 output_path = f.name 64 run_header_abi_dumper(input_path, output_path, cflags, 65 EXPORTED_HEADER_DIRS) 66 actual_output = _read_output_content(output_path) 67 self.assertEqual(actual_output, expected_output) 68 69 def run_and_compare_name(self, name, cflags=[]): 70 input_path = os.path.join(INPUT_DIR, name) 71 expected_path = os.path.join(EXPECTED_DIR, name) 72 self.run_and_compare(input_path, expected_path, cflags) 73 74 def run_and_compare_name_cpp(self, name, cflags=[]): 75 self.run_and_compare_name(name, cflags + ['-x', 'c++', '-std=c++11']) 76 77 def run_and_compare_name_c_cpp(self, name, cflags=[]): 78 self.run_and_compare_name(name, cflags) 79 self.run_and_compare_name_cpp(name, cflags) 80 81 def run_and_compare_abi_diff(self, old_dump, new_dump, lib, arch, 82 expected_return_code, flags=[]): 83 return_code, output = run_and_read_abi_diff( 84 old_dump, new_dump, arch, lib, flags) 85 self.assertEqual(return_code, expected_return_code) 86 return output 87 88 def prepare_and_run_abi_diff(self, old_ref_dump_path, new_ref_dump_path, 89 target_arch, expected_return_code, flags=[]): 90 return self.run_and_compare_abi_diff( 91 old_ref_dump_path, new_ref_dump_path, 'test', target_arch, 92 expected_return_code, flags) 93 94 def get_or_create_dump(self, module, create): 95 if create: 96 return make_and_copy_dump(module, self.get_tmp_dir()) 97 self.assertTrue(module.has_reference_dump, 98 f'Module {module.name} is not configured to generate ' 99 f'reference dump.') 100 return os.path.join(REF_DUMP_DIR, module.arch, module.get_dump_name()) 101 102 def prepare_and_run_abi_diff_all_archs(self, old_lib, new_lib, 103 expected_return_code, flags=[], 104 create_old=False, create_new=True): 105 old_modules = Module.get_test_modules_by_name(old_lib) 106 new_modules = Module.get_test_modules_by_name(new_lib) 107 self.assertEqual(len(old_modules), len(new_modules)) 108 self.assertTrue(len(old_modules)) 109 110 for old_module, new_module in zip(old_modules, new_modules): 111 self.assertEqual(old_module.arch, new_module.arch) 112 old_dump_path = self.get_or_create_dump(old_module, create_old) 113 new_dump_path = self.get_or_create_dump(new_module, create_new) 114 output = self.prepare_and_run_abi_diff( 115 old_dump_path, new_dump_path, new_module.arch, 116 expected_return_code, flags) 117 # Since most test cases are independent of architecture, verifying one 118 # of the reports is sufficient. 119 return output 120 121 def prepare_and_absolute_diff_all_archs(self, old_lib, new_lib): 122 old_modules = Module.get_test_modules_by_name(old_lib) 123 new_modules = Module.get_test_modules_by_name(new_lib) 124 self.assertEqual(len(old_modules), len(new_modules)) 125 126 for old_module, new_module in zip(old_modules, new_modules): 127 self.assertEqual(old_module.arch, new_module.arch) 128 old_dump_path = self.get_or_create_dump(old_module, False) 129 new_dump_path = self.get_or_create_dump(new_module, True) 130 self.assertEqual(_read_output_content(old_dump_path), 131 _read_output_content(new_dump_path)) 132 133 def test_example1_cpp(self): 134 self.run_and_compare_name_cpp('example1.cpp') 135 136 def test_example1_h(self): 137 self.run_and_compare_name_cpp('example1.h') 138 139 def test_example2_h(self): 140 self.run_and_compare_name_cpp('example2.h') 141 142 def test_example3_h(self): 143 self.run_and_compare_name_cpp('example3.h') 144 145 def test_libc_and_cpp(self): 146 self.prepare_and_run_abi_diff_all_archs( 147 "libc_and_cpp", "libc_and_cpp", 0) 148 149 def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct(self): 150 self.prepare_and_run_abi_diff_all_archs( 151 "libc_and_cpp", "libc_and_cpp_with_unused_struct", 0) 152 153 def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct_allow(self): 154 self.prepare_and_run_abi_diff_all_archs( 155 "libc_and_cpp", "libc_and_cpp_with_unused_struct", 0, 156 ["-allow-unreferenced-changes"]) 157 158 def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct_check_all(self): 159 self.prepare_and_run_abi_diff_all_archs( 160 "libc_and_cpp", "libc_and_cpp_with_unused_struct", 1, 161 ["-check-all-apis"]) 162 self.prepare_and_run_abi_diff_all_archs( 163 "libc_and_cpp", "libc_and_cpp_with_unused_struct", 0, 164 ["-check-all-apis", 165 "-ignore-linker-set-key", "_ZTI12UnusedStruct"]) 166 167 def test_libc_and_cpp_with_unused_struct_and_libc_and_cpp_with_unused_cstruct( 168 self): 169 self.prepare_and_run_abi_diff_all_archs( 170 "libc_and_cpp_with_unused_struct", 171 "libc_and_cpp_with_unused_cstruct", 0, 172 ['-check-all-apis', '-allow-unreferenced-changes']) 173 174 def test_libc_and_cpp_and_libc_and_cpp_with_unused_struct_check_all_advice( 175 self): 176 self.prepare_and_run_abi_diff_all_archs( 177 "libc_and_cpp", "libc_and_cpp_with_unused_struct", 0, 178 ['-check-all-apis', '-advice-only']) 179 180 def test_libc_and_cpp_opaque_pointer_diff(self): 181 self.prepare_and_run_abi_diff_all_archs( 182 "libc_and_cpp_with_opaque_ptr_a", 183 "libc_and_cpp_with_opaque_ptr_b", 8, 184 ['-consider-opaque-types-different'], True, True) 185 186 def test_libgolden_cpp_return_type_diff(self): 187 self.prepare_and_run_abi_diff_all_archs( 188 "libgolden_cpp", "libgolden_cpp_return_type_diff", 8) 189 self.prepare_and_run_abi_diff_all_archs( 190 "libgolden_cpp", "libgolden_cpp_return_type_diff", 0, 191 ["-ignore-linker-set-key", "_ZN17HighVolumeSpeaker6ListenEv", 192 "-ignore-linker-set-key", "_ZN16LowVolumeSpeaker6ListenEv"]) 193 194 def test_libgolden_cpp_add_odr(self): 195 self.prepare_and_run_abi_diff_all_archs( 196 "libgolden_cpp", "libgolden_cpp_odr", 0, 197 ['-check-all-apis', '-allow-unreferenced-changes']) 198 199 def test_libgolden_cpp_add_function(self): 200 self.prepare_and_run_abi_diff_all_archs( 201 "libgolden_cpp", "libgolden_cpp_add_function", 6) 202 203 def test_libgolden_cpp_add_function_allow_extension(self): 204 self.prepare_and_run_abi_diff_all_archs( 205 "libgolden_cpp", "libgolden_cpp_add_function", 0, 206 ['-allow-extensions']) 207 208 def test_libgolden_cpp_add_function_and_elf_symbol(self): 209 self.prepare_and_run_abi_diff_all_archs( 210 "libgolden_cpp", "libgolden_cpp_add_function_and_unexported_elf", 211 6) 212 213 def test_libgolden_cpp_fabricated_function_ast_removed_diff(self): 214 self.prepare_and_run_abi_diff_all_archs( 215 "libgolden_cpp_add_function_sybmol_only", 216 "libgolden_cpp_add_function", 0, [], False, False) 217 218 def test_libgolden_cpp_change_function_access(self): 219 self.prepare_and_run_abi_diff_all_archs( 220 "libgolden_cpp", "libgolden_cpp_change_function_access", 8) 221 222 def test_libgolden_cpp_add_global_variable(self): 223 self.prepare_and_run_abi_diff_all_archs( 224 "libgolden_cpp", "libgolden_cpp_add_global_variable", 6) 225 226 def test_libgolden_cpp_change_global_var_access(self): 227 self.prepare_and_run_abi_diff_all_archs( 228 "libgolden_cpp_add_global_variable", 229 "libgolden_cpp_add_global_variable_private", 8) 230 231 def test_libgolden_cpp_parameter_type_diff(self): 232 self.prepare_and_run_abi_diff_all_archs( 233 "libgolden_cpp", "libgolden_cpp_parameter_type_diff", 8) 234 235 def test_libgolden_cpp_with_vtable_diff(self): 236 self.prepare_and_run_abi_diff_all_archs( 237 "libgolden_cpp", "libgolden_cpp_vtable_diff", 8) 238 239 def test_libgolden_cpp_member_diff_advice_only(self): 240 self.prepare_and_run_abi_diff_all_archs( 241 "libgolden_cpp", "libgolden_cpp_member_diff", 0, ['-advice-only']) 242 243 def test_libgolden_cpp_member_diff(self): 244 self.prepare_and_run_abi_diff_all_archs( 245 "libgolden_cpp", "libgolden_cpp_member_diff", 8) 246 self.prepare_and_run_abi_diff_all_archs( 247 "libgolden_cpp", "libgolden_cpp_member_diff", 0, 248 ["-ignore-linker-set-key", "_ZTI16LowVolumeSpeaker"]) 249 250 def test_libgolden_cpp_change_member_access(self): 251 self.prepare_and_run_abi_diff_all_archs( 252 "libgolden_cpp", "libgolden_cpp_change_member_access", 8) 253 254 def test_libgolden_cpp_enum_extended(self): 255 self.prepare_and_run_abi_diff_all_archs( 256 "libgolden_cpp", "libgolden_cpp_enum_extended", 4) 257 258 def test_libgolden_cpp_enum_diff(self): 259 self.prepare_and_run_abi_diff_all_archs( 260 "libgolden_cpp", "libgolden_cpp_enum_diff", 8) 261 self.prepare_and_run_abi_diff_all_archs( 262 "libgolden_cpp", "libgolden_cpp_enum_diff", 0, 263 ["-ignore-linker-set-key", "_ZTIN12SuperSpeaker6VolumeE"]) 264 265 def test_libgolden_cpp_member_fake_diff(self): 266 self.prepare_and_run_abi_diff_all_archs( 267 "libgolden_cpp", "libgolden_cpp_member_fake_diff", 0) 268 269 def test_libgolden_cpp_member_integral_type_diff(self): 270 self.prepare_and_run_abi_diff_all_archs( 271 "libgolden_cpp", "libgolden_cpp_member_integral_type_diff", 8) 272 273 def test_libgolden_cpp_member_cv_diff(self): 274 self.prepare_and_run_abi_diff_all_archs( 275 "libgolden_cpp", "libgolden_cpp_member_cv_diff", 8) 276 277 def test_libgolden_cpp_unreferenced_elf_symbol_removed(self): 278 self.prepare_and_run_abi_diff_all_archs( 279 "libgolden_cpp", "libgolden_cpp_unreferenced_elf_symbol_removed", 280 16) 281 282 def test_libgolden_cpp_unreferenced_elf_symbol_added(self): 283 self.prepare_and_run_abi_diff_all_archs( 284 "libgolden_cpp_unreferenced_elf_symbol_removed", "libgolden_cpp", 285 2, create_old=True, create_new=False) 286 287 def test_libreproducability(self): 288 self.prepare_and_absolute_diff_all_archs( 289 "libreproducability", "libreproducability") 290 291 def test_libgolden_cpp_member_name_changed(self): 292 self.prepare_and_run_abi_diff_all_archs( 293 "libgolden_cpp", "libgolden_cpp_member_name_changed", 0) 294 295 def test_libgolden_cpp_member_function_pointer_changed(self): 296 self.prepare_and_run_abi_diff_all_archs( 297 "libgolden_cpp_function_pointer", 298 "libgolden_cpp_function_pointer_parameter_added", 8, [], 299 True, True) 300 301 def test_libgolden_cpp_internal_struct_access_upgraded(self): 302 self.prepare_and_run_abi_diff_all_archs( 303 "libgolden_cpp_internal_private_struct", 304 "libgolden_cpp_internal_public_struct", 4, [], True, True) 305 306 def test_libgolden_cpp_internal_struct_access_downgraded(self): 307 self.prepare_and_run_abi_diff_all_archs( 308 "libgolden_cpp_internal_public_struct", 309 "libgolden_cpp_internal_private_struct", 8, [], True, True) 310 311 def test_libgolden_cpp_inheritance_type_changed(self): 312 self.prepare_and_run_abi_diff_all_archs( 313 "libgolden_cpp", "libgolden_cpp_inheritance_type_changed", 8, [], 314 True, True) 315 316 def test_libpure_virtual_function(self): 317 self.prepare_and_absolute_diff_all_archs( 318 "libpure_virtual_function", "libpure_virtual_function") 319 320 def test_libc_and_cpp_in_json(self): 321 self.prepare_and_absolute_diff_all_archs( 322 "libgolden_cpp_json", "libgolden_cpp_json") 323 324 def test_libc_and_cpp_in_protobuf_and_json(self): 325 self.prepare_and_run_abi_diff_all_archs( 326 "libgolden_cpp", "libgolden_cpp_json", 0, 327 ["-input-format-old", "ProtobufTextFormat", 328 "-input-format-new", "Json"]) 329 330 def test_opaque_type_self_diff(self): 331 self.prepare_and_run_abi_diff_all_archs( 332 "libopaque_type", "libopaque_type", 0, 333 ["-input-format-old", "Json", "-input-format-new", "Json", 334 "-consider-opaque-types-different"], 335 create_old=False, create_new=False) 336 337 def test_allow_adding_removing_weak_symbols(self): 338 module_old = Module.get_test_modules_by_name("libweak_symbols_old")[0] 339 module_new = Module.get_test_modules_by_name("libweak_symbols_new")[0] 340 lsdump_old = self.get_or_create_dump(module_old, False) 341 lsdump_new = self.get_or_create_dump(module_new, False) 342 343 options = ["-input-format-old", "Json", "-input-format-new", "Json"] 344 345 # If `-allow-adding-removing-weak-symbols` is not specified, removing a 346 # weak symbol must be treated as an incompatible change. 347 self.run_and_compare_abi_diff( 348 lsdump_old, lsdump_new, "libweak_symbols", "arm64", 8, options) 349 350 # If `-allow-adding-removing-weak-symbols` is specified, removing a 351 # weak symbol must be fine and mustn't be a fatal error. 352 self.run_and_compare_abi_diff( 353 lsdump_old, lsdump_new, "libweak_symbols", "arm64", 0, 354 options + ["-allow-adding-removing-weak-symbols"]) 355 356 def test_linker_shared_object_file_and_version_script(self): 357 base_dir = os.path.join( 358 SCRIPT_DIR, 'integration', 'version_script_example') 359 360 cases = [ 361 'libversion_script_example', 362 'libversion_script_example_no_mytag', 363 'libversion_script_example_no_private', 364 'libversion_script_example_api_level', 365 ] 366 367 for module_name in cases: 368 module = Module.get_test_modules_by_name(module_name)[0] 369 example_lsdump_old = self.get_or_create_dump(module, False) 370 example_lsdump_new = self.get_or_create_dump(module, True) 371 self.run_and_compare_abi_diff( 372 example_lsdump_old, example_lsdump_new, 373 module_name, "arm64", 0, 374 ["-input-format-old", "Json", "-input-format-new", "Json"]) 375 376 def test_no_source(self): 377 self.prepare_and_run_abi_diff_all_archs( 378 "libempty", "libempty", 0, 379 ["-input-format-old", "Json", "-input-format-new", "Json"]) 380 381 def test_golden_anonymous_enum(self): 382 self.prepare_and_absolute_diff_all_archs( 383 "libgolden_anonymous_enum", "libgolden_anonymous_enum") 384 385 def test_swap_anonymous_enum(self): 386 self.prepare_and_run_abi_diff_all_archs( 387 "libgolden_anonymous_enum", "libswap_anonymous_enum", 0, 388 ["-input-format-old", "Json", "-input-format-new", "Json", 389 "-check-all-apis"]) 390 391 def test_swap_anonymous_enum_field(self): 392 self.prepare_and_run_abi_diff_all_archs( 393 "libgolden_anonymous_enum", "libswap_anonymous_enum_field", 0, 394 ["-input-format-old", "Json", "-input-format-new", "Json", 395 "-check-all-apis"]) 396 397 def test_anonymous_enum_odr(self): 398 self.prepare_and_absolute_diff_all_archs( 399 "libanonymous_enum_odr", "libanonymous_enum_odr") 400 401 def test_libifunc(self): 402 self.prepare_and_absolute_diff_all_archs( 403 "libifunc", "libifunc") 404 405 def test_merge_multi_definitions(self): 406 self.prepare_and_absolute_diff_all_archs( 407 "libmerge_multi_definitions", "libmerge_multi_definitions") 408 self.prepare_and_run_abi_diff_all_archs( 409 "libmerge_multi_definitions", "libdiff_multi_definitions", 0, 410 flags=["-input-format-new", "Json", "-input-format-old", "Json", 411 "-consider-opaque-types-different"], 412 create_old=False, create_new=False) 413 414 def test_print_resource_dir(self): 415 dumper_path = shutil.which("header-abi-dumper") 416 self.assertIsNotNone(dumper_path) 417 dumper_path = os.path.realpath(dumper_path) 418 common_dir = os.path.dirname(os.path.dirname(dumper_path)) 419 resource_dir = subprocess.check_output( 420 ["header-abi-dumper", "-print-resource-dir"], text=True, 421 stderr=subprocess.DEVNULL).strip() 422 self.assertIn(os.path.dirname(resource_dir), 423 (os.path.join(common_dir, "lib64", "clang"), 424 os.path.join(common_dir, "lib", "clang"))) 425 self.assertRegex(os.path.basename(resource_dir), r"^[\d.]+$") 426 427 def test_struct_extensions(self): 428 output = self.prepare_and_run_abi_diff_all_archs( 429 "libstruct_extensions", "liballowed_struct_extensions", 4, 430 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 431 create_old=False, create_new=False) 432 self.assertEqual(output.count("record_type_extension_diffs"), 6) 433 434 output = self.prepare_and_run_abi_diff_all_archs( 435 "liballowed_struct_extensions", "libstruct_extensions", 8, 436 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 437 create_old=False, create_new=False) 438 self.assertEqual(output.count("record_type_diffs"), 6) 439 440 def test_param_size_diff(self): 441 self.prepare_and_run_abi_diff_all_archs( 442 "libpass_by_value", "libparam_size_diff", 8, 443 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 444 create_old=False, create_new=False) 445 446 def test_return_size_diff(self): 447 self.prepare_and_run_abi_diff_all_archs( 448 "libpass_by_value", "libreturn_size_diff", 8, 449 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 450 create_old=False, create_new=False) 451 452 def test_function_extensions(self): 453 diff = self.prepare_and_run_abi_diff_all_archs( 454 "libfunction_extensions", "liballowed_function_extensions", 4, 455 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 456 create_old=False, create_new=False) 457 self.assertEqual(6, diff.count('function_extension_diffs')) 458 459 diff = self.prepare_and_run_abi_diff_all_archs( 460 "liballowed_function_extensions", "libfunction_extensions", 8, 461 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 462 create_old=False, create_new=False) 463 # Adding and removing __restrict__ at the first level are extensions. 464 self.assertEqual(1, diff.count('function_extension_diffs')) 465 self.assertEqual(5, diff.count('function_diffs')) 466 467 def test_array_diff(self): 468 self.prepare_and_absolute_diff_all_archs("libarray", "libarray") 469 self.prepare_and_absolute_diff_all_archs( 470 "libarray_diff", "libarray_diff") 471 diff = self.prepare_and_run_abi_diff_all_archs( 472 "libarray", "libarray_diff", 8, 473 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 474 create_old=False, create_new=False) 475 476 for type_id in ["StructMember", "Pointer", "DoublePointer"]: 477 self.assertNotIn(f'"{type_id}"', diff, 478 f'"{type_id}" should not be in the diff report.') 479 480 for type_id in ["Struct", "PointerToArray", "PointerTo2DArray", 481 "Reference", "Element"]: 482 self.assertIn(f'"{type_id}"', diff, 483 f'"{type_id}" should be in the diff report.') 484 485 def test_union_diff(self): 486 diff = self.prepare_and_run_abi_diff_all_archs( 487 "libunion", "libunion_diff", 8, 488 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 489 create_old=False, create_new=True) 490 self.assertIn('"ChangeType"', diff) 491 self.assertIn('"ChangeTypeInStruct"', diff) 492 self.assertEqual(2, diff.count("fields_diff")) 493 self.assertNotIn("fields_added", diff) 494 self.assertNotIn("fields_removed", diff) 495 496 def test_enum_diff(self): 497 self.prepare_and_absolute_diff_all_archs("libenum", "libenum") 498 499 def test_io_error(self): 500 cpp_path = os.path.join(self.get_tmp_dir(), "test.cpp") 501 sdump_path = os.path.join(self.get_tmp_dir(), "test.sdump") 502 version_script_path = os.path.join(self.get_tmp_dir(), "map.txt") 503 lsdump_path = os.path.join(self.get_tmp_dir(), "test.lsdump") 504 abidiff_path = os.path.join(self.get_tmp_dir(), "test.abidiff") 505 read_only_path = os.path.join(self.get_tmp_dir(), "read_only.txt") 506 507 with open(cpp_path, "w") as cpp_file: 508 cpp_file.write("void func(int) {}") 509 with open(version_script_path, "w") as version_script_file: 510 pass 511 fd = os.open(read_only_path, flags=(os.O_CREAT | os.O_EXCL), 512 mode=(stat.S_IROTH | stat.S_IRGRP | stat.S_IRUSR)) 513 self.assertGreaterEqual(fd, 0) 514 os.close(fd) 515 516 # Make sure that the commands are valid. 517 dumper_flags = ('-output-format', 'Json') 518 run_header_abi_dumper(cpp_path, sdump_path, flags=dumper_flags) 519 self.assertGreater(os.stat(sdump_path).st_size, 0) 520 linker_flags = ('-input-format', 'Json', 521 '-output-format', 'ProtobufTextFormat') 522 run_header_abi_linker([sdump_path], lsdump_path, version_script_path, 523 "current", "x86_64", linker_flags) 524 self.assertGreater(os.stat(lsdump_path).st_size, 0) 525 diff_flags = ('-input-format-old', 'ProtobufTextFormat', 526 '-input-format-new', 'ProtobufTextFormat') 527 return_code = run_abi_diff(lsdump_path, lsdump_path, abidiff_path, 528 'x86_64', 'libtest', diff_flags) 529 self.assertEqual(return_code, 0) 530 self.assertGreater(os.stat(abidiff_path).st_size, 0) 531 532 # Test with output error. 533 with self.assertRaises(subprocess.CalledProcessError) as assertion: 534 run_header_abi_dumper(cpp_path, read_only_path, flags=dumper_flags) 535 self.assertEqual(assertion.exception.returncode, 1) 536 537 with self.assertRaises(subprocess.CalledProcessError) as assertion: 538 run_header_abi_linker([sdump_path], read_only_path, 539 version_script_path, "current", "x86_64", 540 linker_flags) 541 self.assertEqual(assertion.exception.returncode, 255) 542 543 return_code = run_abi_diff(lsdump_path, lsdump_path, read_only_path, 544 'x86_64', 'libtest', diff_flags) 545 self.assertEqual(return_code, 1) 546 547 def test_bit_field_diff(self): 548 self.prepare_and_absolute_diff_all_archs( 549 "libbit_field", "libbit_field") 550 self.prepare_and_run_abi_diff_all_archs( 551 "libbit_field", "libbit_field_diff", 8, 552 flags=["-input-format-new", "Json", "-input-format-old", "Json"], 553 create_old=False, create_new=True) 554 555 def test_availability(self): 556 self.prepare_and_absolute_diff_all_archs( 557 "libavailability", "libavailability") 558 self.prepare_and_absolute_diff_all_archs( 559 "libavailability_35", "libavailability_35") 560 561 562if __name__ == '__main__': 563 unittest.main() 564