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