From a0867aa01ca782d5f8975cd7fde42dc3f5bfbba5 Mon Sep 17 00:00:00 2001 From: dieter Date: Mon, 17 Apr 2023 08:41:54 +0200 Subject: [PATCH] add `TestGroup` tests; minor cleanup --- src/ZODB/tests/racetest.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/ZODB/tests/racetest.py b/src/ZODB/tests/racetest.py index 24a67a51f..e515446b7 100644 --- a/src/ZODB/tests/racetest.py +++ b/src/ZODB/tests/racetest.py @@ -200,7 +200,7 @@ def xrun(tg, tx, f, N): for i in range(N): # print('%s.%d' % (f.__name__, i)) f(tg) - if tg.failed.is_set(): + if tg.failed(): break # loop verify and modify concurrently. @@ -308,7 +308,7 @@ def t_(): for i in range(N): # print('T%s.%d' % (tx, i)) t_() - if tg.failed.is_set(): + if tg.failed(): break finally: db.close() @@ -392,7 +392,7 @@ def work1(db): db = self.dbopen() try: for i in range(4): - if tg.failed.is_set(): + if tg.failed(): break work1(db) finally: @@ -400,7 +400,7 @@ def work1(db): for i in range(N): # print('T%s.%d' % (tx, i)) - if tg.failed.is_set(): + if tg.failed(): break t_() @@ -490,12 +490,13 @@ class TestGroup(object): - .go() adds test thread to the group. - .wait() waits for all spawned threads to finish and reports all collected failures to containing testcase. - - a test should indicate failure by call to .fail() + - a test should indicate failure by call to .fail(), it + can check for a failure with .failed() """ def __init__(self, testcase): self.testcase = testcase - self.failed = threading.Event() + self.failed_event = threading.Event() self.fail_mu = threading.Lock() self.failv = [] # failures registerd by .fail self.threadv = [] # spawned threads @@ -505,7 +506,11 @@ def fail(self, msg): """fail adds failure to test result.""" with self.fail_mu: self.failv.append(msg) - self.failed.set() + self.failed_event.set() + + def failed(self): + """did the thest already fail.""" + return self.failed_event.is_set() def go(self, f, *argv, **kw): """go spawns f(self, #thread, *argv, **kw) in new test thread.""" @@ -517,11 +522,12 @@ def go(self, f, *argv, **kw): t.start() def _run(self, f, tx, argv, kw): + tname = self.threadv[tx].name try: f(self, tx, *argv, **kw) except Exception as e: self.fail("Unhandled exception %r in thread %s" - % (e, self.threadv[tx].name)) + % (e, tname)) raise finally: self.waitg.done() @@ -537,13 +543,14 @@ def wait(self, timeout): try: t.join(1) except AssertionError: - self.failed.set() + self.failed_event.set() failed_to_finish.append(t.name) if failed_to_finish: self.fail("threads did not finish: %s" % failed_to_finish) + del self.threadv # avoid cyclic garbage - if self.failed.is_set(): - self.testcase.fail('\n\n'.join([_ for _ in self.failv if _])) + if self.failed(): + self.testcase.fail('\n\n'.join(self.failv)) class Daemon(threading.Thread): @@ -616,7 +623,7 @@ def add(self, delta): if self.n < 0: raise AssertionError("#workers is negative") if self.n == 0: - self.condition.notify() + self.condition.notify_all() def done(self): self.add(-1)