~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_server.py

  • Committer: Vincent Ladeuil
  • Date: 2010-06-03 16:10:48 UTC
  • mto: (5247.6.1 http-leaks)
  • mto: This revision was merged to the branch mainline in revision 5396.
  • Revision ID: v.ladeuil+lp@free.fr-20100603161048-n0ir7wz6t7qtycg4
Spawn a thread for each connection from a client.

* bzrlib/tests/test_test_server.py:
(TestTestingServerInAThread.test_client_talks_server_respond):
Check that the connection has been collected.

* bzrlib/tests/test_server.py:
(TestingTCPServerMixin.get_request)
(TestingThreadingTCPServer.get_request): Collect the resources
used for a client connection.
(TestingThreadingTCPServer.process_request): Spawn a thread for
each connection.

Show diffs side-by-side

added added

removed removed

Lines of Context:
296
296
        self.started = threading.Event()
297
297
        self.serving = threading.Event()
298
298
        self.stopped = threading.Event()
 
299
        # We collect the resources used by the clients so we can release them
 
300
        # when shutting down
 
301
        self.clients = []
299
302
 
300
303
    def server_bind(self):
301
304
        # We need to override the SocketServer bind, yet, we still want to use
323
326
        """Verify the request.
324
327
 
325
328
        Return True if we should proceed with this request, False if we should
326
 
        not even touch a single byte in the socket ! This is used to stop the
327
 
        server with a dummy last connection.
 
329
        not even touch a single byte in the socket ! This is useful when we
 
330
        stop the server with a dummy last connection.
328
331
        """
329
332
        return self.serving.isSet()
330
333
 
331
 
    def stop_clients(self):
332
 
        pass
333
 
 
334
 
 
335
 
class TestingTCPServer(TestingTCPServerMixin, SocketServer.TCPServer):
336
 
 
337
 
    def __init__(self, server_address, request_handler_class):
338
 
        TestingTCPServerMixin.__init__(self, SocketServer.TCPServer)
339
 
        SocketServer.TCPServer.__init__(self, server_address,
340
 
                                        request_handler_class)
341
 
 
342
334
    def handle_error(self, request, client_address):
343
335
        # Stop serving and re-raise the last exception seen
344
336
        self.serving.clear()
345
337
        raise
346
338
 
 
339
    def stop_clients(self):
 
340
        pass
 
341
 
 
342
 
 
343
class TestingTCPServer(TestingTCPServerMixin, SocketServer.TCPServer):
 
344
 
 
345
    def __init__(self, server_address, request_handler_class):
 
346
        TestingTCPServerMixin.__init__(self, SocketServer.TCPServer)
 
347
        SocketServer.TCPServer.__init__(self, server_address,
 
348
                                        request_handler_class)
 
349
 
 
350
    def get_request(self):
 
351
        """Get the request and client address from the socket."""
 
352
        sock, addr = self.sibling_class.get_request(self)
 
353
        self.clients.append((sock, addr))
 
354
        return sock, addr
 
355
 
 
356
    # The following methods are called by the main thread
 
357
 
347
358
 
348
359
class TestingThreadingTCPServer(TestingTCPServerMixin,
349
360
                                SocketServer.ThreadingTCPServer):
353
364
        SocketServer.TCPServer.__init__(self, server_address,
354
365
                                        request_handler_class)
355
366
 
 
367
    def get_request (self):
 
368
        """Get the request and client address from the socket."""
 
369
        sock, addr = self.sibling_class.get_request(self)
 
370
        # The thread is not create yet, it will be updated in process_request
 
371
        self.clients.append((sock, addr, None))
 
372
        return sock, addr
 
373
 
 
374
    def process_request_thread(self, stopped, request, client_address):
 
375
        SocketServer.ThreadingTCPServer.process_request_thread(
 
376
            self, request, client_address)
 
377
        self.close_request(request)
 
378
        stopped.set()
 
379
 
 
380
    def process_request(self, request, client_address):
 
381
        """Start a new thread to process the request."""
 
382
        stopped = threading.Event()
 
383
        t = test_server.ThreadWithException(
 
384
            event=stopped,
 
385
            target = self.process_request_thread,
 
386
            args = (stopped, request, client_address))
 
387
        t.name = '%s -> %s' % (client_address, self.server_address)
 
388
        if 'threads' in tests.selftest_debug_flags:
 
389
            print 'Thread for: %s started' % (threading.currentThread().name,)
 
390
        # Update the client description
 
391
        self.clients.pop()
 
392
        self.clients.append((request, client_address, t))
 
393
        t.start()
 
394
 
356
395
 
357
396
class TestingTCPServerInAThread(object):
358
397
    """A server in a thread that re-raise thread exceptions."""
408
447
            # server thread, it may happen that it's not blocked or even not
409
448
            # started.
410
449
            pass
 
450
        # We don't have to wait for the server to shut down to start shutting
 
451
        # down the clients, so let's start now.
411
452
        self.server.stop_clients()
412
453
        # Now we wait for the thread running self.server.serve() to finish
413
454
        self.server.stopped.wait()
424
465
            # Make sure we can be called twice safely
425
466
            self.server = None
426
467
 
 
468
 
427
469
class TestingThreadingTCPServerInAThread(TestingTCPServerInAThread):
428
470
    """A socket server in a thread which spawn one thread for each connection"""
429
471