Skip to content

Commit a15d155

Browse files
authored
bpo-31234: Enhance test_thread.test_forkinthread() (#3516)
* test_thread.test_forkinthread() now waits until the thread completes. * Check the status in the test method, not in the thread function * Don't ignore RuntimeError anymore: since the commit 346cbd3 (bpo-16500, os.register_at_fork(), os.fork() cannot fail anymore with RuntimeError. * Replace 0.01 literal with a new POLL_SLEEP constant * test_forkinthread(): test if os.fork() exists rather than testing the platform.
1 parent d056818 commit a15d155

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

‎Lib/test/test_thread.py‎

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
NUMTASKS = 10
1313
NUMTRIPS = 3
14+
POLL_SLEEP = 0.010 # seconds = 10 ms
1415

1516
_print_mutex = thread.allocate_lock()
1617

@@ -114,7 +115,7 @@ def task():
114115
mut.release()
115116
thread.start_new_thread(task, ())
116117
while not started:
117-
time.sleep(0.01)
118+
time.sleep(POLL_SLEEP)
118119
self.assertEqual(thread._count(), orig + 1)
119120
# Allow the task to finish.
120121
mut.release()
@@ -125,7 +126,7 @@ def task():
125126
wr = weakref.ref(task, lambda _: done.append(None))
126127
del task
127128
while not done:
128-
time.sleep(0.01)
129+
time.sleep(POLL_SLEEP)
129130
self.assertEqual(thread._count(), orig)
130131

131132
def test_save_exception_state_on_error(self):
@@ -148,7 +149,7 @@ def mywrite(self, *args):
148149
thread.start_new_thread(task, ())
149150
started.acquire()
150151
while thread._count() > c:
151-
time.sleep(0.01)
152+
time.sleep(POLL_SLEEP)
152153
self.assertIn("Traceback", stderr.getvalue())
153154

154155

@@ -221,30 +222,36 @@ class TestForkInThread(unittest.TestCase):
221222
def setUp(self):
222223
self.read_fd, self.write_fd = os.pipe()
223224

224-
@unittest.skipIf(sys.platform.startswith('win'),
225-
"This test is only appropriate for POSIX-like systems.")
225+
@unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork')
226226
@support.reap_threads
227227
def test_forkinthread(self):
228+
running = True
229+
status = "not set"
230+
228231
def thread1():
229-
try:
230-
pid = os.fork() # fork in a thread
231-
except RuntimeError:
232-
os._exit(1) # exit the child
232+
nonlocal running, status
233233

234-
if pid == 0: # child
234+
# fork in a thread
235+
pid = os.fork()
236+
if pid == 0:
237+
# child
235238
try:
236239
os.close(self.read_fd)
237240
os.write(self.write_fd, b"OK")
238241
finally:
239242
os._exit(0)
240-
else: # parent
243+
else:
244+
# parent
241245
os.close(self.write_fd)
242246
pid, status = os.waitpid(pid, 0)
243-
self.assertEqual(status, 0)
247+
running = False
244248

245249
thread.start_new_thread(thread1, ())
246250
self.assertEqual(os.read(self.read_fd, 2), b"OK",
247251
"Unable to fork() in thread")
252+
while running:
253+
time.sleep(POLL_SLEEP)
254+
self.assertEqual(status, 0)
248255

249256
def tearDown(self):
250257
try:

0 commit comments

Comments
 (0)