1
# Copyright (C) 2006 Canonical Ltd
1
# Copyright (C) 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
781
781
def test_get_error_unexpected(self):
782
782
"""Error reported by server with no specific representation"""
783
783
class FlakyTransport(object):
784
785
def get_bytes(self, path):
785
786
raise Exception("some random exception from inside server")
786
787
smart_server = server.SmartTCPServer(backing_transport=FlakyTransport())
818
819
self.server = server.SmartTCPServer(self.backing_transport)
819
820
self.server.start_background_thread()
820
821
self.transport = remote.SmartTCPTransport(self.server.get_url())
822
self.addCleanup(self.tearDownServer)
824
def tearDownServer(self):
823
825
if getattr(self, 'transport', None):
824
826
self.transport.disconnect()
825
828
if getattr(self, 'server', None):
826
829
self.server.stop_background_thread()
827
super(SmartTCPTests, self).tearDown()
833
class TestServerSocketUsage(SmartTCPTests):
835
def test_server_setup_teardown(self):
836
"""It should be safe to teardown the server with no requests."""
839
transport = remote.SmartTCPTransport(self.server.get_url())
840
self.tearDownServer()
841
self.assertRaises(errors.ConnectionError, transport.has, '.')
843
def test_server_closes_listening_sock_on_shutdown_after_request(self):
844
"""The server should close its listening socket when it's stopped."""
847
self.transport.has('.')
848
self.tearDownServer()
849
# if the listening socket has closed, we should get a BADFD error
850
# when connecting, rather than a hang.
851
transport = remote.SmartTCPTransport(server.get_url())
852
self.assertRaises(errors.ConnectionError, transport.has, '.')
830
855
class WritableEndToEndTests(SmartTCPTests):
831
856
"""Client to server tests that require a writable transport."""
911
936
self.setUpServer(readonly=True)
912
937
self.assertRaises(errors.TransportNotPossible, self.transport.mkdir,
941
class TestServerHooks(SmartTCPTests):
943
def capture_server_call(self, backing_url, public_url):
944
"""Record a server_started|stopped hook firing."""
945
self.hook_calls.append((backing_url, public_url))
947
def test_server_started_hook(self):
948
"""The server_started hook fires when the server is started."""
950
server.SmartTCPServer.hooks.install_hook('server_started',
951
self.capture_server_call)
953
# at this point, the server will be starting a thread up.
954
# there is no indicator at the moment, so bodge it by doing a request.
955
self.transport.has('.')
956
self.assertEqual([(self.backing_transport.base, self.transport.base)],
959
def test_server_stopped_hook_simple(self):
960
"""The server_stopped hook fires when the server is stopped."""
962
server.SmartTCPServer.hooks.install_hook('server_stopped',
963
self.capture_server_call)
965
result = [(self.backing_transport.base, self.transport.base)]
966
# check the stopping message isn't emitted up front.
967
self.assertEqual([], self.hook_calls)
968
# nor after a single message
969
self.transport.has('.')
970
self.assertEqual([], self.hook_calls)
971
# clean up the server
972
self.tearDownServer()
973
# now it should have fired.
974
self.assertEqual(result, self.hook_calls)
976
# TODO: test that when the server suffers an exception that it calls the
977
# server-stopped hook.
916
980
class SmartServerRequestHandlerTests(tests.TestCaseWithTransport):
917
981
"""Test that call directly into the handler logic, bypassing the network."""