mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 05:28:04 +00:00
Change OphandleTable to use a deterministic clock, so we can test it
To test the changes for #577, we need a deterministic way to simulate the passage of long periods of time. twisted.internet.task.Clock seems, from my Googling, to be the way to go for this functionality. I changed a few things so that OphandleTable would use twisted.internet.task.Clock when testing: * WebishServer.__init___ now takes an optional 'clock' parameter, * which it passes to the root.Root instance it creates. * root.Root.__init__ now takes an optional 'clock' parameter, which it passes to the OphandleTable.__init__ method. * OphandleTable.__init__ now takes an optional 'clock' parameter. If it is provided, and it isn't None, its callLater method will be used to schedule ophandle expirations (as opposed to using reactor.callLater, which is what OphandleTable does normally). * The WebMixin object in test_web.py now sets a self.clock parameter, which is a twisted.internet.task.Clock that it feeds to the WebishServer it creates. Tests using the WebMixin can control the passage of time in OphandleTable by accessing self.clock.
This commit is contained in:
parent
bcdc78bd44
commit
81ad52d6eb
@ -4,6 +4,7 @@ from StringIO import StringIO
|
||||
from twisted.application import service
|
||||
from twisted.trial import unittest
|
||||
from twisted.internet import defer, reactor
|
||||
from twisted.internet.task import Clock
|
||||
from twisted.web import client, error, http
|
||||
from twisted.python import failure, log
|
||||
from nevow import rend
|
||||
@ -119,7 +120,9 @@ class WebMixin(object):
|
||||
self.s = FakeClient()
|
||||
self.s.startService()
|
||||
self.staticdir = self.mktemp()
|
||||
self.ws = webish.WebishServer(self.s, "0", staticdir=self.staticdir)
|
||||
self.clock = Clock()
|
||||
self.ws = webish.WebishServer(self.s, "0", staticdir=self.staticdir,
|
||||
clock=self.clock)
|
||||
self.ws.setServiceParent(self.s)
|
||||
self.webish_port = port = self.ws.listener._port.getHost().port
|
||||
self.webish_url = "http://localhost:%d" % port
|
||||
@ -2873,7 +2876,8 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, unittest.TestCase):
|
||||
self.failUnless("finished" in data, res)
|
||||
d.addCallback(_check1)
|
||||
# the retain-for=0 will cause the handle to be expired very soon
|
||||
d.addCallback(self.stall, 2.0)
|
||||
d.addCallback(lambda ign:
|
||||
self.clock.advance(2.0))
|
||||
d.addCallback(lambda ignored:
|
||||
self.shouldHTTPError("test_ophandle_retainfor",
|
||||
404, "404 Not Found",
|
||||
|
@ -24,10 +24,15 @@ class OphandleTable(rend.Page, service.Service):
|
||||
UNCOLLECTED_HANDLE_LIFETIME = 4*DAY
|
||||
COLLECTED_HANDLE_LIFETIME = 1*DAY
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, clock=None):
|
||||
# both of these are indexed by ophandle
|
||||
self.handles = {} # tuple of (monitor, renderer, when_added)
|
||||
self.timers = {}
|
||||
# The tests will provide a deterministic clock
|
||||
# (twisted.internet.task.Clock) that they can control so that
|
||||
# they can test ophandle expiration. If this is provided, I'll
|
||||
# use it schedule the expiration of ophandles.
|
||||
self.clock = clock
|
||||
|
||||
def stopService(self):
|
||||
for t in self.timers.values():
|
||||
@ -103,7 +108,10 @@ class OphandleTable(rend.Page, service.Service):
|
||||
def _set_timer(self, ophandle, when):
|
||||
if ophandle in self.timers and self.timers[ophandle].active():
|
||||
self.timers[ophandle].cancel()
|
||||
t = reactor.callLater(when, self._release_ophandle, ophandle)
|
||||
if self.clock:
|
||||
t = self.clock.callLater(when, self._release_ophandle, ophandle)
|
||||
else:
|
||||
t = reactor.callLater(when, self._release_ophandle, ophandle)
|
||||
self.timers[ophandle] = t
|
||||
|
||||
def _release_ophandle(self, ophandle):
|
||||
|
@ -145,10 +145,12 @@ class Root(rend.Page):
|
||||
addSlash = True
|
||||
docFactory = getxmlfile("welcome.xhtml")
|
||||
|
||||
def __init__(self, client):
|
||||
def __init__(self, client, clock=None):
|
||||
rend.Page.__init__(self, client)
|
||||
self.client = client
|
||||
self.child_operations = operations.OphandleTable()
|
||||
# If set, clock is a twisted.internet.task.Clock that the tests
|
||||
# use to test ophandle expiration.
|
||||
self.child_operations = operations.OphandleTable(clock)
|
||||
try:
|
||||
s = client.getServiceNamed("storage")
|
||||
except KeyError:
|
||||
|
@ -121,10 +121,15 @@ class MyRequest(appserver.NevowRequest):
|
||||
class WebishServer(service.MultiService):
|
||||
name = "webish"
|
||||
|
||||
def __init__(self, client, webport, nodeurl_path=None, staticdir=None):
|
||||
def __init__(self, client, webport, nodeurl_path=None, staticdir=None,
|
||||
clock=None):
|
||||
service.MultiService.__init__(self)
|
||||
# the 'data' argument to all render() methods default to the Client
|
||||
self.root = root.Root(client)
|
||||
# the 'clock' argument to root.Root is, if set, a
|
||||
# twisted.internet.task.Clock that is provided by the unit tests
|
||||
# so that they can test features that involve the passage of
|
||||
# time in a deterministic manner.
|
||||
self.root = root.Root(client, clock)
|
||||
self.buildServer(webport, nodeurl_path, staticdir)
|
||||
if self.root.child_operations:
|
||||
self.site.remember(self.root.child_operations, IOpHandleTable)
|
||||
|
Loading…
Reference in New Issue
Block a user