[Zodb-checkins] CVS: ZODB3/ZEO/tests - InvalidationTests.py:1.1.4.11

Tim Peters tim.one at comcast.net
Mon Aug 25 19:42:54 EDT 2003


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

Modified Files:
      Tag: ZODB3-3_1-branch
	InvalidationTests.py 
Log Message:
LargeUpdatesThread.testrun():  stick aborts() and syncs() everywhere like
all the other tests do <0.6 wink>.  Use a different way to generate keys
that guarantees distinct threads use different keys.  Accumulate a set
of added keys instead of a list, because the list can contain duplicates
(if the test runs fast enough, a thread can add the same key more than
once).

InvalidationTests.checkConcurrentLargeUpdates():  This didn't really need
its own unique way to check test results.  Rewrote to do a little post-
processing on the tree so that the common result-checking code could
be used.

This still fails almost all the time on Windows using Berkeley, and the
cause of that still isn't understood.  The problem appears to go away
if each thread uses a post-commit sleep of 0.5 seconds; 0.2 seconds isn't
enough(!).


=== ZODB3/ZEO/tests/InvalidationTests.py 1.1.4.10 => 1.1.4.11 ===
--- ZODB3/ZEO/tests/InvalidationTests.py:1.1.4.10	Sat Aug 23 20:06:45 2003
+++ ZODB3/ZEO/tests/InvalidationTests.py	Mon Aug 25 18:42:53 2003
@@ -91,8 +91,6 @@
     # more than 25 objects so that it can test code that runs vote
     # in a separate thread when it modifies more than 25 objects.
 
-    keys = range(3000)
-
     def __init__(self, testcase, db, stop, threadnum, startnum,
                  step=2, sleep=None):
         TestThread.__init__(self, testcase)
@@ -111,45 +109,53 @@
                 tree = cn.root()["tree"]
                 break
             except (ConflictError, KeyError):
+                # print "%d getting tree abort" % self.threadnum
                 get_transaction().abort()
                 cn.sync()
 
-        tkeys = range(self.threadnum, 3000)
+        keys_added = {} # set of keys we commit
+        tkeys = []
         while not self.stop.isSet():
 
-            # The test picks 50 keys spread across many buckets.  The
-            # three threads start with different offsets to minimize
-            # conflict errors.
+            # The test picks 50 keys spread across many buckets.
+            # self.startnum and self.step ensure that all threads use
+            # disjoint key sets, to minimize conflict errors.
 
             nkeys = len(tkeys)
             if nkeys < 50:
-                tkeys = range(self.threadnum, 3000)
+                tkeys = range(self.startnum, 3000, self.step)
                 nkeys = len(tkeys)
-            step = max(nkeys / 50, 1)
-            keys = [tkeys[i] for i in range(0, nkeys - 1, step)]
+            step = max(int(nkeys / 50), 1)
+            keys = [tkeys[i] for i in range(0, nkeys, step)]
             for key in keys:
                 try:
                     tree[key] = self.threadnum
                 except (ReadConflictError, ConflictError), msg:
+                    # print "%d setting key %s" % (self.threadnum, msg)
+                    get_transaction().abort()
                     cn.sync()
                     break
             else:
+                # print "%d set #%d" % (self.threadnum, len(keys))
                 get_transaction().note("keys %s" % ", ".join(map(str, keys)))
                 try:
                     get_transaction().commit()
                     if self.sleep:
                         time.sleep(self.sleep)
                 except ConflictError, msg:
+                    # print "%d commit %s" % (self.threadnum, msg)
                     get_transaction().abort()
+                    cn.sync()
                     continue
                 for k in keys:
                     tkeys.remove(k)
-                self.added_keys += keys
+                    keys_added[k] = 1
                 # sync() is necessary here to process invalidations
                 # if we get a read conflict.  In the read conflict case,
                 # no objects were modified so cn never got registered
                 # with the transaction.
                 cn.sync()
+        self.added_keys = keys_added.keys()
         cn.close()
 
 class VersionStressThread(TestThread):
@@ -409,28 +415,13 @@
         cn.sync()
         self._check_tree(cn, tree)
 
-        # check the threads differently here than in the other tests
-        L = [None, t1, t2, t3]
-        errormsgs = []
-        err = errormsgs.append
-        for t in t1, t2, t3:
-            if not t.added_keys:
-                err("thread %d didn't add any keys" % t.threadnum)
-            for k in t.added_keys:
-                if not tree.has_key(k):
-                    err("%d in thread %d's added_keys, but %d not in "
-                        "tree" % (k, t.threadnum, k))
-                elif tree[k] == 0:
-                    err("%d in thread %d's added_keys, but tree[%d]==0" %
-                        (k, t.threadnum, k))
-        for k, tnum in tree.items():
-            if tnum > 0 and k not in L[tnum].added_keys:
-                err("tree believes %d was added by thread %d, but %d isn't "
-                    "in thread %d's added_keys" % (k, tnum, k, tnum))
+        # Purge the tree of the dummy entries mapping to 0.
+        losers = [k for k, v in tree.items() if v == 0]
+        for k in losers:
+            del tree[k]
+        get_transaction().commit()
 
-        if errormsgs:
-            display(tree)
-            self.fail('\n'.join(errormsgs))
+        self._check_threads(tree, t1, t2, t3)
 
         cn.close()
         db1.close()




More information about the Zodb-checkins mailing list