From 895fcb377e3ebc43d67df1ac66413d92aacffca1 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Tue, 13 Jan 2015 14:14:21 +0000 Subject: [PATCH 01/25] Fix stream token ordering --- synapse/storage/stream.py | 155 ++++++++++++++++++++++---------------- 1 file changed, 92 insertions(+), 63 deletions(-) diff --git a/synapse/storage/stream.py b/synapse/storage/stream.py index 744c821dfe..563c8e3bbb 100644 --- a/synapse/storage/stream.py +++ b/synapse/storage/stream.py @@ -39,6 +39,8 @@ from ._base import SQLBaseStore from synapse.api.errors import SynapseError from synapse.util.logutils import log_function +from collections import namedtuple + import logging @@ -52,58 +54,76 @@ _STREAM_TOKEN = "stream" _TOPOLOGICAL_TOKEN = "topological" -def _parse_stream_token(string): - try: - if string[0] != 's': - raise - return int(string[1:]) - except: - raise SynapseError(400, "Invalid token") +class _StreamToken(namedtuple("_StreamToken", "topological stream")): + """Tokens are positions between events. The token "s1" comes after event 1. + s0 s1 + | | + [0] V [1] V [2] -def _parse_topological_token(string): - try: - if string[0] != 't': - raise - parts = string[1:].split('-', 1) - return (int(parts[0]), int(parts[1])) - except: - raise SynapseError(400, "Invalid token") + Tokens can either be a point in the live event stream or a cursor going + through historic events. + When traversing the live event stream events are ordered by when they + arrived at the homeserver. -def is_stream_token(string): - try: - _parse_stream_token(string) - return True - except: - return False + When traversing historic events the events are ordered by their depth in + the event graph "topological_ordering" and then by when they arrived at the + homeserver "stream_ordering". + Live tokens start with an "s" followed by the "stream_ordering" id of the + event it comes after. Historic tokens start with a "t" followed by the + "topological_ordering" id of the event it comes after, follewed by "-", + followed by the "stream_ordering" id of the event it comes after. + """ + __slots__ = [] -def is_topological_token(string): - try: - _parse_topological_token(string) - return True - except: - return False + @classmethod + def parse(cls, string): + try: + if string[0] == 's': + return cls(None, int(string[1:])) + if string[0] == 't': + parts = string[1:].split('-', 1) + return cls(int(parts[1]), int(parts[0])) + except: + pass + raise SynapseError(400, "Invalid token %r" % (string,)) + @classmethod + def parse_stream_token(cls, string): + try: + if string[0] == 's': + return cls(None, int(string[1:])) + except: + pass + raise SynapseError(400, "Invalid token %r" % (string,)) -def _get_token_bound(token, comparison): - try: - s = _parse_stream_token(token) - return "%s %s %d" % ("stream_ordering", comparison, s) - except: - pass + def __str__(self): + if self.topological is not None: + return "t%d-%d" % (self.topological, self.stream) + else: + return "s%d" % (self.stream,) - try: - top, stream = _parse_topological_token(token) - return "%s %s %d AND %s %s %d" % ( - "topological_ordering", comparison, top, - "stream_ordering", comparison, stream, - ) - except: - pass + def lower_bound(self): + if self.topological is None: + return "(%d < %s)" % (self.stream, "stream_ordering") + else: + return "(%d < %s OR (%d == %s AND %d < %s))" % ( + self.topological, "topological_ordering", + self.topological, "topological_ordering", + self.stream, "stream_ordering", + ) - raise SynapseError(400, "Invalid token") + def upper_bound(self): + if self.topological is None: + return "(%d >= %s)" % (self.stream, "stream_ordering") + else: + return "(%d > %s OR (%d == %s AND %d >= %s))" % ( + self.topological, "topological_ordering", + self.topological, "topological_ordering", + self.stream, "stream_ordering", + ) class StreamStore(SQLBaseStore): @@ -162,8 +182,8 @@ class StreamStore(SQLBaseStore): limit = MAX_STREAM_SIZE # From and to keys should be integers from ordering. - from_id = _parse_stream_token(from_key) - to_id = _parse_stream_token(to_key) + from_id = _StreamToken.parse_stream_token(from_key) + to_id = _StreamToken.parse_stream_token(to_key) if from_key == to_key: return defer.succeed(([], to_key)) @@ -181,7 +201,7 @@ class StreamStore(SQLBaseStore): } def f(txn): - txn.execute(sql, (user_id, user_id, from_id, to_id,)) + txn.execute(sql, (user_id, user_id, from_id.stream, to_id.stream,)) rows = self.cursor_to_dict(txn) @@ -211,17 +231,21 @@ class StreamStore(SQLBaseStore): # Tokens really represent positions between elements, but we use # the convention of pointing to the event before the gap. Hence # we have a bit of asymmetry when it comes to equalities. - from_comp = '<=' if direction == 'b' else '>' - to_comp = '>' if direction == 'b' else '<=' - order = "DESC" if direction == 'b' else "ASC" - args = [room_id] - - bounds = _get_token_bound(from_key, from_comp) - if to_key: - bounds = "%s AND %s" % ( - bounds, _get_token_bound(to_key, to_comp) - ) + if direction == 'b': + order = "DESC" + bounds = _StreamToken.parse(from_key).upper_bound() + if to_key: + bounds = "%s AND %s" % ( + bounds, _StreamToken.parse(to_key).lower_bound() + ) + else: + order = "ASC" + bounds = _StreamToken.parse(from_key).lower_bound() + if to_key: + bounds = "%s AND %s" % ( + bounds, _StreamToken.parse(to_key).upper_bound() + ) if int(limit) > 0: args.append(int(limit)) @@ -249,9 +273,13 @@ class StreamStore(SQLBaseStore): topo = rows[-1]["topological_ordering"] toke = rows[-1]["stream_ordering"] if direction == 'b': - topo -= 1 + # Tokens are positions between events. + # This token points *after* the last event in the chunk. + # We need it to point to the event before it in the chunk + # when we are going backwards so we subtract one from the + # stream part. toke -= 1 - next_token = "t%s-%s" % (topo, toke) + next_token = str(_StreamToken(topo, toke)) else: # TODO (erikj): We should work out what to do here instead. next_token = to_key if to_key else from_key @@ -284,13 +312,14 @@ class StreamStore(SQLBaseStore): rows.reverse() # As we selected with reverse ordering if rows: - # XXX: Always subtract 1 since the start token always goes - # backwards (parity with paginate_room_events). It isn't - # obvious that this is correct; we should clarify the algorithm - # used here. - topo = rows[0]["topological_ordering"] - 1 + # Tokens are positions between events. + # This token points *after* the last event in the chunk. + # We need it to point to the event before it in the chunk + # since we are going backwards so we subtract one from the + # stream part. + topo = rows[0]["topological_ordering"] toke = rows[0]["stream_ordering"] - 1 - start_token = "t%s-%s" % (topo, toke) + start_token = str(_StreamToken(topo, toke)) token = (start_token, end_token) else: From fda63064fc21881c8aabbfef36916b3b00af5299 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Tue, 13 Jan 2015 14:43:26 +0000 Subject: [PATCH 02/25] get_room_events isn't called anywhere --- synapse/storage/stream.py | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/synapse/storage/stream.py b/synapse/storage/stream.py index 563c8e3bbb..8ac2adab05 100644 --- a/synapse/storage/stream.py +++ b/synapse/storage/stream.py @@ -127,36 +127,6 @@ class _StreamToken(namedtuple("_StreamToken", "topological stream")): class StreamStore(SQLBaseStore): - @log_function - def get_room_events(self, user_id, from_key, to_key, room_id, limit=0, - direction='f', with_feedback=False): - # We deal with events request in two different ways depending on if - # this looks like an /events request or a pagination request. - is_events = ( - direction == 'f' - and user_id - and is_stream_token(from_key) - and to_key and is_stream_token(to_key) - ) - - if is_events: - return self.get_room_events_stream( - user_id=user_id, - from_key=from_key, - to_key=to_key, - room_id=room_id, - limit=limit, - with_feedback=with_feedback, - ) - else: - return self.paginate_room_events( - from_key=from_key, - to_key=to_key, - room_id=room_id, - limit=limit, - with_feedback=with_feedback, - ) - @log_function def get_room_events_stream(self, user_id, from_key, to_key, room_id, limit=0, with_feedback=False): From 3891597eb3666bbcbe325e38798b9d78b5d70bcc Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Tue, 13 Jan 2015 15:57:26 +0000 Subject: [PATCH 03/25] Remove unused functions --- synapse/events/builder.py | 6 ------ synapse/storage/room.py | 7 ------- synapse/storage/state.py | 6 ------ tests/storage/test_room.py | 11 ----------- 4 files changed, 30 deletions(-) diff --git a/synapse/events/builder.py b/synapse/events/builder.py index d4cb602ebb..a9b1b99a10 100644 --- a/synapse/events/builder.py +++ b/synapse/events/builder.py @@ -33,12 +33,6 @@ class EventBuilder(EventBase): unsigned=unsigned ) - def update_event_key(self, key, value): - self._event_dict[key] = value - - def update_event_keys(self, other_dict): - self._event_dict.update(other_dict) - def build(self): return FrozenEvent.from_event(self) diff --git a/synapse/storage/room.py b/synapse/storage/room.py index 978b2c4a48..6542f8e4f8 100644 --- a/synapse/storage/room.py +++ b/synapse/storage/room.py @@ -58,13 +58,6 @@ class RoomStore(SQLBaseStore): logger.error("store_room with room_id=%s failed: %s", room_id, e) raise StoreError(500, "Problem creating room.") - def store_room_config(self, room_id, visibility): - return self._simple_update_one( - table=RoomsTable.table_name, - keyvalues={"room_id": room_id}, - updatevalues={"is_public": visibility} - ) - def get_room(self, room_id): """Retrieve a room. diff --git a/synapse/storage/state.py b/synapse/storage/state.py index 5327517704..71db16d0e5 100644 --- a/synapse/storage/state.py +++ b/synapse/storage/state.py @@ -78,12 +78,6 @@ class StateStore(SQLBaseStore): f, ) - def store_state_groups(self, event): - return self.runInteraction( - "store_state_groups", - self._store_state_groups_txn, event - ) - def _store_state_groups_txn(self, txn, event, context): if context.current_state is None: return diff --git a/tests/storage/test_room.py b/tests/storage/test_room.py index 11761fe29a..e7739776ec 100644 --- a/tests/storage/test_room.py +++ b/tests/storage/test_room.py @@ -56,17 +56,6 @@ class RoomStoreTestCase(unittest.TestCase): (yield self.store.get_room(self.room.to_string())) ) - @defer.inlineCallbacks - def test_store_room_config(self): - yield self.store.store_room_config(self.room.to_string(), - visibility=False - ) - - self.assertObjectHasAttributes( - {"is_public": False}, - (yield self.store.get_room(self.room.to_string())) - ) - @defer.inlineCallbacks def test_get_rooms(self): # get_rooms does an INNER JOIN on the room_aliases table :( From c2e7c84e5887de9b622a7cd2cc861f5eef3866c1 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 13 Jan 2015 16:57:28 +0000 Subject: [PATCH 04/25] Don't try to cancel already-expired timers - SYN-230 --- synapse/handlers/typing.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/synapse/handlers/typing.py b/synapse/handlers/typing.py index 22ce7873d0..cd9638dd04 100644 --- a/synapse/handlers/typing.py +++ b/synapse/handlers/typing.py @@ -120,6 +120,10 @@ class TypingNotificationHandler(BaseHandler): member = RoomMember(room_id=room_id, user=target_user) + if member in self._member_typing_timer: + self.clock.cancel_call_later(self._member_typing_timer[member]) + del self._member_typing_timer[member] + yield self._stopped_typing(member) @defer.inlineCallbacks @@ -142,8 +146,10 @@ class TypingNotificationHandler(BaseHandler): del self._member_typing_until[member] - self.clock.cancel_call_later(self._member_typing_timer[member]) - del self._member_typing_timer[member] + if member in self._member_typing_timer: + # Don't cancel it - either it already expired, or the real + # stopped_typing() will cancel it + del self._member_typing_timer[member] @defer.inlineCallbacks def _push_update(self, room_id, user, typing): From cf7e723808fa5882f33b01274fb2b94e5abe9eca Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 13 Jan 2015 16:57:55 +0000 Subject: [PATCH 05/25] Have MockClock detect attempts to cancel expired timers, to prevent a repeat of SYN-230 --- tests/utils.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 731e03f517..97fa8d8181 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -138,7 +138,8 @@ class MockClock(object): now = 1000 def __init__(self): - # list of tuples of (absolute_time, callback) in no particular order + # list of lists of [absolute_time, callback, expired] in no particular + # order self.timers = [] def time(self): @@ -154,11 +155,16 @@ class MockClock(object): LoggingContext.thread_local.current_context = current_context callback() - t = (self.now + delay, wrapped_callback) + t = [self.now + delay, wrapped_callback, False] self.timers.append(t) + return t def cancel_call_later(self, timer): + if timer[2]: + raise Exception("Cannot cancel an expired timer") + + timer[2] = True self.timers = [t for t in self.timers if t != timer] # For unit testing @@ -168,11 +174,17 @@ class MockClock(object): timers = self.timers self.timers = [] - for time, callback in timers: + for t in timers: + time, callback, expired = t + + if expired: + raise Exception("Timer already expired") + if self.now >= time: + t[2] = True callback() else: - self.timers.append((time, callback)) + self.timers.append(t) class SQLiteMemoryDbPool(ConnectionPool, object): From 34a5fbe2b7162c545ab5ae9403147bdd925a58f9 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 13 Jan 2015 17:29:24 +0000 Subject: [PATCH 06/25] Have /join/:room_id return the room ID in response anyway, for consistency of clients (SYN-234) --- synapse/rest/room.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/rest/room.py b/synapse/rest/room.py index caafa959e6..48bba2a5f3 100644 --- a/synapse/rest/room.py +++ b/synapse/rest/room.py @@ -246,7 +246,7 @@ class JoinRoomAliasServlet(RestServlet): } ) - defer.returnValue((200, {})) + defer.returnValue((200, {"room_id": identifier.to_string()})) @defer.inlineCallbacks def on_PUT(self, request, room_identifier, txn_id): From 2bdee982695345e676cc1667c8011b88e0a4cf66 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 16 Jan 2015 19:00:40 +0000 Subject: [PATCH 07/25] Remove temporary debug logging that was accidentally committed --- synapse/handlers/events.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/synapse/handlers/events.py b/synapse/handlers/events.py index c9ade253dd..103bc67c42 100644 --- a/synapse/handlers/events.py +++ b/synapse/handlers/events.py @@ -70,10 +70,8 @@ class EventStreamHandler(BaseHandler): pagin_config.from_token = None rm_handler = self.hs.get_handlers().room_member_handler - logger.debug("BETA") room_ids = yield rm_handler.get_rooms_for_user(auth_user) - logger.debug("ALPHA") with PreserveLoggingContext(): events, tokens = yield self.notifier.get_events_for( auth_user, room_ids, pagin_config, timeout From 602684eac5b7acf61e10d7fabed4977635d3fb46 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 16 Jan 2015 13:21:14 +0000 Subject: [PATCH 08/25] Split transport layer into client and server parts --- synapse/federation/transport/__init__.py | 62 ++++ synapse/federation/transport/client.py | 257 ++++++++++++++++ .../{transport.py => transport/server.py} | 274 +----------------- 3 files changed, 321 insertions(+), 272 deletions(-) create mode 100644 synapse/federation/transport/__init__.py create mode 100644 synapse/federation/transport/client.py rename synapse/federation/{transport.py => transport/server.py} (56%) diff --git a/synapse/federation/transport/__init__.py b/synapse/federation/transport/__init__.py new file mode 100644 index 0000000000..6800ac46c5 --- /dev/null +++ b/synapse/federation/transport/__init__.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2014, 2015 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""The transport layer is responsible for both sending transactions to remote +home servers and receiving a variety of requests from other home servers. + +By default this is done over HTTPS (and all home servers are required to +support HTTPS), however individual pairings of servers may decide to +communicate over a different (albeit still reliable) protocol. +""" + +from .server import TransportLayerServer +from .client import TransportLayerClient + + +class TransportLayer(TransportLayerServer, TransportLayerClient): + """This is a basic implementation of the transport layer that translates + transactions and other requests to/from HTTP. + + Attributes: + server_name (str): Local home server host + + server (synapse.http.server.HttpServer): the http server to + register listeners on + + client (synapse.http.client.HttpClient): the http client used to + send requests + + request_handler (TransportRequestHandler): The handler to fire when we + receive requests for data. + + received_handler (TransportReceivedHandler): The handler to fire when + we receive data. + """ + + def __init__(self, homeserver, server_name, server, client): + """ + Args: + server_name (str): Local home server host + server (synapse.protocol.http.HttpServer): the http server to + register listeners on + client (synapse.protocol.http.HttpClient): the http client used to + send requests + """ + self.keyring = homeserver.get_keyring() + self.server_name = server_name + self.server = server + self.client = client + self.request_handler = None + self.received_handler = None diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py new file mode 100644 index 0000000000..604ade683b --- /dev/null +++ b/synapse/federation/transport/client.py @@ -0,0 +1,257 @@ +# -*- coding: utf-8 -*- +# Copyright 2014, 2015 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from twisted.internet import defer + +from synapse.api.urls import FEDERATION_PREFIX as PREFIX +from synapse.util.logutils import log_function + +import logging +import json + + +logger = logging.getLogger(__name__) + + +class TransportLayerClient(object): + """Sends federation HTTP requests to other servers""" + + @log_function + def get_context_state(self, destination, context, event_id=None): + """ Requests all state for a given context (i.e. room) from the + given server. + + Args: + destination (str): The host name of the remote home server we want + to get the state from. + context (str): The name of the context we want the state of + + Returns: + Deferred: Results in a dict received from the remote homeserver. + """ + logger.debug("get_context_state dest=%s, context=%s", + destination, context) + + subpath = "/state/%s/" % context + + args = {} + if event_id: + args["event_id"] = event_id + + return self._do_request_for_transaction( + destination, subpath, args=args + ) + + @log_function + def get_event(self, destination, event_id): + """ Requests the pdu with give id and origin from the given server. + + Args: + destination (str): The host name of the remote home server we want + to get the state from. + event_id (str): The id of the event being requested. + + Returns: + Deferred: Results in a dict received from the remote homeserver. + """ + logger.debug("get_pdu dest=%s, event_id=%s", + destination, event_id) + + subpath = "/event/%s/" % (event_id, ) + + return self._do_request_for_transaction(destination, subpath) + + @log_function + def backfill(self, dest, context, event_tuples, limit): + """ Requests `limit` previous PDUs in a given context before list of + PDUs. + + Args: + dest (str) + context (str) + event_tuples (list) + limt (int) + + Returns: + Deferred: Results in a dict received from the remote homeserver. + """ + logger.debug( + "backfill dest=%s, context=%s, event_tuples=%s, limit=%s", + dest, context, repr(event_tuples), str(limit) + ) + + if not event_tuples: + # TODO: raise? + return + + subpath = "/backfill/%s/" % (context,) + + args = { + "v": event_tuples, + "limit": [str(limit)], + } + + return self._do_request_for_transaction( + dest, + subpath, + args=args, + ) + + @defer.inlineCallbacks + @log_function + def send_transaction(self, transaction, json_data_callback=None): + """ Sends the given Transaction to its destination + + Args: + transaction (Transaction) + + Returns: + Deferred: Results of the deferred is a tuple in the form of + (response_code, response_body) where the response_body is a + python dict decoded from json + """ + logger.debug( + "send_data dest=%s, txid=%s", + transaction.destination, transaction.transaction_id + ) + + if transaction.destination == self.server_name: + raise RuntimeError("Transport layer cannot send to itself!") + + # FIXME: This is only used by the tests. The actual json sent is + # generated by the json_data_callback. + json_data = transaction.get_dict() + + code, response = yield self.client.put_json( + transaction.destination, + path=PREFIX + "/send/%s/" % transaction.transaction_id, + data=json_data, + json_data_callback=json_data_callback, + ) + + logger.debug( + "send_data dest=%s, txid=%s, got response: %d", + transaction.destination, transaction.transaction_id, code + ) + + defer.returnValue((code, response)) + + @defer.inlineCallbacks + @log_function + def make_query(self, destination, query_type, args, retry_on_dns_fail): + path = PREFIX + "/query/%s" % query_type + + response = yield self.client.get_json( + destination=destination, + path=path, + args=args, + retry_on_dns_fail=retry_on_dns_fail, + ) + + defer.returnValue(response) + + @defer.inlineCallbacks + @log_function + def make_join(self, destination, context, user_id, retry_on_dns_fail=True): + path = PREFIX + "/make_join/%s/%s" % (context, user_id,) + + response = yield self.client.get_json( + destination=destination, + path=path, + retry_on_dns_fail=retry_on_dns_fail, + ) + + defer.returnValue(response) + + @defer.inlineCallbacks + @log_function + def send_join(self, destination, context, event_id, content): + path = PREFIX + "/send_join/%s/%s" % ( + context, + event_id, + ) + + code, content = yield self.client.put_json( + destination=destination, + path=path, + data=content, + ) + + if not 200 <= code < 300: + raise RuntimeError("Got %d from send_join", code) + + defer.returnValue(json.loads(content)) + + @defer.inlineCallbacks + @log_function + def send_invite(self, destination, context, event_id, content): + path = PREFIX + "/invite/%s/%s" % ( + context, + event_id, + ) + + code, content = yield self.client.put_json( + destination=destination, + path=path, + data=content, + ) + + if not 200 <= code < 300: + raise RuntimeError("Got %d from send_invite", code) + + defer.returnValue(json.loads(content)) + + @defer.inlineCallbacks + @log_function + def get_event_auth(self, destination, context, event_id): + path = PREFIX + "/event_auth/%s/%s" % ( + context, + event_id, + ) + + response = yield self.client.get_json( + destination=destination, + path=path, + ) + + defer.returnValue(response) + + @defer.inlineCallbacks + @log_function + def _do_request_for_transaction(self, destination, subpath, args={}): + """ + Args: + destination (str) + path (str) + args (dict): This is parsed directly to the HttpClient. + + Returns: + Deferred: Results in a dict. + """ + + data = yield self.client.get_json( + destination, + path=PREFIX + subpath, + args=args, + ) + + # Add certain keys to the JSON, ready for decoding as a Transaction + data.update( + origin=destination, + destination=self.server_name, + transaction_id=None + ) + + defer.returnValue(data) diff --git a/synapse/federation/transport.py b/synapse/federation/transport/server.py similarity index 56% rename from synapse/federation/transport.py rename to synapse/federation/transport/server.py index 1f0f06e0fe..34b50def7d 100644 --- a/synapse/federation/transport.py +++ b/synapse/federation/transport/server.py @@ -13,14 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""The transport layer is responsible for both sending transactions to remote -home servers and receiving a variety of requests from other home servers. - -Typically, this is done over HTTP (and all home servers are required to -support HTTP), however individual pairings of servers may decide to communicate -over a different (albeit still reliable) protocol. -""" - from twisted.internet import defer from synapse.api.urls import FEDERATION_PREFIX as PREFIX @@ -35,241 +27,8 @@ import re logger = logging.getLogger(__name__) -class TransportLayer(object): - """This is a basic implementation of the transport layer that translates - transactions and other requests to/from HTTP. - - Attributes: - server_name (str): Local home server host - - server (synapse.http.server.HttpServer): the http server to - register listeners on - - client (synapse.http.client.HttpClient): the http client used to - send requests - - request_handler (TransportRequestHandler): The handler to fire when we - receive requests for data. - - received_handler (TransportReceivedHandler): The handler to fire when - we receive data. - """ - - def __init__(self, homeserver, server_name, server, client): - """ - Args: - server_name (str): Local home server host - server (synapse.protocol.http.HttpServer): the http server to - register listeners on - client (synapse.protocol.http.HttpClient): the http client used to - send requests - """ - self.keyring = homeserver.get_keyring() - self.server_name = server_name - self.server = server - self.client = client - self.request_handler = None - self.received_handler = None - - @log_function - def get_context_state(self, destination, context, event_id=None): - """ Requests all state for a given context (i.e. room) from the - given server. - - Args: - destination (str): The host name of the remote home server we want - to get the state from. - context (str): The name of the context we want the state of - - Returns: - Deferred: Results in a dict received from the remote homeserver. - """ - logger.debug("get_context_state dest=%s, context=%s", - destination, context) - - subpath = "/state/%s/" % context - - args = {} - if event_id: - args["event_id"] = event_id - - return self._do_request_for_transaction( - destination, subpath, args=args - ) - - @log_function - def get_event(self, destination, event_id): - """ Requests the pdu with give id and origin from the given server. - - Args: - destination (str): The host name of the remote home server we want - to get the state from. - event_id (str): The id of the event being requested. - - Returns: - Deferred: Results in a dict received from the remote homeserver. - """ - logger.debug("get_pdu dest=%s, event_id=%s", - destination, event_id) - - subpath = "/event/%s/" % (event_id, ) - - return self._do_request_for_transaction(destination, subpath) - - @log_function - def backfill(self, dest, context, event_tuples, limit): - """ Requests `limit` previous PDUs in a given context before list of - PDUs. - - Args: - dest (str) - context (str) - event_tuples (list) - limt (int) - - Returns: - Deferred: Results in a dict received from the remote homeserver. - """ - logger.debug( - "backfill dest=%s, context=%s, event_tuples=%s, limit=%s", - dest, context, repr(event_tuples), str(limit) - ) - - if not event_tuples: - # TODO: raise? - return - - subpath = "/backfill/%s/" % (context,) - - args = { - "v": event_tuples, - "limit": [str(limit)], - } - - return self._do_request_for_transaction( - dest, - subpath, - args=args, - ) - - @defer.inlineCallbacks - @log_function - def send_transaction(self, transaction, json_data_callback=None): - """ Sends the given Transaction to its destination - - Args: - transaction (Transaction) - - Returns: - Deferred: Results of the deferred is a tuple in the form of - (response_code, response_body) where the response_body is a - python dict decoded from json - """ - logger.debug( - "send_data dest=%s, txid=%s", - transaction.destination, transaction.transaction_id - ) - - if transaction.destination == self.server_name: - raise RuntimeError("Transport layer cannot send to itself!") - - # FIXME: This is only used by the tests. The actual json sent is - # generated by the json_data_callback. - json_data = transaction.get_dict() - - code, response = yield self.client.put_json( - transaction.destination, - path=PREFIX + "/send/%s/" % transaction.transaction_id, - data=json_data, - json_data_callback=json_data_callback, - ) - - logger.debug( - "send_data dest=%s, txid=%s, got response: %d", - transaction.destination, transaction.transaction_id, code - ) - - defer.returnValue((code, response)) - - @defer.inlineCallbacks - @log_function - def make_query(self, destination, query_type, args, retry_on_dns_fail): - path = PREFIX + "/query/%s" % query_type - - response = yield self.client.get_json( - destination=destination, - path=path, - args=args, - retry_on_dns_fail=retry_on_dns_fail, - ) - - defer.returnValue(response) - - @defer.inlineCallbacks - @log_function - def make_join(self, destination, context, user_id, retry_on_dns_fail=True): - path = PREFIX + "/make_join/%s/%s" % (context, user_id,) - - response = yield self.client.get_json( - destination=destination, - path=path, - retry_on_dns_fail=retry_on_dns_fail, - ) - - defer.returnValue(response) - - @defer.inlineCallbacks - @log_function - def send_join(self, destination, context, event_id, content): - path = PREFIX + "/send_join/%s/%s" % ( - context, - event_id, - ) - - code, content = yield self.client.put_json( - destination=destination, - path=path, - data=content, - ) - - if not 200 <= code < 300: - raise RuntimeError("Got %d from send_join", code) - - defer.returnValue(json.loads(content)) - - @defer.inlineCallbacks - @log_function - def send_invite(self, destination, context, event_id, content): - path = PREFIX + "/invite/%s/%s" % ( - context, - event_id, - ) - - code, content = yield self.client.put_json( - destination=destination, - path=path, - data=content, - ) - - if not 200 <= code < 300: - raise RuntimeError("Got %d from send_invite", code) - - defer.returnValue(json.loads(content)) - - @defer.inlineCallbacks - @log_function - def get_event_auth(self, destination, context, event_id): - path = PREFIX + "/event_auth/%s/%s" % ( - context, - event_id, - ) - - response = yield self.client.get_json( - destination=destination, - path=path, - ) - - defer.returnValue(response) +class TransportLayerServer(object): + """Handles incoming federation HTTP requests""" @defer.inlineCallbacks def _authenticate_request(self, request): @@ -373,8 +132,6 @@ class TransportLayer(object): """ self.request_handler = handler - # TODO(markjh): Namespace the federation URI paths - # This is for when someone asks us for everything since version X self.server.register_path( "GET", @@ -528,33 +285,6 @@ class TransportLayer(object): defer.returnValue((code, response)) - @defer.inlineCallbacks - @log_function - def _do_request_for_transaction(self, destination, subpath, args={}): - """ - Args: - destination (str) - path (str) - args (dict): This is parsed directly to the HttpClient. - - Returns: - Deferred: Results in a dict. - """ - - data = yield self.client.get_json( - destination, - path=PREFIX + subpath, - args=args, - ) - - # Add certain keys to the JSON, ready for decoding as a Transaction - data.update( - origin=destination, - destination=self.server_name, - transaction_id=None - ) - - defer.returnValue(data) @log_function def _on_backfill_request(self, origin, context, v_list, limits): From 2408c4b0a49bf21f1a84f3ac6549d30fd53bc5d4 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 16 Jan 2015 18:20:19 +0000 Subject: [PATCH 09/25] Fold _do_request_for_transaction into the methods that called it since it was a trivial wrapper around client.get_json --- synapse/federation/transport/client.py | 55 ++++++-------------------- 1 file changed, 11 insertions(+), 44 deletions(-) diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py index 604ade683b..d61ff192eb 100644 --- a/synapse/federation/transport/client.py +++ b/synapse/federation/transport/client.py @@ -29,7 +29,7 @@ class TransportLayerClient(object): """Sends federation HTTP requests to other servers""" @log_function - def get_context_state(self, destination, context, event_id=None): + def get_context_state(self, destination, context, event_id): """ Requests all state for a given context (i.e. room) from the given server. @@ -37,6 +37,7 @@ class TransportLayerClient(object): destination (str): The host name of the remote home server we want to get the state from. context (str): The name of the context we want the state of + event_id (str): The event we want the context at. Returns: Deferred: Results in a dict received from the remote homeserver. @@ -44,14 +45,9 @@ class TransportLayerClient(object): logger.debug("get_context_state dest=%s, context=%s", destination, context) - subpath = "/state/%s/" % context - - args = {} - if event_id: - args["event_id"] = event_id - - return self._do_request_for_transaction( - destination, subpath, args=args + path = PREFIX + "/state/%s/" % context + return self.client.get_json( + destination, path=path, args={"event_id": event_id}, ) @log_function @@ -69,9 +65,8 @@ class TransportLayerClient(object): logger.debug("get_pdu dest=%s, event_id=%s", destination, event_id) - subpath = "/event/%s/" % (event_id, ) - - return self._do_request_for_transaction(destination, subpath) + path = PREFIX + "/event/%s/" % (event_id, ) + return self.client.get_json(destination, path=path) @log_function def backfill(self, dest, context, event_tuples, limit): @@ -96,16 +91,16 @@ class TransportLayerClient(object): # TODO: raise? return - subpath = "/backfill/%s/" % (context,) + path = PREFIX + "/backfill/%s/" % (context,) args = { "v": event_tuples, "limit": [str(limit)], } - return self._do_request_for_transaction( - dest, - subpath, + return self.client.get_json( + destination, + path=path, args=args, ) @@ -227,31 +222,3 @@ class TransportLayerClient(object): ) defer.returnValue(response) - - @defer.inlineCallbacks - @log_function - def _do_request_for_transaction(self, destination, subpath, args={}): - """ - Args: - destination (str) - path (str) - args (dict): This is parsed directly to the HttpClient. - - Returns: - Deferred: Results in a dict. - """ - - data = yield self.client.get_json( - destination, - path=PREFIX + subpath, - args=args, - ) - - # Add certain keys to the JSON, ready for decoding as a Transaction - data.update( - origin=destination, - destination=self.server_name, - transaction_id=None - ) - - defer.returnValue(data) From 5fed04264056263e10b920a917a3a40f88e7e820 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 16 Jan 2015 18:59:04 +0000 Subject: [PATCH 10/25] Finish renaming "context" to "room_id" in federation codebase --- synapse/federation/replication.py | 94 ++++++++++---------------- synapse/federation/transport/client.py | 47 ++++++------- synapse/federation/transport/server.py | 1 - synapse/handlers/_base.py | 4 +- synapse/handlers/federation.py | 10 +-- synapse/http/matrixfederationclient.py | 1 - tests/handlers/test_room.py | 4 +- 7 files changed, 62 insertions(+), 99 deletions(-) diff --git a/synapse/federation/replication.py b/synapse/federation/replication.py index a4c29b484b..6620532a60 100644 --- a/synapse/federation/replication.py +++ b/synapse/federation/replication.py @@ -256,23 +256,21 @@ class ReplicationLayer(object): @defer.inlineCallbacks @log_function - def get_state_for_context(self, destination, context, event_id): - """Requests all of the `current` state PDUs for a given context from + def get_state_for_room(self, destination, room_id, event_id): + """Requests all of the `current` state PDUs for a given room from a remote home server. Args: destination (str): The remote homeserver to query for the state. - context (str): The context we're interested in. + room_id (str): The id of the room we're interested in. event_id (str): The id of the event we want the state at. Returns: Deferred: Results in a list of PDUs. """ - result = yield self.transport_layer.get_context_state( - destination, - context, - event_id=event_id, + result = yield self.transport_layer.get_room_state( + destination, room_id, event_id=event_id, ) pdus = [ @@ -288,9 +286,9 @@ class ReplicationLayer(object): @defer.inlineCallbacks @log_function - def get_event_auth(self, destination, context, event_id): + def get_event_auth(self, destination, room_id, event_id): res = yield self.transport_layer.get_event_auth( - destination, context, event_id, + destination, room_id, event_id, ) auth_chain = [ @@ -304,9 +302,9 @@ class ReplicationLayer(object): @defer.inlineCallbacks @log_function - def on_backfill_request(self, origin, context, versions, limit): + def on_backfill_request(self, origin, room_id, versions, limit): pdus = yield self.handler.on_backfill_request( - origin, context, versions, limit + origin, room_id, versions, limit ) defer.returnValue((200, self._transaction_from_pdus(pdus).get_dict())) @@ -380,12 +378,10 @@ class ReplicationLayer(object): @defer.inlineCallbacks @log_function - def on_context_state_request(self, origin, context, event_id): + def on_context_state_request(self, origin, room_id, event_id): if event_id: pdus = yield self.handler.get_state_for_pdu( - origin, - context, - event_id, + origin, room_id, event_id, ) auth_chain = yield self.store.get_auth_chain( [pdu.event_id for pdu in pdus] @@ -413,7 +409,7 @@ class ReplicationLayer(object): @defer.inlineCallbacks @log_function def on_pull_request(self, origin, versions): - raise NotImplementedError("Pull transacions not implemented") + raise NotImplementedError("Pull transactions not implemented") @defer.inlineCallbacks def on_query_request(self, query_type, args): @@ -422,30 +418,21 @@ class ReplicationLayer(object): defer.returnValue((200, response)) else: defer.returnValue( - (404, "No handler for Query type '%s'" % (query_type, )) + (404, "No handler for Query type '%s'" % (query_type,)) ) @defer.inlineCallbacks - def on_make_join_request(self, context, user_id): - pdu = yield self.handler.on_make_join_request(context, user_id) + def on_make_join_request(self, room_id, user_id): + pdu = yield self.handler.on_make_join_request(room_id, user_id) time_now = self._clock.time_msec() - defer.returnValue({ - "event": pdu.get_pdu_json(time_now), - }) + defer.returnValue({"event": pdu.get_pdu_json(time_now)}) @defer.inlineCallbacks def on_invite_request(self, origin, content): pdu = self.event_from_pdu_json(content) ret_pdu = yield self.handler.on_invite_request(origin, pdu) time_now = self._clock.time_msec() - defer.returnValue( - ( - 200, - { - "event": ret_pdu.get_pdu_json(time_now), - } - ) - ) + defer.returnValue((200, {"event": ret_pdu.get_pdu_json(time_now)})) @defer.inlineCallbacks def on_send_join_request(self, origin, content): @@ -462,26 +449,17 @@ class ReplicationLayer(object): })) @defer.inlineCallbacks - def on_event_auth(self, origin, context, event_id): + def on_event_auth(self, origin, room_id, event_id): time_now = self._clock.time_msec() auth_pdus = yield self.handler.on_event_auth(event_id) - defer.returnValue( - ( - 200, - { - "auth_chain": [ - a.get_pdu_json(time_now) for a in auth_pdus - ], - } - ) - ) + defer.returnValue((200, { + "auth_chain": [a.get_pdu_json(time_now) for a in auth_pdus], + })) @defer.inlineCallbacks - def make_join(self, destination, context, user_id): + def make_join(self, destination, room_id, user_id): ret = yield self.transport_layer.make_join( - destination=destination, - context=context, - user_id=user_id, + destination, room_id, user_id ) pdu_dict = ret["event"] @@ -494,10 +472,10 @@ class ReplicationLayer(object): def send_join(self, destination, pdu): time_now = self._clock.time_msec() _, content = yield self.transport_layer.send_join( - destination, - pdu.room_id, - pdu.event_id, - pdu.get_pdu_json(time_now), + destination=destination, + room_id=pdu.room_id, + event_id=pdu.event_id, + content=pdu.get_pdu_json(time_now), ) logger.debug("Got content: %s", content) @@ -507,9 +485,6 @@ class ReplicationLayer(object): for p in content.get("state", []) ] - # FIXME: We probably want to do something with the auth_chain given - # to us - auth_chain = [ self.event_from_pdu_json(p, outlier=True) for p in content.get("auth_chain", []) @@ -523,11 +498,11 @@ class ReplicationLayer(object): }) @defer.inlineCallbacks - def send_invite(self, destination, context, event_id, pdu): + def send_invite(self, destination, room_id, event_id, pdu): time_now = self._clock.time_msec() code, content = yield self.transport_layer.send_invite( destination=destination, - context=context, + room_id=room_id, event_id=event_id, content=pdu.get_pdu_json(time_now), ) @@ -657,7 +632,7 @@ class ReplicationLayer(object): "_handle_new_pdu getting state for %s", pdu.room_id ) - state, auth_chain = yield self.get_state_for_context( + state, auth_chain = yield self.get_state_for_room( origin, pdu.room_id, pdu.event_id, ) @@ -816,7 +791,7 @@ class _TransactionQueue(object): logger.info("TX [%s] is ready for retry", destination) logger.info("TX [%s] _attempt_new_transaction", destination) - + if destination in self.pending_transactions: # XXX: pending_transactions can get stuck on by a never-ending # request at which point pending_pdus_by_dest just keeps growing. @@ -830,14 +805,15 @@ class _TransactionQueue(object): pending_failures = self.pending_failures_by_dest.pop(destination, []) if pending_pdus: - logger.info("TX [%s] len(pending_pdus_by_dest[dest]) = %d", destination, len(pending_pdus)) + logger.info("TX [%s] len(pending_pdus_by_dest[dest]) = %d", + destination, len(pending_pdus)) if not pending_pdus and not pending_edus and not pending_failures: return logger.debug( - "TX [%s] Attempting new transaction " - "(pdus: %d, edus: %d, failures: %d)", + "TX [%s] Attempting new transaction" + " (pdus: %d, edus: %d, failures: %d)", destination, len(pending_pdus), len(pending_edus), diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py index d61ff192eb..e634a3a213 100644 --- a/synapse/federation/transport/client.py +++ b/synapse/federation/transport/client.py @@ -29,9 +29,9 @@ class TransportLayerClient(object): """Sends federation HTTP requests to other servers""" @log_function - def get_context_state(self, destination, context, event_id): - """ Requests all state for a given context (i.e. room) from the - given server. + def get_room_state(self, destination, room_id, event_id): + """ Requests all state for a given room from the given server at the + given event. Args: destination (str): The host name of the remote home server we want @@ -42,10 +42,10 @@ class TransportLayerClient(object): Returns: Deferred: Results in a dict received from the remote homeserver. """ - logger.debug("get_context_state dest=%s, context=%s", - destination, context) + logger.debug("get_room_state dest=%s, room=%s", + destination, room_id) - path = PREFIX + "/state/%s/" % context + path = PREFIX + "/state/%s/" % room_id return self.client.get_json( destination, path=path, args={"event_id": event_id}, ) @@ -69,13 +69,13 @@ class TransportLayerClient(object): return self.client.get_json(destination, path=path) @log_function - def backfill(self, dest, context, event_tuples, limit): + def backfill(self, destination, room_id, event_tuples, limit): """ Requests `limit` previous PDUs in a given context before list of PDUs. Args: dest (str) - context (str) + room_id (str) event_tuples (list) limt (int) @@ -83,15 +83,15 @@ class TransportLayerClient(object): Deferred: Results in a dict received from the remote homeserver. """ logger.debug( - "backfill dest=%s, context=%s, event_tuples=%s, limit=%s", - dest, context, repr(event_tuples), str(limit) + "backfill dest=%s, room_id=%s, event_tuples=%s, limit=%s", + destination, room_id, repr(event_tuples), str(limit) ) if not event_tuples: # TODO: raise? return - path = PREFIX + "/backfill/%s/" % (context,) + path = PREFIX + "/backfill/%s/" % (room_id,) args = { "v": event_tuples, @@ -159,8 +159,8 @@ class TransportLayerClient(object): @defer.inlineCallbacks @log_function - def make_join(self, destination, context, user_id, retry_on_dns_fail=True): - path = PREFIX + "/make_join/%s/%s" % (context, user_id,) + def make_join(self, destination, room_id, user_id, retry_on_dns_fail=True): + path = PREFIX + "/make_join/%s/%s" % (room_id, user_id) response = yield self.client.get_json( destination=destination, @@ -172,11 +172,8 @@ class TransportLayerClient(object): @defer.inlineCallbacks @log_function - def send_join(self, destination, context, event_id, content): - path = PREFIX + "/send_join/%s/%s" % ( - context, - event_id, - ) + def send_join(self, destination, room_id, event_id, content): + path = PREFIX + "/send_join/%s/%s" % (room_id, event_id) code, content = yield self.client.put_json( destination=destination, @@ -191,11 +188,8 @@ class TransportLayerClient(object): @defer.inlineCallbacks @log_function - def send_invite(self, destination, context, event_id, content): - path = PREFIX + "/invite/%s/%s" % ( - context, - event_id, - ) + def send_invite(self, destination, room_id, event_id, content): + path = PREFIX + "/invite/%s/%s" % (room_id, event_id) code, content = yield self.client.put_json( destination=destination, @@ -210,11 +204,8 @@ class TransportLayerClient(object): @defer.inlineCallbacks @log_function - def get_event_auth(self, destination, context, event_id): - path = PREFIX + "/event_auth/%s/%s" % ( - context, - event_id, - ) + def get_event_auth(self, destination, room_id, event_id): + path = PREFIX + "/event_auth/%s/%s" % (room_id, event_id) response = yield self.client.get_json( destination=destination, diff --git a/synapse/federation/transport/server.py b/synapse/federation/transport/server.py index 34b50def7d..a380a6910b 100644 --- a/synapse/federation/transport/server.py +++ b/synapse/federation/transport/server.py @@ -285,7 +285,6 @@ class TransportLayerServer(object): defer.returnValue((code, response)) - @log_function def _on_backfill_request(self, origin, context, v_list, limits): if not limits: diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py index 38af034b4d..f33d17a31e 100644 --- a/synapse/handlers/_base.py +++ b/synapse/handlers/_base.py @@ -144,7 +144,5 @@ class BaseHandler(object): yield self.notifier.on_new_room_event(event, extra_users=extra_users) yield federation_handler.handle_new_event( - event, - None, - destinations=destinations, + event, destinations=destinations, ) diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py index 195f7c618a..81203bf1a3 100644 --- a/synapse/handlers/federation.py +++ b/synapse/handlers/federation.py @@ -75,14 +75,14 @@ class FederationHandler(BaseHandler): @log_function @defer.inlineCallbacks - def handle_new_event(self, event, snapshot, destinations): + def handle_new_event(self, event, destinations): """ Takes in an event from the client to server side, that has already been authed and handled by the state module, and sends it to any remote home servers that may be interested. Args: - event - snapshot (.storage.Snapshot): THe snapshot the event happened after + event: The event to send + destinations: A list of destinations to send it to Returns: Deferred: Resolved when it has successfully been queued for @@ -154,7 +154,7 @@ class FederationHandler(BaseHandler): replication = self.replication_layer if not state: - state, auth_chain = yield replication.get_state_for_context( + state, auth_chain = yield replication.get_state_for_room( origin, context=event.room_id, event_id=event.event_id, ) @@ -281,7 +281,7 @@ class FederationHandler(BaseHandler): """ pdu = yield self.replication_layer.send_invite( destination=target_host, - context=event.room_id, + room_id=event.room_id, event_id=event.event_id, pdu=event ) diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py index aa14782b0f..1dda3ba2c7 100644 --- a/synapse/http/matrixfederationclient.py +++ b/synapse/http/matrixfederationclient.py @@ -72,7 +72,6 @@ class MatrixFederationHttpClient(object): requests. """ - def __init__(self, hs): self.hs = hs self.signing_key = hs.config.signing_key[0] diff --git a/tests/handlers/test_room.py b/tests/handlers/test_room.py index 0cb8aa4fbc..d3253b48b8 100644 --- a/tests/handlers/test_room.py +++ b/tests/handlers/test_room.py @@ -223,7 +223,7 @@ class RoomMemberHandlerTestCase(unittest.TestCase): yield room_handler.change_membership(event, context) self.federation.handle_new_event.assert_called_once_with( - event, None, destinations=set() + event, destinations=set() ) self.datastore.persist_event.assert_called_once_with( @@ -301,7 +301,7 @@ class RoomMemberHandlerTestCase(unittest.TestCase): yield room_handler.change_membership(event, context) self.federation.handle_new_event.assert_called_once_with( - event, None, destinations=set(['red']) + event, destinations=set(['red']) ) self.datastore.persist_event.assert_called_once_with( From 3e85e52b3f0e9330f29ec3d0f572db7b122c88b0 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 19 Jan 2015 15:26:19 +0000 Subject: [PATCH 11/25] Allow ':memory:' as the database path for sqlite3 --- synapse/app/homeserver.py | 8 +++++++- synapse/config/database.py | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 43b5c26144..61ad53fbb2 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -247,7 +247,13 @@ def setup(): logger.info("Database prepared in %s.", db_name) - hs.get_db_pool() + db_pool = hs.get_db_pool() + + if db_name == ":memory:" + # Memory databases will need to be setup each time they are opened. + reactor.callWhenRunning( + hs.get_db_pool().runWithConnection, prepare_database + ) if config.manhole: f = twisted.manhole.telnet.ShellFactory() diff --git a/synapse/config/database.py b/synapse/config/database.py index 0d33583a7d..daa161c952 100644 --- a/synapse/config/database.py +++ b/synapse/config/database.py @@ -20,7 +20,10 @@ import os class DatabaseConfig(Config): def __init__(self, args): super(DatabaseConfig, self).__init__(args) - self.database_path = self.abspath(args.database_path) + if args.database_path == ":memory:": + self.database_path = ":memory:" + else: + self.database_path = self.abspath(args.database_path) @classmethod def add_arguments(cls, parser): From 00e9c08609eb498d783c3812d9415f2706029559 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 19 Jan 2015 15:30:48 +0000 Subject: [PATCH 12/25] Fix syntax --- synapse/app/homeserver.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 61ad53fbb2..f00b06aa7f 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -241,7 +241,8 @@ def setup(): except UpgradeDatabaseException: sys.stderr.write( "\nFailed to upgrade database.\n" - "Have you checked for version specific instructions in UPGRADES.rst?\n" + "Have you checked for version specific instructions in" + " UPGRADES.rst?\n" ) sys.exit(1) @@ -249,7 +250,7 @@ def setup(): db_pool = hs.get_db_pool() - if db_name == ":memory:" + if db_name == ":memory:": # Memory databases will need to be setup each time they are opened. reactor.callWhenRunning( hs.get_db_pool().runWithConnection, prepare_database From 42529cbcedbea7c7f7347c793f113e2cbc7c73eb Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 19 Jan 2015 15:33:04 +0000 Subject: [PATCH 13/25] Fix pyflakes errors --- synapse/app/homeserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index f00b06aa7f..afe3d19760 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -253,7 +253,7 @@ def setup(): if db_name == ":memory:": # Memory databases will need to be setup each time they are opened. reactor.callWhenRunning( - hs.get_db_pool().runWithConnection, prepare_database + db_pool.runWithConnection, prepare_database ) if config.manhole: From dc70d1fef8c2f2f68c598c75e9808b6bed0873f6 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Mon, 19 Jan 2015 16:24:54 +0000 Subject: [PATCH 14/25] Only start the notifier timeout once we've had a chance to check for updates. Otherwise the timeout could fire while we are waiting for the database to return any updates it might have --- synapse/notifier.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/synapse/notifier.py b/synapse/notifier.py index b9d52d0c4c..3aec1d4af2 100644 --- a/synapse/notifier.py +++ b/synapse/notifier.py @@ -244,14 +244,14 @@ class Notifier(object): ) if timeout: - self.clock.call_later(timeout/1000.0, _timeout_listener) - self._register_with_keys(listener) yield self._check_for_updates(listener) if not timeout: _timeout_listener() + else: + self.clock.call_later(timeout/1000.0, _timeout_listener) return From dbe71e670c9f7068591b61f0975fdf5225a2cf3f Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Wed, 21 Jan 2015 16:58:16 +0000 Subject: [PATCH 15/25] Use common base class for two Presence unit-tests, avoiding boilerplate copypasta --- tests/handlers/test_presence.py | 79 +++++++++++---------------------- 1 file changed, 25 insertions(+), 54 deletions(-) diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py index b85a89052a..e96b73f977 100644 --- a/tests/handlers/test_presence.py +++ b/tests/handlers/test_presence.py @@ -59,23 +59,29 @@ class JustPresenceHandlers(object): def __init__(self, hs): self.presence_handler = PresenceHandler(hs) -class PresenceStateTestCase(unittest.TestCase): - """ Tests presence management. """ +class PresenceTestCase(unittest.TestCase): @defer.inlineCallbacks def setUp(self): db_pool = SQLiteMemoryDbPool() yield db_pool.prepare() + self.clock = MockClock() + self.mock_config = NonCallableMock() self.mock_config.signing_key = [MockKey()] + self.mock_federation_resource = MockHttpResource() + + self.mock_http_client = Mock(spec=[]) + self.mock_http_client.put_json = DeferredMockCallable() + hs = HomeServer("test", - clock=MockClock(), + clock=self.clock, db_pool=db_pool, handlers=None, - resource_for_federation=Mock(), - http_client=None, + resource_for_federation=self.mock_federation_resource, + http_client=self.mock_http_client, config=self.mock_config, keyring=Mock(), ) @@ -92,11 +98,19 @@ class PresenceStateTestCase(unittest.TestCase): self.u_banana = hs.parse_userid("@banana:test") self.u_clementine = hs.parse_userid("@clementine:test") - yield self.store.create_presence(self.u_apple.localpart) + for u in self.u_apple, self.u_banana, self.u_clementine: + yield self.store.create_presence(u.localpart) + yield self.store.set_presence_state( self.u_apple.localpart, {"state": ONLINE, "status_msg": "Online"} ) + # ID of a local user that does not exist + self.u_durian = hs.parse_userid("@durian:test") + + # A remote user + self.u_cabbage = hs.parse_userid("@cabbage:elsewhere") + self.handler = hs.get_handlers().presence_handler self.room_members = [] @@ -128,6 +142,10 @@ class PresenceStateTestCase(unittest.TestCase): self.handler.start_polling_presence = self.mock_start self.handler.stop_polling_presence = self.mock_stop + +class PresenceStateTestCase(PresenceTestCase): + """ Tests presence management. """ + @defer.inlineCallbacks def test_get_my_state(self): state = yield self.handler.get_state( @@ -206,56 +224,9 @@ class PresenceStateTestCase(unittest.TestCase): self.mock_stop.assert_called_with(self.u_apple) -class PresenceInvitesTestCase(unittest.TestCase): +class PresenceInvitesTestCase(PresenceTestCase): """ Tests presence management. """ - @defer.inlineCallbacks - def setUp(self): - self.mock_http_client = Mock(spec=[]) - self.mock_http_client.put_json = DeferredMockCallable() - - self.mock_federation_resource = MockHttpResource() - - db_pool = SQLiteMemoryDbPool() - yield db_pool.prepare() - - self.mock_config = NonCallableMock() - self.mock_config.signing_key = [MockKey()] - - hs = HomeServer("test", - clock=MockClock(), - db_pool=db_pool, - handlers=None, - resource_for_client=Mock(), - resource_for_federation=self.mock_federation_resource, - http_client=self.mock_http_client, - config=self.mock_config, - keyring=Mock(), - ) - hs.handlers = JustPresenceHandlers(hs) - - self.store = hs.get_datastore() - - # Some local users to test with - self.u_apple = hs.parse_userid("@apple:test") - self.u_banana = hs.parse_userid("@banana:test") - yield self.store.create_presence(self.u_apple.localpart) - yield self.store.create_presence(self.u_banana.localpart) - - # ID of a local user that does not exist - self.u_durian = hs.parse_userid("@durian:test") - - # A remote user - self.u_cabbage = hs.parse_userid("@cabbage:elsewhere") - - self.handler = hs.get_handlers().presence_handler - - self.mock_start = Mock() - self.mock_stop = Mock() - - self.handler.start_polling_presence = self.mock_start - self.handler.stop_polling_presence = self.mock_stop - @defer.inlineCallbacks def test_invite_local(self): # TODO(paul): This test will likely break if/when real auth permissions From 73315ce9de1612ad936b490fe164d9eb61a51b34 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Wed, 21 Jan 2015 20:01:57 +0000 Subject: [PATCH 16/25] Abstract out the room ID from presence tests, so it's stored in self --- tests/handlers/test_presence.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py index e96b73f977..c309fbb054 100644 --- a/tests/handlers/test_presence.py +++ b/tests/handlers/test_presence.py @@ -113,17 +113,18 @@ class PresenceTestCase(unittest.TestCase): self.handler = hs.get_handlers().presence_handler + self.room_id = "a-room" self.room_members = [] def get_rooms_for_user(user): if user in self.room_members: - return defer.succeed(["a-room"]) + return defer.succeed([self.room_id]) else: return defer.succeed([]) room_member_handler.get_rooms_for_user = get_rooms_for_user def get_room_members(room_id): - if room_id == "a-room": + if room_id == self.room_id: return defer.succeed(self.room_members) else: return defer.succeed([]) @@ -529,24 +530,25 @@ class PresencePushTestCase(unittest.TestCase): ]) self.room_member_handler = hs.handlers.room_member_handler + self.room_id = "a-room" self.room_members = [] def get_rooms_for_user(user): if user in self.room_members: - return defer.succeed(["a-room"]) + return defer.succeed([self.room_id]) else: return defer.succeed([]) self.room_member_handler.get_rooms_for_user = get_rooms_for_user def get_room_members(room_id): - if room_id == "a-room": + if room_id == self.room_id: return defer.succeed(self.room_members) else: return defer.succeed([]) self.room_member_handler.get_room_members = get_room_members def get_room_hosts(room_id): - if room_id == "a-room": + if room_id == self.room_id: hosts = set([u.domain for u in self.room_members]) return defer.succeed(hosts) else: @@ -882,7 +884,7 @@ class PresencePushTestCase(unittest.TestCase): ) yield self.distributor.fire("user_joined_room", self.u_clementine, - "a-room" + self.room_id ) self.room_members.append(self.u_clementine) @@ -945,7 +947,7 @@ class PresencePushTestCase(unittest.TestCase): self.room_members = [self.u_apple, self.u_banana] yield self.distributor.fire("user_joined_room", self.u_potato, - "a-room" + self.room_id ) yield put_json.await_calls() @@ -974,7 +976,7 @@ class PresencePushTestCase(unittest.TestCase): self.room_members.append(self.u_potato) yield self.distributor.fire("user_joined_room", self.u_clementine, - "a-room" + self.room_id ) put_json.await_calls() From f4ce61ed36e7b639550953882b6ea14171108784 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 15 Jan 2015 16:57:00 +0000 Subject: [PATCH 17/25] Move scripts into scripts --- UPGRADE.rst | 4 ++-- .../database-prepare-for-0.0.1.sh | 0 .../database-prepare-for-0.5.0.sh | 0 database-save.sh => scripts/database-save.sh | 0 nuke-room-from-db.sh => scripts/nuke-room-from-db.sh | 0 sphinx_api_docs.sh => scripts/sphinx_api_docs.sh | 0 6 files changed, 2 insertions(+), 2 deletions(-) rename database-prepare-for-0.0.1.sh => scripts/database-prepare-for-0.0.1.sh (100%) rename database-prepare-for-0.5.0.sh => scripts/database-prepare-for-0.5.0.sh (100%) rename database-save.sh => scripts/database-save.sh (100%) rename nuke-room-from-db.sh => scripts/nuke-room-from-db.sh (100%) rename sphinx_api_docs.sh => scripts/sphinx_api_docs.sh (100%) diff --git a/UPGRADE.rst b/UPGRADE.rst index 9618ad2d57..0f81f3e11f 100644 --- a/UPGRADE.rst +++ b/UPGRADE.rst @@ -52,7 +52,7 @@ resulting conflicts during the upgrade process. Before running the command the homeserver should be first completely shutdown. To run it, simply specify the location of the database, e.g.: - ./database-prepare-for-0.5.0.sh "homeserver.db" + ./scripts/database-prepare-for-0.5.0.sh "homeserver.db" Once this has successfully completed it will be safe to restart the homeserver. You may notice that the homeserver takes a few seconds longer to @@ -147,7 +147,7 @@ rooms the home server was a member of and room alias mappings. Before running the command the homeserver should be first completely shutdown. To run it, simply specify the location of the database, e.g.: - ./database-prepare-for-0.0.1.sh "homeserver.db" + ./scripts/database-prepare-for-0.0.1.sh "homeserver.db" Once this has successfully completed it will be safe to restart the homeserver. You may notice that the homeserver takes a few seconds longer to diff --git a/database-prepare-for-0.0.1.sh b/scripts/database-prepare-for-0.0.1.sh similarity index 100% rename from database-prepare-for-0.0.1.sh rename to scripts/database-prepare-for-0.0.1.sh diff --git a/database-prepare-for-0.5.0.sh b/scripts/database-prepare-for-0.5.0.sh similarity index 100% rename from database-prepare-for-0.5.0.sh rename to scripts/database-prepare-for-0.5.0.sh diff --git a/database-save.sh b/scripts/database-save.sh similarity index 100% rename from database-save.sh rename to scripts/database-save.sh diff --git a/nuke-room-from-db.sh b/scripts/nuke-room-from-db.sh similarity index 100% rename from nuke-room-from-db.sh rename to scripts/nuke-room-from-db.sh diff --git a/sphinx_api_docs.sh b/scripts/sphinx_api_docs.sh similarity index 100% rename from sphinx_api_docs.sh rename to scripts/sphinx_api_docs.sh From 8907e143c1a3378c7dced4048b165e38bb2b17fa Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 15 Jan 2015 16:51:52 +0000 Subject: [PATCH 18/25] Remove jsfiddles --- jsfiddles/create_room_send_msg/demo.css | 17 -- jsfiddles/create_room_send_msg/demo.html | 30 --- jsfiddles/create_room_send_msg/demo.js | 113 -------- jsfiddles/event_stream/demo.css | 17 -- jsfiddles/event_stream/demo.html | 23 -- jsfiddles/event_stream/demo.js | 145 ---------- jsfiddles/example_app/demo.css | 43 --- jsfiddles/example_app/demo.details | 7 - jsfiddles/example_app/demo.html | 56 ---- jsfiddles/example_app/demo.js | 327 ----------------------- jsfiddles/register_login/demo.css | 7 - jsfiddles/register_login/demo.html | 20 -- jsfiddles/register_login/demo.js | 79 ------ jsfiddles/room_memberships/demo.css | 17 -- jsfiddles/room_memberships/demo.html | 37 --- jsfiddles/room_memberships/demo.js | 141 ---------- 16 files changed, 1079 deletions(-) delete mode 100644 jsfiddles/create_room_send_msg/demo.css delete mode 100644 jsfiddles/create_room_send_msg/demo.html delete mode 100644 jsfiddles/create_room_send_msg/demo.js delete mode 100644 jsfiddles/event_stream/demo.css delete mode 100644 jsfiddles/event_stream/demo.html delete mode 100644 jsfiddles/event_stream/demo.js delete mode 100644 jsfiddles/example_app/demo.css delete mode 100644 jsfiddles/example_app/demo.details delete mode 100644 jsfiddles/example_app/demo.html delete mode 100644 jsfiddles/example_app/demo.js delete mode 100644 jsfiddles/register_login/demo.css delete mode 100644 jsfiddles/register_login/demo.html delete mode 100644 jsfiddles/register_login/demo.js delete mode 100644 jsfiddles/room_memberships/demo.css delete mode 100644 jsfiddles/room_memberships/demo.html delete mode 100644 jsfiddles/room_memberships/demo.js diff --git a/jsfiddles/create_room_send_msg/demo.css b/jsfiddles/create_room_send_msg/demo.css deleted file mode 100644 index 48a55f372d..0000000000 --- a/jsfiddles/create_room_send_msg/demo.css +++ /dev/null @@ -1,17 +0,0 @@ -.loggedin { - visibility: hidden; -} - -p { - font-family: monospace; -} - -table -{ - border-spacing:5px; -} - -th,td -{ - padding:5px; -} diff --git a/jsfiddles/create_room_send_msg/demo.html b/jsfiddles/create_room_send_msg/demo.html deleted file mode 100644 index 088ff7ac0f..0000000000 --- a/jsfiddles/create_room_send_msg/demo.html +++ /dev/null @@ -1,30 +0,0 @@ -
-

