blob: 1a99eefb85a6df592ba88d92e119d124b475191a [file] [log] [blame]
Georg Brandl9f2b93e2007-08-24 18:07:52 +00001import unittest
2from test import test_support
Georg Brandlc29863e2009-06-18 22:24:26 +00003from contextlib import closing
Neal Norwitzbb89e682008-03-25 07:00:39 +00004import gc
Jeffrey Yasskincf26f542008-03-21 05:02:44 +00005import pickle
6import select
Guido van Rossum4f17e3e1995-03-16 15:07:38 +00007import signal
Jeffrey Yasskin413f5882008-03-21 18:25:06 +00008import subprocess
Jeffrey Yasskincf26f542008-03-21 05:02:44 +00009import traceback
Christian Heimesacfd8ed2008-02-28 21:00:45 +000010import sys, os, time, errno
11
Brian Curtin24af0e92010-08-06 19:41:01 +000012if sys.platform == 'os2' or sys.platform == 'riscos':
Benjamin Peterson888a39b2009-03-26 20:48:25 +000013 raise unittest.SkipTest("Can't test signal on %s" % \
Christian Heimesacfd8ed2008-02-28 21:00:45 +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
Jeffrey Yasskincf26f542008-03-21 05:02:44 +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
Jeffrey Yasskinab561312008-04-02 04:07:44 +000031def ignoring_eintr(__func, *args, **kwargs):
32 try:
33 return __func(*args, **kwargs)
Jeffrey Yasskin2b860db2008-04-04 04:51:19 +000034 except EnvironmentError as e:
Jeffrey Yasskine71d8122008-04-04 16:48:19 +000035 if e.errno != errno.EINTR:
Jeffrey Yasskinab561312008-04-02 04:07:44 +000036 raise
37 return None
38
39
Brian Curtin24af0e92010-08-06 19:41:01 +000040@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Georg Brandl9f2b93e2007-08-24 18:07:52 +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
Neal Norwitzbb89e682008-03-25 07:00:39 +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
Jeffrey Yasskinee767772008-04-06 23:04:28 +000052 def format_frame(self, frame, limit=None):
53 return ''.join(traceback.format_stack(frame, limit=limit))
54
55 def handlerA(self, signum, frame):
Georg Brandl9f2b93e2007-08-24 18:07:52 +000056 self.a_called = True
57 if test_support.verbose:
Jeffrey Yasskinee767772008-04-06 23:04:28 +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
Jeffrey Yasskinee767772008-04-06 23:04:28 +000061 def handlerB(self, signum, frame):
Georg Brandl9f2b93e2007-08-24 18:07:52 +000062 self.b_called = True
63 if test_support.verbose:
Jeffrey Yasskinee767772008-04-06 23:04:28 +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
Jeffrey Yasskin413f5882008-03-21 18:25:06 +000068 def wait(self, child):
69 """Wait for child to finish, ignoring EINTR."""
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000070 while True:
71 try:
Jeffrey Yasskin413f5882008-03-21 18:25:06 +000072 child.wait()
Jeffrey Yasskin6cda88e2008-03-21 05:51:37 +000073 return
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000074 except OSError as e:
75 if e.errno != errno.EINTR:
76 raise
Fred Drake004d5e62000-10-23 17:22:08 +000077
Jeffrey Yasskincf26f542008-03-21 05:02:44 +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
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000086 # Variables the signals will modify:
87 self.a_called = False
88 self.b_called = False
Tim Peters1742f332006-08-12 04:42:47 +000089
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000090 # Let the sub-processes know who to send signals to.
91 pid = os.getpid()
Georg Brandl9f2b93e2007-08-24 18:07:52 +000092 if test_support.verbose:
93 print "test runner's pid is", pid
Tim Peters1742f332006-08-12 04:42:47 +000094
Jeffrey Yasskinab561312008-04-02 04:07: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.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000100 self.assertTrue(self.a_called)
101 self.assertFalse(self.b_called)
102 self.a_called = False
Tim Peters1742f332006-08-12 04:42:47 +0000103
Jeffrey Yasskinee767772008-04-06 23:04:28 +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
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000108 try:
Jeffrey Yasskin413f5882008-03-21 18:25:06 +0000109 child = subprocess.Popen(['kill', '-USR1', str(pid)])
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000110 # This wait should be interrupted by the signal's exception.
111 self.wait(child)
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000112 time.sleep(1) # Give the signal time to be delivered.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000113 self.fail('HandlerBCalled exception not thrown')
114 except HandlerBCalled:
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000115 self.assertTrue(self.b_called)
116 self.assertFalse(self.a_called)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000117 if test_support.verbose:
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000118 print "HandlerBCalled exception caught"
Neal Norwitzec3c5e32006-07-30 19:18:38 +0000119
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000120 child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)])
121 if child:
122 self.wait(child) # Nothing should happen.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +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()
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000130 # But if another signal arrives before the alarm, pause
131 # may return early.
132 time.sleep(1)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000133 except KeyboardInterrupt:
134 if test_support.verbose:
135 print "KeyboardInterrupt (the alarm() went off)"
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000136 except:
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000137 self.fail("Some other exception woke us from pause: %s" %
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000138 traceback.format_exc())
139 else:
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000140 self.fail("pause returned of its own accord, and the signal"
141 " didn't arrive after another second.")
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000142
Stefan Krah68b4e012010-04-20 07:59:10 +0000143 # Issue 3864. Unknown if this affects earlier versions of freebsd also.
R. David Murraye0e8a872010-04-17 05:26:26 +0000144 @unittest.skipIf(sys.platform=='freebsd6',
145 'inter process signals not reliable (do not mix well with threading) '
146 'on freebsd6')
Jeffrey Yasskincf26f542008-03-21 05:02:44 +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()
Georg Brandlc29863e2009-06-18 22:24:26 +0000154 with closing(os.fdopen(os_done_r)) as done_r, \
155 closing(os.fdopen(os_done_w, 'w')) as done_w:
Jeffrey Yasskincf26f542008-03-21 05:02:44 +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)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000188
189
Brian Curtin24af0e92010-08-06 19:41:01 +0000190@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000191class BasicSignalTests(unittest.TestCase):
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000192 def trivial_signal_handler(self, *args):
193 pass
194
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000195 def test_out_of_range_signal_number_raises_error(self):
196 self.assertRaises(ValueError, signal.getsignal, 4242)
197
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000198 self.assertRaises(ValueError, signal.signal, 4242,
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000199 self.trivial_signal_handler)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000200
201 def test_setting_signal_handler_to_none_raises_error(self):
202 self.assertRaises(TypeError, signal.signal,
203 signal.SIGUSR1, None)
204
Jeffrey Yasskincf26f542008-03-21 05:02:44 +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 Curtin24af0e92010-08-06 19:41:01 +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)
226 sinal.signal(7, handler)
227
228
229@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Guido van Rossum02de8972007-12-19 19:41:06 +0000230class WakeupSignalTests(unittest.TestCase):
231 TIMEOUT_FULL = 10
232 TIMEOUT_HALF = 5
233
234 def test_wakeup_fd_early(self):
235 import select
236
237 signal.alarm(1)
238 before_time = time.time()
239 # We attempt to get a signal during the sleep,
240 # before select is called
241 time.sleep(self.TIMEOUT_FULL)
242 mid_time = time.time()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000243 self.assertTrue(mid_time - before_time < self.TIMEOUT_HALF)
Guido van Rossum02de8972007-12-19 19:41:06 +0000244 select.select([self.read], [], [], self.TIMEOUT_FULL)
245 after_time = time.time()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000246 self.assertTrue(after_time - mid_time < self.TIMEOUT_HALF)
Guido van Rossum02de8972007-12-19 19:41:06 +0000247
248 def test_wakeup_fd_during(self):
249 import select
250
251 signal.alarm(1)
252 before_time = time.time()
253 # We attempt to get a signal during the select call
254 self.assertRaises(select.error, select.select,
255 [self.read], [], [], self.TIMEOUT_FULL)
256 after_time = time.time()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000257 self.assertTrue(after_time - before_time < self.TIMEOUT_HALF)
Guido van Rossum02de8972007-12-19 19:41:06 +0000258
259 def setUp(self):
260 import fcntl
261
262 self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None)
263 self.read, self.write = os.pipe()
264 flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
265 flags = flags | os.O_NONBLOCK
266 fcntl.fcntl(self.write, fcntl.F_SETFL, flags)
267 self.old_wakeup = signal.set_wakeup_fd(self.write)
268
269 def tearDown(self):
270 signal.set_wakeup_fd(self.old_wakeup)
271 os.close(self.read)
272 os.close(self.write)
273 signal.signal(signal.SIGALRM, self.alrm)
274
Brian Curtin24af0e92010-08-06 19:41:01 +0000275@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Facundo Batista7e251e82008-02-23 15:07:35 +0000276class SiginterruptTest(unittest.TestCase):
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000277
278 def setUp(self):
279 """Install a no-op signal handler that can be set to allow
280 interrupts or not, and arrange for the original signal handler to be
281 re-installed when the test is finished.
282 """
Brian Curtin24af0e92010-08-06 19:41:01 +0000283 self.signum = signal.SIGUSR1
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000284 oldhandler = signal.signal(self.signum, lambda x,y: None)
285 self.addCleanup(signal.signal, self.signum, oldhandler)
286
287 def readpipe_interrupted(self):
288 """Perform a read during which a signal will arrive. Return True if the
289 read is interrupted by the signal and raises an exception. Return False
290 if it returns normally.
291 """
292 # Create a pipe that can be used for the read. Also clean it up
293 # when the test is over, since nothing else will (but see below for
294 # the write end).
Facundo Batista7e251e82008-02-23 15:07:35 +0000295 r, w = os.pipe()
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000296 self.addCleanup(os.close, r)
297
298 # Create another process which can send a signal to this one to try
299 # to interrupt the read.
Facundo Batista7e251e82008-02-23 15:07:35 +0000300 ppid = os.getpid()
301 pid = os.fork()
302
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000303 if pid == 0:
304 # Child code: sleep to give the parent enough time to enter the
305 # read() call (there's a race here, but it's really tricky to
306 # eliminate it); then signal the parent process. Also, sleep
307 # again to make it likely that the signal is delivered to the
308 # parent process before the child exits. If the child exits
309 # first, the write end of the pipe will be closed and the test
310 # is invalid.
Facundo Batista7e251e82008-02-23 15:07:35 +0000311 try:
312 time.sleep(0.2)
313 os.kill(ppid, self.signum)
314 time.sleep(0.2)
315 finally:
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000316 # No matter what, just exit as fast as possible now.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000317 exit_subprocess()
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000318 else:
319 # Parent code.
320 # Make sure the child is eventually reaped, else it'll be a
321 # zombie for the rest of the test suite run.
322 self.addCleanup(os.waitpid, pid, 0)
Facundo Batista7e251e82008-02-23 15:07:35 +0000323
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000324 # Close the write end of the pipe. The child has a copy, so
325 # it's not really closed until the child exits. We need it to
326 # close when the child exits so that in the non-interrupt case
327 # the read eventually completes, otherwise we could just close
328 # it *after* the test.
Facundo Batista7e251e82008-02-23 15:07:35 +0000329 os.close(w)
330
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000331 # Try the read and report whether it is interrupted or not to
332 # the caller.
Facundo Batista7e251e82008-02-23 15:07:35 +0000333 try:
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000334 d = os.read(r, 1)
Facundo Batista7e251e82008-02-23 15:07:35 +0000335 return False
336 except OSError, err:
337 if err.errno != errno.EINTR:
338 raise
339 return True
Facundo Batista7e251e82008-02-23 15:07:35 +0000340
341 def test_without_siginterrupt(self):
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000342 """If a signal handler is installed and siginterrupt is not called
343 at all, when that signal arrives, it interrupts a syscall that's in
344 progress.
345 """
346 i = self.readpipe_interrupted()
347 self.assertTrue(i)
348 # Arrival of the signal shouldn't have changed anything.
349 i = self.readpipe_interrupted()
350 self.assertTrue(i)
Facundo Batista7e251e82008-02-23 15:07:35 +0000351
352 def test_siginterrupt_on(self):
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000353 """If a signal handler is installed and siginterrupt is called with
354 a true value for the second argument, when that signal arrives, it
355 interrupts a syscall that's in progress.
356 """
357 signal.siginterrupt(self.signum, 1)
358 i = self.readpipe_interrupted()
359 self.assertTrue(i)
360 # Arrival of the signal shouldn't have changed anything.
361 i = self.readpipe_interrupted()
362 self.assertTrue(i)
Facundo Batista7e251e82008-02-23 15:07:35 +0000363
364 def test_siginterrupt_off(self):
Jean-Paul Calderonee54ddf12010-05-08 20:06:02 +0000365 """If a signal handler is installed and siginterrupt is called with
366 a false value for the second argument, when that signal arrives, it
367 does not interrupt a syscall that's in progress.
368 """
369 signal.siginterrupt(self.signum, 0)
370 i = self.readpipe_interrupted()
371 self.assertFalse(i)
372 # Arrival of the signal shouldn't have changed anything.
373 i = self.readpipe_interrupted()
374 self.assertFalse(i)
375
376
Brian Curtin24af0e92010-08-06 19:41:01 +0000377@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000378class ItimerTest(unittest.TestCase):
379 def setUp(self):
380 self.hndl_called = False
381 self.hndl_count = 0
382 self.itimer = None
Neal Norwitzbb89e682008-03-25 07:00:39 +0000383 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000384
385 def tearDown(self):
Neal Norwitzbb89e682008-03-25 07:00:39 +0000386 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000387 if self.itimer is not None: # test_itimer_exc doesn't change this attr
388 # just ensure that itimer is stopped
389 signal.setitimer(self.itimer, 0)
390
391 def sig_alrm(self, *args):
392 self.hndl_called = True
393 if test_support.verbose:
394 print("SIGALRM handler invoked", args)
395
396 def sig_vtalrm(self, *args):
397 self.hndl_called = True
398
399 if self.hndl_count > 3:
400 # it shouldn't be here, because it should have been disabled.
401 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
402 "timer.")
403 elif self.hndl_count == 3:
404 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
405 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
406 if test_support.verbose:
407 print("last SIGVTALRM handler call")
408
409 self.hndl_count += 1
410
411 if test_support.verbose:
412 print("SIGVTALRM handler invoked", args)
413
414 def sig_prof(self, *args):
415 self.hndl_called = True
416 signal.setitimer(signal.ITIMER_PROF, 0)
417
418 if test_support.verbose:
419 print("SIGPROF handler invoked", args)
420
421 def test_itimer_exc(self):
422 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
423 # defines it ?
424 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Neal Norwitzbb89e682008-03-25 07:00:39 +0000425 # Negative times are treated as zero on some platforms.
426 if 0:
427 self.assertRaises(signal.ItimerError,
428 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000429
430 def test_itimer_real(self):
431 self.itimer = signal.ITIMER_REAL
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000432 signal.setitimer(self.itimer, 1.0)
433 if test_support.verbose:
434 print("\ncall pause()...")
435 signal.pause()
436
437 self.assertEqual(self.hndl_called, True)
438
Stefan Krah68b4e012010-04-20 07:59:10 +0000439 # Issue 3864. Unknown if this affects earlier versions of freebsd also.
R. David Murraye0e8a872010-04-17 05:26:26 +0000440 @unittest.skipIf(sys.platform=='freebsd6',
441 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000442 def test_itimer_virtual(self):
443 self.itimer = signal.ITIMER_VIRTUAL
444 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
445 signal.setitimer(self.itimer, 0.3, 0.2)
446
Mark Dickinson4b841d92009-10-31 10:36:06 +0000447 start_time = time.time()
Stefan Krah68b4e012010-04-20 07:59:10 +0000448 while time.time() - start_time < 60.0:
Mark Dickinson245d9152009-10-04 18:38:39 +0000449 # use up some virtual time by doing real work
450 _ = pow(12345, 67890, 10000019)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000451 if signal.getitimer(self.itimer) == (0.0, 0.0):
452 break # sig_vtalrm handler stopped this itimer
Stefan Krah68b4e012010-04-20 07:59:10 +0000453 else: # Issue 8424
Benjamin Peterson5b5134b2010-05-15 17:48:55 +0000454 self.skipTest("timeout: likely cause: machine too slow or load too "
455 "high")
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000456
457 # virtual itimer should be (0.0, 0.0) now
458 self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0))
459 # and the handler should have been called
460 self.assertEquals(self.hndl_called, True)
461
Stefan Krah68b4e012010-04-20 07:59:10 +0000462 # Issue 3864. Unknown if this affects earlier versions of freebsd also.
R. David Murraye0e8a872010-04-17 05:26:26 +0000463 @unittest.skipIf(sys.platform=='freebsd6',
464 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000465 def test_itimer_prof(self):
466 self.itimer = signal.ITIMER_PROF
467 signal.signal(signal.SIGPROF, self.sig_prof)
Jeffrey Yasskin2b860db2008-04-04 04:51:19 +0000468 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000469
Mark Dickinson4b841d92009-10-31 10:36:06 +0000470 start_time = time.time()
Stefan Krah68b4e012010-04-20 07:59:10 +0000471 while time.time() - start_time < 60.0:
Mark Dickinson4b841d92009-10-31 10:36:06 +0000472 # do some work
473 _ = pow(12345, 67890, 10000019)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000474 if signal.getitimer(self.itimer) == (0.0, 0.0):
475 break # sig_prof handler stopped this itimer
Stefan Krah68b4e012010-04-20 07:59:10 +0000476 else: # Issue 8424
Benjamin Peterson5b5134b2010-05-15 17:48:55 +0000477 self.skipTest("timeout: likely cause: machine too slow or load too "
478 "high")
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000479
Jeffrey Yasskin2b860db2008-04-04 04:51:19 +0000480 # profiling itimer should be (0.0, 0.0) now
481 self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0))
482 # and the handler should have been called
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000483 self.assertEqual(self.hndl_called, True)
484
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000485def test_main():
Brian Curtin24af0e92010-08-06 19:41:01 +0000486 if sys.platform == "win32":
487 support.run_unittest(WindowsSignalTests)
488 else:
489 support.run_unittest(BasicSignalTests, InterProcessSignalTests,
490 WakeupSignalTests, SiginterruptTest, ItimerTest)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000491
492
493if __name__ == "__main__":
494 test_main()