def test_inet_server_responds_to_sighup(self): t = transport.get_transport('memory:///') content = 'a'*1024*1024 t.put_bytes('bigfile', content) factory = server.BzrServerFactory() # Override stdin/stdout so that we can inject our own handles client_read, server_write = self.create_file_pipes() server_read, client_write = self.create_file_pipes() factory._get_stdin_stdout = lambda: (server_read, server_write) factory.set_up(t, None, None, inet=True, timeout=4.0) self.addCleanup(factory.tear_down) started = threading.Event() stopped = threading.Event() def serving(): started.set() factory.smart_server.serve() stopped.set() server_thread = threading.Thread(target=serving) server_thread.start() started.wait() client_medium = medium.SmartSimplePipesClientMedium(client_read, client_write, 'base') client_client = client._SmartClient(client_medium) resp, response_handler = client_client.call_expecting_body('get', 'bigfile') signals._sighup_handler(SIGHUP, None) self.assertTrue(factory.smart_server.finished) # We can still finish reading the file content, but more than that, and # the file is closed. v = response_handler.read_body_bytes() if v != content: self.fail('Got the wrong content back, expected 1M "a"') stopped.wait() server_thread.join()
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_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)
def test_inet_server_responds_to_sighup(self): t = transport.get_transport('memory:///') content = 'a' * 1024 * 1024 t.put_bytes('bigfile', content) factory = server.BzrServerFactory() # Override stdin/stdout so that we can inject our own handles client_read, server_write = self.create_file_pipes() server_read, client_write = self.create_file_pipes() factory._get_stdin_stdout = lambda: (server_read, server_write) factory.set_up(t, None, None, inet=True, timeout=4.0) self.addCleanup(factory.tear_down) started = threading.Event() stopped = threading.Event() def serving(): started.set() factory.smart_server.serve() stopped.set() server_thread = threading.Thread(target=serving) server_thread.start() started.wait() client_medium = medium.SmartSimplePipesClientMedium( client_read, client_write, 'base') client_client = client._SmartClient(client_medium) resp, response_handler = client_client.call_expecting_body( 'get', 'bigfile') signals._sighup_handler(SIGHUP, None) self.assertTrue(factory.smart_server.finished) # We can still finish reading the file content, but more than that, and # the file is closed. v = response_handler.read_body_bytes() if v != content: self.fail('Got the wrong content back, expected 1M "a"') stopped.wait() server_thread.join()