Rev 5561: Catch the bogus ssl exception for closed sockets. in file:///home/vila/src/bzr/bugs/686008-spurious-https-failure/

Vincent Ladeuil v.ladeuil+lp at free.fr
Tue Dec 7 16:18:51 GMT 2010


At file:///home/vila/src/bzr/bugs/686008-spurious-https-failure/

------------------------------------------------------------
revno: 5561
revision-id: v.ladeuil+lp at free.fr-20101207161850-59120ly8otdy633h
parent: pqm at pqm.ubuntu.com-20101206082400-6g52pmiz8tqwq3me
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 686008-spurious-https-failure
timestamp: Tue 2010-12-07 17:18:50 +0100
message:
  Catch the bogus ssl exception for closed sockets.
-------------- next part --------------
=== modified file 'bzrlib/tests/https_server.py'
--- a/bzrlib/tests/https_server.py	2010-07-01 06:40:14 +0000
+++ b/bzrlib/tests/https_server.py	2010-12-07 16:18:50 +0000
@@ -17,6 +17,7 @@
 """HTTPS test server, available when ssl python module is available"""
 
 import ssl
+import sys
 
 from bzrlib.tests import (
     http_server,
@@ -51,6 +52,17 @@
             request.do_handshake()
         return serving
 
+    def ignored_exceptions_during_shutdown(self, e):
+        if (sys.version < (2, 7) and isinstance(e, TypeError)
+            and e.args[0] == "'member_descriptor' object is not callable"):
+            # Fixed in python-2.7 (and some Ubuntu 2.6) there is a bug where
+            # the ssl socket fail to raise a socket.error when trying to read
+            # from a closed socket. This is rarely observed in practice but
+            # still make valid selftest runs fail if not caught.
+            return True
+        base = test_server.TestingTCPServerMixin
+        return base.ignored_exceptions_during_shutdown(self, e)
+
 
 class TestingHTTPSServer(TestingHTTPSServerMixin,
                          http_server.TestingHTTPServer):

=== modified file 'bzrlib/tests/test_http.py'
--- a/bzrlib/tests/test_http.py	2010-11-06 10:55:58 +0000
+++ b/bzrlib/tests/test_http.py	2010-12-07 16:18:50 +0000
@@ -2216,3 +2216,38 @@
         self.assertEqual('', stdout.getvalue())
 
 
+class TestBug686008(tests.TestCase):
+
+    _test_needs_features = [tests.HTTPSServerFeature]
+
+    def test_it(self):
+        from bzrlib.tests import https_server
+        import ssl
+        trigger_bug = False
+        class RequestHandler(http_server.TestingHTTPRequestHandler):
+
+            def handle_one_request(self):
+                if trigger_bug:
+                    # Now, break the ssl socket
+                    sock = socket.socket(socket.AF_INET)
+                    self.connection = ssl.wrap_socket(sock)
+                    self.rfile = self.connection.makefile('rb', self.rbufsize)
+                http_server.TestingHTTPRequestHandler.handle_one_request(self)
+
+            def do_HEAD(self):
+                # Always succeds, leaving the connection open
+                self.close_connection = 0
+                self.send_response(200)
+                self.end_headers()
+
+        server = https_server.HTTPSServer(RequestHandler)
+        self.start_server(server)
+        self.assertIsInstance(server.server,
+                              https_server.TestingThreadingHTTPSServer)
+        t = _urllib.HttpTransport_urllib(server.get_url())
+        self.addCleanup(t.disconnect)
+        # We need a first clean request
+        t.has('foo')
+        # Now we force the server to choke
+        trigger_bug = True
+        server.stop_server()

=== modified file 'bzrlib/tests/test_server.py'
--- a/bzrlib/tests/test_server.py	2010-08-31 08:24:17 +0000
+++ b/bzrlib/tests/test_server.py	2010-12-07 16:18:50 +0000
@@ -313,7 +313,7 @@
             self.ready.set()
 
 
-    def join(self, timeout=5):
+    def join(self, timeout=2000):
         """Overrides Thread.join to raise any exception caught.
 
 
@@ -531,8 +531,8 @@
         # Update the client description
         self.clients.pop()
         self.clients.append((request, client_address, t))
-        # Propagate the exception handler since we must use the same one for
-        # connections running in their own threads than TestingTCPServer.
+        # Propagate the exception handler since we must use the same one than
+        # TestingTCPServer for connections running in their own threads.
         t.set_ignored_exceptions(self.ignored_exceptions)
         t.start()
         started.wait()
@@ -634,7 +634,7 @@
                 # server thread, it may happen that it's not blocked or even
                 # not started.
                 pass
-            # We start shutting down the client while the server itself is
+            # We start shutting down the clients while the server itself is
             # shutting down.
             self.server.stop_client_connections()
             # Now we wait for the thread running self.server.serve() to finish

=== modified file 'doc/en/release-notes/bzr-2.3.txt'
--- a/doc/en/release-notes/bzr-2.3.txt	2010-12-03 11:16:25 +0000
+++ b/doc/en/release-notes/bzr-2.3.txt	2010-12-07 16:18:50 +0000
@@ -61,6 +61,9 @@
    suite.  This can include new facilities for writing tests, fixes to 
    spurious test failures and changes to the way things should be tested.
 
+* Catch exceptions realted to bug #637821 during test cleanup to avoid
+  spurious failures. (Vincent Ladeuil, #686008).
+
 * ``TestDebuntuExpansions`` was escaping the test isolation by calling the
   wrong base class ``setUp``. (Vincent Ladeuil, #684622)
 



More information about the bazaar-commits mailing list