From ffb3e098eaa5ecb714e91199e417db7b23c47fbb Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Fri, 2 Oct 2026 03:01:08 +0000 Subject: [PATCH] test(apiserver): GetJobsInfo pagination returns every row once (bug-1903) Follows page_token with limit=3 over the handler fixture. Before efff6b65 the token's float-rounded array-element ID matched no row and every page restarted at row 0 (the original repeat-the-first-page report); it now pages through every row exactly once. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../controllers/jobs_handler_test.go | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/frontend/apiserver/controllers/jobs_handler_test.go b/src/frontend/apiserver/controllers/jobs_handler_test.go index 5969fa42..14b6f529 100644 --- a/src/frontend/apiserver/controllers/jobs_handler_test.go +++ b/src/frontend/apiserver/controllers/jobs_handler_test.go @@ -1383,3 +1383,49 @@ func TestJobHandler_ControlFilterPlainNameWithSpaces(t *testing.T) { assertExactIDs(t, "-J 'sleep 100' dispatched", f.dispatchedIDs(), []uint64{O}) assertExactIDs(t, "-J 'sleep 100' accepted", itemIDs(t, r.Accepted), []uint64{O}) } + +// bug-1903: following GetJobsInfo's page_token yields the next page, every +// row exactly once, and the last page carries no token. +func TestJobHandler_QueryPagination(t *testing.T) { + f := newHandlerFixture(t) + s := seedQueryJobs(f) + filter := url.QueryEscape("{submit_user:eq:" + handlerTestUser + "}") + + var got []uint64 + token := "" + for page := 0; ; page++ { + if page > 10 { + t.Fatalf("paging did not terminate; rows so far %v", got) + } + path := "/xce/v1/jobs?limit=3&filter=" + filter + if token != "" { + path += "&page_token=" + url.QueryEscape(token) + } + w := f.do(http.MethodGet, path, nil) + got = append(got, rowIDs(t, w)...) + + var reply struct { + Data struct { + PageToken string `json:"page_token"` + } `json:"data"` + } + if err := json.Unmarshal(w.Body.Bytes(), &reply); err != nil { + t.Fatalf("decode page_token: %v", err) + } + if reply.Data.PageToken == "" { + break + } + token = reply.Data.PageToken + } + + seen := map[uint64]int{} + for _, id := range got { + seen[id]++ + } + for id, n := range seen { + if n != 1 { + t.Errorf("row %d returned %d times", id, n) + } + } + assertIDs(t, "all pages", sortedIDs(got...), s.all()) +}