More precisely, on top of jelmer's branch, the following patch also resists the 1.000 stress test. (note that I wrongly tested it with TestingThreadingTCPServer instead of TestingTCPServer in DisconnectingServer at first, for even more stress tests).
@@ -41,13 +42,12 @@
from bzrlib.bundle.serializer.v4 import BundleSerializerV4
from bzrlib.repofmt import knitrepo
from bzrlib.tests import (
+ features,
+ test_commit,
test_read_bundle,
- test_commit,
+ test_server,
)
from bzrlib.transform import TreeTransform
-from bzrlib.tests import (
- features,
- )
def get_text(vf, key):
@@ -1836,7 +1836,7 @@
bundle, then the ConnectionReset error should be propagated.
"""
# Instantiate a server that will provoke a ConnectionReset
- sock_server = _DisconnectingTCPServer()
+ sock_server = DisconnectingServer() self.start_server(sock_server)
# We don't really care what the url is since the server will close the
# connection without interpreting it
@@ -1844,35 +1844,21 @@ self.assertRaises(errors.ConnectionReset, read_mergeable_from_url, url)
def get_url(self):
- return 'bzr://127.0.0.1:%d/' % (self.port,)
-
- def stop_server(self):
- try:
- # make sure the thread dies by connecting to the listening socket,
- # just in case the test failed to do so.
- conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- conn.connect(self.sock.getsockname())
- conn.close()
- except socket.error:
- pass
- self.sock.close()
- self.thread.join()
+ """Return the url of the server"""
+ return "bzr://%s:%d/" % self.server.server_address
It relies on the existing test servers to avoid several pitfalls in the _DisconnectingTCPServer implementation:
- exceptions will be re-raised in the main thread should any of them occur in the server,
- no race condition between accept_and_close() and start_server()
- no need to shutdown(socket.SHUT_RDWR) from the server side, a regular close() is enough here (in DisconnectingHandler.handle())
- properly handle several requests (which I think was the root hang cause as pointed out by poolie)
More precisely, on top of jelmer's branch, the following patch also resists the 1.000 stress test. (note that I wrongly tested it with TestingThreadin gTCPServer instead of TestingTCPServer in DisconnectingServer at first, for even more stress tests).
modified bzrlib/ tests/test_ bundle. py
=== modified file 'bzrlib/ tests/test_ bundle. py' tests/test_ bundle. py 2011-10-05 12:16:17 +0000 tests/test_ bundle. py 2011-11-28 10:57:48 +0000
--- bzrlib/
+++ bzrlib/
@@ -17,6 +17,7 @@
from cStringIO import StringIO
import os
import socket
+import SocketServer
import sys
import threading
@@ -41,13 +42,12 @@ bundle. serializer. v4 import BundleSerializerV4 read_bundle,
from bzrlib.
from bzrlib.repofmt import knitrepo
from bzrlib.tests import (
+ features,
+ test_commit,
test_
- test_commit,
+ test_server,
)
from bzrlib.transform import TreeTransform
-from bzrlib.tests import (
- features,
- )
def get_text(vf, key): CPServer( ) rver()
self. start_server( sock_server)
self. assertRaises( errors. ConnectionReset , read_mergeable_ from_url, url)
@@ -1836,7 +1836,7 @@
bundle, then the ConnectionReset error should be propagated.
"""
# Instantiate a server that will provoke a ConnectionReset
- sock_server = _DisconnectingT
+ sock_server = DisconnectingSe
# We don't really care what the url is since the server will close the
# connection without interpreting it
@@ -1844,35 +1844,21 @@
-class _DisconnectingT CPServer( object) : socket( socket. AF_INET, socket.SOCK_STREAM) bind((' 127.0.0. 1', 0)) getsockname( )[1] _class_ _.__name_ _, self.port), self.accept_ and_close) and_close( self): socket. SHUT_RDWR) ndler(SocketSer ver.BaseRequest Handler) : close() rver(test_ server. TestingTCPServe rInAThread) : tingServer, self).__init__( TestingTCPServe r, ndler)
- """A TCP server that immediately closes any connection made to it."""
-
- def start_server(self):
- self.sock = socket.
- self.sock.
- self.sock.listen(1)
- self.port = self.sock.
- self.thread = threading.Thread(
- name='%s (port %d)' % (self._
- target=
- self.thread.start()
-
- def accept_
- conn, addr = self.sock.accept()
- conn.shutdown(
- conn.close()
+class DisconnectingHa
+ """A request handler that immediately closes any connection made to it."""
+
+ def handle(self):
+ self.request.
+
+
+class DisconnectingSe
+
+ def __init__(self):
+ super(Disconnec
+ ('127.0.0.1', 0),
+ test_server.
+ DisconnectingHa
def get_url(self): 127.0.0. 1:%d/' % (self.port,) socket( socket. AF_INET, socket.SOCK_STREAM) self.sock. getsockname( )) server_ address
- return 'bzr://
-
- def stop_server(self):
- try:
- # make sure the thread dies by connecting to the listening socket,
- # just in case the test failed to do so.
- conn = socket.
- conn.connect(
- conn.close()
- except socket.error:
- pass
- self.sock.close()
- self.thread.join()
+ """Return the url of the server"""
+ return "bzr://%s:%d/" % self.server.
It relies on the existing test servers to avoid several pitfalls in the _DisconnectingT CPServer implementation:
- exceptions will be re-raised in the main thread should any of them occur in the server, socket. SHUT_RDWR) from the server side, a regular close() is enough here (in DisconnectingHa ndler.handle( ))
- no race condition between accept_and_close() and start_server()
- no need to shutdown(
- properly handle several requests (which I think was the root hang cause as pointed out by poolie)