Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Baby steps for testing leaves during a faster join #581

Merged
merged 3 commits into from
Jan 12, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions tests/federation_room_join_partial_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3180,6 +3180,127 @@ func TestPartialStateJoin(t *testing.T) {
}
must.MatchResponse(t, response, spec)
})

t.Run("Leaving during resync is seen after the resync", func(t *testing.T) {
// Before testing that leaves during resyncs are seen during resyncs, sanity
// check that leaves during resyncs appear after the resync.
t.Log("Alice begins a partial join to a room")
alice := deployment.RegisterUser(t, "hs1", "t42alice", "secret", false)
handleTransactions := federation.HandleTransactionRequests(
// Accept all PDUs and EDUs
func(e *gomatrixserverlib.Event) {},
func(e gomatrixserverlib.EDU) {},
)
server := createTestServer(t, deployment, handleTransactions)
cancel := server.Listen()
defer cancel()

serverRoom := createTestRoom(t, server, alice.GetDefaultRoomVersion(t))
t.Log("Alice partial-joins her room")
psjResult := beginPartialStateJoin(t, server, serverRoom, alice)
defer psjResult.Destroy(t)

t.Log("Alice waits to see her join")
aliceNextBatch := alice.MustSyncUntil(
t,
client.SyncReq{Filter: buildLazyLoadingSyncFilter(nil)},
client.SyncJoinedTo(alice.UserID, serverRoom.RoomID),
)

leaveCompleted := NewWaiter()
t.Log("Alice starts a leave request")
go func() {
alice.LeaveRoom(t, serverRoom.RoomID)
t.Log("Alice's leave request completed")
leaveCompleted.Finish()
}()

// We want Synapse to receive the leave before its resync completes.
// HACK: Use a sleep to try and ensure this.
time.Sleep(250 * time.Millisecond)
t.Log("The resync finishes")
psjResult.FinishStateRequest()

// Now that we've resynced, the leave call should be unblocked.
leaveCompleted.Wait(t, 1*time.Second)

t.Log("Alice waits to see her leave appear down /sync")
aliceNextBatch = alice.MustSyncUntil(
t,
client.SyncReq{Since: aliceNextBatch, Filter: buildLazyLoadingSyncFilter(nil)},
client.SyncLeftFrom(alice.UserID, serverRoom.RoomID),
)
})

t.Run("Leaving a room immediately after joining does not wait for resync", func(t *testing.T) {
t.Skip("Not yet implemented (synapse#12802)")
// Prepare to listen for leave events from the HS under test.
// We're only expecting one leave event, but give the channel extra capacity
// to avoid deadlock if the HS does something silly.
leavesChannel := make(chan *gomatrixserverlib.Event, 10)
handleTransactions := federation.HandleTransactionRequests(
func(e *gomatrixserverlib.Event) {
if e.Type() == "m.room.member" {
if ok := gjson.ValidBytes(e.Content()); !ok {
t.Fatalf("Received event %s with invalid content: %v", e.EventID(), e.Content())
}
content := gjson.ParseBytes(e.Content())
membership := content.Get("membership")
if membership.Exists() && membership.Str == "leave" {
leavesChannel <- e
}
}
},
// we don't care about EDUs
func(e gomatrixserverlib.EDU) {},
)

t.Log("Alice begins a partial join to a room")
alice := deployment.RegisterUser(t, "hs1", "t43alice", "secret", false)
server := createTestServer(
t,
deployment,
handleTransactions,
)
cancel := server.Listen()
defer cancel()

serverRoom := createTestRoom(t, server, alice.GetDefaultRoomVersion(t))
psjResult := beginPartialStateJoin(t, server, serverRoom, alice)
defer psjResult.Destroy(t)

t.Log("Alice waits to see her join")
aliceNextBatch := alice.MustSyncUntil(
t,
client.SyncReq{Filter: buildLazyLoadingSyncFilter(nil)},
client.SyncJoinedTo(alice.UserID, serverRoom.RoomID),
)

t.Log("Alice leaves and waits for confirmation")
alice.LeaveRoom(t, serverRoom.RoomID)
aliceNextBatch = alice.MustSyncUntil(
t,
client.SyncReq{Since: aliceNextBatch, Filter: buildLazyLoadingSyncFilter(nil)},
client.SyncLeftFrom(alice.UserID, serverRoom.RoomID),
)

t.Logf("Alice's leave is recieved by the resident server")
select {
case <-time.After(1 * time.Second):
t.Fatal("Resident server did not receive Alice's leave")
case e := <-leavesChannel:
if e.Sender() != alice.UserID {
t.Errorf("Unexpected leave event %s for %s", e.EventID(), e.Sender())
}
}
})

// TODO: tests which assert that:
// - Join+Join+Leave+Leave works
// - Join+Leave+Join works
// - Join+Leave+Rejoin works
// - Join + remote kick works
// - Join + remote ban works, then cannot rejoin
}

// test reception of an event over federation during a resync
Expand Down