Rev 3133: Rework TestingHTTPServer classes, fix test bug. in file:///v/home/vila/src/bzr/bugs/175524/

Vincent Ladeuil v.ladeuil+lp at free.fr
Sun Dec 23 17:48:31 GMT 2007


At file:///v/home/vila/src/bzr/bugs/175524/

------------------------------------------------------------
revno: 3133
revision-id:v.ladeuil+lp at free.fr-20071223174827-sepgat9fxmpnax0f
parent: v.ladeuil+lp at free.fr-20071221221252-hqz3g08cxp2mlku0
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 175524
timestamp: Sun 2007-12-23 18:48:27 +0100
message:
  Rework TestingHTTPServer classes, fix test bug.
  
  * bzrlib/tests/test_http.py:
  (TestRanges.create_transport_readonly_server): Take test
  parameters into account !
  
  * bzrlib/tests/http_server.py:
  (TestingHTTPServerMixin): Replace the wrapper hack.
  (TestingHTTPServerMixin.tearDown): The final explanation about
  request handlers termination.
  (HttpServer.tearDown): Stop messing around trying to find the
  right method name, use tearDown and delegate to server classes.
modified:
  bzrlib/tests/http_server.py    httpserver.py-20061012142527-m1yxdj1xazsf8d7s-1
  bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
-------------- next part --------------
=== modified file 'bzrlib/tests/http_server.py'
--- a/bzrlib/tests/http_server.py	2007-12-21 22:12:52 +0000
+++ b/bzrlib/tests/http_server.py	2007-12-23 17:48:27 +0000
@@ -283,33 +283,16 @@
             return path
 
 
-class TestingHTTPServerWrapper(object):
-    """Isolate the wrapper itself to make the server use transparent.
-
-    Daughter classes can override any method and/or directly call the _server
-    methods.
-    """
-
-    def __init__(self, server_class, test_case_server,
-                 server_address, request_handler_class):
-        self._server = server_class(server_address, request_handler_class)
+class TestingHTTPServerMixin:
+
+    def __init__(self, test_case_server):
         # test_case_server can be used to communicate between the
         # tests and the server (or the request handler and the
         # server), allowing dynamic behaviors to be defined from
         # the tests cases.
-        self._server.test_case_server = test_case_server
-
-    def __getattr__(self, name):
-        return getattr(self._server, name)
-
-    def server_bind(self):
-        """Override server_bind to store the server name."""
-        self._server.server_bind()
-        host, port = self._server.socket.getsockname()[:2]
-        self._server.server_name = socket.getfqdn(host)
-        self._server.server_port = port
-
-    def server_close(self):
+        self.test_case_server = test_case_server
+
+    def tearDown(self):
          """Called to clean-up the server.
  
          Since the server may be (surely is, even) in a blocking listen, we
@@ -317,28 +300,31 @@
          """
          # Note that is this executed as part of the implicit tear down in the
          # main thread while the server runs in its own thread. The clean way
-         # to tear down the server will be to instruct him to stop accepting
-         # connections and wait for the current connection to end naturally. To
-         # end the connection naturally, the http transports should close their
-         # socket when they do not need to talk to the server anymore.  We
-         # don't want to impose such a constraint on the http transports (and
-         # we can't anyway ;). So we must tear down here, from the main thread,
-         # when the test have ended.  Note that since the server is in a
-         # blocking operation and since python use select internally, shutting
-         # down the socket is reliable and relatively clean.
-         self._server.socket.shutdown(socket.SHUT_RDWR)
+         # to tear down the server is to instruct him to stop accepting
+         # connections and wait for the current connection(s) to end
+         # naturally. To end the connection naturally, the http transports
+         # should close their socket when they do not need to talk to the
+         # server anymore. This happens naturally during the garbage collection
+         # phase of the test transport objetcs (the server clients), so we
+         # don't have to worry about them.  So, for the server, we must tear
+         # down here, from the main thread, when the test have ended.  Note
+         # that since the server is in a blocking operation and since python
+         # use select internally, shutting down the socket is reliable and
+         # relatively clean.
+         self.socket.shutdown(socket.SHUT_RDWR)
          # Let the server properly close the socket
