diff --git a/tests/federation_room_join_partial_state_test.go b/tests/federation_room_join_partial_state_test.go index 72693e05..3210c820 100644 --- a/tests/federation_room_join_partial_state_test.go +++ b/tests/federation_room_join_partial_state_test.go @@ -20,6 +20,7 @@ import ( "github.com/gorilla/mux" "github.com/tidwall/gjson" + "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -489,6 +490,51 @@ func testReceiveEventDuringPartialStateJoin( t.Fatalf("GET /event failed with %d: %s", res.StatusCode, string(eventResBody)) } + // fire off a /state_ids request for the last event. + // it must either: + // * block because the homeserver does not have full state at the last event + // * or 403 because the homeserver does not have full state yet and does not consider the + // Complement homeserver to be in the room + stateIdsResponseChan := make(chan *gomatrixserverlib.RespStateIDs) + defer close(stateIdsResponseChan) + go func() { + stateReq := gomatrixserverlib.NewFederationRequest("GET", "hs1", + fmt.Sprintf("/_matrix/federation/v1/state_ids/%s?event_id=%s", + url.PathEscape(psjResult.ServerRoom.RoomID), + url.QueryEscape(event.EventID()), + ), + ) + var respStateIDs gomatrixserverlib.RespStateIDs + if err := psjResult.Server.SendFederationRequest(deployment, stateReq, &respStateIDs); err != nil { + httpErr, ok := err.(gomatrix.HTTPError) + t.Logf("%v", httpErr) + if ok && httpErr.Code == 403 { + stateIdsResponseChan <- nil + return + } + t.Errorf("/state_ids request returned non-200: %s", err) + return + } + stateIdsResponseChan <- &respStateIDs + }() + + select { + case <-time.After(1 * time.Second): + t.Logf("/state_ids request for event %s blocked as expected", event.EventID()) + defer func() { <-stateIdsResponseChan }() + break + case respStateIDs := <-stateIdsResponseChan: + if respStateIDs == nil { + t.Logf("/state_ids request for event %s returned 403 as expected", event.EventID()) + } else { + // since we have not yet given the homeserver the full state at the join event and allowed + // the partial join to complete, it can't possibly know the full state at the last event. + // While it may be possible for the response to be correct by some accident of state res, + // the homeserver is still wrong in spirit. + t.Fatalf("/state_ids request for event %s did not block when it should have", event.EventID()) + } + } + // allow the partial join to complete psjResult.FinishStateRequest() alice.MustSyncUntil(t,