1 package redis_test
2
3 import (
4 "fmt"
5
6 . "github.com/bsm/ginkgo/v2"
7 . "github.com/bsm/gomega"
8
9 "github.com/redis/go-redis/v9"
10 )
11
12 var _ = Describe("ScanIterator", func() {
13 var client *redis.Client
14
15 seed := func(n int) error {
16 pipe := client.Pipeline()
17 for i := 1; i <= n; i++ {
18 pipe.Set(ctx, fmt.Sprintf("K%02d", i), "x", 0).Err()
19 }
20 _, err := pipe.Exec(ctx)
21 return err
22 }
23
24 extraSeed := func(n int, m int) error {
25 pipe := client.Pipeline()
26 for i := 1; i <= m; i++ {
27 pipe.Set(ctx, fmt.Sprintf("A%02d", i), "x", 0).Err()
28 }
29 for i := 1; i <= n; i++ {
30 pipe.Set(ctx, fmt.Sprintf("K%02d", i), "x", 0).Err()
31 }
32 _, err := pipe.Exec(ctx)
33 return err
34 }
35
36 hashKey := "K_HASHTEST"
37 hashSeed := func(n int) error {
38 pipe := client.Pipeline()
39 for i := 1; i <= n; i++ {
40 pipe.HSet(ctx, hashKey, fmt.Sprintf("K%02d", i), "x").Err()
41 }
42 _, err := pipe.Exec(ctx)
43 return err
44 }
45
46 BeforeEach(func() {
47 client = redis.NewClient(redisOptions())
48 Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred())
49 })
50
51 AfterEach(func() {
52 Expect(client.Close()).NotTo(HaveOccurred())
53 })
54
55 It("should scan across empty DBs", func() {
56 iter := client.Scan(ctx, 0, "", 10).Iterator()
57 Expect(iter.Next(ctx)).To(BeFalse())
58 Expect(iter.Err()).NotTo(HaveOccurred())
59 })
60
61 It("should scan across one page", func() {
62 Expect(seed(7)).NotTo(HaveOccurred())
63
64 var vals []string
65 iter := client.Scan(ctx, 0, "", 0).Iterator()
66 for iter.Next(ctx) {
67 vals = append(vals, iter.Val())
68 }
69 Expect(iter.Err()).NotTo(HaveOccurred())
70 Expect(vals).To(ConsistOf([]string{"K01", "K02", "K03", "K04", "K05", "K06", "K07"}))
71 })
72
73 It("should scan across multiple pages", func() {
74 Expect(seed(71)).NotTo(HaveOccurred())
75
76 var vals []string
77 iter := client.Scan(ctx, 0, "", 10).Iterator()
78 for iter.Next(ctx) {
79 vals = append(vals, iter.Val())
80 }
81 Expect(iter.Err()).NotTo(HaveOccurred())
82 Expect(vals).To(HaveLen(71))
83 Expect(vals).To(ContainElement("K01"))
84 Expect(vals).To(ContainElement("K71"))
85 })
86
87 It("should hscan across multiple pages", func() {
88 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
89 Expect(hashSeed(71)).NotTo(HaveOccurred())
90
91 var vals []string
92 iter := client.HScan(ctx, hashKey, 0, "", 10).Iterator()
93 for iter.Next(ctx) {
94 vals = append(vals, iter.Val())
95 }
96 Expect(iter.Err()).NotTo(HaveOccurred())
97 Expect(vals).To(HaveLen(71 * 2))
98 Expect(vals).To(ContainElement("K01"))
99 Expect(vals).To(ContainElement("K71"))
100 Expect(vals).To(ContainElement("x"))
101 })
102
103 It("should hscan without values across multiple pages", Label("NonRedisEnterprise"), func() {
104 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
105 Expect(hashSeed(71)).NotTo(HaveOccurred())
106
107 var vals []string
108 iter := client.HScanNoValues(ctx, hashKey, 0, "", 10).Iterator()
109 for iter.Next(ctx) {
110 vals = append(vals, iter.Val())
111 }
112 Expect(iter.Err()).NotTo(HaveOccurred())
113 Expect(vals).To(HaveLen(71))
114 Expect(vals).To(ContainElement("K01"))
115 Expect(vals).To(ContainElement("K71"))
116 Expect(vals).NotTo(ContainElement("x"))
117 })
118
119 It("should scan to page borders", func() {
120 Expect(seed(20)).NotTo(HaveOccurred())
121
122 var vals []string
123 iter := client.Scan(ctx, 0, "", 10).Iterator()
124 for iter.Next(ctx) {
125 vals = append(vals, iter.Val())
126 }
127 Expect(iter.Err()).NotTo(HaveOccurred())
128 Expect(vals).To(HaveLen(20))
129 })
130
131 It("should scan with match", func() {
132 Expect(seed(33)).NotTo(HaveOccurred())
133
134 var vals []string
135 iter := client.Scan(ctx, 0, "K*2*", 10).Iterator()
136 for iter.Next(ctx) {
137 vals = append(vals, iter.Val())
138 }
139 Expect(iter.Err()).NotTo(HaveOccurred())
140 Expect(vals).To(HaveLen(13))
141 })
142
143 It("should scan with match across empty pages", func() {
144 Expect(extraSeed(2, 10)).NotTo(HaveOccurred())
145
146 var vals []string
147 iter := client.Scan(ctx, 0, "K*", 1).Iterator()
148 for iter.Next(ctx) {
149 vals = append(vals, iter.Val())
150 }
151 Expect(iter.Err()).NotTo(HaveOccurred())
152 Expect(vals).To(HaveLen(2))
153 })
154 })
155
View as plain text