blob: bf7fdcdec1b659b2130d609b788b5795a80ef135 [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
Benjamin Peterson0df35a92009-10-04 20:32:25 +00004import imp
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005import os
Benjamin Peterson0df35a92009-10-04 20:32:25 +00006import signal
7import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008import time
Benjamin Peterson0df35a92009-10-04 20:32:25 +00009
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010from test.fork_wait import ForkWait
Victor Stinner45df8202010-04-28 22:31:17 +000011from test.support import run_unittest, reap_children, get_attribute, import_module
12threading = import_module('threading')
Guido van Rossumf7221c32000-02-25 19:25:05 +000013
R. David Murraya21e4ca2009-03-31 23:16:50 +000014# Skip test if fork does not exist.
15get_attribute(os, 'fork')
16
Guido van Rossum49517822000-05-04 00:36:42 +000017
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000018class ForkTest(ForkWait):
19 def wait_impl(self, cpid):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000020 for i in range(10):
21 # waitpid() shouldn't hang, but some of the buildbots seem to hang
22 # in the forking tests. This is an attempt to fix the problem.
23 spid, status = os.waitpid(cpid, os.WNOHANG)
24 if spid == cpid:
25 break
26 time.sleep(1.0)
27
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000028 self.assertEqual(spid, cpid)
29 self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
Guido van Rossumf7221c32000-02-25 19:25:05 +000030
Benjamin Peterson0df35a92009-10-04 20:32:25 +000031 def test_import_lock_fork(self):
32 import_started = threading.Event()
33 fake_module_name = "fake test module"
34 partial_module = "partial"
35 complete_module = "complete"
36 def importer():
37 imp.acquire_lock()
38 sys.modules[fake_module_name] = partial_module
39 import_started.set()
40 time.sleep(0.01) # Give the other thread time to try and acquire.
41 sys.modules[fake_module_name] = complete_module
42 imp.release_lock()
43 t = threading.Thread(target=importer)
44 t.start()
45 import_started.wait()
46 pid = os.fork()
47 try:
48 if not pid:
49 m = __import__(fake_module_name)
50 if m == complete_module:
51 os._exit(0)
52 else:
53 os._exit(1)
54 else:
55 t.join()
56 # Exitcode 1 means the child got a partial module (bad.) No
57 # exitcode (but a hang, which manifests as 'got pid 0')
58 # means the child deadlocked (also bad.)
59 self.wait_impl(pid)
60 finally:
61 try:
62 os.kill(pid, signal.SIGKILL)
63 except OSError:
64 pass
65
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000066def test_main():
67 run_unittest(ForkTest)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068 reap_children()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069
70if __name__ == "__main__":
71 test_main()