[Zodb-checkins] CVS: Zope/lib/python/ZEO/tests - InvalidationTests.py:1.4.4.3

Tim Peters tim.one at comcast.net
Mon Mar 8 11:56:58 EST 2004


Update of /cvs-repository/Zope/lib/python/ZEO/tests
In directory cvs.zope.org:/tmp/cvs-serv31187/lib/python/ZEO/tests

Modified Files:
      Tag: Zope-2_7-branch
	InvalidationTests.py 
Log Message:
Bring InvalidationTests closer to the current HEAD version.  We squashed
some rare failures there, which are still showing up in overnight
testrunner reports on Zope-2_7-branch (ConflictErrors popping where they
aren't normally expected -- but *can* pop up if timing is just right (or
wrong <wink>)).


=== Zope/lib/python/ZEO/tests/InvalidationTests.py 1.4.4.2 => 1.4.4.3 ===
--- Zope/lib/python/ZEO/tests/InvalidationTests.py:1.4.4.2	Wed Sep 17 16:10:27 2003
+++ Zope/lib/python/ZEO/tests/InvalidationTests.py	Mon Mar  8 11:56:56 2004
@@ -39,7 +39,66 @@
 # thought they added (i.e., the keys for which get_transaction().commit()
 # did not raise any exception).
 
-class StressThread(TestThread):
+class FailableThread(TestThread):
+
+    # mixin class
+    # subclass must provide
+    # - self.stop attribute (an event)
+    # - self._testrun() method
+
+    def testrun(self):
+        try:
+            self._testrun()
+        except:
+            # Report the failure here to all the other threads, so
+            # that they stop quickly.
+            self.stop.set()
+            raise
+
+
+class StressTask:
+    # Append integers startnum, startnum + step, startnum + 2*step, ...
+    # to 'tree'.  If sleep is given, sleep
+    # that long after each append.  At the end, instance var .added_keys
+    # is a list of the ints the thread believes it added successfully.
+    def __init__(self, testcase, db, threadnum, startnum,
+                 step=2, sleep=None):
+        self.db = db
+        self.threadnum = threadnum
+        self.startnum = startnum
+        self.step = step
+        self.sleep = sleep
+        self.added_keys = []
+        self.cn = self.db.open()
+        self.cn.setLocalTransaction()
+        self.cn.sync()
+
+    def doStep(self):
+        tree = self.cn.root()["tree"]
+        key = self.startnum
+        tree[key] = self.threadnum
+
+    def commit(self):
+        cn = self.cn
+        key = self.startnum
+        cn.getTransaction().note("add key %s" % key)
+        try:
+            cn.getTransaction().commit()
+        except ConflictError, msg:
+            cn.getTransaction().abort()
+            cn.sync()
+        else:
+            if self.sleep:
+                time.sleep(self.sleep)
+            self.added_keys.append(key)
+        self.startnum += self.step
+
+    def cleanup(self):
+        self.cn.getTransaction().abort()
+        self.cn.close()
+
+
+class StressThread(FailableThread):
 
     # Append integers startnum, startnum + step, startnum + 2*step, ...
     # to 'tree' until Event stop is set.  If sleep is given, sleep
@@ -57,7 +116,7 @@
         self.added_keys = []
         self.commitdict = commitdict
 
-    def testrun(self):
+    def _testrun(self):
         cn = self.db.open()
         while not self.stop.isSet():
             try:
@@ -87,7 +146,7 @@
             key += self.step
         cn.close()
 
-class LargeUpdatesThread(TestThread):
+class LargeUpdatesThread(FailableThread):
 
     # A thread that performs a lot of updates.  It attempts to modify
     # more than 25 objects so that it can test code that runs vote
@@ -106,6 +165,15 @@
         self.commitdict = commitdict
 
     def testrun(self):
+        try:
+            self._testrun()
+        except:
+            # Report the failure here to all the other threads, so
+            # that they stop quickly.
+            self.stop.set()
+            raise
+
+    def _testrun(self):
         cn = self.db.open()
         while not self.stop.isSet():
             try:
@@ -162,7 +230,7 @@
         self.added_keys = keys_added.keys()
         cn.close()
 
