1# System modules 2from functools import wraps 3from packaging import version 4import ctypes 5import locale 6import os 7import platform 8import re 9import sys 10import tempfile 11import subprocess 12 13# Third-party modules 14import unittest 15 16# LLDB modules 17import lldb 18from . import configuration 19from . import test_categories 20from . import lldbtest_config 21from lldbsuite.support import funcutils 22from lldbsuite.test import lldbplatform 23from lldbsuite.test import lldbplatformutil 24 25 26class DecorateMode: 27 Skip, Xfail = range(2) 28 29 30# You can use no_match to reverse the test of the conditional that is used to match keyword 31# arguments in the skip / xfail decorators. If oslist=["windows", "linux"] skips windows 32# and linux, oslist=no_match(["windows", "linux"]) skips *unless* windows 33# or linux. 34class no_match: 35 def __init__(self, item): 36 self.item = item 37 38 39def _check_expected_version(comparison, expected, actual): 40 def fn_leq(x, y): 41 return x <= y 42 43 def fn_less(x, y): 44 return x < y 45 46 def fn_geq(x, y): 47 return x >= y 48 49 def fn_greater(x, y): 50 return x > y 51 52 def fn_eq(x, y): 53 return x == y 54 55 def fn_neq(x, y): 56 return x != y 57 58 op_lookup = { 59 "==": fn_eq, 60 "=": fn_eq, 61 "!=": fn_neq, 62 "<>": fn_neq, 63 ">": fn_greater, 64 "<": fn_less, 65 ">=": fn_geq, 66 "<=": fn_leq, 67 } 68 69 return op_lookup[comparison](version.parse(actual), version.parse(expected)) 70 71 72def _match_decorator_property(expected, actual): 73 if expected is None: 74 return True 75 76 if actual is None: 77 return False 78 79 if isinstance(expected, no_match): 80 return not _match_decorator_property(expected.item, actual) 81 82 # Python 3.6 doesn't declare a `re.Pattern` type, get the dynamic type. 83 pattern_type = type(re.compile("")) 84 if isinstance(expected, (pattern_type, str)): 85 return re.search(expected, actual) is not None 86 87 if hasattr(expected, "__iter__"): 88 return any( 89 [x is not None and _match_decorator_property(x, actual) for x in expected] 90 ) 91 92 return expected == actual 93 94 95def _compiler_supports( 96 compiler, flag, source="int main() {}", output_file=tempfile.NamedTemporaryFile() 97): 98 """Test whether the compiler supports the given flag.""" 99 if platform.system() == "Darwin": 100 compiler = "xcrun " + compiler 101 try: 102 cmd = "echo '%s' | %s %s -x c -o %s -" % ( 103 source, 104 compiler, 105 flag, 106 output_file.name, 107 ) 108 subprocess.check_call(cmd, shell=True) 109 except subprocess.CalledProcessError: 110 return False 111 return True 112 113 114def expectedFailureIf(condition, bugnumber=None): 115 def expectedFailure_impl(func): 116 if isinstance(func, type) and issubclass(func, unittest.TestCase): 117 raise Exception("Decorator can only be used to decorate a test method") 118 119 if condition: 120 return unittest.expectedFailure(func) 121 return func 122 123 if callable(bugnumber): 124 return expectedFailure_impl(bugnumber) 125 else: 126 return expectedFailure_impl 127 128 129def skipTestIfFn(expected_fn, bugnumber=None): 130 def skipTestIfFn_impl(func): 131 if isinstance(func, type) and issubclass(func, unittest.TestCase): 132 reason = expected_fn() 133 # The return value is the reason (or None if we don't skip), so 134 # reason is used for both args. 135 return unittest.skipIf(condition=reason, reason=reason)(func) 136 137 @wraps(func) 138 def wrapper(*args, **kwargs): 139 self = args[0] 140 if funcutils.requires_self(expected_fn): 141 reason = expected_fn(self) 142 else: 143 reason = expected_fn() 144 145 if reason is not None: 146 self.skipTest(reason) 147 else: 148 return func(*args, **kwargs) 149 150 return wrapper 151 152 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows) 153 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called 154 # the first way, the first argument will be the actual function because decorators are 155 # weird like that. So this is basically a check that says "how was the 156 # decorator used" 157 if callable(bugnumber): 158 return skipTestIfFn_impl(bugnumber) 159 else: 160 return skipTestIfFn_impl 161 162 163def _xfailForDebugInfo(expected_fn, bugnumber=None): 164 def expectedFailure_impl(func): 165 if isinstance(func, type) and issubclass(func, unittest.TestCase): 166 raise Exception("Decorator can only be used to decorate a test method") 167 168 func.__xfail_for_debug_info_cat_fn__ = expected_fn 169 return func 170 171 if callable(bugnumber): 172 return expectedFailure_impl(bugnumber) 173 else: 174 return expectedFailure_impl 175 176 177def _skipForDebugInfo(expected_fn, bugnumber=None): 178 def skipImpl(func): 179 if isinstance(func, type) and issubclass(func, unittest.TestCase): 180 raise Exception("Decorator can only be used to decorate a test method") 181 182 func.__skip_for_debug_info_cat_fn__ = expected_fn 183 return func 184 185 if callable(bugnumber): 186 return skipImpl(bugnumber) 187 else: 188 return skipImpl 189 190 191def _decorateTest( 192 mode, 193 bugnumber=None, 194 oslist=None, 195 hostoslist=None, 196 compiler=None, 197 compiler_version=None, 198 archs=None, 199 triple=None, 200 debug_info=None, 201 swig_version=None, 202 py_version=None, 203 macos_version=None, 204 remote=None, 205 dwarf_version=None, 206 setting=None, 207 asan=None, 208): 209 def fn(actual_debug_info=None): 210 skip_for_os = _match_decorator_property( 211 lldbplatform.translate(oslist), lldbplatformutil.getPlatform() 212 ) 213 skip_for_hostos = _match_decorator_property( 214 lldbplatform.translate(hostoslist), lldbplatformutil.getHostPlatform() 215 ) 216 skip_for_compiler = _match_decorator_property( 217 compiler, lldbplatformutil.getCompiler() 218 ) and lldbplatformutil.expectedCompilerVersion(compiler_version) 219 skip_for_arch = _match_decorator_property( 220 archs, lldbplatformutil.getArchitecture() 221 ) 222 skip_for_debug_info = _match_decorator_property(debug_info, actual_debug_info) 223 skip_for_triple = _match_decorator_property( 224 triple, lldb.selected_platform.GetTriple() 225 ) 226 skip_for_remote = _match_decorator_property( 227 remote, lldb.remote_platform is not None 228 ) 229 230 skip_for_swig_version = ( 231 (swig_version is None) 232 or (not hasattr(lldb, "swig_version")) 233 or ( 234 _check_expected_version( 235 swig_version[0], swig_version[1], lldb.swig_version 236 ) 237 ) 238 ) 239 skip_for_py_version = (py_version is None) or _check_expected_version( 240 py_version[0], 241 py_version[1], 242 "{}.{}".format(sys.version_info.major, sys.version_info.minor), 243 ) 244 skip_for_macos_version = (macos_version is None) or ( 245 (platform.mac_ver()[0] != "") 246 and ( 247 _check_expected_version( 248 macos_version[0], macos_version[1], platform.mac_ver()[0] 249 ) 250 ) 251 ) 252 skip_for_dwarf_version = (dwarf_version is None) or ( 253 _check_expected_version( 254 dwarf_version[0], dwarf_version[1], lldbplatformutil.getDwarfVersion() 255 ) 256 ) 257 skip_for_setting = (setting is None) or (setting in configuration.settings) 258 skip_for_asan = (asan is None) or is_running_under_asan() 259 260 # For the test to be skipped, all specified (e.g. not None) parameters must be True. 261 # An unspecified parameter means "any", so those are marked skip by default. And we skip 262 # the final test if all conditions are True. 263 conditions = [ 264 (oslist, skip_for_os, "target o/s"), 265 (hostoslist, skip_for_hostos, "host o/s"), 266 (compiler, skip_for_compiler, "compiler or version"), 267 (archs, skip_for_arch, "architecture"), 268 (debug_info, skip_for_debug_info, "debug info format"), 269 (triple, skip_for_triple, "target triple"), 270 (swig_version, skip_for_swig_version, "swig version"), 271 (py_version, skip_for_py_version, "python version"), 272 (macos_version, skip_for_macos_version, "macOS version"), 273 (remote, skip_for_remote, "platform locality (remote/local)"), 274 (dwarf_version, skip_for_dwarf_version, "dwarf version"), 275 (setting, skip_for_setting, "setting"), 276 (asan, skip_for_asan, "running under asan"), 277 ] 278 reasons = [] 279 final_skip_result = True 280 for this_condition in conditions: 281 final_skip_result = final_skip_result and this_condition[1] 282 if this_condition[0] is not None and this_condition[1]: 283 reasons.append(this_condition[2]) 284 reason_str = None 285 if final_skip_result: 286 mode_str = {DecorateMode.Skip: "skipping", DecorateMode.Xfail: "xfailing"}[ 287 mode 288 ] 289 if len(reasons) > 0: 290 reason_str = ",".join(reasons) 291 reason_str = "{} due to the following parameter(s): {}".format( 292 mode_str, reason_str 293 ) 294 else: 295 reason_str = "{} unconditionally".format(mode_str) 296 if bugnumber is not None and not callable(bugnumber): 297 reason_str = reason_str + " [" + str(bugnumber) + "]" 298 return reason_str 299 300 if mode == DecorateMode.Skip: 301 if debug_info: 302 return _skipForDebugInfo(fn, bugnumber) 303 return skipTestIfFn(fn, bugnumber) 304 elif mode == DecorateMode.Xfail: 305 if debug_info: 306 return _xfailForDebugInfo(fn, bugnumber) 307 return expectedFailureIf(fn(), bugnumber) 308 else: 309 return None 310 311 312# provide a function to xfail on defined oslist, compiler version, and archs 313# if none is specified for any argument, that argument won't be checked and thus means for all 314# for example, 315# @expectedFailureAll, xfail for all platform/compiler/arch, 316# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture 317# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386 318 319 320def expectedFailureAll( 321 bugnumber=None, 322 oslist=None, 323 hostoslist=None, 324 compiler=None, 325 compiler_version=None, 326 archs=None, 327 triple=None, 328 debug_info=None, 329 swig_version=None, 330 py_version=None, 331 macos_version=None, 332 remote=None, 333 dwarf_version=None, 334 setting=None, 335 asan=None, 336): 337 return _decorateTest( 338 DecorateMode.Xfail, 339 bugnumber=bugnumber, 340 oslist=oslist, 341 hostoslist=hostoslist, 342 compiler=compiler, 343 compiler_version=compiler_version, 344 archs=archs, 345 triple=triple, 346 debug_info=debug_info, 347 swig_version=swig_version, 348 py_version=py_version, 349 macos_version=macos_version, 350 remote=remote, 351 dwarf_version=dwarf_version, 352 setting=setting, 353 asan=asan, 354 ) 355 356 357# provide a function to skip on defined oslist, compiler version, and archs 358# if none is specified for any argument, that argument won't be checked and thus means for all 359# for example, 360# @skipIf, skip for all platform/compiler/arch, 361# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture 362# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386 (all conditions must be true) 363def skipIf( 364 bugnumber=None, 365 oslist=None, 366 hostoslist=None, 367 compiler=None, 368 compiler_version=None, 369 archs=None, 370 triple=None, 371 debug_info=None, 372 swig_version=None, 373 py_version=None, 374 macos_version=None, 375 remote=None, 376 dwarf_version=None, 377 setting=None, 378 asan=None, 379): 380 return _decorateTest( 381 DecorateMode.Skip, 382 bugnumber=bugnumber, 383 oslist=oslist, 384 hostoslist=hostoslist, 385 compiler=compiler, 386 compiler_version=compiler_version, 387 archs=archs, 388 triple=triple, 389 debug_info=debug_info, 390 swig_version=swig_version, 391 py_version=py_version, 392 macos_version=macos_version, 393 remote=remote, 394 dwarf_version=dwarf_version, 395 setting=setting, 396 asan=asan, 397 ) 398 399 400def _skip_fn_for_android(reason, api_levels, archs): 401 def impl(): 402 result = lldbplatformutil.match_android_device( 403 lldbplatformutil.getArchitecture(), 404 valid_archs=archs, 405 valid_api_levels=api_levels, 406 ) 407 return reason if result else None 408 409 return impl 410 411 412def add_test_categories(cat): 413 """Add test categories to a TestCase method""" 414 cat = test_categories.validate(cat, True) 415 416 def impl(func): 417 try: 418 if hasattr(func, "categories"): 419 cat.extend(func.categories) 420 setattr(func, "categories", cat) 421 except AttributeError: 422 raise Exception("Cannot assign categories to inline tests.") 423 424 return func 425 426 return impl 427 428 429def no_debug_info_test(func): 430 """Decorate the item as a test what don't use any debug info. If this annotation is specified 431 then the test runner won't generate a separate test for each debug info format.""" 432 if isinstance(func, type) and issubclass(func, unittest.TestCase): 433 raise Exception( 434 "@no_debug_info_test can only be used to decorate a test method" 435 ) 436 437 @wraps(func) 438 def wrapper(self, *args, **kwargs): 439 return func(self, *args, **kwargs) 440 441 # Mark this function as such to separate them from the regular tests. 442 wrapper.__no_debug_info_test__ = True 443 return wrapper 444 445 446def apple_simulator_test(platform): 447 """ 448 Decorate the test as a test requiring a simulator for a specific platform. 449 450 Consider that a simulator is available if you have the corresponding SDK installed. 451 The SDK identifiers for simulators are iphonesimulator, appletvsimulator, watchsimulator 452 """ 453 454 def should_skip_simulator_test(): 455 if lldbplatformutil.getHostPlatform() not in ["darwin", "macosx"]: 456 return "simulator tests are run only on darwin hosts." 457 try: 458 output = subprocess.check_output( 459 ["xcodebuild", "-showsdks"], stderr=subprocess.DEVNULL 460 ).decode("utf-8") 461 if re.search("%ssimulator" % platform, output): 462 return None 463 else: 464 return "%s simulator is not supported on this system." % platform 465 except subprocess.CalledProcessError: 466 return "Simulators are unsupported on this system (xcodebuild failed)" 467 468 return skipTestIfFn(should_skip_simulator_test) 469 470 471def debugserver_test(func): 472 """Decorate the item as a debugserver test.""" 473 return add_test_categories(["debugserver"])(func) 474 475 476def llgs_test(func): 477 """Decorate the item as a lldb-server test.""" 478 return add_test_categories(["llgs"])(func) 479 480 481def expectedFailureOS( 482 oslist, bugnumber=None, compilers=None, debug_info=None, archs=None 483): 484 return expectedFailureAll( 485 oslist=oslist, 486 bugnumber=bugnumber, 487 compiler=compilers, 488 archs=archs, 489 debug_info=debug_info, 490 ) 491 492 493def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None, archs=None): 494 # For legacy reasons, we support both "darwin" and "macosx" as OS X 495 # triples. 496 return expectedFailureOS( 497 lldbplatform.darwin_all, 498 bugnumber, 499 compilers, 500 debug_info=debug_info, 501 archs=archs, 502 ) 503 504 505def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None): 506 """Mark a test as xfail for Android. 507 508 Arguments: 509 bugnumber - The LLVM pr associated with the problem. 510 api_levels - A sequence of numbers specifying the Android API levels 511 for which a test is expected to fail. None means all API level. 512 arch - A sequence of architecture names specifying the architectures 513 for which a test is expected to fail. None means all architectures. 514 """ 515 return expectedFailureIf( 516 _skip_fn_for_android("xfailing on android", api_levels, archs)(), bugnumber 517 ) 518 519 520def expectedFailureNetBSD(bugnumber=None): 521 return expectedFailureOS(["netbsd"], bugnumber) 522 523 524def expectedFailureWindows(bugnumber=None): 525 return expectedFailureOS(["windows"], bugnumber) 526 527 528# TODO: This decorator does not do anything. Remove it. 529def expectedFlakey(expected_fn, bugnumber=None): 530 def expectedFailure_impl(func): 531 @wraps(func) 532 def wrapper(*args, **kwargs): 533 func(*args, **kwargs) 534 535 return wrapper 536 537 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows) 538 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called 539 # the first way, the first argument will be the actual function because decorators are 540 # weird like that. So this is basically a check that says "which syntax was the original 541 # function decorated with?" 542 if callable(bugnumber): 543 return expectedFailure_impl(bugnumber) 544 else: 545 return expectedFailure_impl 546 547 548def expectedFlakeyOS(oslist, bugnumber=None, compilers=None): 549 def fn(self): 550 return ( 551 lldbplatformutil.getPlatform() in oslist 552 and lldbplatformutil.expectedCompiler(compilers) 553 ) 554 555 return expectedFlakey(fn, bugnumber) 556 557 558def expectedFlakeyDarwin(bugnumber=None, compilers=None): 559 # For legacy reasons, we support both "darwin" and "macosx" as OS X 560 # triples. 561 return expectedFlakeyOS(lldbplatformutil.getDarwinOSTriples(), bugnumber, compilers) 562 563 564def expectedFlakeyFreeBSD(bugnumber=None, compilers=None): 565 return expectedFlakeyOS(["freebsd"], bugnumber, compilers) 566 567 568def expectedFlakeyLinux(bugnumber=None, compilers=None): 569 return expectedFlakeyOS(["linux"], bugnumber, compilers) 570 571 572def expectedFlakeyNetBSD(bugnumber=None, compilers=None): 573 return expectedFlakeyOS(["netbsd"], bugnumber, compilers) 574 575 576def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None): 577 return expectedFlakey( 578 _skip_fn_for_android("flakey on android", api_levels, archs), bugnumber 579 ) 580 581 582def skipIfOutOfTreeDebugserver(func): 583 """Decorate the item to skip tests if using an out-of-tree debugserver.""" 584 585 def is_out_of_tree_debugserver(): 586 return ( 587 "out-of-tree debugserver" 588 if lldbtest_config.out_of_tree_debugserver 589 else None 590 ) 591 592 return skipTestIfFn(is_out_of_tree_debugserver)(func) 593 594 595def skipIfRemote(func): 596 """Decorate the item to skip tests if testing remotely.""" 597 return unittest.skipIf(lldb.remote_platform, "skip on remote platform")(func) 598 599 600def skipIfNoSBHeaders(func): 601 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers.""" 602 603 def are_sb_headers_missing(): 604 if lldb.remote_platform: 605 return "skip because SBHeaders tests make no sense remotely" 606 607 if ( 608 lldbplatformutil.getHostPlatform() == "darwin" 609 and configuration.lldb_framework_path 610 ): 611 header = os.path.join( 612 configuration.lldb_framework_path, 613 "Versions", 614 "Current", 615 "Headers", 616 "LLDB.h", 617 ) 618 if os.path.exists(header): 619 return None 620 621 header = os.path.join( 622 os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h" 623 ) 624 if not os.path.exists(header): 625 return "skip because LLDB.h header not found" 626 return None 627 628 return skipTestIfFn(are_sb_headers_missing)(func) 629 630 631def skipIfRosetta(bugnumber): 632 """Skip a test when running the testsuite on macOS under the Rosetta translation layer.""" 633 634 def is_running_rosetta(): 635 if lldbplatformutil.getPlatform() in ["darwin", "macosx"]: 636 if (platform.uname()[5] == "arm") and ( 637 lldbplatformutil.getArchitecture() == "x86_64" 638 ): 639 return "skipped under Rosetta" 640 return None 641 642 return skipTestIfFn(is_running_rosetta) 643 644 645def skipIfiOSSimulator(func): 646 """Decorate the item to skip tests that should be skipped on the iOS Simulator.""" 647 648 def is_ios_simulator(): 649 return ( 650 "skip on the iOS Simulator" 651 if configuration.lldb_platform_name == "ios-simulator" 652 else None 653 ) 654 655 return skipTestIfFn(is_ios_simulator)(func) 656 657 658def skipIfiOS(func): 659 return skipIfPlatform(lldbplatform.translate(lldbplatform.ios))(func) 660 661 662def skipIftvOS(func): 663 return skipIfPlatform(lldbplatform.translate(lldbplatform.tvos))(func) 664 665 666def skipIfwatchOS(func): 667 return skipIfPlatform(lldbplatform.translate(lldbplatform.watchos))(func) 668 669 670def skipIfbridgeOS(func): 671 return skipIfPlatform(lldbplatform.translate(lldbplatform.bridgeos))(func) 672 673 674def skipIfDarwinEmbedded(func): 675 """Decorate the item to skip tests that should be skipped on Darwin armv7/arm64 targets.""" 676 return skipIfPlatform(lldbplatform.translate(lldbplatform.darwin_embedded))(func) 677 678 679def skipIfDarwinSimulator(func): 680 """Decorate the item to skip tests that should be skipped on Darwin simulator targets.""" 681 return skipIfPlatform(lldbplatform.translate(lldbplatform.darwin_simulator))(func) 682 683 684def skipIfFreeBSD(func): 685 """Decorate the item to skip tests that should be skipped on FreeBSD.""" 686 return skipIfPlatform(["freebsd"])(func) 687 688 689def skipIfNetBSD(func): 690 """Decorate the item to skip tests that should be skipped on NetBSD.""" 691 return skipIfPlatform(["netbsd"])(func) 692 693 694def skipIfDarwin(func): 695 """Decorate the item to skip tests that should be skipped on Darwin.""" 696 return skipIfPlatform(lldbplatform.translate(lldbplatform.darwin_all))(func) 697 698 699def skipIfLinux(func): 700 """Decorate the item to skip tests that should be skipped on Linux.""" 701 return skipIfPlatform(["linux"])(func) 702 703 704def skipIfWindows(func): 705 """Decorate the item to skip tests that should be skipped on Windows.""" 706 return skipIfPlatform(["windows"])(func) 707 708 709def skipIfWindowsAndNonEnglish(func): 710 """Decorate the item to skip tests that should be skipped on non-English locales on Windows.""" 711 712 def is_Windows_NonEnglish(): 713 if sys.platform != "win32": 714 return None 715 kernel = ctypes.windll.kernel32 716 if locale.windows_locale[kernel.GetUserDefaultUILanguage()] == "en_US": 717 return None 718 return "skipping non-English Windows locale" 719 720 return skipTestIfFn(is_Windows_NonEnglish)(func) 721 722 723def skipUnlessWindows(func): 724 """Decorate the item to skip tests that should be skipped on any non-Windows platform.""" 725 return skipUnlessPlatform(["windows"])(func) 726 727 728def skipUnlessDarwin(func): 729 """Decorate the item to skip tests that should be skipped on any non Darwin platform.""" 730 return skipUnlessPlatform(lldbplatformutil.getDarwinOSTriples())(func) 731 732 733def skipUnlessTargetAndroid(func): 734 return unittest.skipUnless( 735 lldbplatformutil.target_is_android(), "requires target to be Android" 736 )(func) 737 738 739def skipIfHostIncompatibleWithTarget(func): 740 """Decorate the item to skip tests when the host and target are incompatible.""" 741 742 def is_host_incompatible_with_remote(): 743 host_arch = lldbplatformutil.getLLDBArchitecture() 744 host_platform = lldbplatformutil.getHostPlatform() 745 target_arch = lldbplatformutil.getArchitecture() 746 target_platform = lldbplatformutil.getPlatform() 747 if ( 748 not (target_arch == "x86_64" and host_arch == "i386") 749 and host_arch != target_arch 750 ): 751 return ( 752 "skipping because target %s is not compatible with host architecture %s" 753 % (target_arch, host_arch) 754 ) 755 if target_platform != host_platform: 756 return "skipping because target is %s but host is %s" % ( 757 target_platform, 758 host_platform, 759 ) 760 if lldbplatformutil.match_android_device(target_arch): 761 return "skipping because target is android" 762 return None 763 764 return skipTestIfFn(is_host_incompatible_with_remote)(func) 765 766 767def skipIfPlatform(oslist): 768 """Decorate the item to skip tests if running on one of the listed platforms.""" 769 # This decorator cannot be ported to `skipIf` yet because it is used on entire 770 # classes, which `skipIf` explicitly forbids. 771 return unittest.skipIf( 772 lldbplatformutil.getPlatform() in oslist, "skip on %s" % (", ".join(oslist)) 773 ) 774 775 776def skipUnlessPlatform(oslist): 777 """Decorate the item to skip tests unless running on one of the listed platforms.""" 778 # This decorator cannot be ported to `skipIf` yet because it is used on entire 779 # classes, which `skipIf` explicitly forbids. 780 return unittest.skipUnless( 781 lldbplatformutil.getPlatform() in oslist, 782 "requires one of %s" % (", ".join(oslist)), 783 ) 784 785 786def skipUnlessArch(arch): 787 """Decorate the item to skip tests unless running on the specified architecture.""" 788 789 def arch_doesnt_match(): 790 target_arch = lldbplatformutil.getArchitecture() 791 if arch != target_arch: 792 return "Test only runs on " + arch + ", but target arch is " + target_arch 793 return None 794 795 return skipTestIfFn(arch_doesnt_match) 796 797 798def skipIfTargetAndroid(bugnumber=None, api_levels=None, archs=None): 799 """Decorator to skip tests when the target is Android. 800 801 Arguments: 802 api_levels - The API levels for which the test should be skipped. If 803 it is None, then the test will be skipped for all API levels. 804 arch - A sequence of architecture names specifying the architectures 805 for which a test is skipped. None means all architectures. 806 """ 807 return skipTestIfFn( 808 _skip_fn_for_android("skipping for android", api_levels, archs), bugnumber 809 ) 810 811 812def skipUnlessAppleSilicon(func): 813 """Decorate the item to skip tests unless running on Apple Silicon.""" 814 815 def not_apple_silicon(): 816 if platform.system() != "Darwin" or lldbplatformutil.getArchitecture() not in [ 817 "arm64", 818 "arm64e", 819 ]: 820 return "Test only runs on Apple Silicon" 821 return None 822 823 return skipTestIfFn(not_apple_silicon)(func) 824 825 826def skipUnlessSupportedTypeAttribute(attr): 827 """Decorate the item to skip test unless Clang supports type __attribute__(attr).""" 828 829 def compiler_doesnt_support_struct_attribute(): 830 compiler_path = lldbplatformutil.getCompiler() 831 f = tempfile.NamedTemporaryFile() 832 cmd = [lldbplatformutil.getCompiler(), "-x", "c++", "-c", "-o", f.name, "-"] 833 p = subprocess.Popen( 834 cmd, 835 stdin=subprocess.PIPE, 836 stdout=subprocess.PIPE, 837 stderr=subprocess.PIPE, 838 universal_newlines=True, 839 ) 840 stdout, stderr = p.communicate("struct __attribute__((%s)) Test {};" % attr) 841 if attr in stderr: 842 return "Compiler does not support attribute %s" % (attr) 843 return None 844 845 return skipTestIfFn(compiler_doesnt_support_struct_attribute) 846 847 848def skipUnlessHasCallSiteInfo(func): 849 """Decorate the function to skip testing unless call site info from clang is available.""" 850 851 def is_compiler_clang_with_call_site_info(): 852 compiler_path = lldbplatformutil.getCompiler() 853 compiler = os.path.basename(compiler_path) 854 if not compiler.startswith("clang"): 855 return "Test requires clang as compiler" 856 857 f = tempfile.NamedTemporaryFile() 858 cmd = ( 859 "echo 'int main() {}' | " 860 "%s -g -glldb -O1 -S -emit-llvm -x c -o %s -" % (compiler_path, f.name) 861 ) 862 if os.popen(cmd).close() is not None: 863 return "Compiler can't compile with call site info enabled" 864 865 with open(f.name, "r") as ir_output_file: 866 buf = ir_output_file.read() 867 868 if "DIFlagAllCallsDescribed" not in buf: 869 return "Compiler did not introduce DIFlagAllCallsDescribed IR flag" 870 871 return None 872 873 return skipTestIfFn(is_compiler_clang_with_call_site_info)(func) 874 875 876def skipUnlessThreadSanitizer(func): 877 """Decorate the item to skip test unless Clang -fsanitize=thread is supported.""" 878 879 def is_compiler_clang_with_thread_sanitizer(): 880 if is_running_under_asan(): 881 return "Thread sanitizer tests are disabled when runing under ASAN" 882 883 compiler_path = lldbplatformutil.getCompiler() 884 compiler = os.path.basename(compiler_path) 885 if not compiler.startswith("clang"): 886 return "Test requires clang as compiler" 887 if lldbplatformutil.getPlatform() == "windows": 888 return "TSAN tests not compatible with 'windows'" 889 # rdar://28659145 - TSAN tests don't look like they're supported on i386 890 if ( 891 lldbplatformutil.getArchitecture() == "i386" 892 and platform.system() == "Darwin" 893 ): 894 return "TSAN tests not compatible with i386 targets" 895 if not _compiler_supports(compiler_path, "-fsanitize=thread"): 896 return "Compiler cannot compile with -fsanitize=thread" 897 return None 898 899 return skipTestIfFn(is_compiler_clang_with_thread_sanitizer)(func) 900 901 902def skipUnlessUndefinedBehaviorSanitizer(func): 903 """Decorate the item to skip test unless -fsanitize=undefined is supported.""" 904 905 def is_compiler_clang_with_ubsan(): 906 if is_running_under_asan(): 907 return ( 908 "Undefined behavior sanitizer tests are disabled when runing under ASAN" 909 ) 910 911 # We need to write out the object into a named temp file for inspection. 912 outputf = tempfile.NamedTemporaryFile() 913 914 # Try to compile with ubsan turned on. 915 if not _compiler_supports( 916 lldbplatformutil.getCompiler(), 917 "-fsanitize=undefined", 918 "int main() { int x = 0; return x / x; }", 919 outputf, 920 ): 921 return "Compiler cannot compile with -fsanitize=undefined" 922 923 # Check that we actually see ubsan instrumentation in the binary. 924 cmd = "nm %s" % outputf.name 925 with os.popen(cmd) as nm_output: 926 if "___ubsan_handle_divrem_overflow" not in nm_output.read(): 927 return "Division by zero instrumentation is missing" 928 929 # Find the ubsan dylib. 930 # FIXME: This check should go away once compiler-rt gains support for __ubsan_on_report. 931 cmd = ( 932 "%s -fsanitize=undefined -x c - -o - -### 2>&1" 933 % lldbplatformutil.getCompiler() 934 ) 935 with os.popen(cmd) as cc_output: 936 driver_jobs = cc_output.read() 937 m = re.search(r'"([^"]+libclang_rt.ubsan_osx_dynamic.dylib)"', driver_jobs) 938 if not m: 939 return "Could not find the ubsan dylib used by the driver" 940 ubsan_dylib = m.group(1) 941 942 # Check that the ubsan dylib has special monitor hooks. 943 cmd = "nm -gU %s" % ubsan_dylib 944 with os.popen(cmd) as nm_output: 945 syms = nm_output.read() 946 if "___ubsan_on_report" not in syms: 947 return "Missing ___ubsan_on_report" 948 if "___ubsan_get_current_report_data" not in syms: 949 return "Missing ___ubsan_get_current_report_data" 950 951 # OK, this dylib + compiler works for us. 952 return None 953 954 return skipTestIfFn(is_compiler_clang_with_ubsan)(func) 955 956 957def is_running_under_asan(): 958 if "ASAN_OPTIONS" in os.environ: 959 return "ASAN unsupported" 960 return None 961 962 963def skipUnlessAddressSanitizer(func): 964 """Decorate the item to skip test unless Clang -fsanitize=thread is supported.""" 965 966 def is_compiler_with_address_sanitizer(): 967 # Also don't run tests that use address sanitizer inside an 968 # address-sanitized LLDB. The tests don't support that 969 # configuration. 970 if is_running_under_asan(): 971 return "Address sanitizer tests are disabled when runing under ASAN" 972 973 if lldbplatformutil.getPlatform() == "windows": 974 return "ASAN tests not compatible with 'windows'" 975 if not _compiler_supports(lldbplatformutil.getCompiler(), "-fsanitize=address"): 976 return "Compiler cannot compile with -fsanitize=address" 977 return None 978 979 return skipTestIfFn(is_compiler_with_address_sanitizer)(func) 980 981 982def skipIfAsan(func): 983 """Skip this test if the environment is set up to run LLDB *itself* under ASAN.""" 984 return skipTestIfFn(is_running_under_asan)(func) 985 986 987def skipUnlessAArch64MTELinuxCompiler(func): 988 """Decorate the item to skip test unless MTE is supported by the test compiler.""" 989 990 def is_toolchain_with_mte(): 991 compiler_path = lldbplatformutil.getCompiler() 992 f = tempfile.NamedTemporaryFile(delete=False) 993 if lldbplatformutil.getPlatform() == "windows": 994 return "MTE tests are not compatible with 'windows'" 995 996 # Note hostos may be Windows. 997 f.close() 998 999 cmd = f"{compiler_path} -x c -o {f.name} -" 1000 if ( 1001 subprocess.run(cmd, shell=True, input="int main() {}".encode()).returncode 1002 != 0 1003 ): 1004 os.remove(f.name) 1005 # Cannot compile at all, don't skip the test 1006 # so that we report the broken compiler normally. 1007 return None 1008 1009 # We need the Linux headers and ACLE MTE intrinsics 1010 test_src = """ 1011 #include <asm/hwcap.h> 1012 #include <arm_acle.h> 1013 #ifndef HWCAP2_MTE 1014 #error 1015 #endif 1016 int main() { 1017 void* ptr = __arm_mte_create_random_tag((void*)(0), 0); 1018 }""" 1019 cmd = f"{compiler_path} -march=armv8.5-a+memtag -x c -o {f.name} -" 1020 res = subprocess.run(cmd, shell=True, input=test_src.encode()) 1021 os.remove(f.name) 1022 if res.returncode != 0: 1023 return "Toolchain does not support MTE" 1024 return None 1025 1026 return skipTestIfFn(is_toolchain_with_mte)(func) 1027 1028 1029def _get_bool_config(key, fail_value=True): 1030 """ 1031 Returns the current LLDB's build config value. 1032 :param key The key to lookup in LLDB's build configuration. 1033 :param fail_value The error value to return when the key can't be found. 1034 Defaults to true so that if an unknown key is lookup up we rather 1035 enable more tests (that then fail) than silently skipping them. 1036 """ 1037 config = lldb.SBDebugger.GetBuildConfiguration() 1038 value_node = config.GetValueForKey(key) 1039 return value_node.GetValueForKey("value").GetBooleanValue(fail_value) 1040 1041 1042def _get_bool_config_skip_if_decorator(key): 1043 have = _get_bool_config(key) 1044 return unittest.skipIf(not have, "requires " + key) 1045 1046 1047def skipIfCurlSupportMissing(func): 1048 return _get_bool_config_skip_if_decorator("curl")(func) 1049 1050 1051def skipIfCursesSupportMissing(func): 1052 return _get_bool_config_skip_if_decorator("curses")(func) 1053 1054 1055def skipIfXmlSupportMissing(func): 1056 return _get_bool_config_skip_if_decorator("xml")(func) 1057 1058 1059def skipIfEditlineSupportMissing(func): 1060 return _get_bool_config_skip_if_decorator("editline")(func) 1061 1062 1063def skipIfEditlineWideCharSupportMissing(func): 1064 return _get_bool_config_skip_if_decorator("editline_wchar")(func) 1065 1066 1067def skipIfFBSDVMCoreSupportMissing(func): 1068 return _get_bool_config_skip_if_decorator("fbsdvmcore")(func) 1069 1070 1071def skipIfLLVMTargetMissing(target): 1072 config = lldb.SBDebugger.GetBuildConfiguration() 1073 targets = config.GetValueForKey("targets").GetValueForKey("value") 1074 found = False 1075 for i in range(targets.GetSize()): 1076 if targets.GetItemAtIndex(i).GetStringValue(99) == target: 1077 found = True 1078 break 1079 1080 return unittest.skipIf(not found, "requires " + target) 1081 1082 1083# Call sysctl on darwin to see if a specified hardware feature is available on this machine. 1084def skipUnlessFeature(feature): 1085 def is_feature_enabled(): 1086 if platform.system() == "Darwin": 1087 try: 1088 output = subprocess.check_output( 1089 ["/usr/sbin/sysctl", feature], stderr=subprocess.DEVNULL 1090 ).decode("utf-8") 1091 # If 'feature: 1' was output, then this feature is available and 1092 # the test should not be skipped. 1093 if re.match(r"%s: 1\s*" % feature, output): 1094 return None 1095 else: 1096 return "%s is not supported on this system." % feature 1097 except subprocess.CalledProcessError: 1098 return "%s is not supported on this system." % feature 1099 1100 return skipTestIfFn(is_feature_enabled) 1101