blob: a00e2d8621133adc6a2cd4ccc5a24d6b2643c968 [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
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008import subprocess
9import traceback
Christian Heimesc06950e2008-02-28 21:17:00 +000010import sys, os, time, errno
11
Brian Curtin3f004b12010-08-06 19:34:52 +000012if sys.platform == 'os2' or sys.platform == 'riscos':
Benjamin Petersone549ead2009-03-28 21:42:05 +000013 raise unittest.SkipTest("Can't test signal on %s" % \
Christian Heimesc06950e2008-02-28 21:17:00 +000014 sys.platform)
15
Guido van Rossumcc5a91d1997-04-16 00:29:15 +000016
Armin Rigo8b2cbfd2004-08-07 21:27:43 +000017class HandlerBCalled(Exception):
18 pass
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000019
Christian Heimes4fbc72b2008-03-22 00:47:35 +000020
21def exit_subprocess():
22 """Use os._exit(0) to exit the current subprocess.
23
24 Otherwise, the test catches the SystemExit and continues executing
25 in parallel with the original test, so you wind up with an
26 exponential number of tests running concurrently.
27 """
28 os._exit(0)
29
30
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000031def ignoring_eintr(__func, *args, **kwargs):
32 try:
33 return __func(*args, **kwargs)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +000034 except EnvironmentError as e:
35 if e.errno != errno.EINTR:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000036 raise
37 return None
38
39
Brian Curtin3f004b12010-08-06 19:34:52 +000040@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Thomas Woutersed03b412007-08-28 21:37:11 +000041class InterProcessSignalTests(unittest.TestCase):
42 MAX_DURATION = 20 # Entire test should last at most 20 sec.
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000043
Christian Heimescc47b052008-03-25 14:56:36 +000044 def setUp(self):
45 self.using_gc = gc.isenabled()
46 gc.disable()
47
48 def tearDown(self):
49 if self.using_gc:
50 gc.enable()
51
Christian Heimes5e696852008-04-09 08:37:03 +000052 def format_frame(self, frame, limit=None):
53 return ''.join(traceback.format_stack(frame, limit=limit))
54
55 def handlerA(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000056 self.a_called = True
Benjamin Petersonee8712c2008-05-20 21:35:26 +000057 if support.verbose:
Christian Heimes5e696852008-04-09 08:37:03 +000058 print("handlerA invoked from signal %s at:\n%s" % (
59 signum, self.format_frame(frame, limit=1)))
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000060
Christian Heimes5e696852008-04-09 08:37:03 +000061 def handlerB(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000062 self.b_called = True
Benjamin Petersonee8712c2008-05-20 21:35:26 +000063 if support.verbose:
Christian Heimes5e696852008-04-09 08:37:03 +000064 print ("handlerB invoked from signal %s at:\n%s" % (
65 signum, self.format_frame(frame, limit=1)))
66 raise HandlerBCalled(signum, self.format_frame(frame))
Neal Norwitz9730bcb2006-01-23 07:50:06 +000067
Christian Heimes4fbc72b2008-03-22 00:47:35 +000068 def wait(self, child):
69 """Wait for child to finish, ignoring EINTR."""
70 while True:
71 try:
72 child.wait()
73 return
74 except OSError as e:
75 if e.errno != errno.EINTR:
76 raise
Fred Drake004d5e62000-10-23 17:22:08 +000077
Christian Heimes4fbc72b2008-03-22 00:47:35 +000078 def run_test(self):
79 # Install handlers. This function runs in a sub-process, so we
80 # don't worry about re-setting the default handlers.
81 signal.signal(signal.SIGHUP, self.handlerA)
82 signal.signal(signal.SIGUSR1, self.handlerB)
83 signal.signal(signal.SIGUSR2, signal.SIG_IGN)
84 signal.signal(signal.SIGALRM, signal.default_int_handler)
Michael W. Hudson5c26e862004-06-11 18:09:28 +000085
Christian Heimes4fbc72b2008-03-22 00:47:35 +000086 # Variables the signals will modify:
87 self.a_called = False
88 self.b_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000089
Christian Heimes4fbc72b2008-03-22 00:47:35 +000090 # Let the sub-processes know who to send signals to.
91 pid = os.getpid()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000092 if support.verbose:
Thomas Woutersed03b412007-08-28 21:37:11 +000093 print("test runner's pid is", pid)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000094
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000095 child = ignoring_eintr(subprocess.Popen, ['kill', '-HUP', str(pid)])
96 if child:
97 self.wait(child)
98 if not self.a_called:
99 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000100 self.assertTrue(self.a_called)
101 self.assertFalse(self.b_called)
102 self.a_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000103
Christian Heimes5e696852008-04-09 08:37:03 +0000104 # Make sure the signal isn't delivered while the previous
105 # Popen object is being destroyed, because __del__ swallows
106 # exceptions.
107 del child
Thomas Woutersed03b412007-08-28 21:37:11 +0000108 try:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000109 child = subprocess.Popen(['kill', '-USR1', str(pid)])
110 # This wait should be interrupted by the signal's exception.
111 self.wait(child)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000112 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000113 self.fail('HandlerBCalled exception not thrown')
114 except HandlerBCalled:
115 self.assertTrue(self.b_called)
116 self.assertFalse(self.a_called)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000117 if support.verbose:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000118 print("HandlerBCalled exception caught")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000119
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000120 child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)])
121 if child:
122 self.wait(child) # Nothing should happen.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000123
124 try:
125 signal.alarm(1)
126 # The race condition in pause doesn't matter in this case,
127 # since alarm is going to raise a KeyboardException, which
128 # will skip the call.
129 signal.pause()
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000130 # But if another signal arrives before the alarm, pause
131 # may return early.
132 time.sleep(1)
Thomas Woutersed03b412007-08-28 21:37:11 +0000133 except KeyboardInterrupt:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000134 if support.verbose:
Thomas Woutersed03b412007-08-28 21:37:11 +0000135 print("KeyboardInterrupt (the alarm() went off)")
Thomas Woutersed03b412007-08-28 21:37:11 +0000136 except:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000137 self.fail("Some other exception woke us from pause: %s" %
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000138 traceback.format_exc())
139 else:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000140 self.fail("pause returned of its own accord, and the signal"
141 " didn't arrive after another second.")
Thomas Woutersed03b412007-08-28 21:37:11 +0000142
R. David Murray44546f82010-04-21 01:59:28 +0000143 # Issue 3864, unknown if this affects earlier versions of freebsd also
144 @unittest.skipIf(sys.platform=='freebsd6',
145 'inter process signals not reliable (do not mix well with threading) '
146 'on freebsd6')
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000147 def test_main(self):
148 # This function spawns a child process to insulate the main
149 # test-running process from all the signals. It then
150 # communicates with that child process over a pipe and
151 # re-raises information about any exceptions the child
152 # throws. The real work happens in self.run_test().
153 os_done_r, os_done_w = os.pipe()
Raymond Hettinger686057b2009-06-04 00:11:54 +0000154 with closing(os.fdopen(os_done_r, 'rb')) as done_r, \
155 closing(os.fdopen(os_done_w, 'wb')) as done_w:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000156 child = os.fork()
157 if child == 0:
158 # In the child process; run the test and report results
159 # through the pipe.
160 try:
161 done_r.close()
162 # Have to close done_w again here because
163 # exit_subprocess() will skip the enclosing with block.
164 with closing(done_w):
165 try:
166 self.run_test()
167 except:
168 pickle.dump(traceback.format_exc(), done_w)
169 else:
170 pickle.dump(None, done_w)
171 except:
172 print('Uh oh, raised from pickle.')
173 traceback.print_exc()
174 finally:
175 exit_subprocess()
176
177 done_w.close()
178 # Block for up to MAX_DURATION seconds for the test to finish.
179 r, w, x = select.select([done_r], [], [], self.MAX_DURATION)
180 if done_r in r:
181 tb = pickle.load(done_r)
182 if tb:
183 self.fail(tb)
184 else:
185 os.kill(child, signal.SIGKILL)
186 self.fail('Test deadlocked after %d seconds.' %
187 self.MAX_DURATION)
Thomas Woutersed03b412007-08-28 21:37:11 +0000188
189
Brian Curtin3f004b12010-08-06 19:34:52 +0000190@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Thomas Woutersed03b412007-08-28 21:37:11 +0000191class BasicSignalTests(unittest.TestCase):
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000192 def trivial_signal_handler(self, *args):
193 pass
194
Thomas Woutersed03b412007-08-28 21:37:11 +0000195 def test_out_of_range_signal_number_raises_error(self):
196 self.assertRaises(ValueError, signal.getsignal, 4242)
197
Thomas Woutersed03b412007-08-28 21:37:11 +0000198 self.assertRaises(ValueError, signal.signal, 4242,
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000199 self.trivial_signal_handler)
Thomas Woutersed03b412007-08-28 21:37:11 +0000200
201 def test_setting_signal_handler_to_none_raises_error(self):
202 self.assertRaises(TypeError, signal.signal,
203 signal.SIGUSR1, None)
204
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000205 def test_getsignal(self):
206 hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler)
207 self.assertEquals(signal.getsignal(signal.SIGHUP),
208 self.trivial_signal_handler)
209 signal.signal(signal.SIGHUP, hup)
210 self.assertEquals(signal.getsignal(signal.SIGHUP), hup)
211
212
Brian Curtin3f004b12010-08-06 19:34:52 +0000213@unittest.skipUnless(sys.platform == "win32", "Windows specific")
214class WindowsSignalTests(unittest.TestCase):
215 def test_issue9324(self):
216 handler = lambda x, y: None
217 signal.signal(signal.SIGABRT, handler)
218 signal.signal(signal.SIGFPE, handler)
219 signal.signal(signal.SIGILL, handler)
220 signal.signal(signal.SIGINT, handler)
221 signal.signal(signal.SIGSEGV, handler)
222 signal.signal(signal.SIGTERM, handler)
223
224 with self.assertRaises(ValueError):
225 signal.signal(-1, handler)
Brian Curtin80cd4bf2010-08-07 03:52:38 +0000226
227 with self.assertRaises(ValueError):
228 signal.signal(7, handler)
Brian Curtin3f004b12010-08-06 19:34:52 +0000229
230
231@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000232class WakeupSignalTests(unittest.TestCase):
233 TIMEOUT_FULL = 10
234 TIMEOUT_HALF = 5
235
236 def test_wakeup_fd_early(self):
237 import select
238
239 signal.alarm(1)
240 before_time = time.time()
241 # We attempt to get a signal during the sleep,
242 # before select is called
243 time.sleep(self.TIMEOUT_FULL)
244 mid_time = time.time()
Georg Brandlab91fde2009-08-13 08:51:18 +0000245 self.assertTrue(mid_time - before_time < self.TIMEOUT_HALF)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000246 select.select([self.read], [], [], self.TIMEOUT_FULL)
247 after_time = time.time()
Georg Brandlab91fde2009-08-13 08:51:18 +0000248 self.assertTrue(after_time - mid_time < self.TIMEOUT_HALF)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000249
250 def test_wakeup_fd_during(self):
251 import select
252
253 signal.alarm(1)
254 before_time = time.time()
255 # We attempt to get a signal during the select call
256 self.assertRaises(select.error, select.select,
257 [self.read], [], [], self.TIMEOUT_FULL)
258 after_time = time.time()
Georg Brandlab91fde2009-08-13 08:51:18 +0000259 self.assertTrue(after_time - before_time < self.TIMEOUT_HALF)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000260
261 def setUp(self):
262 import fcntl
263
264 self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None)
265 self.read, self.write = os.pipe()
266 flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
267 flags = flags | os.O_NONBLOCK
268 fcntl.fcntl(self.write, fcntl.F_SETFL, flags)
269 self.old_wakeup = signal.set_wakeup_fd(self.write)
270
271 def tearDown(self):
272 signal.set_wakeup_fd(self.old_wakeup)
273 os.close(self.read)
274 os.close(self.write)
275 signal.signal(signal.SIGALRM, self.alrm)
276
Brian Curtin3f004b12010-08-06 19:34:52 +0000277@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes8640e742008-02-23 16:23:06 +0000278class SiginterruptTest(unittest.TestCase):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000279
280 def setUp(self):
281 """Install a no-op signal handler that can be set to allow
282 interrupts or not, and arrange for the original signal handler to be
283 re-installed when the test is finished.
284 """
Brian Curtin3f004b12010-08-06 19:34:52 +0000285 self.signum = signal.SIGUSR1
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000286 oldhandler = signal.signal(self.signum, lambda x,y: None)
287 self.addCleanup(signal.signal, self.signum, oldhandler)
288
289 def readpipe_interrupted(self):
290 """Perform a read during which a signal will arrive. Return True if the
291 read is interrupted by the signal and raises an exception. Return False
292 if it returns normally.
293 """
294 # Create a pipe that can be used for the read. Also clean it up
295 # when the test is over, since nothing else will (but see below for
296 # the write end).
Christian Heimes8640e742008-02-23 16:23:06 +0000297 r, w = os.pipe()
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000298 self.addCleanup(os.close, r)
299
300 # Create another process which can send a signal to this one to try
301 # to interrupt the read.
Christian Heimes8640e742008-02-23 16:23:06 +0000302 ppid = os.getpid()
303 pid = os.fork()
304
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000305 if pid == 0:
306 # Child code: sleep to give the parent enough time to enter the
307 # read() call (there's a race here, but it's really tricky to
308 # eliminate it); then signal the parent process. Also, sleep
309 # again to make it likely that the signal is delivered to the
310 # parent process before the child exits. If the child exits
311 # first, the write end of the pipe will be closed and the test
312 # is invalid.
Christian Heimes8640e742008-02-23 16:23:06 +0000313 try:
314 time.sleep(0.2)
315 os.kill(ppid, self.signum)
316 time.sleep(0.2)
317 finally:
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000318 # No matter what, just exit as fast as possible now.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000319 exit_subprocess()
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000320 else:
321 # Parent code.
322 # Make sure the child is eventually reaped, else it'll be a
323 # zombie for the rest of the test suite run.
324 self.addCleanup(os.waitpid, pid, 0)
Christian Heimes8640e742008-02-23 16:23:06 +0000325
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000326 # Close the write end of the pipe. The child has a copy, so
327 # it's not really closed until the child exits. We need it to
328 # close when the child exits so that in the non-interrupt case
329 # the read eventually completes, otherwise we could just close
330 # it *after* the test.
Christian Heimes8640e742008-02-23 16:23:06 +0000331 os.close(w)
332
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000333 # Try the read and report whether it is interrupted or not to
334 # the caller.
Christian Heimes8640e742008-02-23 16:23:06 +0000335 try:
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000336 d = os.read(r, 1)
Christian Heimes8640e742008-02-23 16:23:06 +0000337 return False
338 except OSError as err:
339 if err.errno != errno.EINTR:
340 raise
341 return True
Christian Heimes8640e742008-02-23 16:23:06 +0000342
343 def test_without_siginterrupt(self):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000344 """If a signal handler is installed and siginterrupt is not called
345 at all, when that signal arrives, it interrupts a syscall that's in
346 progress.
347 """
348 i = self.readpipe_interrupted()
349 self.assertTrue(i)
350 # Arrival of the signal shouldn't have changed anything.
351 i = self.readpipe_interrupted()
352 self.assertTrue(i)
Christian Heimes8640e742008-02-23 16:23:06 +0000353
354 def test_siginterrupt_on(self):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000355 """If a signal handler is installed and siginterrupt is called with
356 a true value for the second argument, when that signal arrives, it
357 interrupts a syscall that's in progress.
358 """
359 signal.siginterrupt(self.signum, 1)
360 i = self.readpipe_interrupted()
361 self.assertTrue(i)
362 # Arrival of the signal shouldn't have changed anything.
363 i = self.readpipe_interrupted()
364 self.assertTrue(i)
Christian Heimes8640e742008-02-23 16:23:06 +0000365
366 def test_siginterrupt_off(self):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000367 """If a signal handler is installed and siginterrupt is called with
368 a false value for the second argument, when that signal arrives, it
369 does not interrupt a syscall that's in progress.
370 """
371 signal.siginterrupt(self.signum, 0)
372 i = self.readpipe_interrupted()
373 self.assertFalse(i)
374 # Arrival of the signal shouldn't have changed anything.
375 i = self.readpipe_interrupted()
376 self.assertFalse(i)
377
378
Brian Curtin3f004b12010-08-06 19:34:52 +0000379@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000380class ItimerTest(unittest.TestCase):
381 def setUp(self):
382 self.hndl_called = False
383 self.hndl_count = 0
384 self.itimer = None
Christian Heimescc47b052008-03-25 14:56:36 +0000385 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000386
387 def tearDown(self):
Christian Heimescc47b052008-03-25 14:56:36 +0000388 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000389 if self.itimer is not None: # test_itimer_exc doesn't change this attr
390 # just ensure that itimer is stopped
391 signal.setitimer(self.itimer, 0)
392
393 def sig_alrm(self, *args):
394 self.hndl_called = True
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000395 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000396 print("SIGALRM handler invoked", args)
397
398 def sig_vtalrm(self, *args):
399 self.hndl_called = True
400
401 if self.hndl_count > 3:
402 # it shouldn't be here, because it should have been disabled.
403 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
404 "timer.")
405 elif self.hndl_count == 3:
406 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
407 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000408 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000409 print("last SIGVTALRM handler call")
410
411 self.hndl_count += 1
412
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000413 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000414 print("SIGVTALRM handler invoked", args)
415
416 def sig_prof(self, *args):
417 self.hndl_called = True
418 signal.setitimer(signal.ITIMER_PROF, 0)
419
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000420 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000421 print("SIGPROF handler invoked", args)
422
423 def test_itimer_exc(self):
424 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
425 # defines it ?
426 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Christian Heimescc47b052008-03-25 14:56:36 +0000427 # Negative times are treated as zero on some platforms.
428 if 0:
429 self.assertRaises(signal.ItimerError,
430 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000431
432 def test_itimer_real(self):
433 self.itimer = signal.ITIMER_REAL
Martin v. Löwis823725e2008-03-24 13:39:54 +0000434 signal.setitimer(self.itimer, 1.0)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000435 if support.verbose:
Martin v. Löwis823725e2008-03-24 13:39:54 +0000436 print("\ncall pause()...")
437 signal.pause()
438
439 self.assertEqual(self.hndl_called, True)
440
R. David Murray44546f82010-04-21 01:59:28 +0000441 # Issue 3864, unknown if this affects earlier versions of freebsd also
442 @unittest.skipIf(sys.platform=='freebsd6',
443 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000444 def test_itimer_virtual(self):
445 self.itimer = signal.ITIMER_VIRTUAL
446 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
447 signal.setitimer(self.itimer, 0.3, 0.2)
448
Mark Dickinson78373472009-10-31 10:39:21 +0000449 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000450 while time.time() - start_time < 60.0:
Mark Dickinson95078872009-10-04 18:47:48 +0000451 # use up some virtual time by doing real work
452 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000453 if signal.getitimer(self.itimer) == (0.0, 0.0):
454 break # sig_vtalrm handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000455 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000456 self.skipTest("timeout: likely cause: machine too slow or load too "
457 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000458
459 # virtual itimer should be (0.0, 0.0) now
460 self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0))
461 # and the handler should have been called
462 self.assertEquals(self.hndl_called, True)
463
R. David Murray44546f82010-04-21 01:59:28 +0000464 # Issue 3864, unknown if this affects earlier versions of freebsd also
465 @unittest.skipIf(sys.platform=='freebsd6',
466 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000467 def test_itimer_prof(self):
468 self.itimer = signal.ITIMER_PROF
469 signal.signal(signal.SIGPROF, self.sig_prof)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000470 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000471
Mark Dickinson78373472009-10-31 10:39:21 +0000472 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000473 while time.time() - start_time < 60.0:
Mark Dickinson78373472009-10-31 10:39:21 +0000474 # do some work
475 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000476 if signal.getitimer(self.itimer) == (0.0, 0.0):
477 break # sig_prof handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000478 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000479 self.skipTest("timeout: likely cause: machine too slow or load too "
480 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000481
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000482 # profiling itimer should be (0.0, 0.0) now
483 self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0))
484 # and the handler should have been called
Martin v. Löwis823725e2008-03-24 13:39:54 +0000485 self.assertEqual(self.hndl_called, True)
486
Thomas Woutersed03b412007-08-28 21:37:11 +0000487def test_main():
Brian Curtin80cd4bf2010-08-07 03:52:38 +0000488 support.run_unittest(BasicSignalTests, InterProcessSignalTests,
489 WakeupSignalTests, SiginterruptTest,
490 ItimerTest, WindowsSignalTests)
Thomas Woutersed03b412007-08-28 21:37:11 +0000491
492
493if __name__ == "__main__":
494 test_main()