[Zope-Checkins] CVS: ZODB3/ZEO/tests - ConnectionTests.py:1.4.2.5.4.2

Barry Warsaw barry@zope.com
Fri, 1 Aug 2003 18:34:36 -0400


Update of /cvs-repository/ZODB3/ZEO/tests
In directory cvs.zope.org:/tmp/cvs-serv8328

Modified Files:
      Tag: ZODB3-3_1-boston-branch
	ConnectionTests.py 
Log Message:
checkTimeoutProvokingConflicts(): New test which expands on
checkTimeoutAfterVote() and would -- if the ClientStorage patch wasn't
in place -- provoke the server side behavior we're trying to avoid.
Heh.


=== ZODB3/ZEO/tests/ConnectionTests.py 1.4.2.5.4.1 => 1.4.2.5.4.2 ===
--- ZODB3/ZEO/tests/ConnectionTests.py:1.4.2.5.4.1	Fri Aug  1 16:10:23 2003
+++ ZODB3/ZEO/tests/ConnectionTests.py	Fri Aug  1 18:34:30 2003
@@ -30,7 +30,7 @@
 from ZEO.tests.InvalidationTests import InvalidationTests
 
 from ZODB.Transaction import get_transaction, Transaction
-from ZODB.POSException import ReadOnlyError
+from ZODB.POSException import ReadOnlyError, ConflictError
 from ZODB.tests import StorageTestBase
 from ZODB.tests.MinPO import MinPO
 from ZODB.tests.StorageTestBase import zodb_pickle, zodb_unpickle
@@ -598,13 +598,83 @@
         # Now sleep long enough for the storage to time out
         time.sleep(3)
         storage.sync()
-        self.assert_(not storage.is_connected())
+        unless(not storage.is_connected())
         storage._wait()
-        self.assert_(storage.is_connected())
-        # This will just return
+        unless(storage.is_connected())
+        # We expect finish to fail
         raises(ClientDisconnected, storage.tpc_finish, t)
         # The cache should still be empty
         unless(not storage._cache._index)
         # Load should fail since the object should not be in either the cache
         # or the server.
         raises(KeyError, storage.load, oid, '')
+
+    def checkTimeoutProvokingConflicts(self):
+        eq = self.assertEqual
+        raises = self.assertRaises
+        unless = self.failUnless
+        self.shutdownServer()
+        self.startServer(transaction_timeout=1)
+        self._storage = storage = self.openClientStorage()
+        # Assert that the zeo cache is empty
+        unless(not storage._cache._index)
+        # Create the object
+        oid = storage.new_oid()
+        obj = MinPO(7)
+        ZERO = '\0'*8
+        # We need to successfully commit an object now so we have something to
+        # conflict about.
+        t = Transaction()
+        storage.tpc_begin(t)
+        revid1a = storage.store(oid, ZERO, zodb_pickle(obj), '', t)
+        revid1b = storage.tpc_vote(t)
+        revid1 = StorageTestBase.handle_serials(oid, revid1a, revid1b)
+        storage.tpc_finish(t)
+        # Now do a store, sleeping before the finish so as to cause a timeout
+        obj.value = 8
+        t = Transaction()
+        storage.tpc_begin(t)
+        revid2a = storage.store(oid, revid1, zodb_pickle(obj), '', t)
+        revid2b = storage.tpc_vote(t)
+        revid2 = StorageTestBase.handle_serials(oid, revid2a, revid2b)
+        # Now sleep long enough for the storage to time out
+        time.sleep(3)
+        storage.sync()
+        unless(not storage.is_connected())
+        storage._wait()
+        unless(storage.is_connected())
+        # We expect finish to fail
+        raises(ClientDisconnected, storage.tpc_finish, t)
+        # Now we think we've committed the second transaction, but we really
+        # haven't.  A third one should produce a POSKeyError on the server,
+        # which manifests as a ConflictError on the client.
+        obj.value = 9
+        t = Transaction()
+        storage.tpc_begin(t)
+        storage.store(oid, revid2, zodb_pickle(obj), '', t)
+        raises(ConflictError, storage.tpc_vote, t)
+        # Even aborting won't help
+        storage.tpc_abort(t)
+        storage.tpc_finish(t)
+        # Try again
+        obj.value = 10
+        t = Transaction()
+        storage.tpc_begin(t)
+        storage.store(oid, revid2, zodb_pickle(obj), '', t)
+        # Even aborting won't help
+        raises(ConflictError, storage.tpc_vote, t)
+        # Abort this one and try a transaction that should succeed
+        storage.tpc_abort(t)
+        storage.tpc_finish(t)
+        # Now do a store, sleeping before the finish so as to cause a timeout
+        obj.value = 11
+        t = Transaction()
+        storage.tpc_begin(t)
+        revid2a = storage.store(oid, revid1, zodb_pickle(obj), '', t)
+        revid2b = storage.tpc_vote(t)
+        revid2 = StorageTestBase.handle_serials(oid, revid2a, revid2b)
+        storage.tpc_finish(t)
+        # Now load the object and verify that it has a value of 11
+        data, revid = storage.load(oid, '')
+        eq(zodb_unpickle(data), MinPO(11))
+        eq(revid, revid2)