blob: f458cdb7b0b52e47c42e61f7f428ce04bbfd0897 [file] [log] [blame]
Georg Brandl9f2b93e2007-08-24 18:07:52 +00001import unittest
2from test import test_support
Jeffrey Yasskincf26f542008-03-21 05:02:44 +00003from contextlib import closing, nested
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
12if sys.platform[:3] in ('win', 'os2') or sys.platform == 'riscos':
13 raise test_support.TestSkipped("Can't test signal on %s" % \
14 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
Georg Brandl9f2b93e2007-08-24 18:07:52 +000040class InterProcessSignalTests(unittest.TestCase):
41 MAX_DURATION = 20 # Entire test should last at most 20 sec.
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000042
Neal Norwitzbb89e682008-03-25 07:00:39 +000043 def setUp(self):
44 self.using_gc = gc.isenabled()
45 gc.disable()
46
47 def tearDown(self):
48 if self.using_gc:
49 gc.enable()
50
Jeffrey Yasskinee767772008-04-06 23:04:28 +000051 def format_frame(self, frame, limit=None):
52 return ''.join(traceback.format_stack(frame, limit=limit))
53
54 def handlerA(self, signum, frame):
Georg Brandl9f2b93e2007-08-24 18:07:52 +000055 self.a_called = True
56 if test_support.verbose:
Jeffrey Yasskinee767772008-04-06 23:04:28 +000057 print "handlerA invoked from signal %s at:\n%s" % (
58 signum, self.format_frame(frame, limit=1))
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000059
Jeffrey Yasskinee767772008-04-06 23:04:28 +000060 def handlerB(self, signum, frame):
Georg Brandl9f2b93e2007-08-24 18:07:52 +000061 self.b_called = True
62 if test_support.verbose:
Jeffrey Yasskinee767772008-04-06 23:04:28 +000063 print "handlerB invoked from signal %s at:\n%s" % (
64 signum, self.format_frame(frame, limit=1))
65 raise HandlerBCalled(signum, self.format_frame(frame))
Neal Norwitz9730bcb2006-01-23 07:50:06 +000066
Jeffrey Yasskin413f5882008-03-21 18:25:06 +000067 def wait(self, child):
68 """Wait for child to finish, ignoring EINTR."""
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000069 while True:
70 try:
Jeffrey Yasskin413f5882008-03-21 18:25:06 +000071 child.wait()
Jeffrey Yasskin6cda88e2008-03-21 05:51:37 +000072 return
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000073 except OSError as e:
74 if e.errno != errno.EINTR:
75 raise
Fred Drake004d5e62000-10-23 17:22:08 +000076
Jeffrey Yasskincf26f542008-03-21 05:02:44 +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
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000085 # Variables the signals will modify:
86 self.a_called = False
87 self.b_called = False
Tim Peters1742f332006-08-12 04:42:47 +000088
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000089 # Let the sub-processes know who to send signals to.
90 pid = os.getpid()
Georg Brandl9f2b93e2007-08-24 18:07:52 +000091 if test_support.verbose:
92 print "test runner's pid is", pid
Tim Peters1742f332006-08-12 04:42:47 +000093
Jeffrey Yasskinab561312008-04-02 04:07:44 +000094 child = ignoring_eintr(subprocess.Popen, ['kill', '-HUP', str(pid)])
95 if child:
96 self.wait(child)
97 if not self.a_called:
98 time.sleep(1) # Give the signal time to be delivered.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +000099 self.assertTrue(self.a_called)
100 self.assertFalse(self.b_called)
101 self.a_called = False
Tim Peters1742f332006-08-12 04:42:47 +0000102
Jeffrey Yasskinee767772008-04-06 23:04:28 +0000103 # Make sure the signal isn't delivered while the previous
104 # Popen object is being destroyed, because __del__ swallows
105 # exceptions.
106 del child
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000107 try:
Jeffrey Yasskin413f5882008-03-21 18:25:06 +0000108 child = subprocess.Popen(['kill', '-USR1', str(pid)])
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000109 # This wait should be interrupted by the signal's exception.
110 self.wait(child)
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000111 time.sleep(1) # Give the signal time to be delivered.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000112 self.fail('HandlerBCalled exception not thrown')
113 except HandlerBCalled:
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000114 self.assertTrue(self.b_called)
115 self.assertFalse(self.a_called)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000116 if test_support.verbose:
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000117 print "HandlerBCalled exception caught"
Neal Norwitzec3c5e32006-07-30 19:18:38 +0000118
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000119 child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)])
120 if child:
121 self.wait(child) # Nothing should happen.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000122
123 try:
124 signal.alarm(1)
125 # The race condition in pause doesn't matter in this case,
126 # since alarm is going to raise a KeyboardException, which
127 # will skip the call.
128 signal.pause()
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000129 # But if another signal arrives before the alarm, pause
130 # may return early.
131 time.sleep(1)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000132 except KeyboardInterrupt:
133 if test_support.verbose:
134 print "KeyboardInterrupt (the alarm() went off)"
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000135 except:
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000136 self.fail("Some other exception woke us from pause: %s" %
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000137 traceback.format_exc())
138 else:
Jeffrey Yasskinab561312008-04-02 04:07:44 +0000139 self.fail("pause returned of its own accord, and the signal"
140 " didn't arrive after another second.")
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000141
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000142 def test_main(self):
R. David Murray12c5fbb2010-04-21 01:41:41 +0000143 # Issue 3864, unknown if this affects earlier versions of freebsd also
144 if sys.platform=='freebsd6' and test_support.verbose:
145 sys.stderr.write('skipping -- inter process signals not reliable '
146 '(do not mix well with threading) on freebsd6\n')
147 return
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000148 # 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()
154 with nested(closing(os.fdopen(os_done_r)),
155 closing(os.fdopen(os_done_w, 'w'))) as (done_r, done_w):
156 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
190class BasicSignalTests(unittest.TestCase):
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000191 def trivial_signal_handler(self, *args):
192 pass
193
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000194 def test_out_of_range_signal_number_raises_error(self):
195 self.assertRaises(ValueError, signal.getsignal, 4242)
196
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000197 self.assertRaises(ValueError, signal.signal, 4242,
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000198 self.trivial_signal_handler)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000199
200 def test_setting_signal_handler_to_none_raises_error(self):
201 self.assertRaises(TypeError, signal.signal,
202 signal.SIGUSR1, None)
203
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000204 def test_getsignal(self):
205 hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler)
206 self.assertEquals(signal.getsignal(signal.SIGHUP),
207 self.trivial_signal_handler)
208 signal.signal(signal.SIGHUP, hup)
209 self.assertEquals(signal.getsignal(signal.SIGHUP), hup)
210
211
Guido van Rossum02de8972007-12-19 19:41:06 +0000212class WakeupSignalTests(unittest.TestCase):
213 TIMEOUT_FULL = 10
214 TIMEOUT_HALF = 5
215
216 def test_wakeup_fd_early(self):
217 import select
218
219 signal.alarm(1)
220 before_time = time.time()
221 # We attempt to get a signal during the sleep,
222 # before select is called
223 time.sleep(self.TIMEOUT_FULL)
224 mid_time = time.time()
225 self.assert_(mid_time - before_time < self.TIMEOUT_HALF)
226 select.select([self.read], [], [], self.TIMEOUT_FULL)
227 after_time = time.time()
228 self.assert_(after_time - mid_time < self.TIMEOUT_HALF)
229
230 def test_wakeup_fd_during(self):
231 import select
232
233 signal.alarm(1)
234 before_time = time.time()
235 # We attempt to get a signal during the select call
236 self.assertRaises(select.error, select.select,
237 [self.read], [], [], self.TIMEOUT_FULL)
238 after_time = time.time()
239 self.assert_(after_time - before_time < self.TIMEOUT_HALF)
240
241 def setUp(self):
242 import fcntl
243
244 self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None)
245 self.read, self.write = os.pipe()
246 flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
247 flags = flags | os.O_NONBLOCK
248 fcntl.fcntl(self.write, fcntl.F_SETFL, flags)
249 self.old_wakeup = signal.set_wakeup_fd(self.write)
250
251 def tearDown(self):
252 signal.set_wakeup_fd(self.old_wakeup)
253 os.close(self.read)
254 os.close(self.write)
255 signal.signal(signal.SIGALRM, self.alrm)
256
Facundo Batista7e251e82008-02-23 15:07:35 +0000257class SiginterruptTest(unittest.TestCase):
258 signum = signal.SIGUSR1
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000259
260 def setUp(self):
261 """Install a no-op signal handler that can be set to allow
262 interrupts or not, and arrange for the original signal handler to be
263 re-installed when the test is finished.
264 """
265 self._cleanups = []
266 oldhandler = signal.signal(self.signum, lambda x,y: None)
267 self.addCleanup(signal.signal, self.signum, oldhandler)
268
269
270 def tearDown(self):
271 """Run any cleanup functions which have been registered.
272 """
273 for (f, a) in self._cleanups:
274 f(*a)
275
276
277 def addCleanup(self, f, *a):
278 """Register a function to be called at the end of the test method
279 run.
280 """
281 self._cleanups.append((f, a))
282
283
284 def readpipe_interrupted(self):
285 """Perform a read during which a signal will arrive. Return True if the
286 read is interrupted by the signal and raises an exception. Return False
287 if it returns normally.
288 """
289 # Create a pipe that can be used for the read. Also clean it up
290 # when the test is over, since nothing else will (but see below for
291 # the write end).
Facundo Batista7e251e82008-02-23 15:07:35 +0000292 r, w = os.pipe()
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000293 self.addCleanup(os.close, r)
294
295 # Create another process which can send a signal to this one to try
296 # to interrupt the read.
Facundo Batista7e251e82008-02-23 15:07:35 +0000297 ppid = os.getpid()
298 pid = os.fork()
299
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000300 if pid == 0:
301 # Child code: sleep to give the parent enough time to enter the
302 # read() call (there's a race here, but it's really tricky to
303 # eliminate it); then signal the parent process. Also, sleep
304 # again to make it likely that the signal is delivered to the
305 # parent process before the child exits. If the child exits
306 # first, the write end of the pipe will be closed and the test
307 # is invalid.
Facundo Batista7e251e82008-02-23 15:07:35 +0000308 try:
309 time.sleep(0.2)
310 os.kill(ppid, self.signum)
311 time.sleep(0.2)
312 finally:
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000313 # No matter what, just exit as fast as possible now.
Jeffrey Yasskincf26f542008-03-21 05:02:44 +0000314 exit_subprocess()
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000315 else:
316 # Parent code.
317 # Make sure the child is eventually reaped, else it'll be a
318 # zombie for the rest of the test suite run.
319 self.addCleanup(os.waitpid, pid, 0)
Facundo Batista7e251e82008-02-23 15:07:35 +0000320
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000321 # Close the write end of the pipe. The child has a copy, so
322 # it's not really closed until the child exits. We need it to
323 # close when the child exits so that in the non-interrupt case
324 # the read eventually completes, otherwise we could just close
325 # it *after* the test.
Facundo Batista7e251e82008-02-23 15:07:35 +0000326 os.close(w)
327
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000328 # Try the read and report whether it is interrupted or not to
329 # the caller.
Facundo Batista7e251e82008-02-23 15:07:35 +0000330 try:
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000331 d = os.read(r, 1)
Facundo Batista7e251e82008-02-23 15:07:35 +0000332 return False
333 except OSError, err:
334 if err.errno != errno.EINTR:
335 raise
336 return True
Facundo Batista7e251e82008-02-23 15:07:35 +0000337
338 def test_without_siginterrupt(self):
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000339 """If a signal handler is installed and siginterrupt is not called
340 at all, when that signal arrives, it interrupts a syscall that's in
341 progress.
342 """
343 i = self.readpipe_interrupted()
344 self.assertTrue(i)
345 # Arrival of the signal shouldn't have changed anything.
346 i = self.readpipe_interrupted()
347 self.assertTrue(i)
Facundo Batista7e251e82008-02-23 15:07:35 +0000348
349 def test_siginterrupt_on(self):
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000350 """If a signal handler is installed and siginterrupt is called with
351 a true value for the second argument, when that signal arrives, it
352 interrupts a syscall that's in progress.
353 """
354 signal.siginterrupt(self.signum, 1)
355 i = self.readpipe_interrupted()
356 self.assertTrue(i)
357 # Arrival of the signal shouldn't have changed anything.
358 i = self.readpipe_interrupted()
359 self.assertTrue(i)
Facundo Batista7e251e82008-02-23 15:07:35 +0000360
361 def test_siginterrupt_off(self):
Jean-Paul Calderone0819b092010-05-08 21:11:28 +0000362 """If a signal handler is installed and siginterrupt is called with
363 a false value for the second argument, when that signal arrives, it
364 does not interrupt a syscall that's in progress.
365 """
366 signal.siginterrupt(self.signum, 0)
367 i = self.readpipe_interrupted()
368 self.assertFalse(i)
369 # Arrival of the signal shouldn't have changed anything.
370 i = self.readpipe_interrupted()
371 self.assertFalse(i)
372
373
Guido van Rossum02de8972007-12-19 19:41:06 +0000374
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000375class ItimerTest(unittest.TestCase):
376 def setUp(self):
377 self.hndl_called = False
378 self.hndl_count = 0
379 self.itimer = None
Neal Norwitzbb89e682008-03-25 07:00:39 +0000380 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000381
382 def tearDown(self):
Neal Norwitzbb89e682008-03-25 07:00:39 +0000383 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000384 if self.itimer is not None: # test_itimer_exc doesn't change this attr
385 # just ensure that itimer is stopped
386 signal.setitimer(self.itimer, 0)
387
388 def sig_alrm(self, *args):
389 self.hndl_called = True
390 if test_support.verbose:
391 print("SIGALRM handler invoked", args)
392
393 def sig_vtalrm(self, *args):
394 self.hndl_called = True
395
396 if self.hndl_count > 3:
397 # it shouldn't be here, because it should have been disabled.
398 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
399 "timer.")
400 elif self.hndl_count == 3:
401 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
402 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
403 if test_support.verbose:
404 print("last SIGVTALRM handler call")
405
406 self.hndl_count += 1
407
408 if test_support.verbose:
409 print("SIGVTALRM handler invoked", args)
410
411 def sig_prof(self, *args):
412 self.hndl_called = True
413 signal.setitimer(signal.ITIMER_PROF, 0)
414
415 if test_support.verbose:
416 print("SIGPROF handler invoked", args)
417
418 def test_itimer_exc(self):
419 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
420 # defines it ?
421 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Neal Norwitzbb89e682008-03-25 07:00:39 +0000422 # Negative times are treated as zero on some platforms.
423 if 0:
424 self.assertRaises(signal.ItimerError,
425 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000426
427 def test_itimer_real(self):
428 self.itimer = signal.ITIMER_REAL
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000429 signal.setitimer(self.itimer, 1.0)
430 if test_support.verbose:
431 print("\ncall pause()...")
432 signal.pause()
433
434 self.assertEqual(self.hndl_called, True)
435
436 def test_itimer_virtual(self):
R. David Murray12c5fbb2010-04-21 01:41:41 +0000437 # Issue 3864, unknown if this affects earlier versions of freebsd also
438 if sys.platform=='freebsd6' and test_support.verbose:
439 sys.stderr.write('skipping -- itimer not reliable '
440 '(does not mix well with threading) on freebsd6\n')
441 return
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000442 self.itimer = signal.ITIMER_VIRTUAL
443 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
444 signal.setitimer(self.itimer, 0.3, 0.2)
445
Mark Dickinson265035e2009-10-31 10:37:15 +0000446 start_time = time.time()
Stefan Krah488fea32010-04-20 08:07:08 +0000447 while time.time() - start_time < 60.0:
Mark Dickinson5fab1692009-10-04 18:41:25 +0000448 # use up some virtual time by doing real work
449 _ = pow(12345, 67890, 10000019)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000450 if signal.getitimer(self.itimer) == (0.0, 0.0):
451 break # sig_vtalrm handler stopped this itimer
Stefan Krah488fea32010-04-20 08:07:08 +0000452 else: # Issue 8424
Stefan Krah686e56b2010-05-15 09:34:50 +0000453 sys.stderr.write("test_itimer_virtual: timeout: likely cause: "
Stefan Krah488fea32010-04-20 08:07:08 +0000454 "machine too slow or load too high.\n")
455 return
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
462 def test_itimer_prof(self):
R. David Murray12c5fbb2010-04-21 01:41:41 +0000463 # Issue 3864, unknown if this affects earlier versions of freebsd also
464 if sys.platform=='freebsd6' and test_support.verbose:
465 sys.stderr.write('skipping -- itimer not reliable '
466 '(does not mix well with threading) on freebsd6\n')
467 return
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000468 self.itimer = signal.ITIMER_PROF
469 signal.signal(signal.SIGPROF, self.sig_prof)
Jeffrey Yasskin2b860db2008-04-04 04:51:19 +0000470 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000471
Mark Dickinson265035e2009-10-31 10:37:15 +0000472 start_time = time.time()
Stefan Krah488fea32010-04-20 08:07:08 +0000473 while time.time() - start_time < 60.0:
Mark Dickinson265035e2009-10-31 10:37:15 +0000474 # do some work
475 _ = pow(12345, 67890, 10000019)
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000476 if signal.getitimer(self.itimer) == (0.0, 0.0):
477 break # sig_prof handler stopped this itimer
Stefan Krah488fea32010-04-20 08:07:08 +0000478 else: # Issue 8424
479 sys.stdout.write("test_itimer_prof: timeout: likely cause: "
480 "machine too slow or load too high.\n")
481 return
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000482
Jeffrey Yasskin2b860db2008-04-04 04:51:19 +0000483 # profiling itimer should be (0.0, 0.0) now
484 self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0))
485 # and the handler should have been called
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000486 self.assertEqual(self.hndl_called, True)
487
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000488def test_main():
Guido van Rossum02de8972007-12-19 19:41:06 +0000489 test_support.run_unittest(BasicSignalTests, InterProcessSignalTests,
Martin v. Löwisaef18b12008-03-24 13:31:16 +0000490 WakeupSignalTests, SiginterruptTest, ItimerTest)
Georg Brandl9f2b93e2007-08-24 18:07:52 +0000491
492
493if __name__ == "__main__":
494 test_main()