Commit d9742211 authored by Tim Peters's avatar Tim Peters

Implementing an idea from Guido on the checkins list:

When regrtest.py finds an attribute "test_main" in a test it imports,
regrtest runs the test's test_main after the import.  test_threaded_import
needs this else the cross-thread import lock prevents it from making
progress.  Other tests can use this hack too, but I doubt it will ever be
popular.
parent bc561982
...@@ -244,7 +244,14 @@ def runtest(test, generate, verbose, quiet, testdir = None): ...@@ -244,7 +244,14 @@ def runtest(test, generate, verbose, quiet, testdir = None):
if cfp: if cfp:
sys.stdout = cfp sys.stdout = cfp
print test # Output file starts with test name print test # Output file starts with test name
__import__(test, globals(), locals(), []) the_module = __import__(test, globals(), locals(), [])
# Most tests run to completion simply as a side-effect of
# being imported. For the benefit of tests that can't run
# that way (like test_threaded_import), explicitly invoke
# their test_main() function (if it exists).
indirect_test = getattr(the_module, "test_main", None)
if indirect_test is not None:
indirect_test()
if cfp and not (generate or verbose): if cfp and not (generate or verbose):
cfp.close() cfp.close()
finally: finally:
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
# randrange, and then Python hangs. # randrange, and then Python hangs.
import thread import thread
from test_support import verbose
critical_section = thread.allocate_lock() critical_section = thread.allocate_lock()
done = thread.allocate_lock() done = thread.allocate_lock()
...@@ -20,33 +21,26 @@ def task(): ...@@ -20,33 +21,26 @@ def task():
done.release() done.release()
critical_section.release() critical_section.release()
# Tricky, tricky, tricky. # Tricky: When regrtest imports this module, the thread running regrtest
# When regrtest imports this module, the thread running regrtest grabs the # grabs the import lock and won't let go of it until this module returns.
# import lock and won't let go of it until this module returns. All other # All other threads attempting an import hang for the duration. Since
# threads attempting an import hang for the duration. So we have to spawn # this test spawns threads that do little *but* import, we can't do that
# a thread to run the test and return to regrtest.py right away, else the # successfully until after this module finishes importing and regrtest
# test can't make progress. # regains control. To make this work, a special case was added to
# # regrtest to invoke a module's "test_main" function (if any) after
# One miserable consequence: This test can't wait to make sure all the # importing it.
# threads complete!
#
# Another: If this test fails, the output may show up while running
# some other test.
#
# Another: If you run this test directly, the OS will probably kill
# all the threads right away, because the program exits immediately
# after spawning a thread to run the real test.
#
# Another: If this test ever does fail and you attempt to run it by
# itself via regrtest, the same applies: regrtest will get out so fast
# the OS will kill all the threads here.
def run_the_test(): def test_main(): # magic name! see above
global N, done global N, done
done.acquire() done.acquire()
for N in [1, 2, 3, 4, 20, 4, 3, 2]: for N in (20, 50) * 3:
if verbose:
print "Trying", N, "threads ...",
for i in range(N): for i in range(N):
thread.start_new_thread(task, ()) thread.start_new_thread(task, ())
done.acquire() done.acquire()
if verbose:
print "OK."
thread.start_new_thread(run_the_test, ()) if __name__ == "__main__":
test_main()
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