Compare commits

..

No commits in common. "66f75c5b74196c624af6a39d824c93b4a37d63c2" and "ed5172852ae79dec341a81feeb1b8b99bb1875d6" have entirely different histories.

7 changed files with 143 additions and 7 deletions

View File

@ -1 +0,0 @@
Remove some unnecessary stubbing from unit tests.

View File

@ -16,6 +16,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from mock import Mock
import jsonschema
from twisted.internet import defer
@ -26,7 +28,7 @@ from synapse.api.filtering import Filter
from synapse.events import make_event_from_dict
from tests import unittest
from tests.utils import setup_test_homeserver
from tests.utils import DeferredMockCallable, MockHttpResource, setup_test_homeserver
user_localpart = "test_user"
@ -40,9 +42,21 @@ def MockEvent(**kwargs):
class FilteringTestCase(unittest.TestCase):
@defer.inlineCallbacks
def setUp(self):
hs = setup_test_homeserver(self.addCleanup)
self.mock_federation_resource = MockHttpResource()
self.mock_http_client = Mock(spec=[])
self.mock_http_client.put_json = DeferredMockCallable()
hs = yield setup_test_homeserver(
self.addCleanup,
federation_http_client=self.mock_http_client,
keyring=Mock(),
)
self.filtering = hs.get_filtering()
self.datastore = hs.get_datastore()
def test_errors_on_invalid_filters(self):

View File

@ -42,6 +42,8 @@ class DirectoryTestCase(unittest.HomeserverTestCase):
self.mock_registry.register_query_handler = register_query_handler
hs = self.setup_test_homeserver(
federation_http_client=None,
resource_for_federation=Mock(),
federation_client=self.mock_federation,
federation_registry=self.mock_registry,
)

View File

@ -44,6 +44,8 @@ class ProfileTestCase(unittest.TestCase):
hs = yield setup_test_homeserver(
self.addCleanup,
federation_http_client=None,
resource_for_federation=Mock(),
federation_client=self.mock_federation,
federation_server=Mock(),
federation_registry=self.mock_registry,

View File

@ -14,6 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from mock import Mock
from canonicaljson import json
from twisted.internet import defer
@ -27,10 +30,12 @@ from tests.utils import create_room
class RedactionTestCase(unittest.HomeserverTestCase):
def default_config(self):
config = super().default_config()
def make_homeserver(self, reactor, clock):
config = self.default_config()
config["redaction_retention_period"] = "30d"
return config
return self.setup_test_homeserver(
resource_for_federation=Mock(), federation_http_client=None, config=config
)
def prepare(self, reactor, clock, hs):
self.store = hs.get_datastore()

View File

@ -14,6 +14,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from unittest.mock import Mock
from synapse.api.constants import Membership
from synapse.rest.admin import register_servlets_for_client_rest_resource
from synapse.rest.client.v1 import login, room
@ -32,6 +34,12 @@ class RoomMemberStoreTestCase(unittest.HomeserverTestCase):
room.register_servlets,
]
def make_homeserver(self, reactor, clock):
hs = self.setup_test_homeserver(
resource_for_federation=Mock(), federation_http_client=None
)
return hs
def prepare(self, reactor, clock, hs: TestHomeServer):
# We can't test the RoomMemberStore on its own without the other event

View File

@ -20,12 +20,13 @@ import os
import time
import uuid
import warnings
from inspect import getcallargs
from typing import Type
from urllib import parse as urlparse
from mock import Mock, patch
from twisted.internet import defer
from twisted.internet import defer, reactor
from synapse.api.constants import EventTypes
from synapse.api.errors import CodeMessageException, cs_error
@ -33,6 +34,7 @@ from synapse.api.room_versions import RoomVersions
from synapse.config.database import DatabaseConnectionConfig
from synapse.config.homeserver import HomeServerConfig
from synapse.config.server import DEFAULT_ROOM_VERSION
from synapse.federation.transport import server as federation_server
from synapse.http.server import HttpServer
from synapse.logging.context import current_context, set_current_context
from synapse.server import HomeServer
@ -40,6 +42,7 @@ from synapse.storage import DataStore
from synapse.storage.database import LoggingDatabaseConnection
from synapse.storage.engines import PostgresEngine, create_engine
from synapse.storage.prepare_database import prepare_database
from synapse.util.ratelimitutils import FederationRateLimiter
# set this to True to run the tests against postgres instead of sqlite.
#
@ -339,9 +342,32 @@ def setup_test_homeserver(
hs.get_auth_handler().validate_hash = validate_hash
fed = kwargs.get("resource_for_federation", None)
if fed:
register_federation_servlets(hs, fed)
return hs
def register_federation_servlets(hs, resource):
federation_server.register_servlets(
hs,
resource=resource,
authenticator=federation_server.Authenticator(hs),
ratelimiter=FederationRateLimiter(
hs.get_clock(), config=hs.config.rc_federation
),
)
def get_mock_call_args(pattern_func, mock_func):
""" Return the arguments the mock function was called with interpreted
by the pattern functions argument list.
"""
invoked_args, invoked_kargs = mock_func.call_args
return getcallargs(pattern_func, *invoked_args, **invoked_kargs)
def mock_getRawHeaders(headers=None):
headers = headers if headers is not None else {}
@ -527,6 +553,86 @@ class MockClock:
return d
def _format_call(args, kwargs):
return ", ".join(
["%r" % (a) for a in args] + ["%s=%r" % (k, v) for k, v in kwargs.items()]
)
class DeferredMockCallable:
"""A callable instance that stores a set of pending call expectations and
return values for them. It allows a unit test to assert that the given set
of function calls are eventually made, by awaiting on them to be called.
"""
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))
)
for (call, result, d) in self.expectations:
if args == call[1] and kwargs == call[2]:
d.callback(None)
return result
failure = AssertionError(
"Was not expecting call(%s)" % (_format_call(args, kwargs))
)
for _, _, d in self.expectations:
try:
d.errback(failure)
except Exception:
pass
raise failure
def expect_call_and_return(self, call, result):
self.expectations.append((call, result, defer.Deferred()))
@defer.inlineCallbacks
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])
)
async def create_room(hs, room_id: str, creator_id: str):
"""Creates and persist a creation event for the given room
"""