blob: 22e6f31f7c2382b50ba6d123f8649374b932cc0b [file] [log] [blame]
Guido van Rossumf7221c32000-02-25 19:25:05 +00001"""This test checks for correct fork() behavior.
Guido van Rossumf7221c32000-02-25 19:25:05 +00002"""
3
Thomas Woutersc4dcb382009-09-16 19:55:54 +00004import errno
5import imp
Neal Norwitz05a45592006-03-20 06:30:08 +00006import os
Thomas Woutersc4dcb382009-09-16 19:55:54 +00007import signal
8import sys
Neal Norwitz84bc19a2006-07-07 06:03:15 +00009import time
Thomas Woutersc4dcb382009-09-16 19:55:54 +000010import threading
11
Neal Norwitz05a45592006-03-20 06:30:08 +000012from test.fork_wait import ForkWait
R. David Murray3db8a342009-03-30 23:05:48 +000013from test.test_support import run_unittest, reap_children, get_attribute
Guido van Rossumf7221c32000-02-25 19:25:05 +000014
R. David Murray59beec32009-03-30 19:04:00 +000015#Skip test if fork does not exist.
R. David Murray3db8a342009-03-30 23:05:48 +000016get_attribute(os, 'fork')
R. David Murray59beec32009-03-30 19:04:00 +000017
Guido van Rossum49517822000-05-04 00:36:42 +000018
Neal Norwitz05a45592006-03-20 06:30:08 +000019class ForkTest(ForkWait):
20 def wait_impl(self, cpid):
Neal Norwitz84bc19a2006-07-07 06:03:15 +000021 for i in range(10):
22 # waitpid() shouldn't hang, but some of the buildbots seem to hang
23 # in the forking tests. This is an attempt to fix the problem.
24 spid, status = os.waitpid(cpid, os.WNOHANG)
25 if spid == cpid:
26 break
27 time.sleep(1.0)
28
Neal Norwitz05a45592006-03-20 06:30:08 +000029 self.assertEqual(spid, cpid)
30 self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
Guido van Rossumf7221c32000-02-25 19:25:05 +000031
Thomas Woutersc4dcb382009-09-16 19:55:54 +000032 def test_import_lock_fork(self):
33 import_started = threading.Event()
34 fake_module_name = "fake test module"
35 partial_module = "partial"
36 complete_module = "complete"
37 def importer():
38 imp.acquire_lock()
39 sys.modules[fake_module_name] = partial_module
40 import_started.set()
41 time.sleep(0.01) # Give the other thread time to try and acquire.
42 sys.modules[fake_module_name] = complete_module
43 imp.release_lock()
44 t = threading.Thread(target=importer)
45 t.start()
46 import_started.wait()
47 pid = os.fork()
48 try:
49 if not pid:
50 m = __import__(fake_module_name)
51 if m == complete_module:
52 os._exit(0)
53 else:
54 os._exit(1)
55 else:
56 t.join()
57 # Exitcode 1 means the child got a partial module (bad.) No
58 # exitcode (but a hang, which manifests as 'got pid 0')
59 # means the child deadlocked (also bad.)
60 self.wait_impl(pid)
61 finally:
62 try:
63 os.kill(pid, signal.SIGKILL)
64 except OSError:
65 pass
66
Neal Norwitz05a45592006-03-20 06:30:08 +000067def test_main():
68 run_unittest(ForkTest)
Neal Norwitzb15ac312006-06-29 04:10:08 +000069 reap_children()
Neal Norwitz05a45592006-03-20 06:30:08 +000070
71if __name__ == "__main__":
72 test_main()