@@ -45,50 +45,63 @@ def make_homeserver(self, reactor, clock):
45
45
}
46
46
47
47
self .hs = self .setup_test_homeserver (config = config )
48
+
48
49
return self .hs
49
50
50
51
def prepare (self , reactor , clock , homeserver ):
51
52
self .user_id = self .register_user ("user" , "password" )
52
53
self .token = self .login ("user" , "password" )
53
54
54
- def test_retention_state_event (self ):
55
- """Tests that the server configuration can limit the values a user can set to the
56
- room's retention policy.
55
+ self .store = self .hs .get_datastore ()
56
+ self .serializer = self .hs .get_event_client_serializer ()
57
+ self .clock = self .hs .get_clock ()
58
+
59
+ def test_retention_event_purged_with_state_event (self ):
60
+ """Tests that expired events are correctly purged when the room's retention policy
61
+ is defined by a state event.
57
62
"""
58
63
room_id = self .helper .create_room_as (self .user_id , tok = self .token )
59
64
65
+ # Set the room's retention period to 2 days.
66
+ lifetime = one_day_ms * 2
60
67
self .helper .send_state (
61
68
room_id = room_id ,
62
69
event_type = EventTypes .Retention ,
63
- body = {"max_lifetime" : one_day_ms * 4 },
70
+ body = {"max_lifetime" : lifetime },
64
71
tok = self .token ,
65
- expect_code = 400 ,
66
72
)
67
73
74
+ self ._test_retention_event_purged (room_id , one_day_ms * 1.5 )
75
+
76
+ def test_retention_event_purged_with_state_event_outside_allowed (self ):
77
+ """Tests that the server configuration can override the policy for a room when
78
+ running the purge jobs.
79
+ """
80
+ room_id = self .helper .create_room_as (self .user_id , tok = self .token )
81
+
82
+ # Set a max_lifetime higher than the maximum allowed value.
68
83
self .helper .send_state (
69
84
room_id = room_id ,
70
85
event_type = EventTypes .Retention ,
71
- body = {"max_lifetime" : one_hour_ms },
86
+ body = {"max_lifetime" : one_day_ms * 4 },
72
87
tok = self .token ,
73
- expect_code = 400 ,
74
88
)
75
89
76
- def test_retention_event_purged_with_state_event (self ):
77
- """Tests that expired events are correctly purged when the room's retention policy
78
- is defined by a state event.
79
- """
80
- room_id = self .helper .create_room_as (self .user_id , tok = self .token )
90
+ # Check that the event is purged after waiting for the maximum allowed duration
91
+ # instead of the one specified in the room's policy.
92
+ self ._test_retention_event_purged (room_id , one_day_ms * 1.5 )
81
93
82
- # Set the room's retention period to 2 days.
83
- lifetime = one_day_ms * 2
94
+ # Set a max_lifetime lower than the minimum allowed value.
84
95
self .helper .send_state (
85
96
room_id = room_id ,
86
97
event_type = EventTypes .Retention ,
87
- body = {"max_lifetime" : lifetime },
98
+ body = {"max_lifetime" : one_hour_ms },
88
99
tok = self .token ,
89
100
)
90
101
91
- self ._test_retention_event_purged (room_id , one_day_ms * 1.5 )
102
+ # Check that the event is purged after waiting for the minimum allowed duration
103
+ # instead of the one specified in the room's policy.
104
+ self ._test_retention_event_purged (room_id , one_day_ms * 0.5 )
92
105
93
106
def test_retention_event_purged_without_state_event (self ):
94
107
"""Tests that expired events are correctly purged when the room's retention policy
@@ -140,7 +153,27 @@ def test_visibility(self):
140
153
# That event should be the second, not outdated event.
141
154
self .assertEqual (filtered_events [0 ].event_id , valid_event_id , filtered_events )
142
155
143
- def _test_retention_event_purged (self , room_id , increment ):
156
+ def _test_retention_event_purged (self , room_id : str , increment : float ):
157
+ """Run the following test scenario to test the message retention policy support:
158
+
159
+ 1. Send event 1
160
+ 2. Increment time by `increment`
161
+ 3. Send event 2
162
+ 4. Increment time by `increment`
163
+ 5. Check that event 1 has been purged
164
+ 6. Check that event 2 has not been purged
165
+ 7. Check that state events that were sent before event 1 aren't purged.
166
+ The main reason for sending a second event is because currently Synapse won't
167
+ purge the latest message in a room because it would otherwise result in a lack of
168
+ forward extremities for this room. It's also a good thing to ensure the purge jobs
169
+ aren't too greedy and purge messages they shouldn't.
170
+
171
+ Args:
172
+ room_id: The ID of the room to test retention in.
173
+ increment: The number of milliseconds to advance the clock each time. Must be
174
+ defined so that events in the room aren't purged if they are `increment`
175
+ old but are purged if they are `increment * 2` old.
176
+ """
144
177
# Get the create event to, later, check that we can still access it.
145
178
message_handler = self .hs .get_message_handler ()
146
179
create_event = self .get_success (
@@ -156,7 +189,7 @@ def _test_retention_event_purged(self, room_id, increment):
156
189
expired_event_id = resp .get ("event_id" )
157
190
158
191
# Check that we can retrieve the event.
159
- expired_event = self .get_event (room_id , expired_event_id )
192
+ expired_event = self .get_event (expired_event_id )
160
193
self .assertEqual (
161
194
expired_event .get ("content" , {}).get ("body" ), "1" , expired_event
162
195
)
@@ -174,26 +207,31 @@ def _test_retention_event_purged(self, room_id, increment):
174
207
# one should still be kept.
175
208
self .reactor .advance (increment / 1000 )
176
209
177
- # Check that the event has been purged from the database.
178
- self .get_event (room_id , expired_event_id , expected_code = 404 )
210
+ # Check that the first event has been purged from the database, i.e. that we
211
+ # can't retrieve it anymore, because it has expired.
212
+ self .get_event (expired_event_id , expect_none = True )
179
213
180
- # Check that the event that hasn't been purged can still be retrieved.
181
- valid_event = self .get_event (room_id , valid_event_id )
214
+ # Check that the event that hasn't expired can still be retrieved.
215
+ valid_event = self .get_event (valid_event_id )
182
216
self .assertEqual (valid_event .get ("content" , {}).get ("body" ), "2" , valid_event )
183
217
184
218
# Check that we can still access state events that were sent before the event that
185
219
# has been purged.
186
220
self .get_event (room_id , create_event .event_id )
187
221
188
- def get_event (self , room_id , event_id , expected_code = 200 ):
189
- url = "/_matrix/client/r0/rooms/%s/event/%s" % ( room_id , event_id )
222
+ def get_event (self , event_id , expect_none = False ):
223
+ event = self . get_success ( self . store . get_event ( event_id , allow_none = True ) )
190
224
191
- request , channel = self .make_request ("GET" , url , access_token = self .token )
192
- self .render (request )
225
+ if expect_none :
226
+ self .assertIsNone (event )
227
+ return {}
193
228
194
- self .assertEqual ( channel . code , expected_code , channel . result )
229
+ self .assertIsNotNone ( event )
195
230
196
- return channel .json_body
231
+ time_now = self .clock .time_msec ()
232
+ serialized = self .get_success (self .serializer .serialize_event (event , time_now ))
233
+
234
+ return serialized
197
235
198
236
199
237
class RetentionNoDefaultPolicyTestCase (unittest .HomeserverTestCase ):
0 commit comments