From fd0dd79c85b467379a67b0d88ee9ed800ce1b880 Mon Sep 17 00:00:00 2001 From: Shane Jaroch Date: Fri, 17 Jul 2026 07:02:04 -0400 Subject: [PATCH] Guard against homeservers stuck in a `/messages` pagination loop Signed-off-by: Shane Jaroch --- tests/csapi/room_messages_test.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/csapi/room_messages_test.go b/tests/csapi/room_messages_test.go index b21aa55a..1d3ab702 100644 --- a/tests/csapi/room_messages_test.go +++ b/tests/csapi/room_messages_test.go @@ -427,7 +427,18 @@ func _sendAndTestMessageHistory( testCase.numberOfMessagesToSend, ) fromToken := "" - for { + // Guard against a buggy homeserver that never terminates pagination (e.g. it + // keeps returning an `end` token, possibly oscillating between a small set of + // tokens like `[-1, 1]` -> `[1, -1]` -> ...). Without this, the test would spin + // until the overall test timeout (which can be as long as 3600s) instead of + // failing fast with a useful error. + seenTokens := map[string]bool{fromToken: true} + maxIterations := testCase.numberOfMessagesToSend + 1 + for iteration := 0; ; iteration++ { + if iteration >= maxIterations { + t.Fatalf("paginated %d times without reaching the start of the room (no `end` token) -- homeserver may be stuck in a pagination loop", iteration) + } + messageQueryParams := url.Values{ "dir": []string{"b"}, "limit": []string{strconv.Itoa(testCase.messagesRequestLimit)}, @@ -472,6 +483,11 @@ func _sendAndTestMessageHistory( break } fromToken = endTokenRes.Str + + if seenTokens[fromToken] { + t.Fatalf("homeserver returned a pagination token (%s) we've already seen -- it appears to be stuck in loop or repeating elements", fromToken) + } + seenTokens[fromToken] = true } // Put them in chronological order to match the expected list