test_resource.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2016 OpenMarket Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import contextlib
  16. import json
  17. from mock import Mock, NonCallableMock
  18. from twisted.internet import defer
  19. import synapse.types
  20. from synapse.replication.resource import ReplicationResource
  21. from synapse.types import UserID
  22. from tests import unittest
  23. from tests.utils import setup_test_homeserver
  24. class ReplicationResourceCase(unittest.TestCase):
  25. @defer.inlineCallbacks
  26. def setUp(self):
  27. self.hs = yield setup_test_homeserver(
  28. "red",
  29. http_client=None,
  30. replication_layer=Mock(),
  31. ratelimiter=NonCallableMock(spec_set=[
  32. "send_message",
  33. ]),
  34. )
  35. self.user_id = "@seeing:red"
  36. self.user = UserID.from_string(self.user_id)
  37. self.hs.get_ratelimiter().send_message.return_value = (True, 0)
  38. self.resource = ReplicationResource(self.hs)
  39. @defer.inlineCallbacks
  40. def test_streams(self):
  41. # Passing "-1" returns the current stream positions
  42. code, body = yield self.get(streams="-1")
  43. self.assertEquals(code, 200)
  44. self.assertEquals(body["streams"]["field_names"], ["name", "position"])
  45. position = body["streams"]["position"]
  46. # Passing the current position returns an empty response after the
  47. # timeout
  48. get = self.get(streams=str(position), timeout="0")
  49. self.hs.clock.advance_time_msec(1)
  50. code, body = yield get
  51. self.assertEquals(code, 200)
  52. self.assertEquals(body, {})
  53. @defer.inlineCallbacks
  54. def test_events(self):
  55. get = self.get(events="-1", timeout="0")
  56. yield self.hs.get_handlers().room_creation_handler.create_room(
  57. synapse.types.create_requester(self.user), {}
  58. )
  59. code, body = yield get
  60. self.assertEquals(code, 200)
  61. self.assertEquals(body["events"]["field_names"], [
  62. "position", "internal", "json", "state_group"
  63. ])
  64. @defer.inlineCallbacks
  65. def test_presence(self):
  66. get = self.get(presence="-1")
  67. yield self.hs.get_presence_handler().set_state(
  68. self.user, {"presence": "online"}
  69. )
  70. code, body = yield get
  71. self.assertEquals(code, 200)
  72. self.assertEquals(body["presence"]["field_names"], [
  73. "position", "user_id", "state", "last_active_ts",
  74. "last_federation_update_ts", "last_user_sync_ts",
  75. "status_msg", "currently_active",
  76. ])
  77. @defer.inlineCallbacks
  78. def test_typing(self):
  79. room_id = yield self.create_room()
  80. get = self.get(typing="-1")
  81. yield self.hs.get_typing_handler().started_typing(
  82. self.user, self.user, room_id, timeout=2
  83. )
  84. code, body = yield get
  85. self.assertEquals(code, 200)
  86. self.assertEquals(body["typing"]["field_names"], [
  87. "position", "room_id", "typing"
  88. ])
  89. @defer.inlineCallbacks
  90. def test_receipts(self):
  91. room_id = yield self.create_room()
  92. event_id = yield self.send_text_message(room_id, "Hello, World")
  93. get = self.get(receipts="-1")
  94. yield self.hs.get_receipts_handler().received_client_receipt(
  95. room_id, "m.read", self.user_id, event_id
  96. )
  97. code, body = yield get
  98. self.assertEquals(code, 200)
  99. self.assertEquals(body["receipts"]["field_names"], [
  100. "position", "room_id", "receipt_type", "user_id", "event_id", "data"
  101. ])
  102. def _test_timeout(stream):
  103. """Check that a request for the given stream timesout"""
  104. @defer.inlineCallbacks
  105. def test_timeout(self):
  106. get = self.get(**{stream: "-1", "timeout": "0"})
  107. self.hs.clock.advance_time_msec(1)
  108. code, body = yield get
  109. self.assertEquals(code, 200)
  110. self.assertEquals(body.get("rows", []), [])
  111. test_timeout.__name__ = "test_timeout_%s" % (stream)
  112. return test_timeout
  113. test_timeout_events = _test_timeout("events")
  114. test_timeout_presence = _test_timeout("presence")
  115. test_timeout_typing = _test_timeout("typing")
  116. test_timeout_receipts = _test_timeout("receipts")
  117. test_timeout_user_account_data = _test_timeout("user_account_data")
  118. test_timeout_room_account_data = _test_timeout("room_account_data")
  119. test_timeout_tag_account_data = _test_timeout("tag_account_data")
  120. test_timeout_backfill = _test_timeout("backfill")
  121. test_timeout_push_rules = _test_timeout("push_rules")
  122. test_timeout_pushers = _test_timeout("pushers")
  123. test_timeout_state = _test_timeout("state")
  124. @defer.inlineCallbacks
  125. def send_text_message(self, room_id, message):
  126. handler = self.hs.get_handlers().message_handler
  127. event = yield handler.create_and_send_nonmember_event(
  128. synapse.types.create_requester(self.user),
  129. {
  130. "type": "m.room.message",
  131. "content": {"body": "message", "msgtype": "m.text"},
  132. "room_id": room_id,
  133. "sender": self.user.to_string(),
  134. }
  135. )
  136. defer.returnValue(event.event_id)
  137. @defer.inlineCallbacks
  138. def create_room(self):
  139. result = yield self.hs.get_handlers().room_creation_handler.create_room(
  140. synapse.types.create_requester(self.user), {}
  141. )
  142. defer.returnValue(result["room_id"])
  143. @defer.inlineCallbacks
  144. def get(self, **params):
  145. request = NonCallableMock(spec_set=[
  146. "write", "finish", "setResponseCode", "setHeader", "args",
  147. "method", "processing"
  148. ])
  149. request.method = "GET"
  150. request.args = {k: [v] for k, v in params.items()}
  151. @contextlib.contextmanager
  152. def processing():
  153. yield
  154. request.processing = processing
  155. yield self.resource._async_render_GET(request)
  156. self.assertTrue(request.finish.called)
  157. if request.setResponseCode.called:
  158. response_code = request.setResponseCode.call_args[0][0]
  159. else:
  160. response_code = 200
  161. response_json = "".join(
  162. call[0][0] for call in request.write.call_args_list
  163. )
  164. response_body = json.loads(response_json)
  165. if response_code == 200:
  166. self.check_response(response_body)
  167. defer.returnValue((response_code, response_body))
  168. def check_response(self, response_body):
  169. for name, stream in response_body.items():
  170. self.assertIn("field_names", stream)
  171. field_names = stream["field_names"]
  172. self.assertIn("rows", stream)
  173. for row in stream["rows"]:
  174. self.assertEquals(
  175. len(row), len(field_names),
  176. "%s: len(row = %r) == len(field_names = %r)" % (
  177. name, row, field_names
  178. )
  179. )