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