blob: 311d0f09912697c255f812426071b107042e48eb [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Raymond Hettinger722d8c32009-06-18 22:21:03 +00003from contextlib import closing
Christian Heimescc47b052008-03-25 14:56:36 +00004import gc
Christian Heimes4fbc72b2008-03-22 00:47:35 +00005import pickle
6import select
Guido van Rossum4f17e3e1995-03-16 15:07:38 +00007import signal
Victor Stinnerd49b1f12011-05-08 02:03:15 +02008import struct
Christian Heimes4fbc72b2008-03-22 00:47:35 +00009import subprocess
10import traceback
Christian Heimesc06950e2008-02-28 21:17:00 +000011import sys, os, time, errno
Victor Stinnerd6284962011-06-20 23:28:09 +020012from test.script_helper import assert_python_ok, spawn_python
Victor Stinnerb3e72192011-05-08 01:46:11 +020013try:
14 import threading
15except ImportError:
16 threading = None
Christian Heimesc06950e2008-02-28 21:17:00 +000017
Brian Curtin912443c2010-09-06 16:10:04 +000018if sys.platform in ('os2', 'riscos'):
19 raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
Christian Heimesc06950e2008-02-28 21:17:00 +000020
Guido van Rossumcc5a91d1997-04-16 00:29:15 +000021
Armin Rigo8b2cbfd2004-08-07 21:27:43 +000022class HandlerBCalled(Exception):
23 pass
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000024
Christian Heimes4fbc72b2008-03-22 00:47:35 +000025
26def exit_subprocess():
27 """Use os._exit(0) to exit the current subprocess.
28
29 Otherwise, the test catches the SystemExit and continues executing
30 in parallel with the original test, so you wind up with an
31 exponential number of tests running concurrently.
32 """
33 os._exit(0)
34
35
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000036def ignoring_eintr(__func, *args, **kwargs):
37 try:
38 return __func(*args, **kwargs)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +000039 except EnvironmentError as e:
40 if e.errno != errno.EINTR:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000041 raise
42 return None
43
44
Brian Curtin3f004b12010-08-06 19:34:52 +000045@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Thomas Woutersed03b412007-08-28 21:37:11 +000046class InterProcessSignalTests(unittest.TestCase):
47 MAX_DURATION = 20 # Entire test should last at most 20 sec.
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000048
Christian Heimescc47b052008-03-25 14:56:36 +000049 def setUp(self):
50 self.using_gc = gc.isenabled()
51 gc.disable()
52
53 def tearDown(self):
54 if self.using_gc:
55 gc.enable()
56
Christian Heimes5e696852008-04-09 08:37:03 +000057 def format_frame(self, frame, limit=None):
58 return ''.join(traceback.format_stack(frame, limit=limit))
59
60 def handlerA(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000061 self.a_called = True
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000062
Christian Heimes5e696852008-04-09 08:37:03 +000063 def handlerB(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000064 self.b_called = True
Christian Heimes5e696852008-04-09 08:37:03 +000065 raise HandlerBCalled(signum, self.format_frame(frame))
Neal Norwitz9730bcb2006-01-23 07:50:06 +000066
Christian Heimes4fbc72b2008-03-22 00:47:35 +000067 def wait(self, child):
68 """Wait for child to finish, ignoring EINTR."""
69 while True:
70 try:
71 child.wait()
72 return
73 except OSError as e:
74 if e.errno != errno.EINTR:
75 raise
Fred Drake004d5e62000-10-23 17:22:08 +000076
Christian Heimes4fbc72b2008-03-22 00:47:35 +000077 def run_test(self):
78 # Install handlers. This function runs in a sub-process, so we
79 # don't worry about re-setting the default handlers.
80 signal.signal(signal.SIGHUP, self.handlerA)
81 signal.signal(signal.SIGUSR1, self.handlerB)
82 signal.signal(signal.SIGUSR2, signal.SIG_IGN)
83 signal.signal(signal.SIGALRM, signal.default_int_handler)
Michael W. Hudson5c26e862004-06-11 18:09:28 +000084
Christian Heimes4fbc72b2008-03-22 00:47:35 +000085 # Variables the signals will modify:
86 self.a_called = False
87 self.b_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000088
Christian Heimes4fbc72b2008-03-22 00:47:35 +000089 # Let the sub-processes know who to send signals to.
90 pid = os.getpid()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000091
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000092 child = ignoring_eintr(subprocess.Popen, ['kill', '-HUP', str(pid)])
93 if child:
94 self.wait(child)
95 if not self.a_called:
96 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +000097 self.assertTrue(self.a_called)
98 self.assertFalse(self.b_called)
99 self.a_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000100
Christian Heimes5e696852008-04-09 08:37:03 +0000101 # Make sure the signal isn't delivered while the previous
102 # Popen object is being destroyed, because __del__ swallows
103 # exceptions.
104 del child
Thomas Woutersed03b412007-08-28 21:37:11 +0000105 try:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000106 child = subprocess.Popen(['kill', '-USR1', str(pid)])
107 # This wait should be interrupted by the signal's exception.
108 self.wait(child)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000109 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000110 self.fail('HandlerBCalled exception not thrown')
111 except HandlerBCalled:
112 self.assertTrue(self.b_called)
113 self.assertFalse(self.a_called)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000114
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000115 child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)])
116 if child:
117 self.wait(child) # Nothing should happen.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000118
119 try:
120 signal.alarm(1)
121 # The race condition in pause doesn't matter in this case,
122 # since alarm is going to raise a KeyboardException, which
123 # will skip the call.
124 signal.pause()
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000125 # But if another signal arrives before the alarm, pause
126 # may return early.
127 time.sleep(1)
Thomas Woutersed03b412007-08-28 21:37:11 +0000128 except KeyboardInterrupt:
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200129 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000130 except:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000131 self.fail("Some other exception woke us from pause: %s" %
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000132 traceback.format_exc())
133 else:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000134 self.fail("pause returned of its own accord, and the signal"
135 " didn't arrive after another second.")
Thomas Woutersed03b412007-08-28 21:37:11 +0000136
R. David Murray44546f82010-04-21 01:59:28 +0000137 # Issue 3864, unknown if this affects earlier versions of freebsd also
138 @unittest.skipIf(sys.platform=='freebsd6',
139 'inter process signals not reliable (do not mix well with threading) '
140 'on freebsd6')
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000141 def test_main(self):
142 # This function spawns a child process to insulate the main
143 # test-running process from all the signals. It then
144 # communicates with that child process over a pipe and
145 # re-raises information about any exceptions the child
146 # throws. The real work happens in self.run_test().
147 os_done_r, os_done_w = os.pipe()
Raymond Hettinger686057b2009-06-04 00:11:54 +0000148 with closing(os.fdopen(os_done_r, 'rb')) as done_r, \
149 closing(os.fdopen(os_done_w, 'wb')) as done_w:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000150 child = os.fork()
151 if child == 0:
152 # In the child process; run the test and report results
153 # through the pipe.
154 try:
155 done_r.close()
156 # Have to close done_w again here because
157 # exit_subprocess() will skip the enclosing with block.
158 with closing(done_w):
159 try:
160 self.run_test()
161 except:
162 pickle.dump(traceback.format_exc(), done_w)
163 else:
164 pickle.dump(None, done_w)
165 except:
166 print('Uh oh, raised from pickle.')
167 traceback.print_exc()
168 finally:
169 exit_subprocess()
170
171 done_w.close()
172 # Block for up to MAX_DURATION seconds for the test to finish.
173 r, w, x = select.select([done_r], [], [], self.MAX_DURATION)
174 if done_r in r:
175 tb = pickle.load(done_r)
176 if tb:
177 self.fail(tb)
178 else:
179 os.kill(child, signal.SIGKILL)
180 self.fail('Test deadlocked after %d seconds.' %
181 self.MAX_DURATION)
Thomas Woutersed03b412007-08-28 21:37:11 +0000182
183
Brian Curtin3f004b12010-08-06 19:34:52 +0000184@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Victor Stinnerb3e72192011-05-08 01:46:11 +0200185class PosixTests(unittest.TestCase):
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000186 def trivial_signal_handler(self, *args):
187 pass
188
Thomas Woutersed03b412007-08-28 21:37:11 +0000189 def test_out_of_range_signal_number_raises_error(self):
190 self.assertRaises(ValueError, signal.getsignal, 4242)
191
Thomas Woutersed03b412007-08-28 21:37:11 +0000192 self.assertRaises(ValueError, signal.signal, 4242,
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000193 self.trivial_signal_handler)
Thomas Woutersed03b412007-08-28 21:37:11 +0000194
195 def test_setting_signal_handler_to_none_raises_error(self):
196 self.assertRaises(TypeError, signal.signal,
197 signal.SIGUSR1, None)
198
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000199 def test_getsignal(self):
200 hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000201 self.assertEqual(signal.getsignal(signal.SIGHUP),
202 self.trivial_signal_handler)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000203 signal.signal(signal.SIGHUP, hup)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000204 self.assertEqual(signal.getsignal(signal.SIGHUP), hup)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000205
206
Brian Curtin3f004b12010-08-06 19:34:52 +0000207@unittest.skipUnless(sys.platform == "win32", "Windows specific")
208class WindowsSignalTests(unittest.TestCase):
209 def test_issue9324(self):
Brian Curtineccd4d92010-10-01 15:09:53 +0000210 # Updated for issue #10003, adding SIGBREAK
Brian Curtin3f004b12010-08-06 19:34:52 +0000211 handler = lambda x, y: None
Brian Curtineccd4d92010-10-01 15:09:53 +0000212 for sig in (signal.SIGABRT, signal.SIGBREAK, signal.SIGFPE,
213 signal.SIGILL, signal.SIGINT, signal.SIGSEGV,
214 signal.SIGTERM):
215 # Set and then reset a handler for signals that work on windows
216 signal.signal(sig, signal.signal(sig, handler))
Brian Curtin3f004b12010-08-06 19:34:52 +0000217
218 with self.assertRaises(ValueError):
219 signal.signal(-1, handler)
Brian Curtin80cd4bf2010-08-07 03:52:38 +0000220
221 with self.assertRaises(ValueError):
222 signal.signal(7, handler)
Brian Curtin3f004b12010-08-06 19:34:52 +0000223
224
225@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000226class WakeupSignalTests(unittest.TestCase):
227 TIMEOUT_FULL = 10
228 TIMEOUT_HALF = 5
229
Victor Stinnerc13ef662011-05-25 02:35:58 +0200230 def handler(self, signum, frame):
231 pass
232
Victor Stinner20822682011-05-31 22:31:09 +0200233 def check_signum(self, *signals):
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200234 data = os.read(self.read, len(signals)+1)
235 raised = struct.unpack('%uB' % len(data), data)
Victor Stinner20822682011-05-31 22:31:09 +0200236 # We don't care of the signal delivery order (it's not portable or
237 # reliable)
238 raised = set(raised)
239 signals = set(signals)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200240 self.assertEqual(raised, signals)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200241
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000242 def test_wakeup_fd_early(self):
243 import select
244
245 signal.alarm(1)
246 before_time = time.time()
247 # We attempt to get a signal during the sleep,
248 # before select is called
249 time.sleep(self.TIMEOUT_FULL)
250 mid_time = time.time()
Georg Brandlab91fde2009-08-13 08:51:18 +0000251 self.assertTrue(mid_time - before_time < self.TIMEOUT_HALF)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000252 select.select([self.read], [], [], self.TIMEOUT_FULL)
253 after_time = time.time()
Georg Brandlab91fde2009-08-13 08:51:18 +0000254 self.assertTrue(after_time - mid_time < self.TIMEOUT_HALF)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200255 self.check_signum(signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000256
257 def test_wakeup_fd_during(self):
258 import select
259
260 signal.alarm(1)
261 before_time = time.time()
262 # We attempt to get a signal during the select call
263 self.assertRaises(select.error, select.select,
264 [self.read], [], [], self.TIMEOUT_FULL)
265 after_time = time.time()
Georg Brandlab91fde2009-08-13 08:51:18 +0000266 self.assertTrue(after_time - before_time < self.TIMEOUT_HALF)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200267 self.check_signum(signal.SIGALRM)
268
269 def test_signum(self):
Victor Stinnerc13ef662011-05-25 02:35:58 +0200270 old_handler = signal.signal(signal.SIGUSR1, self.handler)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200271 self.addCleanup(signal.signal, signal.SIGUSR1, old_handler)
272 os.kill(os.getpid(), signal.SIGUSR1)
273 os.kill(os.getpid(), signal.SIGALRM)
274 self.check_signum(signal.SIGUSR1, signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000275
Victor Stinnerc13ef662011-05-25 02:35:58 +0200276 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
277 'need signal.pthread_sigmask()')
278 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
279 'need signal.pthread_kill()')
280 def test_pending(self):
281 signum1 = signal.SIGUSR1
282 signum2 = signal.SIGUSR2
283 tid = threading.current_thread().ident
284
285 old_handler = signal.signal(signum1, self.handler)
286 self.addCleanup(signal.signal, signum1, old_handler)
287 old_handler = signal.signal(signum2, self.handler)
288 self.addCleanup(signal.signal, signum2, old_handler)
289
290 signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2))
291 signal.pthread_kill(tid, signum1)
292 signal.pthread_kill(tid, signum2)
293 # Unblocking the 2 signals calls the C signal handler twice
294 signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2))
295
Victor Stinner20822682011-05-31 22:31:09 +0200296 self.check_signum(signum1, signum2)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200297
Victor Stinnere71db442011-06-24 20:52:27 +0200298 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
299 'need signal.pthread_kill()')
300 def test_pthread_kill_main_thread(self):
301 # Test that a signal can be sent to the main thread with pthread_kill()
302 # before any other thread has been created (see issue #12392).
303 code = """if True:
304 import threading
305 import signal
306 import sys
307
308 def handler(signum, frame):
309 sys.exit(3)
310
311 signal.signal(signal.SIGUSR1, handler)
312 signal.pthread_kill(threading.get_ident(), signal.SIGUSR1)
313 sys.exit(1)
314 """
315
316 with spawn_python('-c', code) as process:
317 stdout, stderr = process.communicate()
318 exitcode = process.wait()
319 if exitcode != 3:
320 raise Exception("Child error (exit code %s): %s" %
321 (exitcode, stdout))
322
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000323 def setUp(self):
324 import fcntl
325
Victor Stinnerc13ef662011-05-25 02:35:58 +0200326 self.alrm = signal.signal(signal.SIGALRM, self.handler)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000327 self.read, self.write = os.pipe()
328 flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
329 flags = flags | os.O_NONBLOCK
330 fcntl.fcntl(self.write, fcntl.F_SETFL, flags)
331 self.old_wakeup = signal.set_wakeup_fd(self.write)
332
333 def tearDown(self):
334 signal.set_wakeup_fd(self.old_wakeup)
335 os.close(self.read)
336 os.close(self.write)
337 signal.signal(signal.SIGALRM, self.alrm)
338
Brian Curtin3f004b12010-08-06 19:34:52 +0000339@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes8640e742008-02-23 16:23:06 +0000340class SiginterruptTest(unittest.TestCase):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000341
Victor Stinnerd6284962011-06-20 23:28:09 +0200342 def readpipe_interrupted(self, interrupt):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000343 """Perform a read during which a signal will arrive. Return True if the
344 read is interrupted by the signal and raises an exception. Return False
345 if it returns normally.
346 """
Victor Stinnerd6284962011-06-20 23:28:09 +0200347 # use a subprocess to have only one thread, to have a timeout on the
348 # blocking read and to not touch signal handling in this process
349 code = """if 1:
350 import errno
351 import os
352 import signal
353 import sys
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000354
Victor Stinnerd6284962011-06-20 23:28:09 +0200355 interrupt = %r
356 r, w = os.pipe()
Christian Heimes8640e742008-02-23 16:23:06 +0000357
Victor Stinnerd6284962011-06-20 23:28:09 +0200358 def handler(signum, frame):
359 pass
360
Victor Stinner45273652011-06-22 22:15:51 +0200361 print("ready")
362 sys.stdout.flush()
363
Victor Stinnerd6284962011-06-20 23:28:09 +0200364 signal.signal(signal.SIGALRM, handler)
365 if interrupt is not None:
366 signal.siginterrupt(signal.SIGALRM, interrupt)
367
368 # run the test twice
369 for loop in range(2):
370 # send a SIGALRM in a second (during the read)
371 signal.alarm(1)
372 try:
373 # blocking call: read from a pipe without data
374 os.read(r, 1)
375 except OSError as err:
376 if err.errno != errno.EINTR:
377 raise
378 else:
379 sys.exit(2)
380 sys.exit(3)
381 """ % (interrupt,)
382 with spawn_python('-c', code) as process:
Christian Heimes8640e742008-02-23 16:23:06 +0000383 try:
Victor Stinner45273652011-06-22 22:15:51 +0200384 # wait until the child process is loaded and has started
385 first_line = process.stdout.readline()
386
Victor Stinnerd6284962011-06-20 23:28:09 +0200387 stdout, stderr = process.communicate(timeout=3.0)
388 except subprocess.TimeoutExpired:
389 process.kill()
Christian Heimes8640e742008-02-23 16:23:06 +0000390 return False
Victor Stinnerd6284962011-06-20 23:28:09 +0200391 else:
Victor Stinner45273652011-06-22 22:15:51 +0200392 stdout = first_line + stdout
Victor Stinnerd6284962011-06-20 23:28:09 +0200393 exitcode = process.wait()
394 if exitcode not in (2, 3):
395 raise Exception("Child error (exit code %s): %s"
396 % (exitcode, stdout))
397 return (exitcode == 3)
Christian Heimes8640e742008-02-23 16:23:06 +0000398
399 def test_without_siginterrupt(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200400 # If a signal handler is installed and siginterrupt is not called
401 # at all, when that signal arrives, it interrupts a syscall that's in
402 # progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200403 interrupted = self.readpipe_interrupted(None)
404 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000405
406 def test_siginterrupt_on(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200407 # If a signal handler is installed and siginterrupt is called with
408 # a true value for the second argument, when that signal arrives, it
409 # interrupts a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200410 interrupted = self.readpipe_interrupted(True)
411 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000412
413 def test_siginterrupt_off(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200414 # If a signal handler is installed and siginterrupt is called with
415 # a false value for the second argument, when that signal arrives, it
416 # does not interrupt a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200417 interrupted = self.readpipe_interrupted(False)
418 self.assertFalse(interrupted)
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000419
420
Brian Curtin3f004b12010-08-06 19:34:52 +0000421@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000422class ItimerTest(unittest.TestCase):
423 def setUp(self):
424 self.hndl_called = False
425 self.hndl_count = 0
426 self.itimer = None
Christian Heimescc47b052008-03-25 14:56:36 +0000427 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000428
429 def tearDown(self):
Christian Heimescc47b052008-03-25 14:56:36 +0000430 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000431 if self.itimer is not None: # test_itimer_exc doesn't change this attr
432 # just ensure that itimer is stopped
433 signal.setitimer(self.itimer, 0)
434
435 def sig_alrm(self, *args):
436 self.hndl_called = True
Martin v. Löwis823725e2008-03-24 13:39:54 +0000437
438 def sig_vtalrm(self, *args):
439 self.hndl_called = True
440
441 if self.hndl_count > 3:
442 # it shouldn't be here, because it should have been disabled.
443 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
444 "timer.")
445 elif self.hndl_count == 3:
446 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
447 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000448
449 self.hndl_count += 1
450
Martin v. Löwis823725e2008-03-24 13:39:54 +0000451 def sig_prof(self, *args):
452 self.hndl_called = True
453 signal.setitimer(signal.ITIMER_PROF, 0)
454
Martin v. Löwis823725e2008-03-24 13:39:54 +0000455 def test_itimer_exc(self):
456 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
457 # defines it ?
458 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Christian Heimescc47b052008-03-25 14:56:36 +0000459 # Negative times are treated as zero on some platforms.
460 if 0:
461 self.assertRaises(signal.ItimerError,
462 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000463
464 def test_itimer_real(self):
465 self.itimer = signal.ITIMER_REAL
Martin v. Löwis823725e2008-03-24 13:39:54 +0000466 signal.setitimer(self.itimer, 1.0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000467 signal.pause()
Martin v. Löwis823725e2008-03-24 13:39:54 +0000468 self.assertEqual(self.hndl_called, True)
469
R. David Murray44546f82010-04-21 01:59:28 +0000470 # Issue 3864, unknown if this affects earlier versions of freebsd also
Gregory P. Smith397cd8a2010-10-17 04:23:21 +0000471 @unittest.skipIf(sys.platform in ('freebsd6', 'netbsd5'),
472 'itimer not reliable (does not mix well with threading) on some BSDs.')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000473 def test_itimer_virtual(self):
474 self.itimer = signal.ITIMER_VIRTUAL
475 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
476 signal.setitimer(self.itimer, 0.3, 0.2)
477
Mark Dickinson78373472009-10-31 10:39:21 +0000478 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000479 while time.time() - start_time < 60.0:
Mark Dickinson95078872009-10-04 18:47:48 +0000480 # use up some virtual time by doing real work
481 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000482 if signal.getitimer(self.itimer) == (0.0, 0.0):
483 break # sig_vtalrm handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000484 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000485 self.skipTest("timeout: likely cause: machine too slow or load too "
486 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000487
488 # virtual itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000489 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Martin v. Löwis823725e2008-03-24 13:39:54 +0000490 # and the handler should have been called
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000491 self.assertEqual(self.hndl_called, True)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000492
R. David Murray44546f82010-04-21 01:59:28 +0000493 # Issue 3864, unknown if this affects earlier versions of freebsd also
494 @unittest.skipIf(sys.platform=='freebsd6',
495 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000496 def test_itimer_prof(self):
497 self.itimer = signal.ITIMER_PROF
498 signal.signal(signal.SIGPROF, self.sig_prof)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000499 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000500
Mark Dickinson78373472009-10-31 10:39:21 +0000501 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000502 while time.time() - start_time < 60.0:
Mark Dickinson78373472009-10-31 10:39:21 +0000503 # do some work
504 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000505 if signal.getitimer(self.itimer) == (0.0, 0.0):
506 break # sig_prof handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000507 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000508 self.skipTest("timeout: likely cause: machine too slow or load too "
509 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000510
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000511 # profiling itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000512 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000513 # and the handler should have been called
Martin v. Löwis823725e2008-03-24 13:39:54 +0000514 self.assertEqual(self.hndl_called, True)
515
Victor Stinnera9293352011-04-30 15:21:58 +0200516
Victor Stinner35b300c2011-05-04 13:20:35 +0200517class PendingSignalsTests(unittest.TestCase):
518 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200519 Test pthread_sigmask(), pthread_kill(), sigpending() and sigwait()
520 functions.
Victor Stinner35b300c2011-05-04 13:20:35 +0200521 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200522 def setUp(self):
523 self.has_pthread_kill = hasattr(signal, 'pthread_kill')
524
Victor Stinner35b300c2011-05-04 13:20:35 +0200525 def handler(self, signum, frame):
526 1/0
527
528 def read_sigmask(self):
529 return signal.pthread_sigmask(signal.SIG_BLOCK, [])
530
Victor Stinnerb3e72192011-05-08 01:46:11 +0200531 def can_test_blocked_signals(self, skip):
532 """
533 Check if a blocked signal can be raised to the main thread without
534 calling its signal handler. We need pthread_kill() or exactly one
535 thread (the main thread).
Victor Stinnera9293352011-04-30 15:21:58 +0200536
Victor Stinnerb3e72192011-05-08 01:46:11 +0200537 Return True if it's possible. Otherwise, return False and print a
538 warning if skip is False, or raise a SkipTest exception if skip is
539 True.
540 """
541 if self.has_pthread_kill:
542 return True
Victor Stinnera9293352011-04-30 15:21:58 +0200543
Victor Stinnerf44ce872011-05-03 17:20:31 +0200544 # The fault handler timeout thread masks all signals. If the main
545 # thread masks also SIGUSR1, all threads mask this signal. In this
546 # case, if we send SIGUSR1 to the process, the signal is pending in the
547 # main or the faulthandler timeout thread. Unblock SIGUSR1 in the main
548 # thread calls the signal handler only if the signal is pending for the
Victor Stinnerb3e72192011-05-08 01:46:11 +0200549 # main thread. Stop the faulthandler timeout thread to workaround this
550 # problem.
551 import faulthandler
Victor Stinnerf44ce872011-05-03 17:20:31 +0200552 faulthandler.cancel_dump_tracebacks_later()
Victor Stinner2d4a91e2011-05-03 14:11:22 +0200553
Victor Stinnerb3e72192011-05-08 01:46:11 +0200554 # Issue #11998: The _tkinter module loads the Tcl library which
555 # creates a thread waiting events in select(). This thread receives
556 # signals blocked by all other threads. We cannot test blocked
557 # signals
558 if '_tkinter' in sys.modules:
559 message = ("_tkinter is loaded and pthread_kill() is missing, "
560 "cannot test blocked signals (issue #11998)")
561 if skip:
562 self.skipTest(message)
563 else:
564 print("WARNING: %s" % message)
565 return False
566 return True
567
568 def kill(self, signum):
569 if self.has_pthread_kill:
Victor Stinner2a129742011-05-30 23:02:52 +0200570 tid = threading.get_ident()
Victor Stinnerb3e72192011-05-08 01:46:11 +0200571 signal.pthread_kill(tid, signum)
572 else:
573 pid = os.getpid()
574 os.kill(pid, signum)
575
576 @unittest.skipUnless(hasattr(signal, 'sigpending'),
577 'need signal.sigpending()')
578 def test_sigpending_empty(self):
579 self.assertEqual(signal.sigpending(), set())
580
581 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
582 'need signal.pthread_sigmask()')
583 @unittest.skipUnless(hasattr(signal, 'sigpending'),
584 'need signal.sigpending()')
585 def test_sigpending(self):
586 self.can_test_blocked_signals(True)
587
588 signum = signal.SIGUSR1
589 old_handler = signal.signal(signum, self.handler)
590 self.addCleanup(signal.signal, signum, old_handler)
591
592 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
593 self.kill(signum)
594 self.assertEqual(signal.sigpending(), {signum})
595 with self.assertRaises(ZeroDivisionError):
596 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
597
598 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
599 'need signal.pthread_kill()')
600 def test_pthread_kill(self):
601 signum = signal.SIGUSR1
Victor Stinner2a129742011-05-30 23:02:52 +0200602 current = threading.get_ident()
Victor Stinnerb3e72192011-05-08 01:46:11 +0200603
604 old_handler = signal.signal(signum, self.handler)
605 self.addCleanup(signal.signal, signum, old_handler)
606
607 with self.assertRaises(ZeroDivisionError):
608 signal.pthread_kill(current, signum)
609
Victor Stinner7f294d12011-06-10 14:02:10 +0200610 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
611 'need signal.pthread_sigmask()')
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200612 def wait_helper(self, test, blocked):
613 """
614 test: body of the "def test(signum):" function.
615 blocked: number of the blocked signal
616 """
617 code = '''
618import signal
619import sys
620
621def handler(signum, frame):
622 1/0
623
624def test(signum):
625%s
626
627blocked = %s
628signum = signal.SIGALRM
629
630# child: block and wait the signal
631try:
632 signal.signal(signum, handler)
633 signal.pthread_sigmask(signal.SIG_BLOCK, [blocked])
634
635 # Do the tests
636 test(signum)
637
638 # The handler must not be called on unblock
639 try:
640 signal.pthread_sigmask(signal.SIG_UNBLOCK, [blocked])
641 except ZeroDivisionError:
642 print("the signal handler has been called",
643 file=sys.stderr)
644 sys.exit(1)
645except BaseException as err:
646 print("error: {}".format(err), file=sys.stderr)
647 sys.stderr.flush()
648 sys.exit(1)
649''' % (test, blocked)
Victor Stinner415007e2011-06-13 16:19:06 +0200650
Ross Lagerwallbc808222011-06-25 12:13:40 +0200651 # sig*wait* must be called with the signal blocked: since the current
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200652 # process might have several threads running, use a subprocess to have
653 # a single thread.
654 assert_python_ok('-c', code)
Victor Stinneraf494602011-06-10 12:48:13 +0200655
Victor Stinnerb3e72192011-05-08 01:46:11 +0200656 @unittest.skipUnless(hasattr(signal, 'sigwait'),
657 'need signal.sigwait()')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200658 def test_sigwait(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200659 test = '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200660 signal.alarm(1)
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200661 received = signal.sigwait([signum])
662 assert received == signum , 'received %s, not %s' % (received, signum)
663 '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200664
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200665 self.wait_helper(test, signal.SIGALRM)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200666
667 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
668 'need signal.sigwaitinfo()')
669 def test_sigwaitinfo(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200670 test = '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200671 signal.alarm(1)
672 info = signal.sigwaitinfo([signum])
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200673 assert info.si_signo == signum, "info.si_signo != %s" % signum
674 '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200675
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200676 self.wait_helper(test, signal.SIGALRM)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200677
678 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
679 'need signal.sigtimedwait()')
680 def test_sigtimedwait(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200681 test = '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200682 signal.alarm(1)
683 info = signal.sigtimedwait([signum], (10, 1000))
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200684 assert info.si_signo == signum, 'info.si_signo != %s' % signum
685 '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200686
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200687 self.wait_helper(test, signal.SIGALRM)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200688
Ross Lagerwallbc808222011-06-25 12:13:40 +0200689 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
690 'need signal.sigtimedwait()')
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200691 # issue #12303: sigtimedwait() takes 30 seconds on FreeBSD 6 (kernel bug)
692 @unittest.skipIf(sys.platform =='freebsd6',
693 'sigtimedwait() with a null timeout doens\'t work on FreeBSD 6')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200694 def test_sigtimedwait_poll(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200695 # check that polling with sigtimedwait works
696 test = '''
697 import os
698 os.kill(os.getpid(), signum)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200699 info = signal.sigtimedwait([signum], (0, 0))
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200700 assert info.si_signo == signum, 'info.si_signo != %s' % signum
701 '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200702
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200703 self.wait_helper(test, signal.SIGALRM)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200704
705 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
706 'need signal.sigtimedwait()')
707 def test_sigtimedwait_timeout(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200708 test = '''
709 received = signal.sigtimedwait([signum], (1, 0))
710 assert received is None, "received=%r" % (received,)
711 '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200712
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200713 self.wait_helper(test, signal.SIGALRM)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200714
715 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
716 'need signal.sigtimedwait()')
717 def test_sigtimedwait_negative_timeout(self):
718 signum = signal.SIGALRM
719 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, -1))
720 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (0, -1))
721 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, 0))
722
Ross Lagerwallbc808222011-06-25 12:13:40 +0200723 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
724 'need signal.sigwaitinfo()')
725 def test_sigwaitinfo_interrupted(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200726 test = '''
727 import errno
728
729 hndl_called = True
730 def alarm_handler(signum, frame):
731 hndl_called = False
732
733 signal.signal(signal.SIGALRM, alarm_handler)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200734 signal.alarm(1)
735 try:
736 signal.sigwaitinfo([signal.SIGUSR1])
737 except OSError as e:
738 if e.errno == errno.EINTR:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200739 assert hndl_called, "SIGALRM handler not called"
Ross Lagerwallbc808222011-06-25 12:13:40 +0200740 else:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200741 raise Exception("Expected EINTR to be raised by sigwaitinfo")
Ross Lagerwallbc808222011-06-25 12:13:40 +0200742 else:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200743 raise Exception("Expected EINTR to be raised by sigwaitinfo")
744 '''
Ross Lagerwallbc808222011-06-25 12:13:40 +0200745
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200746 self.wait_helper(test, signal.SIGUSR1)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200747
748 @unittest.skipUnless(hasattr(signal, 'sigwait'),
749 'need signal.sigwait()')
Victor Stinner415007e2011-06-13 16:19:06 +0200750 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
751 'need signal.pthread_sigmask()')
Victor Stinner10c30d62011-06-10 01:39:53 +0200752 @unittest.skipIf(threading is None, "test needs threading module")
753 def test_sigwait_thread(self):
Victor Stinner415007e2011-06-13 16:19:06 +0200754 # Check that calling sigwait() from a thread doesn't suspend the whole
755 # process. A new interpreter is spawned to avoid problems when mixing
756 # threads and fork(): only async-safe functions are allowed between
757 # fork() and exec().
758 assert_python_ok("-c", """if True:
759 import os, threading, sys, time, signal
Victor Stinner10c30d62011-06-10 01:39:53 +0200760
Victor Stinner415007e2011-06-13 16:19:06 +0200761 # the default handler terminates the process
762 signum = signal.SIGUSR1
763
764 def kill_later():
765 # wait until the main thread is waiting in sigwait()
766 time.sleep(1)
767 os.kill(os.getpid(), signum)
768
769 # the signal must be blocked by all the threads
770 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
771 killer = threading.Thread(target=kill_later)
Victor Stinneraf494602011-06-10 12:48:13 +0200772 killer.start()
773 received = signal.sigwait([signum])
774 if received != signum:
775 print("sigwait() received %s, not %s" % (received, signum),
776 file=sys.stderr)
Victor Stinner415007e2011-06-13 16:19:06 +0200777 sys.exit(1)
Victor Stinner10c30d62011-06-10 01:39:53 +0200778 killer.join()
Victor Stinner415007e2011-06-13 16:19:06 +0200779 # unblock the signal, which should have been cleared by sigwait()
780 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
781 """)
Victor Stinneraf494602011-06-10 12:48:13 +0200782
Victor Stinnerb3e72192011-05-08 01:46:11 +0200783 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
784 'need signal.pthread_sigmask()')
785 def test_pthread_sigmask_arguments(self):
786 self.assertRaises(TypeError, signal.pthread_sigmask)
787 self.assertRaises(TypeError, signal.pthread_sigmask, 1)
788 self.assertRaises(TypeError, signal.pthread_sigmask, 1, 2, 3)
789 self.assertRaises(OSError, signal.pthread_sigmask, 1700, [])
790
791 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
792 'need signal.pthread_sigmask()')
793 def test_pthread_sigmask(self):
794 test_blocked_signals = self.can_test_blocked_signals(False)
795 signum = signal.SIGUSR1
Victor Stinner6fd49e12011-05-04 12:38:03 +0200796
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200797 # Install our signal handler
Victor Stinner35b300c2011-05-04 13:20:35 +0200798 old_handler = signal.signal(signum, self.handler)
Victor Stinnera9293352011-04-30 15:21:58 +0200799 self.addCleanup(signal.signal, signum, old_handler)
800
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200801 # Unblock SIGUSR1 (and copy the old mask) to test our signal handler
Victor Stinnera9293352011-04-30 15:21:58 +0200802 old_mask = signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
803 self.addCleanup(signal.pthread_sigmask, signal.SIG_SETMASK, old_mask)
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200804 with self.assertRaises(ZeroDivisionError):
Victor Stinnerb3e72192011-05-08 01:46:11 +0200805 self.kill(signum)
Victor Stinnera9293352011-04-30 15:21:58 +0200806
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200807 # Block and then raise SIGUSR1. The signal is blocked: the signal
808 # handler is not called, and the signal is now pending
Victor Stinnera9293352011-04-30 15:21:58 +0200809 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
Victor Stinnerb3e72192011-05-08 01:46:11 +0200810 if test_blocked_signals:
811 self.kill(signum)
Victor Stinnera9293352011-04-30 15:21:58 +0200812
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200813 # Check the new mask
Victor Stinner35b300c2011-05-04 13:20:35 +0200814 blocked = self.read_sigmask()
Victor Stinnera9293352011-04-30 15:21:58 +0200815 self.assertIn(signum, blocked)
Victor Stinner35b300c2011-05-04 13:20:35 +0200816 self.assertEqual(old_mask ^ blocked, {signum})
Victor Stinnera9293352011-04-30 15:21:58 +0200817
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200818 # Unblock SIGUSR1
Victor Stinnerb3e72192011-05-08 01:46:11 +0200819 if test_blocked_signals:
Victor Stinner6fd49e12011-05-04 12:38:03 +0200820 with self.assertRaises(ZeroDivisionError):
821 # unblock the pending signal calls immediatly the signal handler
822 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
823 else:
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200824 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
825 with self.assertRaises(ZeroDivisionError):
Victor Stinnerb3e72192011-05-08 01:46:11 +0200826 self.kill(signum)
Victor Stinnera9293352011-04-30 15:21:58 +0200827
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200828 # Check the new mask
Victor Stinner35b300c2011-05-04 13:20:35 +0200829 unblocked = self.read_sigmask()
Victor Stinnera9293352011-04-30 15:21:58 +0200830 self.assertNotIn(signum, unblocked)
Victor Stinner35b300c2011-05-04 13:20:35 +0200831 self.assertEqual(blocked ^ unblocked, {signum})
Victor Stinnera9293352011-04-30 15:21:58 +0200832 self.assertSequenceEqual(old_mask, unblocked)
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200833 # Finally, restore the previous signal handler and the signal mask
Victor Stinnera9293352011-04-30 15:21:58 +0200834
835
Thomas Woutersed03b412007-08-28 21:37:11 +0000836def test_main():
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100837 try:
Victor Stinnerb3e72192011-05-08 01:46:11 +0200838 support.run_unittest(PosixTests, InterProcessSignalTests,
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100839 WakeupSignalTests, SiginterruptTest,
Victor Stinnera9293352011-04-30 15:21:58 +0200840 ItimerTest, WindowsSignalTests,
Victor Stinner35b300c2011-05-04 13:20:35 +0200841 PendingSignalsTests)
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100842 finally:
843 support.reap_children()
Thomas Woutersed03b412007-08-28 21:37:11 +0000844
845
846if __name__ == "__main__":
847 test_main()