1 from __future__
import absolute_import
4 from distutils
.version
import LooseVersion
5 from functools
import wraps
19 from . import configuration
20 from . import test_categories
21 from . import lldbtest_config
22 from lldbsuite
.test_event
.event_builder
import EventBuilder
23 from lldbsuite
.support
import funcutils
24 from lldbsuite
.test
import lldbplatform
25 from lldbsuite
.test
import lldbplatformutil
29 Skip
, Xfail
= range(2)
32 # You can use no_match to reverse the test of the conditional that is used to match keyword
33 # arguments in the skip / xfail decorators. If oslist=["windows", "linux"] skips windows
34 # and linux, oslist=no_match(["windows", "linux"]) skips *unless* windows
38 def __init__(self
, item
):
42 def _check_expected_version(comparison
, expected
, actual
):
43 def fn_leq(x
, y
): return x
<= y
45 def fn_less(x
, y
): return x
< y
47 def fn_geq(x
, y
): return x
>= y
49 def fn_greater(x
, y
): return x
> y
51 def fn_eq(x
, y
): return x
== y
53 def fn_neq(x
, y
): return x
!= y
65 expected_str
= '.'.join([str(x
) for x
in expected
])
66 actual_str
= '.'.join([str(x
) for x
in actual
])
68 return op_lookup
[comparison
](
69 LooseVersion(actual_str
),
70 LooseVersion(expected_str
))
73 _re_pattern_type
= type(re
.compile(''))
74 def _match_decorator_property(expected
, actual
):
75 if actual
is None or expected
is None:
78 if isinstance(expected
, no_match
):
79 return not _match_decorator_property(expected
.item
, actual
)
80 elif isinstance(expected
, (_re_pattern_type
,) + six
.string_types
):
81 return re
.search(expected
, actual
) is not None
82 elif hasattr(expected
, "__iter__"):
83 return any([x
is not None and _match_decorator_property(x
, actual
)
86 return expected
== actual
89 def expectedFailure(expected_fn
, bugnumber
=None):
90 def expectedFailure_impl(func
):
91 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
93 "Decorator can only be used to decorate a test method")
96 def wrapper(*args
, **kwargs
):
98 if funcutils
.requires_self(expected_fn
):
99 xfail_reason
= expected_fn(self
)
101 xfail_reason
= expected_fn()
102 if xfail_reason
is not None:
103 if configuration
.results_formatter_object
is not None:
104 # Mark this test as expected to fail.
105 configuration
.results_formatter_object
.handle_event(
106 EventBuilder
.event_for_mark_test_expected_failure(self
))
107 xfail_func
= unittest2
.expectedFailure(func
)
108 xfail_func(*args
, **kwargs
)
110 func(*args
, **kwargs
)
112 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
113 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
114 # the first way, the first argument will be the actual function because decorators are
115 # weird like that. So this is basically a check that says "which syntax was the original
116 # function decorated with?"
117 if six
.callable(bugnumber
):
118 return expectedFailure_impl(bugnumber
)
120 return expectedFailure_impl
123 def skipTestIfFn(expected_fn
, bugnumber
=None):
124 def skipTestIfFn_impl(func
):
125 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
127 "@skipTestIfFn can only be used to decorate a test method")
130 def wrapper(*args
, **kwargs
):
132 if funcutils
.requires_self(expected_fn
):
133 reason
= expected_fn(self
)
135 reason
= expected_fn()
137 if reason
is not None:
138 self
.skipTest(reason
)
140 func(*args
, **kwargs
)
143 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
144 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
145 # the first way, the first argument will be the actual function because decorators are
146 # weird like that. So this is basically a check that says "how was the
148 if six
.callable(bugnumber
):
149 return skipTestIfFn_impl(bugnumber
)
151 return skipTestIfFn_impl
154 def _decorateTest(mode
,
155 bugnumber
=None, oslist
=None, hostoslist
=None,
156 compiler
=None, compiler_version
=None,
157 archs
=None, triple
=None,
159 swig_version
=None, py_version
=None,
161 remote
=None, dwarf_version
=None):
163 skip_for_os
= _match_decorator_property(
164 lldbplatform
.translate(oslist
), self
.getPlatform())
165 skip_for_hostos
= _match_decorator_property(
166 lldbplatform
.translate(hostoslist
),
167 lldbplatformutil
.getHostPlatform())
168 skip_for_compiler
= _match_decorator_property(
169 compiler
, self
.getCompiler()) and self
.expectedCompilerVersion(compiler_version
)
170 skip_for_arch
= _match_decorator_property(
171 archs
, self
.getArchitecture())
172 skip_for_debug_info
= _match_decorator_property(
173 debug_info
, self
.getDebugInfo())
174 skip_for_triple
= _match_decorator_property(
175 triple
, lldb
.DBG
.GetSelectedPlatform().GetTriple())
176 skip_for_remote
= _match_decorator_property(
177 remote
, lldb
.remote_platform
is not None)
179 skip_for_swig_version
= (
180 swig_version
is None) or (
183 'swig_version')) or (
184 _check_expected_version(
188 skip_for_py_version
= (
189 py_version
is None) or _check_expected_version(
190 py_version
[0], py_version
[1], sys
.version_info
)
191 skip_for_macos_version
= (macos_version
is None) or (
192 (platform
.mac_ver()[0] != "") and (_check_expected_version(
195 platform
.mac_ver()[0])))
196 skip_for_dwarf_version
= (dwarf_version
is None) or (
197 _check_expected_version(dwarf_version
[0], dwarf_version
[1],
198 self
.getDwarfVersion()))
200 # For the test to be skipped, all specified (e.g. not None) parameters must be True.
201 # An unspecified parameter means "any", so those are marked skip by default. And we skip
202 # the final test if all conditions are True.
203 conditions
= [(oslist
, skip_for_os
, "target o/s"),
204 (hostoslist
, skip_for_hostos
, "host o/s"),
205 (compiler
, skip_for_compiler
, "compiler or version"),
206 (archs
, skip_for_arch
, "architecture"),
207 (debug_info
, skip_for_debug_info
, "debug info format"),
208 (triple
, skip_for_triple
, "target triple"),
209 (swig_version
, skip_for_swig_version
, "swig version"),
210 (py_version
, skip_for_py_version
, "python version"),
211 (macos_version
, skip_for_macos_version
, "macOS version"),
212 (remote
, skip_for_remote
, "platform locality (remote/local)"),
213 (dwarf_version
, skip_for_dwarf_version
, "dwarf version")]
215 final_skip_result
= True
216 for this_condition
in conditions
:
217 final_skip_result
= final_skip_result
and this_condition
[1]
218 if this_condition
[0] is not None and this_condition
[1]:
219 reasons
.append(this_condition
[2])
221 if final_skip_result
:
223 DecorateMode
.Skip
: "skipping",
224 DecorateMode
.Xfail
: "xfailing"}[mode
]
226 reason_str
= ",".join(reasons
)
227 reason_str
= "{} due to the following parameter(s): {}".format(
228 mode_str
, reason_str
)
230 reason_str
= "{} unconditionally"
231 if bugnumber
is not None and not six
.callable(bugnumber
):
232 reason_str
= reason_str
+ " [" + str(bugnumber
) + "]"
235 if mode
== DecorateMode
.Skip
:
236 return skipTestIfFn(fn
, bugnumber
)
237 elif mode
== DecorateMode
.Xfail
:
238 return expectedFailure(fn
, bugnumber
)
242 # provide a function to xfail on defined oslist, compiler version, and archs
243 # if none is specified for any argument, that argument won't be checked and thus means for all
245 # @expectedFailureAll, xfail for all platform/compiler/arch,
246 # @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
247 # @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
250 def expectedFailureAll(bugnumber
=None,
251 oslist
=None, hostoslist
=None,
252 compiler
=None, compiler_version
=None,
253 archs
=None, triple
=None,
255 swig_version
=None, py_version
=None,
257 remote
=None, dwarf_version
=None):
258 return _decorateTest(DecorateMode
.Xfail
,
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
,
266 remote
=remote
,dwarf_version
=dwarf_version
)
269 # provide a function to skip on defined oslist, compiler version, and archs
270 # if none is specified for any argument, that argument won't be checked and thus means for all
272 # @skipIf, skip for all platform/compiler/arch,
273 # @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
274 # @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
275 def skipIf(bugnumber
=None,
276 oslist
=None, hostoslist
=None,
277 compiler
=None, compiler_version
=None,
278 archs
=None, triple
=None,
280 swig_version
=None, py_version
=None,
282 remote
=None, dwarf_version
=None):
283 return _decorateTest(DecorateMode
.Skip
,
285 oslist
=oslist
, hostoslist
=hostoslist
,
286 compiler
=compiler
, compiler_version
=compiler_version
,
287 archs
=archs
, triple
=triple
,
288 debug_info
=debug_info
,
289 swig_version
=swig_version
, py_version
=py_version
,
290 macos_version
=macos_version
,
291 remote
=remote
, dwarf_version
=dwarf_version
)
294 def _skip_for_android(reason
, api_levels
, archs
):
296 result
= lldbplatformutil
.match_android_device(
297 obj
.getArchitecture(), valid_archs
=archs
, valid_api_levels
=api_levels
)
298 return reason
if result
else None
302 def add_test_categories(cat
):
303 """Add test categories to a TestCase method"""
304 cat
= test_categories
.validate(cat
, True)
307 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
309 "@add_test_categories can only be used to decorate a test method")
311 if hasattr(func
, "categories"):
312 cat
.extend(func
.categories
)
313 setattr(func
, "categories", cat
)
314 except AttributeError:
315 raise Exception('Cannot assign categories to inline tests.')
322 def benchmarks_test(func
):
323 """Decorate the item as a benchmarks test."""
324 def should_skip_benchmarks_test():
325 return "benchmarks test"
327 # Mark this function as such to separate them from the regular tests.
328 result
= skipTestIfFn(should_skip_benchmarks_test
)(func
)
329 result
.__benchmarks
_test
__ = True
333 def no_debug_info_test(func
):
334 """Decorate the item as a test what don't use any debug info. If this annotation is specified
335 then the test runner won't generate a separate test for each debug info format. """
336 if isinstance(func
, type) and issubclass(func
, unittest2
.TestCase
):
338 "@no_debug_info_test can only be used to decorate a test method")
341 def wrapper(self
, *args
, **kwargs
):
342 return func(self
, *args
, **kwargs
)
344 # Mark this function as such to separate them from the regular tests.
345 wrapper
.__no
_debug
_info
_test
__ = True
348 def apple_simulator_test(platform
):
350 Decorate the test as a test requiring a simulator for a specific platform.
352 Consider that a simulator is available if you have the corresponding SDK installed.
353 The SDK identifiers for simulators are iphonesimulator, appletvsimulator, watchsimulator
355 def should_skip_simulator_test():
356 if lldbplatformutil
.getHostPlatform() != 'darwin':
357 return "simulator tests are run only on darwin hosts"
359 DEVNULL
= open(os
.devnull
, 'w')
360 output
= subprocess
.check_output(["xcodebuild", "-showsdks"], stderr
=DEVNULL
).decode("utf-8")
361 if re
.search('%ssimulator' % platform
, output
):
364 return "%s simulator is not supported on this system." % platform
365 except subprocess
.CalledProcessError
:
366 return "Simulators are unsupported on this system (xcodebuild failed)"
368 return skipTestIfFn(should_skip_simulator_test
)
371 def debugserver_test(func
):
372 """Decorate the item as a debugserver test."""
373 def should_skip_debugserver_test():
374 return "debugserver tests" if configuration
.dont_do_debugserver_test
else None
375 return skipTestIfFn(should_skip_debugserver_test
)(func
)
379 """Decorate the item as a lldb-server test."""
380 def should_skip_llgs_tests():
381 return "llgs tests" if configuration
.dont_do_llgs_test
else None
382 return skipTestIfFn(should_skip_llgs_tests
)(func
)
385 def not_remote_testsuite_ready(func
):
386 """Decorate the item as a test which is not ready yet for remote testsuite."""
388 return "Not ready for remote testsuite" if lldb
.remote_platform
else None
389 return skipTestIfFn(is_remote
)(func
)
392 def expectedFailureOS(
398 return expectedFailureAll(
403 debug_info
=debug_info
)
406 def expectedFailureDarwin(bugnumber
=None, compilers
=None, debug_info
=None):
407 # For legacy reasons, we support both "darwin" and "macosx" as OS X
409 return expectedFailureOS(
410 lldbplatform
.darwin_all
,
413 debug_info
=debug_info
)
416 def expectedFailureAndroid(bugnumber
=None, api_levels
=None, archs
=None):
417 """ Mark a test as xfail for Android.
420 bugnumber - The LLVM pr associated with the problem.
421 api_levels - A sequence of numbers specifying the Android API levels
422 for which a test is expected to fail. None means all API level.
423 arch - A sequence of architecture names specifying the architectures
424 for which a test is expected to fail. None means all architectures.
426 return expectedFailure(
428 "xfailing on android",
434 def expectedFailureNetBSD(bugnumber
=None):
435 return expectedFailureOS(
439 # Flakey tests get two chances to run. If they fail the first time round, the result formatter
440 # makes sure it is run one more time.
443 def expectedFlakey(expected_fn
, bugnumber
=None):
444 def expectedFailure_impl(func
):
446 def wrapper(*args
, **kwargs
):
448 if expected_fn(self
):
449 # Send event marking test as explicitly eligible for rerunning.
450 if configuration
.results_formatter_object
is not None:
451 # Mark this test as rerunnable.
452 configuration
.results_formatter_object
.handle_event(
453 EventBuilder
.event_for_mark_test_rerun_eligible(self
))
454 func(*args
, **kwargs
)
456 # Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
457 # or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
458 # the first way, the first argument will be the actual function because decorators are
459 # weird like that. So this is basically a check that says "which syntax was the original
460 # function decorated with?"
461 if six
.callable(bugnumber
):
462 return expectedFailure_impl(bugnumber
)
464 return expectedFailure_impl
467 def expectedFlakeyOS(oslist
, bugnumber
=None, compilers
=None):
469 return (self
.getPlatform() in oslist
and
470 self
.expectedCompiler(compilers
))
471 return expectedFlakey(fn
, bugnumber
)
474 def expectedFlakeyDarwin(bugnumber
=None, compilers
=None):
475 # For legacy reasons, we support both "darwin" and "macosx" as OS X
477 return expectedFlakeyOS(
478 lldbplatformutil
.getDarwinOSTriples(),
483 def expectedFlakeyFreeBSD(bugnumber
=None, compilers
=None):
484 return expectedFlakeyOS(['freebsd'], bugnumber
, compilers
)
487 def expectedFlakeyLinux(bugnumber
=None, compilers
=None):
488 return expectedFlakeyOS(['linux'], bugnumber
, compilers
)
491 def expectedFlakeyNetBSD(bugnumber
=None, compilers
=None):
492 return expectedFlakeyOS(['netbsd'], bugnumber
, compilers
)
495 def expectedFlakeyAndroid(bugnumber
=None, api_levels
=None, archs
=None):
496 return expectedFlakey(
503 def skipIfOutOfTreeDebugserver(func
):
504 """Decorate the item to skip tests if using an out-of-tree debugserver."""
505 def is_out_of_tree_debugserver():
506 return "out-of-tree debugserver" if lldbtest_config
.out_of_tree_debugserver
else None
507 return skipTestIfFn(is_out_of_tree_debugserver
)(func
)
509 def skipIfRemote(func
):
510 """Decorate the item to skip tests if testing remotely."""
512 return "skip on remote platform" if lldb
.remote_platform
else None
513 return skipTestIfFn(is_remote
)(func
)
516 def skipIfNoSBHeaders(func
):
517 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
518 def are_sb_headers_missing():
519 if lldb
.remote_platform
:
520 return "skip because SBHeaders tests make no sense remotely"
522 if lldbplatformutil
.getHostPlatform() == 'darwin':
523 header
= os
.path
.join(
524 os
.environ
["LLDB_LIB_DIR"],
530 if os
.path
.exists(header
):
533 header
= os
.path
.join(
534 os
.environ
["LLDB_SRC"],
539 if not os
.path
.exists(header
):
540 return "skip because LLDB.h header not found"
543 return skipTestIfFn(are_sb_headers_missing
)(func
)
546 def skipIfiOSSimulator(func
):
547 """Decorate the item to skip tests that should be skipped on the iOS Simulator."""
548 def is_ios_simulator():
549 return "skip on the iOS Simulator" if configuration
.lldb_platform_name
== 'ios-simulator' else None
550 return skipTestIfFn(is_ios_simulator
)(func
)
553 return skipIfPlatform(["ios"])(func
)
555 def skipIftvOS(func
):
556 return skipIfPlatform(["tvos"])(func
)
558 def skipIfwatchOS(func
):
559 return skipIfPlatform(["watchos"])(func
)
561 def skipIfbridgeOS(func
):
562 return skipIfPlatform(["bridgeos"])(func
)
564 def skipIfDarwinEmbedded(func
):
565 """Decorate the item to skip tests that should be skipped on Darwin armv7/arm64 targets."""
566 return skipIfPlatform(
567 lldbplatform
.translate(
568 lldbplatform
.darwin_embedded
))(func
)
570 def skipIfFreeBSD(func
):
571 """Decorate the item to skip tests that should be skipped on FreeBSD."""
572 return skipIfPlatform(["freebsd"])(func
)
575 def skipIfNetBSD(func
):
576 """Decorate the item to skip tests that should be skipped on NetBSD."""
577 return skipIfPlatform(["netbsd"])(func
)
580 def skipIfDarwin(func
):
581 """Decorate the item to skip tests that should be skipped on Darwin."""
582 return skipIfPlatform(
583 lldbplatform
.translate(
584 lldbplatform
.darwin_all
))(func
)
587 def skipIfLinux(func
):
588 """Decorate the item to skip tests that should be skipped on Linux."""
589 return skipIfPlatform(["linux"])(func
)
592 def skipIfWindows(func
):
593 """Decorate the item to skip tests that should be skipped on Windows."""
594 return skipIfPlatform(["windows"])(func
)
596 def skipUnlessWindows(func
):
597 """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
598 return skipUnlessPlatform(["windows"])(func
)
601 def skipUnlessDarwin(func
):
602 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
603 return skipUnlessPlatform(lldbplatformutil
.getDarwinOSTriples())(func
)
605 def skipUnlessTargetAndroid(func
):
606 return unittest2
.skipUnless(lldbplatformutil
.target_is_android(),
607 "requires target to be Android")(func
)
610 def skipIfHostIncompatibleWithRemote(func
):
611 """Decorate the item to skip tests if binaries built on this host are incompatible."""
613 def is_host_incompatible_with_remote(self
):
614 host_arch
= self
.getLldbArchitecture()
615 host_platform
= lldbplatformutil
.getHostPlatform()
616 target_arch
= self
.getArchitecture()
617 target_platform
= 'darwin' if self
.platformIsDarwin() else self
.getPlatform()
618 if not (target_arch
== 'x86_64' and host_arch
==
619 'i386') and host_arch
!= target_arch
:
620 return "skipping because target %s is not compatible with host architecture %s" % (
621 target_arch
, host_arch
)
622 if target_platform
!= host_platform
:
623 return "skipping because target is %s but host is %s" % (
624 target_platform
, host_platform
)
625 if lldbplatformutil
.match_android_device(target_arch
):
626 return "skipping because target is android"
628 return skipTestIfFn(is_host_incompatible_with_remote
)(func
)
631 def skipIfPlatform(oslist
):
632 """Decorate the item to skip tests if running on one of the listed platforms."""
633 # This decorator cannot be ported to `skipIf` yet because it is used on entire
634 # classes, which `skipIf` explicitly forbids.
635 return unittest2
.skipIf(lldbplatformutil
.getPlatform() in oslist
,
636 "skip on %s" % (", ".join(oslist
)))
639 def skipUnlessPlatform(oslist
):
640 """Decorate the item to skip tests unless running on one of the listed platforms."""
641 # This decorator cannot be ported to `skipIf` yet because it is used on entire
642 # classes, which `skipIf` explicitly forbids.
643 return unittest2
.skipUnless(lldbplatformutil
.getPlatform() in oslist
,
644 "requires one of %s" % (", ".join(oslist
)))
646 def skipUnlessArch(arch
):
647 """Decorate the item to skip tests unless running on the specified architecture."""
649 def arch_doesnt_match(self
):
650 target_arch
= self
.getArchitecture()
651 if arch
!= target_arch
:
652 return "Test only runs on " + arch
+ ", but target arch is " + target_arch
655 return skipTestIfFn(arch_doesnt_match
)
657 def skipIfTargetAndroid(bugnumber
=None, api_levels
=None, archs
=None):
658 """Decorator to skip tests when the target is Android.
661 api_levels - The API levels for which the test should be skipped. If
662 it is None, then the test will be skipped for all API levels.
663 arch - A sequence of architecture names specifying the architectures
664 for which a test is skipped. None means all architectures.
668 "skipping for android",
673 def skipUnlessSupportedTypeAttribute(attr
):
674 """Decorate the item to skip test unless Clang supports type __attribute__(attr)."""
675 def compiler_doesnt_support_struct_attribute(self
):
676 compiler_path
= self
.getCompiler()
677 f
= tempfile
.NamedTemporaryFile()
678 cmd
= [self
.getCompiler(), "-x", "c++", "-c", "-o", f
.name
, "-"]
679 p
= subprocess
.Popen(cmd
, stdin
=subprocess
.PIPE
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, universal_newlines
=True)
680 stdout
, stderr
= p
.communicate('struct __attribute__((%s)) Test {};'%attr
)
682 return "Compiler does not support attribute %s"%(attr)
684 return skipTestIfFn(compiler_doesnt_support_struct_attribute
)
686 def skipUnlessHasCallSiteInfo(func
):
687 """Decorate the function to skip testing unless call site info from clang is available."""
689 def is_compiler_clang_with_call_site_info(self
):
690 compiler_path
= self
.getCompiler()
691 compiler
= os
.path
.basename(compiler_path
)
692 if not compiler
.startswith("clang"):
693 return "Test requires clang as compiler"
695 f
= tempfile
.NamedTemporaryFile()
696 cmd
= "echo 'int main() {}' | " \
697 "%s -g -glldb -O1 -Xclang -femit-debug-entry-values -S -emit-llvm -x c -o %s -" % (compiler_path
, f
.name
)
698 if os
.popen(cmd
).close() is not None:
699 return "Compiler can't compile with call site info enabled"
701 with
open(f
.name
, 'r') as ir_output_file
:
702 buf
= ir_output_file
.read()
704 if 'DIFlagAllCallsDescribed' not in buf
:
705 return "Compiler did not introduce DIFlagAllCallsDescribed IR flag"
708 return skipTestIfFn(is_compiler_clang_with_call_site_info
)(func
)
710 def skipUnlessThreadSanitizer(func
):
711 """Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
713 def is_compiler_clang_with_thread_sanitizer(self
):
714 compiler_path
= self
.getCompiler()
715 compiler
= os
.path
.basename(compiler_path
)
716 if not compiler
.startswith("clang"):
717 return "Test requires clang as compiler"
718 if lldbplatformutil
.getPlatform() == 'windows':
719 return "TSAN tests not compatible with 'windows'"
720 # rdar://28659145 - TSAN tests don't look like they're supported on i386
721 if self
.getArchitecture() == 'i386' and platform
.system() == 'Darwin':
722 return "TSAN tests not compatible with i386 targets"
723 f
= tempfile
.NamedTemporaryFile()
724 cmd
= "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path
, f
.name
)
725 if os
.popen(cmd
).close() is not None:
726 return None # The compiler cannot compile at all, let's *not* skip the test
727 cmd
= "echo 'int main() {}' | %s -fsanitize=thread -x c -o %s -" % (compiler_path
, f
.name
)
728 if os
.popen(cmd
).close() is not None:
729 return "Compiler cannot compile with -fsanitize=thread"
731 return skipTestIfFn(is_compiler_clang_with_thread_sanitizer
)(func
)
733 def skipUnlessUndefinedBehaviorSanitizer(func
):
734 """Decorate the item to skip test unless -fsanitize=undefined is supported."""
736 def is_compiler_clang_with_ubsan(self
):
737 # Write out a temp file which exhibits UB.
738 inputf
= tempfile
.NamedTemporaryFile(suffix
='.c', mode
='w')
739 inputf
.write('int main() { int x = 0; return x / x; }\n')
742 # We need to write out the object into a named temp file for inspection.
743 outputf
= tempfile
.NamedTemporaryFile()
745 # Try to compile with ubsan turned on.
746 cmd
= '%s -fsanitize=undefined %s -o %s' % (self
.getCompiler(), inputf
.name
, outputf
.name
)
747 if os
.popen(cmd
).close() is not None:
748 return "Compiler cannot compile with -fsanitize=undefined"
750 # Check that we actually see ubsan instrumentation in the binary.
751 cmd
= 'nm %s' % outputf
.name
752 with os
.popen(cmd
) as nm_output
:
753 if '___ubsan_handle_divrem_overflow' not in nm_output
.read():
754 return "Division by zero instrumentation is missing"
756 # Find the ubsan dylib.
757 # FIXME: This check should go away once compiler-rt gains support for __ubsan_on_report.
758 cmd
= '%s -fsanitize=undefined -x c - -o - -### 2>&1' % self
.getCompiler()
759 with os
.popen(cmd
) as cc_output
:
760 driver_jobs
= cc_output
.read()
761 m
= re
.search(r
'"([^"]+libclang_rt.ubsan_osx_dynamic.dylib)"', driver_jobs
)
763 return "Could not find the ubsan dylib used by the driver"
764 ubsan_dylib
= m
.group(1)
766 # Check that the ubsan dylib has special monitor hooks.
767 cmd
= 'nm -gU %s' % ubsan_dylib
768 with os
.popen(cmd
) as nm_output
:
769 syms
= nm_output
.read()
770 if '___ubsan_on_report' not in syms
:
771 return "Missing ___ubsan_on_report"
772 if '___ubsan_get_current_report_data' not in syms
:
773 return "Missing ___ubsan_get_current_report_data"
775 # OK, this dylib + compiler works for us.
778 return skipTestIfFn(is_compiler_clang_with_ubsan
)(func
)
780 def skipUnlessAddressSanitizer(func
):
781 """Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
783 def is_compiler_with_address_sanitizer(self
):
784 compiler_path
= self
.getCompiler()
785 compiler
= os
.path
.basename(compiler_path
)
786 f
= tempfile
.NamedTemporaryFile()
787 if lldbplatformutil
.getPlatform() == 'windows':
788 return "ASAN tests not compatible with 'windows'"
789 cmd
= "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path
, f
.name
)
790 if os
.popen(cmd
).close() is not None:
791 return None # The compiler cannot compile at all, let's *not* skip the test
792 cmd
= "echo 'int main() {}' | %s -fsanitize=address -x c -o %s -" % (compiler_path
, f
.name
)
793 if os
.popen(cmd
).close() is not None:
794 return "Compiler cannot compile with -fsanitize=address"
796 return skipTestIfFn(is_compiler_with_address_sanitizer
)(func
)
798 def _get_bool_config_skip_if_decorator(key
):
799 config
= lldb
.SBDebugger
.GetBuildConfiguration()
800 value_node
= config
.GetValueForKey(key
)
801 fail_value
= True # More likely to notice if something goes wrong
802 have
= value_node
.GetValueForKey("value").GetBooleanValue(fail_value
)
803 return unittest2
.skipIf(not have
, "requires " + key
)
805 def skipIfCursesSupportMissing(func
):
806 return _get_bool_config_skip_if_decorator("curses")(func
)
808 def skipIfXmlSupportMissing(func
):
809 return _get_bool_config_skip_if_decorator("xml")(func
)
811 def skipIfEditlineSupportMissing(func
):
812 return _get_bool_config_skip_if_decorator("editline")(func
)
814 def skipIfLLVMTargetMissing(target
):
815 config
= lldb
.SBDebugger
.GetBuildConfiguration()
816 targets
= config
.GetValueForKey("targets").GetValueForKey("value")
818 for i
in range(targets
.GetSize()):
819 if targets
.GetItemAtIndex(i
).GetStringValue(99) == target
:
823 return unittest2
.skipIf(not found
, "requires " + target
)
825 # Call sysctl on darwin to see if a specified hardware feature is available on this machine.
826 def skipUnlessFeature(feature
):
827 def is_feature_enabled(self
):
828 if platform
.system() == 'Darwin':
830 DEVNULL
= open(os
.devnull
, 'w')
831 output
= subprocess
.check_output(["/usr/sbin/sysctl", feature
], stderr
=DEVNULL
).decode("utf-8")
832 # If 'feature: 1' was output, then this feature is available and
833 # the test should not be skipped.
834 if re
.match('%s: 1\s*' % feature
, output
):
837 return "%s is not supported on this system." % feature
838 except subprocess
.CalledProcessError
:
839 return "%s is not supported on this system." % feature
840 return skipTestIfFn(is_feature_enabled
)
842 def skipIfAsan(func
):
843 """Skip this test if the environment is set up to run LLDB itself under ASAN."""
845 if ('ASAN_OPTIONS' in os
.environ
):
846 return "ASAN unsupported"
848 return skipTestIfFn(is_asan
)(func
)