def test_wb_connect_after_timeout(self): """ Test an odd error scenario. If the zookeeper client succeeds in connecting after a timeout, the connection should be closed, as the connect deferred has already fired. """ mock_client = self.mocker.patch(self.client) mock_client.close() def close_state(): # Ensure the client state variable is correct after the close call. self.client.connected = False self.mocker.call(close_state) self.mocker.replay() task = DelayedCall(1, lambda: 1, None, None, None, None) task.called = True d = Deferred() d.errback(ConnectionTimeoutException()) self.client._cb_connected( task, d, None, zookeeper.CONNECTED_STATE, "/") self.failUnlessFailure(d, ConnectionTimeoutException) return d
def _cb_timeout(response: Response, request: Request, timeout: float, timeout_cl: DelayedCall) -> Response: if timeout_cl.active(): timeout_cl.cancel() return response url = urldefrag(request.url)[0] raise TimeoutError( f"Getting {url} took longer than {timeout} seconds.")
def test_repr(self): """ The string representation of a L{DelayedCall} instance, as returned by {repr}, is identical to that returned by L{str}. """ dc = DelayedCall(13, nothing, (6, ), {"A": 9}, None, None, lambda: 1.6) self.assertEqual(str(dc), repr(dc))
def _getDelayedCallAt(self, time): """ Get a L{DelayedCall} instance at a given C{time}. @param time: The absolute time at which the returned L{DelayedCall} will be scheduled. """ def noop(call): pass return DelayedCall(time, lambda: None, (), {}, noop, noop, None)
def test_wb_reconnect_after_timeout_and_close(self): """ Another odd error scenario, if a client instance has has connect and closed methods invoked in succession multiple times, and a previous callback connect timeouts, the callback of a previous connect can be invoked by a subsequent connect, with a CONNECTING_STATE. Verify this does not attempt to invoke the connect deferred again. """ d = Deferred() d.callback(True) task = DelayedCall(1, lambda: 1, None, None, None, None) task.called = True self.assertEqual( self.client._cb_connected( task, d, None, zookeeper.CONNECTING_STATE, ""), None)
def test_str(self): """ The string representation of a L{DelayedCall} instance, as returned by L{str}, includes the unsigned id of the instance, as well as its state, the function to be called, and the function arguments. """ dc = DelayedCall(12, nothing, (3, ), {"A": 5}, None, None, lambda: 1.5) expected = ("<DelayedCall 0x{:x} [10.5s] called=0 cancelled=0 " "nothing(3, A=5)>".format(id(dc))) self.assertEqual(str(dc), expected)
def test_str(self): """ The string representation of a L{DelayedCall} instance, as returned by L{str}, includes the unsigned id of the instance, as well as its state, the function to be called, and the function arguments. """ dc = DelayedCall(12, nothing, (3, ), {"A": 5}, None, None, lambda: 1.5) expectedRegexp = ( "<DelayedCall 0x{:x} \\[10.5s\\] called=0 cancelled=0 " "nothing\\(3, A=5\\)\n\n" "traceback at creation:".format(id(dc))) self.assertRegex(str(dc), expectedRegexp)
def test_cleanPendingCancelsCalls(self): """ During pending-call cleanup, the janitor cancels pending timed calls. """ def func(): return "Lulz" cancelled = [] delayedCall = DelayedCall(300, func, (), {}, cancelled.append, lambda x: None) reactor = StubReactor([delayedCall]) jan = _Janitor(None, None, reactor=reactor) jan._cleanPending() self.assertEquals(cancelled, [delayedCall])
def _on_timeout_error(self, failure, request, timeout: float = None, timer: DelayedCall = None): failure.trap(defer.CancelledError) msg = {} if timer is not None: msg['remaining'] = timer.time - timer.seconds() if timer is not None and timer.cancelled: ex = CancelledError(msg) return self._write_error(request, 520, ex) msg['timeout'] = timeout ex = GlobalTimeoutError(msg) return self._write_error(request, 504, ex)
def test_cleanPendingReturnsDelayedCallStrings(self): """ The Janitor produces string representations of delayed calls from the delayed call cleanup method. It gets the string representations *before* cancelling the calls; this is important because cancelling the call removes critical debugging information from the string representation. """ delayedCall = DelayedCall( 300, lambda: None, (), {}, lambda x: None, lambda x: None, seconds=lambda: 0 ) delayedCallString = str(delayedCall) reactor = StubReactor([delayedCall]) jan = _Janitor(None, None, reactor=reactor) strings = jan._cleanPending() self.assertEqual(strings, [delayedCallString])
def test_postClassCleanupWithPendingCallErrors(self): """ The post-class cleanup method call C{addError} on the result with a L{DirtyReactorAggregateError} Failure if there are pending calls. """ delayedCall = DelayedCall( 300, lambda: None, (), {}, lambda x: None, lambda x: None, seconds=lambda: 0 ) delayedCallString = str(delayedCall) reactor = StubReactor([delayedCall], []) test = object() reporter = StubErrorReporter() jan = _Janitor(test, reporter, reactor=reactor) jan.postClassCleanup() self.assertEqual(len(reporter.errors), 1) self.assertEqual(reporter.errors[0][1].value.delayedCalls, [delayedCallString])
def callLater(self, seconds, f, *args, **kwargs): def run(): dc.called = True self._delayedCalls.remove(dc) f(*args, **kwargs) handle = self._asyncioEventloop.call_later(seconds, run) dchandle = _DCHandle(handle) def cancel(dc): self._delayedCalls.remove(dc) dchandle.cancel() def reset(dc): dchandle.handle = self._asyncioEventloop.call_at(dc.time, run) dc = DelayedCall(self.seconds() + seconds, run, (), {}, cancel, reset, seconds=self.seconds) self._delayedCalls.add(dc) return dc
def callLater(self, delay: float, callable: Callable[..., object], *args: object, **kw: object) -> IDelayedCall: """ See L{twisted.internet.interfaces.IReactorTime.callLater}. """ dc = DelayedCall( self.seconds() + delay, callable, args, kw, self.calls.remove, lambda c: None, self.seconds, ) self.calls.append(dc) self._sortCalls() return dc
def test_str(self): """ The string representation of a L{DelayedCall} instance, as returned by C{str}, includes the unsigned id of the instance, as well as its state, the function to be called, and the function arguments. """ def nothing(): pass dc = DelayedCall(12, nothing, (3, ), {"A": 5}, None, None, lambda: 1.5) ids = {dc: 200} def fakeID(obj): try: return ids[obj] except (TypeError, KeyError): return id(obj) self.addCleanup(setIDFunction, setIDFunction(fakeID)) self.assertEqual( str(dc), "<DelayedCall 0xc8 [10.5s] called=0 cancelled=0 nothing(3, A=5)>")
def callLater(self, seconds, f, *args, **kwargs): def run(*a, **k): dc.called = True self._delayedCalls.remove(dc) result = f(*a, **k) return result handle = self.spawn_later(seconds, run, *args, **kwargs) dchandle = _DCHandle(handle) def cancel(dc): self._delayedCalls.remove(dc) dchandle.cancel() def reset(dc): dchandle.handle = self.spawn_later(dc.time - self.seconds(), run) dc = DelayedCall(self.seconds() + seconds, run, (), {}, cancel, reset, seconds=self.seconds) self._delayedCalls.add(dc) return dc
def cancel(self): if self.cancelled or self.called: self.cancelled = True return return TwistedDelayedCall.cancel(self)