aboutsummaryrefslogtreecommitdiff
path: root/packages/Python/lldbsuite/test/decorators.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/Python/lldbsuite/test/decorators.py')
-rw-r--r--packages/Python/lldbsuite/test/decorators.py334
1 files changed, 255 insertions, 79 deletions
diff --git a/packages/Python/lldbsuite/test/decorators.py b/packages/Python/lldbsuite/test/decorators.py
index 93e48272c5d3..866923607867 100644
--- a/packages/Python/lldbsuite/test/decorators.py
+++ b/packages/Python/lldbsuite/test/decorators.py
@@ -5,6 +5,7 @@ from __future__ import print_function
from distutils.version import LooseVersion, StrictVersion
from functools import wraps
import os
+import platform
import re
import sys
import tempfile
@@ -24,24 +25,33 @@ from lldbsuite.support import funcutils
from lldbsuite.test import lldbplatform
from lldbsuite.test import lldbplatformutil
+
class DecorateMode:
Skip, Xfail = range(2)
-
+
# You can use no_match to reverse the test of the conditional that is used to match keyword
# arguments in the skip / xfail decorators. If oslist=["windows", "linux"] skips windows
-# and linux, oslist=no_match(["windows", "linux"]) skips *unless* windows or linux.
+# and linux, oslist=no_match(["windows", "linux"]) skips *unless* windows
+# or linux.
class no_match:
+
def __init__(self, item):
self.item = item
+
def _check_expected_version(comparison, expected, actual):
- def fn_leq(x,y): return x <= y
- def fn_less(x,y): return x < y
- def fn_geq(x,y): return x >= y
- def fn_greater(x,y): return x > y
- def fn_eq(x,y): return x == y
- def fn_neq(x,y): return x != y
+ def fn_leq(x, y): return x <= y
+
+ def fn_less(x, y): return x < y
+
+ def fn_geq(x, y): return x >= y
+
+ def fn_greater(x, y): return x > y
+
+ def fn_eq(x, y): return x == y
+
+ def fn_neq(x, y): return x != y
op_lookup = {
"==": fn_eq,
@@ -52,11 +62,14 @@ def _check_expected_version(comparison, expected, actual):
"<": fn_less,
">=": fn_geq,
"<=": fn_leq
- }
+ }
expected_str = '.'.join([str(x) for x in expected])
actual_str = '.'.join([str(x) for x in actual])
- return op_lookup[comparison](LooseVersion(actual_str), LooseVersion(expected_str))
+ return op_lookup[comparison](
+ LooseVersion(actual_str),
+ LooseVersion(expected_str))
+
def _match_decorator_property(expected, actual):
if actual is None or expected is None:
@@ -64,17 +77,21 @@ def _match_decorator_property(expected, actual):
if isinstance(expected, no_match):
return not _match_decorator_property(expected.item, actual)
- elif isinstance(expected, (re._pattern_type,)+six.string_types):
+ elif isinstance(expected, (re._pattern_type,) + six.string_types):
return re.search(expected, actual) is not None
elif hasattr(expected, "__iter__"):
- return any([x is not None and _match_decorator_property(x, actual) for x in expected])
+ return any([x is not None and _match_decorator_property(x, actual)
+ for x in expected])
else:
return expected == actual
+
def expectedFailure(expected_fn, bugnumber=None):
def expectedFailure_impl(func):
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("Decorator can only be used to decorate a test method")
+ raise Exception(
+ "Decorator can only be used to decorate a test method")
+
@wraps(func)
def wrapper(*args, **kwargs):
self = args[0]
@@ -102,10 +119,12 @@ def expectedFailure(expected_fn, bugnumber=None):
else:
return expectedFailure_impl
+
def skipTestIfFn(expected_fn, bugnumber=None):
def skipTestIfFn_impl(func):
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@skipTestIfFn can only be used to decorate a test method")
+ raise Exception(
+ "@skipTestIfFn can only be used to decorate a test method")
@wraps(func)
def wrapper(*args, **kwargs):
@@ -116,7 +135,7 @@ def skipTestIfFn(expected_fn, bugnumber=None):
reason = expected_fn()
if reason is not None:
- self.skipTest(reason)
+ self.skipTest(reason)
else:
func(*args, **kwargs)
return wrapper
@@ -124,30 +143,56 @@ def skipTestIfFn(expected_fn, bugnumber=None):
# Some decorators can be called both with no arguments (e.g. @expectedFailureWindows)
# or with arguments (e.g. @expectedFailureWindows(compilers=['gcc'])). When called
# the first way, the first argument will be the actual function because decorators are
- # weird like that. So this is basically a check that says "how was the decorator used"
+ # weird like that. So this is basically a check that says "how was the
+ # decorator used"
if six.callable(bugnumber):
return skipTestIfFn_impl(bugnumber)
else:
return skipTestIfFn_impl
+
def _decorateTest(mode,
- bugnumber=None, oslist=None, hostoslist=None,
- compiler=None, compiler_version=None,
- archs=None, triple=None,
- debug_info=None,
- swig_version=None, py_version=None,
- remote=None):
+ bugnumber=None, oslist=None, hostoslist=None,
+ compiler=None, compiler_version=None,
+ archs=None, triple=None,
+ debug_info=None,
+ swig_version=None, py_version=None,
+ macos_version=None,
+ remote=None):
def fn(self):
- skip_for_os = _match_decorator_property(lldbplatform.translate(oslist), self.getPlatform())
- skip_for_hostos = _match_decorator_property(lldbplatform.translate(hostoslist), lldbplatformutil.getHostPlatform())
- skip_for_compiler = _match_decorator_property(compiler, self.getCompiler()) and self.expectedCompilerVersion(compiler_version)
- skip_for_arch = _match_decorator_property(archs, self.getArchitecture())
- skip_for_debug_info = _match_decorator_property(debug_info, self.debug_info)
- skip_for_triple = _match_decorator_property(triple, lldb.DBG.GetSelectedPlatform().GetTriple())
- skip_for_remote = _match_decorator_property(remote, lldb.remote_platform is not None)
-
- skip_for_swig_version = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (_check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
- skip_for_py_version = (py_version is None) or _check_expected_version(py_version[0], py_version[1], sys.version_info)
+ skip_for_os = _match_decorator_property(
+ lldbplatform.translate(oslist), self.getPlatform())
+ skip_for_hostos = _match_decorator_property(
+ lldbplatform.translate(hostoslist),
+ lldbplatformutil.getHostPlatform())
+ skip_for_compiler = _match_decorator_property(
+ compiler, self.getCompiler()) and self.expectedCompilerVersion(compiler_version)
+ skip_for_arch = _match_decorator_property(
+ archs, self.getArchitecture())
+ skip_for_debug_info = _match_decorator_property(
+ debug_info, self.debug_info)
+ skip_for_triple = _match_decorator_property(
+ triple, lldb.DBG.GetSelectedPlatform().GetTriple())
+ skip_for_remote = _match_decorator_property(
+ remote, lldb.remote_platform is not None)
+
+ skip_for_swig_version = (
+ swig_version is None) or (
+ not hasattr(
+ lldb,
+ 'swig_version')) or (
+ _check_expected_version(
+ swig_version[0],
+ swig_version[1],
+ lldb.swig_version))
+ skip_for_py_version = (
+ py_version is None) or _check_expected_version(
+ py_version[0], py_version[1], sys.version_info)
+ skip_for_macos_version = (macos_version is None) or (
+ _check_expected_version(
+ macos_version[0],
+ macos_version[1],
+ platform.mac_ver()[0]))
# For the test to be skipped, all specified (e.g. not None) parameters must be True.
# An unspecified parameter means "any", so those are marked skip by default. And we skip
@@ -160,6 +205,7 @@ def _decorateTest(mode,
(triple, skip_for_triple, "target triple"),
(swig_version, skip_for_swig_version, "swig version"),
(py_version, skip_for_py_version, "python version"),
+ (macos_version, skip_for_macos_version, "macOS version"),
(remote, skip_for_remote, "platform locality (remote/local)")]
reasons = []
final_skip_result = True
@@ -169,10 +215,13 @@ def _decorateTest(mode,
reasons.append(this_condition[2])
reason_str = None
if final_skip_result:
- mode_str = {DecorateMode.Skip : "skipping", DecorateMode.Xfail : "xfailing"}[mode]
+ mode_str = {
+ DecorateMode.Skip: "skipping",
+ DecorateMode.Xfail: "xfailing"}[mode]
if len(reasons) > 0:
reason_str = ",".join(reasons)
- reason_str = "{} due to the following parameter(s): {}".format(mode_str, reason_str)
+ reason_str = "{} due to the following parameter(s): {}".format(
+ mode_str, reason_str)
else:
reason_str = "{} unconditionally"
if bugnumber is not None and not six.callable(bugnumber):
@@ -192,21 +241,25 @@ def _decorateTest(mode,
# @expectedFailureAll, xfail for all platform/compiler/arch,
# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
+
+
def expectedFailureAll(bugnumber=None,
oslist=None, hostoslist=None,
compiler=None, compiler_version=None,
archs=None, triple=None,
debug_info=None,
swig_version=None, py_version=None,
+ macos_version=None,
remote=None):
return _decorateTest(DecorateMode.Xfail,
- bugnumber=bugnumber,
- oslist=oslist, hostoslist=hostoslist,
- compiler=compiler, compiler_version=compiler_version,
- archs=archs, triple=triple,
- debug_info=debug_info,
- swig_version=swig_version, py_version=py_version,
- remote=remote)
+ bugnumber=bugnumber,
+ oslist=oslist, hostoslist=hostoslist,
+ compiler=compiler, compiler_version=compiler_version,
+ archs=archs, triple=triple,
+ debug_info=debug_info,
+ swig_version=swig_version, py_version=py_version,
+ macos_version=None,
+ remote=remote)
# provide a function to skip on defined oslist, compiler version, and archs
@@ -221,28 +274,35 @@ def skipIf(bugnumber=None,
archs=None, triple=None,
debug_info=None,
swig_version=None, py_version=None,
+ macos_version=None,
remote=None):
return _decorateTest(DecorateMode.Skip,
- bugnumber=bugnumber,
- oslist=oslist, hostoslist=hostoslist,
- compiler=compiler, compiler_version=compiler_version,
- archs=archs, triple=triple,
- debug_info=debug_info,
- swig_version=swig_version, py_version=py_version,
- remote=remote)
+ bugnumber=bugnumber,
+ oslist=oslist, hostoslist=hostoslist,
+ compiler=compiler, compiler_version=compiler_version,
+ archs=archs, triple=triple,
+ debug_info=debug_info,
+ swig_version=swig_version, py_version=py_version,
+ macos_version=macos_version,
+ remote=remote)
+
def _skip_for_android(reason, api_levels, archs):
def impl(obj):
- result = lldbplatformutil.match_android_device(obj.getArchitecture(), valid_archs=archs, valid_api_levels=api_levels)
+ result = lldbplatformutil.match_android_device(
+ obj.getArchitecture(), valid_archs=archs, valid_api_levels=api_levels)
return reason if result else None
return impl
+
def add_test_categories(cat):
"""Add test categories to a TestCase method"""
cat = test_categories.validate(cat, True)
+
def impl(func):
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@add_test_categories can only be used to decorate a test method")
+ raise Exception(
+ "@add_test_categories can only be used to decorate a test method")
if hasattr(func, "categories"):
cat.extend(func.categories)
func.categories = cat
@@ -250,6 +310,7 @@ def add_test_categories(cat):
return impl
+
def benchmarks_test(func):
"""Decorate the item as a benchmarks test."""
def should_skip_benchmarks_test():
@@ -260,11 +321,14 @@ def benchmarks_test(func):
result.__benchmarks_test__ = True
return result
+
def no_debug_info_test(func):
"""Decorate the item as a test what don't use any debug info. If this annotation is specified
then the test runner won't generate a separate test for each debug info format. """
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@no_debug_info_test can only be used to decorate a test method")
+ raise Exception(
+ "@no_debug_info_test can only be used to decorate a test method")
+
@wraps(func)
def wrapper(self, *args, **kwargs):
return func(self, *args, **kwargs)
@@ -273,30 +337,51 @@ def no_debug_info_test(func):
wrapper.__no_debug_info_test__ = True
return wrapper
+
def debugserver_test(func):
"""Decorate the item as a debugserver test."""
def should_skip_debugserver_test():
return "debugserver tests" if configuration.dont_do_debugserver_test else None
return skipTestIfFn(should_skip_debugserver_test)(func)
+
def llgs_test(func):
"""Decorate the item as a lldb-server test."""
def should_skip_llgs_tests():
return "llgs tests" if configuration.dont_do_llgs_test else None
return skipTestIfFn(should_skip_llgs_tests)(func)
+
def not_remote_testsuite_ready(func):
"""Decorate the item as a test which is not ready yet for remote testsuite."""
def is_remote():
return "Not ready for remote testsuite" if lldb.remote_platform else None
return skipTestIfFn(is_remote)(func)
-def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None, archs=None):
- return expectedFailureAll(oslist=oslist, bugnumber=bugnumber, compiler=compilers, archs=archs, debug_info=debug_info)
+
+def expectedFailureOS(
+ oslist,
+ bugnumber=None,
+ compilers=None,
+ debug_info=None,
+ archs=None):
+ return expectedFailureAll(
+ oslist=oslist,
+ bugnumber=bugnumber,
+ compiler=compilers,
+ archs=archs,
+ debug_info=debug_info)
+
def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
- # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
- return expectedFailureOS(lldbplatform.darwin_all, bugnumber, compilers, debug_info=debug_info)
+ # For legacy reasons, we support both "darwin" and "macosx" as OS X
+ # triples.
+ return expectedFailureOS(
+ lldbplatform.darwin_all,
+ bugnumber,
+ compilers,
+ debug_info=debug_info)
+
def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
""" Mark a test as xfail for Android.
@@ -308,10 +393,17 @@ def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
arch - A sequence of architecture names specifying the architectures
for which a test is expected to fail. None means all architectures.
"""
- return expectedFailure(_skip_for_android("xfailing on android", api_levels, archs), bugnumber)
+ return expectedFailure(
+ _skip_for_android(
+ "xfailing on android",
+ api_levels,
+ archs),
+ bugnumber)
# Flakey tests get two chances to run. If they fail the first time round, the result formatter
# makes sure it is run one more time.
+
+
def expectedFlakey(expected_fn, bugnumber=None):
def expectedFailure_impl(func):
@wraps(func)
@@ -335,52 +427,76 @@ def expectedFlakey(expected_fn, bugnumber=None):
else:
return expectedFailure_impl
+
def expectedFlakeyDwarf(bugnumber=None):
def fn(self):
return self.debug_info == "dwarf"
return expectedFlakey(fn, bugnumber)
+
def expectedFlakeyDsym(bugnumber=None):
def fn(self):
return self.debug_info == "dwarf"
return expectedFlakey(fn, bugnumber)
+
def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
def fn(self):
return (self.getPlatform() in oslist and
self.expectedCompiler(compilers))
return expectedFlakey(fn, bugnumber)
+
def expectedFlakeyDarwin(bugnumber=None, compilers=None):
- # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
- return expectedFlakeyOS(lldbplatformutil.getDarwinOSTriples(), bugnumber, compilers)
+ # For legacy reasons, we support both "darwin" and "macosx" as OS X
+ # triples.
+ return expectedFlakeyOS(
+ lldbplatformutil.getDarwinOSTriples(),
+ bugnumber,
+ compilers)
+
def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
+
def expectedFlakeyLinux(bugnumber=None, compilers=None):
return expectedFlakeyOS(['linux'], bugnumber, compilers)
+
def expectedFlakeyNetBSD(bugnumber=None, compilers=None):
return expectedFlakeyOS(['netbsd'], bugnumber, compilers)
+
def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
if compiler_version is None:
- compiler_version=['=', None]
+ compiler_version = ['=', None]
+
def fn(self):
return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
return expectedFlakey(fn, bugnumber)
# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
+
+
def expectedFlakeyClang(bugnumber=None, compiler_version=None):
return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
+
+
def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
+
def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
- return expectedFlakey(_skip_for_android("flakey on android", api_levels, archs), bugnumber)
+ return expectedFlakey(
+ _skip_for_android(
+ "flakey on android",
+ api_levels,
+ archs),
+ bugnumber)
+
def skipIfRemote(func):
"""Decorate the item to skip tests if testing remotely."""
@@ -388,61 +504,88 @@ def skipIfRemote(func):
return "skip on remote platform" if lldb.remote_platform else None
return skipTestIfFn(is_remote)(func)
+
def skipIfRemoteDueToDeadlock(func):
"""Decorate the item to skip tests if testing remotely due to the test deadlocking."""
def is_remote():
return "skip on remote platform (deadlocks)" if lldb.remote_platform else None
return skipTestIfFn(is_remote)(func)
+
def skipIfNoSBHeaders(func):
"""Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
def are_sb_headers_missing():
if lldbplatformutil.getHostPlatform() == 'darwin':
- header = os.path.join(os.environ["LLDB_LIB_DIR"], 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
- else:
- header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
+ header = os.path.join(
+ os.environ["LLDB_LIB_DIR"],
+ 'LLDB.framework',
+ 'Versions',
+ 'Current',
+ 'Headers',
+ 'LLDB.h')
+ if os.path.exists(header):
+ return None
+
+ header = os.path.join(
+ os.environ["LLDB_SRC"],
+ "include",
+ "lldb",
+ "API",
+ "LLDB.h")
if not os.path.exists(header):
return "skip because LLDB.h header not found"
return None
return skipTestIfFn(are_sb_headers_missing)(func)
+
def skipIfiOSSimulator(func):
"""Decorate the item to skip tests that should be skipped on the iOS Simulator."""
def is_ios_simulator():
return "skip on the iOS Simulator" if configuration.lldb_platform_name == 'ios-simulator' else None
return skipTestIfFn(is_ios_simulator)(func)
+
def skipIfFreeBSD(func):
"""Decorate the item to skip tests that should be skipped on FreeBSD."""
return skipIfPlatform(["freebsd"])(func)
+
def skipIfNetBSD(func):
"""Decorate the item to skip tests that should be skipped on NetBSD."""
return skipIfPlatform(["netbsd"])(func)
+
def skipIfDarwin(func):
"""Decorate the item to skip tests that should be skipped on Darwin."""
- return skipIfPlatform(lldbplatform.translate(lldbplatform.darwin_all))(func)
+ return skipIfPlatform(
+ lldbplatform.translate(
+ lldbplatform.darwin_all))(func)
+
def skipIfLinux(func):
"""Decorate the item to skip tests that should be skipped on Linux."""
return skipIfPlatform(["linux"])(func)
+
def skipIfWindows(func):
"""Decorate the item to skip tests that should be skipped on Windows."""
return skipIfPlatform(["windows"])(func)
+
def skipUnlessWindows(func):
"""Decorate the item to skip tests that should be skipped on any non-Windows platform."""
return skipUnlessPlatform(["windows"])(func)
+
def skipUnlessDarwin(func):
"""Decorate the item to skip tests that should be skipped on any non Darwin platform."""
return skipUnlessPlatform(lldbplatformutil.getDarwinOSTriples())(func)
+
def skipUnlessGoInstalled(func):
"""Decorate the item to skip tests when no Go compiler is available."""
+
def is_go_missing(self):
compiler = self.getGoCompilerVersion()
if not compiler:
@@ -450,7 +593,8 @@ def skipUnlessGoInstalled(func):
match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
if not match_version:
# Couldn't determine version.
- return "skipping because go version could not be parsed out of {}".format(compiler)
+ return "skipping because go version could not be parsed out of {}".format(
+ compiler)
else:
min_strict_version = StrictVersion("1.4.0")
compiler_strict_version = StrictVersion(match_version.group(1))
@@ -460,20 +604,28 @@ def skipUnlessGoInstalled(func):
return None
return skipTestIfFn(is_go_missing)(func)
+
def skipIfHostIncompatibleWithRemote(func):
"""Decorate the item to skip tests if binaries built on this host are incompatible."""
+
def is_host_incompatible_with_remote(self):
host_arch = self.getLldbArchitecture()
host_platform = lldbplatformutil.getHostPlatform()
target_arch = self.getArchitecture()
target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
- if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
- return "skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch)
- elif target_platform != host_platform:
- return "skipping because target is %s but host is %s" % (target_platform, host_platform)
+ if not (target_arch == 'x86_64' and host_arch ==
+ 'i386') and host_arch != target_arch:
+ return "skipping because target %s is not compatible with host architecture %s" % (
+ target_arch, host_arch)
+ if target_platform != host_platform:
+ return "skipping because target is %s but host is %s" % (
+ target_platform, host_platform)
+ if lldbplatformutil.match_android_device(target_arch):
+ return "skipping because target is android"
return None
return skipTestIfFn(is_host_incompatible_with_remote)(func)
+
def skipIfPlatform(oslist):
"""Decorate the item to skip tests if running on one of the listed platforms."""
# This decorator cannot be ported to `skipIf` yet because it is used on entire
@@ -481,12 +633,14 @@ def skipIfPlatform(oslist):
return unittest2.skipIf(lldbplatformutil.getPlatform() in oslist,
"skip on %s" % (", ".join(oslist)))
+
def skipUnlessPlatform(oslist):
"""Decorate the item to skip tests unless running on one of the listed platforms."""
# This decorator cannot be ported to `skipIf` yet because it is used on entire
# classes, which `skipIf` explicitly forbids.
return unittest2.skipUnless(lldbplatformutil.getPlatform() in oslist,
- "requires on of %s" % (", ".join(oslist)))
+ "requires one of %s" % (", ".join(oslist)))
+
def skipIfTargetAndroid(api_levels=None, archs=None):
"""Decorator to skip tests when the target is Android.
@@ -497,28 +651,50 @@ def skipIfTargetAndroid(api_levels=None, archs=None):
arch - A sequence of architecture names specifying the architectures
for which a test is skipped. None means all architectures.
"""
- return skipTestIfFn(_skip_for_android("skipping for android", api_levels, archs))
+ return skipTestIfFn(
+ _skip_for_android(
+ "skipping for android",
+ api_levels,
+ archs))
-def skipUnlessCompilerRt(func):
- """Decorate the item to skip tests if testing remotely."""
- def is_compiler_rt_missing():
- compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "llvm","projects","compiler-rt")
- return "compiler-rt not found" if not os.path.exists(compilerRtPath) else None
- return skipTestIfFn(is_compiler_rt_missing)(func)
def skipUnlessThreadSanitizer(func):
"""Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
+
def is_compiler_clang_with_thread_sanitizer(self):
compiler_path = self.getCompiler()
compiler = os.path.basename(compiler_path)
if not compiler.startswith("clang"):
return "Test requires clang as compiler"
+ if lldbplatformutil.getPlatform() == 'windows':
+ return "TSAN tests not compatible with 'windows'"
+ # rdar://28659145 - TSAN tests don't look like they're supported on i386
+ if self.getArchitecture() == 'i386' and platform.system() == 'Darwin':
+ return "TSAN tests not compatible with i386 targets"
f = tempfile.NamedTemporaryFile()
cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name)
- if os.popen(cmd).close() != None:
+ if os.popen(cmd).close() is not None:
return None # The compiler cannot compile at all, let's *not* skip the test
cmd = "echo 'int main() {}' | %s -fsanitize=thread -x c -o %s -" % (compiler_path, f.name)
- if os.popen(cmd).close() != None:
+ if os.popen(cmd).close() is not None:
return "Compiler cannot compile with -fsanitize=thread"
return None
return skipTestIfFn(is_compiler_clang_with_thread_sanitizer)(func)
+
+def skipUnlessAddressSanitizer(func):
+ """Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
+
+ def is_compiler_with_address_sanitizer(self):
+ compiler_path = self.getCompiler()
+ compiler = os.path.basename(compiler_path)
+ f = tempfile.NamedTemporaryFile()
+ if lldbplatformutil.getPlatform() == 'windows':
+ return "ASAN tests not compatible with 'windows'"
+ cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name)
+ if os.popen(cmd).close() is not None:
+ return None # The compiler cannot compile at all, let's *not* skip the test
+ cmd = "echo 'int main() {}' | %s -fsanitize=address -x c -o %s -" % (compiler_path, f.name)
+ if os.popen(cmd).close() is not None:
+ return "Compiler cannot compile with -fsanitize=address"
+ return None
+ return skipTestIfFn(is_compiler_with_address_sanitizer)(func)