Skip to content

Commit 708348a

Browse files
authored
Wait for received events using /sync in faster room joins tests (#441)
matrix-org/synapse#13477 unblocked lazy-loading `/sync`s while a room has partial state, which allows us to wait for received events using `/sync`. "Resync completes even when events arrive before their prev_events" is now the only test that waits for events using `/event`, since the outliers do not appear in the `/sync` timeline.
1 parent 33b97e7 commit 708348a

File tree

1 file changed

+46
-20
lines changed

1 file changed

+46
-20
lines changed

tests/federation_room_join_partial_state_test.go

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ func TestPartialStateJoin(t *testing.T) {
6565
return serverRoom
6666
}
6767

68+
// getSyncToken gets the latest sync token
69+
getSyncToken := func(t *testing.T, alice *client.CSAPI) string {
70+
_, syncToken := alice.MustSync(t,
71+
client.SyncReq{
72+
Filter: buildLazyLoadingSyncFilter(nil),
73+
TimeoutMillis: "0",
74+
},
75+
)
76+
return syncToken
77+
}
78+
6879
// test that a regular /sync request made during a partial-state /send_join
6980
// request blocks until the state is correctly synced.
7081
t.Run("SyncBlocksDuringPartialStateJoin", func(t *testing.T) {
@@ -182,6 +193,7 @@ func TestPartialStateJoin(t *testing.T) {
182193
deployment := Deploy(t, b.BlueprintAlice)
183194
defer deployment.Destroy(t)
184195
alice := deployment.Client(t, "hs1", "@alice:hs1")
196+
syncToken := getSyncToken(t, alice)
185197

186198
server := createTestServer(t, deployment)
187199
cancel := server.Listen()
@@ -197,14 +209,15 @@ func TestPartialStateJoin(t *testing.T) {
197209
t.Logf("Derek created event with ID %s", event.EventID())
198210

199211
// derek sends an event in the room
200-
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, event)
212+
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, event, syncToken)
201213
})
202214

203215
// we should be able to receive events with a missing prev event over federation during the resync
204216
t.Run("CanReceiveEventsWithMissingParentsDuringPartialStateJoin", func(t *testing.T) {
205217
deployment := Deploy(t, b.BlueprintAlice)
206218
defer deployment.Destroy(t)
207219
alice := deployment.Client(t, "hs1", "@alice:hs1")
220+
syncToken := getSyncToken(t, alice)
208221

209222
server := createTestServer(t, deployment)
210223
cancel := server.Listen()
@@ -236,14 +249,15 @@ func TestPartialStateJoin(t *testing.T) {
236249
[]string{eventB.EventID()}, []*gomatrixserverlib.Event{eventA})
237250

238251
// send event B to hs1
239-
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, eventB)
252+
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, eventB, syncToken)
240253
})
241254

242255
// we should be able to receive events with partially missing prev events over federation during the resync
243256
t.Run("CanReceiveEventsWithHalfMissingParentsDuringPartialStateJoin", func(t *testing.T) {
244257
deployment := Deploy(t, b.BlueprintAlice)
245258
defer deployment.Destroy(t)
246259
alice := deployment.Client(t, "hs1", "@alice:hs1")
260+
syncToken := getSyncToken(t, alice)
247261

248262
server := createTestServer(t, deployment)
249263
cancel := server.Listen()
@@ -277,7 +291,7 @@ func TestPartialStateJoin(t *testing.T) {
277291
[]string{eventB.EventID()}, []*gomatrixserverlib.Event{eventA})
278292

279293
// send event B to hs1
280-
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, eventB)
294+
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, eventB, syncToken)
281295
})
282296

