1from __future__ import absolute_import 2 3# System modules 4from distutils.version import LooseVersion 5from functools import wraps 6import os 7import platform 8import re 9import sys 10import tempfile 11import subprocess 12 13# Third-party modules 14import six 15import unittest2 16 17# LLDB modules 18import lldb 19from . import configuration 20from . import test_categories 21from . import lldbtest_config 22from lldbsuite.test_event.event_builder import EventBuilder 23from lldbsuite.support import funcutils 24from lldbsuite.test import lldbplatform 25from lldbsuite.test import lldbplatformutil 26 27 28class DecorateMode: 29 Skip, Xfail = range(2) 30 31 32# You can use no_match to reverse the test of the conditional that is used to match keyword 33# arguments in the skip / xfail decorators. If oslist=["windows", "linux"] skips windows 34# and linux, oslist=no_match(["windows", "linux"]) skips *unless* windows 35# or linux. 36class no_match: 37 38 def __init__(self, item): 39 self.item = item 40 41 42def _check_expected_version(comparison, expected, actual): 43 def fn_leq(x, y): return x <= y 44 45 def fn_less(x, y): return x < y 46 47 def fn_geq(x, y): return x >= y 48 49 def fn_greater(x, y): return x > y 50 51 def fn_eq(x, y): return x == y 52 53 def fn_neq(x, y): return x != y 54 55 op_lookup = { 56 "==": fn_eq, 57 "=": fn_eq, 58 "!=": fn_neq, 59 "<>": fn_neq, 60 ">": fn_greater, 61 "<": fn_less, 62 ">=": fn_geq, 63 "<=": fn_leq 64 } 65 expected_str = '.'.join([str(x) for x in expected]) 66 actual_str = '.'.join([str(x) for x in actual]) 67 68 return op_lookup[comparison]( 69 LooseVersion(actual_str), 70 LooseVersion(expected_str)) 71 72 73_re_pattern_type = type(re.compile('')) 74def _match_decorator_property(expected, actual): 75 if actual is None or expected is None: 76 return True 77 78 if isinstance(expected, no_match): 79 return not _match_decorator_property(expected.item, actual) 80 elif isinstance(expected, (_re_pattern_type,) + six.string_types): 81 return re.search(expected, actual) is not None 82 elif hasattr(expected, "__iter__"): 83 return any([x is not None and _match_decorator_property(x, actual) 84 for x in expected]) 85 else: 86 return expected == actual 87 88 89def expectedFailure(expected_fn, bugnumber=None): 90 def expectedFailure_impl(func): 91 if isinstance(func, type) and issubclass(func, unittest2.TestCase): 92 raise Exception( 93 "Decorator can only be used to decorate a test method") 94 95 @wraps(func) 96 def wrapper(*args, **kwargs): 97 self = args[0] 98 if funcutils.requires_self(expected_fn): 99 xfail_reason = expected_fn(self) 100 else: 101 xfail_reason = expected_fn() 102 if xfail_reason is not None: 103 if configuration.results_formatter_object is not None: 104 # Mark this test as expected to fail. 105 configuration.results_formatter_object.handle_event( 106 EventBuilder.event_for_mark_test_expected_failure(self)) 107 xfail_func = unittest2.expectedFailure(func) 108 xfail_func(*args, **kwargs) 109 else: 110 func(*args, **kwargs) 111 return wrapper 112 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows) 113 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called 114 # the first way, the first argument will be the actual function because decorators are 115 # weird like that. So this is basically a check that says "which syntax was the original 116 # function decorated with?" 117 if six.callable(bugnumber): 118 return expectedFailure_impl(bugnumber) 119 else: 120 return expectedFailure_impl 121 122 123def skipTestIfFn(expected_fn, bugnumber=None): 124 def skipTestIfFn_impl(func): 125 if isinstance(func, type) and issubclass(func, unittest2.TestCase): 126 raise Exception( 127 "@skipTestIfFn can only be used to decorate a test method") 128 129 @wraps(func) 130 def wrapper(*args, **kwargs): 131 self = args[0] 132 if funcutils.requires_self(expected_fn): 133 reason = expected_fn(self) 134 else: 135 reason = expected_fn() 136 137 if reason is not None: 138 self.skipTest(reason) 139 else: 140 func(*args, **kwargs) 141 return wrapper 142 143 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows) 144 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called 145 # the first way, the first argument will be the actual function because decorators are 146 # weird like that. So this is basically a check that says "how was the 147 # decorator used" 148 if six.callable(bugnumber): 149 return skipTestIfFn_impl(bugnumber) 150 else: 151 return skipTestIfFn_impl 152 153 154def _decorateTest(mode, 155 bugnumber=None, oslist=None, hostoslist=None, 156 compiler=None, compiler_version=None, 157 archs=None, triple=None, 158 debug_info=None, 159 swig_version=None, py_version=None, 160 macos_version=None, 161 remote=None, dwarf_version=None, 162 setting=None): 163 def fn(self): 164 skip_for_os = _match_decorator_property( 165 lldbplatform.translate(oslist), self.getPlatform()) 166 skip_for_hostos = _match_decorator_property( 167 lldbplatform.translate(hostoslist), 168 lldbplatformutil.getHostPlatform()) 169 skip_for_compiler = _match_decorator_property( 170 compiler, self.getCompiler()) and self.expectedCompilerVersion(compiler_version) 171 skip_for_arch = _match_decorator_property( 172 archs, self.getArchitecture()) 173 skip_for_debug_info = _match_decorator_property( 174 debug_info, self.getDebugInfo()) 175 skip_for_triple = _match_decorator_property( 176 triple, lldb.selected_platform.GetTriple()) 177 skip_for_remote = _match_decorator_property( 178 remote, lldb.remote_platform is not None) 179 180 skip_for_swig_version = ( 181 swig_version is None) or ( 182 not hasattr( 183 lldb, 184 'swig_version')) or ( 185 _check_expected_version( 186 swig_version[0], 187 swig_version[1], 188 lldb.swig_version)) 189 skip_for_py_version = ( 190 py_version is None) or _check_expected_version( 191 py_version[0], py_version[1], sys.version_info) 192 skip_for_macos_version = (macos_version is None) or ( 193 (platform.mac_ver()[0] != "") and (_check_expected_version( 194 macos_version[0], 195 macos_version[1], 196 platform.mac_ver()[0]))) 197 skip_for_dwarf_version = (dwarf_version is None) or ( 198 _check_expected_version(dwarf_version[0], dwarf_version[1], 199 self.getDwarfVersion())) 200 skip_for_setting = (setting is None) or ( 201 setting in configuration.settings) 202 203 # For the test to be skipped, all specified (e.g. not None) parameters must be True. 204 # An unspecified parameter means "any", so those are marked skip by default. And we skip 205 # the final test if all conditions are True. 206 conditions = [(oslist, skip_for_os, "target o/s"), 207 (hostoslist, skip_for_hostos, "host o/s"), 208 (compiler, skip_for_compiler, "compiler or version"), 209 (archs, skip_for_arch, "architecture"), 210 (debug_info, skip_for_debug_info, "debug info format"), 211 (triple, skip_for_triple, "target triple"), 212 (swig_version, skip_for_swig_version, "swig version"), 213 (py_version, skip_for_py_version, "python version"), 214 (macos_version, skip_for_macos_version, "macOS version"), 215 (remote, skip_for_remote, "platform locality (remote/local)"), 216 (dwarf_version, skip_for_dwarf_version, "dwarf version"), 217 (setting, skip_for_setting, "setting")] 218 reasons = [] 219 final_skip_result = True 220 for this_condition in conditions: 221 final_skip_result = final_skip_result and this_condition[1] 222 if this_condition[0] is not None and this_condition[1]: 223 reasons.append(this_condition[2]) 224 reason_str = None 225 if final_skip_result: 226 mode_str = { 227 DecorateMode.Skip: "skipping", 228 DecorateMode.Xfail: "xfailing"}[mode] 229 if len(reasons) > 0: 230 reason_str = ",".join(reasons) 231 reason_str = "{} due to the following parameter(s): {}".format( 232 mode_str, reason_str) 233 else: 234 reason_str = "{} unconditionally" 235 if bugnumber is not None and not six.callable(bugnumber): 236 reason_str = reason_str + " [" + str(bugnumber) + "]" 237 return reason_str 238 239 if mode == DecorateMode.Skip: 240 return skipTestIfFn(fn, bugnumber) 241 elif mode == DecorateMode.Xfail: 242 return expectedFailure(fn, bugnumber) 243 else: 244 return None 245 246# provide a function to xfail on defined oslist, compiler version, and archs 247# if none is specified for any argument, that argument won't be checked and thus means for all 248# for example, 249# @expectedFailureAll, xfail for all platform/compiler/arch, 250# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture 251# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386 252 253 254def expectedFailureAll(bugnumber=None, 255 oslist=None, hostoslist=None, 256 compiler=None, compiler_version=None, 257 archs=None, triple=None, 258 debug_info=None, 259 swig_version=None, py_version=None, 260 macos_version=None, 261 remote=None, dwarf_version=None, 262 setting=None): 263 return _decorateTest(DecorateMode.Xfail, 264 bugnumber=bugnumber, 265 oslist=oslist, hostoslist=hostoslist, 266 compiler=compiler, compiler_version=compiler_version, 267 archs=archs, triple=triple, 268 debug_info=debug_info, 269 swig_version=swig_version, py_version=py_version, 270 macos_version=None, 271 remote=remote,dwarf_version=dwarf_version, 272 setting=setting) 273 274 275# provide a function to skip on defined oslist, compiler version, and archs 276# if none is specified for any argument, that argument won't be checked and thus means for all 277# for example, 278# @skipIf, skip for all platform/compiler/arch, 279# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture 280# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386 281def skipIf(bugnumber=None, 282 oslist=None, hostoslist=None, 283 compiler=None, compiler_version=None, 284 archs=None, triple=None, 285 debug_info=None, 286 swig_version=None, py_version=None, 287 macos_version=None, 288 remote=None, dwarf_version=None, 289 setting=None): 290 return _decorateTest(DecorateMode.Skip, 291 bugnumber=bugnumber, 292 oslist=oslist, hostoslist=hostoslist, 293 compiler=compiler, compiler_version=compiler_version, 294 archs=archs, triple=triple, 295 debug_info=debug_info, 296 swig_version=swig_version, py_version=py_version, 297 macos_version=macos_version, 298 remote=remote, dwarf_version=dwarf_version, 299 setting=setting) 300 301 302def _skip_for_android(reason, api_levels, archs): 303 def impl(obj): 304 result = lldbplatformutil.match_android_device( 305 obj.getArchitecture(), valid_archs=archs, valid_api_levels=api_levels) 306 return reason if result else None 307 return impl 308 309 310def add_test_categories(cat): 311 """Add test categories to a TestCase method""" 312 cat = test_categories.validate(cat, True) 313 314 def impl(func): 315 if isinstance(func, type) and issubclass(func, unittest2.TestCase): 316 raise Exception( 317 "@add_test_categories can only be used to decorate a test method") 318 try: 319 if hasattr(func, "categories"): 320 cat.extend(func.categories) 321 setattr(func, "categories", cat) 322 except AttributeError: 323 raise Exception('Cannot assign categories to inline tests.') 324 325 return func 326 327 return impl 328 329 330def benchmarks_test(func): 331 """Decorate the item as a benchmarks test.""" 332 def should_skip_benchmarks_test(): 333 return "benchmarks test" 334 335 # Mark this function as such to separate them from the regular tests. 336 result = skipTestIfFn(should_skip_benchmarks_test)(func) 337 result.__benchmarks_test__ = True 338 return result 339 340 341def no_debug_info_test(func): 342 """Decorate the item as a test what don't use any debug info. If this annotation is specified 343 then the test runner won't generate a separate test for each debug info format. """ 344 if isinstance(func, type) and issubclass(func, unittest2.TestCase): 345 raise Exception( 346 "@no_debug_info_test can only be used to decorate a test method") 347 348 @wraps(func) 349 def wrapper(self, *args, **kwargs): 350 return func(self, *args, **kwargs) 351 352 # Mark this function as such to separate them from the regular tests. 353 wrapper.__no_debug_info_test__ = True 354 return wrapper 355 356def apple_simulator_test(platform): 357 """ 358 Decorate the test as a test requiring a simulator for a specific platform. 359 360 Consider that a simulator is available if you have the corresponding SDK installed. 361 The SDK identifiers for simulators are iphonesimulator, appletvsimulator, watchsimulator 362 """ 363 def should_skip_simulator_test(): 364 if lldbplatformutil.getHostPlatform() != 'darwin': 365 return "simulator tests are run only on darwin hosts" 366 try: 367 DEVNULL = open(os.devnull, 'w') 368 output = subprocess.check_output(["xcodebuild", "-showsdks"], stderr=DEVNULL).decode("utf-8") 369 if re.search('%ssimulator' % platform, output): 370 return None 371 else: 372 return "%s simulator is not supported on this system." % platform 373 except subprocess.CalledProcessError: 374 return "Simulators are unsupported on this system (xcodebuild failed)" 375 376 return skipTestIfFn(should_skip_simulator_test) 377 378 379def debugserver_test(func): 380 """Decorate the item as a debugserver test.""" 381 def should_skip_debugserver_test(): 382 return "debugserver tests" if configuration.dont_do_debugserver_test else None 383 return skipTestIfFn(should_skip_debugserver_test)(func) 384 385 386def llgs_test(func): 387 """Decorate the item as a lldb-server test.""" 388 def should_skip_llgs_tests(): 389 return "llgs tests" if configuration.dont_do_llgs_test else None 390 return skipTestIfFn(should_skip_llgs_tests)(func) 391 392 393def not_remote_testsuite_ready(func): 394 """Decorate the item as a test which is not ready yet for remote testsuite.""" 395 def is_remote(): 396 return "Not ready for remote testsuite" if lldb.remote_platform else None 397 return skipTestIfFn(is_remote)(func) 398 399 400def expectedFailureOS( 401 oslist, 402 bugnumber=None, 403 compilers=None, 404 debug_info=None, 405 archs=None): 406 return expectedFailureAll( 407 oslist=oslist, 408 bugnumber=bugnumber, 409 compiler=compilers, 410 archs=archs, 411 debug_info=debug_info) 412 413 414def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None, archs=None): 415 # For legacy reasons, we support both "darwin" and "macosx" as OS X 416 # triples. 417 return expectedFailureOS( 418 lldbplatform.darwin_all, 419 bugnumber, 420 compilers, 421 debug_info=debug_info, 422 archs=archs) 423 424 425def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None): 426 """ Mark a test as xfail for Android. 427 428 Arguments: 429 bugnumber - The LLVM pr associated with the problem. 430 api_levels - A sequence of numbers specifying the Android API levels 431 for which a test is expected to fail. None means all API level. 432 arch - A sequence of architecture names specifying the architectures 433 for which a test is expected to fail. None means all architectures. 434 """ 435 return expectedFailure( 436 _skip_for_android( 437 "xfailing on android", 438 api_levels, 439 archs), 440 bugnumber) 441 442 443def expectedFailureNetBSD(bugnumber=None): 444 return expectedFailureOS( 445 ['netbsd'], 446 bugnumber) 447 448# Flakey tests get two chances to run. If they fail the first time round, the result formatter 449# makes sure it is run one more time. 450 451 452def expectedFlakey(expected_fn, bugnumber=None): 453 def expectedFailure_impl(func): 454 @wraps(func) 455 def wrapper(*args, **kwargs): 456 self = args[0] 457 if expected_fn(self): 458 # Send event marking test as explicitly eligible for rerunning. 459 if configuration.results_formatter_object is not None: 460 # Mark this test as rerunnable. 461 configuration.results_formatter_object.handle_event( 462 EventBuilder.event_for_mark_test_rerun_eligible(self)) 463 func(*args, **kwargs) 464 return wrapper 465 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows) 466 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called 467 # the first way, the first argument will be the actual function because decorators are 468 # weird like that. So this is basically a check that says "which syntax was the original 469 # function decorated with?" 470 if six.callable(bugnumber): 471 return expectedFailure_impl(bugnumber) 472 else: 473 return expectedFailure_impl 474 475 476def expectedFlakeyOS(oslist, bugnumber=None, compilers=None): 477 def fn(self): 478 return (self.getPlatform() in oslist and 479 self.expectedCompiler(compilers)) 480 return expectedFlakey(fn, bugnumber) 481 482 483def expectedFlakeyDarwin(bugnumber=None, compilers=None): 484 # For legacy reasons, we support both "darwin" and "macosx" as OS X 485 # triples. 486 return expectedFlakeyOS( 487 lldbplatformutil.getDarwinOSTriples(), 488 bugnumber, 489 compilers) 490 491 492def expectedFlakeyFreeBSD(bugnumber=None, compilers=None): 493 return expectedFlakeyOS(['freebsd'], bugnumber, compilers) 494 495 496def expectedFlakeyLinux(bugnumber=None, compilers=None): 497 return expectedFlakeyOS(['linux'], bugnumber, compilers) 498 499 500def expectedFlakeyNetBSD(bugnumber=None, compilers=None): 501 return expectedFlakeyOS(['netbsd'], bugnumber, compilers) 502 503 504def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None): 505 return expectedFlakey( 506 _skip_for_android( 507 "flakey on android", 508 api_levels, 509 archs), 510 bugnumber) 511 512def skipIfOutOfTreeDebugserver(func): 513 """Decorate the item to skip tests if using an out-of-tree debugserver.""" 514 def is_out_of_tree_debugserver(): 515 return "out-of-tree debugserver" if lldbtest_config.out_of_tree_debugserver else None 516 return skipTestIfFn(is_out_of_tree_debugserver)(func) 517 518def skipIfRemote(func): 519 """Decorate the item to skip tests if testing remotely.""" 520 def is_remote(): 521 return "skip on remote platform" if lldb.remote_platform else None 522 return skipTestIfFn(is_remote)(func) 523 524 525def skipIfNoSBHeaders(func): 526 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers.""" 527 def are_sb_headers_missing(): 528 if lldb.remote_platform: 529 return "skip because SBHeaders tests make no sense remotely" 530 531 if lldbplatformutil.getHostPlatform() == 'darwin': 532 header = os.path.join( 533 os.environ["LLDB_LIB_DIR"], 534 'LLDB.framework', 535 'Versions', 536 'Current', 537 'Headers', 538 'LLDB.h') 539 if os.path.exists(header): 540 return None 541 542 header = os.path.join( 543 os.environ["LLDB_SRC"], 544 "include", 545 "lldb", 546 "API", 547 "LLDB.h") 548 if not os.path.exists(header): 549 return "skip because LLDB.h header not found" 550 return None 551 552 return skipTestIfFn(are_sb_headers_missing)(func) 553 554 555def skipIfRosetta(func, bugnumber=None): 556 """Skip a test when running the testsuite on macOS under the Rosetta translation layer.""" 557 def is_running_rosetta(self): 558 if not lldbplatformutil.getPlatform() in ['darwin', 'macosx']: 559 return False 560 return platform.uname()[5] == "arm" and self.getArchitecture() == "x86_64" 561 return skipTestIfFn(is_running_rosetta, bugnumber)(func) 562 563def skipIfiOSSimulator(func): 564 """Decorate the item to skip tests that should be skipped on the iOS Simulator.""" 565 def is_ios_simulator(): 566 return "skip on the iOS Simulator" if configuration.lldb_platform_name == 'ios-simulator' else None 567 return skipTestIfFn(is_ios_simulator)(func) 568 569def skipIfiOS(func): 570 return skipIfPlatform(["ios"])(func) 571 572def skipIftvOS(func): 573 return skipIfPlatform(["tvos"])(func) 574 575def skipIfwatchOS(func): 576 return skipIfPlatform(["watchos"])(func) 577 578def skipIfbridgeOS(func): 579 return skipIfPlatform(["bridgeos"])(func) 580 581def skipIfDarwinEmbedded(func): 582 """Decorate the item to skip tests that should be skipped on Darwin armv7/arm64 targets.""" 583 return skipIfPlatform( 584 lldbplatform.translate( 585 lldbplatform.darwin_embedded))(func) 586 587def skipIfFreeBSD(func): 588 """Decorate the item to skip tests that should be skipped on FreeBSD.""" 589 return skipIfPlatform(["freebsd"])(func) 590 591 592def skipIfNetBSD(func): 593 """Decorate the item to skip tests that should be skipped on NetBSD.""" 594 return skipIfPlatform(["netbsd"])(func) 595 596 597def skipIfDarwin(func): 598 """Decorate the item to skip tests that should be skipped on Darwin.""" 599 return skipIfPlatform( 600 lldbplatform.translate( 601 lldbplatform.darwin_all))(func) 602 603 604def skipIfLinux(func): 605 """Decorate the item to skip tests that should be skipped on Linux.""" 606 return skipIfPlatform(["linux"])(func) 607 608 609def skipIfWindows(func): 610 """Decorate the item to skip tests that should be skipped on Windows.""" 611 return skipIfPlatform(["windows"])(func) 612 613def skipUnlessWindows(func): 614 """Decorate the item to skip tests that should be skipped on any non-Windows platform.""" 615 return skipUnlessPlatform(["windows"])(func) 616 617 618def skipUnlessDarwin(func): 619 """Decorate the item to skip tests that should be skipped on any non Darwin platform.""" 620 return skipUnlessPlatform(lldbplatformutil.getDarwinOSTriples())(func) 621 622def skipUnlessTargetAndroid(func): 623 return unittest2.skipUnless(lldbplatformutil.target_is_android(), 624 "requires target to be Android")(func) 625 626 627def skipIfHostIncompatibleWithRemote(func): 628 """Decorate the item to skip tests if binaries built on this host are incompatible.""" 629 630 def is_host_incompatible_with_remote(self): 631 host_arch = self.getLldbArchitecture() 632 host_platform = lldbplatformutil.getHostPlatform() 633 target_arch = self.getArchitecture() 634 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform() 635 if not (target_arch == 'x86_64' and host_arch == 636 'i386') and host_arch != target_arch: 637 return "skipping because target %s is not compatible with host architecture %s" % ( 638 target_arch, host_arch) 639 if target_platform != host_platform: 640 return "skipping because target is %s but host is %s" % ( 641 target_platform, host_platform) 642 if lldbplatformutil.match_android_device(target_arch): 643 return "skipping because target is android" 644 return None 645 return skipTestIfFn(is_host_incompatible_with_remote)(func) 646 647 648def skipIfPlatform(oslist): 649 """Decorate the item to skip tests if running on one of the listed platforms.""" 650 # This decorator cannot be ported to `skipIf` yet because it is used on entire 651 # classes, which `skipIf` explicitly forbids. 652 return unittest2.skipIf(lldbplatformutil.getPlatform() in oslist, 653 "skip on %s" % (", ".join(oslist))) 654 655 656def skipUnlessPlatform(oslist): 657 """Decorate the item to skip tests unless running on one of the listed platforms.""" 658 # This decorator cannot be ported to `skipIf` yet because it is used on entire 659 # classes, which `skipIf` explicitly forbids. 660 return unittest2.skipUnless(lldbplatformutil.getPlatform() in oslist, 661 "requires one of %s" % (", ".join(oslist))) 662 663def skipUnlessArch(arch): 664 """Decorate the item to skip tests unless running on the specified architecture.""" 665 666 def arch_doesnt_match(self): 667 target_arch = self.getArchitecture() 668 if arch != target_arch: 669 return "Test only runs on " + arch + ", but target arch is " + target_arch 670 return None 671 672 return skipTestIfFn(arch_doesnt_match) 673 674def skipIfTargetAndroid(bugnumber=None, api_levels=None, archs=None): 675 """Decorator to skip tests when the target is Android. 676 677 Arguments: 678 api_levels - The API levels for which the test should be skipped. If 679 it is None, then the test will be skipped for all API levels. 680 arch - A sequence of architecture names specifying the architectures 681 for which a test is skipped. None means all architectures. 682 """ 683 return skipTestIfFn( 684 _skip_for_android( 685 "skipping for android", 686 api_levels, 687 archs), 688 bugnumber) 689 690def skipUnlessSupportedTypeAttribute(attr): 691 """Decorate the item to skip test unless Clang supports type __attribute__(attr).""" 692 def compiler_doesnt_support_struct_attribute(self): 693 compiler_path = self.getCompiler() 694 f = tempfile.NamedTemporaryFile() 695 cmd = [self.getCompiler(), "-x", "c++", "-c", "-o", f.name, "-"] 696 p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) 697 stdout, stderr = p.communicate('struct __attribute__((%s)) Test {};'%attr) 698 if attr in stderr: 699 return "Compiler does not support attribute %s"%(attr) 700 return None 701 return skipTestIfFn(compiler_doesnt_support_struct_attribute) 702 703def skipUnlessHasCallSiteInfo(func): 704 """Decorate the function to skip testing unless call site info from clang is available.""" 705 706 def is_compiler_clang_with_call_site_info(self): 707 compiler_path = self.getCompiler() 708 compiler = os.path.basename(compiler_path) 709 if not compiler.startswith("clang"): 710 return "Test requires clang as compiler" 711 712 f = tempfile.NamedTemporaryFile() 713 cmd = "echo 'int main() {}' | " \ 714 "%s -g -glldb -O1 -S -emit-llvm -x c -o %s -" % (compiler_path, f.name) 715 if os.popen(cmd).close() is not None: 716 return "Compiler can't compile with call site info enabled" 717 718 with open(f.name, 'r') as ir_output_file: 719 buf = ir_output_file.read() 720 721 if 'DIFlagAllCallsDescribed' not in buf: 722 return "Compiler did not introduce DIFlagAllCallsDescribed IR flag" 723 724 return None 725 return skipTestIfFn(is_compiler_clang_with_call_site_info)(func) 726 727def skipUnlessThreadSanitizer(func): 728 """Decorate the item to skip test unless Clang -fsanitize=thread is supported.""" 729 730 def is_compiler_clang_with_thread_sanitizer(self): 731 if is_running_under_asan(): 732 return "Thread sanitizer tests are disabled when runing under ASAN" 733 734 compiler_path = self.getCompiler() 735 compiler = os.path.basename(compiler_path) 736 if not compiler.startswith("clang"): 737 return "Test requires clang as compiler" 738 if lldbplatformutil.getPlatform() == 'windows': 739 return "TSAN tests not compatible with 'windows'" 740 # rdar://28659145 - TSAN tests don't look like they're supported on i386 741 if self.getArchitecture() == 'i386' and platform.system() == 'Darwin': 742 return "TSAN tests not compatible with i386 targets" 743 f = tempfile.NamedTemporaryFile() 744 cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name) 745 if os.popen(cmd).close() is not None: 746 return None # The compiler cannot compile at all, let's *not* skip the test 747 cmd = "echo 'int main() {}' | %s -fsanitize=thread -x c -o %s -" % (compiler_path, f.name) 748 if os.popen(cmd).close() is not None: 749 return "Compiler cannot compile with -fsanitize=thread" 750 return None 751 return skipTestIfFn(is_compiler_clang_with_thread_sanitizer)(func) 752 753def skipUnlessUndefinedBehaviorSanitizer(func): 754 """Decorate the item to skip test unless -fsanitize=undefined is supported.""" 755 756 def is_compiler_clang_with_ubsan(self): 757 if is_running_under_asan(): 758 return "Undefined behavior sanitizer tests are disabled when runing under ASAN" 759 760 # Write out a temp file which exhibits UB. 761 inputf = tempfile.NamedTemporaryFile(suffix='.c', mode='w') 762 inputf.write('int main() { int x = 0; return x / x; }\n') 763 inputf.flush() 764 765 # We need to write out the object into a named temp file for inspection. 766 outputf = tempfile.NamedTemporaryFile() 767 768 # Try to compile with ubsan turned on. 769 cmd = '%s -fsanitize=undefined %s -o %s' % (self.getCompiler(), inputf.name, outputf.name) 770 if os.popen(cmd).close() is not None: 771 return "Compiler cannot compile with -fsanitize=undefined" 772 773 # Check that we actually see ubsan instrumentation in the binary. 774 cmd = 'nm %s' % outputf.name 775 with os.popen(cmd) as nm_output: 776 if '___ubsan_handle_divrem_overflow' not in nm_output.read(): 777 return "Division by zero instrumentation is missing" 778 779 # Find the ubsan dylib. 780 # FIXME: This check should go away once compiler-rt gains support for __ubsan_on_report. 781 cmd = '%s -fsanitize=undefined -x c - -o - -### 2>&1' % self.getCompiler() 782 with os.popen(cmd) as cc_output: 783 driver_jobs = cc_output.read() 784 m = re.search(r'"([^"]+libclang_rt.ubsan_osx_dynamic.dylib)"', driver_jobs) 785 if not m: 786 return "Could not find the ubsan dylib used by the driver" 787 ubsan_dylib = m.group(1) 788 789 # Check that the ubsan dylib has special monitor hooks. 790 cmd = 'nm -gU %s' % ubsan_dylib 791 with os.popen(cmd) as nm_output: 792 syms = nm_output.read() 793 if '___ubsan_on_report' not in syms: 794 return "Missing ___ubsan_on_report" 795 if '___ubsan_get_current_report_data' not in syms: 796 return "Missing ___ubsan_get_current_report_data" 797 798 # OK, this dylib + compiler works for us. 799 return None 800 801 return skipTestIfFn(is_compiler_clang_with_ubsan)(func) 802 803def is_running_under_asan(): 804 if ('ASAN_OPTIONS' in os.environ): 805 return "ASAN unsupported" 806 return None 807 808def skipUnlessAddressSanitizer(func): 809 """Decorate the item to skip test unless Clang -fsanitize=thread is supported.""" 810 811 def is_compiler_with_address_sanitizer(self): 812 # Also don't run tests that use address sanitizer inside an 813 # address-sanitized LLDB. The tests don't support that 814 # configuration. 815 if is_running_under_asan(): 816 return "Address sanitizer tests are disabled when runing under ASAN" 817 818 compiler_path = self.getCompiler() 819 compiler = os.path.basename(compiler_path) 820 f = tempfile.NamedTemporaryFile() 821 if lldbplatformutil.getPlatform() == 'windows': 822 return "ASAN tests not compatible with 'windows'" 823 cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name) 824 if os.popen(cmd).close() is not None: 825 return None # The compiler cannot compile at all, let's *not* skip the test 826 cmd = "echo 'int main() {}' | %s -fsanitize=address -x c -o %s -" % (compiler_path, f.name) 827 if os.popen(cmd).close() is not None: 828 return "Compiler cannot compile with -fsanitize=address" 829 return None 830 return skipTestIfFn(is_compiler_with_address_sanitizer)(func) 831 832def skipIfAsan(func): 833 """Skip this test if the environment is set up to run LLDB *itself* under ASAN.""" 834 return skipTestIfFn(is_running_under_asan)(func) 835 836def _get_bool_config_skip_if_decorator(key): 837 config = lldb.SBDebugger.GetBuildConfiguration() 838 value_node = config.GetValueForKey(key) 839 fail_value = True # More likely to notice if something goes wrong 840 have = value_node.GetValueForKey("value").GetBooleanValue(fail_value) 841 return unittest2.skipIf(not have, "requires " + key) 842 843def skipIfCursesSupportMissing(func): 844 return _get_bool_config_skip_if_decorator("curses")(func) 845 846def skipIfXmlSupportMissing(func): 847 return _get_bool_config_skip_if_decorator("xml")(func) 848 849def skipIfEditlineSupportMissing(func): 850 return _get_bool_config_skip_if_decorator("editline")(func) 851 852def skipIfLLVMTargetMissing(target): 853 config = lldb.SBDebugger.GetBuildConfiguration() 854 targets = config.GetValueForKey("targets").GetValueForKey("value") 855 found = False 856 for i in range(targets.GetSize()): 857 if targets.GetItemAtIndex(i).GetStringValue(99) == target: 858 found = True 859 break 860 861 return unittest2.skipIf(not found, "requires " + target) 862 863# Call sysctl on darwin to see if a specified hardware feature is available on this machine. 864def skipUnlessFeature(feature): 865 def is_feature_enabled(self): 866 if platform.system() == 'Darwin': 867 try: 868 DEVNULL = open(os.devnull, 'w') 869 output = subprocess.check_output(["/usr/sbin/sysctl", feature], stderr=DEVNULL).decode("utf-8") 870 # If 'feature: 1' was output, then this feature is available and 871 # the test should not be skipped. 872 if re.match('%s: 1\s*' % feature, output): 873 return None 874 else: 875 return "%s is not supported on this system." % feature 876 except subprocess.CalledProcessError: 877 return "%s is not supported on this system." % feature 878 return skipTestIfFn(is_feature_enabled) 879 880def skipIfReproducer(func): 881 """Skip this test if the environment is set up to run LLDB with reproducers.""" 882 def is_reproducer(): 883 if configuration.capture_path or configuration.replay_path: 884 return "reproducers unsupported" 885 return None 886 return skipTestIfFn(is_reproducer)(func) 887