mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-03 03:36:44 +00:00
util: move PollMixin to a separate file (pollmixin.py), so testutil can be moved into test/
This commit is contained in:
parent
3dd9b79e3f
commit
294e3fb682
@ -18,7 +18,7 @@ from allmydata.immutable.filenode import FileNode, LiteralFileNode
|
|||||||
from allmydata.offloaded import Helper
|
from allmydata.offloaded import Helper
|
||||||
from allmydata.control import ControlServer
|
from allmydata.control import ControlServer
|
||||||
from allmydata.introducer.client import IntroducerClient
|
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.uri import LiteralFileURI
|
||||||
from allmydata.dirnode import NewDirectoryNode
|
from allmydata.dirnode import NewDirectoryNode
|
||||||
from allmydata.mutable.node import MutableFileNode, MutableWatcher
|
from allmydata.mutable.node import MutableFileNode, MutableWatcher
|
||||||
@ -38,7 +38,7 @@ class StubClient(Referenceable):
|
|||||||
def _make_secret():
|
def _make_secret():
|
||||||
return base32.b2a(os.urandom(hashutil.CRYPTO_VAL_SIZE)) + "\n"
|
return base32.b2a(os.urandom(hashutil.CRYPTO_VAL_SIZE)) + "\n"
|
||||||
|
|
||||||
class Client(node.Node, testutil.PollMixin):
|
class Client(node.Node, pollmixin.PollMixin):
|
||||||
implements(IStatsProducer)
|
implements(IStatsProducer)
|
||||||
|
|
||||||
PORTNUMFILE = "client.port"
|
PORTNUMFILE = "client.port"
|
||||||
|
@ -8,7 +8,7 @@ from twisted.web import client as tw_client
|
|||||||
from allmydata import client, introducer
|
from allmydata import client, introducer
|
||||||
from allmydata.immutable import upload
|
from allmydata.immutable import upload
|
||||||
from allmydata.scripts import create_node
|
from allmydata.scripts import create_node
|
||||||
from allmydata.util import testutil, fileutil
|
from allmydata.util import fileutil, pollmixin
|
||||||
import foolscap
|
import foolscap
|
||||||
from foolscap import eventual
|
from foolscap import eventual
|
||||||
from twisted.python import log
|
from twisted.python import log
|
||||||
@ -57,7 +57,7 @@ def discardPage(url, stall=False, *args, **kwargs):
|
|||||||
reactor.connectTCP(host, port, factory)
|
reactor.connectTCP(host, port, factory)
|
||||||
return factory.deferred
|
return factory.deferred
|
||||||
|
|
||||||
class SystemFramework(testutil.PollMixin):
|
class SystemFramework(pollmixin.PollMixin):
|
||||||
numnodes = 5
|
numnodes = 5
|
||||||
|
|
||||||
def __init__(self, basedir, mode):
|
def __init__(self, basedir, mode):
|
||||||
|
@ -16,7 +16,7 @@ from allmydata.checker_results import CheckerResults, CheckAndRepairResults, \
|
|||||||
DeepCheckResults, DeepCheckAndRepairResults
|
DeepCheckResults, DeepCheckAndRepairResults
|
||||||
from allmydata.mutable.common import CorruptShareError
|
from allmydata.mutable.common import CorruptShareError
|
||||||
from allmydata.storage import storage_index_to_dir
|
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.stats import PickleStatsGatherer
|
||||||
from allmydata.key_generator import KeyGeneratorService
|
from allmydata.key_generator import KeyGeneratorService
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ class LoggingServiceParent(service.MultiService):
|
|||||||
return log.msg(*args, **kwargs)
|
return log.msg(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class SystemTestMixin(testutil.PollMixin, testutil.StallMixin):
|
class SystemTestMixin(pollmixin.PollMixin, testutil.StallMixin):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.sparent = service.MultiService()
|
self.sparent = service.MultiService()
|
||||||
|
@ -14,7 +14,7 @@ from allmydata.introducer.server import IntroducerService
|
|||||||
# test compatibility with old introducer .tac files
|
# test compatibility with old introducer .tac files
|
||||||
from allmydata.introducer import IntroducerNode
|
from allmydata.introducer import IntroducerNode
|
||||||
from allmydata.introducer import old
|
from allmydata.introducer import old
|
||||||
from allmydata.util import testutil, idlib
|
from allmydata.util import testutil, idlib, pollmixin
|
||||||
|
|
||||||
class FakeNode(Referenceable):
|
class FakeNode(Referenceable):
|
||||||
pass
|
pass
|
||||||
@ -46,7 +46,7 @@ class ServiceMixin:
|
|||||||
d.addCallback(flushEventualQueue)
|
d.addCallback(flushEventualQueue)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
class Introducer(ServiceMixin, unittest.TestCase, testutil.PollMixin):
|
class Introducer(ServiceMixin, unittest.TestCase, pollmixin.PollMixin):
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
ic = IntroducerClient(None, "introducer.furl", "my_nickname",
|
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_announcements()), 2)
|
||||||
self.failUnlessEqual(len(i.get_subscribers()), 0)
|
self.failUnlessEqual(len(i.get_subscribers()), 0)
|
||||||
|
|
||||||
class SystemTestMixin(ServiceMixin, testutil.PollMixin):
|
class SystemTestMixin(ServiceMixin, pollmixin.PollMixin):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
ServiceMixin.setUp(self)
|
ServiceMixin.setUp(self)
|
||||||
|
@ -6,7 +6,7 @@ from twisted.application import service
|
|||||||
from foolscap import Tub, eventual
|
from foolscap import Tub, eventual
|
||||||
|
|
||||||
from allmydata import key_generator
|
from allmydata import key_generator
|
||||||
from allmydata.util import testutil
|
from allmydata.util import pollmixin
|
||||||
from pycryptopp.publickey import rsa
|
from pycryptopp.publickey import rsa
|
||||||
|
|
||||||
def flush_but_dont_ignore(res):
|
def flush_but_dont_ignore(res):
|
||||||
@ -16,7 +16,7 @@ def flush_but_dont_ignore(res):
|
|||||||
d.addCallback(_done)
|
d.addCallback(_done)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
class KeyGenService(unittest.TestCase, testutil.PollMixin):
|
class KeyGenService(unittest.TestCase, pollmixin.PollMixin):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.parent = service.MultiService()
|
self.parent = service.MultiService()
|
||||||
self.parent.startService()
|
self.parent.startService()
|
||||||
|
@ -6,7 +6,7 @@ from twisted.python import usage, runtime
|
|||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
import os.path, re
|
import os.path, re
|
||||||
from allmydata.scripts import runner
|
from allmydata.scripts import runner
|
||||||
from allmydata.util import fileutil, testutil
|
from allmydata.util import fileutil, pollmixin
|
||||||
|
|
||||||
class CreateNode(unittest.TestCase):
|
class CreateNode(unittest.TestCase):
|
||||||
def workdir(self, name):
|
def workdir(self, name):
|
||||||
@ -93,7 +93,7 @@ class CreateNode(unittest.TestCase):
|
|||||||
[],
|
[],
|
||||||
run_by_human=False)
|
run_by_human=False)
|
||||||
|
|
||||||
class RunNode(unittest.TestCase, testutil.PollMixin):
|
class RunNode(unittest.TestCase, pollmixin.PollMixin):
|
||||||
def workdir(self, name):
|
def workdir(self, name):
|
||||||
basedir = os.path.join("test_runner", "RunNode", name)
|
basedir = os.path.join("test_runner", "RunNode", name)
|
||||||
fileutil.make_dirs(basedir)
|
fileutil.make_dirs(basedir)
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
from twisted.application import service
|
from twisted.application import service
|
||||||
from allmydata.stats import CPUUsageMonitor
|
from allmydata.stats import CPUUsageMonitor
|
||||||
from allmydata.util import testutil
|
from allmydata.util import testutil, pollmixin
|
||||||
|
|
||||||
class FasterMonitor(CPUUsageMonitor):
|
class FasterMonitor(CPUUsageMonitor):
|
||||||
POLL_INTERVAL = 0.1
|
POLL_INTERVAL = 0.1
|
||||||
|
|
||||||
|
|
||||||
class CPUUsage(unittest.TestCase, testutil.PollMixin, testutil.StallMixin):
|
class CPUUsage(unittest.TestCase, pollmixin.PollMixin, testutil.StallMixin):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.s = service.MultiService()
|
self.s = service.MultiService()
|
||||||
self.s.startService()
|
self.s.startService()
|
||||||
|
@ -8,7 +8,7 @@ from twisted.python import failure
|
|||||||
|
|
||||||
from allmydata.util import base32, idlib, humanreadable, mathutil, hashutil
|
from allmydata.util import base32, idlib, humanreadable, mathutil, hashutil
|
||||||
from allmydata.util import assertutil, fileutil, testutil, deferredutil
|
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):
|
class Base32(unittest.TestCase):
|
||||||
def test_b2a_matches_Pythons(self):
|
def test_b2a_matches_Pythons(self):
|
||||||
@ -330,7 +330,7 @@ class FileUtil(unittest.TestCase):
|
|||||||
|
|
||||||
class PollMixinTests(unittest.TestCase):
|
class PollMixinTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.pm = testutil.PollMixin()
|
self.pm = pollmixin.PollMixin()
|
||||||
|
|
||||||
def test_PollMixin_True(self):
|
def test_PollMixin_True(self):
|
||||||
d = self.pm.poll(check_f=lambda : True,
|
d = self.pm.poll(check_f=lambda : True,
|
||||||
@ -350,7 +350,7 @@ class PollMixinTests(unittest.TestCase):
|
|||||||
def _suc(res):
|
def _suc(res):
|
||||||
self.fail("poll should have failed, not returned %s" % (res,))
|
self.fail("poll should have failed, not returned %s" % (res,))
|
||||||
def _err(f):
|
def _err(f):
|
||||||
f.trap(testutil.TimeoutError)
|
f.trap(pollmixin.TimeoutError)
|
||||||
return None # success
|
return None # success
|
||||||
d.addCallbacks(_suc, _err)
|
d.addCallbacks(_suc, _err)
|
||||||
return d
|
return d
|
||||||
|
36
src/allmydata/util/pollmixin.py
Normal file
36
src/allmydata/util/pollmixin.py
Normal file
@ -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()
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
import os, signal, time
|
import os, signal, time
|
||||||
from random import randrange
|
from random import randrange
|
||||||
|
|
||||||
from twisted.internet import reactor, defer, task
|
from twisted.internet import reactor, defer
|
||||||
from twisted.python import failure
|
from twisted.python import failure
|
||||||
|
|
||||||
def insecurerandstr(n):
|
def insecurerandstr(n):
|
||||||
@ -43,38 +43,6 @@ class SignalMixin:
|
|||||||
if self.sigchldHandler:
|
if self.sigchldHandler:
|
||||||
signal.signal(signal.SIGCHLD, 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:
|
class StallMixin:
|
||||||
def stall(self, res=None, delay=1):
|
def stall(self, res=None, delay=1):
|
||||||
d = defer.Deferred()
|
d = defer.Deferred()
|
||||||
|
Loading…
Reference in New Issue
Block a user