Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 48 additions & 22 deletions Lib/test/regrtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
-- 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:
Expand Down Expand Up @@ -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)

Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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 = []
Expand Down Expand Up @@ -544,10 +561,13 @@ def work():
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))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testdir is not passed to a subprocess in 3.x.

Do you want to port this to 3.5-3.7?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. I expected that only 2.7 has an old regrtest, but 3.5 also has the "old" regrtest. This change is required by test_regrtest for tests using -jN. It seems like we don't have these tests in 3.5 yet: test_regrtest only has unit tests on the command line parsing. Said differently, Python 3.5 is also impacted by bpo-30283. I added a comment in the issue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But master don't pass testdir too.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But master don't pass testdir too.

In master, there is no need to pass testdir since regrtest is designed differently. run_test_in_subprocess() pass "ns" a dict which contains testdir. In the slave, setup_tests() is called with ns and so sys.path is updated properly.

I hate regrtest.py of Python 2.7/3.5, I would prefer to just replace it with master libregrtest...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it is passed in slaveargs!

popen = Popen(args,
stdout=PIPE, stderr=PIPE,
universal_newlines=True,
close_fds=(os.name != 'nt'))
stdout, stderr = popen.communicate()
retcode = popen.wait()

Expand Down Expand Up @@ -616,18 +636,20 @@ def work():
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)',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testdir is not passed to runtest() in 3.5.

Do you want to port this to 3.5?

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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testdir is not passed to runtest() in 3.5.

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
Expand Down Expand Up @@ -695,7 +717,8 @@ def work():
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -947,7 +970,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
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
Expand All @@ -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
Expand All @@ -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).
Expand Down
Loading