2006-04-21 07:40:58 -03:00
|
|
|
"""This test case provides support for checking forking and wait behavior.
|
|
|
|
|
Merged revisions 80552-80556,80564-80566,80568-80571 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r80552 | victor.stinner | 2010-04-27 23:46:03 +0200 (mar., 27 avril 2010) | 3 lines
Issue #7449, part 1: fix test_support.py for Python compiled without thread
........
r80553 | victor.stinner | 2010-04-27 23:47:01 +0200 (mar., 27 avril 2010) | 1 line
Issue #7449, part 2: regrtest.py -j option requires thread support
........
r80554 | victor.stinner | 2010-04-27 23:51:26 +0200 (mar., 27 avril 2010) | 9 lines
Issue #7449 part 3, test_doctest: import trace module in test_coverage()
Import trace module fail if the threading module is missing. test_coverage() is
only used if test_doctest.py is used with the -c option. This commit allows to
execute the test suite without thread support.
Move "import trace" in test_coverage() and use
test_support.import_module('trace').
........
r80555 | victor.stinner | 2010-04-27 23:56:26 +0200 (mar., 27 avril 2010) | 6 lines
Issue #7449, part 4: skip test_multiprocessing if thread support is disabled
import threading after _multiprocessing to raise a more revelant error message:
"No module named _multiprocessing". _multiprocessing is not compiled without
thread support.
........
r80556 | victor.stinner | 2010-04-28 00:01:24 +0200 (mer., 28 avril 2010) | 8 lines
Issue #7449, part 5: split Test.test_open() of ctypes/test/test_errno.py
* Split Test.test_open() in 2 functions: test_open() and test_thread_open()
* Skip test_open() and test_thread_open() if we are unable to find the C
library
* Skip test_thread_open() if thread support is disabled
* Use unittest.skipUnless(os.name == "nt", ...) on test_GetLastError()
........
r80564 | victor.stinner | 2010-04-28 00:59:35 +0200 (mer., 28 avril 2010) | 4 lines
Issue #7449, part 6: fix test_hashlib for missing threading module
Move @test_support.reap_thread decorator from test_main() to test_threaded_hashing().
........
r80565 | victor.stinner | 2010-04-28 01:01:29 +0200 (mer., 28 avril 2010) | 6 lines
Issue #7449, part 7: simplify threading detection in test_capi
* Skip TestPendingCalls if threading module is missing
* Test if threading module is present or not, instead of test the presence of
_testcapi._test_thread_state
........
r80566 | victor.stinner | 2010-04-28 01:03:16 +0200 (mer., 28 avril 2010) | 4 lines
Issue #7449, part 8: don't skip the whole test_asynchat if threading is missing
TestFifo can be executed without the threading module
........
r80568 | victor.stinner | 2010-04-28 01:14:58 +0200 (mer., 28 avril 2010) | 6 lines
Issue #7449, part 9: fix test_xmlrpclib for missing threading module
* Skip testcases using threads if threading module is missing
* Use "http://" instead of URL in ServerProxyTestCase if threading is missing
because URL is not set in this case
........
r80569 | victor.stinner | 2010-04-28 01:33:58 +0200 (mer., 28 avril 2010) | 6 lines
Partial revert of r80556 (Issue #7449, part 5, fix ctypes test)
Rewrite r80556: the thread test have to be executed just after the test on
libc_open() and so the test cannot be splitted in two functions (without
duplicating code, and I don't want to duplicate code).
........
r80570 | victor.stinner | 2010-04-28 01:51:16 +0200 (mer., 28 avril 2010) | 8 lines
Issue #7449, part 10: test_cmd imports trace module using test_support.import_module()
Use test_support.import_module() instead of import to raise a SkipTest
exception if the import fail. Import trace fails if the threading module is
missing.
See also part 3: test_doctest: import trace module in test_coverage().
........
r80571 | victor.stinner | 2010-04-28 01:55:59 +0200 (mer., 28 avril 2010) | 6 lines
Issue #7449, last part (11): fix many tests if thread support is disabled
* Use try/except ImportError or test_support.import_module() to import thread
and threading modules
* Add @unittest.skipUnless(threading, ...) to testcases using threads
........
2010-04-28 19:31:17 -03:00
|
|
|
To test different wait behavior, override the wait_impl method.
|
2006-04-21 07:40:58 -03:00
|
|
|
|
|
|
|
We want fork1() semantics -- only the forking thread survives in the
|
|
|
|
child after a fork().
|
|
|
|
|
|
|
|
On some systems (e.g. Solaris without posix threads) we find that all
|
|
|
|
active threads survive in the child after a fork(); this is an error.
|
|
|
|
"""
|
|
|
|
|
2023-03-08 07:45:38 -04:00
|
|
|
import os, time, unittest
|
2017-09-07 13:56:24 -03:00
|
|
|
import threading
|
2019-12-11 06:30:03 -04:00
|
|
|
from test import support
|
2020-05-27 19:10:27 -03:00
|
|
|
from test.support import threading_helper
|
2022-12-29 18:41:39 -04:00
|
|
|
import warnings
|
2017-08-18 18:12:26 -03:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
|
|
|
|
LONGSLEEP = 2
|
|
|
|
SHORTSLEEP = 0.5
|
|
|
|
NUM_THREADS = 4
|
|
|
|
|
|
|
|
class ForkWait(unittest.TestCase):
|
|
|
|
|
|
|
|
def setUp(self):
|
2020-05-27 19:10:27 -03:00
|
|
|
self._threading_key = threading_helper.threading_setup()
|
2006-04-21 07:40:58 -03:00
|
|
|
self.alive = {}
|
|
|
|
self.stop = 0
|
2017-08-18 18:12:26 -03:00
|
|
|
self.threads = []
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
# Stop threads
|
|
|
|
self.stop = 1
|
|
|
|
for thread in self.threads:
|
|
|
|
thread.join()
|
|
|
|
thread = None
|
|
|
|
self.threads.clear()
|
2020-05-27 19:10:27 -03:00
|
|
|
threading_helper.threading_cleanup(*self._threading_key)
|
2006-04-21 07:40:58 -03:00
|
|
|
|
|
|
|
def f(self, id):
|
|
|
|
while not self.stop:
|
|
|
|
self.alive[id] = os.getpid()
|
|
|
|
try:
|
|
|
|
time.sleep(SHORTSLEEP)
|
2012-12-25 10:47:37 -04:00
|
|
|
except OSError:
|
2006-04-21 07:40:58 -03:00
|
|
|
pass
|
|
|
|
|
2020-03-31 16:46:40 -03:00
|
|
|
def wait_impl(self, cpid, *, exitcode):
|
|
|
|
support.wait_process(cpid, exitcode=exitcode)
|
2006-04-21 07:40:58 -03:00
|
|
|
|
|
|
|
def test_wait(self):
|
|
|
|
for i in range(NUM_THREADS):
|
2017-08-18 18:12:26 -03:00
|
|
|
thread = threading.Thread(target=self.f, args=(i,))
|
|
|
|
thread.start()
|
|
|
|
self.threads.append(thread)
|
2006-04-21 07:40:58 -03:00
|
|
|
|
2014-03-17 20:39:04 -03:00
|
|
|
# busy-loop to wait for threads
|
2022-06-16 08:44:58 -03:00
|
|
|
for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
|
2022-06-15 06:42:10 -03:00
|
|
|
if len(self.alive) >= NUM_THREADS:
|
2014-03-17 20:39:04 -03:00
|
|
|
break
|
2006-04-21 07:40:58 -03:00
|
|
|
|
2007-02-11 02:12:03 -04:00
|
|
|
a = sorted(self.alive.keys())
|
2010-11-20 15:04:17 -04:00
|
|
|
self.assertEqual(a, list(range(NUM_THREADS)))
|
2006-04-21 07:40:58 -03:00
|
|
|
|
|
|
|
prefork_lives = self.alive.copy()
|
|
|
|
|
2022-12-29 18:41:39 -04:00
|
|
|
# Ignore the warning about fork with threads.
|
|
|
|
with warnings.catch_warnings(category=DeprecationWarning,
|
|
|
|
action="ignore"):
|
|
|
|
if (cpid := os.fork()) == 0:
|
|
|
|
# Child
|
|
|
|
time.sleep(LONGSLEEP)
|
|
|
|
n = 0
|
|
|
|
for key in self.alive:
|
|
|
|
if self.alive[key] != prefork_lives[key]:
|
|
|
|
n += 1
|
|
|
|
os._exit(n)
|
|
|
|
else:
|
|
|
|
# Parent
|
|
|
|
self.wait_impl(cpid, exitcode=0)
|