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