[Zodb-checkins] SVN: ZODB/trunk/src/ZEO/tests/ Improved the get_port function to address a race condition. This
Jim Fulton
jim at zope.com
Sat Nov 15 14:56:17 EST 2008
Log message for revision 92986:
Improved the get_port function to address a race condition. This
requires passing a test object.
With this, it appears that I can run tests in parallel without getting
extra spurious errors.
Changed:
U ZODB/trunk/src/ZEO/tests/ConnectionTests.py
U ZODB/trunk/src/ZEO/tests/forker.py
U ZODB/trunk/src/ZEO/tests/testZEO.py
U ZODB/trunk/src/ZEO/tests/zeoserver.py
-=-
Modified: ZODB/trunk/src/ZEO/tests/ConnectionTests.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/ConnectionTests.py 2008-11-15 19:09:08 UTC (rev 92985)
+++ ZODB/trunk/src/ZEO/tests/ConnectionTests.py 2008-11-15 19:56:16 UTC (rev 92986)
@@ -165,7 +165,7 @@
self.addr.append(self._getAddr())
def _getAddr(self):
- return 'localhost', forker.get_port()
+ return 'localhost', forker.get_port(self)
def getConfig(self, path, create, read_only):
raise NotImplementedError
Modified: ZODB/trunk/src/ZEO/tests/forker.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/forker.py 2008-11-15 19:09:08 UTC (rev 92985)
+++ ZODB/trunk/src/ZEO/tests/forker.py 2008-11-15 19:56:16 UTC (rev 92986)
@@ -23,6 +23,7 @@
import StringIO
import tempfile
import logging
+import zope.testing.setupstack
logger = logging.getLogger('ZEO.tests.forker')
@@ -203,7 +204,7 @@
logger.debug('shutdown_zeo_server(): acked: %s' % ack)
s.close()
-def get_port():
+def get_port(test=None):
"""Return a port that is not in use.
Checks if a port is in use by trying to connect to it. Assumes it
@@ -213,6 +214,10 @@
Raises RuntimeError after 10 tries.
"""
+
+ if test is not None:
+ return get_port2(test)
+
for i in range(10):
port = random.randrange(20000, 30000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -238,3 +243,37 @@
s.close()
s1.close()
raise RuntimeError("Can't find port")
+
+def get_port2(test):
+ for i in range(10):
+ while 1:
+ port = random.randrange(20000, 30000)
+ if port%3 == 0:
+ break
+
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.bind(('localhost', port+2))
+ except socket.error, e:
+ if e[0] != errno.EADDRINUSE:
+ raise
+ continue
+
+ if not (can_connect(port) or can_connect(port+1)):
+ zope.testing.setupstack.register(test, s.close)
+ return port
+
+ s.close()
+
+ raise RuntimeError("Can't find port")
+
+def can_connect(port):
+ c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ c.connect(('localhost', port))
+ except socket.error:
+ return False # Perhaps we should check value of error too.
+ else:
+ c.close()
+ return True
+
Modified: ZODB/trunk/src/ZEO/tests/testZEO.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/testZEO.py 2008-11-15 19:09:08 UTC (rev 92985)
+++ ZODB/trunk/src/ZEO/tests/testZEO.py 2008-11-15 19:56:16 UTC (rev 92986)
@@ -224,7 +224,7 @@
def setUp(self):
StorageTestBase.StorageTestBase.setUp(self)
logger.info("setUp() %s", self.id())
- port = get_port()
+ port = get_port(self)
zconf = forker.ZEOConfig(('', port))
zport, adminaddr, pid, path = forker.start_zeo_server(self.getConfig(),
zconf, port)
@@ -310,7 +310,7 @@
""" % tempfile.mktemp(dir='.')
def _new_storage(self):
- port = get_port()
+ port = get_port(self)
zconf = forker.ZEOConfig(('', port))
zport, adminaddr, pid, path = forker.start_zeo_server(self.getConfig(),
zconf, port)
@@ -571,7 +571,7 @@
def _makeBaseStorage(self):
logger.info("setUp() %s", self.id())
- port = get_port()
+ port = get_port(self)
zconf = forker.ZEOConfig(('', port))
zport, adminaddr, pid, path = forker.start_zeo_server(self.getConfig(),
zconf, port)
@@ -1091,28 +1091,40 @@
connection closed
"""
-test_classes = [FileStorageTests, FileStorageRecoveryTests,
- MappingStorageTests, DemoStorageTests,
- BlobAdaptedFileStorageTests, BlobWritableCacheTests,
- ConfigurationTests,
- ]
+slow_test_classes = [
+ BlobAdaptedFileStorageTests, BlobWritableCacheTests,
+ DemoStorageTests, FileStorageTests, MappingStorageTests,
+ ]
+
+quick_test_classes = [FileStorageRecoveryTests, ConfigurationTests]
+def setUp(test):
+ ZODB.tests.util.setUp(test)
+ test.globs['get_port'] = lambda : get_port(test)
+
def test_suite():
suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ZODB.tests.util.AAAA_Test_Runner_Hack))
- suite.addTest(doctest.DocTestSuite(
- setUp=zope.testing.setupstack.setUpDirectory,
- tearDown=zope.testing.setupstack.tearDown))
- suite.addTest(doctest.DocFileSuite(
- 'registerDB.test'
- ))
- suite.addTest(
- doctest.DocFileSuite('zeo-fan-out.test',
- setUp=zope.testing.setupstack.setUpDirectory,
- tearDown=zope.testing.setupstack.tearDown,
- ),
+
+ # Collect misc tests into their own layer to educe size of
+ # unit test layer
+ zeo = unittest.TestSuite()
+ zeo.addTest(unittest.makeSuite(ZODB.tests.util.AAAA_Test_Runner_Hack))
+ zeo.addTest(doctest.DocTestSuite(
+ setUp=setUp, tearDown=zope.testing.setupstack.tearDown))
+ zeo.addTest(doctest.DocFileSuite('registerDB.test'))
+ zeo.addTest(
+ doctest.DocFileSuite(
+ 'zeo-fan-out.test',
+ setUp=setUp, tearDown=zope.testing.setupstack.tearDown,
+ ),
)
- for klass in test_classes:
+ for klass in quick_test_classes:
+ zeo.addTest(unittest.makeSuite(klass, "check"))
+ zeo.layer = ZODB.tests.util.MininalTestLayer('testZeo-misc')
+ suite.addTest(zeo)
+
+ # Put the heavyweights in their own layers
+ for klass in slow_test_classes:
sub = unittest.makeSuite(klass, "check")
sub.layer = ZODB.tests.util.MininalTestLayer(klass.__name__)
suite.addTest(sub)
Modified: ZODB/trunk/src/ZEO/tests/zeoserver.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/zeoserver.py 2008-11-15 19:09:08 UTC (rev 92985)
+++ ZODB/trunk/src/ZEO/tests/zeoserver.py 2008-11-15 19:56:16 UTC (rev 92986)
@@ -195,7 +195,8 @@
log(label, 'creating the test server, keep: %s', keep)
t = ZEOTestServer(test_addr, server, keep)
except socket.error, e:
- if e[0] <> errno.EADDRINUSE: raise
+ if e[0] != errno.EADDRINUSE:
+ raise
log(label, 'addr in use, closing and exiting')
storage.close()
cleanup(storage)
More information about the Zodb-checkins
mailing list