~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/http_server.py

  • Committer: Vincent Ladeuil
  • Date: 2007-12-23 17:48:27 UTC
  • mto: (3146.3.1 179368) (3156.2.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 3158.
  • Revision ID: v.ladeuil+lp@free.fr-20071223174827-sepgat9fxmpnax0f
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.

Show diffs side-by-side

added added

removed removed

Lines of Context:
283
283
            return path
284
284
 
285
285
 
286
 
class TestingHTTPServerWrapper(object):
287
 
    """Isolate the wrapper itself to make the server use transparent.
288
 
 
289
 
    Daughter classes can override any method and/or directly call the _server
290
 
    methods.
291
 
    """
292
 
 
293
 
    def __init__(self, server_class, test_case_server,
294
 
                 server_address, request_handler_class):
295
 
        self._server = server_class(server_address, request_handler_class)
 
286
class TestingHTTPServerMixin:
 
287
 
 
288
    def __init__(self, test_case_server):
296
289
        # test_case_server can be used to communicate between the
297
290
        # tests and the server (or the request handler and the
298
291
        # server), allowing dynamic behaviors to be defined from
299
292
        # the tests cases.
300
 
        self._server.test_case_server = test_case_server
301
 
 
302
 
    def __getattr__(self, name):
303
 
        return getattr(self._server, name)
304
 
 
305
 
    def server_bind(self):
306
 
        """Override server_bind to store the server name."""
307
 
        self._server.server_bind()
308
 
        host, port = self._server.socket.getsockname()[:2]
309
 
        self._server.server_name = socket.getfqdn(host)
310
 
        self._server.server_port = port
311
 
 
312
 
    def server_close(self):
 
293
        self.test_case_server = test_case_server
 
294
 
 
295
    def tearDown(self):
313
296
         """Called to clean-up the server.
314
297
 
315
298
         Since the server may be (surely is, even) in a blocking listen, we
317
300
         """
318
301
         # Note that is this executed as part of the implicit tear down in the
319
302
         # main thread while the server runs in its own thread. The clean way
320
 
         # to tear down the server will be to instruct him to stop accepting
321
 
         # connections and wait for the current connection to end naturally. To
322
 
         # end the connection naturally, the http transports should close their
323
 
         # socket when they do not need to talk to the server anymore.  We
324
 
         # don't want to impose such a constraint on the http transports (and
325
 
         # we can't anyway ;). So we must tear down here, from the main thread,
326
 
         # when the test have ended.  Note that since the server is in a
327
 
         # blocking operation and since python use select internally, shutting
328
 
         # down the socket is reliable and relatively clean.
329
 
         self._server.socket.shutdown(socket.SHUT_RDWR)
 
303
         # to tear down the server is to instruct him to stop accepting
 
304
         # connections and wait for the current connection(s) to end
 
305
         # naturally. To end the connection naturally, the http transports
 
306
         # should close their socket when they do not need to talk to the
 
307
         # server anymore. This happens naturally during the garbage collection
 
308
         # phase of the test transport objetcs (the server clients), so we
 
309
         # don't have to worry about them.  So, for the server, we must tear
 
310
         # down here, from the main thread, when the test have ended.  Note
 
311
         # that since the server is in a blocking operation and since python
 
312
         # use select internally, shutting down the socket is reliable and
 
313
         # relatively clean.
 
314
         self.socket.shutdown(socket.SHUT_RDWR)
330
315
         # Let the server properly close the socket
331
 
         self._server.server_close()
 
316
         self.server_close()
332
317
 
333
 
class TestingHTTPServer(TestingHTTPServerWrapper):
 
318
class TestingHTTPServer(SocketServer.TCPServer, TestingHTTPServerMixin):
334
319
 
335
320
    def __init__(self, server_address, request_handler_class, test_case_server):
336
 
        super(TestingHTTPServer, self).__init__(
337
 
            SocketServer.TCPServer, test_case_server,
338
 
            server_address, request_handler_class)
339
 
 
340
 
 
341
 
class TestingThreadingHTTPServer(TestingHTTPServerWrapper):
 
321
        TestingHTTPServerMixin.__init__(self, test_case_server)
 
322
        SocketServer.TCPServer.__init__(self, server_address,
 
323
                                        request_handler_class)
 
324
 
 
325
 
 
326
class TestingThreadingHTTPServer(SocketServer.ThreadingTCPServer,
 
327
                                 TestingHTTPServerMixin):
342
328
    """A threading HTTP test server for HTTP 1.1.
343
329
 
344
330
    Since tests can initiate several concurrent connections to the same http
347
333
    """
348
334
 
349
335
    def __init__(self, server_address, request_handler_class, test_case_server):
350
 
        super(TestingThreadingHTTPServer, self).__init__(
351
 
            SocketServer.ThreadingTCPServer, test_case_server,
352
 
            server_address, request_handler_class)
 
336
        TestingHTTPServerMixin.__init__(self, test_case_server)
 
337
        SocketServer.ThreadingTCPServer.__init__(self, server_address,
 
338
                                                 request_handler_class)
353
339
        # Decides how threads will act upon termination of the main
354
340
        # process. This is prophylactic as we should not leave the threads
355
341
        # lying around.
356
 
        self._server.daemon_threads = True
 
342
        self.daemon_threads = True
357
343
 
358
344
 
359
345
class HttpServer(transport.Server):
374
360
    # used to form the url that connects to this server
375
361
    _url_protocol = 'http'
376
362
 
377
 
    # Subclasses can provide a specific request handler
378
363
    def __init__(self, request_handler=TestingHTTPRequestHandler,
379
364
                 protocol_version=None):
380
365
        """Constructor.
497
482
 
498
483
    def tearDown(self):
499
484
        """See bzrlib.transport.Server.tearDown."""
500
 
        self._httpd.server_close()
 
485
        self._httpd.tearDown()
501
486
        self._http_running = False
502
 
        # FIXME: ensure that all threads have been shut down for the 1.1
503
 
        # server.
504
487
        self._http_thread.join()
505
488
 
506
489
    def get_url(self):