-class VersionStressThread(TestThread):
+class VersionStressThread(FailableThread):
 
     def __init__(self, testcase, db, stop, threadnum, commitdict, startnum,
                  step=2, sleep=None):
@@ -177,6 +245,15 @@
         self.commitdict = commitdict
 
     def testrun(self):
+        try:
+            self._testrun()
+        except:
+            # Report the failure here to all the other threads, so
+            # that they stop quickly.
+            self.stop.set()
+            raise
+
+    def _testrun(self):
         commit = 0
         key = self.startnum
         while not self.stop.isSet():
@@ -302,7 +379,10 @@
         delay = self.MINTIME
         start = time.time()
         while time.time() - start <= self.MAXTIME:
-            time.sleep(delay)
+            stop.wait(delay)
+            if stop.isSet():
+                # Some thread failed.  Stop right now.
+                break
             delay = 2.0
             if len(commitdict) >= len(threads):
                 break
@@ -321,6 +401,7 @@
         cn = db1.open()
         tree = cn.root()["tree"] = OOBTree()
         get_transaction().commit()
+        cn.close()
 
         # Run two threads that update the BTree
         cd = {}
@@ -328,7 +409,11 @@
         t2 = self.StressThread(self, db2, stop, 2, cd, 2)
         self.go(stop, cd, t1, t2)
 
-        cn.sync()
+        db1._storage.sync()
+        db2._storage.sync()
+
+        cn = db1.open()
+        tree = cn.root()["tree"]
         self._check_tree(cn, tree)
         self._check_threads(tree, t1, t2)
 
@@ -344,6 +429,7 @@
         cn = db1.open()
         tree = cn.root()["tree"] = OOBTree()
         get_transaction().commit()
+        cn.close()
 
         # Run two threads that update the BTree
         cd = {}
@@ -351,7 +437,8 @@
         t2 = self.StressThread(self, db1, stop, 2, cd, 2, sleep=0.01)
         self.go(stop, cd, t1, t2)
 
-        cn.sync()
+        cn = db1.open()
+        tree = cn.root()["tree"]
         self._check_tree(cn, tree)
         self._check_threads(tree, t1, t2)
 
@@ -367,6 +454,7 @@
         cn = db1.open()
         tree = cn.root()["tree"] = OOBTree()
         get_transaction().commit()
+        cn.close()
 
         # Run three threads that update the BTree.
         # Two of the threads share a single storage so that it
@@ -379,7 +467,11 @@
         t3 = self.StressThread(self, db2, stop, 3, cd, 3, 3, 0.01)
         self.go(stop, cd, t1, t2, t3)
 
-        cn.sync()
+        db1._storage.sync()
+        db2._storage.sync()
+
+        cn = db1.open()
+        tree = cn.root()["tree"]
         self._check_tree(cn, tree)
         self._check_threads(tree, t1, t2, t3)
 
@@ -396,6 +488,7 @@
         cn = db1.open()
         tree = cn.root()["tree"] = OOBTree()
         get_transaction().commit()
+        cn.close()
 
         # Run three threads that update the BTree.
         # Two of the threads share a single storage so that it
@@ -408,7 +501,11 @@
         t3 = VersionStressThread(self, db2, stop, 3, cd, 3, 3, 0.01)
         self.go(stop, cd, t1, t2, t3)
 
-        cn.sync()
+        db1._storage.sync()
+        db2._storage.sync()
+
+        cn = db1.open()
+        tree = cn.root()["tree"]
         self._check_tree(cn, tree)
         self._check_threads(tree, t1, t2, t3)
 
@@ -428,6 +525,7 @@
         for i in range(0, 3000, 2):
             tree[i] = 0
         get_transaction().commit()
+        cn.close()
 
         # Run three threads that update the BTree.
         # Two of the threads share a single storage so that it
@@ -440,7 +538,11 @@
         t3 = LargeUpdatesThread(self, db2, stop, 3, cd, 3, 3, 0.01)
         self.go(stop, cd, t1, t2, t3)
 
-        cn.sync()
+        db1._storage.sync()
+        db2._storage.sync()
+
+        cn = db1.open()
+        tree = cn.root()["tree"]
         self._check_tree(cn, tree)
 
         # Purge the tree of the dummy entries mapping to 0.




More information about the Zodb-checkins mailing list