[Zope-Checkins] CVS: ZODB3/ZODB/tests - MTStorage.py:1.6.4.1
Jeremy Hylton
jeremy@zope.com
Tue, 13 May 2003 13:59:09 -0400
Update of /cvs-repository/ZODB3/ZODB/tests
In directory cvs.zope.org:/tmp/cvs-serv19734/tests
Modified Files:
Tag: ZODB3-3_1-branch
MTStorage.py
Log Message:
Fix occasional assertion errors in 7 zodb client threads test.
Backport code from ZODB4 that causes the test to fail when an
exception occurs in a thread.
Add a sync() call after abort() to clear ReadConflictError. This is
necessary in ZODB 3.1 because the Connection does not register with
the TM.
=== ZODB3/ZODB/tests/MTStorage.py 1.6 => 1.6.4.1 ===
--- ZODB3/ZODB/tests/MTStorage.py:1.6 Thu Sep 19 16:42:00 2002
+++ ZODB3/ZODB/tests/MTStorage.py Tue May 13 13:59:08 2003
@@ -1,4 +1,5 @@
import random
+import sys
import threading
import time
@@ -18,19 +19,50 @@
l.sort()
return l
-class ZODBClientThread(threading.Thread):
+class TestThread(threading.Thread):
+ """Base class for defining threads that run from unittest.
- __super_init = threading.Thread.__init__
+ If the thread exits with an uncaught exception, catch it and
+ re-raise it when the thread is joined. The re-raise will cause
+ the test to fail.
+
+ The subclass should define a runtest() method instead of a run()
+ method.
+ """
+
+ def __init__(self, test):
+ threading.Thread.__init__(self)
+ self.test = test
+ self._fail = None
+ self._exc_info = None
+
+ def run(self):
+ try:
+ self.runtest()
+ except:
+ self._exc_info = sys.exc_info()
+
+ def fail(self, msg=""):
+ self._test.fail(msg)
+
+ def join(self, timeout=None):
+ threading.Thread.join(self, timeout)
+ if self._exc_info:
+ raise self._exc_info[0], self._exc_info[1], self._exc_info[2]
+
+class ZODBClientThread(TestThread):
+
+ __super_init = TestThread.__init__
def __init__(self, db, test, commits=10, delay=SHORT_DELAY):
- self.__super_init()
+ self.__super_init(test)
self.setDaemon(1)
self.db = db
self.test = test
self.commits = commits
self.delay = delay
- def run(self):
+ def runtest(self):
conn = self.db.open()
root = conn.root()
d = self.get_thread_dict(root)
@@ -56,27 +88,28 @@
root[name] = m
get_transaction().commit()
break
- except ConflictError:
+ except ConflictError, err:
get_transaction().abort()
+ root._p_jar.sync()
for i in range(10):
try:
return root.get(name)
except ConflictError:
get_transaction().abort()
-class StorageClientThread(threading.Thread):
+class StorageClientThread(TestThread):
- __super_init = threading.Thread.__init__
+ __super_init = TestThread.__init__
def __init__(self, storage, test, commits=10, delay=SHORT_DELAY):
- self.__super_init()
+ self.__super_init(test)
self.storage = storage
self.test = test
self.commits = commits
self.delay = delay
self.oids = {}
- def run(self):
+ def runtest(self):
for i in range(self.commits):
self.dostore(i)
self.check()
@@ -120,7 +153,7 @@
class ExtStorageClientThread(StorageClientThread):
- def run(self):
+ def runtest(self):
# pick some other storage ops to execute
ops = [getattr(self, meth) for meth in dir(ExtStorageClientThread)
if meth.startswith('do_')]