This room creation / message sending demo requires a home server to be running on http://localhost:8008

-
-
- - - -
-
-
- - -
-
- - - -
- - - - - - - - - -
Room IDMy stateRoom AliasLatest message
-
- diff --git a/jsfiddles/create_room_send_msg/demo.js b/jsfiddles/create_room_send_msg/demo.js deleted file mode 100644 index 9c346e2f64..0000000000 --- a/jsfiddles/create_room_send_msg/demo.js +++ /dev/null @@ -1,113 +0,0 @@ -var accountInfo = {}; - -var showLoggedIn = function(data) { - accountInfo = data; - getCurrentRoomList(); - $(".loggedin").css({visibility: "visible"}); -}; - -$('.login').live('click', function() { - var user = $("#userLogin").val(); - var password = $("#passwordLogin").val(); - $.ajax({ - url: "http://localhost:8008/_matrix/client/api/v1/login", - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify({ user: user, password: password, type: "m.login.password" }), - dataType: "json", - success: function(data) { - showLoggedIn(data); - }, - error: function(err) { - var errMsg = "To try this, you need a home server running!"; - var errJson = $.parseJSON(err.responseText); - if (errJson) { - errMsg = JSON.stringify(errJson); - } - alert(errMsg); - } - }); -}); - -var getCurrentRoomList = function() { - var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1"; - $.getJSON(url, function(data) { - var rooms = data.rooms; - for (var i=0; i 0) { - data.room_alias_name = roomAlias; - } - $.ajax({ - url: "http://localhost:8008/_matrix/client/api/v1/createRoom?access_token="+accountInfo.access_token, - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify(data), - dataType: "json", - success: function(data) { - data.membership = "join"; // you are automatically joined into every room you make. - data.latest_message = ""; - addRoom(data); - }, - error: function(err) { - alert(JSON.stringify($.parseJSON(err.responseText))); - } - }); -}); - -var addRoom = function(data) { - row = "" + - ""+data.room_id+"" + - ""+data.membership+"" + - ""+data.room_alias+"" + - ""+data.latest_message+"" + - ""; - $("#rooms").append(row); -}; - -$('.sendMessage').live('click', function() { - var roomId = $("#roomId").val(); - var body = $("#messageBody").val(); - var msgId = $.now(); - - if (roomId.length === 0 || body.length === 0) { - return; - } - - var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/send/m.room.message?access_token=$token"; - url = url.replace("$token", accountInfo.access_token); - url = url.replace("$roomid", encodeURIComponent(roomId)); - - var data = { - msgtype: "m.text", - body: body - }; - - $.ajax({ - url: url, - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify(data), - dataType: "json", - success: function(data) { - $("#messageBody").val(""); - // wipe the table and reload it. Using the event stream would be the best - // solution but that is out of scope of this fiddle. - $("#rooms").find("tr:gt(0)").remove(); - getCurrentRoomList(); - }, - error: function(err) { - alert(JSON.stringify($.parseJSON(err.responseText))); - } - }); -}); diff --git a/jsfiddles/event_stream/demo.css b/jsfiddles/event_stream/demo.css deleted file mode 100644 index 48a55f372d..0000000000 --- a/jsfiddles/event_stream/demo.css +++ /dev/null @@ -1,17 +0,0 @@ -.loggedin { - visibility: hidden; -} - -p { - font-family: monospace; -} - -table -{ - border-spacing:5px; -} - -th,td -{ - padding:5px; -} diff --git a/jsfiddles/event_stream/demo.html b/jsfiddles/event_stream/demo.html deleted file mode 100644 index 7657780d28..0000000000 --- a/jsfiddles/event_stream/demo.html +++ /dev/null @@ -1,23 +0,0 @@ -
-

This event stream demo requires a home server to be running on http://localhost:8008

-
-
- - - -
-
-
- -
-

- - - - - - - -
Room IDLatest message
-
- diff --git a/jsfiddles/event_stream/demo.js b/jsfiddles/event_stream/demo.js deleted file mode 100644 index acba8391fa..0000000000 --- a/jsfiddles/event_stream/demo.js +++ /dev/null @@ -1,145 +0,0 @@ -var accountInfo = {}; - -var eventStreamInfo = { - from: "END" -}; - -var roomInfo = []; - -var longpollEventStream = function() { - var url = "http://localhost:8008/_matrix/client/api/v1/events?access_token=$token&from=$from"; - url = url.replace("$token", accountInfo.access_token); - url = url.replace("$from", eventStreamInfo.from); - - $.getJSON(url, function(data) { - eventStreamInfo.from = data.end; - - var hasNewLatestMessage = false; - for (var i=0; i"+roomList[i].room_id+"" + - ""+roomList[i].latest_message+"" + - ""; - rows += row; - } - - $("#rooms").append(rows); -}; - diff --git a/jsfiddles/example_app/demo.css b/jsfiddles/example_app/demo.css deleted file mode 100644 index 4c1e157cc8..0000000000 --- a/jsfiddles/example_app/demo.css +++ /dev/null @@ -1,43 +0,0 @@ -.roomListDashboard, .roomContents, .sendMessageForm { - visibility: hidden; -} - -.roomList { - background-color: #909090; -} - -.messageWrapper { - background-color: #EEEEEE; - height: 400px; - overflow: scroll; -} - -.membersWrapper { - background-color: #EEEEEE; - height: 200px; - width: 50%; - overflow: scroll; -} - -.textEntry { - width: 100% -} - -p { - font-family: monospace; -} - -table -{ - border-spacing:5px; -} - -th,td -{ - padding:5px; -} - -.roomList tr:not(:first-child):hover { - background-color: orange; - cursor: pointer; -} diff --git a/jsfiddles/example_app/demo.details b/jsfiddles/example_app/demo.details deleted file mode 100644 index 3f96d3e744..0000000000 --- a/jsfiddles/example_app/demo.details +++ /dev/null @@ -1,7 +0,0 @@ - name: Example Matrix Client - description: Includes login, live event streaming, creating rooms, sending messages and viewing member lists. - authors: - - matrix.org - resources: - - http://matrix.org - normalize_css: no \ No newline at end of file diff --git a/jsfiddles/example_app/demo.html b/jsfiddles/example_app/demo.html deleted file mode 100644 index 7a9dffddd0..0000000000 --- a/jsfiddles/example_app/demo.html +++ /dev/null @@ -1,56 +0,0 @@ - - -
-
- - -
- - - - - - - - -
RoomMy stateLatest message
-
- -
-

Select a room

-
- - - -
-
-
- - -
-
- -
-

Member list:

-
- - - -
-
-
- diff --git a/jsfiddles/example_app/demo.js b/jsfiddles/example_app/demo.js deleted file mode 100644 index 13c9c2b339..0000000000 --- a/jsfiddles/example_app/demo.js +++ /dev/null @@ -1,327 +0,0 @@ -var accountInfo = {}; - -var eventStreamInfo = { - from: "END" -}; - -var roomInfo = []; -var memberInfo = []; -var viewingRoomId; - -// ************** Event Streaming ************** -var longpollEventStream = function() { - var url = "http://localhost:8008/_matrix/client/api/v1/events?access_token=$token&from=$from"; - url = url.replace("$token", accountInfo.access_token); - url = url.replace("$from", eventStreamInfo.from); - - $.getJSON(url, function(data) { - eventStreamInfo.from = data.end; - - var hasNewLatestMessage = false; - var updatedMemberList = false; - var i=0; - var j=0; - for (i=0; i 0) { - data.room_alias_name = roomAlias; - } - $.ajax({ - url: "http://localhost:8008/_matrix/client/api/v1/createRoom?access_token="+accountInfo.access_token, - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify(data), - dataType: "json", - success: function(response) { - $("#roomAlias").val(""); - response.membership = "join"; // you are automatically joined into every room you make. - response.latest_message = ""; - - roomInfo.push(response); - setRooms(roomInfo); - }, - error: function(err) { - alert(JSON.stringify($.parseJSON(err.responseText))); - } - }); -}); - -// ************** Getting current state ************** -var getCurrentRoomList = function() { - var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1"; - $.getJSON(url, function(data) { - var rooms = data.rooms; - for (var i=0; i=0; --i) { - addMessage(data.chunk[i]); - } - }); -}; - -var getMemberList = function(roomId) { - $("#members").empty(); - memberInfo = []; - var url = "http://localhost:8008/_matrix/client/api/v1/rooms/" + - encodeURIComponent(roomId) + "/members?access_token=" + accountInfo.access_token; - $.getJSON(url, function(data) { - for (var i=0; i"+roomList[i].room_id+"" + - ""+roomList[i].membership+"" + - ""+roomList[i].latest_message+"" + - ""; - rows += row; - } - - $("#rooms").append(rows); - - $('#rooms').find("tr").click(function(){ - var roomId = $(this).find('td:eq(0)').text(); - var membership = $(this).find('td:eq(1)').text(); - if (membership !== "join") { - console.log("Joining room " + roomId); - var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/join?access_token=$token"; - url = url.replace("$token", accountInfo.access_token); - url = url.replace("$roomid", encodeURIComponent(roomId)); - $.ajax({ - url: url, - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify({membership: "join"}), - dataType: "json", - success: function(data) { - loadRoomContent(roomId); - getCurrentRoomList(); - }, - error: function(err) { - alert(JSON.stringify($.parseJSON(err.responseText))); - } - }); - } - else { - loadRoomContent(roomId); - } - }); -}; - -var addMessage = function(data) { - - var msg = data.content.body; - if (data.type === "m.room.member") { - if (data.content.membership === undefined) { - return; - } - if (data.content.membership === "invite") { - msg = "invited " + data.state_key + " to the room"; - } - else if (data.content.membership === "join") { - msg = "joined the room"; - } - else if (data.content.membership === "leave") { - msg = "left the room"; - } - else if (data.content.membership === "ban") { - msg = "was banned from the room"; - } - } - if (msg === undefined) { - return; - } - - var row = "" + - ""+data.user_id+"" + - ""+msg+"" + - ""; - $("#messages").append(row); -}; - -var addMember = function(data) { - var row = "" + - ""+data.state_key+"" + - ""+data.content.membership+"" + - ""; - $("#members").append(row); -}; - diff --git a/jsfiddles/register_login/demo.css b/jsfiddles/register_login/demo.css deleted file mode 100644 index 11781c250f..0000000000 --- a/jsfiddles/register_login/demo.css +++ /dev/null @@ -1,7 +0,0 @@ -.loggedin { - visibility: hidden; -} - -p { - font-family: monospace; -} diff --git a/jsfiddles/register_login/demo.html b/jsfiddles/register_login/demo.html deleted file mode 100644 index fcac453ac2..0000000000 --- a/jsfiddles/register_login/demo.html +++ /dev/null @@ -1,20 +0,0 @@ -
-

This registration/login demo requires a home server to be running on http://localhost:8008

-
-
- - - -
-
- - - -
-
-

- - -

-
- diff --git a/jsfiddles/register_login/demo.js b/jsfiddles/register_login/demo.js deleted file mode 100644 index 2e6957b631..0000000000 --- a/jsfiddles/register_login/demo.js +++ /dev/null @@ -1,79 +0,0 @@ -var accountInfo = {}; - -var showLoggedIn = function(data) { - accountInfo = data; - $(".loggedin").css({visibility: "visible"}); - $("#welcomeText").text("Welcome " + accountInfo.user_id+". Your access token is: " + - accountInfo.access_token); -}; - -$('.register').live('click', function() { - var user = $("#user").val(); - var password = $("#password").val(); - $.ajax({ - url: "http://localhost:8008/_matrix/client/api/v1/register", - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify({ user: user, password: password, type: "m.login.password" }), - dataType: "json", - success: function(data) { - showLoggedIn(data); - }, - error: function(err) { - var errMsg = "To try this, you need a home server running!"; - var errJson = $.parseJSON(err.responseText); - if (errJson) { - errMsg = JSON.stringify(errJson); - } - alert(errMsg); - } - }); -}); - -var login = function(user, password) { - $.ajax({ - url: "http://localhost:8008/_matrix/client/api/v1/login", - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify({ user: user, password: password, type: "m.login.password" }), - dataType: "json", - success: function(data) { - showLoggedIn(data); - }, - error: function(err) { - var errMsg = "To try this, you need a home server running!"; - var errJson = $.parseJSON(err.responseText); - if (errJson) { - errMsg = JSON.stringify(errJson); - } - alert(errMsg); - } - }); -}; - -$('.login').live('click', function() { - var user = $("#userLogin").val(); - var password = $("#passwordLogin").val(); - $.getJSON("http://localhost:8008/_matrix/client/api/v1/login", function(data) { - if (data.flows[0].type !== "m.login.password") { - alert("I don't know how to login with this type: " + data.type); - return; - } - login(user, password); - }); -}); - -$('.logout').live('click', function() { - accountInfo = {}; - $("#imSyncText").text(""); - $(".loggedin").css({visibility: "hidden"}); -}); - -$('.testToken').live('click', function() { - var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1"; - $.getJSON(url, function(data) { - $("#imSyncText").text(JSON.stringify(data, undefined, 2)); - }).fail(function(err) { - $("#imSyncText").text(JSON.stringify($.parseJSON(err.responseText))); - }); -}); diff --git a/jsfiddles/room_memberships/demo.css b/jsfiddles/room_memberships/demo.css deleted file mode 100644 index 48a55f372d..0000000000 --- a/jsfiddles/room_memberships/demo.css +++ /dev/null @@ -1,17 +0,0 @@ -.loggedin { - visibility: hidden; -} - -p { - font-family: monospace; -} - -table -{ - border-spacing:5px; -} - -th,td -{ - padding:5px; -} diff --git a/jsfiddles/room_memberships/demo.html b/jsfiddles/room_memberships/demo.html deleted file mode 100644 index e6f39df5aa..0000000000 --- a/jsfiddles/room_memberships/demo.html +++ /dev/null @@ -1,37 +0,0 @@ -
-

This room membership demo requires a home server to be running on http://localhost:8008

-
-
- - - -
-
-
- -
-
- - - - -
-
- - -
- - - - - - - - -
Room IDMy stateRoom Alias
-
- diff --git a/jsfiddles/room_memberships/demo.js b/jsfiddles/room_memberships/demo.js deleted file mode 100644 index 8a7b1aa88e..0000000000 --- a/jsfiddles/room_memberships/demo.js +++ /dev/null @@ -1,141 +0,0 @@ -var accountInfo = {}; - -var showLoggedIn = function(data) { - accountInfo = data; - getCurrentRoomList(); - $(".loggedin").css({visibility: "visible"}); - $("#membership").change(function() { - if ($("#membership").val() === "invite") { - $("#targetUser").css({visibility: "visible"}); - } - else { - $("#targetUser").css({visibility: "hidden"}); - } -}); -}; - -$('.login').live('click', function() { - var user = $("#userLogin").val(); - var password = $("#passwordLogin").val(); - $.ajax({ - url: "http://localhost:8008/_matrix/client/api/v1/login", - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify({ user: user, password: password, type: "m.login.password" }), - dataType: "json", - success: function(data) { - $("#rooms").find("tr:gt(0)").remove(); - showLoggedIn(data); - }, - error: function(err) { - var errMsg = "To try this, you need a home server running!"; - var errJson = $.parseJSON(err.responseText); - if (errJson) { - errMsg = JSON.stringify(errJson); - } - alert(errMsg); - } - }); -}); - -var getCurrentRoomList = function() { - $("#roomId").val(""); - // wipe the table and reload it. Using the event stream would be the best - // solution but that is out of scope of this fiddle. - $("#rooms").find("tr:gt(0)").remove(); - - var url = "http://localhost:8008/_matrix/client/api/v1/initialSync?access_token=" + accountInfo.access_token + "&limit=1"; - $.getJSON(url, function(data) { - var rooms = data.rooms; - for (var i=0; i"+data.room_id+"" + - ""+data.membership+"" + - ""+data.room_alias+"" + - ""; - $("#rooms").append(row); -}; - -$('.changeMembership').live('click', function() { - var roomId = $("#roomId").val(); - var member = $("#targetUser").val(); - var membership = $("#membership").val(); - - if (roomId.length === 0) { - return; - } - - var url = "http://localhost:8008/_matrix/client/api/v1/rooms/$roomid/$membership?access_token=$token"; - url = url.replace("$token", accountInfo.access_token); - url = url.replace("$roomid", encodeURIComponent(roomId)); - url = url.replace("$membership", membership); - - var data = {}; - - if (membership === "invite") { - data = { - user_id: member - }; - } - - $.ajax({ - url: url, - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify(data), - dataType: "json", - success: function(data) { - getCurrentRoomList(); - }, - error: function(err) { - alert(JSON.stringify($.parseJSON(err.responseText))); - } - }); -}); - -$('.joinAlias').live('click', function() { - var roomAlias = $("#roomAlias").val(); - var url = "http://localhost:8008/_matrix/client/api/v1/join/$roomalias?access_token=$token"; - url = url.replace("$token", accountInfo.access_token); - url = url.replace("$roomalias", encodeURIComponent(roomAlias)); - $.ajax({ - url: url, - type: "POST", - contentType: "application/json; charset=utf-8", - data: JSON.stringify({}), - dataType: "json", - success: function(data) { - getCurrentRoomList(); - }, - error: function(err) { - alert(JSON.stringify($.parseJSON(err.responseText))); - } - }); -}); From d3d0713de587c97c3c23200a15215eb0807ff87e Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 15 Jan 2015 17:06:12 +0000 Subject: [PATCH 19/25] Move experiments, graph and cmdclient into contrib --- {cmdclient => contrib/cmdclient}/console.py | 0 {cmdclient => contrib/cmdclient}/http.py | 0 {experiments => contrib/experiments}/cursesio.py | 0 {experiments => contrib/experiments}/test_messaging.py | 0 {graph => contrib/graph}/graph.py | 0 {graph => contrib/graph}/graph2.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {cmdclient => contrib/cmdclient}/console.py (100%) rename {cmdclient => contrib/cmdclient}/http.py (100%) rename {experiments => contrib/experiments}/cursesio.py (100%) rename {experiments => contrib/experiments}/test_messaging.py (100%) rename {graph => contrib/graph}/graph.py (100%) rename {graph => contrib/graph}/graph2.py (100%) diff --git a/cmdclient/console.py b/contrib/cmdclient/console.py similarity index 100% rename from cmdclient/console.py rename to contrib/cmdclient/console.py diff --git a/cmdclient/http.py b/contrib/cmdclient/http.py similarity index 100% rename from cmdclient/http.py rename to contrib/cmdclient/http.py diff --git a/experiments/cursesio.py b/contrib/experiments/cursesio.py similarity index 100% rename from experiments/cursesio.py rename to contrib/experiments/cursesio.py diff --git a/experiments/test_messaging.py b/contrib/experiments/test_messaging.py similarity index 100% rename from experiments/test_messaging.py rename to contrib/experiments/test_messaging.py diff --git a/graph/graph.py b/contrib/graph/graph.py similarity index 100% rename from graph/graph.py rename to contrib/graph/graph.py diff --git a/graph/graph2.py b/contrib/graph/graph2.py similarity index 100% rename from graph/graph2.py rename to contrib/graph/graph2.py From 58691680b8dd93fab56fed914b0204f2b6751b6a Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Jan 2015 14:20:53 +0000 Subject: [PATCH 20/25] update .gitignore, set media-store-path in demo --- .gitignore | 11 +++-------- demo/start.sh | 3 ++- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index af90668c89..2ed22b1cd3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,17 +26,12 @@ htmlcov demo/*.db demo/*.log +demo/*.log.* demo/*.pid +demo/media_store.* demo/etc -graph/*.svg -graph/*.png -graph/*.dot - -**/webclient/config.js -**/webclient/test/coverage/ -**/webclient/test/environment-protractor.js - uploads .idea/ +media_store/ diff --git a/demo/start.sh b/demo/start.sh index ce3e292486..bb2248770d 100755 --- a/demo/start.sh +++ b/demo/start.sh @@ -32,7 +32,8 @@ for port in 8080 8081 8082; do -D --pid-file "$DIR/$port.pid" \ --manhole $((port + 1000)) \ --tls-dh-params-path "demo/demo.tls.dh" \ - $PARAMS $SYNAPSE_PARAMS + --media-store-path "demo/media_store.$port" \ + $PARAMS $SYNAPSE_PARAMS \ python -m synapse.app.homeserver \ --config-path "demo/etc/$port.config" \ From d00cca11b961f59c590956691b750eb082160edc Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Jan 2015 14:28:07 +0000 Subject: [PATCH 21/25] Add demo and scripts to python manifest --- MANIFEST.in | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index a1a77ff540..7979ec0809 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,13 @@ -recursive-include docs * -recursive-include tests *.py +include synctl +include LICENSE +include VERSION +include *.rst + recursive-include synapse/storage/schema *.sql -recursive-include syweb/webclient * + +recursive-include demo *.dh +recursive-include demo *.py +recursive-include demo *.sh +recursive-include docs * +recursive-include scripts * +recursive-include tests *.py From 16bfabb9c51e4721851a5d3220d5b78cff4d7892 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Jan 2015 14:32:51 +0000 Subject: [PATCH 22/25] Fix manifest. Ignore contrib and docs directories when checking manifest against source control. --- MANIFEST.in | 1 + setup.cfg | 8 ++++++++ tests/storage/TESTS_NEEDED_FOR | 5 ----- 3 files changed, 9 insertions(+), 5 deletions(-) delete mode 100644 tests/storage/TESTS_NEEDED_FOR diff --git a/MANIFEST.in b/MANIFEST.in index 7979ec0809..8243a942ee 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,6 +2,7 @@ include synctl include LICENSE include VERSION include *.rst +include demo/README recursive-include synapse/storage/schema *.sql diff --git a/setup.cfg b/setup.cfg index 2830831f00..888ad6ed4a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,3 +8,11 @@ test = trial [trial] test_suite = tests + +[check-manifest] +ignore = + contrib + contrib/* + docs/* + pylint.cfg + tox.ini diff --git a/tests/storage/TESTS_NEEDED_FOR b/tests/storage/TESTS_NEEDED_FOR deleted file mode 100644 index 8e5d0cbdc4..0000000000 --- a/tests/storage/TESTS_NEEDED_FOR +++ /dev/null @@ -1,5 +0,0 @@ -synapse/storage/feedback.py -synapse/storage/keys.py -synapse/storage/pdu.py -synapse/storage/stream.py -synapse/storage/transactions.py From 1d2016b4a881538aa86f4824f1131dfada186ae0 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Jan 2015 14:59:08 +0000 Subject: [PATCH 23/25] Move client v1 api rest servlets into a "client/v1" directory --- synapse/client/__init__.py | 14 ++++++++++++++ synapse/{rest => client/v1}/__init__.py | 0 synapse/{rest => client/v1}/admin.py | 0 synapse/{rest => client/v1}/base.py | 2 +- synapse/{rest => client/v1}/directory.py | 0 synapse/{rest => client/v1}/events.py | 2 +- synapse/{rest => client/v1}/initial_sync.py | 0 synapse/{rest => client/v1}/login.py | 0 synapse/{rest => client/v1}/presence.py | 0 synapse/{rest => client/v1}/profile.py | 0 synapse/{rest => client/v1}/register.py | 0 synapse/{rest => client/v1}/room.py | 0 synapse/{rest => client/v1}/transactions.py | 0 synapse/{rest => client/v1}/voip.py | 0 synapse/server.py | 2 +- tests/client/__init__.py | 14 ++++++++++++++ tests/{rest => client/v1}/__init__.py | 0 tests/{rest => client/v1}/test_events.py | 14 +++++++------- tests/{rest => client/v1}/test_presence.py | 2 +- tests/{rest => client/v1}/test_profile.py | 2 +- tests/{rest => client/v1}/test_rooms.py | 18 +++++++++--------- tests/{rest => client/v1}/test_typing.py | 6 +++--- tests/{rest => client/v1}/utils.py | 0 23 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 synapse/client/__init__.py rename synapse/{rest => client/v1}/__init__.py (100%) rename synapse/{rest => client/v1}/admin.py (100%) rename synapse/{rest => client/v1}/base.py (97%) rename synapse/{rest => client/v1}/directory.py (100%) rename synapse/{rest => client/v1}/events.py (97%) rename synapse/{rest => client/v1}/initial_sync.py (100%) rename synapse/{rest => client/v1}/login.py (100%) rename synapse/{rest => client/v1}/presence.py (100%) rename synapse/{rest => client/v1}/profile.py (100%) rename synapse/{rest => client/v1}/register.py (100%) rename synapse/{rest => client/v1}/room.py (100%) rename synapse/{rest => client/v1}/transactions.py (100%) rename synapse/{rest => client/v1}/voip.py (100%) create mode 100644 tests/client/__init__.py rename tests/{rest => client/v1}/__init__.py (100%) rename tests/{rest => client/v1}/test_events.py (94%) rename tests/{rest => client/v1}/test_presence.py (99%) rename tests/{rest => client/v1}/test_profile.py (99%) rename tests/{rest => client/v1}/test_rooms.py (98%) rename tests/{rest => client/v1}/test_typing.py (96%) rename tests/{rest => client/v1}/utils.py (100%) diff --git a/synapse/client/__init__.py b/synapse/client/__init__.py new file mode 100644 index 0000000000..1a84d94cd9 --- /dev/null +++ b/synapse/client/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/synapse/rest/__init__.py b/synapse/client/v1/__init__.py similarity index 100% rename from synapse/rest/__init__.py rename to synapse/client/v1/__init__.py diff --git a/synapse/rest/admin.py b/synapse/client/v1/admin.py similarity index 100% rename from synapse/rest/admin.py rename to synapse/client/v1/admin.py diff --git a/synapse/rest/base.py b/synapse/client/v1/base.py similarity index 97% rename from synapse/rest/base.py rename to synapse/client/v1/base.py index c583945527..d005206b77 100644 --- a/synapse/rest/base.py +++ b/synapse/client/v1/base.py @@ -15,7 +15,7 @@ """ This module contains base REST classes for constructing REST servlets. """ from synapse.api.urls import CLIENT_PREFIX -from synapse.rest.transactions import HttpTransactionStore +from .transactions import HttpTransactionStore import re import logging diff --git a/synapse/rest/directory.py b/synapse/client/v1/directory.py similarity index 100% rename from synapse/rest/directory.py rename to synapse/client/v1/directory.py diff --git a/synapse/rest/events.py b/synapse/client/v1/events.py similarity index 97% rename from synapse/rest/events.py rename to synapse/client/v1/events.py index bedcb2bcc6..c2515528ac 100644 --- a/synapse/rest/events.py +++ b/synapse/client/v1/events.py @@ -18,7 +18,7 @@ from twisted.internet import defer from synapse.api.errors import SynapseError from synapse.streams.config import PaginationConfig -from synapse.rest.base import RestServlet, client_path_pattern +from .base import RestServlet, client_path_pattern import logging diff --git a/synapse/rest/initial_sync.py b/synapse/client/v1/initial_sync.py similarity index 100% rename from synapse/rest/initial_sync.py rename to synapse/client/v1/initial_sync.py diff --git a/synapse/rest/login.py b/synapse/client/v1/login.py similarity index 100% rename from synapse/rest/login.py rename to synapse/client/v1/login.py diff --git a/synapse/rest/presence.py b/synapse/client/v1/presence.py similarity index 100% rename from synapse/rest/presence.py rename to synapse/client/v1/presence.py diff --git a/synapse/rest/profile.py b/synapse/client/v1/profile.py similarity index 100% rename from synapse/rest/profile.py rename to synapse/client/v1/profile.py diff --git a/synapse/rest/register.py b/synapse/client/v1/register.py similarity index 100% rename from synapse/rest/register.py rename to synapse/client/v1/register.py diff --git a/synapse/rest/room.py b/synapse/client/v1/room.py similarity index 100% rename from synapse/rest/room.py rename to synapse/client/v1/room.py diff --git a/synapse/rest/transactions.py b/synapse/client/v1/transactions.py similarity index 100% rename from synapse/rest/transactions.py rename to synapse/client/v1/transactions.py diff --git a/synapse/rest/voip.py b/synapse/client/v1/voip.py similarity index 100% rename from synapse/rest/voip.py rename to synapse/client/v1/voip.py diff --git a/synapse/server.py b/synapse/server.py index d861efd2fd..57a95bf753 100644 --- a/synapse/server.py +++ b/synapse/server.py @@ -24,7 +24,7 @@ from synapse.events.utils import serialize_event from synapse.notifier import Notifier from synapse.api.auth import Auth from synapse.handlers import Handlers -from synapse.rest import RestServletFactory +from synapse.client.v1 import RestServletFactory from synapse.state import StateHandler from synapse.storage import DataStore from synapse.types import UserID, RoomAlias, RoomID, EventID diff --git a/tests/client/__init__.py b/tests/client/__init__.py new file mode 100644 index 0000000000..1a84d94cd9 --- /dev/null +++ b/tests/client/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/rest/__init__.py b/tests/client/v1/__init__.py similarity index 100% rename from tests/rest/__init__.py rename to tests/client/v1/__init__.py diff --git a/tests/rest/test_events.py b/tests/client/v1/test_events.py similarity index 94% rename from tests/rest/test_events.py rename to tests/client/v1/test_events.py index d3159e2cf4..9b36dd3225 100644 --- a/tests/rest/test_events.py +++ b/tests/client/v1/test_events.py @@ -19,13 +19,13 @@ from tests import unittest # twisted imports from twisted.internet import defer -import synapse.rest.events -import synapse.rest.register -import synapse.rest.room +import synapse.client.v1.events +import synapse.client.v1.register +import synapse.client.v1.room from synapse.server import HomeServer -from ..utils import MockHttpResource, SQLiteMemoryDbPool, MockKey +from ...utils import MockHttpResource, SQLiteMemoryDbPool, MockKey from .utils import RestTestCase from mock import Mock, NonCallableMock @@ -144,9 +144,9 @@ class EventStreamPermissionsTestCase(RestTestCase): hs.get_clock().time_msec.return_value = 1000000 hs.get_clock().time.return_value = 1000 - synapse.rest.register.register_servlets(hs, self.mock_resource) - synapse.rest.events.register_servlets(hs, self.mock_resource) - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.register.register_servlets(hs, self.mock_resource) + synapse.client.v1.events.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) # register an account self.user_id = "sid1" diff --git a/tests/rest/test_presence.py b/tests/client/v1/test_presence.py similarity index 99% rename from tests/rest/test_presence.py rename to tests/client/v1/test_presence.py index 769c7824bc..e7d636c74d 100644 --- a/tests/rest/test_presence.py +++ b/tests/client/v1/test_presence.py @@ -20,7 +20,7 @@ from twisted.internet import defer from mock import Mock -from ..utils import MockHttpResource, MockKey +from ...utils import MockHttpResource, MockKey from synapse.api.constants import PresenceState from synapse.handlers.presence import PresenceHandler diff --git a/tests/rest/test_profile.py b/tests/client/v1/test_profile.py similarity index 99% rename from tests/rest/test_profile.py rename to tests/client/v1/test_profile.py index 3a0d1e700a..1182cc54eb 100644 --- a/tests/rest/test_profile.py +++ b/tests/client/v1/test_profile.py @@ -20,7 +20,7 @@ from twisted.internet import defer from mock import Mock, NonCallableMock -from ..utils import MockHttpResource, MockKey +from ...utils import MockHttpResource, MockKey from synapse.api.errors import SynapseError, AuthError from synapse.server import HomeServer diff --git a/tests/rest/test_rooms.py b/tests/client/v1/test_rooms.py similarity index 98% rename from tests/rest/test_rooms.py rename to tests/client/v1/test_rooms.py index 8e65ff9a1c..33a8631d76 100644 --- a/tests/rest/test_rooms.py +++ b/tests/client/v1/test_rooms.py @@ -18,7 +18,7 @@ # twisted imports from twisted.internet import defer -import synapse.rest.room +import synapse.client.v1.room from synapse.api.constants import Membership from synapse.server import HomeServer @@ -30,7 +30,7 @@ import json import urllib import types -from ..utils import MockHttpResource, SQLiteMemoryDbPool, MockKey +from ...utils import MockHttpResource, SQLiteMemoryDbPool, MockKey from .utils import RestTestCase from mock import Mock, NonCallableMock @@ -82,7 +82,7 @@ class RoomPermissionsTestCase(RestTestCase): self.auth_user_id = self.rmcreator_id - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) self.auth = hs.get_auth() @@ -476,7 +476,7 @@ class RoomsMemberListTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) def tearDown(self): pass @@ -565,7 +565,7 @@ class RoomsCreateTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) def tearDown(self): pass @@ -668,7 +668,7 @@ class RoomTopicTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) # create the room self.room_id = yield self.create_room_as(self.user_id) @@ -783,7 +783,7 @@ class RoomMemberStateTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) self.room_id = yield self.create_room_as(self.user_id) @@ -919,7 +919,7 @@ class RoomMessagesTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) self.room_id = yield self.create_room_as(self.user_id) @@ -1023,7 +1023,7 @@ class RoomInitialSyncTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) # Since I'm getting my own presence I need to exist as far as presence # is concerned. diff --git a/tests/rest/test_typing.py b/tests/client/v1/test_typing.py similarity index 96% rename from tests/rest/test_typing.py rename to tests/client/v1/test_typing.py index 18138af1b5..d6d677bde3 100644 --- a/tests/rest/test_typing.py +++ b/tests/client/v1/test_typing.py @@ -18,10 +18,10 @@ # twisted imports from twisted.internet import defer -import synapse.rest.room +import synapse.client.v1.room from synapse.server import HomeServer -from ..utils import MockHttpResource, MockClock, SQLiteMemoryDbPool, MockKey +from ...utils import MockHttpResource, MockClock, SQLiteMemoryDbPool, MockKey from .utils import RestTestCase from mock import Mock, NonCallableMock @@ -104,7 +104,7 @@ class RoomTypingTestCase(RestTestCase): hs.get_handlers().room_member_handler.fetch_room_distributions_into = ( fetch_room_distributions_into) - synapse.rest.room.register_servlets(hs, self.mock_resource) + synapse.client.v1.room.register_servlets(hs, self.mock_resource) self.room_id = yield self.create_room_as(self.user_id) # Need another user to make notifications actually work diff --git a/tests/rest/utils.py b/tests/client/v1/utils.py similarity index 100% rename from tests/rest/utils.py rename to tests/client/v1/utils.py From 97c68c508dac6b4b3203b3bc475ffdfd185b6e03 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Jan 2015 16:10:07 +0000 Subject: [PATCH 24/25] Move rest APIs back under the rest directory --- synapse/app/homeserver.py | 4 ++-- synapse/{client => rest}/__init__.py | 0 synapse/rest/client/__init__.py | 14 ++++++++++++++ synapse/{ => rest}/client/v1/__init__.py | 0 synapse/{ => rest}/client/v1/admin.py | 0 synapse/{ => rest}/client/v1/base.py | 0 synapse/{ => rest}/client/v1/directory.py | 0 synapse/{ => rest}/client/v1/events.py | 0 synapse/{ => rest}/client/v1/initial_sync.py | 0 synapse/{ => rest}/client/v1/login.py | 0 synapse/{ => rest}/client/v1/presence.py | 0 synapse/{ => rest}/client/v1/profile.py | 0 synapse/{ => rest}/client/v1/register.py | 0 synapse/{ => rest}/client/v1/room.py | 0 synapse/{ => rest}/client/v1/transactions.py | 0 synapse/{ => rest}/client/v1/voip.py | 0 synapse/{ => rest}/media/__init__.py | 0 synapse/{ => rest}/media/v0/__init__.py | 0 .../{ => rest}/media/v0/content_repository.py | 0 synapse/{ => rest}/media/v1/__init__.py | 0 synapse/{ => rest}/media/v1/base_resource.py | 0 synapse/{ => rest}/media/v1/download_resource.py | 0 synapse/{ => rest}/media/v1/filepath.py | 0 synapse/{ => rest}/media/v1/media_repository.py | 0 .../{ => rest}/media/v1/thumbnail_resource.py | 0 synapse/{ => rest}/media/v1/thumbnailer.py | 0 synapse/{ => rest}/media/v1/upload_resource.py | 0 synapse/server.py | 2 +- tests/client/v1/test_events.py | 12 ++++++------ tests/client/v1/test_rooms.py | 16 ++++++++-------- tests/client/v1/test_typing.py | 4 ++-- 31 files changed, 33 insertions(+), 19 deletions(-) rename synapse/{client => rest}/__init__.py (100%) create mode 100644 synapse/rest/client/__init__.py rename synapse/{ => rest}/client/v1/__init__.py (100%) rename synapse/{ => rest}/client/v1/admin.py (100%) rename synapse/{ => rest}/client/v1/base.py (100%) rename synapse/{ => rest}/client/v1/directory.py (100%) rename synapse/{ => rest}/client/v1/events.py (100%) rename synapse/{ => rest}/client/v1/initial_sync.py (100%) rename synapse/{ => rest}/client/v1/login.py (100%) rename synapse/{ => rest}/client/v1/presence.py (100%) rename synapse/{ => rest}/client/v1/profile.py (100%) rename synapse/{ => rest}/client/v1/register.py (100%) rename synapse/{ => rest}/client/v1/room.py (100%) rename synapse/{ => rest}/client/v1/transactions.py (100%) rename synapse/{ => rest}/client/v1/voip.py (100%) rename synapse/{ => rest}/media/__init__.py (100%) rename synapse/{ => rest}/media/v0/__init__.py (100%) rename synapse/{ => rest}/media/v0/content_repository.py (100%) rename synapse/{ => rest}/media/v1/__init__.py (100%) rename synapse/{ => rest}/media/v1/base_resource.py (100%) rename synapse/{ => rest}/media/v1/download_resource.py (100%) rename synapse/{ => rest}/media/v1/filepath.py (100%) rename synapse/{ => rest}/media/v1/media_repository.py (100%) rename synapse/{ => rest}/media/v1/thumbnail_resource.py (100%) rename synapse/{ => rest}/media/v1/thumbnailer.py (100%) rename synapse/{ => rest}/media/v1/upload_resource.py (100%) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index afe3d19760..cd24bbdc79 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -26,8 +26,8 @@ from twisted.web.resource import Resource from twisted.web.static import File from twisted.web.server import Site from synapse.http.server import JsonResource, RootRedirect -from synapse.media.v0.content_repository import ContentRepoResource -from synapse.media.v1.media_repository import MediaRepositoryResource +from synapse.rest.media.v0.content_repository import ContentRepoResource +from synapse.rest.media.v1.media_repository import MediaRepositoryResource from synapse.http.server_key_resource import LocalKey from synapse.http.matrixfederationclient import MatrixFederationHttpClient from synapse.api.urls import ( diff --git a/synapse/client/__init__.py b/synapse/rest/__init__.py similarity index 100% rename from synapse/client/__init__.py rename to synapse/rest/__init__.py diff --git a/synapse/rest/client/__init__.py b/synapse/rest/client/__init__.py new file mode 100644 index 0000000000..1a84d94cd9 --- /dev/null +++ b/synapse/rest/client/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/synapse/client/v1/__init__.py b/synapse/rest/client/v1/__init__.py similarity index 100% rename from synapse/client/v1/__init__.py rename to synapse/rest/client/v1/__init__.py diff --git a/synapse/client/v1/admin.py b/synapse/rest/client/v1/admin.py similarity index 100% rename from synapse/client/v1/admin.py rename to synapse/rest/client/v1/admin.py diff --git a/synapse/client/v1/base.py b/synapse/rest/client/v1/base.py similarity index 100% rename from synapse/client/v1/base.py rename to synapse/rest/client/v1/base.py diff --git a/synapse/client/v1/directory.py b/synapse/rest/client/v1/directory.py similarity index 100% rename from synapse/client/v1/directory.py rename to synapse/rest/client/v1/directory.py diff --git a/synapse/client/v1/events.py b/synapse/rest/client/v1/events.py similarity index 100% rename from synapse/client/v1/events.py rename to synapse/rest/client/v1/events.py diff --git a/synapse/client/v1/initial_sync.py b/synapse/rest/client/v1/initial_sync.py similarity index 100% rename from synapse/client/v1/initial_sync.py rename to synapse/rest/client/v1/initial_sync.py diff --git a/synapse/client/v1/login.py b/synapse/rest/client/v1/login.py similarity index 100% rename from synapse/client/v1/login.py rename to synapse/rest/client/v1/login.py diff --git a/synapse/client/v1/presence.py b/synapse/rest/client/v1/presence.py similarity index 100% rename from synapse/client/v1/presence.py rename to synapse/rest/client/v1/presence.py diff --git a/synapse/client/v1/profile.py b/synapse/rest/client/v1/profile.py similarity index 100% rename from synapse/client/v1/profile.py rename to synapse/rest/client/v1/profile.py diff --git a/synapse/client/v1/register.py b/synapse/rest/client/v1/register.py similarity index 100% rename from synapse/client/v1/register.py rename to synapse/rest/client/v1/register.py diff --git a/synapse/client/v1/room.py b/synapse/rest/client/v1/room.py similarity index 100% rename from synapse/client/v1/room.py rename to synapse/rest/client/v1/room.py diff --git a/synapse/client/v1/transactions.py b/synapse/rest/client/v1/transactions.py similarity index 100% rename from synapse/client/v1/transactions.py rename to synapse/rest/client/v1/transactions.py diff --git a/synapse/client/v1/voip.py b/synapse/rest/client/v1/voip.py similarity index 100% rename from synapse/client/v1/voip.py rename to synapse/rest/client/v1/voip.py diff --git a/synapse/media/__init__.py b/synapse/rest/media/__init__.py similarity index 100% rename from synapse/media/__init__.py rename to synapse/rest/media/__init__.py diff --git a/synapse/media/v0/__init__.py b/synapse/rest/media/v0/__init__.py similarity index 100% rename from synapse/media/v0/__init__.py rename to synapse/rest/media/v0/__init__.py diff --git a/synapse/media/v0/content_repository.py b/synapse/rest/media/v0/content_repository.py similarity index 100% rename from synapse/media/v0/content_repository.py rename to synapse/rest/media/v0/content_repository.py diff --git a/synapse/media/v1/__init__.py b/synapse/rest/media/v1/__init__.py similarity index 100% rename from synapse/media/v1/__init__.py rename to synapse/rest/media/v1/__init__.py diff --git a/synapse/media/v1/base_resource.py b/synapse/rest/media/v1/base_resource.py similarity index 100% rename from synapse/media/v1/base_resource.py rename to synapse/rest/media/v1/base_resource.py diff --git a/synapse/media/v1/download_resource.py b/synapse/rest/media/v1/download_resource.py similarity index 100% rename from synapse/media/v1/download_resource.py rename to synapse/rest/media/v1/download_resource.py diff --git a/synapse/media/v1/filepath.py b/synapse/rest/media/v1/filepath.py similarity index 100% rename from synapse/media/v1/filepath.py rename to synapse/rest/media/v1/filepath.py diff --git a/synapse/media/v1/media_repository.py b/synapse/rest/media/v1/media_repository.py similarity index 100% rename from synapse/media/v1/media_repository.py rename to synapse/rest/media/v1/media_repository.py diff --git a/synapse/media/v1/thumbnail_resource.py b/synapse/rest/media/v1/thumbnail_resource.py similarity index 100% rename from synapse/media/v1/thumbnail_resource.py rename to synapse/rest/media/v1/thumbnail_resource.py diff --git a/synapse/media/v1/thumbnailer.py b/synapse/rest/media/v1/thumbnailer.py similarity index 100% rename from synapse/media/v1/thumbnailer.py rename to synapse/rest/media/v1/thumbnailer.py diff --git a/synapse/media/v1/upload_resource.py b/synapse/rest/media/v1/upload_resource.py similarity index 100% rename from synapse/media/v1/upload_resource.py rename to synapse/rest/media/v1/upload_resource.py diff --git a/synapse/server.py b/synapse/server.py index 57a95bf753..e9add8e2b4 100644 --- a/synapse/server.py +++ b/synapse/server.py @@ -24,7 +24,7 @@ from synapse.events.utils import serialize_event from synapse.notifier import Notifier from synapse.api.auth import Auth from synapse.handlers import Handlers -from synapse.client.v1 import RestServletFactory +from synapse.rest.client.v1 import RestServletFactory from synapse.state import StateHandler from synapse.storage import DataStore from synapse.types import UserID, RoomAlias, RoomID, EventID diff --git a/tests/client/v1/test_events.py b/tests/client/v1/test_events.py index 9b36dd3225..e914b05a52 100644 --- a/tests/client/v1/test_events.py +++ b/tests/client/v1/test_events.py @@ -19,9 +19,9 @@ from tests import unittest # twisted imports from twisted.internet import defer -import synapse.client.v1.events -import synapse.client.v1.register -import synapse.client.v1.room +import synapse.rest.client.v1.events +import synapse.rest.client.v1.register +import synapse.rest.client.v1.room from synapse.server import HomeServer @@ -144,9 +144,9 @@ class EventStreamPermissionsTestCase(RestTestCase): hs.get_clock().time_msec.return_value = 1000000 hs.get_clock().time.return_value = 1000 - synapse.client.v1.register.register_servlets(hs, self.mock_resource) - synapse.client.v1.events.register_servlets(hs, self.mock_resource) - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.register.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.events.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) # register an account self.user_id = "sid1" diff --git a/tests/client/v1/test_rooms.py b/tests/client/v1/test_rooms.py index 33a8631d76..4d529ef007 100644 --- a/tests/client/v1/test_rooms.py +++ b/tests/client/v1/test_rooms.py @@ -18,7 +18,7 @@ # twisted imports from twisted.internet import defer -import synapse.client.v1.room +import synapse.rest.client.v1.room from synapse.api.constants import Membership from synapse.server import HomeServer @@ -82,7 +82,7 @@ class RoomPermissionsTestCase(RestTestCase): self.auth_user_id = self.rmcreator_id - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) self.auth = hs.get_auth() @@ -476,7 +476,7 @@ class RoomsMemberListTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) def tearDown(self): pass @@ -565,7 +565,7 @@ class RoomsCreateTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) def tearDown(self): pass @@ -668,7 +668,7 @@ class RoomTopicTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) # create the room self.room_id = yield self.create_room_as(self.user_id) @@ -783,7 +783,7 @@ class RoomMemberStateTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) self.room_id = yield self.create_room_as(self.user_id) @@ -919,7 +919,7 @@ class RoomMessagesTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) self.room_id = yield self.create_room_as(self.user_id) @@ -1023,7 +1023,7 @@ class RoomInitialSyncTestCase(RestTestCase): return defer.succeed(None) hs.get_datastore().insert_client_ip = _insert_client_ip - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) # Since I'm getting my own presence I need to exist as far as presence # is concerned. diff --git a/tests/client/v1/test_typing.py b/tests/client/v1/test_typing.py index d6d677bde3..af3a9a6c1c 100644 --- a/tests/client/v1/test_typing.py +++ b/tests/client/v1/test_typing.py @@ -18,7 +18,7 @@ # twisted imports from twisted.internet import defer -import synapse.client.v1.room +import synapse.rest.client.v1.room from synapse.server import HomeServer from ...utils import MockHttpResource, MockClock, SQLiteMemoryDbPool, MockKey @@ -104,7 +104,7 @@ class RoomTypingTestCase(RestTestCase): hs.get_handlers().room_member_handler.fetch_room_distributions_into = ( fetch_room_distributions_into) - synapse.client.v1.room.register_servlets(hs, self.mock_resource) + synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource) self.room_id = yield self.create_room_as(self.user_id) # Need another user to make notifications actually work From 53584420a50d09b40f3235d8e4c033009e8eb0da Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Jan 2015 16:13:27 +0000 Subject: [PATCH 25/25] Move client rest tests back under rest --- tests/{client => rest}/__init__.py | 0 tests/rest/client/__init__.py | 14 ++++++++++++++ tests/{ => rest}/client/v1/__init__.py | 0 tests/{ => rest}/client/v1/test_events.py | 2 +- tests/{ => rest}/client/v1/test_presence.py | 2 +- tests/{ => rest}/client/v1/test_profile.py | 2 +- tests/{ => rest}/client/v1/test_rooms.py | 2 +- tests/{ => rest}/client/v1/test_typing.py | 2 +- tests/{ => rest}/client/v1/utils.py | 0 9 files changed, 19 insertions(+), 5 deletions(-) rename tests/{client => rest}/__init__.py (100%) create mode 100644 tests/rest/client/__init__.py rename tests/{ => rest}/client/v1/__init__.py (100%) rename tests/{ => rest}/client/v1/test_events.py (99%) rename tests/{ => rest}/client/v1/test_presence.py (99%) rename tests/{ => rest}/client/v1/test_profile.py (99%) rename tests/{ => rest}/client/v1/test_rooms.py (99%) rename tests/{ => rest}/client/v1/test_typing.py (98%) rename tests/{ => rest}/client/v1/utils.py (100%) diff --git a/tests/client/__init__.py b/tests/rest/__init__.py similarity index 100% rename from tests/client/__init__.py rename to tests/rest/__init__.py diff --git a/tests/rest/client/__init__.py b/tests/rest/client/__init__.py new file mode 100644 index 0000000000..1a84d94cd9 --- /dev/null +++ b/tests/rest/client/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/client/v1/__init__.py b/tests/rest/client/v1/__init__.py similarity index 100% rename from tests/client/v1/__init__.py rename to tests/rest/client/v1/__init__.py diff --git a/tests/client/v1/test_events.py b/tests/rest/client/v1/test_events.py similarity index 99% rename from tests/client/v1/test_events.py rename to tests/rest/client/v1/test_events.py index e914b05a52..0384ffbb3d 100644 --- a/tests/client/v1/test_events.py +++ b/tests/rest/client/v1/test_events.py @@ -25,7 +25,7 @@ import synapse.rest.client.v1.room from synapse.server import HomeServer -from ...utils import MockHttpResource, SQLiteMemoryDbPool, MockKey +from ....utils import MockHttpResource, SQLiteMemoryDbPool, MockKey from .utils import RestTestCase from mock import Mock, NonCallableMock diff --git a/tests/client/v1/test_presence.py b/tests/rest/client/v1/test_presence.py similarity index 99% rename from tests/client/v1/test_presence.py rename to tests/rest/client/v1/test_presence.py index e7d636c74d..0b6f7cfccb 100644 --- a/tests/client/v1/test_presence.py +++ b/tests/rest/client/v1/test_presence.py @@ -20,7 +20,7 @@ from twisted.internet import defer from mock import Mock -from ...utils import MockHttpResource, MockKey +from ....utils import MockHttpResource, MockKey from synapse.api.constants import PresenceState from synapse.handlers.presence import PresenceHandler diff --git a/tests/client/v1/test_profile.py b/tests/rest/client/v1/test_profile.py similarity index 99% rename from tests/client/v1/test_profile.py rename to tests/rest/client/v1/test_profile.py index 1182cc54eb..47cfb10a6d 100644 --- a/tests/client/v1/test_profile.py +++ b/tests/rest/client/v1/test_profile.py @@ -20,7 +20,7 @@ from twisted.internet import defer from mock import Mock, NonCallableMock -from ...utils import MockHttpResource, MockKey +from ....utils import MockHttpResource, MockKey from synapse.api.errors import SynapseError, AuthError from synapse.server import HomeServer diff --git a/tests/client/v1/test_rooms.py b/tests/rest/client/v1/test_rooms.py similarity index 99% rename from tests/client/v1/test_rooms.py rename to tests/rest/client/v1/test_rooms.py index 4d529ef007..12f8040541 100644 --- a/tests/client/v1/test_rooms.py +++ b/tests/rest/client/v1/test_rooms.py @@ -30,7 +30,7 @@ import json import urllib import types -from ...utils import MockHttpResource, SQLiteMemoryDbPool, MockKey +from ....utils import MockHttpResource, SQLiteMemoryDbPool, MockKey from .utils import RestTestCase from mock import Mock, NonCallableMock diff --git a/tests/client/v1/test_typing.py b/tests/rest/client/v1/test_typing.py similarity index 98% rename from tests/client/v1/test_typing.py rename to tests/rest/client/v1/test_typing.py index af3a9a6c1c..647bcebfd8 100644 --- a/tests/client/v1/test_typing.py +++ b/tests/rest/client/v1/test_typing.py @@ -21,7 +21,7 @@ from twisted.internet import defer import synapse.rest.client.v1.room from synapse.server import HomeServer -from ...utils import MockHttpResource, MockClock, SQLiteMemoryDbPool, MockKey +from ....utils import MockHttpResource, MockClock, SQLiteMemoryDbPool, MockKey from .utils import RestTestCase from mock import Mock, NonCallableMock diff --git a/tests/client/v1/utils.py b/tests/rest/client/v1/utils.py similarity index 100% rename from tests/client/v1/utils.py rename to tests/rest/client/v1/utils.py