| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | import unittest | 
					
						
							|  |  |  | from test import test_support | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  | from contextlib import closing, nested | 
					
						
							| 
									
										
										
										
											2008-03-25 07:00:39 +00:00
										 |  |  | import gc | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  | import pickle | 
					
						
							|  |  |  | import select | 
					
						
							| 
									
										
										
										
											1995-03-16 15:07:38 +00:00
										 |  |  | import signal | 
					
						
							| 
									
										
										
										
											2008-03-21 18:25:06 +00:00
										 |  |  | import subprocess | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  | import traceback | 
					
						
							| 
									
										
										
										
											2008-02-28 21:00:45 +00:00
										 |  |  | import sys, os, time, errno | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if sys.platform[:3] in ('win', 'os2') or sys.platform == 'riscos': | 
					
						
							|  |  |  |     raise test_support.TestSkipped("Can't test signal on %s" % \ | 
					
						
							|  |  |  |                                    sys.platform) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-16 00:29:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-07 21:27:43 +00:00
										 |  |  | class HandlerBCalled(Exception): | 
					
						
							|  |  |  |     pass | 
					
						
							| 
									
										
										
										
											1995-03-16 15:07:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def exit_subprocess(): | 
					
						
							|  |  |  |     """Use os._exit(0) to exit the current subprocess.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Otherwise, the test catches the SystemExit and continues executing | 
					
						
							|  |  |  |     in parallel with the original test, so you wind up with an | 
					
						
							|  |  |  |     exponential number of tests running concurrently. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     os._exit(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  | def ignoring_eintr(__func, *args, **kwargs): | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         return __func(*args, **kwargs) | 
					
						
							| 
									
										
										
										
											2008-04-04 04:51:19 +00:00
										 |  |  |     except EnvironmentError as e: | 
					
						
							| 
									
										
										
										
											2008-04-04 16:48:19 +00:00
										 |  |  |         if e.errno != errno.EINTR: | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  |             raise | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | class InterProcessSignalTests(unittest.TestCase): | 
					
						
							|  |  |  |     MAX_DURATION = 20   # Entire test should last at most 20 sec. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-25 07:00:39 +00:00
										 |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.using_gc = gc.isenabled() | 
					
						
							|  |  |  |         gc.disable() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         if self.using_gc: | 
					
						
							|  |  |  |             gc.enable() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-06 23:04:28 +00:00
										 |  |  |     def format_frame(self, frame, limit=None): | 
					
						
							|  |  |  |         return ''.join(traceback.format_stack(frame, limit=limit)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def handlerA(self, signum, frame): | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  |         self.a_called = True | 
					
						
							|  |  |  |         if test_support.verbose: | 
					
						
							| 
									
										
										
										
											2008-04-06 23:04:28 +00:00
										 |  |  |             print "handlerA invoked from signal %s at:\n%s" % ( | 
					
						
							|  |  |  |                 signum, self.format_frame(frame, limit=1)) | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-06 23:04:28 +00:00
										 |  |  |     def handlerB(self, signum, frame): | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  |         self.b_called = True | 
					
						
							|  |  |  |         if test_support.verbose: | 
					
						
							| 
									
										
										
										
											2008-04-06 23:04:28 +00:00
										 |  |  |             print "handlerB invoked from signal %s at:\n%s" % ( | 
					
						
							|  |  |  |                 signum, self.format_frame(frame, limit=1)) | 
					
						
							|  |  |  |         raise HandlerBCalled(signum, self.format_frame(frame)) | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-21 18:25:06 +00:00
										 |  |  |     def wait(self, child): | 
					
						
							|  |  |  |         """Wait for child to finish, ignoring EINTR.""" | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |         while True: | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2008-03-21 18:25:06 +00:00
										 |  |  |                 child.wait() | 
					
						
							| 
									
										
										
										
											2008-03-21 05:51:37 +00:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |             except OSError as e: | 
					
						
							|  |  |  |                 if e.errno != errno.EINTR: | 
					
						
							|  |  |  |                     raise | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |     def run_test(self): | 
					
						
							|  |  |  |         # Install handlers. This function runs in a sub-process, so we | 
					
						
							|  |  |  |         # don't worry about re-setting the default handlers. | 
					
						
							|  |  |  |         signal.signal(signal.SIGHUP, self.handlerA) | 
					
						
							|  |  |  |         signal.signal(signal.SIGUSR1, self.handlerB) | 
					
						
							|  |  |  |         signal.signal(signal.SIGUSR2, signal.SIG_IGN) | 
					
						
							|  |  |  |         signal.signal(signal.SIGALRM, signal.default_int_handler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Variables the signals will modify: | 
					
						
							|  |  |  |         self.a_called = False | 
					
						
							|  |  |  |         self.b_called = False | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |         # Let the sub-processes know who to send signals to. | 
					
						
							|  |  |  |         pid = os.getpid() | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  |         if test_support.verbose: | 
					
						
							|  |  |  |             print "test runner's pid is", pid | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  |         child = ignoring_eintr(subprocess.Popen, ['kill', '-HUP', str(pid)]) | 
					
						
							|  |  |  |         if child: | 
					
						
							|  |  |  |             self.wait(child) | 
					
						
							|  |  |  |             if not self.a_called: | 
					
						
							|  |  |  |                 time.sleep(1)  # Give the signal time to be delivered. | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |         self.assertTrue(self.a_called) | 
					
						
							|  |  |  |         self.assertFalse(self.b_called) | 
					
						
							|  |  |  |         self.a_called = False | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-06 23:04:28 +00:00
										 |  |  |         # Make sure the signal isn't delivered while the previous | 
					
						
							|  |  |  |         # Popen object is being destroyed, because __del__ swallows | 
					
						
							|  |  |  |         # exceptions. | 
					
						
							|  |  |  |         del child | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2008-03-21 18:25:06 +00:00
										 |  |  |             child = subprocess.Popen(['kill', '-USR1', str(pid)]) | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |             # This wait should be interrupted by the signal's exception. | 
					
						
							|  |  |  |             self.wait(child) | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  |             time.sleep(1)  # Give the signal time to be delivered. | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |             self.fail('HandlerBCalled exception not thrown') | 
					
						
							|  |  |  |         except HandlerBCalled: | 
					
						
							|  |  |  |             self.assertTrue(self.b_called) | 
					
						
							|  |  |  |             self.assertFalse(self.a_called) | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  |             if test_support.verbose: | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |                 print "HandlerBCalled exception caught" | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  |         child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)]) | 
					
						
							|  |  |  |         if child: | 
					
						
							|  |  |  |             self.wait(child)  # Nothing should happen. | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             signal.alarm(1) | 
					
						
							|  |  |  |             # The race condition in pause doesn't matter in this case, | 
					
						
							|  |  |  |             # since alarm is going to raise a KeyboardException, which | 
					
						
							|  |  |  |             # will skip the call. | 
					
						
							|  |  |  |             signal.pause() | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  |             # But if another signal arrives before the alarm, pause | 
					
						
							|  |  |  |             # may return early. | 
					
						
							|  |  |  |             time.sleep(1) | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  |         except KeyboardInterrupt: | 
					
						
							|  |  |  |             if test_support.verbose: | 
					
						
							|  |  |  |                 print "KeyboardInterrupt (the alarm() went off)" | 
					
						
							|  |  |  |         except: | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  |             self.fail("Some other exception woke us from pause: %s" % | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |                       traceback.format_exc()) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2008-04-02 04:07:44 +00:00
										 |  |  |             self.fail("pause returned of its own accord, and the signal" | 
					
						
							|  |  |  |                       " didn't arrive after another second.") | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_main(self): | 
					
						
							|  |  |  |         # This function spawns a child process to insulate the main | 
					
						
							|  |  |  |         # test-running process from all the signals. It then | 
					
						
							|  |  |  |         # communicates with that child process over a pipe and | 
					
						
							|  |  |  |         # re-raises information about any exceptions the child | 
					
						
							|  |  |  |         # throws. The real work happens in self.run_test(). | 
					
						
							|  |  |  |         os_done_r, os_done_w = os.pipe() | 
					
						
							|  |  |  |         with nested(closing(os.fdopen(os_done_r)), | 
					
						
							|  |  |  |                     closing(os.fdopen(os_done_w, 'w'))) as (done_r, done_w): | 
					
						
							|  |  |  |             child = os.fork() | 
					
						
							|  |  |  |             if child == 0: | 
					
						
							|  |  |  |                 # In the child process; run the test and report results | 
					
						
							|  |  |  |                 # through the pipe. | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     done_r.close() | 
					
						
							|  |  |  |                     # Have to close done_w again here because | 
					
						
							|  |  |  |                     # exit_subprocess() will skip the enclosing with block. | 
					
						
							|  |  |  |                     with closing(done_w): | 
					
						
							|  |  |  |                         try: | 
					
						
							|  |  |  |                             self.run_test() | 
					
						
							|  |  |  |                         except: | 
					
						
							|  |  |  |                             pickle.dump(traceback.format_exc(), done_w) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             pickle.dump(None, done_w) | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     print 'Uh oh, raised from pickle.' | 
					
						
							|  |  |  |                     traceback.print_exc() | 
					
						
							|  |  |  |                 finally: | 
					
						
							|  |  |  |                     exit_subprocess() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             done_w.close() | 
					
						
							|  |  |  |             # Block for up to MAX_DURATION seconds for the test to finish. | 
					
						
							|  |  |  |             r, w, x = select.select([done_r], [], [], self.MAX_DURATION) | 
					
						
							|  |  |  |             if done_r in r: | 
					
						
							|  |  |  |                 tb = pickle.load(done_r) | 
					
						
							|  |  |  |                 if tb: | 
					
						
							|  |  |  |                     self.fail(tb) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 os.kill(child, signal.SIGKILL) | 
					
						
							|  |  |  |                 self.fail('Test deadlocked after %d seconds.' % | 
					
						
							|  |  |  |                           self.MAX_DURATION) | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BasicSignalTests(unittest.TestCase): | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |     def trivial_signal_handler(self, *args): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  |     def test_out_of_range_signal_number_raises_error(self): | 
					
						
							|  |  |  |         self.assertRaises(ValueError, signal.getsignal, 4242) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertRaises(ValueError, signal.signal, 4242, | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |                           self.trivial_signal_handler) | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_setting_signal_handler_to_none_raises_error(self): | 
					
						
							|  |  |  |         self.assertRaises(TypeError, signal.signal, | 
					
						
							|  |  |  |                           signal.SIGUSR1, None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |     def test_getsignal(self): | 
					
						
							|  |  |  |         hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler) | 
					
						
							|  |  |  |         self.assertEquals(signal.getsignal(signal.SIGHUP), | 
					
						
							|  |  |  |                           self.trivial_signal_handler) | 
					
						
							|  |  |  |         signal.signal(signal.SIGHUP, hup) | 
					
						
							|  |  |  |         self.assertEquals(signal.getsignal(signal.SIGHUP), hup) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-19 19:41:06 +00:00
										 |  |  | class WakeupSignalTests(unittest.TestCase): | 
					
						
							|  |  |  |     TIMEOUT_FULL = 10 | 
					
						
							|  |  |  |     TIMEOUT_HALF = 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_wakeup_fd_early(self): | 
					
						
							|  |  |  |         import select | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         signal.alarm(1) | 
					
						
							|  |  |  |         before_time = time.time() | 
					
						
							|  |  |  |         # We attempt to get a signal during the sleep, | 
					
						
							|  |  |  |         # before select is called | 
					
						
							|  |  |  |         time.sleep(self.TIMEOUT_FULL) | 
					
						
							|  |  |  |         mid_time = time.time() | 
					
						
							|  |  |  |         self.assert_(mid_time - before_time < self.TIMEOUT_HALF) | 
					
						
							|  |  |  |         select.select([self.read], [], [], self.TIMEOUT_FULL) | 
					
						
							|  |  |  |         after_time = time.time() | 
					
						
							|  |  |  |         self.assert_(after_time - mid_time < self.TIMEOUT_HALF) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_wakeup_fd_during(self): | 
					
						
							|  |  |  |         import select | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         signal.alarm(1) | 
					
						
							|  |  |  |         before_time = time.time() | 
					
						
							|  |  |  |         # We attempt to get a signal during the select call | 
					
						
							|  |  |  |         self.assertRaises(select.error, select.select, | 
					
						
							|  |  |  |             [self.read], [], [], self.TIMEOUT_FULL) | 
					
						
							|  |  |  |         after_time = time.time() | 
					
						
							|  |  |  |         self.assert_(after_time - before_time < self.TIMEOUT_HALF) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         import fcntl | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None) | 
					
						
							|  |  |  |         self.read, self.write = os.pipe() | 
					
						
							|  |  |  |         flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0) | 
					
						
							|  |  |  |         flags = flags | os.O_NONBLOCK | 
					
						
							|  |  |  |         fcntl.fcntl(self.write, fcntl.F_SETFL, flags) | 
					
						
							|  |  |  |         self.old_wakeup = signal.set_wakeup_fd(self.write) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         signal.set_wakeup_fd(self.old_wakeup) | 
					
						
							|  |  |  |         os.close(self.read) | 
					
						
							|  |  |  |         os.close(self.write) | 
					
						
							|  |  |  |         signal.signal(signal.SIGALRM, self.alrm) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-23 15:07:35 +00:00
										 |  |  | class SiginterruptTest(unittest.TestCase): | 
					
						
							|  |  |  |     signum = signal.SIGUSR1 | 
					
						
							|  |  |  |     def readpipe_interrupted(self, cb): | 
					
						
							|  |  |  |         r, w = os.pipe() | 
					
						
							|  |  |  |         ppid = os.getpid() | 
					
						
							|  |  |  |         pid = os.fork() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         oldhandler = signal.signal(self.signum, lambda x,y: None) | 
					
						
							|  |  |  |         cb() | 
					
						
							|  |  |  |         if pid==0: | 
					
						
							|  |  |  |             # child code: sleep, kill, sleep. and then exit, | 
					
						
							|  |  |  |             # which closes the pipe from which the parent process reads | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 time.sleep(0.2) | 
					
						
							|  |  |  |                 os.kill(ppid, self.signum) | 
					
						
							|  |  |  |                 time.sleep(0.2) | 
					
						
							|  |  |  |             finally: | 
					
						
							| 
									
										
										
										
											2008-03-21 05:02:44 +00:00
										 |  |  |                 exit_subprocess() | 
					
						
							| 
									
										
										
										
											2008-02-23 15:07:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             os.close(w) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 d=os.read(r, 1) | 
					
						
							|  |  |  |                 return False | 
					
						
							|  |  |  |             except OSError, err: | 
					
						
							|  |  |  |                 if err.errno != errno.EINTR: | 
					
						
							|  |  |  |                     raise | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             signal.signal(self.signum, oldhandler) | 
					
						
							|  |  |  |             os.waitpid(pid, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_without_siginterrupt(self): | 
					
						
							|  |  |  |         i=self.readpipe_interrupted(lambda: None) | 
					
						
							|  |  |  |         self.assertEquals(i, True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_siginterrupt_on(self): | 
					
						
							|  |  |  |         i=self.readpipe_interrupted(lambda: signal.siginterrupt(self.signum, 1)) | 
					
						
							|  |  |  |         self.assertEquals(i, True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_siginterrupt_off(self): | 
					
						
							|  |  |  |         i=self.readpipe_interrupted(lambda: signal.siginterrupt(self.signum, 0)) | 
					
						
							|  |  |  |         self.assertEquals(i, False) | 
					
						
							| 
									
										
										
										
											2007-12-19 19:41:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-24 13:31:16 +00:00
										 |  |  | class ItimerTest(unittest.TestCase): | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.hndl_called = False | 
					
						
							|  |  |  |         self.hndl_count = 0 | 
					
						
							|  |  |  |         self.itimer = None | 
					
						
							| 
									
										
										
										
											2008-03-25 07:00:39 +00:00
										 |  |  |         self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm) | 
					
						
							| 
									
										
										
										
											2008-03-24 13:31:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							| 
									
										
										
										
											2008-03-25 07:00:39 +00:00
										 |  |  |         signal.signal(signal.SIGALRM, self.old_alarm) | 
					
						
							| 
									
										
										
										
											2008-03-24 13:31:16 +00:00
										 |  |  |         if self.itimer is not None: # test_itimer_exc doesn't change this attr | 
					
						
							|  |  |  |             # just ensure that itimer is stopped | 
					
						
							|  |  |  |             signal.setitimer(self.itimer, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def sig_alrm(self, *args): | 
					
						
							|  |  |  |         self.hndl_called = True | 
					
						
							|  |  |  |         if test_support.verbose: | 
					
						
							|  |  |  |             print("SIGALRM handler invoked", args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def sig_vtalrm(self, *args): | 
					
						
							|  |  |  |         self.hndl_called = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.hndl_count > 3: | 
					
						
							|  |  |  |             # it shouldn't be here, because it should have been disabled. | 
					
						
							|  |  |  |             raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL " | 
					
						
							|  |  |  |                 "timer.") | 
					
						
							|  |  |  |         elif self.hndl_count == 3: | 
					
						
							|  |  |  |             # disable ITIMER_VIRTUAL, this function shouldn't be called anymore | 
					
						
							|  |  |  |             signal.setitimer(signal.ITIMER_VIRTUAL, 0) | 
					
						
							|  |  |  |             if test_support.verbose: | 
					
						
							|  |  |  |                 print("last SIGVTALRM handler call") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.hndl_count += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if test_support.verbose: | 
					
						
							|  |  |  |             print("SIGVTALRM handler invoked", args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def sig_prof(self, *args): | 
					
						
							|  |  |  |         self.hndl_called = True | 
					
						
							|  |  |  |         signal.setitimer(signal.ITIMER_PROF, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if test_support.verbose: | 
					
						
							|  |  |  |             print("SIGPROF handler invoked", args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_itimer_exc(self): | 
					
						
							|  |  |  |         # XXX I'm assuming -1 is an invalid itimer, but maybe some platform | 
					
						
							|  |  |  |         # defines it ? | 
					
						
							|  |  |  |         self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0) | 
					
						
							| 
									
										
										
										
											2008-03-25 07:00:39 +00:00
										 |  |  |         # Negative times are treated as zero on some platforms. | 
					
						
							|  |  |  |         if 0: | 
					
						
							|  |  |  |             self.assertRaises(signal.ItimerError, | 
					
						
							|  |  |  |                               signal.setitimer, signal.ITIMER_REAL, -1) | 
					
						
							| 
									
										
										
										
											2008-03-24 13:31:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_itimer_real(self): | 
					
						
							|  |  |  |         self.itimer = signal.ITIMER_REAL | 
					
						
							|  |  |  |         signal.setitimer(self.itimer, 1.0) | 
					
						
							|  |  |  |         if test_support.verbose: | 
					
						
							|  |  |  |             print("\ncall pause()...") | 
					
						
							|  |  |  |         signal.pause() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(self.hndl_called, True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_itimer_virtual(self): | 
					
						
							|  |  |  |         self.itimer = signal.ITIMER_VIRTUAL | 
					
						
							|  |  |  |         signal.signal(signal.SIGVTALRM, self.sig_vtalrm) | 
					
						
							|  |  |  |         signal.setitimer(self.itimer, 0.3, 0.2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for i in xrange(100000000): | 
					
						
							|  |  |  |             if signal.getitimer(self.itimer) == (0.0, 0.0): | 
					
						
							|  |  |  |                 break # sig_vtalrm handler stopped this itimer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # virtual itimer should be (0.0, 0.0) now | 
					
						
							|  |  |  |         self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) | 
					
						
							|  |  |  |         # and the handler should have been called | 
					
						
							|  |  |  |         self.assertEquals(self.hndl_called, True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_itimer_prof(self): | 
					
						
							|  |  |  |         self.itimer = signal.ITIMER_PROF | 
					
						
							|  |  |  |         signal.signal(signal.SIGPROF, self.sig_prof) | 
					
						
							| 
									
										
										
										
											2008-04-04 04:51:19 +00:00
										 |  |  |         signal.setitimer(self.itimer, 0.2, 0.2) | 
					
						
							| 
									
										
										
										
											2008-03-24 13:31:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for i in xrange(100000000): | 
					
						
							|  |  |  |             if signal.getitimer(self.itimer) == (0.0, 0.0): | 
					
						
							|  |  |  |                 break # sig_prof handler stopped this itimer | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 04:51:19 +00:00
										 |  |  |         # profiling itimer should be (0.0, 0.0) now | 
					
						
							|  |  |  |         self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) | 
					
						
							|  |  |  |         # and the handler should have been called | 
					
						
							| 
									
										
										
										
											2008-03-24 13:31:16 +00:00
										 |  |  |         self.assertEqual(self.hndl_called, True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | def test_main(): | 
					
						
							| 
									
										
										
										
											2007-12-19 19:41:06 +00:00
										 |  |  |     test_support.run_unittest(BasicSignalTests, InterProcessSignalTests, | 
					
						
							| 
									
										
										
										
											2008-03-24 13:31:16 +00:00
										 |  |  |         WakeupSignalTests, SiginterruptTest, ItimerTest) | 
					
						
							| 
									
										
										
										
											2007-08-24 18:07:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     test_main() |