Rev 5290: Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining. in file:///home/vila/src/bzr/experimental/leaking-tests/

Vincent Ladeuil v.ladeuil+lp at free.fr
Fri Jun 18 15:20:08 BST 2010


At file:///home/vila/src/bzr/experimental/leaking-tests/

------------------------------------------------------------
revno: 5290
revision-id: v.ladeuil+lp at free.fr-20100618142008-ra18rgm51i8fqryt
parent: v.ladeuil+lp at free.fr-20100618075117-mtkr7hzyz34hht7i
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: smart-server-leaks
timestamp: Fri 2010-06-18 16:20:08 +0200
message:
  Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
  
  * bzrlib/tests/test_server.py:
  (TestingSmartRequestHandler, TestingSmartServer)
  (SmartTCPServer_for_testing): Plug the smart server into
  TestingTCPServerInAThread.
-------------- next part --------------
=== modified file 'bzrlib/tests/test_server.py'
--- a/bzrlib/tests/test_server.py	2010-06-18 07:51:17 +0000
+++ b/bzrlib/tests/test_server.py	2010-06-18 14:20:08 +0000
@@ -506,7 +506,7 @@
         # Update the client description
         self.clients.pop()
         self.clients.append((request, client_address, t))
-        # Propagate the exception handler since we must the same one for
+        # Propagate the exception handler since we must use the same one for
         # connections running in their own threads than TestingTCPServer.
         t.set_ignored_exceptions(self.ignored_exceptions)
         t.start()
@@ -643,27 +643,61 @@
         self.server._pending_exception(self._server_thread)
 
 
-class SmartTCPServer_for_testing(server.SmartTCPServer):
+class TestingSmartRequestHandler(SocketServer.BaseRequestHandler,
+                                 medium.SmartServerSocketStreamMedium):
+
+    def __init__(self, request, client_address, server):
+        medium.SmartServerSocketStreamMedium.__init__(
+            self, request, server.backing_transport,
+            server.root_client_path)
+        request.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+        SocketServer.BaseRequestHandler.__init__(self, request, client_address,
+                                                 server)
+
+    def handle(self):
+        while not self.finished:
+            server_protocol = self._build_protocol()
+            self._serve_one_request(server_protocol)
+
+
+class TestingSmartServer(TestingThreadingTCPServer, server.SmartTCPServer):
+
+    def __init__(self, server_address, request_handler_class,
+                 backing_transport, root_client_path):
+        TestingThreadingTCPServer.__init__(self, server_address,
+                                           request_handler_class)
+        server.SmartTCPServer.__init__(self, backing_transport,
+                                       root_client_path)
+
+    def get_url(self):
+        """Return the url of the server"""
+        return "bzr://%s:%d/" % self.server_address
+
+
+class SmartTCPServer_for_testing(TestingTCPServerInAThread):
     """Server suitable for use by transport tests.
 
     This server is backed by the process's cwd.
     """
-
     def __init__(self, thread_name_suffix=''):
-        super(SmartTCPServer_for_testing, self).__init__(None)
         self.client_path_extra = None
         self.thread_name_suffix = thread_name_suffix
-        self._create_server_socket('127.0.0.1', 0)
-        # We collect the sockets/threads used by the clients so we can
-        # close/join them when shutting down
-        self.clients = []
-
-    def get_backing_transport(self, backing_transport_server):
-        """Get a backing transport from a server we are decorating."""
-        return transport.get_transport(backing_transport_server.get_url())
+        self.host = '127.0.0.1'
+        self.port = 0
+        super(SmartTCPServer_for_testing, self).__init__(
+                (self.host, self.port),
+                TestingSmartServer,
+                TestingSmartRequestHandler)
+
+    def create_server(self):
+        return self.server_class((self.host, self.port),
+                                 self.request_handler_class,
+                                 self.backing_transport,
+                                 self.root_client_path)
+
 
     def start_server(self, backing_transport_server=None,
-              client_path_extra='/extra/'):
+                     client_path_extra='/extra/'):
         """Set up server for testing.
 
         :param backing_transport_server: backing server to use.  If not
@@ -678,6 +712,7 @@
         """
         if not client_path_extra.startswith('/'):
             raise ValueError(client_path_extra)
+        self.root_client_path = self.client_path_extra = client_path_extra
         from bzrlib.transport.chroot import ChrootServer
         if backing_transport_server is None:
             backing_transport_server = LocalURLServer()
@@ -686,48 +721,14 @@
         self.chroot_server.start_server()
         self.backing_transport = transport.get_transport(
             self.chroot_server.get_url())
-        self.root_client_path = self.client_path_extra = client_path_extra
-        self.start_background_thread(self.thread_name_suffix)
-
-    def serve_conn(self, conn, thread_name_suffix):
-        conn_thread = super(SmartTCPServer_for_testing, self).serve_conn(
-            conn, thread_name_suffix)
-        self.clients.append((conn, conn_thread))
-        return conn_thread
-
-    def shutdown_client(self, client_socket):
-        """Properly shutdown a client socket.
-
-        Under some circumstances (as in bug #383920), we need to force the
-        shutdown as python delays it until gc occur otherwise and the client
-        may hang.
-
-        This should be called only when no other thread is trying to use the
-        socket.
-        """
-        try:
-            # The request process has been completed, the thread is about to
-            # die, let's shutdown the socket if we can.
-            client_socket.shutdown(socket.SHUT_RDWR)
-        except (socket.error, select.error), e:
-            if e[0] in (errno.EBADF, errno.ENOTCONN):
-                # Right, the socket is already down
-                pass
-            else:
-                raise
-
-    def stop_server(self):
-        self.stop_background_thread()
-        # Let's close all our pending clients too
-        for sock, thread in self.clients:
-            self.shutdown_client(sock)
-            thread.join()
-            del thread
-        self.clients = []
-        self.chroot_server.stop_server()
+        super(SmartTCPServer_for_testing, self).start_server()
+
+    def get_backing_transport(self, backing_transport_server):
+        """Get a backing transport from a server we are decorating."""
+        return transport.get_transport(backing_transport_server.get_url())
 
     def get_url(self):
-        url = super(SmartTCPServer_for_testing, self).get_url()
+        url = self.server.get_url()
         return url[:-1] + self.client_path_extra
 
     def get_bogus_url(self):



More information about the bazaar-commits mailing list