def test_registered_callback_gets_called(self): calls = [] def call_me(): calls.append('called') signals.register_on_hangup('myid', call_me) signals._sighup_handler(SIGHUP, None) self.assertEqual(['called'], calls) signals.unregister_on_hangup('myid')
def test_keyboard_interrupt_propagated(self): # In case we get 'stuck' while running a hangup function, we should # not suppress KeyboardInterrupt def call_me_and_raise(): raise KeyboardInterrupt() signals.register_on_hangup('myid', call_me_and_raise) self.assertRaises(KeyboardInterrupt, signals._sighup_handler, SIGHUP, None) signals.unregister_on_hangup('myid')
def test_unregister_during_call(self): # _sighup_handler should handle if some callbacks actually remove # themselves while running. calls = [] def call_me_and_unregister(): signals.unregister_on_hangup('myid') calls.append('called_and_unregistered') def call_me(): calls.append('called') signals.register_on_hangup('myid', call_me_and_unregister) signals.register_on_hangup('other', call_me) signals._sighup_handler(SIGHUP, None)
def test_not_installed(self): # If you haven't called bzrlib.smart.signals.install_sighup_handler, # then _on_sighup should be None, and all the calls become no-ops. signals._on_sighup = None calls = [] def call_me(): calls.append('called') signals.register_on_hangup('myid', calls) signals._sighup_handler(SIGHUP, None) signals.unregister_on_hangup('myid') log = self.get_log() self.assertEqual('', log)
def test_failing_callback(self): calls = [] def call_me(): calls.append('called') def fail_me(): raise RuntimeError('something bad happened') signals.register_on_hangup('myid', call_me) signals.register_on_hangup('otherid', fail_me) # _sighup_handler should call both, even though it got an exception signals._sighup_handler(SIGHUP, None) signals.unregister_on_hangup('myid') signals.unregister_on_hangup('otherid') log = self.get_log() self.assertContainsRe(log, '(?s)Traceback.*RuntimeError') self.assertEqual(['called'], calls)
def test_weak_references(self): # TODO: This is probably a very-CPython-specific test # Adding yourself to the callback should not make you immortal # We overrideAttr during the test suite, so that we don't pollute the # original dict. However, we can test that what we override matches # what we are putting there. self.assertIsInstance(signals._on_sighup, weakref.WeakValueDictionary) calls = [] def call_me(): calls.append('called') signals.register_on_hangup('myid', call_me) del call_me # Non-CPython might want to do a gc.collect() here signals._sighup_handler(SIGHUP, None) self.assertEqual([], calls)