[Zodb-checkins] CVS: ZODB3/ZEO/tests - ConnectionTests.py:1.12 forker.py:1.30 testClientCache.py:1.7 zeoserver.py:1.6
Jeremy Hylton
jeremy@zope.com
Fri, 3 Jan 2003 17:08:15 -0500
Update of /cvs-repository/ZODB3/ZEO/tests
In directory cvs.zope.org:/tmp/cvs-serv21352/ZEO/tests
Modified Files:
ConnectionTests.py forker.py testClientCache.py zeoserver.py
Log Message:
Merge ZODB3-fast-restart-branch to the trunk
=== ZODB3/ZEO/tests/ConnectionTests.py 1.11 => 1.12 ===
--- ZODB3/ZEO/tests/ConnectionTests.py:1.11 Fri Dec 20 00:22:06 2002
+++ ZODB3/ZEO/tests/ConnectionTests.py Fri Jan 3 17:07:40 2003
@@ -20,7 +20,9 @@
import socket
import asyncore
import tempfile
+import thread # XXX do we really need to catch thread.error
import threading
+import time
import zLOG
@@ -36,9 +38,18 @@
from ZODB.tests.StorageTestBase import zodb_pickle, zodb_unpickle
from ZODB.tests.StorageTestBase import handle_all_serials, ZERO
+class TestClientStorage(ClientStorage):
+
+ def verify_cache(self, stub):
+ self.end_verify = threading.Event()
+ self.verify_result = ClientStorage.verify_cache(self, stub)
+
+ def endVerify(self):
+ ClientStorage.endVerify(self)
+ self.end_verify.set()
class DummyDB:
- def invalidate(self, *args, **kws):
+ def invalidate(self, *args, **kwargs):
pass
@@ -48,6 +59,7 @@
__super_setUp = StorageTestBase.setUp
__super_tearDown = StorageTestBase.tearDown
keep = 0
+ invq = None
def setUp(self):
"""Test setup for connection tests.
@@ -99,17 +111,15 @@
raise NotImplementedError
def openClientStorage(self, cache='', cache_size=200000, wait=1,
- read_only=0, read_only_fallback=0,
- addr=None):
- if addr is None:
- addr = self.addr
- storage = ClientStorage(addr,
- client=cache,
- cache_size=cache_size,
- wait=wait,
- min_disconnect_poll=0.1,
- read_only=read_only,
- read_only_fallback=read_only_fallback)
+ read_only=0, read_only_fallback=0):
+ base = TestClientStorage(self.addr,
+ client=cache,
+ cache_size=cache_size,
+ wait=wait,
+ min_disconnect_poll=0.1,
+ read_only=read_only,
+ read_only_fallback=read_only_fallback)
+ storage = base
storage.registerDB(DummyDB(), None)
return storage
@@ -121,7 +131,7 @@
path = "%s.%d" % (self.file, index)
conf = self.getConfig(path, create, read_only)
zeoport, adminaddr, pid = forker.start_zeo_server(
- conf, addr, ro_svr, self.keep)
+ conf, addr, ro_svr, self.keep, self.invq)
self._pids.append(pid)
self._servers.append(adminaddr)
@@ -420,9 +430,9 @@
for t in threads:
t.closeclients()
-
class ReconnectionTests(CommonSetupTearDown):
keep = 1
+ invq = 2
def checkReadOnlyStorage(self):
# Open a read-only client to a read-only *storage*; stores fail
@@ -556,6 +566,113 @@
time.sleep(0.1)
else:
self.fail("Couldn't store after starting a read-write server")
+
+ def checkNoVerificationOnServerRestart(self):
+ self._storage = self.openClientStorage()
+ # When we create a new storage, it should always do a full
+ # verification
+ self.assertEqual(self._storage.verify_result, "full verification")
+ self._dostore()
+ self.shutdownServer()
+ self.pollDown()
+ self._storage.verify_result = None
+ self.startServer(create=0)
+ self.pollUp()
+ # There were no transactions committed, so no verification
+ # should be needed.
+ self.assertEqual(self._storage.verify_result, "no verification")
+
+ def checkNoVerificationOnServerRestartWith2Clients(self):
+ perstorage = self.openClientStorage(cache="test")
+ self.assertEqual(perstorage.verify_result, "full verification")
+
+ self._storage = self.openClientStorage()
+ oid = self._storage.new_oid()
+ # When we create a new storage, it should always do a full
+ # verification
+ self.assertEqual(self._storage.verify_result, "full verification")
+ # do two storages of the object to make sure an invalidation
+ # message is generated
+ revid = self._dostore(oid)
+ self._dostore(oid, revid)
+
+ perstorage.load(oid, '')
+
+ self.shutdownServer()
+
+ self.pollDown()
+ self._storage.verify_result = None
+ perstorage.verify_result = None
+ self.startServer(create=0)
+ self.pollUp()
+ # There were no transactions committed, so no verification
+ # should be needed.
+ self.assertEqual(self._storage.verify_result, "no verification")
+
+ perstorage.close()
+ self.assertEqual(perstorage.verify_result, "no verification")
+
+ def checkQuickVerificationWith2Clients(self):
+ perstorage = self.openClientStorage(cache="test")
+ self.assertEqual(perstorage.verify_result, "full verification")
+
+ self._storage = self.openClientStorage()
+ oid = self._storage.new_oid()
+ # When we create a new storage, it should always do a full
+ # verification
+ self.assertEqual(self._storage.verify_result, "full verification")
+ # do two storages of the object to make sure an invalidation
+ # message is generated
+ revid = self._dostore(oid)
+ revid = self._dostore(oid, revid)
+
+ perstorage.load(oid, '')
+ perstorage.close()
+
+ revid = self._dostore(oid, revid)
+
+ perstorage = self.openClientStorage(cache="test")
+ self.assertEqual(perstorage.verify_result, "quick verification")
+
+ self.assertEqual(perstorage.load(oid, ''),
+ self._storage.load(oid, ''))
+
+
+
+ def checkVerificationWith2ClientsInvqOverflow(self):
+ perstorage = self.openClientStorage(cache="test")
+ self.assertEqual(perstorage.verify_result, "full verification")
+
+ self._storage = self.openClientStorage()
+ oid = self._storage.new_oid()
+ # When we create a new storage, it should always do a full
+ # verification
+ self.assertEqual(self._storage.verify_result, "full verification")
+ # do two storages of the object to make sure an invalidation
+ # message is generated
+ revid = self._dostore(oid)
+ revid = self._dostore(oid, revid)
+
+ perstorage.load(oid, '')
+ perstorage.close()
+
+ # the test code sets invq bound to 2
+ for i in range(5):
+ revid = self._dostore(oid, revid)
+
+ perstorage = self.openClientStorage(cache="test")
+ self.assertEqual(perstorage.verify_result, "full verification")
+ t = time.time() + 30
+ while not perstorage.end_verify.isSet():
+ perstorage.sync()
+ if time.time() > t:
+ self.fail("timed out waiting for endVerify")
+
+ self.assertEqual(self._storage.load(oid, '')[1], revid)
+ self.assertEqual(perstorage.load(oid, ''),
+ self._storage.load(oid, ''))
+
+ perstorage.close()
class MSTThread(threading.Thread):
=== ZODB3/ZEO/tests/forker.py 1.29 => 1.30 ===
--- ZODB3/ZEO/tests/forker.py:1.29 Tue Dec 17 13:34:11 2002
+++ ZODB3/ZEO/tests/forker.py Fri Jan 3 17:07:40 2003
@@ -51,7 +51,7 @@
raise RuntimeError, "Can't find port"
-def start_zeo_server(conf, addr=None, ro_svr=0, keep=0):
+def start_zeo_server(conf, addr=None, ro_svr=0, keep=0, invq=None):
"""Start a ZEO server in a separate process.
Returns the ZEO port, the test server port, and the pid.
@@ -77,6 +77,8 @@
args.append('-r')
if keep:
args.append('-k')
+ if invq:
+ args += ['-Q', str(invq)]
args.append(str(port))
d = os.environ.copy()
d['PYTHONPATH'] = os.pathsep.join(sys.path)
=== ZODB3/ZEO/tests/testClientCache.py 1.6 => 1.7 ===
--- ZODB3/ZEO/tests/testClientCache.py:1.6 Wed Sep 18 17:22:58 2002
+++ ZODB3/ZEO/tests/testClientCache.py Fri Jan 3 17:07:40 2003
@@ -261,6 +261,19 @@
self.assert_(None is not cache._index.get(oid1) < 0)
self.assert_(None is not cache._index.get(oid2) < 0)
+ def testLastTid(self):
+ cache = self.cache
+ self.failUnless(cache.getLastTid() is None)
+ ltid = 'pqrstuvw'
+ cache.setLastTid(ltid)
+ self.assertEqual(cache.getLastTid(), ltid)
+ cache.checkSize(10*self.cachesize) # Force a file flip
+ self.assertEqual(cache.getLastTid(), ltid)
+ cache.setLastTid(None)
+ self.failUnless(cache.getLastTid() is None)
+ cache.checkSize(10*self.cachesize) # Force a file flip
+ self.failUnless(cache.getLastTid() is None)
+
class PersistentClientCacheTests(unittest.TestCase):
def setUp(self):
@@ -347,6 +360,26 @@
if loaded != None:
self.fail("invalidated data resurrected, size %d, was %d" %
(len(loaded[0]), len(data)))
+
+ def testPersistentLastTid(self):
+ cache = self.cache
+ self.failUnless(cache.getLastTid() is None)
+ ltid = 'pqrstuvw'
+ cache.setLastTid(ltid)
+ self.assertEqual(cache.getLastTid(), ltid)
+ oid = 'abcdefgh'
+ data = '1234'
+ serial = 'ABCDEFGH'
+ cache.store(oid, data, serial, '', '', '')
+ self.assertEqual(cache.getLastTid(), ltid)
+ cache.checkSize(10*self.cachesize) # Force a file flip
+ self.assertEqual(cache.getLastTid(), ltid)
+ cache = self.reopenCache()
+ self.assertEqual(cache.getLastTid(), ltid)
+ cache.setLastTid(None)
+ self.failUnless(cache.getLastTid() is None)
+ cache.checkSize(10*self.cachesize) # Force a file flip
+ self.failUnless(cache.getLastTid() is None)
def test_suite():
suite = unittest.TestSuite()
=== ZODB3/ZEO/tests/zeoserver.py 1.5 => 1.6 ===
--- ZODB3/ZEO/tests/zeoserver.py:1.5 Fri Jan 3 16:19:05 2003
+++ ZODB3/ZEO/tests/zeoserver.py Fri Jan 3 17:07:40 2003
@@ -116,8 +116,9 @@
ro_svr = 0
keep = 0
configfile = None
+ invalidation_queue_size = 100
# Parse the arguments and let getopt.error percolate
- opts, args = getopt.getopt(sys.argv[1:], 'rkC:')
+ opts, args = getopt.getopt(sys.argv[1:], 'rkC:Q:')
for opt, arg in opts:
if opt == '-r':
ro_svr = 1
@@ -125,6 +126,8 @@
keep = 1
elif opt == '-C':
configfile = arg
+ elif opt == '-Q':
+ invalidation_queue_size = int(arg)
# Open the config file and let ZConfig parse the data there. Then remove
# the config file, otherwise we'll leave turds.
fp = open(configfile, 'r')
@@ -145,7 +148,9 @@
sys.exit(2)
addr = ('', zeo_port)
log(label, 'creating the storage server')
- serv = ZEO.StorageServer.StorageServer(addr, {'1': storage}, ro_svr)
+ serv = ZEO.StorageServer.StorageServer(
+ addr, {'1': storage}, ro_svr,
+ invalidation_queue_size=invalidation_queue_size)
log(label, 'entering ThreadedAsync loop')
ThreadedAsync.LoopCallback.loop()