summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test/lldbtest.py
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test/lldbtest.py')
-rw-r--r--lldb/packages/Python/lldbsuite/test/lldbtest.py277
1 files changed, 30 insertions, 247 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 6847935034c..1f66df1f4b8 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -37,7 +37,6 @@ from __future__ import absolute_import
# System modules
import abc
import collections
-from distutils.version import LooseVersion
import gc
import glob
import inspect
@@ -60,11 +59,13 @@ import six
import use_lldb_suite
import lldb
from . import configuration
+from . import decorators
from . import lldbplatformutil
from . import lldbtest_config
from . import lldbutil
from . import test_categories
from lldbsuite.support import encoded_file
+from lldbsuite.support import funcutils
from .result_formatter import EventBuilder
@@ -440,43 +441,9 @@ def builder_module():
return __import__("builder_netbsd")
return __import__("builder_" + sys.platform)
-def does_function_require_self(func):
- import inspect
- func_argc = len(inspect.getargspec(func).args)
- if func_argc == 0 or (getattr(func,'im_self',None) is not None) or (hasattr(func, '__self__')):
- return False
- else:
- return True
-
-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
-
- op_lookup = {
- "==": fn_eq,
- "=": fn_eq,
- "!=": fn_neq,
- "<>": fn_neq,
- ">": fn_greater,
- "<": 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))
-
#
# Decorators for categorizing test cases.
#
-class DecorateMode:
- Skip, Xfail = range(2)
-
from functools import wraps
def skip_for_android(reason, api_levels, archs):
@@ -504,7 +471,7 @@ def benchmarks_test(func):
return "benchmarks test"
# Mark this function as such to separate them from the regular tests.
- result = skipTestIfFn(should_skip_benchmarks_test)(func)
+ result = decorators.skipTestIfFn(should_skip_benchmarks_test)(func)
result.__benchmarks_test__ = True
return result
@@ -525,48 +492,19 @@ 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)
+ return decorators.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)
+ return decorators.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 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")
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- xfail_reason = expected_fn(self)
- if xfail_reason is not None:
- if configuration.results_formatter_object is not None:
- # Mark this test as expected to fail.
- configuration.results_formatter_object.handle_event(
- EventBuilder.event_for_mark_test_expected_failure(self))
- xfail_func = unittest2.expectedFailure(func)
- xfail_func(*args, **kwargs)
- else:
- func(*args, **kwargs)
- return wrapper
- # 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 "which syntax was the original
- # function decorated with?"
- if six.callable(bugnumber):
- return expectedFailure_impl(bugnumber)
- else:
- return expectedFailure_impl
+ return decorators.skipTestIfFn(is_remote)(func)
# You can also pass not_in(list) to reverse the sense of the test for the arguments that
# are simple lists, namely oslist, compiler, and debug_info.
@@ -574,19 +512,6 @@ def expectedFailure(expected_fn, bugnumber=None):
def not_in(iterable):
return lambda x : x not in iterable
-def check_list_or_lambda(list_or_lambda, value):
- if six.callable(list_or_lambda):
- return list_or_lambda(value)
- elif isinstance(list_or_lambda, list):
- for item in list_or_lambda:
- if value in item:
- return True
- return False
- elif isinstance(list_or_lambda, str):
- return value is None or value in list_or_lambda
- else:
- return list_or_lambda is None or value is None or list_or_lambda == value
-
def matchArchitectures(archs, actual_arch):
retype = type(re.compile('hello, world'))
list_passes = isinstance(archs, list) and actual_arch in archs
@@ -595,41 +520,19 @@ def matchArchitectures(archs, actual_arch):
return (list_passes or basestring_passes or regex_passes)
-# provide a function to xfail on defined oslist, compiler version, and archs
-# if none is specified for any argument, that argument won't be checked and thus means for all
-# for example,
-# @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,
- 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)
-
def expectedFailureDwarf(bugnumber=None):
- return expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
+ return decorators.expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
def expectedFailureDwo(bugnumber=None):
- return expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
+ return decorators.expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
def expectedFailureDsym(bugnumber=None):
- return expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
+ return decorators.expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
if compiler_version is None:
compiler_version=['=', None]
- return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
+ return decorators.expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
# to XFAIL a specific clang versions, try this
# @expectedFailureClang('bugnumber', ['<=', '3.4'])
@@ -643,7 +546,7 @@ def expectedFailureIcc(bugnumber=None):
return expectedFailureCompiler('icc', None, bugnumber)
def expectedFailureArch(arch, bugnumber=None):
- return decorateTest(DecorateMode.Xfail, archs=arch, bugnumber=bugnumber)
+ return decorators.expectedFailureAll(archs=arch, bugnumber=bugnumber)
def expectedFailurei386(bugnumber=None):
return expectedFailureArch('i386', bugnumber)
@@ -652,10 +555,10 @@ def expectedFailurex86_64(bugnumber=None):
return expectedFailureArch('x86_64', bugnumber)
def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None, archs=None):
- return decorateTest(DecorateMode.Xfail, oslist=oslist, bugnumber=bugnumber, compiler=compilers, archs=archs, debug_info=debug_info)
+ return decorators.expectedFailureAll(oslist=oslist, bugnumber=bugnumber, compiler=compilers, archs=archs, debug_info=debug_info)
def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
- return decorateTest(DecorateMode.Xfail, hostoslist=oslist, bugnumber=bugnumber)
+ return decorators.expectedFailureAll(hostoslist=oslist, bugnumber=bugnumber)
def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
# For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
@@ -686,7 +589,7 @@ 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 decorators.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.
@@ -764,13 +667,13 @@ def skipIfRemote(func):
"""Decorate the item to skip tests if testing remotely."""
def is_remote():
return "skip on remote platform" if lldb.remote_platform else None
- return skipTestIfFn(is_remote)(func)
+ return decorators.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)
+ return decorators.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."""
@@ -784,13 +687,13 @@ def skipIfNoSBHeaders(func):
return "skip because LLDB.h header not found"
return None
- return skipTestIfFn(are_sb_headers_missing)(func)
+ return decorators.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)
+ return decorators.skipTestIfFn(is_ios_simulator)(func)
def skipIfFreeBSD(func):
"""Decorate the item to skip tests that should be skipped on FreeBSD."""
@@ -849,7 +752,7 @@ def skipUnlessGoInstalled(func):
return "skipping because available version ({}) does not meet minimum required version ({})".format(
compiler_strict_version, min_strict_version)
return None
- return skipTestIfFn(is_go_missing)(func)
+ return decorators.skipTestIfFn(is_go_missing)(func)
def getPlatform():
"""Returns the target platform which the tests are running on."""
@@ -860,22 +763,6 @@ def getPlatform():
platform = 'netbsd'
return platform
-def getHostPlatform():
- """Returns the host platform running the test suite."""
- # Attempts to return a platform name matching a target Triple platform.
- if sys.platform.startswith('linux'):
- return 'linux'
- elif sys.platform.startswith('win32'):
- return 'windows'
- elif sys.platform.startswith('darwin'):
- return 'darwin'
- elif sys.platform.startswith('freebsd'):
- return 'freebsd'
- elif sys.platform.startswith('netbsd'):
- return 'netbsd'
- else:
- return sys.platform
-
def platformIsDarwin():
"""Returns true if the OS triple for the selected platform is any valid apple OS"""
return getPlatform() in getDarwinOSTriples()
@@ -884,7 +771,7 @@ 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 = getHostPlatform()
+ 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:
@@ -892,15 +779,15 @@ def skipIfHostIncompatibleWithRemote(func):
elif target_platform != host_platform:
return "skipping because target is %s but host is %s" % (target_platform, host_platform)
return None
- return skipTestIfFn(is_host_incompatible_with_remote)(func)
+ return decorators.skipTestIfFn(is_host_incompatible_with_remote)(func)
def skipIfHostPlatform(oslist):
"""Decorate the item to skip tests if running on one of the listed host platforms."""
- return skipIf(hostoslist=oslist)
+ return decorators.skipIf(hostoslist=oslist)
def skipUnlessHostPlatform(oslist):
"""Decorate the item to skip tests unless running on one of the listed host platforms."""
- return skipIf(hostoslist=not_in(oslist))
+ return decorators.skipIf(hostoslist=not_in(oslist))
def skipUnlessArch(archs):
"""Decorate the item to skip tests unless running on one of the listed architectures."""
@@ -935,85 +822,9 @@ def skipUnlessPlatform(oslist):
return unittest2.skipUnless(getPlatform() in oslist,
"requires on of %s" % (", ".join(oslist)))
-# provide a function to skip on defined oslist, compiler version, and archs
-# if none is specified for any argument, that argument won't be checked and thus means for all
-# for example,
-# @skipIf, skip for all platform/compiler/arch,
-# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
-# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
-
-# TODO: refactor current code, to make skipIfxxx functions to call this function
-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):
- def fn(self):
- skip_for_os = check_list_or_lambda(oslist, self.getPlatform())
- skip_for_hostos = check_list_or_lambda(hostoslist, getHostPlatform())
- skip_for_compiler = check_list_or_lambda(self.getCompiler(), compiler) and self.expectedCompilerVersion(compiler_version)
- skip_for_arch = check_list_or_lambda(archs, self.getArchitecture())
- skip_for_debug_info = check_list_or_lambda(debug_info, self.debug_info)
- skip_for_triple = triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())
- 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_remote = (remote is None) or (remote == (lldb.remote_platform is not None))
-
- # 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
- # the final test if all conditions are True.
- conditions = [(oslist, skip_for_os, "target o/s"),
- (hostoslist, skip_for_hostos, "host o/s"),
- (compiler, skip_for_compiler, "compiler or version"),
- (archs, skip_for_arch, "architecture"),
- (debug_info, skip_for_debug_info, "debug info format"),
- (triple, skip_for_triple, "target triple"),
- (swig_version, skip_for_swig_version, "swig version"),
- (py_version, skip_for_py_version, "python version"),
- (remote, skip_for_remote, "platform locality (remote/local)")]
- reasons = []
- final_skip_result = True
- for this_condition in conditions:
- final_skip_result = final_skip_result and this_condition[1]
- if this_condition[0] is not None and this_condition[1]:
- reasons.append(this_condition[2])
- reason_str = None
- if final_skip_result:
- 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)
- else:
- reason_str = "{} unconditionally"
- return reason_str
-
- if mode == DecorateMode.Skip:
- return skipTestIfFn(fn, bugnumber)
- elif mode == DecorateMode.Xfail:
- return expectedFailure(fn, bugnumber)
- else:
- return None
-
-def skipIf(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):
- 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)
def skipIfDebugInfo(bugnumber=None, debug_info=None):
- return skipIf(bugnumber=bugnumber, debug_info=debug_info)
+ return decorators.skipIf(bugnumber=bugnumber, debug_info=debug_info)
def skipIfDWO(bugnumber=None):
return skipIfDebugInfo(bugnumber, ["dwo"])
@@ -1024,45 +835,17 @@ def skipIfDwarf(bugnumber=None):
def skipIfDsym(bugnumber=None):
return skipIfDebugInfo(bugnumber, ["dsym"])
-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")
-
- @wraps(func)
- def wrapper(*args, **kwargs):
- from unittest2 import case
- self = args[0]
- if does_function_require_self(expected_fn):
- reason = expected_fn(self)
- else:
- reason = expected_fn()
- if reason is not None:
- self.skipTest(reason)
- else:
- func(*args, **kwargs)
- return wrapper
-
- # 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"
- if six.callable(bugnumber):
- return skipTestIfFn_impl(bugnumber)
- else:
- return skipTestIfFn_impl
-
def skipIfGcc(func):
"""Decorate the item to skip tests that should be skipped if building with gcc ."""
- return skipIf(compiler="gcc")(func)
+ return decorators.skipIf(compiler="gcc")(func)
def skipIfIcc(func):
"""Decorate the item to skip tests that should be skipped if building with icc ."""
- return skipIf(compiler="icc")(func)
+ return decorators.skipIf(compiler="icc")(func)
def skipIfi386(func):
"""Decorate the item to skip tests that should be skipped if building 32-bit."""
- return skipIf(archs="i386")(func)
+ return decorators.skipIf(archs="i386")(func)
def skipIfTargetAndroid(api_levels=None, archs=None):
"""Decorator to skip tests when the target is Android.
@@ -1073,14 +856,14 @@ 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 decorators.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)
+ return decorators.skipTestIfFn(is_compiler_rt_missing)(func)
class _PlatformContext(object):
"""Value object class which contains platform-specific options."""
@@ -1509,7 +1292,7 @@ class Base(unittest2.TestCase):
for hook in reversed(self.hooks):
with recording(self, traceAlways) as sbuf:
print("Executing tearDown hook:", getsource_if_available(hook), file=sbuf)
- if does_function_require_self(hook):
+ if funcutils.requires_self(hook):
hook(self)
else:
hook() # try the plain call and hope it works
OpenPOWER on IntegriCloud