Skip to content

Commit

Permalink
Some cleanup and improving federation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MadLittleMods committed Jul 14, 2021
1 parent 1f780ec commit 425206d
Showing 1 changed file with 77 additions and 11 deletions.
88 changes: 77 additions & 11 deletions tests/msc2716_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,9 @@ var (
insertionEventType = "org.matrix.msc2716.insertion"
markerEventType = "org.matrix.msc2716.marker"

historicalContentField = "org.matrix.msc2716.historical"
nextChunkIdContentField = "org.matrix.msc2716.next_chunk_id"
chunkIdContentField = "org.matrix.msc2716.chunk_id"
markerInsertionContentField = "org.matrix.msc2716.marker.insertion"
markerInsertionPrevEventsContentField = "org.matrix.msc2716.marker.insertion_prev_events"
historicalContentField = "org.matrix.msc2716.historical"
nextChunkIDContentField = "org.matrix.msc2716.next_chunk_id"
markerInsertionContentField = "org.matrix.msc2716.marker.insertion"
)

func TestBackfillingHistory(t *testing.T) {
Expand Down Expand Up @@ -166,7 +164,7 @@ func TestBackfillingHistory(t *testing.T) {
JSON: []match.JSON{
match.JSONArrayEach("chunk", func(r gjson.Result) error {
// Find all events in order
if len(r.Get("content").Get("body").Str) > 0 || r.Get("type").Str == insertionEventType || r.Get("type").Str == markerEventType {
if isRelevantEvent(r) {
// Pop the next message off the expected list
nextEventIdInOrder := workingExpectedEventIDOrder[0]
workingExpectedEventIDOrder = workingExpectedEventIDOrder[1:]
Expand Down Expand Up @@ -229,7 +227,7 @@ func TestBackfillingHistory(t *testing.T) {

must.MatchResponse(t, messagesRes, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOffAllowUnwanted("chunk", []interface{}{historicalEventIDs[0], historicalEventIDs[1], historicalEventIDs[2]}, func(r gjson.Result) interface{} {
match.JSONCheckOffAllowUnwanted("chunk", makeInterfaceSlice(historicalEventIDs), func(r gjson.Result) interface{} {
return r.Get("event_id").Str
}, nil),
},
Expand Down Expand Up @@ -379,14 +377,16 @@ func TestBackfillingHistory(t *testing.T) {
// Join the room from a remote homeserver after the backfilled messages were sent
remoteCharlie.JoinRoom(t, roomID, []string{"hs1"})

// TODO: I think we need to update this to be similar to
// SyncUntilTimelineHas but going back in time because this can be flakey
messagesRes := remoteCharlie.MustDoFunc(t, "GET", []string{"_matrix", "client", "r0", "rooms", roomID, "messages"}, client.WithContentType("application/json"), client.WithQueries(url.Values{
"dir": []string{"b"},
"limit": []string{"100"},
}))

must.MatchResponse(t, messagesRes, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOffAllowUnwanted("chunk", []interface{}{historicalEventIDs[0], historicalEventIDs[1]}, func(r gjson.Result) interface{} {
match.JSONCheckOffAllowUnwanted("chunk", makeInterfaceSlice(historicalEventIDs), func(r gjson.Result) interface{} {
return r.Get("event_id").Str
}, nil),
},
Expand Down Expand Up @@ -434,6 +434,57 @@ func TestBackfillingHistory(t *testing.T) {
)
batchSendResBody := client.ParseJSON(t, batchSendRes)
historicalEventIDs := getEventsFromBatchSendResponseBody(t, batchSendResBody)
baseInsertionEventID := historicalEventIDs[len(historicalEventIDs)-1]

// 2 historical events + 2 insertion events
if len(historicalEventIDs) != 4 {
t.Fatalf("Expected eventID list should be length 15 but saw %d: %s", len(historicalEventIDs), historicalEventIDs)
}

beforeMarkerMessagesRes := remoteCharlie.MustDoFunc(t, "GET", []string{"_matrix", "client", "r0", "rooms", roomID, "messages"}, client.WithContentType("application/json"), client.WithQueries(url.Values{
"dir": []string{"b"},
"limit": []string{"100"},
}))
beforeMarkerMesssageResBody := client.ParseJSON(t, beforeMarkerMessagesRes)
eventDebugStringsFromBeforeMarkerResponse := getRelevantEventDebugStringsFromMessagesResponse(t, beforeMarkerMesssageResBody)
// Since the original body can only be read once, create a new one from the body bytes we just read
beforeMarkerMessagesRes.Body = ioutil.NopCloser(bytes.NewBuffer(beforeMarkerMesssageResBody))

// Make sure the history isn't visible before we expect it to be there.
// This is to avoid some bug in the homeserver using some unknown
// mechanism to distribute the historical messages to other homeservers.
must.MatchResponse(t, beforeMarkerMessagesRes, match.HTTPResponse{
JSON: []match.JSON{
match.JSONArrayEach("chunk", func(r gjson.Result) error {
// Throw if we find one of the historical events in the message response
for _, historicalEventID := range historicalEventIDs {
if r.Get("event_id").Str == historicalEventID {
return fmt.Errorf("Historical event (%s) found on remote homeserver before marker event was sent out\nmessage response (%d): %v\nhistoricalEventIDs (%d): %v", historicalEventID, len(eventDebugStringsFromBeforeMarkerResponse), eventDebugStringsFromBeforeMarkerResponse, len(historicalEventIDs), historicalEventIDs)
}
}

return nil
}),
},
})

// Send a marker event to let all of the homeservers know about the
// insertion point where all of the historical messages are at
markerEvent := b.Event{
Type: markerEventType,
Content: map[string]interface{}{
markerInsertionContentField: baseInsertionEventID,
},
}
// We can't use as.SendEventSynced(...) because application services can't use the /sync API
markerSendRes := as.MustDoFunc(t, "PUT", []string{"_matrix", "client", "r0", "rooms", roomID, "send", markerEvent.Type, "txn-m123"}, client.WithJSONBody(t, markerEvent.Content))
markerSendBody := client.ParseJSON(t, markerSendRes)
markerEventID := client.GetJSONFieldStr(t, markerSendBody, "event_id")

// Make sure the marker event has reached the remote homeserver
remoteCharlie.SyncUntilTimelineHas(t, roomID, func(ev gjson.Result) bool {
return ev.Get("event_id").Str == markerEventID
})

messagesRes := remoteCharlie.MustDoFunc(t, "GET", []string{"_matrix", "client", "r0", "rooms", roomID, "messages"}, client.WithContentType("application/json"), client.WithQueries(url.Values{
"dir": []string{"b"},
Expand All @@ -442,7 +493,7 @@ func TestBackfillingHistory(t *testing.T) {

must.MatchResponse(t, messagesRes, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOffAllowUnwanted("chunk", []interface{}{historicalEventIDs[0], historicalEventIDs[1]}, func(r gjson.Result) interface{} {
match.JSONCheckOffAllowUnwanted("chunk", makeInterfaceSlice(historicalEventIDs), func(r gjson.Result) interface{} {
return r.Get("event_id").Str
}, nil),
},
Expand Down Expand Up @@ -492,14 +543,16 @@ func TestBackfillingHistory(t *testing.T) {
batchSendResBody := client.ParseJSON(t, batchSendRes)
historicalEventIDs := getEventsFromBatchSendResponseBody(t, batchSendResBody)

// TODO: Send marker event

messagesRes := remoteCharlie.MustDoFunc(t, "GET", []string{"_matrix", "client", "r0", "rooms", roomID, "messages"}, client.WithContentType("application/json"), client.WithQueries(url.Values{
"dir": []string{"b"},
"limit": []string{"100"},
}))

must.MatchResponse(t, messagesRes, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOffAllowUnwanted("chunk", []interface{}{historicalEventIDs[0], historicalEventIDs[1]}, func(r gjson.Result) interface{} {
match.JSONCheckOffAllowUnwanted("chunk", makeInterfaceSlice(historicalEventIDs), func(r gjson.Result) interface{} {
return r.Get("event_id").Str
}, nil),
},
Expand All @@ -508,6 +561,15 @@ func TestBackfillingHistory(t *testing.T) {
})
}

func makeInterfaceSlice(slice []string) []interface{} {
interfaceSlice := make([]interface{}, len(slice))
for i := range slice {
interfaceSlice[i] = slice[i]
}

return interfaceSlice
}

func reversed(in []string) []string {
out := make([]string, len(in))
for i := 0; i < len(in); i++ {
Expand All @@ -516,6 +578,10 @@ func reversed(in []string) []string {
return out
}

func isRelevantEvent(r gjson.Result) bool {
return len(r.Get("content").Get("body").Str) > 0 || r.Get("type").Str == insertionEventType || r.Get("type").Str == markerEventType
}

func getRelevantEventDebugStringsFromMessagesResponse(t *testing.T, body []byte) (eventIDsFromResponse []string) {
t.Helper()

Expand All @@ -529,7 +595,7 @@ func getRelevantEventDebugStringsFromMessagesResponse(t *testing.T, body []byte)
}

res.ForEach(func(key, r gjson.Result) bool {
if len(r.Get("content").Get("body").Str) > 0 || r.Get("type").Str == insertionEventType || r.Get("type").Str == markerEventType {
if isRelevantEvent(r) {
eventIDsFromResponse = append(eventIDsFromResponse, r.Get("event_id").Str+" ("+r.Get("content").Get("body").Str+")")
}
return true
Expand Down

0 comments on commit 425206d

Please sign in to comment.