Skip to content

Commit e87a374

Browse files
committed
chore: add page limit test
1 parent 3b610e1 commit e87a374

2 files changed

Lines changed: 26 additions & 14 deletions

File tree

internal/commands/relationship.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ func RegisterRelationshipCmd(rootCmd *cobra.Command) *cobra.Command {
106106
relationshipCmd.AddCommand(readCmd)
107107
readCmd.Flags().Bool("json", false, "output as JSON")
108108
readCmd.Flags().String("subject-filter", "", "optional subject filter")
109-
readCmd.Flags().Uint32("page-limit", 100, "limit of relations returned per page")
109+
readCmd.Flags().Uint32("page-limit", 100, "number of relationships queried in each batch when making a no-limit call. used to tune impact on SpiceDB. overridden by --limit when provided")
110+
readCmd.Flags().Uint32("limit", 0, "number of relationships returned in a single request. overrides --page-limit when both are provided.")
110111
readCmd.Flags().String("cursor", "", "resume pagination from a specific cursor token")
111112
readCmd.Flags().Bool("show-cursor", false, "display the cursor token after pagination")
112113
registerConsistencyFlags(readCmd.Flags())
@@ -277,7 +278,13 @@ func readRelationshipsImpl(cmd *cobra.Command, args []string, responseHandler fu
277278

278279
request := &v1.ReadRelationshipsRequest{RelationshipFilter: filter}
279280

280-
limit := cobrautil.MustGetUint32(cmd, "page-limit")
281+
pageSize := cobrautil.MustGetUint32(cmd, "page-limit")
282+
limit := cobrautil.MustGetUint32(cmd, "limit")
283+
limitSet := limit > 0
284+
// If --limit is not set, use --page-size as the per-request limit
285+
if !limitSet {
286+
limit = pageSize
287+
}
281288
request.OptionalLimit = limit
282289
request.Consistency, err = consistencyFromCmd(cmd)
283290
if err != nil {
@@ -325,7 +332,9 @@ func readRelationshipsImpl(cmd *cobra.Command, args []string, responseHandler fu
325332
return err
326333
}
327334

328-
if relCount < limit || limit == 0 {
335+
// If we set an explicit limit or if we find a page smaller than the page limit,
336+
// we stop.
337+
if limitSet || relCount < limit {
329338
break
330339
}
331340

internal/commands/relationship_test.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ func assertRelationshipCount(ctx context.Context, t *testing.T, c client.Client,
820820
require.Equal(t, count, relCount)
821821
}
822822

823-
func testReadRelationshipsCommand(t *testing.T, pageLimit uint32, cursor string, showCursor bool) *cobra.Command {
823+
func testReadRelationshipsCommand(t *testing.T, limit, pageLimit uint32, cursor string, showCursor bool) *cobra.Command {
824824
t.Helper()
825825
return zedtesting.CreateTestCobraCommandWithFlagValue(t,
826826
zedtesting.BoolFlag{FlagName: "consistency-full", FlagValue: true},
@@ -829,6 +829,7 @@ func testReadRelationshipsCommand(t *testing.T, pageLimit uint32, cursor string,
829829
zedtesting.StringFlag{FlagName: "consistency-at-exactly"},
830830
zedtesting.StringFlag{FlagName: "revision"},
831831
zedtesting.StringFlag{FlagName: "subject-filter"},
832+
zedtesting.UintFlag32{FlagName: "limit", FlagValue: limit},
832833
zedtesting.UintFlag32{FlagName: "page-limit", FlagValue: pageLimit},
833834
zedtesting.BoolFlag{FlagName: "json"},
834835
zedtesting.StringFlag{FlagName: "cursor", FlagValue: cursor},
@@ -878,20 +879,22 @@ func TestReadRelationshipsCursor(t *testing.T) {
878879
_, err = c.WriteRelationships(ctx, &v1.WriteRelationshipsRequest{Updates: updates})
879880
require.NoError(t, err)
880881

881-
t.Run("no page limit returns all in one page", func(t *testing.T) {
882+
t.Run("setting limit returns all in one page", func(t *testing.T) {
882883
callback, pages := makeTestCallback()
883884

884-
cmd := testReadRelationshipsCommand(t, 0, "", false)
885+
cmd := testReadRelationshipsCommand(t, 5, 100, "", false)
885886
err := readRelationshipsImpl(cmd, []string{"test/resource"}, callback)
886887
require.NoError(t, err)
887888
require.Len(t, *pages, 1, "there should only be one page of results")
888-
require.Len(t, (*pages)[0], 10, "there should be 10 results in the page")
889+
require.Len(t, (*pages)[0], 5, "there should be 5 results in the page")
889890
})
890891

892+
// When page limit is set and limit is not, it should iterate through all
893+
// results using the page size.
891894
t.Run("page limit paginates through results", func(t *testing.T) {
892895
callback, pages := makeTestCallback()
893896

894-
cmd := testReadRelationshipsCommand(t, 3, "", false)
897+
cmd := testReadRelationshipsCommand(t, 0, 3, "", false)
895898
err := readRelationshipsImpl(cmd, []string{"test/resource"}, callback)
896899
require.NoError(t, err)
897900
require.NoError(t, err)
@@ -914,7 +917,7 @@ func TestReadRelationshipsCursor(t *testing.T) {
914917
fmt.Fprintf(&output, format, a...)
915918
}
916919

917-
cmd := testReadRelationshipsCommand(t, 3, "", true)
920+
cmd := testReadRelationshipsCommand(t, 5, 100, "", true)
918921
err := readRelationships(cmd, []string{"test/resource"})
919922
require.NoError(t, err)
920923
require.Contains(t, output.String(), "Last cursor: ")
@@ -948,22 +951,22 @@ func TestReadRelationshipsCursor(t *testing.T) {
948951
require.NotNil(t, resumeCursor)
949952
require.NotEmpty(t, resumeCursor.Token)
950953

951-
// Now call read with the cursor and confirm only the remaining 6 are emitted.
954+
// Now call read with the cursor and confirm only 4 are emitted
952955
callback, pages := makeTestCallback()
953956

954-
cmd := testReadRelationshipsCommand(t, resumePageLimit, resumeCursor.Token, false)
957+
cmd := testReadRelationshipsCommand(t, resumePageLimit, 100, resumeCursor.Token, false)
955958
err = readRelationshipsImpl(cmd, []string{"test/resource"}, callback)
956959
require.NoError(t, err)
957-
require.Len(t, *pages, 2)
960+
require.Len(t, *pages, 1)
958961

959962
lengths := slicez.Map(*pages, func(page []*v1.ReadRelationshipsResponse) int {
960963
return len(page)
961964
})
962-
require.Equal(t, []int{4, 2}, lengths)
965+
require.Equal(t, []int{4}, lengths)
963966
})
964967

965968
t.Run("invalid cursor returns error", func(t *testing.T) {
966-
cmd := testReadRelationshipsCommand(t, 0, "not-a-real-cursor", false)
969+
cmd := testReadRelationshipsCommand(t, 0, 100, "not-a-real-cursor", false)
967970
err := readRelationships(cmd, []string{"test/resource"})
968971
require.Error(t, err)
969972
})

0 commit comments

Comments
 (0)