[Zope3-checkins] CVS: ZODB/src/ZODB/tests - PackableStorage.py:1.33
Tim Peters
tim.one at comcast.net
Fri Mar 12 13:08:14 EST 2004
Update of /cvs-repository/ZODB/src/ZODB/tests
In directory cvs.zope.org:/tmp/cvs-serv24766/src/ZODB/tests
Modified Files:
PackableStorage.py
Log Message:
_PackWhileWriting(): Save a lot more info to display in case of failure.
Forcing the output even when a test passes is interesting on my box.
When ZEO is involved, a single ClientThread tends to run all the way to
completion before another ClientThread manages to sneak in -- apart from
their first transactions, it's as if we ran one thread, then started the
next after the first finished (etc). When ZEO isn't involved, threads
take turns. When I see failures, they involve ZEO. It's possible that
30 seconds just isn't long enough to wait on this box.
=== ZODB/src/ZODB/tests/PackableStorage.py 1.32 => 1.33 ===
--- ZODB/src/ZODB/tests/PackableStorage.py:1.32 Thu Mar 11 22:11:34 2004
+++ ZODB/src/ZODB/tests/PackableStorage.py Fri Mar 12 13:08:13 2004
@@ -175,7 +175,10 @@
root[i].value = MinPO(i)
get_transaction().commit()
- threads = [ClientThread(db, choices) for i in range(4)]
+ NUM_LOOP_TRIP = 50
+ timer = ElapsedTimer(time.time())
+ threads = [ClientThread(db, choices, NUM_LOOP_TRIP, timer, i)
+ for i in range(4)]
for t in threads:
t.start()
@@ -190,24 +193,44 @@
if True in liveness:
# They should have finished by now.
print 'Liveness:', liveness
- # Display how far each thread got, one column per thread.
- i = 0
- fmt = "(%2s %10s)"
- while True:
- found_one = False
- columns = []
- for t in threads:
- if i < len(t.outcomes):
- found_one = True
- result = tuple(t.outcomes[i])
- else:
- result = ('--', '--')
- columns.append(fmt % result)
- if found_one:
- print ' '.join(columns)
- i += 1
- else:
- break
+ # Combine the outcomes, and sort by start time.
+ outcomes = []
+ for t in threads:
+ outcomes.extend(t.outcomes)
+ # each outcome list has as many of these as a loop trip got thru:
+ # thread_id
+ # elapsed millis at loop top
+ # elapsed millis at attempt to assign to self.root[index]
+ # index into self.root getting replaced
+ # elapsed millis when outcome known
+ # 'OK' or 'Conflict'
+ # True if we got beyond this line, False if it raised an
+ # exception (one possible Conflict cause):
+ # self.root[index].value = MinPO(j)
+ def cmp_by_time(a, b):
+ return cmp((a[1], a[0]), (b[1], b[0]))
+ outcomes.sort(cmp_by_time)
+ counts = [0] * 4
+ for outcome in outcomes:
+ n = len(outcome)
+ assert n >= 2
+ tid = outcome[0]
+ print 'tid:%d top:%5d' % (tid, outcome[1]),
+ if n > 2:
+ print 'commit:%5d' % outcome[2],
+ if n > 3:
+ print 'index:%2d' % outcome[3],
+ if n > 4:
+ print 'known:%5d' % outcome[4],
+ if n > 5:
+ print '%8s' % outcome[5],
+ if n > 6:
+ print 'assigned:%5s' % outcome[6],
+ counts[tid] += 1
+ if counts[tid] == NUM_LOOP_TRIP:
+ print 'thread %d done' % tid,
+ print
+
self.fail('a thread is still alive')
# Iterate over the storage to make sure it's sane, but not every
@@ -575,22 +598,49 @@
# random write activity while the main thread is packing it.
class ClientThread(TestThread):
- def __init__(self, db, choices):
+ def __init__(self, db, choices, loop_trip, timer, thread_id):
TestThread.__init__(self)
self.root = db.open().root()
self.choices = choices
- # list of pairs, (root index written to, 'OK' or 'Conflict')
+ self.loop_trip = loop_trip
+ self.millis = timer.elapsed_millis
+ self.thread_id = thread_id
+ # list of lists; each list has as many of these as a loop trip
+ # got thru:
+ # thread_id
+ # elapsed millis at loop top
+ # elapsed millis at attempt
+ # index into self.root getting replaced
+ # elapsed millis when outcome known
+ # 'OK' or 'Conflict'
+ # True if we got beyond this line, False if it raised an exception:
+ # self.root[index].value = MinPO(j)
self.outcomes = []
def runtest(self):
from random import choice
- for j in range(50):
+ for j in range(self.loop_trip):
+ assign_worked = False
+ alist = [self.thread_id, self.millis()]
+ self.outcomes.append(alist)
try:
index = choice(self.choices)
+ alist.extend([self.millis(), index])
self.root[index].value = MinPO(j)
+ assign_worked = True
get_transaction().commit()
- self.outcomes.append((index, 'OK'))
+ alist.append(self.millis())
+ alist.append('OK')
except ConflictError:
+ alist.append(self.millis())
+ alist.append('Conflict')
get_transaction().abort()
- self.outcomes.append((index, 'Conflict'))
+ alist.append(assign_worked)
+
+class ElapsedTimer:
+ def __init__(self, start_time):
+ self.start_time = start_time
+
+ def elapsed_millis(self):
+ return int((time.time() - self.start_time) * 1000)
More information about the Zope3-Checkins
mailing list