Rev 5276: Simplify stop_server and use a better sync for in file:///home/vila/src/bzr/experimental/leaking-tests/

Vincent Ladeuil v.ladeuil+lp at free.fr
Mon Jun 7 16:49:37 BST 2010


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

------------------------------------------------------------
revno: 5276
revision-id: v.ladeuil+lp at free.fr-20100607154937-zo90gld8628109ow
parent: v.ladeuil+lp at free.fr-20100607143055-2b8jjouvol0cfi87
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: propagate-exceptions
timestamp: Mon 2010-06-07 17:49:37 +0200
message:
  Simplify stop_server and use a better sync for
  test_exception_swallowed_while_serving test.
  
  * bzrlib/tests/test_test_server.py:
  (TestTCPServerInAThread.test_exception_swallowed_while_serving.FailingWhileServingConnectionHandler):
  We need to make sure the exception has been recorded which
  requires using the thread event.
  
  * bzrlib/tests/test_server.py:
  (TestingTCPServerMixin.serve): Make sure we clear the 'stopped'
  event.
  (TestingTCPServerMixin.shutdown_socket): Can also be used for the
  server socket.
  (TestingTCPServerInAThread.stop_server): Simplified, we just
  shutdown he socket.
-------------- next part --------------
=== modified file 'bzrlib/tests/test_server.py'
--- a/bzrlib/tests/test_server.py	2010-06-07 14:30:55 +0000
+++ b/bzrlib/tests/test_server.py	2010-06-07 15:49:37 +0000
@@ -350,13 +350,15 @@
         self.stopped.clear()
         # We are listening and ready to accept connections
         self.started.set()
-        while self.serving.isSet():
-            # Really a connection but the python framework is generic and
-            # call them requests
-            self.handle_request()
-        # Let's close the listening socket
-        self.server_close()
-        self.stopped.set()
+        try:
+            while self.serving.isSet():
+                # Really a connection but the python framework is generic and
+                # call them requests
+                self.handle_request()
+            # Let's close the listening socket
+            self.server_close()
+        finally:
+            self.stopped.set()
 
     def verify_request(self, request, client_address):
         """Verify the request.
@@ -389,18 +391,12 @@
             c = self.clients.pop()
             self.shutdown_client(c)
 
-    def shutdown_client_socket(self, sock):
-        """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.
+    def shutdown_socket(self, sock):
+        """Properly shutdown a socket.
 
         This should be called only when no other thread is trying to use the
         socket.
         """
-        # The request process has been completed, the thread is about to
-        # die, let's shutdown the socket if we can.
         try:
             sock.shutdown(socket.SHUT_RDWR)
             sock.close()
@@ -441,7 +437,7 @@
 
     def shutdown_client(self, client):
         sock, addr = client
-        self.shutdown_client_socket(sock)
+        self.shutdown_socket(sock)
 
 
 class TestingThreadingTCPServer(TestingTCPServerMixin,
@@ -490,7 +486,7 @@
 
     def shutdown_client(self, client):
         sock, addr, connection_thread = client
-        self.shutdown_client_socket(sock)
+        self.shutdown_socket(sock)
         if connection_thread is not None:
             # The thread has been created only if the request is processed but
             # after the connection is inited. This could happen during server
@@ -559,28 +555,21 @@
             self.server.serving.clear()
             self.set_ignored_exceptions(
                 self.server.ignored_exceptions_during_shutdown)
-            # The server is listening for a last connection, let's give it:
-            last_conn = None
-            try:
-                last_conn = osutils.connect_socket(self.server.server_address)
-            except socket.error, e:
-                # But ignore connection errors as the point is to unblock the
-                # server thread, it may happen that it's not blocked or even
-                # not started.
-                pass
+            self.server.shutdown_socket(self.server.socket)
             # We start shutting down the client while the server itself is
             # shutting down.
             self.server.stop_client_connections()
             # Now we wait for the thread running self.server.serve() to finish
             self.server.stopped.wait()
-            if last_conn is not None:
-                # Close the last connection without trying to use it. The
-                # server will not process a single byte on that socket to avoid
-                # complications (SSL starts with a handshake for example).
-                last_conn.close()
             # Check for any exception that could have occurred in the server
             # thread
-            self._server_thread.join()
+            try:
+                self._server_thread.join()
+            except Exception, e:
+                if self.server.ignored_exceptions(e):
+                    pass
+                else:
+                    raise
         finally:
             # Make sure we can be called twice safely, note that this means
             # that we will raise a single exception even if several occurred in

=== modified file 'bzrlib/tests/test_test_server.py'
--- a/bzrlib/tests/test_test_server.py	2010-06-07 12:55:58 +0000
+++ b/bzrlib/tests/test_test_server.py	2010-06-07 15:49:37 +0000
@@ -204,7 +204,9 @@
         class FailingWhileServingConnectionHandler(TCPConnectionHandler):
 
             def handle(self):
-                sync.set()
+                # We want to sync with the thread that is serving the
+                # connection.
+                threading.currentThread().set_event(sync)
                 raise CantServe()
 
         server = self.get_server(
@@ -212,7 +214,9 @@
         # Install the exception swallower
         server.set_ignored_exceptions(CantServe)
         client = self.get_client()
+        # Connect to the server so the exception is raised there
         client.connect(server.server_address)
+        # Wait for the exception to propagate.
         sync.wait()
         # The connection wasn't served properly but the exception should have
         # been swallowed.



More information about the bazaar-commits mailing list