Rev 3115: Select the server depending on the request handler protocol. Add tests. in file:///v/home/vila/src/bzr/bugs/175524/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Tue Dec 18 13:53:09 GMT 2007
At file:///v/home/vila/src/bzr/bugs/175524/
------------------------------------------------------------
revno: 3115
revision-id:v.ladeuil+lp at free.fr-20071218135304-rqiekrykivoq8qdm
parent: v.ladeuil+lp at free.fr-20071217101617-zsszx3y00yj25dd2
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 175524
timestamp: Tue 2007-12-18 14:53:04 +0100
message:
Select the server depending on the request handler protocol. Add tests.
* bzrlib/tests/test_http.py:
Fix some more imports.
(TestHTTPServer): Smoke test for hhtp server.
* bzrlib/tests/http_server.py:
(HttpServer._get_httpd): Create the server for the protocol
handled by the request handler.
(HttpServer._http_start): Catch exceptions that could occur during
server construction or python will hang.
(HttpServer.setUp): Report exception if any.
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-17 10:16:17 +0000
+++ b/bzrlib/tests/http_server.py 2007-12-18 13:53:04 +0000
@@ -348,6 +348,11 @@
Subclasses can provide a specific request handler.
"""
+ # The real servers depending on the protocol
+ http_server_class = {'HTTP/1.0': TestingHTTPServer,
+ 'HTTP/1.1': TestingThreadingHTTPServer,
+ }
+
# Whether or not we proxy the requests (see
# TestingHTTPRequestHandler.translate_path).
proxy_requests = False
@@ -367,20 +372,42 @@
def _get_httpd(self):
if self._httpd is None:
- self._httpd = TestingHTTPServer(
- (self.host, self.port), self.request_handler, self)
+ rhandler = self.request_handler
+ proto_vers = rhandler.protocol_version
+ # Create the appropriate server for the required protocol
+ serv_cls = self.http_server_class.get(proto_vers, None)
+ if serv_cls is None:
+ raise httplib.UnknownProtocol(proto_vers)
+ else:
+ self._httpd = serv_cls((self.host, self.port), rhandler, self)
host, self.port = self._httpd.socket.getsockname()
return self._httpd
def _http_start(self):
- httpd = self._get_httpd()
- self._http_base_url = '%s://%s:%s/' % (self._url_protocol,
- self.host,
- self.port)
- self._http_starting.release()
+ """Server thread main entry point. """
+ self._http_running = False
+ try:
+ try:
+ httpd = self._get_httpd()
+ self._http_base_url = '%s://%s:%s/' % (self._url_protocol,
+ self.host, self.port)
+ self._http_running = True
+ except:
+ # Whatever goes wrong, we save the exception for the main
+ # thread. Note that since we are running in a thread, no signal
+ # can be received, so we don't care about KeyboardInterrupt.
+ self._http_exception = sys.exc_info()
+ finally:
+ # Release the lock or the main thread will block and the whole
+ # process will hang.
+ self._http_starting.release()
+ # From now on, exceptions are taken care of by the
+ # SocketServer.BaseServer or the request handler.
while self._http_running:
try:
+ # Really an HTTP connection but the python framework is generic
+ # and call them requests
httpd.handle_request()
except socket.timeout:
pass
@@ -416,15 +443,21 @@
backing_transport_server
self._home_dir = os.getcwdu()
self._local_path_parts = self._home_dir.split(os.path.sep)
+ self._http_base_url = None
+
self._http_starting = threading.Lock()
self._http_starting.acquire()
- self._http_running = True
- self._http_base_url = None
self._http_thread = threading.Thread(target=self._http_start)
self._http_thread.setDaemon(True)
+ self._http_exception = None
self._http_thread.start()
+
# Wait for the server thread to start (i.e release the lock)
self._http_starting.acquire()
+
+ if self._http_exception is not None:
+ exc_class, exc_value, exc_tb = self._http_exception
+ raise exc_class, exc_value, exc_tb
self._http_starting.release()
self.logs = []
=== modified file 'bzrlib/tests/test_http.py'
--- a/bzrlib/tests/test_http.py 2007-12-11 14:26:18 +0000
+++ b/bzrlib/tests/test_http.py 2007-12-18 13:53:04 +0000
@@ -21,6 +21,7 @@
# TODO: What about renaming to bzrlib.tests.transport.http ?
from cStringIO import StringIO
+import httplib
import os
import select
import socket
@@ -37,16 +38,12 @@
urlutils,
)
from bzrlib.tests import (
+ http_server,
TestCase,
TestUIFactory,
TestSkipped,
StringIOWrapper,
)
-from bzrlib.tests.http_server import (
- HttpServer,
- HttpServer_PyCurl,
- HttpServer_urllib,
- )
from bzrlib.tests.http_utils import (
BadProtocolRequestHandler,
BadStatusRequestHandler,
@@ -151,6 +148,54 @@
self.port = None
+class TestHTTPServer(tests.TestCase):
+ """Test the HTTP servers implementations."""
+
+ def test_invalid_protocol(self):
+ class BogusRequestHandler(http_server.TestingHTTPRequestHandler):
+
+ protocol_version = 'HTTP/0.1'
+
+ server = http_server.HttpServer(BogusRequestHandler)
+ try:
+ self.assertRaises(httplib.UnknownProtocol,server.setUp)
+ except:
+ server.tearDown()
+ self.fail('HTTP Server creation did not raise UnknownProtocol')
+
+ def test_server_start_and_stop(self):
+ server = http_server.HttpServer()
+ server.setUp()
+ self.assertTrue(server._http_running)
+ server.tearDown()
+ self.assertFalse(server._http_running)
+
+ def test_create_http_server_one_zero(self):
+ class RequestHandlerOneZero(http_server.TestingHTTPRequestHandler):
+
+ protocol_version = 'HTTP/1.0'
+
+ server = http_server.HttpServer(RequestHandlerOneZero)
+ server.setUp()
+ try:
+ self.assertIsInstance(server._httpd, http_server.TestingHTTPServer)
+ finally:
+ server.tearDown()
+
+ def test_create_http_server_one_one(self):
+ class RequestHandlerOneOne(http_server.TestingHTTPRequestHandler):
+
+ protocol_version = 'HTTP/1.1'
+
+ server = http_server.HttpServer(RequestHandlerOneOne)
+ server.setUp()
+ try:
+ self.assertIsInstance(server._httpd,
+ http_server.TestingThreadingHTTPServer)
+ finally:
+ server.tearDown()
+
+
class TestWithTransport_pycurl(object):
"""Test case to inherit from if pycurl is present"""
@@ -231,7 +276,7 @@
"""Test http urls with urllib"""
_transport = HttpTransport_urllib
- _server = HttpServer_urllib
+ _server = http_server.HttpServer_urllib
_qualified_prefix = 'http+urllib'
@@ -239,7 +284,7 @@
tests.TestCase):
"""Test http urls with pycurl"""
- _server = HttpServer_PyCurl
+ _server = http_server.HttpServer_PyCurl
_qualified_prefix = 'http+pycurl'
# TODO: This should really be moved into another pycurl
@@ -433,7 +478,7 @@
"""Tests exceptions during the connection phase"""
def create_transport_readonly_server(self):
- return HttpServer(WallRequestHandler)
+ return http_server.HttpServer(WallRequestHandler)
def test_http_has(self):
server = self.get_readonly_server()
@@ -469,7 +514,7 @@
"""Tests bad status from server."""
def create_transport_readonly_server(self):
- return HttpServer(BadStatusRequestHandler)
+ return http_server.HttpServer(BadStatusRequestHandler)
def test_http_has(self):
server = self.get_readonly_server()
@@ -501,7 +546,7 @@
"""
def create_transport_readonly_server(self):
- return HttpServer(InvalidStatusRequestHandler)
+ return http_server.HttpServer(InvalidStatusRequestHandler)
class TestInvalidStatusServer_urllib(TestInvalidStatusServer,
@@ -521,7 +566,7 @@
"""Tests bad protocol from server."""
def create_transport_readonly_server(self):
- return HttpServer(BadProtocolRequestHandler)
+ return http_server.HttpServer(BadProtocolRequestHandler)
def test_http_has(self):
server = self.get_readonly_server()
@@ -551,7 +596,7 @@
"""Tests forbidden server"""
def create_transport_readonly_server(self):
- return HttpServer(ForbiddenRequestHandler)
+ return http_server.HttpServer(ForbiddenRequestHandler)
def test_http_has(self):
server = self.get_readonly_server()
@@ -688,7 +733,7 @@
"""Test readv against a server which accept only single range requests"""
def create_transport_readonly_server(self):
- return HttpServer(SingleRangeRequestHandler)
+ return http_server.HttpServer(SingleRangeRequestHandler)
class TestSingleRangeRequestServer_urllib(TestSingleRangeRequestServer,
@@ -708,7 +753,7 @@
"""Test readv against a server which only accept single range requests"""
def create_transport_readonly_server(self):
- return HttpServer(SingleOnlyRangeRequestHandler)
+ return http_server.HttpServer(SingleOnlyRangeRequestHandler)
class TestSingleOnlyRangeRequestServer_urllib(TestSingleOnlyRangeRequestServer,
@@ -728,7 +773,7 @@
"""Test readv against a server which do not accept range requests"""
def create_transport_readonly_server(self):
- return HttpServer(NoRangeRequestHandler)
+ return http_server.HttpServer(NoRangeRequestHandler)
class TestNoRangeRequestServer_urllib(TestNoRangeRequestServer,
More information about the bazaar-commits
mailing list