Skip to content

Commit 093a6cb

Browse files
Remove messy WithWaitForLeave test clean-up in TestPartialStateJoin (#894)
Follow-up to #880 which introduces a better way to avoid the test pollution and obsoletes the need for all of this cleanup logic. See the PR description there for a more complete context on why. `WithWaitForLeave` was originally introduced in this context: > Many of the faster joins test flakes are due to the homeserver under test failing to contact Complement homeservers after they have been torn down. When this happens, subsequent tests can fail if they use a Complement homeserver that happens to have the same `hostname:port` as one which the homeserver under test has previously marked as offline. > > *-- #626 But thanks to #880 we no longer use the same `hostname:port` for engineered homeservers anymore. And we can go even further with cleaning this up by removing the need for `Destroy(...)` altogether, see #895
1 parent 1a2baac commit 093a6cb

1 file changed

Lines changed: 9 additions & 110 deletions

File tree

tests/msc3902/federation_room_join_partial_state_test.go

Lines changed: 9 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -123,74 +123,6 @@ func (s *server) AddEDUHandler(eduHandler func(gomatrixserverlib.EDU) bool) func
123123
}
124124
}
125125

126-
// WithWaitForLeave runs the given action and, when the resulting leave is
127-
// expected to reach this server, waits for it. `leaveAction` is always run; the
128-
// wait is skipped when `user` had already left the room (per their own
129-
// homeserver, so the action produces no new leave) or when this server isn't in
130-
// the room (so the leave won't be federated to us).
131-
func (s *server) WithWaitForLeave(
132-
t *testing.T, room *federation.ServerRoom, user *client.CSAPI, leaveAction func(),
133-
) {
134-
userID := user.UserID
135-
leaveChannel := make(chan gomatrixserverlib.PDU, 10)
136-
removePDUHandler := s.AddPDUHandler(
137-
func(e gomatrixserverlib.PDU) bool {
138-
if membership, _ := e.Membership(); e.Type() == "m.room.member" &&
139-
*e.StateKey() == userID &&
140-
membership == "leave" {
141-
leaveChannel <- e
142-
return true
143-
}
144-
return false
145-
},
146-
)
147-
defer removePDUHandler()
148-
149-
// We need to check if the user (on their homeserver) thinks they're in the
150-
// room, before performing the `leaveAction` (to avoid races).
151-
//
152-
// If they are not in the room, then the `leaveAction` will not produce a
153-
// new leave event and we should not wait for one.
154-
//
155-
// If they are in the room then the `leaveAction` will produce a new leave
156-
// event. We then need to check if we expect this server receive the leave
157-
// event by checking if this server is in the room. If they are, we wait, if
158-
// not we can return immediately after the `leaveAction`.
159-
userInRoom := userIsJoinedTo(t, user, room.RoomID)
160-
161-
leaveAction()
162-
163-
if !userInRoom {
164-
// The user had already left, so the action produced no new leave and
165-
// none is coming: don't wait.
166-
t.Logf("%s is not joined to test room %s; not waiting for them to leave.", userID, room.RoomID)
167-
return
168-
}
169-
170-
if !s.isInRoom(room) {
171-
// The homeserver only federates the leave to servers that are in the
172-
// room. If we aren't, no leave PDU is coming to us, so don't block until
173-
// the timeout.
174-
t.Logf("%s is not in test room %s; not waiting for %s to leave.", s.ServerName(), room.RoomID, userID)
175-
return
176-
}
177-
178-
// Otherwise the action triggered the leave, which arrives as a PDU our
179-
// handler matches. Wait on its channel rather than polling
180-
// `room.CurrentState`: the room's current state is updated (by
181-
// `room.AddEvent`) *before* the PDU callback runs, so returning on a
182-
// `CurrentState` check could deregister our handler in the window before the
183-
// callback fires, making the (expected) leave look unexpected to
184-
// `HandleTransactionRequests`. This returns as soon as the leave arrives; the
185-
// timeout is only a ceiling for declaring failure.
186-
select {
187-
case <-leaveChannel:
188-
t.Logf("%s saw %s leave test room %s.", s.ServerName(), userID, room.RoomID)
189-
case <-time.After(1 * time.Second):
190-
t.Errorf("%s timed out waiting for %s to leave test room %s.", s.ServerName(), userID, room.RoomID)
191-
}
192-
}
193-
194126
// isInRoom reports whether this Complement server has a joined user in the room,
195127
// according to its own `ServerRoom` view. The server reliably tracks its own
196128
// users' membership (it created their join/leave events), so this answers "will
@@ -2295,7 +2227,7 @@ func TestPartialStateJoin(t *testing.T) {
22952227

22962228
// The room starts with @charlie:server1 and @derek:server1 in it.
22972229
// @elsie:server2 joins the room before @t23alice:hs1.
2298-
server2Room := server2.MustJoinRoom(
2230+
server2.MustJoinRoom(
22992231
t,
23002232
deployment,
23012233
server1.ServerName(),
@@ -2306,7 +2238,6 @@ func TestPartialStateJoin(t *testing.T) {
23062238

23072239
// @t23alice:hs1 joins the room.
23082240
psjResult := beginPartialStateJoin(t, server1, room, alice)
2309-
defer server2.WithWaitForLeave(t, server2Room, alice, func() { psjResult.Destroy(t) })
23102241

23112242
// Both homeservers should receive device list updates.
23122243
renameDevice(t, alice, "A new device name 1")
@@ -2343,17 +2274,14 @@ func TestPartialStateJoin(t *testing.T) {
23432274
t.Log("@charlie and @derek received device list update.")
23442275

23452276
// @elsie:server2 joins the room.
2346-
server2Room := server2.MustJoinRoom(
2277+
server2.MustJoinRoom(
23472278
t,
23482279
deployment,
23492280
server1.ServerName(),
23502281
room.RoomID,
23512282
server2.UserID("elsie"),
23522283
federation.WithPartialState(),
23532284
)
2354-
// NB: We register the `psjResult.Destroy()` cleanup twice. This is alright because it
2355-
// is idempotent. Here we wait for server 2 to observe the leave too.
2356-
defer server2.WithWaitForLeave(t, server2Room, alice, func() { psjResult.Destroy(t) })
23572285
joinEvent := room.CurrentState("m.room.member", server2.UserID("elsie"))
23582286
server1.MustSendTransaction(t, deployment, deployment.GetFullyQualifiedHomeserverName(t, "hs1"), []json.RawMessage{joinEvent.JSON()}, nil)
23592287
awaitEventViaSync(t, alice, room.RoomID, joinEvent.EventID(), "")
@@ -2505,14 +2433,14 @@ func TestPartialStateJoin(t *testing.T) {
25052433
t *testing.T, deployment complement.Deployment, alice *client.CSAPI,
25062434
server1 *server, server2 *server,
25072435
partialStateRoom *federation.ServerRoom, syncToken string,
2508-
) (nextSyncToken string, leaveSharedRoom func()) {
2436+
) (nextSyncToken string) {
25092437
elsie := server2.UserID("elsie")
25102438

25112439
// @alice:hs1 creates a public room.
25122440
roomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"})
25132441

25142442
// @elsie:server2 joins the room.
2515-
server2Room := server2.MustJoinRoom(t, deployment, deployment.GetFullyQualifiedHomeserverName(t, "hs1"), roomID, elsie)
2443+
server2.MustJoinRoom(t, deployment, deployment.GetFullyQualifiedHomeserverName(t, "hs1"), roomID, elsie)
25162444
alice.MustSyncUntil(t,
25172445
client.SyncReq{
25182446
Since: syncToken,
@@ -2529,13 +2457,7 @@ func TestPartialStateJoin(t *testing.T) {
25292457
server1.MustSendTransaction(t, deployment, deployment.GetFullyQualifiedHomeserverName(t, "hs1"), []json.RawMessage{leaveEvent.JSON()}, nil)
25302458
syncToken = awaitEventViaSync(t, alice, partialStateRoom.RoomID, leaveEvent.EventID(), syncToken)
25312459

2532-
leaveSharedRoom = func() {
2533-
server2.WithWaitForLeave(t, server2Room, alice, func() {
2534-
alice.MustLeaveRoom(t, roomID)
2535-
})
2536-
}
2537-
2538-
return syncToken, leaveSharedRoom
2460+
return syncToken
25392461
}
25402462

25412463
// testMissedDeviceListUpdateSentOncePartialJoinCompletes takes a room where hs1 incorrectly
@@ -2561,8 +2483,7 @@ func TestPartialStateJoin(t *testing.T) {
25612483
// The homeserver under test cannot simply use the current state of the room to
25622484
// determine which device list updates it must send out once the partial state join
25632485
// completes.
2564-
_, leaveSharedRoom := setupAnotherSharedRoomThenLeave(t, deployment, alice, server1, server2, room, syncToken)
2565-
defer leaveSharedRoom()
2486+
setupAnotherSharedRoomThenLeave(t, deployment, alice, server1, server2, room, syncToken)
25662487
}
25672488

25682489
// Finish the partial state join.
@@ -2589,8 +2510,7 @@ func TestPartialStateJoin(t *testing.T) {
25892510
// The room starts with @charlie:server1 and @derek:server1 in it.
25902511
// @t26alice:hs1 joins the room, followed by @elsie:server2.
25912512
// @elsie:server2 is kicked with an invalid event.
2592-
syncToken, server2Room, psjResult := setupIncorrectlyAcceptedKick(t, deployment, alice, server1, server2, deviceListUpdateChannel1, deviceListUpdateChannel2, room)
2593-
defer server2.WithWaitForLeave(t, server2Room, alice, func() { psjResult.Destroy(t) })
2513+
syncToken, _, psjResult := setupIncorrectlyAcceptedKick(t, deployment, alice, server1, server2, deviceListUpdateChannel1, deviceListUpdateChannel2, room)
25942514

25952515
// @t26alice:hs1 sends out a device list update which is missed by @elsie:server2.
25962516
// @elsie:server2 must receive missed device list updates once the partial state join finishes.
@@ -2641,7 +2561,7 @@ func TestPartialStateJoin(t *testing.T) {
26412561
// The room starts with @charlie:server1 and @derek:server1 in it.
26422562
// @elsie:server2 joins the room, followed by @t28alice:hs1.
26432563
// server1 does not tell hs1 that server2 is in the room.
2644-
server2Room := server2.MustJoinRoom(
2564+
server2.MustJoinRoom(
26452565
t,
26462566
deployment,
26472567
server1.ServerName(),
@@ -2650,7 +2570,6 @@ func TestPartialStateJoin(t *testing.T) {
26502570
federation.WithPartialState(),
26512571
)
26522572
psjResult := beginPartialStateJoin(t, server1, room, alice)
2653-
defer server2.WithWaitForLeave(t, server2Room, alice, func() { psjResult.Destroy(t) })
26542573

26552574
// @t28alice:hs1 sends out a device list update which is missed by @elsie:server2.
26562575
// @elsie:server2 must receive missed device list updates once the partial state join finishes.
@@ -3045,15 +2964,14 @@ func TestPartialStateJoin(t *testing.T) {
30452964

30462965
// @charlie joins the room.
30472966
// Now @charlie's device list is definitely being tracked.
3048-
otherRoom := server.MustJoinRoom(t, deployment, deployment.GetFullyQualifiedHomeserverName(t, "hs1"), otherRoomID, server.UserID("charlie"))
2967+
server.MustJoinRoom(t, deployment, deployment.GetFullyQualifiedHomeserverName(t, "hs1"), otherRoomID, server.UserID("charlie"))
30492968
alice.MustSyncUntil(t,
30502969
client.SyncReq{
30512970
Since: syncToken,
30522971
Filter: buildLazyLoadingSyncFilter(nil),
30532972
},
30542973
client.SyncJoinedTo(server.UserID("charlie"), otherRoomID),
30552974
)
3056-
defer server.WithWaitForLeave(t, otherRoom, alice, func() { alice.MustLeaveRoom(t, otherRoomID) })
30572975

30582976
// Depending on the homeserver implementation, @t31alice:hs1 must have been told that either:
30592977
// * charlie updated their device list, or
@@ -4455,8 +4373,6 @@ func beginPartialStateJoin(t *testing.T, server *server, serverRoom *federation.
44554373

44564374
// Destroy cleans up the resources associated with the join attempt.
44574375
// It is idempotent and must be called once the test is finished.
4458-
// Specifically, it ensures that the partial state join completes and makes the joining user leave
4459-
// the room.
44604376
func (psj *partialStateJoinResult) Destroy(t *testing.T) {
44614377
if psj.fedStateIdsSendResponseWaiter != nil {
44624378
psj.fedStateIdsSendResponseWaiter.Finish()
@@ -4465,23 +4381,6 @@ func (psj *partialStateJoinResult) Destroy(t *testing.T) {
44654381
if psj.fedStateIdsRequestReceivedWaiter != nil {
44664382
psj.fedStateIdsRequestReceivedWaiter.Finish()
44674383
}
4468-
4469-
// Since the same deployment is being used across multiple tests, ensure that it
4470-
// has finished all federation activity before tearing down the Complement server.
4471-
// Otherwise the homeserver at the Complement's hostname:port combination may be
4472-
// considered offline and interfere with subsequent tests.
4473-
t.Log("Cleaning up after test...")
4474-
4475-
awaitPartialStateJoinCompletion(t, psj.ServerRoom, psj.User)
4476-
4477-
// The caller is about to tear down the Complement homeserver. Leave the room, so
4478-
// that the homeserver under test stops sending it presence updates.
4479-
psj.Server.WithWaitForLeave(
4480-
t,
4481-
psj.ServerRoom,
4482-
psj.User,
4483-
func() { psj.User.MustLeaveRoom(t, psj.ServerRoom.RoomID) },
4484-
)
44854384
}
44864385

44874386
// send a message into the room without letting the homeserver under test know about it.

0 commit comments

Comments
 (0)