Commit 5af38295 authored by Michael Arntzenius's avatar Michael Arntzenius

update tester infrastructure to support new CPython tests

parent fd785dc1
...@@ -187,6 +187,8 @@ add_test(NAME check-format COMMAND ${CMAKE_SOURCE_DIR}/tools/check_format.sh ${L ...@@ -187,6 +187,8 @@ add_test(NAME check-format COMMAND ${CMAKE_SOURCE_DIR}/tools/check_format.sh ${L
add_test(NAME gc_unittest COMMAND gc_unittest) add_test(NAME gc_unittest COMMAND gc_unittest)
add_test(NAME analysis_unittest COMMAND analysis_unittest) add_test(NAME analysis_unittest COMMAND analysis_unittest)
add_test(NAME pyston_defaults COMMAND ${PYTHON_EXE} ${CMAKE_SOURCE_DIR}/tools/tester.py -R ./pyston -j${TEST_THREADS} -a=-S -k ${CMAKE_SOURCE_DIR}/test/tests) add_test(NAME pyston_defaults COMMAND ${PYTHON_EXE} ${CMAKE_SOURCE_DIR}/tools/tester.py -R ./pyston -j${TEST_THREADS} -a=-S -k ${CMAKE_SOURCE_DIR}/test/tests)
# we pass -I to cpython tests and skip failing ones b/c they are slooow otherwise
add_test(NAME pyston_defaults_cpython_tests COMMAND ${PYTHON_EXE} ${CMAKE_SOURCE_DIR}/tools/tester.py -R ./pyston -j${TEST_THREADS} -a=-S -a=-I -k --exit-code-only --skip-failing ${CMAKE_SOURCE_DIR}/test/cpython)
add_test(NAME pyston_max_compilation_tier COMMAND ${PYTHON_EXE} ${CMAKE_SOURCE_DIR}/tools/tester.py -R ./pyston -j${TEST_THREADS} -a=-O -a=-S -k ${CMAKE_SOURCE_DIR}/test/tests) add_test(NAME pyston_max_compilation_tier COMMAND ${PYTHON_EXE} ${CMAKE_SOURCE_DIR}/tools/tester.py -R ./pyston -j${TEST_THREADS} -a=-O -a=-S -k ${CMAKE_SOURCE_DIR}/test/tests)
add_test(NAME pyston_experimental_pypa_parser COMMAND ${PYTHON_EXE} ${CMAKE_SOURCE_DIR}/tools/tester.py -a=-x -R ./pyston -j${TEST_THREADS} -a=-n -a=-S -k ${CMAKE_SOURCE_DIR}/test/tests) add_test(NAME pyston_experimental_pypa_parser COMMAND ${PYTHON_EXE} ${CMAKE_SOURCE_DIR}/tools/tester.py -a=-x -R ./pyston -j${TEST_THREADS} -a=-n -a=-S -k ${CMAKE_SOURCE_DIR}/test/tests)
......
...@@ -490,6 +490,8 @@ check: ...@@ -490,6 +490,8 @@ check:
$(MAKE) ext_python ext_pyston pyston_dbg $(MAKE) ext_python ext_pyston pyston_dbg
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_dbg -j$(TEST_THREADS) -k -a=-S $(TESTS_DIR) $(ARGS) $(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_dbg -j$(TEST_THREADS) -k -a=-S $(TESTS_DIR) $(ARGS)
@# we pass -I to cpython tests & skip failing ones because they are sloooow otherwise
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_dbg -j$(TEST_THREADS) -k -a=-S -a=-I --exit-code-only --skip-failing $(TEST_DIR)/cpython $(ARGS)
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_dbg -j$(TEST_THREADS) -k -a=-n -a=-x -a=-S $(TESTS_DIR) $(ARGS) $(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_dbg -j$(TEST_THREADS) -k -a=-n -a=-x -a=-S $(TESTS_DIR) $(ARGS)
@# skip -O for dbg @# skip -O for dbg
...@@ -504,6 +506,8 @@ check: ...@@ -504,6 +506,8 @@ check:
@# It can be useful to test release mode, since it actually exposes different functionality @# It can be useful to test release mode, since it actually exposes different functionality
@# since we can make different decisions about which internal functions to inline or not. @# since we can make different decisions about which internal functions to inline or not.
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_release -j$(TEST_THREADS) -k -a=-S $(TESTS_DIR) $(ARGS) $(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_release -j$(TEST_THREADS) -k -a=-S $(TESTS_DIR) $(ARGS)
@# we pass -I to cpython tests and skip failing ones because they are sloooow otherwise
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_release -j$(TEST_THREADS) -k -a=-S -a=-I --exit-code-only --skip-failing $(TEST_DIR)/cpython $(ARGS)
@# skip -n for dbg @# skip -n for dbg
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_release -j$(TEST_THREADS) -k -a=-O -a=-x -a=-S $(TESTS_DIR) $(ARGS) $(PYTHON) $(TOOLS_DIR)/tester.py -R pyston_release -j$(TEST_THREADS) -k -a=-O -a=-x -a=-S $(TESTS_DIR) $(ARGS)
...@@ -916,7 +920,8 @@ clean: ...@@ -916,7 +920,8 @@ clean:
# ex instead of saying "make tests/run_1", I can just write "make run_1" # ex instead of saying "make tests/run_1", I can just write "make run_1"
define make_search define make_search
$(eval \ $(eval \
$1: $(TEST_DIR)/tests/$1 ; $1: $(TESTS_DIR)/$1 ;
$1: $(TEST_DIR)/cpython/$1 ;
$1: ./microbenchmarks/$1 ; $1: ./microbenchmarks/$1 ;
$1: ./minibenchmarks/$1 ; $1: ./minibenchmarks/$1 ;
$1: ./benchmarks/$1 ; $1: ./benchmarks/$1 ;
...@@ -932,6 +937,8 @@ $(eval \ ...@@ -932,6 +937,8 @@ $(eval \
.PHONY: test$1 check$1 .PHONY: test$1 check$1
check$1 test$1: $(PYTHON_EXE_DEPS) pyston$1 ext_pyston check$1 test$1: $(PYTHON_EXE_DEPS) pyston$1 ext_pyston
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston$1 -j$(TEST_THREADS) -a=-S -k $(TESTS_DIR) $(ARGS) $(PYTHON) $(TOOLS_DIR)/tester.py -R pyston$1 -j$(TEST_THREADS) -a=-S -k $(TESTS_DIR) $(ARGS)
@# we pass -I to cpython tests and skip failing ones because they are sloooow otherwise
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston$1 -j$(TEST_THREADS) -a=-S -a=-I -k --exit-code-only --skip-failing $(TEST_DIR)/cpython $(ARGS)
$(PYTHON) $(TOOLS_DIR)/tester.py -a=-x -R pyston$1 -j$(TEST_THREADS) -a=-n -a=-S -k $(TESTS_DIR) $(ARGS) $(PYTHON) $(TOOLS_DIR)/tester.py -a=-x -R pyston$1 -j$(TEST_THREADS) -a=-n -a=-S -k $(TESTS_DIR) $(ARGS)
$(PYTHON) $(TOOLS_DIR)/tester.py -R pyston$1 -j$(TEST_THREADS) -a=-O -a=-S -k $(TESTS_DIR) $(ARGS) $(PYTHON) $(TOOLS_DIR)/tester.py -R pyston$1 -j$(TEST_THREADS) -a=-O -a=-S -k $(TESTS_DIR) $(ARGS)
......
...@@ -346,25 +346,19 @@ def _is_gui_available(): ...@@ -346,25 +346,19 @@ def _is_gui_available():
def is_resource_enabled(resource): def is_resource_enabled(resource):
"""Test whether a resource is enabled. Known resources are set by """Test whether a resource is enabled. Known resources are set by
regrtest.py.""" regrtest.py."""
# Pyston change: we assume that resources are not available in general
return use_resources is not None and resource in use_resources return use_resources is not None and resource in use_resources
def requires(resource, msg=None): def requires(resource, msg=None):
"""Raise ResourceDenied if the specified resource is not available. """Raise ResourceDenied if the specified resource is not available."""
If the caller's module is __main__ then automatically return True. The
possibility of False being returned occurs when regrtest.py is executing."""
if resource == 'gui' and not _is_gui_available(): if resource == 'gui' and not _is_gui_available():
raise ResourceDenied(_is_gui_available.reason) raise ResourceDenied(_is_gui_available.reason)
# see if the caller's module is __main__ - if so, treat as if # Pyston change: we don't check if the caller's module is __main__ using sys._getframe() magic.
# the resource was set
if sys._getframe(1).f_globals.get("__name__") == "__main__":
return
if not is_resource_enabled(resource): if not is_resource_enabled(resource):
if msg is None: if msg is None:
msg = "Use of the `%s' resource not enabled" % resource msg = "Use of the `%s' resource not enabled" % resource
raise ResourceDenied(msg) raise ResourceDenied(msg)
# Don't use "localhost", since resolving it uses the DNS under recent # Don't use "localhost", since resolving it uses the DNS under recent
# Windows versions (see issue #18792). # Windows versions (see issue #18792).
HOST = "127.0.0.1" HOST = "127.0.0.1"
...@@ -506,6 +500,11 @@ try: ...@@ -506,6 +500,11 @@ try:
except NameError: except NameError:
have_unicode = False have_unicode = False
requires_unicode = unittest.skipUnless(have_unicode, 'no unicode support')
def u(s):
return unicode(s, 'unicode-escape')
is_jython = sys.platform.startswith('java') is_jython = sys.platform.startswith('java')
# FS_NONASCII: non-ASCII Unicode character encodable by # FS_NONASCII: non-ASCII Unicode character encodable by
...@@ -749,42 +748,49 @@ class WarningsRecorder(object): ...@@ -749,42 +748,49 @@ class WarningsRecorder(object):
def _filterwarnings(filters, quiet=False): def _filterwarnings(filters, quiet=False):
"""Catch the warnings, then check if all the expected # Pyston change:
warnings have been raised and re-raise unexpected warnings. # this bare yield seems to work for now, but we might need to yield up a WarningsRecorder in some cases?
If 'quiet' is True, only re-raise the unexpected warnings. yield
"""
# TODO: Frame introspection in Pyston?
# old code follows:
# """Catch the warnings, then check if all the expected
# warnings have been raised and re-raise unexpected warnings.
# If 'quiet' is True, only re-raise the unexpected warnings.
# """
# Clear the warning registry of the calling module # Clear the warning registry of the calling module
# in order to re-raise the warnings. # in order to re-raise the warnings.
frame = sys._getframe(2) # frame = sys._getframe(2)
registry = frame.f_globals.get('__warningregistry__') # registry = frame.f_globals.get('__warningregistry__')
if registry: # if registry:
registry.clear() # registry.clear()
with warnings.catch_warnings(record=True) as w: # with warnings.catch_warnings(record=True) as w:
# Set filter "always" to record all warnings. Because # # Set filter "always" to record all warnings. Because
# test_warnings swap the module, we need to look up in # # test_warnings swap the module, we need to look up in
# the sys.modules dictionary. # # the sys.modules dictionary.
sys.modules['warnings'].simplefilter("always") # sys.modules['warnings'].simplefilter("always")
yield WarningsRecorder(w) # yield WarningsRecorder(w)
# Filter the recorded warnings # # Filter the recorded warnings
reraise = [warning.message for warning in w] # reraise = [warning.message for warning in w]
missing = [] # missing = []
for msg, cat in filters: # for msg, cat in filters:
seen = False # seen = False
for exc in reraise[:]: # for exc in reraise[:]:
message = str(exc) # message = str(exc)
# Filter out the matching messages # # Filter out the matching messages
if (re.match(msg, message, re.I) and # if (re.match(msg, message, re.I) and
issubclass(exc.__class__, cat)): # issubclass(exc.__class__, cat)):
seen = True # seen = True
reraise.remove(exc) # reraise.remove(exc)
if not seen and not quiet: # if not seen and not quiet:
# This filter caught nothing # # This filter caught nothing
missing.append((msg, cat.__name__)) # missing.append((msg, cat.__name__))
if reraise: # if reraise:
raise AssertionError("unhandled warning %r" % reraise[0]) # raise AssertionError("unhandled warning %r" % reraise[0])
if missing: # if missing:
raise AssertionError("filter (%r, %s) did not catch any warning" % # raise AssertionError("filter (%r, %s) did not catch any warning" %
missing[0]) # missing[0])
@contextlib.contextmanager @contextlib.contextmanager
......
...@@ -139,7 +139,10 @@ class TestLoader(object): ...@@ -139,7 +139,10 @@ class TestLoader(object):
hasattr(getattr(testCaseClass, attrname), '__call__') hasattr(getattr(testCaseClass, attrname), '__call__')
testFnNames = filter(isTestMethod, dir(testCaseClass)) testFnNames = filter(isTestMethod, dir(testCaseClass))
if self.sortTestMethodsUsing: if self.sortTestMethodsUsing:
testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing)) # Pyston change:
# TODO(rntz): needs builtin `cmp` to work
#testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
testFnNames.sort()
return testFnNames return testFnNames
def discover(self, start_dir, pattern='test*.py', top_level_dir=None): def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
......
...@@ -153,14 +153,17 @@ class TestResult(object): ...@@ -153,14 +153,17 @@ class TestResult(object):
"""Converts a sys.exc_info()-style tuple of values into a string.""" """Converts a sys.exc_info()-style tuple of values into a string."""
exctype, value, tb = err exctype, value, tb = err
# Skip test runner traceback levels # Skip test runner traceback levels
while tb and self._is_relevant_tb_level(tb): # Pyston change: I've commented this out for now. - rntz
tb = tb.tb_next # TODO(rntz): needs traceback stuff to work
# while tb and self._is_relevant_tb_level(tb):
if exctype is test.failureException: # tb = tb.tb_next
# Skip assert*() traceback levels
length = self._count_relevant_tb_levels(tb) # if exctype is test.failureException:
msgLines = traceback.format_exception(exctype, value, tb, length) # # Skip assert*() traceback levels
else: # length = self._count_relevant_tb_levels(tb)
# msgLines = traceback.format_exception(exctype, value, tb, length)
# else:
# msgLines = traceback.format_exception(exctype, value, tb)
msgLines = traceback.format_exception(exctype, value, tb) msgLines = traceback.format_exception(exctype, value, tb)
if self.buffer: if self.buffer:
......
# skip-if: True
# This is a test to make sure that the stack space we allocate # This is a test to make sure that the stack space we allocate
# for "long arg" calls (ie calls that take more than 4 arguments) # for "long arg" calls (ie calls that take more than 4 arguments)
# gets restored. # gets restored.
......
# skip-if: True
# I was worried about using a recursive parser for obscenely-nested source code, # I was worried about using a recursive parser for obscenely-nested source code,
# but based off this example it looks like that's what cPython and pypy both use as well. # but based off this example it looks like that's what cPython and pypy both use as well.
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment