Move some of the common decorators to decorators.py.

This doesn't attempt to move every decorator.  The reason for
this is that it requires touching every single test file to import
decorators.py.  I would like to do this in a followup patch, but
in the interest of keeping the patches as bite-sized as possible,
I've only attempted to move the underlying common decorators first.
A few tests call these directly, so those tests are updated as part
of this patch.

llvm-svn: 259807
This commit is contained in:
Zachary Turner
2016-02-04 18:03:01 +00:00
parent a4859dfa46
commit 7a5382de82
34 changed files with 347 additions and 278 deletions

View File

@@ -0,0 +1,16 @@
from __future__ import print_function
from __future__ import absolute_import
# System modules
import inspect
# Third-party modules
# LLDB modules
def requires_self(func):
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

View File

@@ -6,8 +6,9 @@ from __future__ import print_function
import os, re
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
import subprocess
class SBBreakpointCallbackCase(TestBase):

View File

@@ -0,0 +1,220 @@
from __future__ import print_function
from __future__ import absolute_import
# System modules
from distutils.version import LooseVersion
from functools import wraps
import re
import sys
# Third-party modules
import six
import unittest2
# LLDB modules
import use_lldb_suite
import lldb
from . import configuration
from .result_formatter import EventBuilder
from lldbsuite.support import funcutils
from lldbsuite.test import lldbplatformutil
class DecorateMode:
Skip, Xfail = range(2)
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))
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 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]
if funcutils.requires_self(expected_fn):
xfail_reason = expected_fn(self)
else:
xfail_reason = expected_fn()
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
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 funcutils.requires_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 _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, lldbplatformutil.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
# 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)
# 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
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)

View File

@@ -3,8 +3,9 @@ from __future__ import print_function
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ExprCharTestCase(TestBase):

View File

@@ -1,6 +1,10 @@
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class TestMacros(TestBase):

View File

@@ -7,8 +7,9 @@ from __future__ import print_function
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class PersistObjCPointeeType(TestBase):

View File

@@ -8,8 +8,9 @@ from __future__ import print_function
import os
import lldb
from lldbsuite.test import lldbutil
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
def python_leaky_fd_version(test):

View File

@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class BreakpointLocationsTestCase(TestBase):

View File

@@ -6,8 +6,9 @@ from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class DebugBreakTestCase(TestBase):

View File

@@ -8,8 +8,9 @@ from __future__ import print_function
import os, time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class VectorTypesFormattingTestCase(TestBase):

View File

@@ -2,13 +2,12 @@
from __future__ import print_function
import unittest2
import os
import lldb
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
import re

View File

@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
@skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently
class LoadUnloadTestCase(TestBase):

View File

@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ReturnValueTestCase(TestBase):

View File

@@ -17,8 +17,9 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
@skipIfWindows
class ConcurrentEventsTestCase(TestBase):

View File

@@ -8,8 +8,9 @@ from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class CreateDuringStepTestCase(TestBase):

View File

@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class HelloWatchLocationTestCase(TestBase):

View File

@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class ConstVariableTestCase(TestBase):

View File

@@ -3,8 +3,9 @@
from __future__ import print_function
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class GlobalVariablesTestCase(TestBase):

View File

@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class RegisterVariableTestCase(TestBase):

View File

@@ -6,8 +6,9 @@ from __future__ import print_function
import os, time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class TypedefTestCase(TestBase):

View File

@@ -2,8 +2,9 @@
Tests that auto types work
"""
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class CPPAutoTestCase(TestBase):

View File

@@ -1,6 +1,7 @@
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class TestWithLimitDebugInfo(TestBase):

View File

@@ -7,8 +7,9 @@ from __future__ import print_function
import os, time
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
def Msg(expr, val):
return "'expression %s' matches the output (from compiled code): %s" % (expr, val)

View File

@@ -6,13 +6,14 @@ from __future__ import print_function
import unittest2
import os, time
import lldb
import platform
import lldbsuite.test.lldbutil as lldbutil
from distutils.version import StrictVersion
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ObjCNewSyntaxTestCase(TestBase):

View File

@@ -9,8 +9,9 @@ from __future__ import print_function
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class BuiltinTrapTestCase(TestBase):

View File

@@ -6,6 +6,7 @@ from __future__ import absolute_import
# System modules
import re
import subprocess
import sys
# Third-party modules
from six.moves.urllib import parse as urlparse
@@ -85,3 +86,19 @@ def finalize_build_dictionary(dictionary):
if android_device_api() >= 16:
dictionary["PIE"] = 1
return dictionary
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

View File

@@ -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

View File

@@ -18,8 +18,9 @@ from __future__ import print_function
import os, time
import re
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class APIDefaultConstructorTestCase(TestBase):

View File

@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class Disassemble_VST1_64(TestBase):

View File

@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ThreadsStackTracesTestCase(TestBase):

View File

@@ -9,7 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.lldbutil import symbol_type_to_str
class ModuleAndSectionAPIsTestCase(TestBase):

View File

@@ -10,8 +10,9 @@ from __future__ import print_function
import os, time
import re
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ValueAsLinkedListTestCase(TestBase):

View File

@@ -9,8 +9,9 @@ from __future__ import print_function
import os, time
import re
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TargetWatchAddressAPITestCase(TestBase):

View File

@@ -1,8 +1,9 @@
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test import lldbutil
class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):
mydir = TestBase.compute_mydir(__file__)