summaryrefslogtreecommitdiff
path: root/lib/python2.7/test/test_threaded_import.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/test/test_threaded_import.py')
-rw-r--r--lib/python2.7/test/test_threaded_import.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/python2.7/test/test_threaded_import.py b/lib/python2.7/test/test_threaded_import.py
new file mode 100644
index 0000000..b31fdf1
--- /dev/null
+++ b/lib/python2.7/test/test_threaded_import.py
@@ -0,0 +1,76 @@
+# This is a variant of the very old (early 90's) file
+# Demo/threads/bug.py. It simply provokes a number of threads into
+# trying to import the same module "at the same time".
+# There are no pleasant failure modes -- most likely is that Python
+# complains several times about module random having no attribute
+# randrange, and then Python hangs.
+
+import unittest
+from test.test_support import verbose, TestFailed, import_module
+thread = import_module('thread')
+
+critical_section = thread.allocate_lock()
+done = thread.allocate_lock()
+
+def task():
+ global N, critical_section, done
+ import random
+ x = random.randrange(1, 3)
+ critical_section.acquire()
+ N -= 1
+ # Must release critical_section before releasing done, else the main
+ # thread can exit and set critical_section to None as part of global
+ # teardown; then critical_section.release() raises AttributeError.
+ finished = N == 0
+ critical_section.release()
+ if finished:
+ done.release()
+
+def test_import_hangers():
+ import sys
+ if verbose:
+ print "testing import hangers ...",
+
+ import test.threaded_import_hangers
+ try:
+ if test.threaded_import_hangers.errors:
+ raise TestFailed(test.threaded_import_hangers.errors)
+ elif verbose:
+ print "OK."
+ finally:
+ # In case this test is run again, make sure the helper module
+ # gets loaded from scratch again.
+ del sys.modules['test.threaded_import_hangers']
+
+# Tricky: When regrtest imports this module, the thread running regrtest
+# grabs the import lock and won't let go of it until this module returns.
+# All other threads attempting an import hang for the duration. Since
+# this test spawns threads that do little *but* import, we can't do that
+# successfully until after this module finishes importing and regrtest
+# regains control. To make this work, a special case was added to
+# regrtest to invoke a module's "test_main" function (if any) after
+# importing it.
+
+def test_main(): # magic name! see above
+ global N, done
+
+ import imp
+ if imp.lock_held():
+ # This triggers on, e.g., from test import autotest.
+ raise unittest.SkipTest("can't run when import lock is held")
+
+ done.acquire()
+ for N in (20, 50) * 3:
+ if verbose:
+ print "Trying", N, "threads ...",
+ for i in range(N):
+ thread.start_new_thread(task, ())
+ done.acquire()
+ if verbose:
+ print "OK."
+ done.release()
+
+ test_import_hangers()
+
+if __name__ == "__main__":
+ test_main()