diff options
Diffstat (limited to 'tests/federation')
-rw-r--r-- | tests/federation/__init__.py | 0 | ||||
-rw-r--r-- | tests/federation/test_federation.py | 240 | ||||
-rw-r--r-- | tests/federation/test_pdu_codec.py | 146 |
3 files changed, 386 insertions, 0 deletions
diff --git a/tests/federation/__init__.py b/tests/federation/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/federation/__init__.py diff --git a/tests/federation/test_federation.py b/tests/federation/test_federation.py new file mode 100644 index 0000000000..1792f9de56 --- /dev/null +++ b/tests/federation/test_federation.py @@ -0,0 +1,240 @@ +# trial imports +from twisted.internet import defer +from twisted.trial import unittest + +# python imports +from mock import Mock +import logging + +from ..utils import MockHttpServer + +from synapse.server import HomeServer +from synapse.federation import initialize_http_replication +from synapse.federation.units import Pdu +from synapse.storage.pdu import PduTuple, PduEntry + + +logging.getLogger().addHandler(logging.NullHandler()) + + +def make_pdu(prev_pdus=[], **kwargs): + """Provide some default fields for making a PduTuple.""" + pdu_fields = { + "is_state": False, + "unrecognized_keys": [], + "outlier": False, + "have_processed": True, + "state_key": None, + "power_level": None, + "prev_state_id": None, + "prev_state_origin": None, + } + pdu_fields.update(kwargs) + + return PduTuple(PduEntry(**pdu_fields), prev_pdus) + + +class MockClock(object): + now = 1000 + + def time(self): + return self.now + + def time_msec(self): + return self.time() * 1000 + + +class FederationTestCase(unittest.TestCase): + def setUp(self): + self.mock_http_server = MockHttpServer() + self.mock_http_client = Mock(spec=[ + "put_json", + ]) + self.mock_persistence = Mock(spec=[ + "get_current_state_for_context", + "get_pdu", + "persist_pdu", + "update_min_depth_for_context", + "prep_send_transaction", + "delivered_txn", + "get_received_txn_response", + "set_received_txn_response", + ]) + self.mock_persistence.get_received_txn_response.return_value = ( + defer.succeed(None) + ) + self.clock = MockClock() + hs = HomeServer("test", + http_server=self.mock_http_server, + http_client=self.mock_http_client, + db_pool=None, + datastore=self.mock_persistence, + clock=self.clock, + ) + self.federation = initialize_http_replication(hs) + self.distributor = hs.get_distributor() + + @defer.inlineCallbacks + def test_get_state(self): + self.mock_persistence.get_current_state_for_context.return_value = ( + defer.succeed([]) + ) + + # Empty context initially + (code, response) = yield self.mock_http_server.trigger("GET", + "/state/my-context/", None) + self.assertEquals(200, code) + self.assertFalse(response["pdus"]) + + # Now lets give the context some state + self.mock_persistence.get_current_state_for_context.return_value = ( + defer.succeed([ + make_pdu( + pdu_id="the-pdu-id", + origin="red", + context="my-context", + pdu_type="m.topic", + ts=123456789000, + depth=1, + is_state=True, + content_json='{"topic":"The topic"}', + state_key="", + power_level=1000, + prev_state_id="last-pdu-id", + prev_state_origin="blue", + ), + ]) + ) + + (code, response) = yield self.mock_http_server.trigger("GET", + "/state/my-context/", None) + self.assertEquals(200, code) + self.assertEquals(1, len(response["pdus"])) + + @defer.inlineCallbacks + def test_get_pdu(self): + self.mock_persistence.get_pdu.return_value = ( + defer.succeed(None) + ) + + (code, response) = yield self.mock_http_server.trigger("GET", + "/pdu/red/abc123def456/", None) + self.assertEquals(404, code) + + # Now insert such a PDU + self.mock_persistence.get_pdu.return_value = ( + defer.succeed( + make_pdu( + pdu_id="abc123def456", + origin="red", + context="my-context", + pdu_type="m.text", + ts=123456789001, + depth=1, + content_json='{"text":"Here is the message"}', + ) + ) + ) + + (code, response) = yield self.mock_http_server.trigger("GET", + "/pdu/red/abc123def456/", None) + self.assertEquals(200, code) + self.assertEquals(1, len(response["pdus"])) + self.assertEquals("m.text", response["pdus"][0]["pdu_type"]) + + @defer.inlineCallbacks + def test_send_pdu(self): + self.mock_http_client.put_json.return_value = defer.succeed( + (200, "OK") + ) + + pdu = Pdu( + pdu_id="abc123def456", + origin="red", + destinations=["remote"], + context="my-context", + ts=123456789002, + pdu_type="m.test", + content={"testing": "content here"}, + depth=1, + ) + + yield self.federation.send_pdu(pdu) + + self.mock_http_client.put_json.assert_called_with( + "remote", + path="/send/1000000/", + data={ + "ts": 1000000, + "origin": "test", + "pdus": [ + { + "origin": "red", + "pdu_id": "abc123def456", + "prev_pdus": [], + "ts": 123456789002, + "context": "my-context", + "pdu_type": "m.test", + "is_state": False, + "content": {"testing": "content here"}, + "depth": 1, + }, + ] + } + ) + + @defer.inlineCallbacks + def test_send_edu(self): + self.mock_http_client.put_json.return_value = defer.succeed( + (200, "OK") + ) + + yield self.federation.send_edu( + destination="remote", + edu_type="m.test", + content={"testing": "content here"}, + ) + + # MockClock ensures we can guess these timestamps + self.mock_http_client.put_json.assert_called_with( + "remote", + path="/send/1000000/", + data={ + "origin": "test", + "ts": 1000000, + "pdus": [], + "edus": [ + { + "origin": "test", + "destination": "remote", + "edu_type": "m.test", + "content": {"testing": "content here"}, + } + ], + }) + + @defer.inlineCallbacks + def test_recv_edu(self): + recv_observer = Mock() + recv_observer.return_value = defer.succeed(()) + + self.federation.register_edu_handler("m.test", recv_observer) + + yield self.mock_http_server.trigger("PUT", "/send/1001000/", + """{ + "origin": "remote", + "ts": 1001000, + "pdus": [], + "edus": [ + { + "origin": "remote", + "destination": "test", + "edu_type": "m.test", + "content": {"testing": "reply here"} + } + ] + }""") + + recv_observer.assert_called_with( + "remote", {"testing": "reply here"} + ) diff --git a/tests/federation/test_pdu_codec.py b/tests/federation/test_pdu_codec.py new file mode 100644 index 0000000000..688182fa5b --- /dev/null +++ b/tests/federation/test_pdu_codec.py @@ -0,0 +1,146 @@ +# -*- coding: utf-8 -*- +from twisted.trial import unittest + +from synapse.federation.pdu_codec import ( + PduCodec, encode_event_id, decode_event_id +) +from synapse.federation.units import Pdu +#from synapse.api.events.room import MessageEvent + +from synapse.server import HomeServer + +from mock import Mock + + +class PduCodecTestCase(unittest.TestCase): + def setUp(self): + self.hs = HomeServer("blargle.net") + self.event_factory = self.hs.get_event_factory() + + self.codec = PduCodec(self.hs) + + def test_decode_event_id(self): + self.assertEquals( + ("foo", "bar.com"), + decode_event_id("foo@bar.com", "A") + ) + + self.assertEquals( + ("foo", "bar.com"), + decode_event_id("foo", "bar.com") + ) + + def test_encode_event_id(self): + self.assertEquals("A@B", encode_event_id("A", "B")) + + def test_codec_event_id(self): + event_id = "aa@bb.com" + + self.assertEquals( + event_id, + encode_event_id(*decode_event_id(event_id, None)) + ) + + pdu_id = ("aa", "bb.com") + + self.assertEquals( + pdu_id, + decode_event_id(encode_event_id(*pdu_id), None) + ) + + def test_event_from_pdu(self): + pdu = Pdu( + pdu_id="foo", + context="rooooom", + pdu_type="m.room.message", + origin="bar.com", + ts=12345, + depth=5, + prev_pdus=[("alice", "bob.com")], + is_state=False, + content={"msgtype": u"test"}, + ) + + event = self.codec.event_from_pdu(pdu) + + self.assertEquals("foo@bar.com", event.event_id) + self.assertEquals(pdu.context, event.room_id) + self.assertEquals(pdu.is_state, event.is_state) + self.assertEquals(pdu.depth, event.depth) + self.assertEquals(["alice@bob.com"], event.prev_events) + self.assertEquals(pdu.content, event.content) + + def test_pdu_from_event(self): + event = self.event_factory.create_event( + etype="m.room.message", + event_id="gargh_id", + room_id="rooom", + user_id="sender", + content={"msgtype": u"test"}, + ) + + pdu = self.codec.pdu_from_event(event) + + self.assertEquals(event.event_id, pdu.pdu_id) + self.assertEquals(self.hs.hostname, pdu.origin) + self.assertEquals(event.room_id, pdu.context) + self.assertEquals(event.content, pdu.content) + self.assertEquals(event.type, pdu.pdu_type) + + event = self.event_factory.create_event( + etype="m.room.message", + event_id="gargh_id@bob.com", + room_id="rooom", + user_id="sender", + content={"msgtype": u"test"}, + ) + + pdu = self.codec.pdu_from_event(event) + + self.assertEquals("gargh_id", pdu.pdu_id) + self.assertEquals("bob.com", pdu.origin) + self.assertEquals(event.room_id, pdu.context) + self.assertEquals(event.content, pdu.content) + self.assertEquals(event.type, pdu.pdu_type) + + def test_event_from_state_pdu(self): + pdu = Pdu( + pdu_id="foo", + context="rooooom", + pdu_type="m.room.topic", + origin="bar.com", + ts=12345, + depth=5, + prev_pdus=[("alice", "bob.com")], + is_state=True, + content={"topic": u"test"}, + state_key="", + ) + + event = self.codec.event_from_pdu(pdu) + + self.assertEquals("foo@bar.com", event.event_id) + self.assertEquals(pdu.context, event.room_id) + self.assertEquals(pdu.is_state, event.is_state) + self.assertEquals(pdu.depth, event.depth) + self.assertEquals(["alice@bob.com"], event.prev_events) + self.assertEquals(pdu.content, event.content) + self.assertEquals(pdu.state_key, event.state_key) + + def test_pdu_from_state_event(self): + event = self.event_factory.create_event( + etype="m.room.topic", + event_id="gargh_id", + room_id="rooom", + user_id="sender", + content={"topic": u"test"}, + ) + + pdu = self.codec.pdu_from_event(event) + + self.assertEquals(event.event_id, pdu.pdu_id) + self.assertEquals(self.hs.hostname, pdu.origin) + self.assertEquals(event.room_id, pdu.context) + self.assertEquals(event.content, pdu.content) + self.assertEquals(event.type, pdu.pdu_type) + self.assertEquals(event.state_key, pdu.state_key) |