diff --git a/tests/utils.py b/tests/utils.py
index b32d5ef356..37b759febc 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -21,7 +21,7 @@ from synapse.api.events.room import (
RoomMemberEvent, MessageEvent
)
-from twisted.internet import defer
+from twisted.internet import defer, reactor
from collections import namedtuple
from mock import patch, Mock
@@ -248,8 +248,11 @@ class DeferredMockCallable(object):
def __init__(self):
self.expectations = []
+ self.calls = []
def __call__(self, *args, **kwargs):
+ self.calls.append((args, kwargs))
+
if not self.expectations:
raise ValueError("%r has no pending calls to handle call(%s)" % (
self, _format_call(args, kwargs))
@@ -260,15 +263,52 @@ class DeferredMockCallable(object):
d.callback(None)
return result
- raise AssertionError("Was not expecting call(%s)" %
+ failure = AssertionError("Was not expecting call(%s)" %
_format_call(args, kwargs)
)
+ for _, _, d in self.expectations:
+ try:
+ d.errback(failure)
+ except:
+ pass
+
+ raise failure
+
def expect_call_and_return(self, call, result):
self.expectations.append((call, result, defer.Deferred()))
@defer.inlineCallbacks
- def await_calls(self):
- while self.expectations:
- (_, _, d) = self.expectations.pop(0)
- yield d
+ def await_calls(self, timeout=1000):
+ deferred = defer.DeferredList(
+ [d for _, _, d in self.expectations],
+ fireOnOneErrback=True
+ )
+
+ timer = reactor.callLater(
+ timeout/1000,
+ deferred.errback,
+ AssertionError(
+ "%d pending calls left: %s"% (
+ len([e for e in self.expectations if not e[2].called]),
+ [e for e in self.expectations if not e[2].called]
+ )
+ )
+ )
+
+ yield deferred
+
+ timer.cancel()
+
+ self.calls = []
+
+ def assert_had_no_calls(self):
+ if self.calls:
+ calls = self.calls
+ self.calls = []
+
+ raise AssertionError("Expected not to received any calls, got:\n" +
+ "\n".join([
+ "call(%s)" % _format_call(c[0], c[1]) for c in calls
+ ])
+ )
|