summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_signal.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_signal.py')
-rw-r--r--Lib/test/test_signal.py51
1 files changed, 50 insertions, 1 deletions
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index f7fcb04..a6267d2 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -25,7 +25,11 @@ script = """
) &
""" % vars()
+a_called = b_called = False
+
def handlerA(*args):
+ global a_called
+ a_called = True
if verbose:
print "handlerA", args
@@ -33,11 +37,14 @@ class HandlerBCalled(Exception):
pass
def handlerB(*args):
+ global b_called
+ b_called = True
if verbose:
print "handlerB", args
raise HandlerBCalled, args
-signal.alarm(20) # Entire test lasts at most 20 sec.
+MAX_DURATION = 20
+signal.alarm(MAX_DURATION) # Entire test should last at most 20 sec.
hup = signal.signal(signal.SIGHUP, handlerA)
usr1 = signal.signal(signal.SIGUSR1, handlerB)
usr2 = signal.signal(signal.SIGUSR2, signal.SIG_IGN)
@@ -65,9 +72,35 @@ try:
except TypeError:
pass
+# Set up a child to send an alarm signal to us (the parent) after waiting
+# long enough to receive the alarm. It seems we miss the alarm for some
+# reason. This will hopefully stop the hangs on Tru64/Alpha.
+def force_test_exit():
+ # Sigh, both imports seem necessary to avoid errors.
+ import os
+ fork_pid = os.fork()
+ if fork_pid == 0:
+ # In child
+ import os, time
+ try:
+ # Wait 5 seconds longer than the expected alarm to give enough
+ # time for the normal sequence of events to occur. This is
+ # just a stop-gap to prevent the test from hanging.
+ time.sleep(MAX_DURATION + 5)
+ print >> sys.__stdout__, ' child should not have to kill parent'
+ for i in range(3):
+ os.kill(pid, signal.SIGALARM)
+ finally:
+ os._exit(0)
+ # In parent (or error)
+ return fork_pid
+
try:
os.system(script)
+ # Try to ensure this test exits even if there is some problem with alarm.
+ # Tru64/Alpha sometimes hangs and is ultimately killed by the buildbot.
+ fork_pid = force_test_exit()
print "starting pause() loop..."
try:
@@ -88,6 +121,22 @@ try:
if verbose:
print "KeyboardInterrupt (assume the alarm() went off)"
+ # Forcibly kill the child we created to ping us if there was a test error.
+ try:
+ # Make sure we don't kill ourself if there was a fork error.
+ if fork_pid > 0:
+ os.kill(fork_pid, signal.SIGKILL)
+ except:
+ # If the child killed us, it has probably exited. Killing a
+ # non-existant process will raise an error which we don't care about.
+ pass
+
+ if not a_called:
+ print 'HandlerA not called'
+
+ if not b_called:
+ print 'HandlerB not called'
+
finally:
signal.signal(signal.SIGHUP, hup)
signal.signal(signal.SIGUSR1, usr1)