blob: 88527df25e203318cdbf0e038398765f6e0c805a [file] [log] [blame]
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001"""This test case provides support for checking forking and wait behavior.
2
Victor Stinner45df8202010-04-28 22:31:17 +00003To test different wait behavior, override the wait_impl method.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004
5We want fork1() semantics -- only the forking thread survives in the
6child after a fork().
7
8On some systems (e.g. Solaris without posix threads) we find that all
9active threads survive in the child after a fork(); this is an error.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010"""
11
Victor Stinner45df8202010-04-28 22:31:17 +000012import os, sys, time, unittest
13import test.support as support
14_thread = support.import_module('_thread')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015
16LONGSLEEP = 2
17SHORTSLEEP = 0.5
18NUM_THREADS = 4
19
20class ForkWait(unittest.TestCase):
21
22 def setUp(self):
23 self.alive = {}
24 self.stop = 0
25
26 def f(self, id):
27 while not self.stop:
28 self.alive[id] = os.getpid()
29 try:
30 time.sleep(SHORTSLEEP)
31 except IOError:
32 pass
33
34 def wait_impl(self, cpid):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000035 for i in range(10):
36 # waitpid() shouldn't hang, but some of the buildbots seem to hang
37 # in the forking tests. This is an attempt to fix the problem.
38 spid, status = os.waitpid(cpid, os.WNOHANG)
39 if spid == cpid:
40 break
41 time.sleep(2 * SHORTSLEEP)
42
Ezio Melottib3aedd42010-11-20 19:04:17 +000043 self.assertEqual(spid, cpid)
44 self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000045
Antoine Pitrou606c3f52011-05-09 21:17:02 +020046 @support.reap_threads
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000047 def test_wait(self):
48 for i in range(NUM_THREADS):
Georg Brandl2067bfd2008-05-25 13:05:15 +000049 _thread.start_new(self.f, (i,))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000050
51 time.sleep(LONGSLEEP)
52
Guido van Rossumcc2b0162007-02-11 06:12:03 +000053 a = sorted(self.alive.keys())
Ezio Melottib3aedd42010-11-20 19:04:17 +000054 self.assertEqual(a, list(range(NUM_THREADS)))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000055
56 prefork_lives = self.alive.copy()
57
58 if sys.platform in ['unixware7']:
59 cpid = os.fork1()
60 else:
61 cpid = os.fork()
62
63 if cpid == 0:
64 # Child
65 time.sleep(LONGSLEEP)
66 n = 0
67 for key in self.alive:
68 if self.alive[key] != prefork_lives[key]:
69 n += 1
70 os._exit(n)
71 else:
72 # Parent
Antoine Pitrou606c3f52011-05-09 21:17:02 +020073 try:
74 self.wait_impl(cpid)
75 finally:
76 # Tell threads to die
77 self.stop = 1