From 294e3fb6826b29f90d03d4bcf6a59c32846f8677 Mon Sep 17 00:00:00 2001 From: Brian Warner <warner@allmydata.com> Date: Tue, 28 Oct 2008 21:15:48 -0700 Subject: [PATCH] util: move PollMixin to a separate file (pollmixin.py), so testutil can be moved into test/ --- src/allmydata/client.py | 4 +-- src/allmydata/test/check_memory.py | 4 +-- src/allmydata/test/common.py | 4 +-- src/allmydata/test/test_introducer.py | 6 ++--- src/allmydata/test/test_keygen.py | 4 +-- src/allmydata/test/test_runner.py | 4 +-- src/allmydata/test/test_stats.py | 4 +-- src/allmydata/test/test_util.py | 6 ++--- src/allmydata/util/pollmixin.py | 36 +++++++++++++++++++++++++++ src/allmydata/util/testutil.py | 34 +------------------------ 10 files changed, 55 insertions(+), 51 deletions(-) create mode 100644 src/allmydata/util/pollmixin.py diff --git a/src/allmydata/client.py b/src/allmydata/client.py index 797d1745..463a5cbd 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -18,7 +18,7 @@ from allmydata.immutable.filenode import FileNode, LiteralFileNode from allmydata.offloaded import Helper from allmydata.control import ControlServer from allmydata.introducer.client import IntroducerClient -from allmydata.util import hashutil, base32, testutil, fileutil +from allmydata.util import hashutil, base32, pollmixin, fileutil from allmydata.uri import LiteralFileURI from allmydata.dirnode import NewDirectoryNode from allmydata.mutable.node import MutableFileNode, MutableWatcher @@ -38,7 +38,7 @@ class StubClient(Referenceable): def _make_secret(): return base32.b2a(os.urandom(hashutil.CRYPTO_VAL_SIZE)) + "\n" -class Client(node.Node, testutil.PollMixin): +class Client(node.Node, pollmixin.PollMixin): implements(IStatsProducer) PORTNUMFILE = "client.port" diff --git a/src/allmydata/test/check_memory.py b/src/allmydata/test/check_memory.py index ddfa4337..a106e6b1 100644 --- a/src/allmydata/test/check_memory.py +++ b/src/allmydata/test/check_memory.py @@ -8,7 +8,7 @@ from twisted.web import client as tw_client from allmydata import client, introducer from allmydata.immutable import upload from allmydata.scripts import create_node -from allmydata.util import testutil, fileutil +from allmydata.util import fileutil, pollmixin import foolscap from foolscap import eventual from twisted.python import log @@ -57,7 +57,7 @@ def discardPage(url, stall=False, *args, **kwargs): reactor.connectTCP(host, port, factory) return factory.deferred -class SystemFramework(testutil.PollMixin): +class SystemFramework(pollmixin.PollMixin): numnodes = 5 def __init__(self, basedir, mode): diff --git a/src/allmydata/test/common.py b/src/allmydata/test/common.py index d09ebff2..3fd6b6a3 100644 --- a/src/allmydata/test/common.py +++ b/src/allmydata/test/common.py @@ -16,7 +16,7 @@ from allmydata.checker_results import CheckerResults, CheckAndRepairResults, \ DeepCheckResults, DeepCheckAndRepairResults from allmydata.mutable.common import CorruptShareError from allmydata.storage import storage_index_to_dir -from allmydata.util import log, testutil, fileutil +from allmydata.util import log, testutil, fileutil, pollmixin from allmydata.stats import PickleStatsGatherer from allmydata.key_generator import KeyGeneratorService @@ -291,7 +291,7 @@ class LoggingServiceParent(service.MultiService): return log.msg(*args, **kwargs) -class SystemTestMixin(testutil.PollMixin, testutil.StallMixin): +class SystemTestMixin(pollmixin.PollMixin, testutil.StallMixin): def setUp(self): self.sparent = service.MultiService() diff --git a/src/allmydata/test/test_introducer.py b/src/allmydata/test/test_introducer.py index 08d52915..96a587a7 100644 --- a/src/allmydata/test/test_introducer.py +++ b/src/allmydata/test/test_introducer.py @@ -14,7 +14,7 @@ from allmydata.introducer.server import IntroducerService # test compatibility with old introducer .tac files from allmydata.introducer import IntroducerNode from allmydata.introducer import old -from allmydata.util import testutil, idlib +from allmydata.util import testutil, idlib, pollmixin class FakeNode(Referenceable): pass @@ -46,7 +46,7 @@ class ServiceMixin: d.addCallback(flushEventualQueue) return d -class Introducer(ServiceMixin, unittest.TestCase, testutil.PollMixin): +class Introducer(ServiceMixin, unittest.TestCase, pollmixin.PollMixin): def test_create(self): ic = IntroducerClient(None, "introducer.furl", "my_nickname", @@ -75,7 +75,7 @@ class Introducer(ServiceMixin, unittest.TestCase, testutil.PollMixin): self.failUnlessEqual(len(i.get_announcements()), 2) self.failUnlessEqual(len(i.get_subscribers()), 0) -class SystemTestMixin(ServiceMixin, testutil.PollMixin): +class SystemTestMixin(ServiceMixin, pollmixin.PollMixin): def setUp(self): ServiceMixin.setUp(self) diff --git a/src/allmydata/test/test_keygen.py b/src/allmydata/test/test_keygen.py index 27ed94db..11b8f7de 100644 --- a/src/allmydata/test/test_keygen.py +++ b/src/allmydata/test/test_keygen.py @@ -6,7 +6,7 @@ from twisted.application import service from foolscap import Tub, eventual from allmydata import key_generator -from allmydata.util import testutil +from allmydata.util import pollmixin from pycryptopp.publickey import rsa def flush_but_dont_ignore(res): @@ -16,7 +16,7 @@ def flush_but_dont_ignore(res): d.addCallback(_done) return d -class KeyGenService(unittest.TestCase, testutil.PollMixin): +class KeyGenService(unittest.TestCase, pollmixin.PollMixin): def setUp(self): self.parent = service.MultiService() self.parent.startService() diff --git a/src/allmydata/test/test_runner.py b/src/allmydata/test/test_runner.py index c34d2e25..426163c0 100644 --- a/src/allmydata/test/test_runner.py +++ b/src/allmydata/test/test_runner.py @@ -6,7 +6,7 @@ from twisted.python import usage, runtime from twisted.internet import defer import os.path, re from allmydata.scripts import runner -from allmydata.util import fileutil, testutil +from allmydata.util import fileutil, pollmixin class CreateNode(unittest.TestCase): def workdir(self, name): @@ -93,7 +93,7 @@ class CreateNode(unittest.TestCase): [], run_by_human=False) -class RunNode(unittest.TestCase, testutil.PollMixin): +class RunNode(unittest.TestCase, pollmixin.PollMixin): def workdir(self, name): basedir = os.path.join("test_runner", "RunNode", name) fileutil.make_dirs(basedir) diff --git a/src/allmydata/test/test_stats.py b/src/allmydata/test/test_stats.py index 26286693..4cf4d8a5 100644 --- a/src/allmydata/test/test_stats.py +++ b/src/allmydata/test/test_stats.py @@ -2,13 +2,13 @@ from twisted.trial import unittest from twisted.application import service from allmydata.stats import CPUUsageMonitor -from allmydata.util import testutil +from allmydata.util import testutil, pollmixin class FasterMonitor(CPUUsageMonitor): POLL_INTERVAL = 0.1 -class CPUUsage(unittest.TestCase, testutil.PollMixin, testutil.StallMixin): +class CPUUsage(unittest.TestCase, pollmixin.PollMixin, testutil.StallMixin): def setUp(self): self.s = service.MultiService() self.s.startService() diff --git a/src/allmydata/test/test_util.py b/src/allmydata/test/test_util.py index babaef78..5414d9b5 100644 --- a/src/allmydata/test/test_util.py +++ b/src/allmydata/test/test_util.py @@ -8,7 +8,7 @@ from twisted.python import failure from allmydata.util import base32, idlib, humanreadable, mathutil, hashutil from allmydata.util import assertutil, fileutil, testutil, deferredutil -from allmydata.util import limiter, time_format +from allmydata.util import limiter, time_format, pollmixin class Base32(unittest.TestCase): def test_b2a_matches_Pythons(self): @@ -330,7 +330,7 @@ class FileUtil(unittest.TestCase): class PollMixinTests(unittest.TestCase): def setUp(self): - self.pm = testutil.PollMixin() + self.pm = pollmixin.PollMixin() def test_PollMixin_True(self): d = self.pm.poll(check_f=lambda : True, @@ -350,7 +350,7 @@ class PollMixinTests(unittest.TestCase): def _suc(res): self.fail("poll should have failed, not returned %s" % (res,)) def _err(f): - f.trap(testutil.TimeoutError) + f.trap(pollmixin.TimeoutError) return None # success d.addCallbacks(_suc, _err) return d diff --git a/src/allmydata/util/pollmixin.py b/src/allmydata/util/pollmixin.py new file mode 100644 index 00000000..4f7ab828 --- /dev/null +++ b/src/allmydata/util/pollmixin.py @@ -0,0 +1,36 @@ + +import time +from twisted.internet import task + +class TimeoutError(Exception): + pass + +class PollComplete(Exception): + pass + +class PollMixin: + + def poll(self, check_f, pollinterval=0.01, timeout=100): + # Return a Deferred, then call check_f periodically until it returns + # True, at which point the Deferred will fire.. If check_f raises an + # exception, the Deferred will errback. If the check_f does not + # indicate success within timeout= seconds, the Deferred will + # errback. If timeout=None, no timeout will be enforced, and the loop + # will poll forever (or really until Trial times out). + cutoff = None + if timeout is not None: + cutoff = time.time() + timeout + lc = task.LoopingCall(self._poll, check_f, cutoff) + d = lc.start(pollinterval) + def _convert_done(f): + f.trap(PollComplete) + return None + d.addErrback(_convert_done) + return d + + def _poll(self, check_f, cutoff): + if cutoff is not None and time.time() > cutoff: + raise TimeoutError("PollMixin never saw %s return True" % check_f) + if check_f(): + raise PollComplete() + diff --git a/src/allmydata/util/testutil.py b/src/allmydata/util/testutil.py index 84911306..27d6b434 100644 --- a/src/allmydata/util/testutil.py +++ b/src/allmydata/util/testutil.py @@ -1,7 +1,7 @@ import os, signal, time from random import randrange -from twisted.internet import reactor, defer, task +from twisted.internet import reactor, defer from twisted.python import failure def insecurerandstr(n): @@ -43,38 +43,6 @@ class SignalMixin: if self.sigchldHandler: signal.signal(signal.SIGCHLD, self.sigchldHandler) -class TimeoutError(Exception): - pass - -class PollComplete(Exception): - pass - -class PollMixin: - - def poll(self, check_f, pollinterval=0.01, timeout=100): - # Return a Deferred, then call check_f periodically until it returns - # True, at which point the Deferred will fire.. If check_f raises an - # exception, the Deferred will errback. If the check_f does not - # indicate success within timeout= seconds, the Deferred will - # errback. If timeout=None, no timeout will be enforced, and the loop - # will poll forever (or really until Trial times out). - cutoff = None - if timeout is not None: - cutoff = time.time() + timeout - lc = task.LoopingCall(self._poll, check_f, cutoff) - d = lc.start(pollinterval) - def _convert_done(f): - f.trap(PollComplete) - return None - d.addErrback(_convert_done) - return d - - def _poll(self, check_f, cutoff): - if cutoff is not None and time.time() > cutoff: - raise TimeoutError("PollMixin never saw %s return True" % check_f) - if check_f(): - raise PollComplete() - class StallMixin: def stall(self, res=None, delay=1): d = defer.Deferred() -- 2.45.2