blob: 8df1bf0a192323df2d5234b4088466cf0b8e13c5 [file] [log] [blame]
Victor Stinner8d642482011-07-01 15:24:50 +02001import errno
Christian Heimescc47b052008-03-25 14:56:36 +00002import gc
Victor Stinner8d642482011-07-01 15:24:50 +02003import os
Christian Heimes4fbc72b2008-03-22 00:47:35 +00004import pickle
5import select
Guido van Rossum4f17e3e1995-03-16 15:07:38 +00006import signal
Christian Heimes4fbc72b2008-03-22 00:47:35 +00007import subprocess
Victor Stinner8d642482011-07-01 15:24:50 +02008import sys
9import time
Christian Heimes4fbc72b2008-03-22 00:47:35 +000010import traceback
Victor Stinner8d642482011-07-01 15:24:50 +020011import unittest
12from test import support
13from contextlib import closing
Victor Stinnere40b3aa2011-07-04 17:35:10 +020014from test.script_helper import assert_python_ok, spawn_python
Christian Heimesc06950e2008-02-28 21:17:00 +000015
Brian Curtin912443c2010-09-06 16:10:04 +000016if sys.platform in ('os2', 'riscos'):
17 raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
Christian Heimesc06950e2008-02-28 21:17:00 +000018
Guido van Rossumcc5a91d1997-04-16 00:29:15 +000019
Armin Rigo8b2cbfd2004-08-07 21:27:43 +000020class HandlerBCalled(Exception):
21 pass
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000022
Christian Heimes4fbc72b2008-03-22 00:47:35 +000023
24def exit_subprocess():
25 """Use os._exit(0) to exit the current subprocess.
26
27 Otherwise, the test catches the SystemExit and continues executing
28 in parallel with the original test, so you wind up with an
29 exponential number of tests running concurrently.
30 """
31 os._exit(0)
32
33
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000034def ignoring_eintr(__func, *args, **kwargs):
35 try:
36 return __func(*args, **kwargs)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +000037 except EnvironmentError as e:
38 if e.errno != errno.EINTR:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000039 raise
40 return None
41
42
Brian Curtin3f004b12010-08-06 19:34:52 +000043@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Thomas Woutersed03b412007-08-28 21:37:11 +000044class InterProcessSignalTests(unittest.TestCase):
45 MAX_DURATION = 20 # Entire test should last at most 20 sec.
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000046
Christian Heimescc47b052008-03-25 14:56:36 +000047 def setUp(self):
48 self.using_gc = gc.isenabled()
49 gc.disable()
50
51 def tearDown(self):
52 if self.using_gc:
53 gc.enable()
54
Christian Heimes5e696852008-04-09 08:37:03 +000055 def format_frame(self, frame, limit=None):
56 return ''.join(traceback.format_stack(frame, limit=limit))
57
58 def handlerA(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000059 self.a_called = True
Benjamin Petersonee8712c2008-05-20 21:35:26 +000060 if support.verbose:
Christian Heimes5e696852008-04-09 08:37:03 +000061 print("handlerA invoked from signal %s at:\n%s" % (
62 signum, self.format_frame(frame, limit=1)))
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000063
Christian Heimes5e696852008-04-09 08:37:03 +000064 def handlerB(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000065 self.b_called = True
Benjamin Petersonee8712c2008-05-20 21:35:26 +000066 if support.verbose:
Christian Heimes5e696852008-04-09 08:37:03 +000067 print ("handlerB invoked from signal %s at:\n%s" % (
68 signum, self.format_frame(frame, limit=1)))
69 raise HandlerBCalled(signum, self.format_frame(frame))
Neal Norwitz9730bcb2006-01-23 07:50:06 +000070
Christian Heimes4fbc72b2008-03-22 00:47:35 +000071 def wait(self, child):
72 """Wait for child to finish, ignoring EINTR."""
73 while True:
74 try:
75 child.wait()
76 return
77 except OSError as e:
78 if e.errno != errno.EINTR:
79 raise
Fred Drake004d5e62000-10-23 17:22:08 +000080
Christian Heimes4fbc72b2008-03-22 00:47:35 +000081 def run_test(self):
82 # Install handlers. This function runs in a sub-process, so we
83 # don't worry about re-setting the default handlers.
84 signal.signal(signal.SIGHUP, self.handlerA)
85 signal.signal(signal.SIGUSR1, self.handlerB)
86 signal.signal(signal.SIGUSR2, signal.SIG_IGN)
87 signal.signal(signal.SIGALRM, signal.default_int_handler)
Michael W. Hudson5c26e862004-06-11 18:09:28 +000088
Christian Heimes4fbc72b2008-03-22 00:47:35 +000089 # Variables the signals will modify:
90 self.a_called = False
91 self.b_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000092
Christian Heimes4fbc72b2008-03-22 00:47:35 +000093 # Let the sub-processes know who to send signals to.
94 pid = os.getpid()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000095 if support.verbose:
Thomas Woutersed03b412007-08-28 21:37:11 +000096 print("test runner's pid is", pid)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000097
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000098 child = ignoring_eintr(subprocess.Popen, ['kill', '-HUP', str(pid)])
99 if child:
100 self.wait(child)
101 if not self.a_called:
102 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000103 self.assertTrue(self.a_called)
104 self.assertFalse(self.b_called)
105 self.a_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000106
Christian Heimes5e696852008-04-09 08:37:03 +0000107 # Make sure the signal isn't delivered while the previous
108 # Popen object is being destroyed, because __del__ swallows
109 # exceptions.
110 del child
Thomas Woutersed03b412007-08-28 21:37:11 +0000111 try:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000112 child = subprocess.Popen(['kill', '-USR1', str(pid)])
113 # This wait should be interrupted by the signal's exception.
114 self.wait(child)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000115 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000116 self.fail('HandlerBCalled exception not thrown')
117 except HandlerBCalled:
118 self.assertTrue(self.b_called)
119 self.assertFalse(self.a_called)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000120 if support.verbose:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000121 print("HandlerBCalled exception caught")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000122
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000123 child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)])
124 if child:
125 self.wait(child) # Nothing should happen.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000126
127 try:
128 signal.alarm(1)
129 # The race condition in pause doesn't matter in this case,
130 # since alarm is going to raise a KeyboardException, which
131 # will skip the call.
132 signal.pause()
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000133 # But if another signal arrives before the alarm, pause
134 # may return early.
135 time.sleep(1)
Thomas Woutersed03b412007-08-28 21:37:11 +0000136 except KeyboardInterrupt:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000137 if support.verbose:
Thomas Woutersed03b412007-08-28 21:37:11 +0000138 print("KeyboardInterrupt (the alarm() went off)")
Thomas Woutersed03b412007-08-28 21:37:11 +0000139 except:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000140 self.fail("Some other exception woke us from pause: %s" %
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000141 traceback.format_exc())
142 else:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000143 self.fail("pause returned of its own accord, and the signal"
144 " didn't arrive after another second.")
Thomas Woutersed03b412007-08-28 21:37:11 +0000145
R. David Murray44546f82010-04-21 01:59:28 +0000146 # Issue 3864, unknown if this affects earlier versions of freebsd also
147 @unittest.skipIf(sys.platform=='freebsd6',
148 'inter process signals not reliable (do not mix well with threading) '
149 'on freebsd6')
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000150 def test_main(self):
151 # This function spawns a child process to insulate the main
152 # test-running process from all the signals. It then
153 # communicates with that child process over a pipe and
154 # re-raises information about any exceptions the child
155 # throws. The real work happens in self.run_test().
156 os_done_r, os_done_w = os.pipe()
Raymond Hettinger686057b2009-06-04 00:11:54 +0000157 with closing(os.fdopen(os_done_r, 'rb')) as done_r, \
158 closing(os.fdopen(os_done_w, 'wb')) as done_w:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000159 child = os.fork()
160 if child == 0:
161 # In the child process; run the test and report results
162 # through the pipe.
163 try:
164 done_r.close()
165 # Have to close done_w again here because
166 # exit_subprocess() will skip the enclosing with block.
167 with closing(done_w):
168 try:
169 self.run_test()
170 except:
171 pickle.dump(traceback.format_exc(), done_w)
172 else:
173 pickle.dump(None, done_w)
174 except:
175 print('Uh oh, raised from pickle.')
176 traceback.print_exc()
177 finally:
178 exit_subprocess()
179
180 done_w.close()
181 # Block for up to MAX_DURATION seconds for the test to finish.
182 r, w, x = select.select([done_r], [], [], self.MAX_DURATION)
183 if done_r in r:
184 tb = pickle.load(done_r)
185 if tb:
186 self.fail(tb)
187 else:
188 os.kill(child, signal.SIGKILL)
189 self.fail('Test deadlocked after %d seconds.' %
190 self.MAX_DURATION)
Thomas Woutersed03b412007-08-28 21:37:11 +0000191
192
Brian Curtin3f004b12010-08-06 19:34:52 +0000193@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Thomas Woutersed03b412007-08-28 21:37:11 +0000194class BasicSignalTests(unittest.TestCase):
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000195 def trivial_signal_handler(self, *args):
196 pass
197
Thomas Woutersed03b412007-08-28 21:37:11 +0000198 def test_out_of_range_signal_number_raises_error(self):
199 self.assertRaises(ValueError, signal.getsignal, 4242)
200
Thomas Woutersed03b412007-08-28 21:37:11 +0000201 self.assertRaises(ValueError, signal.signal, 4242,
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000202 self.trivial_signal_handler)
Thomas Woutersed03b412007-08-28 21:37:11 +0000203
204 def test_setting_signal_handler_to_none_raises_error(self):
205 self.assertRaises(TypeError, signal.signal,
206 signal.SIGUSR1, None)
207
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000208 def test_getsignal(self):
209 hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000210 self.assertEqual(signal.getsignal(signal.SIGHUP),
211 self.trivial_signal_handler)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000212 signal.signal(signal.SIGHUP, hup)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000213 self.assertEqual(signal.getsignal(signal.SIGHUP), hup)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000214
215
Brian Curtin3f004b12010-08-06 19:34:52 +0000216@unittest.skipUnless(sys.platform == "win32", "Windows specific")
217class WindowsSignalTests(unittest.TestCase):
218 def test_issue9324(self):
Brian Curtineccd4d92010-10-01 15:09:53 +0000219 # Updated for issue #10003, adding SIGBREAK
Brian Curtin3f004b12010-08-06 19:34:52 +0000220 handler = lambda x, y: None
Brian Curtineccd4d92010-10-01 15:09:53 +0000221 for sig in (signal.SIGABRT, signal.SIGBREAK, signal.SIGFPE,
222 signal.SIGILL, signal.SIGINT, signal.SIGSEGV,
223 signal.SIGTERM):
224 # Set and then reset a handler for signals that work on windows
225 signal.signal(sig, signal.signal(sig, handler))
Brian Curtin3f004b12010-08-06 19:34:52 +0000226
227 with self.assertRaises(ValueError):
228 signal.signal(-1, handler)
Brian Curtin80cd4bf2010-08-07 03:52:38 +0000229
230 with self.assertRaises(ValueError):
231 signal.signal(7, handler)
Brian Curtin3f004b12010-08-06 19:34:52 +0000232
233
234@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000235class WakeupSignalTests(unittest.TestCase):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200236 def check_wakeup(self, test_body):
237 # use a subprocess to have only one thread and to not change signal
238 # handling of the parent process
239 code = """if 1:
240 import fcntl
241 import os
242 import signal
243
244 def handler(signum, frame):
245 pass
246
247 {}
248
249 signal.signal(signal.SIGALRM, handler)
250 read, write = os.pipe()
251 flags = fcntl.fcntl(write, fcntl.F_GETFL, 0)
252 flags = flags | os.O_NONBLOCK
253 fcntl.fcntl(write, fcntl.F_SETFL, flags)
254 signal.set_wakeup_fd(write)
255
256 test()
257
258 os.close(read)
259 os.close(write)
260 """.format(test_body)
261
262 assert_python_ok('-c', code)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000263
264 def test_wakeup_fd_early(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200265 self.check_wakeup("""def test():
266 import select
267 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000268
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200269 TIMEOUT_FULL = 10
270 TIMEOUT_HALF = 5
271
272 signal.alarm(1)
273 before_time = time.time()
274 # We attempt to get a signal during the sleep,
275 # before select is called
276 time.sleep(TIMEOUT_FULL)
277 mid_time = time.time()
278 dt = mid_time - before_time
279 if dt >= TIMEOUT_HALF:
280 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
281 select.select([read], [], [], TIMEOUT_FULL)
282 after_time = time.time()
283 dt = after_time - mid_time
284 if dt >= TIMEOUT_HALF:
285 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
286 """)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000287
288 def test_wakeup_fd_during(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200289 self.check_wakeup("""def test():
290 import select
291 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000292
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200293 TIMEOUT_FULL = 10
294 TIMEOUT_HALF = 5
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000295
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200296 signal.alarm(1)
297 before_time = time.time()
298 # We attempt to get a signal during the select call
299 try:
300 select.select([read], [], [], TIMEOUT_FULL)
301 except select.error:
302 pass
303 else:
304 raise Exception("select.error not raised")
305 after_time = time.time()
306 dt = after_time - before_time
307 if dt >= TIMEOUT_HALF:
308 raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
309 """)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000310
Brian Curtin3f004b12010-08-06 19:34:52 +0000311@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes8640e742008-02-23 16:23:06 +0000312class SiginterruptTest(unittest.TestCase):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000313
Victor Stinner8d642482011-07-01 15:24:50 +0200314 def readpipe_interrupted(self, interrupt):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000315 """Perform a read during which a signal will arrive. Return True if the
316 read is interrupted by the signal and raises an exception. Return False
317 if it returns normally.
318 """
Victor Stinner8d642482011-07-01 15:24:50 +0200319 class Timeout(Exception):
320 pass
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000321
Victor Stinner8d642482011-07-01 15:24:50 +0200322 # use a subprocess to have only one thread, to have a timeout on the
323 # blocking read and to not touch signal handling in this process
324 code = """if 1:
325 import errno
326 import os
327 import signal
328 import sys
Christian Heimes8640e742008-02-23 16:23:06 +0000329
Victor Stinner8d642482011-07-01 15:24:50 +0200330 interrupt = %r
331 r, w = os.pipe()
332
333 def handler(signum, frame):
334 pass
335
Victor Stinner8d642482011-07-01 15:24:50 +0200336 signal.signal(signal.SIGALRM, handler)
337 if interrupt is not None:
338 signal.siginterrupt(signal.SIGALRM, interrupt)
339
Victor Stinnerdfde0d42011-07-01 15:58:39 +0200340 print("ready")
341 sys.stdout.flush()
342
Victor Stinner8d642482011-07-01 15:24:50 +0200343 # run the test twice
344 for loop in range(2):
345 # send a SIGALRM in a second (during the read)
346 signal.alarm(1)
347 try:
348 # blocking call: read from a pipe without data
349 os.read(r, 1)
350 except OSError as err:
351 if err.errno != errno.EINTR:
352 raise
353 else:
354 sys.exit(2)
355 sys.exit(3)
356 """ % (interrupt,)
357 with spawn_python('-c', code) as process:
Christian Heimes8640e742008-02-23 16:23:06 +0000358 try:
Victor Stinner8d642482011-07-01 15:24:50 +0200359 # wait until the child process is loaded and has started
360 first_line = process.stdout.readline()
Christian Heimes8640e742008-02-23 16:23:06 +0000361
Victor Stinnerdfde0d42011-07-01 15:58:39 +0200362 # Wait the process with a timeout of 5 seconds
363 timeout = time.time() + 5.0
Victor Stinner8d642482011-07-01 15:24:50 +0200364 while True:
365 if timeout < time.time():
366 raise Timeout()
367 status = process.poll()
368 if status is not None:
369 break
370 time.sleep(0.1)
Christian Heimes8640e742008-02-23 16:23:06 +0000371
Victor Stinner8d642482011-07-01 15:24:50 +0200372 stdout, stderr = process.communicate()
373 except Timeout:
374 process.kill()
Christian Heimes8640e742008-02-23 16:23:06 +0000375 return False
Victor Stinner8d642482011-07-01 15:24:50 +0200376 else:
377 stdout = first_line + stdout
378 exitcode = process.wait()
379 if exitcode not in (2, 3):
380 raise Exception("Child error (exit code %s): %s"
381 % (exitcode, stdout))
382 return (exitcode == 3)
Christian Heimes8640e742008-02-23 16:23:06 +0000383
384 def test_without_siginterrupt(self):
Victor Stinner8d642482011-07-01 15:24:50 +0200385 # If a signal handler is installed and siginterrupt is not called
386 # at all, when that signal arrives, it interrupts a syscall that's in
387 # progress.
388 interrupted = self.readpipe_interrupted(None)
389 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000390
391 def test_siginterrupt_on(self):
Victor Stinner8d642482011-07-01 15:24:50 +0200392 # If a signal handler is installed and siginterrupt is called with
393 # a true value for the second argument, when that signal arrives, it
394 # interrupts a syscall that's in progress.
395 interrupted = self.readpipe_interrupted(True)
396 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000397
398 def test_siginterrupt_off(self):
Victor Stinner8d642482011-07-01 15:24:50 +0200399 # If a signal handler is installed and siginterrupt is called with
400 # a false value for the second argument, when that signal arrives, it
401 # does not interrupt a syscall that's in progress.
402 interrupted = self.readpipe_interrupted(False)
403 self.assertFalse(interrupted)
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000404
405
Brian Curtin3f004b12010-08-06 19:34:52 +0000406@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000407class ItimerTest(unittest.TestCase):
408 def setUp(self):
409 self.hndl_called = False
410 self.hndl_count = 0
411 self.itimer = None
Christian Heimescc47b052008-03-25 14:56:36 +0000412 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000413
414 def tearDown(self):
Christian Heimescc47b052008-03-25 14:56:36 +0000415 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000416 if self.itimer is not None: # test_itimer_exc doesn't change this attr
417 # just ensure that itimer is stopped
418 signal.setitimer(self.itimer, 0)
419
420 def sig_alrm(self, *args):
421 self.hndl_called = True
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000422 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000423 print("SIGALRM handler invoked", args)
424
425 def sig_vtalrm(self, *args):
426 self.hndl_called = True
427
428 if self.hndl_count > 3:
429 # it shouldn't be here, because it should have been disabled.
430 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
431 "timer.")
432 elif self.hndl_count == 3:
433 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
434 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000435 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000436 print("last SIGVTALRM handler call")
437
438 self.hndl_count += 1
439
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000440 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000441 print("SIGVTALRM handler invoked", args)
442
443 def sig_prof(self, *args):
444 self.hndl_called = True
445 signal.setitimer(signal.ITIMER_PROF, 0)
446
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000447 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000448 print("SIGPROF handler invoked", args)
449
450 def test_itimer_exc(self):
451 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
452 # defines it ?
453 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Christian Heimescc47b052008-03-25 14:56:36 +0000454 # Negative times are treated as zero on some platforms.
455 if 0:
456 self.assertRaises(signal.ItimerError,
457 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000458
459 def test_itimer_real(self):
460 self.itimer = signal.ITIMER_REAL
Martin v. Löwis823725e2008-03-24 13:39:54 +0000461 signal.setitimer(self.itimer, 1.0)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000462 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000463 print("\ncall pause()...")
464 signal.pause()
465
466 self.assertEqual(self.hndl_called, True)
467
R. David Murray44546f82010-04-21 01:59:28 +0000468 # Issue 3864, unknown if this affects earlier versions of freebsd also
Gregory P. Smith397cd8a2010-10-17 04:23:21 +0000469 @unittest.skipIf(sys.platform in ('freebsd6', 'netbsd5'),
470 'itimer not reliable (does not mix well with threading) on some BSDs.')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000471 def test_itimer_virtual(self):
472 self.itimer = signal.ITIMER_VIRTUAL
473 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
474 signal.setitimer(self.itimer, 0.3, 0.2)
475
Mark Dickinson78373472009-10-31 10:39:21 +0000476 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000477 while time.time() - start_time < 60.0:
Mark Dickinson95078872009-10-04 18:47:48 +0000478 # use up some virtual time by doing real work
479 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000480 if signal.getitimer(self.itimer) == (0.0, 0.0):
481 break # sig_vtalrm handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000482 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000483 self.skipTest("timeout: likely cause: machine too slow or load too "
484 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000485
486 # virtual itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000487 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Martin v. Löwis823725e2008-03-24 13:39:54 +0000488 # and the handler should have been called
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000489 self.assertEqual(self.hndl_called, True)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000490
R. David Murray44546f82010-04-21 01:59:28 +0000491 # Issue 3864, unknown if this affects earlier versions of freebsd also
492 @unittest.skipIf(sys.platform=='freebsd6',
493 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000494 def test_itimer_prof(self):
495 self.itimer = signal.ITIMER_PROF
496 signal.signal(signal.SIGPROF, self.sig_prof)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000497 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000498
Mark Dickinson78373472009-10-31 10:39:21 +0000499 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000500 while time.time() - start_time < 60.0:
Mark Dickinson78373472009-10-31 10:39:21 +0000501 # do some work
502 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000503 if signal.getitimer(self.itimer) == (0.0, 0.0):
504 break # sig_prof handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000505 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000506 self.skipTest("timeout: likely cause: machine too slow or load too "
507 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000508
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000509 # profiling itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000510 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000511 # and the handler should have been called
Martin v. Löwis823725e2008-03-24 13:39:54 +0000512 self.assertEqual(self.hndl_called, True)
513
Thomas Woutersed03b412007-08-28 21:37:11 +0000514def test_main():
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100515 try:
516 support.run_unittest(BasicSignalTests, InterProcessSignalTests,
517 WakeupSignalTests, SiginterruptTest,
518 ItimerTest, WindowsSignalTests)
519 finally:
520 support.reap_children()
Thomas Woutersed03b412007-08-28 21:37:11 +0000521
522
523if __name__ == "__main__":
524 test_main()