2 from distutils
.version
import LooseVersion
3 from functools
import wraps
18 from . import configuration
19 from . import test_categories
20 from . import lldbtest_config
21 from lldbsuite
.support
import funcutils
22 from lldbsuite
.test
import lldbplatform
23 from lldbsuite
.test
import lldbplatformutil
27 Skip
, Xfail
= range(2)
30 # You can use no_match to reverse the test of the conditional that is used to match keyword
31 # arguments in the skip / xfail decorators. If oslist=["windows", "linux"] skips windows
32 # and linux, oslist=no_match(["windows", "linux"]) skips *unless* windows
35 def __init__(self
, item
):
39 def _check_expected_version(comparison
, expected
, actual
):
68 expected_str
= ".".join([str(x
) for x
in expected
])
69 actual_str
= ".".join([str(x
) for x
in actual
])
71 return op_lookup
[comparison
](LooseVersion(actual_str
), LooseVersion(expected_str
))
74 def _match_decorator_property(expected
, actual
):
81 if isinstance(expected
, no_match
):
82 return not _match_decorator_property(expected
.item
, actual
)
84 # Python 3.6 doesn't declare a `re.Pattern` type, get the dynamic type.
85 pattern_type
= type(re
.compile(""))
86 if isinstance(expected
, (pattern_type
, str)):
87 return re
.search(expected
, actual
) is not None
89 if hasattr(expected
, "__iter__"):
91 [x
is not None and _match_decorator_property(x
, actual
) for x
in expected
]
94 return expected
== actual
97 def _compiler_supports(
98 compiler
, flag
, source
="int main() {}", output_file
=tempfile
.NamedTemporaryFile()
100 """Test whether the compiler supports the given flag."""
101 if platform
.system() == "Darwin":
102 compiler
= "xcrun " + compiler
104 cmd
= "echo '%s' | %s %s -x c -o %s -" % (
110 subprocess
.check_call(cmd
, shell
=True)
111 except subprocess
.CalledProcessError
:
116 def expectedFailure(func
):
117 return unittest2
.expectedFailure(func
)
120 def expectedFailureIfFn(expected_fn
, bugnumber
=None):
121 def expectedFailure_impl(func
):
122 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
123 raise Exception("Decorator can only be used to decorate a test method")
126 def wrapper(*args
, **kwargs
):
127 xfail_reason
= expected_fn(*args
, **kwargs
)
128 if xfail_reason
is not None:
129 xfail_func
= unittest2
.expectedFailure(func
)
130 xfail_func(*args
, **kwargs
)
132 func(*args
, **kwargs
)
136 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
137 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
138 # the first way, the first argument will be the actual function because decorators are
139 # weird like that. So this is basically a check that says "which syntax was the original
140 # function decorated with?"
141 if callable(bugnumber
):
142 return expectedFailure_impl(bugnumber
)
144 return expectedFailure_impl
147 def skipTestIfFn(expected_fn
, bugnumber
=None):
148 def skipTestIfFn_impl(func
):
149 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
150 reason
= expected_fn()
151 # The return value is the reason (or None if we don't skip), so
152 # reason is used for both args.
153 return unittest2
.skipIf(condition
=reason
, reason
=reason
)(func
)
156 def wrapper(*args
, **kwargs
):
158 if funcutils
.requires_self(expected_fn
):
159 reason
= expected_fn(self
)
161 reason
= expected_fn()
163 if reason
is not None:
164 self
.skipTest(reason
)
166 return func(*args
, **kwargs
)
170 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
171 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
172 # the first way, the first argument will be the actual function because decorators are
173 # weird like that. So this is basically a check that says "how was the
175 if callable(bugnumber
):
176 return skipTestIfFn_impl(bugnumber
)
178 return skipTestIfFn_impl
187 compiler_version
=None,
199 skip_for_os
= _match_decorator_property(
200 lldbplatform
.translate(oslist
), self
.getPlatform()
202 skip_for_hostos
= _match_decorator_property(
203 lldbplatform
.translate(hostoslist
), lldbplatformutil
.getHostPlatform()
205 skip_for_compiler
= _match_decorator_property(
206 compiler
, self
.getCompiler()
207 ) and self
.expectedCompilerVersion(compiler_version
)
208 skip_for_arch
= _match_decorator_property(archs
, self
.getArchitecture())
209 skip_for_debug_info
= _match_decorator_property(debug_info
, self
.getDebugInfo())
210 skip_for_triple
= _match_decorator_property(
211 triple
, lldb
.selected_platform
.GetTriple()
213 skip_for_remote
= _match_decorator_property(
214 remote
, lldb
.remote_platform
is not None
217 skip_for_swig_version
= (
218 (swig_version
is None)
219 or (not hasattr(lldb
, "swig_version"))
221 _check_expected_version(
222 swig_version
[0], swig_version
[1], lldb
.swig_version
226 skip_for_py_version
= (py_version
is None) or _check_expected_version(
227 py_version
[0], py_version
[1], sys
.version_info
229 skip_for_macos_version
= (macos_version
is None) or (
230 (platform
.mac_ver()[0] != "")
232 _check_expected_version(
233 macos_version
[0], macos_version
[1], platform
.mac_ver()[0]
237 skip_for_dwarf_version
= (dwarf_version
is None) or (
238 _check_expected_version(
239 dwarf_version
[0], dwarf_version
[1], self
.getDwarfVersion()
242 skip_for_setting
= (setting
is None) or (setting
in configuration
.settings
)
244 # For the test to be skipped, all specified (e.g. not None) parameters must be True.
245 # An unspecified parameter means "any", so those are marked skip by default. And we skip
246 # the final test if all conditions are True.
248 (oslist
, skip_for_os
, "target o/s"),
249 (hostoslist
, skip_for_hostos
, "host o/s"),
250 (compiler
, skip_for_compiler
, "compiler or version"),
251 (archs
, skip_for_arch
, "architecture"),
252 (debug_info
, skip_for_debug_info
, "debug info format"),
253 (triple
, skip_for_triple
, "target triple"),
254 (swig_version
, skip_for_swig_version
, "swig version"),
255 (py_version
, skip_for_py_version
, "python version"),
256 (macos_version
, skip_for_macos_version
, "macOS version"),
257 (remote
, skip_for_remote
, "platform locality (remote/local)"),
258 (dwarf_version
, skip_for_dwarf_version
, "dwarf version"),
259 (setting
, skip_for_setting
, "setting"),
262 final_skip_result
= True
263 for this_condition
in conditions
:
264 final_skip_result
= final_skip_result
and this_condition
[1]
265 if this_condition
[0] is not None and this_condition
[1]:
266 reasons
.append(this_condition
[2])
268 if final_skip_result
:
269 mode_str
= {DecorateMode
.Skip
: "skipping", DecorateMode
.Xfail
: "xfailing"}[
273 reason_str
= ",".join(reasons
)
274 reason_str
= "{} due to the following parameter(s): {}".format(
278 reason_str
= "{} unconditionally".format(mode_str
)
279 if bugnumber
is not None and not callable(bugnumber
):
280 reason_str
= reason_str
+ " [" + str(bugnumber
) + "]"
283 if mode
== DecorateMode
.Skip
:
284 return skipTestIfFn(fn
, bugnumber
)
285 elif mode
== DecorateMode
.Xfail
:
286 return expectedFailureIfFn(fn
, bugnumber
)
291 # provide a function to xfail on defined oslist, compiler version, and archs
292 # if none is specified for any argument, that argument won't be checked and thus means for all
294 # @expectedFailureAll, xfail for all platform/compiler/arch,
295 # @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
296 # @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
299 def expectedFailureAll(
304 compiler_version
=None,
315 return _decorateTest(
319 hostoslist
=hostoslist
,
321 compiler_version
=compiler_version
,
324 debug_info
=debug_info
,
325 swig_version
=swig_version
,
326 py_version
=py_version
,
327 macos_version
=macos_version
,
329 dwarf_version
=dwarf_version
,
334 # provide a function to skip on defined oslist, compiler version, and archs
335 # if none is specified for any argument, that argument won't be checked and thus means for all
337 # @skipIf, skip for all platform/compiler/arch,
338 # @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
339 # @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
345 compiler_version
=None,
356 return _decorateTest(
360 hostoslist
=hostoslist
,
362 compiler_version
=compiler_version
,
365 debug_info
=debug_info
,
366 swig_version
=swig_version
,
367 py_version
=py_version
,
368 macos_version
=macos_version
,
370 dwarf_version
=dwarf_version
,
375 def _skip_for_android(reason
, api_levels
, archs
):
377 result
= lldbplatformutil
.match_android_device(
378 obj
.getArchitecture(), valid_archs
=archs
, valid_api_levels
=api_levels
380 return reason
if result
else None
385 def add_test_categories(cat
):
386 """Add test categories to a TestCase method"""
387 cat
= test_categories
.validate(cat
, True)
390 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
392 "@add_test_categories can only be used to decorate a test method"
395 if hasattr(func
, "categories"):
396 cat
.extend(func
.categories
)
397 setattr(func
, "categories", cat
)
398 except AttributeError:
399 raise Exception("Cannot assign categories to inline tests.")
406 def benchmarks_test(func
):
407 """Decorate the item as a benchmarks test."""
409 def should_skip_benchmarks_test():
410 return "benchmarks test"
412 # Mark this function as such to separate them from the regular tests.
413 result
= skipTestIfFn(should_skip_benchmarks_test
)(func
)
414 result
.__benchmarks
_test
__ = True
418 def no_debug_info_test(func
):
419 """Decorate the item as a test what don't use any debug info. If this annotation is specified
420 then the test runner won't generate a separate test for each debug info format."""
421 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
423 "@no_debug_info_test can only be used to decorate a test method"
427 def wrapper(self
, *args
, **kwargs
):
428 return func(self
, *args
, **kwargs
)
430 # Mark this function as such to separate them from the regular tests.
431 wrapper
.__no
_debug
_info
_test
__ = True
435 def apple_simulator_test(platform
):
437 Decorate the test as a test requiring a simulator for a specific platform.
439 Consider that a simulator is available if you have the corresponding SDK installed.
440 The SDK identifiers for simulators are iphonesimulator, appletvsimulator, watchsimulator
443 def should_skip_simulator_test():
444 if lldbplatformutil
.getHostPlatform() not in ["darwin", "macosx"]:
445 return "simulator tests are run only on darwin hosts."
447 DEVNULL
= open(os
.devnull
, "w")
448 output
= subprocess
.check_output(
449 ["xcodebuild", "-showsdks"], stderr
=DEVNULL
451 if re
.search("%ssimulator" % platform
, output
):
454 return "%s simulator is not supported on this system." % platform
455 except subprocess
.CalledProcessError
:
456 return "Simulators are unsupported on this system (xcodebuild failed)"
458 return skipTestIfFn(should_skip_simulator_test
)
461 def debugserver_test(func
):
462 """Decorate the item as a debugserver test."""
463 return add_test_categories(["debugserver"])(func
)
467 """Decorate the item as a lldb-server test."""
468 return add_test_categories(["llgs"])(func
)
471 def expectedFailureOS(
472 oslist
, bugnumber
=None, compilers
=None, debug_info
=None, archs
=None
474 return expectedFailureAll(
479 debug_info
=debug_info
,
483 def expectedFailureDarwin(bugnumber
=None, compilers
=None, debug_info
=None, archs
=None):
484 # For legacy reasons, we support both "darwin" and "macosx" as OS X
486 return expectedFailureOS(
487 lldbplatform
.darwin_all
,
490 debug_info
=debug_info
,
495 def expectedFailureAndroid(bugnumber
=None, api_levels
=None, archs
=None):
496 """Mark a test as xfail for Android.
499 bugnumber - The LLVM pr associated with the problem.
500 api_levels - A sequence of numbers specifying the Android API levels
501 for which a test is expected to fail. None means all API level.
502 arch - A sequence of architecture names specifying the architectures
503 for which a test is expected to fail. None means all architectures.
505 return expectedFailureIfFn(
506 _skip_for_android("xfailing on android", api_levels
, archs
), bugnumber
510 def expectedFailureNetBSD(bugnumber
=None):
511 return expectedFailureOS(["netbsd"], bugnumber
)
514 def expectedFailureWindows(bugnumber
=None):
515 return expectedFailureOS(["windows"], bugnumber
)
518 # TODO: This decorator does not do anything. Remove it.
519 def expectedFlakey(expected_fn
, bugnumber
=None):
520 def expectedFailure_impl(func
):
522 def wrapper(*args
, **kwargs
):
523 func(*args
, **kwargs
)
527 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
528 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
529 # the first way, the first argument will be the actual function because decorators are
530 # weird like that. So this is basically a check that says "which syntax was the original
531 # function decorated with?"
532 if callable(bugnumber
):
533 return expectedFailure_impl(bugnumber
)
535 return expectedFailure_impl
538 def expectedFlakeyOS(oslist
, bugnumber
=None, compilers
=None):
540 return self
.getPlatform() in oslist
and self
.expectedCompiler(compilers
)
542 return expectedFlakey(fn
, bugnumber
)
545 def expectedFlakeyDarwin(bugnumber
=None, compilers
=None):
546 # For legacy reasons, we support both "darwin" and "macosx" as OS X
548 return expectedFlakeyOS(lldbplatformutil
.getDarwinOSTriples(), bugnumber
, compilers
)
551 def expectedFlakeyFreeBSD(bugnumber
=None, compilers
=None):
552 return expectedFlakeyOS(["freebsd"], bugnumber
, compilers
)
555 def expectedFlakeyLinux(bugnumber
=None, compilers
=None):
556 return expectedFlakeyOS(["linux"], bugnumber
, compilers
)
559 def expectedFlakeyNetBSD(bugnumber
=None, compilers
=None):
560 return expectedFlakeyOS(["netbsd"], bugnumber
, compilers
)
563 def expectedFlakeyAndroid(bugnumber
=None, api_levels
=None, archs
=None):
564 return expectedFlakey(
565 _skip_for_android("flakey on android", api_levels
, archs
), bugnumber
569 def skipIfOutOfTreeDebugserver(func
):
570 """Decorate the item to skip tests if using an out-of-tree debugserver."""
572 def is_out_of_tree_debugserver():
574 "out-of-tree debugserver"
575 if lldbtest_config
.out_of_tree_debugserver
579 return skipTestIfFn(is_out_of_tree_debugserver
)(func
)
582 def skipIfRemote(func
):
583 """Decorate the item to skip tests if testing remotely."""
584 return unittest2
.skipIf(lldb
.remote_platform
, "skip on remote platform")(func
)
587 def skipIfNoSBHeaders(func
):
588 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
590 def are_sb_headers_missing():
591 if lldb
.remote_platform
:
592 return "skip because SBHeaders tests make no sense remotely"
595 lldbplatformutil
.getHostPlatform() == "darwin"
596 and configuration
.lldb_framework_path
598 header
= os
.path
.join(
599 configuration
.lldb_framework_path
,
605 if os
.path
.exists(header
):
608 header
= os
.path
.join(
609 os
.environ
["LLDB_SRC"], "include", "lldb", "API", "LLDB.h"
611 if not os
.path
.exists(header
):
612 return "skip because LLDB.h header not found"
615 return skipTestIfFn(are_sb_headers_missing
)(func
)
618 def skipIfRosetta(bugnumber
):
619 """Skip a test when running the testsuite on macOS under the Rosetta translation layer."""
621 def is_running_rosetta(self
):
622 if lldbplatformutil
.getPlatform() in ["darwin", "macosx"]:
623 if (platform
.uname()[5] == "arm") and (self
.getArchitecture() == "x86_64"):
624 return "skipped under Rosetta"
627 return skipTestIfFn(is_running_rosetta
)
630 def skipIfiOSSimulator(func
):
631 """Decorate the item to skip tests that should be skipped on the iOS Simulator."""
633 def is_ios_simulator():
635 "skip on the iOS Simulator"
636 if configuration
.lldb_platform_name
== "ios-simulator"
640 return skipTestIfFn(is_ios_simulator
)(func
)
644 return skipIfPlatform(lldbplatform
.translate(lldbplatform
.ios
))(func
)
647 def skipIftvOS(func
):
648 return skipIfPlatform(lldbplatform
.translate(lldbplatform
.tvos
))(func
)
651 def skipIfwatchOS(func
):
652 return skipIfPlatform(lldbplatform
.translate(lldbplatform
.watchos
))(func
)
655 def skipIfbridgeOS(func
):
656 return skipIfPlatform(lldbplatform
.translate(lldbplatform
.bridgeos
))(func
)
659 def skipIfDarwinEmbedded(func
):
660 """Decorate the item to skip tests that should be skipped on Darwin armv7/arm64 targets."""
661 return skipIfPlatform(lldbplatform
.translate(lldbplatform
.darwin_embedded
))(func
)
664 def skipIfDarwinSimulator(func
):
665 """Decorate the item to skip tests that should be skipped on Darwin simulator targets."""
666 return skipIfPlatform(lldbplatform
.translate(lldbplatform
.darwin_simulator
))(func
)
669 def skipIfFreeBSD(func
):
670 """Decorate the item to skip tests that should be skipped on FreeBSD."""
671 return skipIfPlatform(["freebsd"])(func
)
674 def skipIfNetBSD(func
):
675 """Decorate the item to skip tests that should be skipped on NetBSD."""
676 return skipIfPlatform(["netbsd"])(func
)
679 def skipIfDarwin(func
):
680 """Decorate the item to skip tests that should be skipped on Darwin."""
681 return skipIfPlatform(lldbplatform
.translate(lldbplatform
.darwin_all
))(func
)
684 def skipIfLinux(func
):
685 """Decorate the item to skip tests that should be skipped on Linux."""
686 return skipIfPlatform(["linux"])(func
)
689 def skipIfWindows(func
):
690 """Decorate the item to skip tests that should be skipped on Windows."""
691 return skipIfPlatform(["windows"])(func
)
694 def skipIfWindowsAndNonEnglish(func
):
695 """Decorate the item to skip tests that should be skipped on non-English locales on Windows."""
697 def is_Windows_NonEnglish(self
):
698 if sys
.platform
!= "win32":
700 kernel
= ctypes
.windll
.kernel32
701 if locale
.windows_locale
[kernel
.GetUserDefaultUILanguage()] == "en_US":
703 return "skipping non-English Windows locale"
705 return skipTestIfFn(is_Windows_NonEnglish
)(func
)
708 def skipUnlessWindows(func
):
709 """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
710 return skipUnlessPlatform(["windows"])(func
)
713 def skipUnlessDarwin(func
):
714 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
715 return skipUnlessPlatform(lldbplatformutil
.getDarwinOSTriples())(func
)
718 def skipUnlessTargetAndroid(func
):
719 return unittest2
.skipUnless(
720 lldbplatformutil
.target_is_android(), "requires target to be Android"
724 def skipIfHostIncompatibleWithRemote(func
):
725 """Decorate the item to skip tests if binaries built on this host are incompatible."""
727 def is_host_incompatible_with_remote(self
):
728 host_arch
= self
.getLldbArchitecture()
729 host_platform
= lldbplatformutil
.getHostPlatform()
730 target_arch
= self
.getArchitecture()
731 target_platform
= "darwin" if self
.platformIsDarwin() else self
.getPlatform()
733 not (target_arch
== "x86_64" and host_arch
== "i386")
734 and host_arch
!= target_arch
737 "skipping because target %s is not compatible with host architecture %s"
738 % (target_arch
, host_arch
)
740 if target_platform
!= host_platform
:
741 return "skipping because target is %s but host is %s" % (
745 if lldbplatformutil
.match_android_device(target_arch
):
746 return "skipping because target is android"
749 return skipTestIfFn(is_host_incompatible_with_remote
)(func
)
752 def skipIfPlatform(oslist
):
753 """Decorate the item to skip tests if running on one of the listed platforms."""
754 # This decorator cannot be ported to `skipIf` yet because it is used on entire
755 # classes, which `skipIf` explicitly forbids.
756 return unittest2
.skipIf(
757 lldbplatformutil
.getPlatform() in oslist
, "skip on %s" % (", ".join(oslist
))
761 def skipUnlessPlatform(oslist
):
762 """Decorate the item to skip tests unless running on one of the listed platforms."""
763 # This decorator cannot be ported to `skipIf` yet because it is used on entire
764 # classes, which `skipIf` explicitly forbids.
765 return unittest2
.skipUnless(
766 lldbplatformutil
.getPlatform() in oslist
,
767 "requires one of %s" % (", ".join(oslist
)),
771 def skipUnlessArch(arch
):
772 """Decorate the item to skip tests unless running on the specified architecture."""
774 def arch_doesnt_match(self
):
775 target_arch
= self
.getArchitecture()
776 if arch
!= target_arch
:
777 return "Test only runs on " + arch
+ ", but target arch is " + target_arch
780 return skipTestIfFn(arch_doesnt_match
)
783 def skipIfTargetAndroid(bugnumber
=None, api_levels
=None, archs
=None):
784 """Decorator to skip tests when the target is Android.
787 api_levels - The API levels for which the test should be skipped. If
788 it is None, then the test will be skipped for all API levels.
789 arch - A sequence of architecture names specifying the architectures
790 for which a test is skipped. None means all architectures.
793 _skip_for_android("skipping for android", api_levels
, archs
), bugnumber
797 def skipUnlessAppleSilicon(func
):
798 """Decorate the item to skip tests unless running on Apple Silicon."""
800 def not_apple_silicon(test
):
801 if platform
.system() != "Darwin" or test
.getArchitecture() not in [
805 return "Test only runs on Apple Silicon"
808 return skipTestIfFn(not_apple_silicon
)(func
)
811 def skipUnlessSupportedTypeAttribute(attr
):
812 """Decorate the item to skip test unless Clang supports type __attribute__(attr)."""
814 def compiler_doesnt_support_struct_attribute(self
):
815 compiler_path
= self
.getCompiler()
816 f
= tempfile
.NamedTemporaryFile()
817 cmd
= [self
.getCompiler(), "-x", "c++", "-c", "-o", f
.name
, "-"]
818 p
= subprocess
.Popen(
820 stdin
=subprocess
.PIPE
,
821 stdout
=subprocess
.PIPE
,
822 stderr
=subprocess
.PIPE
,
823 universal_newlines
=True,
825 stdout
, stderr
= p
.communicate("struct __attribute__((%s)) Test {};" % attr
)
827 return "Compiler does not support attribute %s" % (attr
)
830 return skipTestIfFn(compiler_doesnt_support_struct_attribute
)
833 def skipUnlessHasCallSiteInfo(func
):
834 """Decorate the function to skip testing unless call site info from clang is available."""
836 def is_compiler_clang_with_call_site_info(self
):
837 compiler_path
= self
.getCompiler()
838 compiler
= os
.path
.basename(compiler_path
)
839 if not compiler
.startswith("clang"):
840 return "Test requires clang as compiler"
842 f
= tempfile
.NamedTemporaryFile()
844 "echo 'int main() {}' | "
845 "%s -g -glldb -O1 -S -emit-llvm -x c -o %s -" % (compiler_path
, f
.name
)
847 if os
.popen(cmd
).close() is not None:
848 return "Compiler can't compile with call site info enabled"
850 with
open(f
.name
, "r") as ir_output_file
:
851 buf
= ir_output_file
.read()
853 if "DIFlagAllCallsDescribed" not in buf
:
854 return "Compiler did not introduce DIFlagAllCallsDescribed IR flag"
858 return skipTestIfFn(is_compiler_clang_with_call_site_info
)(func
)
861 def skipUnlessThreadSanitizer(func
):
862 """Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
864 def is_compiler_clang_with_thread_sanitizer(self
):
865 if is_running_under_asan():
866 return "Thread sanitizer tests are disabled when runing under ASAN"
868 compiler_path
= self
.getCompiler()
869 compiler
= os
.path
.basename(compiler_path
)
870 if not compiler
.startswith("clang"):
871 return "Test requires clang as compiler"
872 if lldbplatformutil
.getPlatform() == "windows":
873 return "TSAN tests not compatible with 'windows'"
874 # rdar://28659145 - TSAN tests don't look like they're supported on i386
875 if self
.getArchitecture() == "i386" and platform
.system() == "Darwin":
876 return "TSAN tests not compatible with i386 targets"
877 if not _compiler_supports(compiler_path
, "-fsanitize=thread"):
878 return "Compiler cannot compile with -fsanitize=thread"
881 return skipTestIfFn(is_compiler_clang_with_thread_sanitizer
)(func
)
884 def skipUnlessUndefinedBehaviorSanitizer(func
):
885 """Decorate the item to skip test unless -fsanitize=undefined is supported."""
887 def is_compiler_clang_with_ubsan(self
):
888 if is_running_under_asan():
890 "Undefined behavior sanitizer tests are disabled when runing under ASAN"
893 # We need to write out the object into a named temp file for inspection.
894 outputf
= tempfile
.NamedTemporaryFile()
896 # Try to compile with ubsan turned on.
897 if not _compiler_supports(
899 "-fsanitize=undefined",
900 "int main() { int x = 0; return x / x; }",
903 return "Compiler cannot compile with -fsanitize=undefined"
905 # Check that we actually see ubsan instrumentation in the binary.
906 cmd
= "nm %s" % outputf
.name
907 with os
.popen(cmd
) as nm_output
:
908 if "___ubsan_handle_divrem_overflow" not in nm_output
.read():
909 return "Division by zero instrumentation is missing"
911 # Find the ubsan dylib.
912 # FIXME: This check should go away once compiler-rt gains support for __ubsan_on_report.
913 cmd
= "%s -fsanitize=undefined -x c - -o - -### 2>&1" % self
.getCompiler()
914 with os
.popen(cmd
) as cc_output
:
915 driver_jobs
= cc_output
.read()
916 m
= re
.search(r
'"([^"]+libclang_rt.ubsan_osx_dynamic.dylib)"', driver_jobs
)
918 return "Could not find the ubsan dylib used by the driver"
919 ubsan_dylib
= m
.group(1)
921 # Check that the ubsan dylib has special monitor hooks.
922 cmd
= "nm -gU %s" % ubsan_dylib
923 with os
.popen(cmd
) as nm_output
:
924 syms
= nm_output
.read()
925 if "___ubsan_on_report" not in syms
:
926 return "Missing ___ubsan_on_report"
927 if "___ubsan_get_current_report_data" not in syms
:
928 return "Missing ___ubsan_get_current_report_data"
930 # OK, this dylib + compiler works for us.
933 return skipTestIfFn(is_compiler_clang_with_ubsan
)(func
)
936 def is_running_under_asan():
937 if "ASAN_OPTIONS" in os
.environ
:
938 return "ASAN unsupported"
942 def skipUnlessAddressSanitizer(func
):
943 """Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
945 def is_compiler_with_address_sanitizer(self
):
946 # Also don't run tests that use address sanitizer inside an
947 # address-sanitized LLDB. The tests don't support that
949 if is_running_under_asan():
950 return "Address sanitizer tests are disabled when runing under ASAN"
952 if lldbplatformutil
.getPlatform() == "windows":
953 return "ASAN tests not compatible with 'windows'"
954 if not _compiler_supports(self
.getCompiler(), "-fsanitize=address"):
955 return "Compiler cannot compile with -fsanitize=address"
958 return skipTestIfFn(is_compiler_with_address_sanitizer
)(func
)
961 def skipIfAsan(func
):
962 """Skip this test if the environment is set up to run LLDB *itself* under ASAN."""
963 return skipTestIfFn(is_running_under_asan
)(func
)
966 def skipUnlessAArch64MTELinuxCompiler(func
):
967 """Decorate the item to skip test unless MTE is supported by the test compiler."""
969 def is_toolchain_with_mte(self
):
970 compiler_path
= self
.getCompiler()
971 compiler
= os
.path
.basename(compiler_path
)
972 f
= tempfile
.NamedTemporaryFile()
973 if lldbplatformutil
.getPlatform() == "windows":
974 return "MTE tests are not compatible with 'windows'"
976 cmd
= "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path
, f
.name
)
977 if os
.popen(cmd
).close() is not None:
978 # Cannot compile at all, don't skip the test
979 # so that we report the broken compiler normally.
982 # We need the Linux headers and ACLE MTE intrinsics
984 #include <asm/hwcap.h>
985 #include <arm_acle.h>
990 void* ptr = __arm_mte_create_random_tag((void*)(0), 0);
992 cmd
= "echo '%s' | %s -march=armv8.5-a+memtag -x c -o %s -" % (
997 if os
.popen(cmd
).close() is not None:
998 return "Toolchain does not support MTE"
1001 return skipTestIfFn(is_toolchain_with_mte
)(func
)
1004 def _get_bool_config(key
, fail_value
=True):
1006 Returns the current LLDB's build config value.
1007 :param key The key to lookup in LLDB's build configuration.
1008 :param fail_value The error value to return when the key can't be found.
1009 Defaults to true so that if an unknown key is lookup up we rather
1010 enable more tests (that then fail) than silently skipping them.
1012 config
= lldb
.SBDebugger
.GetBuildConfiguration()
1013 value_node
= config
.GetValueForKey(key
)
1014 return value_node
.GetValueForKey("value").GetBooleanValue(fail_value
)
1017 def _get_bool_config_skip_if_decorator(key
):
1018 have
= _get_bool_config(key
)
1019 return unittest2
.skipIf(not have
, "requires " + key
)
1022 def skipIfCursesSupportMissing(func
):
1023 return _get_bool_config_skip_if_decorator("curses")(func
)
1026 def skipIfXmlSupportMissing(func
):
1027 return _get_bool_config_skip_if_decorator("xml")(func
)
1030 def skipIfEditlineSupportMissing(func
):
1031 return _get_bool_config_skip_if_decorator("editline")(func
)
1034 def skipIfEditlineWideCharSupportMissing(func
):
1035 return _get_bool_config_skip_if_decorator("editline_wchar")(func
)
1038 def skipIfFBSDVMCoreSupportMissing(func
):
1039 return _get_bool_config_skip_if_decorator("fbsdvmcore")(func
)
1042 def skipIfLLVMTargetMissing(target
):
1043 config
= lldb
.SBDebugger
.GetBuildConfiguration()
1044 targets
= config
.GetValueForKey("targets").GetValueForKey("value")
1046 for i
in range(targets
.GetSize()):
1047 if targets
.GetItemAtIndex(i
).GetStringValue(99) == target
:
1051 return unittest2
.skipIf(not found
, "requires " + target
)
1054 # Call sysctl on darwin to see if a specified hardware feature is available on this machine.
1055 def skipUnlessFeature(feature
):
1056 def is_feature_enabled(self
):
1057 if platform
.system() == "Darwin":
1059 DEVNULL
= open(os
.devnull
, "w")
1060 output
= subprocess
.check_output(
1061 ["/usr/sbin/sysctl", feature
], stderr
=DEVNULL
1063 # If 'feature: 1' was output, then this feature is available and
1064 # the test should not be skipped.
1065 if re
.match("%s: 1\s*" % feature
, output
):
1068 return "%s is not supported on this system." % feature
1069 except subprocess
.CalledProcessError
:
1070 return "%s is not supported on this system." % feature
1072 return skipTestIfFn(is_feature_enabled
)