-         self._server.server_close()
+         self.server_close()
 
-class TestingHTTPServer(TestingHTTPServerWrapper):
+class TestingHTTPServer(SocketServer.TCPServer, TestingHTTPServerMixin):
 
     def __init__(self, server_address, request_handler_class, test_case_server):
-        super(TestingHTTPServer, self).__init__(
-            SocketServer.TCPServer, test_case_server,
-            server_address, request_handler_class)
-
-
-class TestingThreadingHTTPServer(TestingHTTPServerWrapper):
+        TestingHTTPServerMixin.__init__(self, test_case_server)
+        SocketServer.TCPServer.__init__(self, server_address,
+                                        request_handler_class)
+
+
+class TestingThreadingHTTPServer(SocketServer.ThreadingTCPServer,
+                                 TestingHTTPServerMixin):
     """A threading HTTP test server for HTTP 1.1.
 
     Since tests can initiate several concurrent connections to the same http
@@ -347,13 +333,13 @@
     """
 
     def __init__(self, server_address, request_handler_class, test_case_server):
-        super(TestingThreadingHTTPServer, self).__init__(
-            SocketServer.ThreadingTCPServer, test_case_server,
-            server_address, request_handler_class)
+        TestingHTTPServerMixin.__init__(self, test_case_server)
+        SocketServer.ThreadingTCPServer.__init__(self, server_address,
+                                                 request_handler_class)
         # Decides how threads will act upon termination of the main
         # process. This is prophylactic as we should not leave the threads
         # lying around.
-        self._server.daemon_threads = True
+        self.daemon_threads = True
 
 
 class HttpServer(transport.Server):
@@ -374,7 +360,6 @@
     # used to form the url that connects to this server
     _url_protocol = 'http'
 
-    # Subclasses can provide a specific request handler
     def __init__(self, request_handler=TestingHTTPRequestHandler,
                  protocol_version=None):
         """Constructor.
@@ -497,10 +482,8 @@
 
     def tearDown(self):
         """See bzrlib.transport.Server.tearDown."""
-        self._httpd.server_close()
+        self._httpd.tearDown()
         self._http_running = False
-        # FIXME: ensure that all threads have been shut down for the 1.1
-        # server.
         self._http_thread.join()
 
     def get_url(self):

=== modified file 'bzrlib/tests/test_http.py'
--- a/bzrlib/tests/test_http.py	2007-12-21 21:58:06 +0000
+++ b/bzrlib/tests/test_http.py	2007-12-23 17:48:27 +0000
@@ -559,12 +559,14 @@
 
     def test_http_has(self):
         if self._testing_pycurl() and self._protocol_version == 'HTTP/1.1':
-            raise tests.KnownFailure('pycurl hangs if the server send back garbage')
+            raise tests.KnownFailure(
+                'pycurl hangs if the server send back garbage')
         super(TestInvalidStatusServer, self).test_http_has()
 
     def test_http_get(self):
         if self._testing_pycurl() and self._protocol_version == 'HTTP/1.1':
-            raise tests.KnownFailure('pycurl hangs if the server send back garbage')
+            raise tests.KnownFailure(
+                'pycurl hangs if the server send back garbage')
         super(TestInvalidStatusServer, self).test_http_get()
 
 
@@ -815,10 +817,10 @@
 class TestLimitedRangeRequestServer(http_utils.TestCaseWithWebserver):
     """Tests readv requests against a server erroring out on too much ranges."""
 
+    # Requests with more range specifiers will error out
     range_limit = 3
 
     def create_transport_readonly_server(self):
-        # Requests with more range specifiers will error out
         return LimitedRangeHTTPServer(range_limit=self.range_limit,
                                       protocol_version=self._protocol_version)
 
@@ -1013,6 +1015,9 @@
         server = self.get_readonly_server()
         self.transport = self._transport(server.get_url())
 
+    def create_transport_readonly_server(self):
+        return http_server.HttpServer(protocol_version=self._protocol_version)
+
     def _file_contents(self, relpath, ranges):
         offsets = [ (start, end - start + 1) for start, end in ranges]
         coalesce = self.transport._coalesce_offsets



More information about the bazaar-commits mailing list