283297
// we should be able to receive events with a missing prev event, with half missing prev events,
@@ -286,6 +300,7 @@ func TestPartialStateJoin(t *testing.T) {
286300
deployment := Deploy(t, b.BlueprintAlice)
287301
defer deployment.Destroy(t)
288302
alice := deployment.Client(t, "hs1", "@alice:hs1")
303+
syncToken := getSyncToken(t, alice)
289304

290305
server := createTestServer(t, deployment)
291306
cancel := server.Listen()
@@ -323,7 +338,7 @@ func TestPartialStateJoin(t *testing.T) {
323338
handleStateRequests(t, server, serverRoom, eventA.EventID(), serverRoom.AllCurrentState(), nil, nil)
324339

325340
// send event C to hs1
326-
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, eventC)
341+
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, eventC, syncToken)
327342
})
328343

329344
// a request to (client-side) /members?at= should block until the (federation) /state request completes
@@ -635,6 +650,7 @@ func TestPartialStateJoin(t *testing.T) {
635650
deployment := Deploy(t, b.BlueprintAlice)
636651
defer deployment.Destroy(t)
637652
alice := deployment.Client(t, "hs1", "@alice:hs1")
653+
syncToken := getSyncToken(t, alice)
638654

639655
server := createTestServer(t, deployment)
640656
cancel := server.Listen()
@@ -692,7 +708,7 @@ func TestPartialStateJoin(t *testing.T) {
692708

693709
t.Logf("Charlie sent timeline event 2")
694710
// wait for it to become visible, which implies that all the outliers have been pulled in.
695-
awaitEventArrival(t, time.Second, alice, serverRoom.RoomID, timelineEvent2.EventID())
711+
awaitEventViaSync(t, alice, serverRoom.RoomID, timelineEvent2.EventID(), syncToken)
696712

697713
// now we send over all the other events in the gap.
698714
server.MustSendTransaction(t, deployment, "hs1", []json.RawMessage{lateEvent.JSON()}, nil)
@@ -741,6 +757,7 @@ func TestPartialStateJoin(t *testing.T) {
741757
deployment := Deploy(t, b.BlueprintAlice)
742758
defer deployment.Destroy(t)
743759
alice := deployment.Client(t, "hs1", "@alice:hs1")
760+
syncToken := getSyncToken(t, alice)
744761

745762
server := createTestServer(t, deployment)
746763
cancel := server.Listen()
@@ -777,7 +794,7 @@ func TestPartialStateJoin(t *testing.T) {
777794
[]json.RawMessage{badStateEvent.JSON(), sentinelEvent.JSON()}, nil)
778795

779796
// wait for the sentinel event to be visible
780-
awaitEventArrival(t, time.Second, alice, serverRoom.RoomID, sentinelEvent.EventID())
797+
syncToken = awaitEventViaSync(t, alice, serverRoom.RoomID, sentinelEvent.EventID(), syncToken)
781798

782799
// ... and check that the bad state event is *not* visible
783800
must.MatchResponse(t,
@@ -793,7 +810,7 @@ func TestPartialStateJoin(t *testing.T) {
793810
// one more (non-state) event, for testReceiveEventDuringPartialStateJoin
794811
event := psjResult.CreateMessageEvent(t, "charlie", nil)
795812
t.Logf("charlie created regular timeline event %s", event.EventID())
796-
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, event)
813+
testReceiveEventDuringPartialStateJoin(t, deployment, alice, psjResult, event, syncToken)
797814

798815
// check that the bad state event is *still* not visible
799816
must.MatchResponse(t,
@@ -1214,14 +1231,14 @@ func TestPartialStateJoin(t *testing.T) {
12141231

12151232
// test reception of an event over federation during a resync
12161233
// sends the given event to the homeserver under test, checks that a client can see it and checks
1217-
// the state at the event
1234+
// the state at the event. returns the new sync token after the event.
12181235
func testReceiveEventDuringPartialStateJoin(
1219-
t *testing.T, deployment *docker.Deployment, alice *client.CSAPI, psjResult partialStateJoinResult, event *gomatrixserverlib.Event,
1220-
) {
1236+
t *testing.T, deployment *docker.Deployment, alice *client.CSAPI, psjResult partialStateJoinResult, event *gomatrixserverlib.Event, syncToken string,
1237+
) string {
12211238
// send the event to the homeserver
12221239
psjResult.Server.MustSendTransaction(t, deployment, "hs1", []json.RawMessage{event.JSON()}, nil)
12231240

1224-
awaitEventArrival(t, time.Second, alice, psjResult.ServerRoom.RoomID, event.EventID())
1241+
syncToken = awaitEventViaSync(t, alice, psjResult.ServerRoom.RoomID, event.EventID(), syncToken)
12251242

12261243
// fire off a /state_ids request for the last event.
12271244
// it must either:
@@ -1274,7 +1291,7 @@ func testReceiveEventDuringPartialStateJoin(
12741291
)
12751292
if err := psjResult.Server.SendFederationRequest(context.Background(), deployment, stateReq, &respStateIDs); err != nil {
12761293
t.Errorf("/state_ids request returned non-200: %s", err)
1277-
return
1294+
return syncToken
12781295
}
12791296
var gotState, expectedState []interface{}
12801297
for _, ev := range respStateIDs.StateEventIDs {
@@ -1284,21 +1301,30 @@ func testReceiveEventDuringPartialStateJoin(
12841301
expectedState = append(expectedState, ev.EventID())
12851302
}
12861303
must.CheckOffAll(t, gotState, expectedState)
1304+
1305+
return syncToken
12871306
}
12881307

1289-
// awaitEventArrival waits for alice to be able to see a given event
1290-
func awaitEventArrival(t *testing.T, timeout time.Duration, alice *client.CSAPI, roomID string, eventID string) {
1291-
/* TODO: check that a lazy-loading sync can see the event. Currently this doesn't work, because /sync blocks.
1292-
* https://github.com/matrix-org/synapse/issues/13146
1293-
alice.MustSyncUntil(t,
1308+
// awaitEventViaSync waits for alice to be able to see a given event via an incremental lazy-loading
1309+
// /sync and returns the new sync token after
1310+
func awaitEventViaSync(t *testing.T, alice *client.CSAPI, roomID string, eventID string, syncToken string) string {
1311+
// check that a lazy-loading sync can see the event
1312+
syncToken = alice.MustSyncUntil(t,
12941313
client.SyncReq{
1314+
Since: syncToken,
12951315
Filter: buildLazyLoadingSyncFilter(nil),
12961316
},
12971317
client.SyncTimelineHasEventID(roomID, eventID),
12981318
)
1299-
*/
13001319

1301-
// still, Alice should be able to see the event with an /event request. We might have to try it a few times.
1320+
t.Logf("Alice successfully received event %s via /sync", eventID)
1321+
1322+
return syncToken
1323+
}
1324+
1325+
// awaitEventArrival waits for alice to be able to see a given event via /event
1326+
func awaitEventArrival(t *testing.T, timeout time.Duration, alice *client.CSAPI, roomID string, eventID string) {
1327+
// Alice should be able to see the event with an /event request. We might have to try it a few times.
13021328
alice.DoFunc(t, "GET", []string{"_matrix", "client", "r0", "rooms", roomID, "event", eventID},
13031329
client.WithRetryUntil(timeout, func(res *http.Response) bool {
13041330
if res.StatusCode == 200 {
@@ -1312,7 +1338,7 @@ func awaitEventArrival(t *testing.T, timeout time.Duration, alice *client.CSAPI,
13121338
return false
13131339
}),
13141340
)
1315-
t.Logf("Alice successfully received event %s", eventID)
1341+
t.Logf("Alice successfully observed event %s via /event", eventID)
13161342
}
13171343

13181344
// buildLazyLoadingSyncFilter constructs a json-marshalled filter suitable the 'Filter' field of a client.SyncReq

0 commit comments

Comments
 (0)