Commit d2aff607 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

[2.7] bpo-30283: Backport test_regrtest from master to 2.7 (#1513)

* bpo-30283: regrtest: add --testdir option

* bpo-30283: Backport _testcapi.raise_signal()

Function used by test_regrtest to simulate an interrupted unit test.

* bpo-30283: Backport test_regrtest from master
parent c8a77d33
......@@ -60,6 +60,8 @@ Special runs
-- call gc.set_threshold(THRESHOLD)
-F/--forever -- run the specified tests in a loop, until an error happens
-P/--pgo -- enable Profile Guided Optimization training
--testdir -- execute test files in the specified directory
(instead of the Python stdlib test suite)
Additional Option Details:
......@@ -276,7 +278,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
'multiprocess=', 'slaveargs=', 'forever', 'header', 'pgo',
'failfast', 'match='])
'failfast', 'match=', 'testdir='])
except getopt.error, msg:
usage(2, msg)
......@@ -285,6 +287,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
random_seed = random.randrange(10000000)
if use_resources is None:
use_resources = []
slaveargs = None
for o, a in opts:
if o in ('-h', '--help'):
usage(0)
......@@ -367,16 +370,11 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
elif o == '--header':
header = True
elif o == '--slaveargs':
args, kwargs = json.loads(a)
try:
result = runtest(*args, **kwargs)
except BaseException, e:
result = INTERRUPTED, e.__class__.__name__
print # Force a newline (just in case)
print json.dumps(result)
sys.exit(0)
slaveargs = a
elif o in ('-P', '--pgo'):
pgo = True
elif o in ('--testdir'):
testdir = a
else:
print >>sys.stderr, ("No handler for option {}. Please "
"report this as a bug at http://bugs.python.org.").format(o)
......@@ -390,6 +388,25 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
if failfast and not (verbose or verbose3):
usage("-G/--failfast needs either -v or -W")
if testdir:
testdir = os.path.abspath(testdir)
# Prepend test directory to sys.path, so runtest() will be able
# to locate tests
sys.path.insert(0, testdir)
if slaveargs is not None:
args, kwargs = json.loads(slaveargs)
if testdir:
kwargs['testdir'] = testdir
try:
result = runtest(*args, **kwargs)
except BaseException, e:
result = INTERRUPTED, e.__class__.__name__
print # Force a newline (just in case)
print json.dumps(result)
sys.exit(0)
good = []
bad = []
skipped = []
......@@ -544,10 +561,13 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
output.put((None, None, None, None))
return
# -E is needed by some tests, e.g. test_import
popen = Popen(base_cmd + ['--slaveargs', json.dumps(args_tuple)],
stdout=PIPE, stderr=PIPE,
universal_newlines=True,
close_fds=(os.name != 'nt'))
args = base_cmd + ['--slaveargs', json.dumps(args_tuple)]
if testdir:
args.extend(('--testdir', testdir))
popen = Popen(args,
stdout=PIPE, stderr=PIPE,
universal_newlines=True,
close_fds=(os.name != 'nt'))
stdout, stderr = popen.communicate()
retcode = popen.wait()
......@@ -616,18 +636,20 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
if trace:
# If we're tracing code coverage, then we don't exit with status
# if on a false return value from main.
tracer.runctx('runtest(test, verbose, quiet)',
tracer.runctx('runtest(test, verbose, quiet, testdir=testdir)',
globals=globals(), locals=vars())
else:
try:
result = runtest(test, verbose, quiet, huntrleaks, None, pgo,
failfast=failfast,
match_tests=match_tests)
match_tests=match_tests,
testdir=testdir)
accumulate_result(test, result)
if verbose3 and result[0] == FAILED:
if not pgo:
print "Re-running test %r in verbose mode" % test
runtest(test, True, quiet, huntrleaks, None, pgo)
runtest(test, True, quiet, huntrleaks, None, pgo,
testdir=testdir)
except KeyboardInterrupt:
interrupted = True
break
......@@ -695,7 +717,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
sys.stdout.flush()
try:
test_support.verbose = True
ok = runtest(test, True, quiet, huntrleaks, None, pgo)
ok = runtest(test, True, quiet, huntrleaks, None, pgo,
testdir=testdir)
except KeyboardInterrupt:
# print a newline separate from the ^C
print
......@@ -757,7 +780,7 @@ def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
def runtest(test, verbose, quiet,
huntrleaks=False, use_resources=None, pgo=False,
failfast=False, match_tests=None):
failfast=False, match_tests=None, testdir=None):
"""Run a single test.
test -- the name of the test
......@@ -786,7 +809,7 @@ def runtest(test, verbose, quiet,
test_support.match_tests = match_tests
if failfast:
test_support.failfast = True
return runtest_inner(test, verbose, quiet, huntrleaks, pgo)
return runtest_inner(test, verbose, quiet, huntrleaks, pgo, testdir)
finally:
cleanup_test_droppings(test, verbose)
......@@ -947,7 +970,7 @@ class saved_test_environment:
return False
def runtest_inner(test, verbose, quiet, huntrleaks=False, pgo=False):
def runtest_inner(test, verbose, quiet, huntrleaks=False, pgo=False, testdir=None):
test_support.unload(test)
if verbose:
capture_stdout = None
......@@ -961,7 +984,7 @@ def runtest_inner(test, verbose, quiet, huntrleaks=False, pgo=False):
try:
if capture_stdout:
sys.stdout = capture_stdout
if test.startswith('test.'):
if test.startswith('test.') or testdir:
abstest = test
else:
# Always import it from the test package
......@@ -970,7 +993,10 @@ def runtest_inner(test, verbose, quiet, huntrleaks=False, pgo=False):
with saved_test_environment(test, verbose, quiet, pgo) as environment:
start_time = time.time()
the_package = __import__(abstest, globals(), locals(), [])
the_module = getattr(the_package, test)
if abstest.startswith('test.'):
the_module = getattr(the_package, test)
else:
the_module = the_package
# Old tests run to completion simply as a side-effect of
# being imported. For tests based on unittest or doctest,
# explicitly invoke their test_main() function (if it exists).
......
This diff is collapsed.
......@@ -10,6 +10,7 @@
#include "structmember.h"
#include "datetime.h"
#include "marshal.h"
#include <signal.h>
#ifdef WITH_THREAD
#include "pythread.h"
......@@ -2481,6 +2482,24 @@ pymarshal_read_object_from_file(PyObject* self, PyObject *args)
return Py_BuildValue("Nl", obj, pos);
}
static PyObject*
test_raise_signal(PyObject* self, PyObject *args)
{
int signum, err;
if (PyArg_ParseTuple(args, "i:raise_signal", &signum) < 0)
return NULL;
err = raise(signum);
if (err)
return PyErr_SetFromErrno(PyExc_OSError);
if (PyErr_CheckSignals() < 0)
return NULL;
Py_RETURN_NONE;
}
static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
......@@ -2593,6 +2612,7 @@ static PyMethodDef TestMethods[] = {
pymarshal_read_last_object_from_file, METH_VARARGS},
{"pymarshal_read_object_from_file",
pymarshal_read_object_from_file, METH_VARARGS},
{"raise_signal", (PyCFunction)test_raise_signal, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
......
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