1 package redis_test
2
3 import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "reflect"
8 "strconv"
9 "time"
10
11 . "github.com/bsm/ginkgo/v2"
12 . "github.com/bsm/gomega"
13
14 "github.com/redis/go-redis/v9"
15 "github.com/redis/go-redis/v9/internal/proto"
16 )
17
18 type TimeValue struct {
19 time.Time
20 }
21
22 func (t *TimeValue) ScanRedis(s string) (err error) {
23 t.Time, err = time.Parse(time.RFC3339Nano, s)
24 return
25 }
26
27 var _ = Describe("Commands", func() {
28 ctx := context.TODO()
29 var client *redis.Client
30
31 BeforeEach(func() {
32 client = redis.NewClient(redisOptions())
33 Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred())
34 })
35
36 AfterEach(func() {
37 Expect(client.Close()).NotTo(HaveOccurred())
38 })
39
40 Describe("server", func() {
41 It("should Auth", func() {
42 cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error {
43 pipe.Auth(ctx, "password")
44 pipe.Auth(ctx, "")
45 return nil
46 })
47 Expect(err).To(HaveOccurred())
48 Expect(err.Error()).To(ContainSubstring("ERR AUTH"))
49 Expect(cmds[0].Err().Error()).To(ContainSubstring("ERR AUTH"))
50 Expect(cmds[1].Err().Error()).To(ContainSubstring("ERR AUTH"))
51
52 stats := client.PoolStats()
53 Expect(stats.Hits).To(Equal(uint32(1)))
54 Expect(stats.Misses).To(Equal(uint32(1)))
55 Expect(stats.Timeouts).To(Equal(uint32(0)))
56 Expect(stats.TotalConns).To(Equal(uint32(1)))
57 Expect(stats.IdleConns).To(Equal(uint32(1)))
58 })
59
60 It("should hello", func() {
61 cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error {
62 pipe.Hello(ctx, 3, "", "", "")
63 return nil
64 })
65 Expect(err).NotTo(HaveOccurred())
66 m, err := cmds[0].(*redis.MapStringInterfaceCmd).Result()
67 Expect(err).NotTo(HaveOccurred())
68 Expect(m["proto"]).To(Equal(int64(3)))
69 })
70
71 It("should Echo", func() {
72 pipe := client.Pipeline()
73 echo := pipe.Echo(ctx, "hello")
74 _, err := pipe.Exec(ctx)
75 Expect(err).NotTo(HaveOccurred())
76
77 Expect(echo.Err()).NotTo(HaveOccurred())
78 Expect(echo.Val()).To(Equal("hello"))
79 })
80
81 It("should Ping", func() {
82 ping := client.Ping(ctx)
83 Expect(ping.Err()).NotTo(HaveOccurred())
84 Expect(ping.Val()).To(Equal("PONG"))
85 })
86
87 It("should Ping with Do method", func() {
88 result := client.Conn().Do(ctx, "PING")
89 Expect(result.Err()).NotTo(HaveOccurred())
90 Expect(result.Val()).To(Equal("PONG"))
91 })
92
93 It("should Wait", func() {
94 const wait = 3 * time.Second
95
96
97 start := time.Now()
98 val, err := client.Wait(ctx, 1, wait).Result()
99 Expect(err).NotTo(HaveOccurred())
100 Expect(val).To(Equal(int64(0)))
101 Expect(time.Now()).To(BeTemporally("~", start.Add(wait), 3*time.Second))
102 })
103
104 It("should WaitAOF", func() {
105 const waitAOF = 3 * time.Second
106 Skip("flaky test")
107
108
109 start := time.Now()
110 val, err := client.WaitAOF(ctx, 1, 1, waitAOF).Result()
111 Expect(err).NotTo(HaveOccurred())
112 Expect(val).NotTo(ContainSubstring("ERR WAITAOF cannot be used when numlocal is set but appendonly is disabled"))
113 Expect(time.Now()).To(BeTemporally("~", start.Add(waitAOF), 3*time.Second))
114 })
115
116 It("should Select", Label("NonRedisEnterprise"), func() {
117 pipe := client.Pipeline()
118 sel := pipe.Select(ctx, 1)
119 _, err := pipe.Exec(ctx)
120 Expect(err).NotTo(HaveOccurred())
121
122 Expect(sel.Err()).NotTo(HaveOccurred())
123 Expect(sel.Val()).To(Equal("OK"))
124 })
125
126 It("should SwapDB", Label("NonRedisEnterprise"), func() {
127 pipe := client.Pipeline()
128 sel := pipe.SwapDB(ctx, 1, 2)
129 _, err := pipe.Exec(ctx)
130 Expect(err).NotTo(HaveOccurred())
131
132 Expect(sel.Err()).NotTo(HaveOccurred())
133 Expect(sel.Val()).To(Equal("OK"))
134 })
135
136 It("should BgRewriteAOF", func() {
137 Skip("flaky test")
138
139 val, err := client.BgRewriteAOF(ctx).Result()
140 Expect(err).NotTo(HaveOccurred())
141 Expect(val).To(ContainSubstring("Background append only file rewriting"))
142 })
143
144 It("should BgSave", func() {
145 Skip("flaky test")
146
147
148 Eventually(func() string {
149 return client.BgSave(ctx).Val()
150 }, "30s").Should(Equal("Background saving started"))
151 })
152
153 It("Should CommandGetKeys", func() {
154 keys, err := client.CommandGetKeys(ctx, "MSET", "a", "b", "c", "d", "e", "f").Result()
155 Expect(err).NotTo(HaveOccurred())
156 Expect(keys).To(Equal([]string{"a", "c", "e"}))
157
158 keys, err = client.CommandGetKeys(ctx, "EVAL", "not consulted", "3", "key1", "key2", "key3", "arg1", "arg2", "arg3", "argN").Result()
159 Expect(err).NotTo(HaveOccurred())
160 Expect(keys).To(Equal([]string{"key1", "key2", "key3"}))
161
162 keys, err = client.CommandGetKeys(ctx, "SORT", "mylist", "ALPHA", "STORE", "outlist").Result()
163 Expect(err).NotTo(HaveOccurred())
164 Expect(keys).To(Equal([]string{"mylist", "outlist"}))
165
166 _, err = client.CommandGetKeys(ctx, "FAKECOMMAND", "arg1", "arg2").Result()
167 Expect(err).To(HaveOccurred())
168 Expect(err).To(MatchError("ERR Invalid command specified"))
169 })
170
171 It("should CommandGetKeysAndFlags", func() {
172 keysAndFlags, err := client.CommandGetKeysAndFlags(ctx, "LMOVE", "mylist1", "mylist2", "left", "left").Result()
173 Expect(err).NotTo(HaveOccurred())
174 Expect(keysAndFlags).To(Equal([]redis.KeyFlags{
175 {
176 Key: "mylist1",
177 Flags: []string{"RW", "access", "delete"},
178 },
179 {
180 Key: "mylist2",
181 Flags: []string{"RW", "insert"},
182 },
183 }))
184
185 _, err = client.CommandGetKeysAndFlags(ctx, "FAKECOMMAND", "arg1", "arg2").Result()
186 Expect(err).To(HaveOccurred())
187 Expect(err).To(MatchError("ERR Invalid command specified"))
188 })
189
190 It("should ClientKill", func() {
191 r := client.ClientKill(ctx, "1.1.1.1:1111")
192 Expect(r.Err()).To(MatchError("ERR No such client"))
193 Expect(r.Val()).To(Equal(""))
194 })
195
196 It("should ClientKillByFilter", func() {
197 r := client.ClientKillByFilter(ctx, "TYPE", "test")
198 Expect(r.Err()).To(MatchError("ERR Unknown client type 'test'"))
199 Expect(r.Val()).To(Equal(int64(0)))
200 })
201
202 It("should ClientKillByFilter with MAXAGE", Label("NonRedisEnterprise"), func() {
203 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
204 var s []string
205 started := make(chan bool)
206 done := make(chan bool)
207
208 go func() {
209 defer GinkgoRecover()
210
211 started <- true
212 blpop := client.BLPop(ctx, 0, "list")
213 Expect(blpop.Val()).To(Equal(s))
214 done <- true
215 }()
216 <-started
217
218 select {
219 case <-done:
220 Fail("BLPOP is not blocked.")
221 case <-time.After(1100 * time.Millisecond):
222
223 }
224
225 killed := client.ClientKillByFilter(ctx, "MAXAGE", "1")
226 Expect(killed.Err()).NotTo(HaveOccurred())
227 Expect(killed.Val()).To(BeNumerically(">=", 1))
228
229 select {
230 case <-done:
231
232 case <-time.After(200 * time.Millisecond):
233 Fail("BLPOP is still blocked.")
234 }
235 })
236
237 It("should ClientID", func() {
238 err := client.ClientID(ctx).Err()
239 Expect(err).NotTo(HaveOccurred())
240 Expect(client.ClientID(ctx).Val()).To(BeNumerically(">=", 0))
241 })
242
243 It("should ClientUnblock", func() {
244 id := client.ClientID(ctx).Val()
245 r, err := client.ClientUnblock(ctx, id).Result()
246 Expect(err).NotTo(HaveOccurred())
247 Expect(r).To(Equal(int64(0)))
248 })
249
250 It("should ClientUnblockWithError", func() {
251 id := client.ClientID(ctx).Val()
252 r, err := client.ClientUnblockWithError(ctx, id).Result()
253 Expect(err).NotTo(HaveOccurred())
254 Expect(r).To(Equal(int64(0)))
255 })
256
257 It("should ClientInfo", func() {
258 info, err := client.ClientInfo(ctx).Result()
259 Expect(err).NotTo(HaveOccurred())
260 Expect(info).NotTo(BeNil())
261 })
262
263 It("should ClientPause", Label("NonRedisEnterprise"), func() {
264 err := client.ClientPause(ctx, time.Second).Err()
265 Expect(err).NotTo(HaveOccurred())
266
267 start := time.Now()
268 err = client.Ping(ctx).Err()
269 Expect(err).NotTo(HaveOccurred())
270 Expect(time.Now()).To(BeTemporally("~", start.Add(time.Second), 800*time.Millisecond))
271 })
272
273 It("should ClientSetName and ClientGetName", func() {
274 pipe := client.Pipeline()
275 set := pipe.ClientSetName(ctx, "theclientname")
276 get := pipe.ClientGetName(ctx)
277 _, err := pipe.Exec(ctx)
278 Expect(err).NotTo(HaveOccurred())
279
280 Expect(set.Err()).NotTo(HaveOccurred())
281 Expect(set.Val()).To(BeTrue())
282
283 Expect(get.Err()).NotTo(HaveOccurred())
284 Expect(get.Val()).To(Equal("theclientname"))
285 })
286
287 It("should ClientSetInfo", func() {
288 pipe := client.Pipeline()
289
290
291 libName := "go-redis"
292 libInfo := redis.WithLibraryName(libName)
293 setInfo := pipe.ClientSetInfo(ctx, libInfo)
294 _, err := pipe.Exec(ctx)
295
296 Expect(err).NotTo(HaveOccurred())
297 Expect(setInfo.Err()).NotTo(HaveOccurred())
298 Expect(setInfo.Val()).To(Equal("OK"))
299
300
301 libVer := "vX.x"
302 libInfo = redis.WithLibraryVersion(libVer)
303 setInfo = pipe.ClientSetInfo(ctx, libInfo)
304 _, err = pipe.Exec(ctx)
305
306 Expect(err).NotTo(HaveOccurred())
307 Expect(setInfo.Err()).NotTo(HaveOccurred())
308 Expect(setInfo.Val()).To(Equal("OK"))
309
310
311 libInfo = redis.LibraryInfo{LibName: &libName, LibVer: &libVer}
312
313 Expect(func() {
314 defer func() {
315 if r := recover(); r != nil {
316 err := r.(error)
317 Expect(err).To(MatchError("both LibName and LibVer cannot be set at the same time"))
318 }
319 }()
320 pipe.ClientSetInfo(ctx, libInfo)
321 }).To(Panic())
322
323
324 libInfo = redis.LibraryInfo{}
325
326 Expect(func() {
327 defer func() {
328 if r := recover(); r != nil {
329 err := r.(error)
330 Expect(err).To(MatchError("at least one of LibName and LibVer should be set"))
331 }
332 }()
333 pipe.ClientSetInfo(ctx, libInfo)
334 }).To(Panic())
335
336 clientInfo := client.ClientInfo(ctx).Val()
337 Expect(clientInfo.LibName).To(ContainSubstring("go-redis(go-redis,"))
338
339 opt := redisOptions()
340 opt.IdentitySuffix = "suffix"
341 client2 := redis.NewClient(opt)
342 defer client2.Close()
343 clientInfo = client2.ClientInfo(ctx).Val()
344 Expect(clientInfo.LibName).To(ContainSubstring("go-redis(suffix,"))
345
346 })
347
348 It("should ConfigGet", func() {
349 val, err := client.ConfigGet(ctx, "*").Result()
350 Expect(err).NotTo(HaveOccurred())
351 Expect(val).NotTo(BeEmpty())
352 })
353
354 It("should ConfigGet Modules", func() {
355 SkipBeforeRedisVersion(8, "Config doesn't include modules before Redis 8")
356 expected := map[string]string{
357 "search-*": "search-timeout",
358 "ts-*": "ts-retention-policy",
359 "bf-*": "bf-error-rate",
360 "cf-*": "cf-initial-size",
361 }
362
363 for prefix, lookup := range expected {
364 val, err := client.ConfigGet(ctx, prefix).Result()
365 Expect(err).NotTo(HaveOccurred())
366 Expect(val).NotTo(BeEmpty())
367 Expect(val[lookup]).NotTo(BeEmpty())
368 }
369 })
370
371 It("should ConfigResetStat", Label("NonRedisEnterprise"), func() {
372 r := client.ConfigResetStat(ctx)
373 Expect(r.Err()).NotTo(HaveOccurred())
374 Expect(r.Val()).To(Equal("OK"))
375 })
376
377 It("should ConfigSet", Label("NonRedisEnterprise"), func() {
378 configGet := client.ConfigGet(ctx, "maxmemory")
379 Expect(configGet.Err()).NotTo(HaveOccurred())
380 Expect(configGet.Val()).To(HaveLen(1))
381 _, ok := configGet.Val()["maxmemory"]
382 Expect(ok).To(BeTrue())
383
384 configSet := client.ConfigSet(ctx, "maxmemory", configGet.Val()["maxmemory"])
385 Expect(configSet.Err()).NotTo(HaveOccurred())
386 Expect(configSet.Val()).To(Equal("OK"))
387 })
388
389 It("should ConfigGet with Modules", Label("NonRedisEnterprise"), func() {
390 SkipBeforeRedisVersion(8, "config get won't return modules configs before redis 8")
391 configGet := client.ConfigGet(ctx, "*")
392 Expect(configGet.Err()).NotTo(HaveOccurred())
393 Expect(configGet.Val()).To(HaveKey("maxmemory"))
394 Expect(configGet.Val()).To(HaveKey("search-timeout"))
395 Expect(configGet.Val()).To(HaveKey("ts-retention-policy"))
396 Expect(configGet.Val()).To(HaveKey("bf-error-rate"))
397 Expect(configGet.Val()).To(HaveKey("cf-initial-size"))
398 })
399
400 It("should ConfigSet FT DIALECT", func() {
401 SkipBeforeRedisVersion(8, "config doesn't include modules before Redis 8")
402 defaultState, err := client.ConfigGet(ctx, "search-default-dialect").Result()
403 Expect(err).NotTo(HaveOccurred())
404
405
406 res, err := client.ConfigSet(ctx, "search-default-dialect", "3").Result()
407 Expect(err).NotTo(HaveOccurred())
408 Expect(res).To(BeEquivalentTo("OK"))
409
410 defDialect, err := client.FTConfigGet(ctx, "DEFAULT_DIALECT").Result()
411 Expect(err).NotTo(HaveOccurred())
412 Expect(defDialect).To(BeEquivalentTo(map[string]interface{}{"DEFAULT_DIALECT": "3"}))
413
414 resGet, err := client.ConfigGet(ctx, "search-default-dialect").Result()
415 Expect(err).NotTo(HaveOccurred())
416 Expect(resGet).To(BeEquivalentTo(map[string]string{"search-default-dialect": "3"}))
417
418
419 res, err = client.ConfigSet(ctx, "search-default-dialect", "2").Result()
420 Expect(err).NotTo(HaveOccurred())
421 Expect(res).To(BeEquivalentTo("OK"))
422
423 defDialect, err = client.FTConfigGet(ctx, "DEFAULT_DIALECT").Result()
424 Expect(err).NotTo(HaveOccurred())
425 Expect(defDialect).To(BeEquivalentTo(map[string]interface{}{"DEFAULT_DIALECT": "2"}))
426
427
428 res, err = client.ConfigSet(ctx, "search-default-dialect", "1").Result()
429 Expect(err).NotTo(HaveOccurred())
430 Expect(res).To(BeEquivalentTo("OK"))
431
432 defDialect, err = client.FTConfigGet(ctx, "DEFAULT_DIALECT").Result()
433 Expect(err).NotTo(HaveOccurred())
434 Expect(defDialect).To(BeEquivalentTo(map[string]interface{}{"DEFAULT_DIALECT": "1"}))
435
436 resGet, err = client.ConfigGet(ctx, "search-default-dialect").Result()
437 Expect(err).NotTo(HaveOccurred())
438 Expect(resGet).To(BeEquivalentTo(map[string]string{"search-default-dialect": "1"}))
439
440
441 res, err = client.ConfigSet(ctx, "search-default-dialect", defaultState["search-default-dialect"]).Result()
442 Expect(err).NotTo(HaveOccurred())
443 Expect(res).To(BeEquivalentTo("OK"))
444 })
445
446 It("should ConfigSet fail for ReadOnly", func() {
447 SkipBeforeRedisVersion(8, "Config doesn't include modules before Redis 8")
448 _, err := client.ConfigSet(ctx, "search-max-doctablesize", "100000").Result()
449 Expect(err).To(HaveOccurred())
450 })
451
452 It("should ConfigSet Modules", func() {
453 SkipBeforeRedisVersion(8, "Config doesn't include modules before Redis 8")
454 defaults := map[string]string{}
455 expected := map[string]string{
456 "search-timeout": "100",
457 "ts-retention-policy": "2",
458 "bf-error-rate": "0.13",
459 "cf-initial-size": "64",
460 }
461
462
463 for setting := range expected {
464 val, err := client.ConfigGet(ctx, setting).Result()
465 Expect(err).NotTo(HaveOccurred())
466 defaults[setting] = val[setting]
467 }
468
469
470 for setting, value := range expected {
471 val, err := client.ConfigSet(ctx, setting, value).Result()
472 Expect(err).NotTo(HaveOccurred())
473 Expect(val).NotTo(BeEmpty())
474 Expect(val).To(Equal("OK"))
475 }
476
477 for setting, value := range expected {
478 val, err := client.ConfigGet(ctx, setting).Result()
479 Expect(err).NotTo(HaveOccurred())
480 Expect(val).NotTo(BeEmpty())
481 Expect(val[setting]).To(Equal(value))
482 }
483
484
485 for setting, value := range defaults {
486 val, err := client.ConfigSet(ctx, setting, value).Result()
487 Expect(err).NotTo(HaveOccurred())
488 Expect(val).NotTo(BeEmpty())
489 Expect(val).To(Equal("OK"))
490 }
491 })
492
493 It("should Fail ConfigSet Modules", func() {
494 SkipBeforeRedisVersion(8, "Config doesn't include modules before Redis 8")
495 expected := map[string]string{
496 "search-timeout": "-100",
497 "ts-retention-policy": "-10",
498 "bf-error-rate": "1.5",
499 "cf-initial-size": "-10",
500 }
501
502 for setting, value := range expected {
503 val, err := client.ConfigSet(ctx, setting, value).Result()
504 Expect(err).To(HaveOccurred())
505 Expect(err).To(MatchError(ContainSubstring(setting)))
506 Expect(val).To(BeEmpty())
507 }
508 })
509
510 It("should ConfigRewrite", Label("NonRedisEnterprise"), func() {
511 configRewrite := client.ConfigRewrite(ctx)
512 Expect(configRewrite.Err()).NotTo(HaveOccurred())
513 Expect(configRewrite.Val()).To(Equal("OK"))
514 })
515
516 It("should DBSize", func() {
517 size, err := client.DBSize(ctx).Result()
518 Expect(err).NotTo(HaveOccurred())
519 Expect(size).To(Equal(int64(0)))
520 })
521
522 It("should Info", func() {
523 info := client.Info(ctx)
524 Expect(info.Err()).NotTo(HaveOccurred())
525 Expect(info.Val()).NotTo(Equal(""))
526 })
527
528 It("should InfoMap", Label("redis.info"), func() {
529 info := client.InfoMap(ctx)
530 Expect(info.Err()).NotTo(HaveOccurred())
531 Expect(info.Val()).NotTo(BeNil())
532
533 info = client.InfoMap(ctx, "dummy")
534 Expect(info.Err()).NotTo(HaveOccurred())
535 Expect(info.Val()).To(BeNil())
536
537 info = client.InfoMap(ctx, "server")
538 Expect(info.Err()).NotTo(HaveOccurred())
539 Expect(info.Val()).To(HaveLen(1))
540 })
541
542 It("should Info Modules", Label("redis.info"), func() {
543 SkipBeforeRedisVersion(8, "modules are included in info for Redis Version >= 8")
544 info := client.Info(ctx)
545 Expect(info.Err()).NotTo(HaveOccurred())
546 Expect(info.Val()).NotTo(BeNil())
547
548 info = client.Info(ctx, "search")
549 Expect(info.Err()).NotTo(HaveOccurred())
550 Expect(info.Val()).To(ContainSubstring("search"))
551
552 info = client.Info(ctx, "modules")
553 Expect(info.Err()).NotTo(HaveOccurred())
554 Expect(info.Val()).To(ContainSubstring("search"))
555 Expect(info.Val()).To(ContainSubstring("ReJSON"))
556 Expect(info.Val()).To(ContainSubstring("timeseries"))
557 Expect(info.Val()).To(ContainSubstring("bf"))
558
559 info = client.Info(ctx, "everything")
560 Expect(info.Err()).NotTo(HaveOccurred())
561 Expect(info.Val()).To(ContainSubstring("search"))
562 Expect(info.Val()).To(ContainSubstring("ReJSON"))
563 Expect(info.Val()).To(ContainSubstring("timeseries"))
564 Expect(info.Val()).To(ContainSubstring("bf"))
565 })
566
567 It("should InfoMap Modules", Label("redis.info"), func() {
568 SkipBeforeRedisVersion(8, "modules are included in info for Redis Version >= 8")
569 info := client.InfoMap(ctx)
570 Expect(info.Err()).NotTo(HaveOccurred())
571 Expect(info.Val()).NotTo(BeNil())
572
573 info = client.InfoMap(ctx, "search")
574 Expect(info.Err()).NotTo(HaveOccurred())
575 Expect(len(info.Val())).To(BeNumerically(">=", 2))
576 Expect(info.Val()["search_version"]).ToNot(BeNil())
577
578 info = client.InfoMap(ctx, "modules")
579 Expect(info.Err()).NotTo(HaveOccurred())
580 val := info.Val()
581 modules, ok := val["Modules"]
582 Expect(ok).To(BeTrue())
583 Expect(len(val)).To(BeNumerically(">=", 2))
584 Expect(val["search_version"]).ToNot(BeNil())
585 Expect(modules["search"]).ToNot(BeNil())
586 Expect(modules["ReJSON"]).ToNot(BeNil())
587 Expect(modules["timeseries"]).ToNot(BeNil())
588 Expect(modules["bf"]).ToNot(BeNil())
589
590 info = client.InfoMap(ctx, "everything")
591 Expect(info.Err()).NotTo(HaveOccurred())
592 Expect(len(info.Val())).To(BeNumerically(">=", 10))
593 })
594
595 It("should Info cpu", func() {
596 info := client.Info(ctx, "cpu")
597 Expect(info.Err()).NotTo(HaveOccurred())
598 Expect(info.Val()).NotTo(Equal(""))
599 Expect(info.Val()).To(ContainSubstring(`used_cpu_sys`))
600 })
601
602 It("should Info cpu and memory", func() {
603 info := client.Info(ctx, "cpu", "memory")
604 Expect(info.Err()).NotTo(HaveOccurred())
605 Expect(info.Val()).NotTo(Equal(""))
606 Expect(info.Val()).To(ContainSubstring(`used_cpu_sys`))
607 Expect(info.Val()).To(ContainSubstring(`memory`))
608 })
609
610 It("should LastSave", Label("NonRedisEnterprise"), func() {
611 lastSave := client.LastSave(ctx)
612 Expect(lastSave.Err()).NotTo(HaveOccurred())
613 Expect(lastSave.Val()).NotTo(Equal(0))
614 })
615
616 It("should Save", Label("NonRedisEnterprise"), func() {
617
618 Eventually(func() string {
619 return client.Save(ctx).Val()
620 }, "10s").Should(Equal("OK"))
621 })
622
623 It("should SlaveOf", Label("NonRedisEnterprise"), func() {
624 slaveOf := client.SlaveOf(ctx, "localhost", "8888")
625 Expect(slaveOf.Err()).NotTo(HaveOccurred())
626 Expect(slaveOf.Val()).To(Equal("OK"))
627
628 slaveOf = client.SlaveOf(ctx, "NO", "ONE")
629 Expect(slaveOf.Err()).NotTo(HaveOccurred())
630 Expect(slaveOf.Val()).To(Equal("OK"))
631 })
632
633 It("should Time", func() {
634 tm, err := client.Time(ctx).Result()
635 Expect(err).NotTo(HaveOccurred())
636 Expect(tm).To(BeTemporally("~", time.Now(), 3*time.Second))
637 })
638
639 It("should Command", Label("NonRedisEnterprise"), func() {
640 cmds, err := client.Command(ctx).Result()
641 Expect(err).NotTo(HaveOccurred())
642
643 cmd := cmds["mget"]
644 Expect(cmd.Name).To(Equal("mget"))
645 Expect(cmd.Arity).To(Equal(int8(-2)))
646 Expect(cmd.Flags).To(ContainElement("readonly"))
647 Expect(cmd.FirstKeyPos).To(Equal(int8(1)))
648 Expect(cmd.LastKeyPos).To(Equal(int8(-1)))
649 Expect(cmd.StepCount).To(Equal(int8(1)))
650
651 cmd = cmds["ping"]
652 Expect(cmd.Name).To(Equal("ping"))
653 Expect(cmd.Arity).To(Equal(int8(-1)))
654 Expect(cmd.Flags).To(ContainElement("fast"))
655 Expect(cmd.FirstKeyPos).To(Equal(int8(0)))
656 Expect(cmd.LastKeyPos).To(Equal(int8(0)))
657 Expect(cmd.StepCount).To(Equal(int8(0)))
658 })
659
660 It("should return all command names", func() {
661 cmdList := client.CommandList(ctx, nil)
662 Expect(cmdList.Err()).NotTo(HaveOccurred())
663 cmdNames := cmdList.Val()
664
665 Expect(cmdNames).NotTo(BeEmpty())
666
667
668 Expect(cmdNames).To(ContainElement("get"))
669 Expect(cmdNames).To(ContainElement("set"))
670 Expect(cmdNames).To(ContainElement("hset"))
671 })
672
673 It("should filter commands by module", func() {
674 filter := &redis.FilterBy{
675 Module: "JSON",
676 }
677 cmdList := client.CommandList(ctx, filter)
678 Expect(cmdList.Err()).NotTo(HaveOccurred())
679 Expect(cmdList.Val()).To(HaveLen(0))
680 })
681
682 It("should filter commands by ACL category", func() {
683 filter := &redis.FilterBy{
684 ACLCat: "admin",
685 }
686
687 cmdList := client.CommandList(ctx, filter)
688 Expect(cmdList.Err()).NotTo(HaveOccurred())
689 cmdNames := cmdList.Val()
690
691
692 Expect(len(cmdNames)).To(BeNumerically(">", 10))
693 })
694
695 It("should filter commands by pattern", func() {
696 filter := &redis.FilterBy{
697 Pattern: "*GET*",
698 }
699 cmdList := client.CommandList(ctx, filter)
700 Expect(cmdList.Err()).NotTo(HaveOccurred())
701 cmdNames := cmdList.Val()
702
703
704 Expect(cmdNames).To(ContainElement("get"))
705 Expect(cmdNames).To(ContainElement("getbit"))
706 Expect(cmdNames).To(ContainElement("getrange"))
707 Expect(cmdNames).NotTo(ContainElement("set"))
708 })
709 })
710
711 Describe("debugging", Label("NonRedisEnterprise"), func() {
712 It("should DebugObject", func() {
713 err := client.DebugObject(ctx, "foo").Err()
714 Expect(err).To(MatchError("ERR no such key"))
715
716 err = client.Set(ctx, "foo", "bar", 0).Err()
717 Expect(err).NotTo(HaveOccurred())
718
719 s, err := client.DebugObject(ctx, "foo").Result()
720 Expect(err).NotTo(HaveOccurred())
721 Expect(s).To(ContainSubstring("serializedlength:4"))
722 })
723
724 It("should MemoryUsage", func() {
725 err := client.MemoryUsage(ctx, "foo").Err()
726 Expect(err).To(Equal(redis.Nil))
727
728 err = client.Set(ctx, "foo", "bar", 0).Err()
729 Expect(err).NotTo(HaveOccurred())
730
731 n, err := client.MemoryUsage(ctx, "foo").Result()
732 Expect(err).NotTo(HaveOccurred())
733 Expect(n).NotTo(BeZero())
734
735 n, err = client.MemoryUsage(ctx, "foo", 0).Result()
736 Expect(err).NotTo(HaveOccurred())
737 Expect(n).NotTo(BeZero())
738 })
739 })
740
741 Describe("keys", func() {
742 It("should Del", func() {
743 err := client.Set(ctx, "key1", "Hello", 0).Err()
744 Expect(err).NotTo(HaveOccurred())
745 err = client.Set(ctx, "key2", "World", 0).Err()
746 Expect(err).NotTo(HaveOccurred())
747
748 n, err := client.Del(ctx, "key1", "key2", "key3").Result()
749 Expect(err).NotTo(HaveOccurred())
750 Expect(n).To(Equal(int64(2)))
751 })
752
753 It("should Unlink", func() {
754 err := client.Set(ctx, "key1", "Hello", 0).Err()
755 Expect(err).NotTo(HaveOccurred())
756 err = client.Set(ctx, "key2", "World", 0).Err()
757 Expect(err).NotTo(HaveOccurred())
758
759 n, err := client.Unlink(ctx, "key1", "key2", "key3").Result()
760 Expect(err).NotTo(HaveOccurred())
761 Expect(n).To(Equal(int64(2)))
762 })
763
764 It("should Dump", func() {
765 set := client.Set(ctx, "key", "hello", 0)
766 Expect(set.Err()).NotTo(HaveOccurred())
767 Expect(set.Val()).To(Equal("OK"))
768
769 dump := client.Dump(ctx, "key")
770 Expect(dump.Err()).NotTo(HaveOccurred())
771 Expect(dump.Val()).NotTo(BeEmpty())
772 })
773
774 It("should Exists", func() {
775 set := client.Set(ctx, "key1", "Hello", 0)
776 Expect(set.Err()).NotTo(HaveOccurred())
777 Expect(set.Val()).To(Equal("OK"))
778
779 n, err := client.Exists(ctx, "key1").Result()
780 Expect(err).NotTo(HaveOccurred())
781 Expect(n).To(Equal(int64(1)))
782
783 n, err = client.Exists(ctx, "key2").Result()
784 Expect(err).NotTo(HaveOccurred())
785 Expect(n).To(Equal(int64(0)))
786
787 n, err = client.Exists(ctx, "key1", "key2").Result()
788 Expect(err).NotTo(HaveOccurred())
789 Expect(n).To(Equal(int64(1)))
790
791 n, err = client.Exists(ctx, "key1", "key1").Result()
792 Expect(err).NotTo(HaveOccurred())
793 Expect(n).To(Equal(int64(2)))
794 })
795
796 It("should Expire", func() {
797 set := client.Set(ctx, "key", "Hello", 0)
798 Expect(set.Err()).NotTo(HaveOccurred())
799 Expect(set.Val()).To(Equal("OK"))
800
801 expire := client.Expire(ctx, "key", 10*time.Second)
802 Expect(expire.Err()).NotTo(HaveOccurred())
803 Expect(expire.Val()).To(Equal(true))
804
805 ttl := client.TTL(ctx, "key")
806 Expect(ttl.Err()).NotTo(HaveOccurred())
807 Expect(ttl.Val()).To(Equal(10 * time.Second))
808
809 set = client.Set(ctx, "key", "Hello World", 0)
810 Expect(set.Err()).NotTo(HaveOccurred())
811 Expect(set.Val()).To(Equal("OK"))
812
813 ttl = client.TTL(ctx, "key")
814 Expect(ttl.Err()).NotTo(HaveOccurred())
815 Expect(ttl.Val()).To(Equal(time.Duration(-1)))
816
817 ttl = client.TTL(ctx, "nonexistent_key")
818 Expect(ttl.Err()).NotTo(HaveOccurred())
819 Expect(ttl.Val()).To(Equal(time.Duration(-2)))
820 })
821
822 It("should ExpireAt", func() {
823 setCmd := client.Set(ctx, "key", "Hello", 0)
824 Expect(setCmd.Err()).NotTo(HaveOccurred())
825 Expect(setCmd.Val()).To(Equal("OK"))
826
827 n, err := client.Exists(ctx, "key").Result()
828 Expect(err).NotTo(HaveOccurred())
829 Expect(n).To(Equal(int64(1)))
830
831
832 expireAt := time.Now().Add(time.Minute)
833 expireAtCmd := client.ExpireAt(ctx, "key", expireAt)
834 Expect(expireAtCmd.Err()).NotTo(HaveOccurred())
835 Expect(expireAtCmd.Val()).To(Equal(true))
836
837 timeCmd := client.ExpireTime(ctx, "key")
838 Expect(timeCmd.Err()).NotTo(HaveOccurred())
839 Expect(timeCmd.Val().Seconds()).To(BeNumerically("==", expireAt.Unix()))
840
841
842 expireAtCmd = client.ExpireAt(ctx, "key", time.Now().Add(-time.Hour))
843 Expect(expireAtCmd.Err()).NotTo(HaveOccurred())
844 Expect(expireAtCmd.Val()).To(Equal(true))
845
846 n, err = client.Exists(ctx, "key").Result()
847 Expect(err).NotTo(HaveOccurred())
848 Expect(n).To(Equal(int64(0)))
849 })
850
851 It("should Keys", func() {
852 mset := client.MSet(ctx, "one", "1", "two", "2", "three", "3", "four", "4")
853 Expect(mset.Err()).NotTo(HaveOccurred())
854 Expect(mset.Val()).To(Equal("OK"))
855
856 keys := client.Keys(ctx, "*o*")
857 Expect(keys.Err()).NotTo(HaveOccurred())
858 Expect(keys.Val()).To(ConsistOf([]string{"four", "one", "two"}))
859
860 keys = client.Keys(ctx, "t??")
861 Expect(keys.Err()).NotTo(HaveOccurred())
862 Expect(keys.Val()).To(Equal([]string{"two"}))
863
864 keys = client.Keys(ctx, "*")
865 Expect(keys.Err()).NotTo(HaveOccurred())
866 Expect(keys.Val()).To(ConsistOf([]string{"four", "one", "three", "two"}))
867 })
868
869 It("should Migrate", Label("NonRedisEnterprise"), func() {
870 migrate := client.Migrate(ctx, "localhost", redisSecondaryPort, "key", 0, 0)
871 Expect(migrate.Err()).NotTo(HaveOccurred())
872 Expect(migrate.Val()).To(Equal("NOKEY"))
873
874 set := client.Set(ctx, "key", "hello", 0)
875 Expect(set.Err()).NotTo(HaveOccurred())
876 Expect(set.Val()).To(Equal("OK"))
877
878 migrate = client.Migrate(ctx, "localhost", redisSecondaryPort, "key", 0, 0)
879 Expect(migrate.Err()).To(MatchError("IOERR error or timeout writing to target instance"))
880 Expect(migrate.Val()).To(Equal(""))
881 })
882
883 It("should Move", Label("NonRedisEnterprise"), func() {
884 move := client.Move(ctx, "key", 2)
885 Expect(move.Err()).NotTo(HaveOccurred())
886 Expect(move.Val()).To(Equal(false))
887
888 set := client.Set(ctx, "key", "hello", 0)
889 Expect(set.Err()).NotTo(HaveOccurred())
890 Expect(set.Val()).To(Equal("OK"))
891
892 move = client.Move(ctx, "key", 2)
893 Expect(move.Err()).NotTo(HaveOccurred())
894 Expect(move.Val()).To(Equal(true))
895
896 get := client.Get(ctx, "key")
897 Expect(get.Err()).To(Equal(redis.Nil))
898 Expect(get.Val()).To(Equal(""))
899
900 pipe := client.Pipeline()
901 pipe.Select(ctx, 2)
902 get = pipe.Get(ctx, "key")
903 pipe.FlushDB(ctx)
904
905 _, err := pipe.Exec(ctx)
906 Expect(err).NotTo(HaveOccurred())
907 Expect(get.Val()).To(Equal("hello"))
908 })
909
910 It("should Object", Label("NonRedisEnterprise"), func() {
911 start := time.Now()
912 set := client.Set(ctx, "key", "hello", 0)
913 Expect(set.Err()).NotTo(HaveOccurred())
914 Expect(set.Val()).To(Equal("OK"))
915
916 refCount := client.ObjectRefCount(ctx, "key")
917 Expect(refCount.Err()).NotTo(HaveOccurred())
918 Expect(refCount.Val()).To(Equal(int64(1)))
919
920 client.ConfigSet(ctx, "maxmemory-policy", "volatile-lfu")
921 freq := client.ObjectFreq(ctx, "key")
922 Expect(freq.Err()).NotTo(HaveOccurred())
923 client.ConfigSet(ctx, "maxmemory-policy", "noeviction")
924
925 err := client.ObjectEncoding(ctx, "key").Err()
926 Expect(err).NotTo(HaveOccurred())
927
928 idleTime := client.ObjectIdleTime(ctx, "key")
929 Expect(idleTime.Err()).NotTo(HaveOccurred())
930
931
932
933
934
935
936 Expect(idleTime.Val()).To(BeNumerically("<=", time.Since(start)+time.Second))
937 })
938
939 It("should Persist", func() {
940 set := client.Set(ctx, "key", "Hello", 0)
941 Expect(set.Err()).NotTo(HaveOccurred())
942 Expect(set.Val()).To(Equal("OK"))
943
944 expire := client.Expire(ctx, "key", 10*time.Second)
945 Expect(expire.Err()).NotTo(HaveOccurred())
946 Expect(expire.Val()).To(Equal(true))
947
948 ttl := client.TTL(ctx, "key")
949 Expect(ttl.Err()).NotTo(HaveOccurred())
950 Expect(ttl.Val()).To(Equal(10 * time.Second))
951
952 persist := client.Persist(ctx, "key")
953 Expect(persist.Err()).NotTo(HaveOccurred())
954 Expect(persist.Val()).To(Equal(true))
955
956 ttl = client.TTL(ctx, "key")
957 Expect(ttl.Err()).NotTo(HaveOccurred())
958 Expect(ttl.Val() < 0).To(Equal(true))
959 })
960
961 It("should PExpire", func() {
962 set := client.Set(ctx, "key", "Hello", 0)
963 Expect(set.Err()).NotTo(HaveOccurred())
964 Expect(set.Val()).To(Equal("OK"))
965
966 expiration := 900 * time.Millisecond
967 pexpire := client.PExpire(ctx, "key", expiration)
968 Expect(pexpire.Err()).NotTo(HaveOccurred())
969 Expect(pexpire.Val()).To(Equal(true))
970
971 ttl := client.TTL(ctx, "key")
972 Expect(ttl.Err()).NotTo(HaveOccurred())
973 Expect(ttl.Val()).To(Equal(time.Second))
974
975 pttl := client.PTTL(ctx, "key")
976 Expect(pttl.Err()).NotTo(HaveOccurred())
977 Expect(pttl.Val()).To(BeNumerically("~", expiration, 100*time.Millisecond))
978 })
979
980 It("should PExpireAt", func() {
981 set := client.Set(ctx, "key", "Hello", 0)
982 Expect(set.Err()).NotTo(HaveOccurred())
983 Expect(set.Val()).To(Equal("OK"))
984
985 expiration := 900 * time.Millisecond
986 pexpireat := client.PExpireAt(ctx, "key", time.Now().Add(expiration))
987 Expect(pexpireat.Err()).NotTo(HaveOccurred())
988 Expect(pexpireat.Val()).To(Equal(true))
989
990 ttl := client.TTL(ctx, "key")
991 Expect(ttl.Err()).NotTo(HaveOccurred())
992 Expect(ttl.Val()).To(Equal(time.Second))
993
994 pttl := client.PTTL(ctx, "key")
995 Expect(pttl.Err()).NotTo(HaveOccurred())
996 Expect(pttl.Val()).To(BeNumerically("~", expiration, 100*time.Millisecond))
997 })
998
999 It("should PExpireTime", func() {
1000
1001
1002 pExpireTime := client.PExpireTime(ctx, "key")
1003 Expect(pExpireTime.Err()).NotTo(HaveOccurred())
1004 Expect(pExpireTime.Val() < 0).To(Equal(true))
1005
1006 set := client.Set(ctx, "key", "hello", 0)
1007 Expect(set.Err()).NotTo(HaveOccurred())
1008 Expect(set.Val()).To(Equal("OK"))
1009
1010 timestamp := time.Now().Add(time.Minute)
1011 expireAt := client.PExpireAt(ctx, "key", timestamp)
1012 Expect(expireAt.Err()).NotTo(HaveOccurred())
1013 Expect(expireAt.Val()).To(Equal(true))
1014
1015 pExpireTime = client.PExpireTime(ctx, "key")
1016 Expect(pExpireTime.Err()).NotTo(HaveOccurred())
1017 Expect(pExpireTime.Val().Milliseconds()).To(BeNumerically("==", timestamp.UnixMilli()))
1018 })
1019
1020 It("should PTTL", func() {
1021 set := client.Set(ctx, "key", "Hello", 0)
1022 Expect(set.Err()).NotTo(HaveOccurred())
1023 Expect(set.Val()).To(Equal("OK"))
1024
1025 expiration := time.Second
1026 expire := client.Expire(ctx, "key", expiration)
1027 Expect(expire.Err()).NotTo(HaveOccurred())
1028 Expect(set.Val()).To(Equal("OK"))
1029
1030 pttl := client.PTTL(ctx, "key")
1031 Expect(pttl.Err()).NotTo(HaveOccurred())
1032 Expect(pttl.Val()).To(BeNumerically("~", expiration, 100*time.Millisecond))
1033 })
1034
1035 It("should RandomKey", func() {
1036 randomKey := client.RandomKey(ctx)
1037 Expect(randomKey.Err()).To(Equal(redis.Nil))
1038 Expect(randomKey.Val()).To(Equal(""))
1039
1040 set := client.Set(ctx, "key", "hello", 0)
1041 Expect(set.Err()).NotTo(HaveOccurred())
1042 Expect(set.Val()).To(Equal("OK"))
1043
1044 randomKey = client.RandomKey(ctx)
1045 Expect(randomKey.Err()).NotTo(HaveOccurred())
1046 Expect(randomKey.Val()).To(Equal("key"))
1047 })
1048
1049 It("should Rename", Label("NonRedisEnterprise"), func() {
1050 set := client.Set(ctx, "key", "hello", 0)
1051 Expect(set.Err()).NotTo(HaveOccurred())
1052 Expect(set.Val()).To(Equal("OK"))
1053
1054 status := client.Rename(ctx, "key", "key1")
1055 Expect(status.Err()).NotTo(HaveOccurred())
1056 Expect(status.Val()).To(Equal("OK"))
1057
1058 get := client.Get(ctx, "key1")
1059 Expect(get.Err()).NotTo(HaveOccurred())
1060 Expect(get.Val()).To(Equal("hello"))
1061 })
1062
1063 It("should RenameNX", Label("NonRedisEnterprise"), func() {
1064 set := client.Set(ctx, "key", "hello", 0)
1065 Expect(set.Err()).NotTo(HaveOccurred())
1066 Expect(set.Val()).To(Equal("OK"))
1067
1068 renameNX := client.RenameNX(ctx, "key", "key1")
1069 Expect(renameNX.Err()).NotTo(HaveOccurred())
1070 Expect(renameNX.Val()).To(Equal(true))
1071
1072 get := client.Get(ctx, "key1")
1073 Expect(get.Err()).NotTo(HaveOccurred())
1074 Expect(get.Val()).To(Equal("hello"))
1075 })
1076
1077 It("should Restore", func() {
1078 err := client.Set(ctx, "key", "hello", 0).Err()
1079 Expect(err).NotTo(HaveOccurred())
1080
1081 dump := client.Dump(ctx, "key")
1082 Expect(dump.Err()).NotTo(HaveOccurred())
1083
1084 err = client.Del(ctx, "key").Err()
1085 Expect(err).NotTo(HaveOccurred())
1086
1087 restore, err := client.Restore(ctx, "key", 0, dump.Val()).Result()
1088 Expect(err).NotTo(HaveOccurred())
1089 Expect(restore).To(Equal("OK"))
1090
1091 type_, err := client.Type(ctx, "key").Result()
1092 Expect(err).NotTo(HaveOccurred())
1093 Expect(type_).To(Equal("string"))
1094
1095 val, err := client.Get(ctx, "key").Result()
1096 Expect(err).NotTo(HaveOccurred())
1097 Expect(val).To(Equal("hello"))
1098 })
1099
1100 It("should RestoreReplace", func() {
1101 err := client.Set(ctx, "key", "hello", 0).Err()
1102 Expect(err).NotTo(HaveOccurred())
1103
1104 dump := client.Dump(ctx, "key")
1105 Expect(dump.Err()).NotTo(HaveOccurred())
1106
1107 restore, err := client.RestoreReplace(ctx, "key", 0, dump.Val()).Result()
1108 Expect(err).NotTo(HaveOccurred())
1109 Expect(restore).To(Equal("OK"))
1110
1111 type_, err := client.Type(ctx, "key").Result()
1112 Expect(err).NotTo(HaveOccurred())
1113 Expect(type_).To(Equal("string"))
1114
1115 val, err := client.Get(ctx, "key").Result()
1116 Expect(err).NotTo(HaveOccurred())
1117 Expect(val).To(Equal("hello"))
1118 })
1119
1120 It("should Sort RO", func() {
1121 size, err := client.LPush(ctx, "list", "1").Result()
1122 Expect(err).NotTo(HaveOccurred())
1123 Expect(size).To(Equal(int64(1)))
1124
1125 size, err = client.LPush(ctx, "list", "3").Result()
1126 Expect(err).NotTo(HaveOccurred())
1127 Expect(size).To(Equal(int64(2)))
1128
1129 size, err = client.LPush(ctx, "list", "2").Result()
1130 Expect(err).NotTo(HaveOccurred())
1131 Expect(size).To(Equal(int64(3)))
1132
1133 els, err := client.SortRO(ctx, "list", &redis.Sort{
1134 Offset: 0,
1135 Count: 2,
1136 Order: "ASC",
1137 }).Result()
1138 Expect(err).NotTo(HaveOccurred())
1139 Expect(els).To(Equal([]string{"1", "2"}))
1140 })
1141
1142 It("should Sort", func() {
1143 size, err := client.LPush(ctx, "list", "1").Result()
1144 Expect(err).NotTo(HaveOccurred())
1145 Expect(size).To(Equal(int64(1)))
1146
1147 size, err = client.LPush(ctx, "list", "3").Result()
1148 Expect(err).NotTo(HaveOccurred())
1149 Expect(size).To(Equal(int64(2)))
1150
1151 size, err = client.LPush(ctx, "list", "2").Result()
1152 Expect(err).NotTo(HaveOccurred())
1153 Expect(size).To(Equal(int64(3)))
1154
1155 els, err := client.Sort(ctx, "list", &redis.Sort{
1156 Offset: 0,
1157 Count: 2,
1158 Order: "ASC",
1159 }).Result()
1160 Expect(err).NotTo(HaveOccurred())
1161 Expect(els).To(Equal([]string{"1", "2"}))
1162 })
1163
1164 It("should Sort and Get", Label("NonRedisEnterprise"), func() {
1165 size, err := client.LPush(ctx, "list", "1").Result()
1166 Expect(err).NotTo(HaveOccurred())
1167 Expect(size).To(Equal(int64(1)))
1168
1169 size, err = client.LPush(ctx, "list", "3").Result()
1170 Expect(err).NotTo(HaveOccurred())
1171 Expect(size).To(Equal(int64(2)))
1172
1173 size, err = client.LPush(ctx, "list", "2").Result()
1174 Expect(err).NotTo(HaveOccurred())
1175 Expect(size).To(Equal(int64(3)))
1176
1177 err = client.Set(ctx, "object_2", "value2", 0).Err()
1178 Expect(err).NotTo(HaveOccurred())
1179
1180 {
1181 els, err := client.Sort(ctx, "list", &redis.Sort{
1182 Get: []string{"object_*"},
1183 }).Result()
1184 Expect(err).NotTo(HaveOccurred())
1185 Expect(els).To(Equal([]string{"", "value2", ""}))
1186 }
1187
1188 {
1189 els, err := client.SortInterfaces(ctx, "list", &redis.Sort{
1190 Get: []string{"object_*"},
1191 }).Result()
1192 Expect(err).NotTo(HaveOccurred())
1193 Expect(els).To(Equal([]interface{}{nil, "value2", nil}))
1194 }
1195 })
1196
1197 It("should Sort and Store", Label("NonRedisEnterprise"), func() {
1198 size, err := client.LPush(ctx, "list", "1").Result()
1199 Expect(err).NotTo(HaveOccurred())
1200 Expect(size).To(Equal(int64(1)))
1201
1202 size, err = client.LPush(ctx, "list", "3").Result()
1203 Expect(err).NotTo(HaveOccurred())
1204 Expect(size).To(Equal(int64(2)))
1205
1206 size, err = client.LPush(ctx, "list", "2").Result()
1207 Expect(err).NotTo(HaveOccurred())
1208 Expect(size).To(Equal(int64(3)))
1209
1210 n, err := client.SortStore(ctx, "list", "list2", &redis.Sort{
1211 Offset: 0,
1212 Count: 2,
1213 Order: "ASC",
1214 }).Result()
1215 Expect(err).NotTo(HaveOccurred())
1216 Expect(n).To(Equal(int64(2)))
1217
1218 els, err := client.LRange(ctx, "list2", 0, -1).Result()
1219 Expect(err).NotTo(HaveOccurred())
1220 Expect(els).To(Equal([]string{"1", "2"}))
1221 })
1222
1223 It("should Touch", func() {
1224 set1 := client.Set(ctx, "touch1", "hello", 0)
1225 Expect(set1.Err()).NotTo(HaveOccurred())
1226 Expect(set1.Val()).To(Equal("OK"))
1227
1228 set2 := client.Set(ctx, "touch2", "hello", 0)
1229 Expect(set2.Err()).NotTo(HaveOccurred())
1230 Expect(set2.Val()).To(Equal("OK"))
1231
1232 touch := client.Touch(ctx, "touch1", "touch2", "touch3")
1233 Expect(touch.Err()).NotTo(HaveOccurred())
1234 Expect(touch.Val()).To(Equal(int64(2)))
1235 })
1236
1237 It("should ExpireTime", func() {
1238
1239
1240 expireTimeCmd := client.ExpireTime(ctx, "key")
1241 Expect(expireTimeCmd.Err()).NotTo(HaveOccurred())
1242 Expect(expireTimeCmd.Val() < 0).To(Equal(true))
1243
1244 set := client.Set(ctx, "key", "hello", 0)
1245 Expect(set.Err()).NotTo(HaveOccurred())
1246 Expect(set.Val()).To(Equal("OK"))
1247
1248 expireAt := time.Now().Add(time.Minute)
1249 expireAtCmd := client.ExpireAt(ctx, "key", expireAt)
1250 Expect(expireAtCmd.Err()).NotTo(HaveOccurred())
1251 Expect(expireAtCmd.Val()).To(Equal(true))
1252
1253 expireTimeCmd = client.ExpireTime(ctx, "key")
1254 Expect(expireTimeCmd.Err()).NotTo(HaveOccurred())
1255 Expect(expireTimeCmd.Val().Seconds()).To(BeNumerically("==", expireAt.Unix()))
1256 })
1257
1258 It("should TTL", func() {
1259
1260
1261 ttl := client.TTL(ctx, "key")
1262 Expect(ttl.Err()).NotTo(HaveOccurred())
1263 Expect(ttl.Val() < 0).To(Equal(true))
1264
1265 set := client.Set(ctx, "key", "hello", 0)
1266 Expect(set.Err()).NotTo(HaveOccurred())
1267 Expect(set.Val()).To(Equal("OK"))
1268
1269 expire := client.Expire(ctx, "key", 60*time.Second)
1270 Expect(expire.Err()).NotTo(HaveOccurred())
1271 Expect(expire.Val()).To(Equal(true))
1272
1273 ttl = client.TTL(ctx, "key")
1274 Expect(ttl.Err()).NotTo(HaveOccurred())
1275 Expect(ttl.Val()).To(Equal(60 * time.Second))
1276 })
1277
1278 It("should Type", func() {
1279 set := client.Set(ctx, "key", "hello", 0)
1280 Expect(set.Err()).NotTo(HaveOccurred())
1281 Expect(set.Val()).To(Equal("OK"))
1282
1283 type_ := client.Type(ctx, "key")
1284 Expect(type_.Err()).NotTo(HaveOccurred())
1285 Expect(type_.Val()).To(Equal("string"))
1286 })
1287 })
1288
1289 Describe("scanning", func() {
1290 It("should Scan", func() {
1291 for i := 0; i < 1000; i++ {
1292 set := client.Set(ctx, fmt.Sprintf("key%d", i), "hello", 0)
1293 Expect(set.Err()).NotTo(HaveOccurred())
1294 }
1295
1296 keys, cursor, err := client.Scan(ctx, 0, "", 0).Result()
1297 Expect(err).NotTo(HaveOccurred())
1298 Expect(keys).NotTo(BeEmpty())
1299 Expect(cursor).NotTo(BeZero())
1300 })
1301
1302 It("should ScanType", func() {
1303 for i := 0; i < 1000; i++ {
1304 set := client.Set(ctx, fmt.Sprintf("key%d", i), "hello", 0)
1305 Expect(set.Err()).NotTo(HaveOccurred())
1306 }
1307
1308 keys, cursor, err := client.ScanType(ctx, 0, "", 0, "string").Result()
1309 Expect(err).NotTo(HaveOccurred())
1310 Expect(keys).NotTo(BeEmpty())
1311 Expect(cursor).NotTo(BeZero())
1312 })
1313
1314 It("should SScan", func() {
1315 for i := 0; i < 1000; i++ {
1316 sadd := client.SAdd(ctx, "myset", fmt.Sprintf("member%d", i))
1317 Expect(sadd.Err()).NotTo(HaveOccurred())
1318 }
1319
1320 keys, cursor, err := client.SScan(ctx, "myset", 0, "", 0).Result()
1321 Expect(err).NotTo(HaveOccurred())
1322 Expect(keys).NotTo(BeEmpty())
1323 Expect(cursor).NotTo(BeZero())
1324 })
1325
1326 It("should HScan", func() {
1327 for i := 0; i < 1000; i++ {
1328 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
1329 Expect(sadd.Err()).NotTo(HaveOccurred())
1330 }
1331
1332 keys, cursor, err := client.HScan(ctx, "myhash", 0, "", 0).Result()
1333 Expect(err).NotTo(HaveOccurred())
1334
1335 Expect(cursor).To(BeNumerically(">=", 2))
1336 Expect(len(keys)).To(BeNumerically(">=", 2))
1337 Expect(keys[0]).To(HavePrefix("key"))
1338 Expect(keys[1]).To(Equal("hello"))
1339 })
1340
1341 It("should HScan without values", Label("NonRedisEnterprise"), func() {
1342 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
1343 for i := 0; i < 1000; i++ {
1344 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
1345 Expect(sadd.Err()).NotTo(HaveOccurred())
1346 }
1347
1348 keys, cursor, err := client.HScanNoValues(ctx, "myhash", 0, "", 0).Result()
1349 Expect(err).NotTo(HaveOccurred())
1350
1351 Expect(cursor).To(BeNumerically(">=", 2))
1352 Expect(len(keys)).To(BeNumerically(">=", 2))
1353 Expect(keys[0]).To(HavePrefix("key"))
1354 Expect(keys[1]).To(HavePrefix("key"))
1355 Expect(keys).NotTo(BeEmpty())
1356 Expect(cursor).NotTo(BeZero())
1357 })
1358
1359 It("should ZScan", func() {
1360 for i := 0; i < 1000; i++ {
1361 err := client.ZAdd(ctx, "myset", redis.Z{
1362 Score: float64(i),
1363 Member: fmt.Sprintf("member%d", i),
1364 }).Err()
1365 Expect(err).NotTo(HaveOccurred())
1366 }
1367
1368 keys, cursor, err := client.ZScan(ctx, "myset", 0, "", 0).Result()
1369 Expect(err).NotTo(HaveOccurred())
1370 Expect(keys).NotTo(BeEmpty())
1371 Expect(cursor).NotTo(BeZero())
1372 })
1373 })
1374
1375 Describe("strings", func() {
1376 It("should Append", func() {
1377 n, err := client.Exists(ctx, "key").Result()
1378 Expect(err).NotTo(HaveOccurred())
1379 Expect(n).To(Equal(int64(0)))
1380
1381 appendRes := client.Append(ctx, "key", "Hello")
1382 Expect(appendRes.Err()).NotTo(HaveOccurred())
1383 Expect(appendRes.Val()).To(Equal(int64(5)))
1384
1385 appendRes = client.Append(ctx, "key", " World")
1386 Expect(appendRes.Err()).NotTo(HaveOccurred())
1387 Expect(appendRes.Val()).To(Equal(int64(11)))
1388
1389 get := client.Get(ctx, "key")
1390 Expect(get.Err()).NotTo(HaveOccurred())
1391 Expect(get.Val()).To(Equal("Hello World"))
1392 })
1393
1394 It("should BitCount", func() {
1395 set := client.Set(ctx, "key", "foobar", 0)
1396 Expect(set.Err()).NotTo(HaveOccurred())
1397 Expect(set.Val()).To(Equal("OK"))
1398
1399 bitCount := client.BitCount(ctx, "key", nil)
1400 Expect(bitCount.Err()).NotTo(HaveOccurred())
1401 Expect(bitCount.Val()).To(Equal(int64(26)))
1402
1403 bitCount = client.BitCount(ctx, "key", &redis.BitCount{
1404 Start: 0,
1405 End: 0,
1406 })
1407 Expect(bitCount.Err()).NotTo(HaveOccurred())
1408 Expect(bitCount.Val()).To(Equal(int64(4)))
1409
1410 bitCount = client.BitCount(ctx, "key", &redis.BitCount{
1411 Start: 1,
1412 End: 1,
1413 })
1414 Expect(bitCount.Err()).NotTo(HaveOccurred())
1415 Expect(bitCount.Val()).To(Equal(int64(6)))
1416 })
1417
1418 It("should BitOpAnd", Label("NonRedisEnterprise"), func() {
1419 set := client.Set(ctx, "key1", "1", 0)
1420 Expect(set.Err()).NotTo(HaveOccurred())
1421 Expect(set.Val()).To(Equal("OK"))
1422
1423 set = client.Set(ctx, "key2", "0", 0)
1424 Expect(set.Err()).NotTo(HaveOccurred())
1425 Expect(set.Val()).To(Equal("OK"))
1426
1427 bitOpAnd := client.BitOpAnd(ctx, "dest", "key1", "key2")
1428 Expect(bitOpAnd.Err()).NotTo(HaveOccurred())
1429 Expect(bitOpAnd.Val()).To(Equal(int64(1)))
1430
1431 get := client.Get(ctx, "dest")
1432 Expect(get.Err()).NotTo(HaveOccurred())
1433 Expect(get.Val()).To(Equal("0"))
1434 })
1435
1436 It("should BitOpOr", Label("NonRedisEnterprise"), func() {
1437 set := client.Set(ctx, "key1", "1", 0)
1438 Expect(set.Err()).NotTo(HaveOccurred())
1439 Expect(set.Val()).To(Equal("OK"))
1440
1441 set = client.Set(ctx, "key2", "0", 0)
1442 Expect(set.Err()).NotTo(HaveOccurred())
1443 Expect(set.Val()).To(Equal("OK"))
1444
1445 bitOpOr := client.BitOpOr(ctx, "dest", "key1", "key2")
1446 Expect(bitOpOr.Err()).NotTo(HaveOccurred())
1447 Expect(bitOpOr.Val()).To(Equal(int64(1)))
1448
1449 get := client.Get(ctx, "dest")
1450 Expect(get.Err()).NotTo(HaveOccurred())
1451 Expect(get.Val()).To(Equal("1"))
1452 })
1453
1454 It("should BitOpXor", Label("NonRedisEnterprise"), func() {
1455 set := client.Set(ctx, "key1", "\xff", 0)
1456 Expect(set.Err()).NotTo(HaveOccurred())
1457 Expect(set.Val()).To(Equal("OK"))
1458
1459 set = client.Set(ctx, "key2", "\x0f", 0)
1460 Expect(set.Err()).NotTo(HaveOccurred())
1461 Expect(set.Val()).To(Equal("OK"))
1462
1463 bitOpXor := client.BitOpXor(ctx, "dest", "key1", "key2")
1464 Expect(bitOpXor.Err()).NotTo(HaveOccurred())
1465 Expect(bitOpXor.Val()).To(Equal(int64(1)))
1466
1467 get := client.Get(ctx, "dest")
1468 Expect(get.Err()).NotTo(HaveOccurred())
1469 Expect(get.Val()).To(Equal("\xf0"))
1470 })
1471
1472 It("should BitOpDiff", Label("NonRedisEnterprise"), func() {
1473 SkipBeforeRedisVersion(8.2, "BITOP DIFF is available since Redis 8.2")
1474 set := client.Set(ctx, "key1", "\xff", 0)
1475 Expect(set.Err()).NotTo(HaveOccurred())
1476 Expect(set.Val()).To(Equal("OK"))
1477
1478 set = client.Set(ctx, "key2", "\x0f", 0)
1479 Expect(set.Err()).NotTo(HaveOccurred())
1480 Expect(set.Val()).To(Equal("OK"))
1481
1482 bitOpDiff := client.BitOpDiff(ctx, "dest", "key1", "key2")
1483 Expect(bitOpDiff.Err()).NotTo(HaveOccurred())
1484 Expect(bitOpDiff.Val()).To(Equal(int64(1)))
1485
1486 get := client.Get(ctx, "dest")
1487 Expect(get.Err()).NotTo(HaveOccurred())
1488 Expect(get.Val()).To(Equal("\xf0"))
1489 })
1490
1491 It("should BitOpDiff1", Label("NonRedisEnterprise"), func() {
1492 SkipBeforeRedisVersion(8.2, "BITOP DIFF is available since Redis 8.2")
1493 set := client.Set(ctx, "key1", "\xff", 0)
1494 Expect(set.Err()).NotTo(HaveOccurred())
1495 Expect(set.Val()).To(Equal("OK"))
1496
1497 set = client.Set(ctx, "key2", "\x0f", 0)
1498 Expect(set.Err()).NotTo(HaveOccurred())
1499 Expect(set.Val()).To(Equal("OK"))
1500
1501 bitOpDiff1 := client.BitOpDiff1(ctx, "dest", "key1", "key2")
1502 Expect(bitOpDiff1.Err()).NotTo(HaveOccurred())
1503 Expect(bitOpDiff1.Val()).To(Equal(int64(1)))
1504
1505 get := client.Get(ctx, "dest")
1506 Expect(get.Err()).NotTo(HaveOccurred())
1507 Expect(get.Val()).To(Equal("\x00"))
1508 })
1509
1510 It("should BitOpAndOr", Label("NonRedisEnterprise"), func() {
1511 SkipBeforeRedisVersion(8.2, "BITOP ANDOR is available since Redis 8.2")
1512 set := client.Set(ctx, "key1", "\xff", 0)
1513 Expect(set.Err()).NotTo(HaveOccurred())
1514 Expect(set.Val()).To(Equal("OK"))
1515
1516 set = client.Set(ctx, "key2", "\x0f", 0)
1517 Expect(set.Err()).NotTo(HaveOccurred())
1518 Expect(set.Val()).To(Equal("OK"))
1519
1520 bitOpAndOr := client.BitOpAndOr(ctx, "dest", "key1", "key2")
1521 Expect(bitOpAndOr.Err()).NotTo(HaveOccurred())
1522 Expect(bitOpAndOr.Val()).To(Equal(int64(1)))
1523
1524 get := client.Get(ctx, "dest")
1525 Expect(get.Err()).NotTo(HaveOccurred())
1526 Expect(get.Val()).To(Equal("\x0f"))
1527 })
1528
1529 It("should BitOpOne", Label("NonRedisEnterprise"), func() {
1530 SkipBeforeRedisVersion(8.2, "BITOP ONE is available since Redis 8.2")
1531 set := client.Set(ctx, "key1", "\xff", 0)
1532 Expect(set.Err()).NotTo(HaveOccurred())
1533 Expect(set.Val()).To(Equal("OK"))
1534
1535 set = client.Set(ctx, "key2", "\x0f", 0)
1536 Expect(set.Err()).NotTo(HaveOccurred())
1537 Expect(set.Val()).To(Equal("OK"))
1538
1539 bitOpOne := client.BitOpOne(ctx, "dest", "key1", "key2")
1540 Expect(bitOpOne.Err()).NotTo(HaveOccurred())
1541 Expect(bitOpOne.Val()).To(Equal(int64(1)))
1542
1543 get := client.Get(ctx, "dest")
1544 Expect(get.Err()).NotTo(HaveOccurred())
1545 Expect(get.Val()).To(Equal("\xf0"))
1546 })
1547
1548 It("should BitOpNot", Label("NonRedisEnterprise"), func() {
1549 set := client.Set(ctx, "key1", "\x00", 0)
1550 Expect(set.Err()).NotTo(HaveOccurred())
1551 Expect(set.Val()).To(Equal("OK"))
1552
1553 bitOpNot := client.BitOpNot(ctx, "dest", "key1")
1554 Expect(bitOpNot.Err()).NotTo(HaveOccurred())
1555 Expect(bitOpNot.Val()).To(Equal(int64(1)))
1556
1557 get := client.Get(ctx, "dest")
1558 Expect(get.Err()).NotTo(HaveOccurred())
1559 Expect(get.Val()).To(Equal("\xff"))
1560 })
1561
1562 It("should BitPos", func() {
1563 err := client.Set(ctx, "mykey", "\xff\xf0\x00", 0).Err()
1564 Expect(err).NotTo(HaveOccurred())
1565
1566 pos, err := client.BitPos(ctx, "mykey", 0).Result()
1567 Expect(err).NotTo(HaveOccurred())
1568 Expect(pos).To(Equal(int64(12)))
1569
1570 pos, err = client.BitPos(ctx, "mykey", 1).Result()
1571 Expect(err).NotTo(HaveOccurred())
1572 Expect(pos).To(Equal(int64(0)))
1573
1574 pos, err = client.BitPos(ctx, "mykey", 0, 2).Result()
1575 Expect(err).NotTo(HaveOccurred())
1576 Expect(pos).To(Equal(int64(16)))
1577
1578 pos, err = client.BitPos(ctx, "mykey", 1, 2).Result()
1579 Expect(err).NotTo(HaveOccurred())
1580 Expect(pos).To(Equal(int64(-1)))
1581
1582 pos, err = client.BitPos(ctx, "mykey", 0, -1).Result()
1583 Expect(err).NotTo(HaveOccurred())
1584 Expect(pos).To(Equal(int64(16)))
1585
1586 pos, err = client.BitPos(ctx, "mykey", 1, -1).Result()
1587 Expect(err).NotTo(HaveOccurred())
1588 Expect(pos).To(Equal(int64(-1)))
1589
1590 pos, err = client.BitPos(ctx, "mykey", 0, 2, 1).Result()
1591 Expect(err).NotTo(HaveOccurred())
1592 Expect(pos).To(Equal(int64(-1)))
1593
1594 pos, err = client.BitPos(ctx, "mykey", 0, 0, -3).Result()
1595 Expect(err).NotTo(HaveOccurred())
1596 Expect(pos).To(Equal(int64(-1)))
1597
1598 pos, err = client.BitPos(ctx, "mykey", 0, 0, 0).Result()
1599 Expect(err).NotTo(HaveOccurred())
1600 Expect(pos).To(Equal(int64(-1)))
1601 })
1602
1603 It("should BitPosSpan", func() {
1604 err := client.Set(ctx, "mykey", "\x00\xff\x00", 0).Err()
1605 Expect(err).NotTo(HaveOccurred())
1606
1607 pos, err := client.BitPosSpan(ctx, "mykey", 0, 1, 3, "byte").Result()
1608 Expect(err).NotTo(HaveOccurred())
1609 Expect(pos).To(Equal(int64(16)))
1610
1611 pos, err = client.BitPosSpan(ctx, "mykey", 0, 1, 3, "bit").Result()
1612 Expect(err).NotTo(HaveOccurred())
1613 Expect(pos).To(Equal(int64(1)))
1614 })
1615
1616 It("should BitField", func() {
1617 nn, err := client.BitField(ctx, "mykey", "INCRBY", "i5", 100, 1, "GET", "u4", 0).Result()
1618 Expect(err).NotTo(HaveOccurred())
1619 Expect(nn).To(Equal([]int64{1, 0}))
1620
1621 nn, err = client.BitField(ctx, "mykey", "set", "i1", 1, 1, "GET", "u4", 0).Result()
1622 Expect(err).NotTo(HaveOccurred())
1623 Expect(nn).To(Equal([]int64{0, 4}))
1624 })
1625
1626 It("should BitFieldRO", func() {
1627 nn, err := client.BitField(ctx, "mykey", "SET", "u8", 8, 255).Result()
1628 Expect(err).NotTo(HaveOccurred())
1629 Expect(nn).To(Equal([]int64{0}))
1630
1631 nn, err = client.BitFieldRO(ctx, "mykey", "u8", 0).Result()
1632 Expect(err).NotTo(HaveOccurred())
1633 Expect(nn).To(Equal([]int64{0}))
1634
1635 nn, err = client.BitFieldRO(ctx, "mykey", "u8", 0, "u4", 8, "u4", 12, "u4", 13).Result()
1636 Expect(err).NotTo(HaveOccurred())
1637 Expect(nn).To(Equal([]int64{0, 15, 15, 14}))
1638 })
1639
1640 It("should Decr", func() {
1641 set := client.Set(ctx, "key", "10", 0)
1642 Expect(set.Err()).NotTo(HaveOccurred())
1643 Expect(set.Val()).To(Equal("OK"))
1644
1645 decr := client.Decr(ctx, "key")
1646 Expect(decr.Err()).NotTo(HaveOccurred())
1647 Expect(decr.Val()).To(Equal(int64(9)))
1648
1649 set = client.Set(ctx, "key", "234293482390480948029348230948", 0)
1650 Expect(set.Err()).NotTo(HaveOccurred())
1651 Expect(set.Val()).To(Equal("OK"))
1652
1653 decr = client.Decr(ctx, "key")
1654 Expect(decr.Err()).To(MatchError("ERR value is not an integer or out of range"))
1655 Expect(decr.Val()).To(Equal(int64(0)))
1656 })
1657
1658 It("should DecrBy", func() {
1659 set := client.Set(ctx, "key", "10", 0)
1660 Expect(set.Err()).NotTo(HaveOccurred())
1661 Expect(set.Val()).To(Equal("OK"))
1662
1663 decrBy := client.DecrBy(ctx, "key", 5)
1664 Expect(decrBy.Err()).NotTo(HaveOccurred())
1665 Expect(decrBy.Val()).To(Equal(int64(5)))
1666 })
1667
1668 It("should Get", func() {
1669 get := client.Get(ctx, "_")
1670 Expect(get.Err()).To(Equal(redis.Nil))
1671 Expect(get.Val()).To(Equal(""))
1672
1673 set := client.Set(ctx, "key", "hello", 0)
1674 Expect(set.Err()).NotTo(HaveOccurred())
1675 Expect(set.Val()).To(Equal("OK"))
1676
1677 get = client.Get(ctx, "key")
1678 Expect(get.Err()).NotTo(HaveOccurred())
1679 Expect(get.Val()).To(Equal("hello"))
1680 })
1681
1682 It("should GetBit", func() {
1683 setBit := client.SetBit(ctx, "key", 7, 1)
1684 Expect(setBit.Err()).NotTo(HaveOccurred())
1685 Expect(setBit.Val()).To(Equal(int64(0)))
1686
1687 getBit := client.GetBit(ctx, "key", 0)
1688 Expect(getBit.Err()).NotTo(HaveOccurred())
1689 Expect(getBit.Val()).To(Equal(int64(0)))
1690
1691 getBit = client.GetBit(ctx, "key", 7)
1692 Expect(getBit.Err()).NotTo(HaveOccurred())
1693 Expect(getBit.Val()).To(Equal(int64(1)))
1694
1695 getBit = client.GetBit(ctx, "key", 100)
1696 Expect(getBit.Err()).NotTo(HaveOccurred())
1697 Expect(getBit.Val()).To(Equal(int64(0)))
1698 })
1699
1700 It("should GetRange", func() {
1701 set := client.Set(ctx, "key", "This is a string", 0)
1702 Expect(set.Err()).NotTo(HaveOccurred())
1703 Expect(set.Val()).To(Equal("OK"))
1704
1705 getRange := client.GetRange(ctx, "key", 0, 3)
1706 Expect(getRange.Err()).NotTo(HaveOccurred())
1707 Expect(getRange.Val()).To(Equal("This"))
1708
1709 getRange = client.GetRange(ctx, "key", -3, -1)
1710 Expect(getRange.Err()).NotTo(HaveOccurred())
1711 Expect(getRange.Val()).To(Equal("ing"))
1712
1713 getRange = client.GetRange(ctx, "key", 0, -1)
1714 Expect(getRange.Err()).NotTo(HaveOccurred())
1715 Expect(getRange.Val()).To(Equal("This is a string"))
1716
1717 getRange = client.GetRange(ctx, "key", 10, 100)
1718 Expect(getRange.Err()).NotTo(HaveOccurred())
1719 Expect(getRange.Val()).To(Equal("string"))
1720 })
1721
1722 It("should GetSet", func() {
1723 incr := client.Incr(ctx, "key")
1724 Expect(incr.Err()).NotTo(HaveOccurred())
1725 Expect(incr.Val()).To(Equal(int64(1)))
1726
1727 getSet := client.GetSet(ctx, "key", "0")
1728 Expect(getSet.Err()).NotTo(HaveOccurred())
1729 Expect(getSet.Val()).To(Equal("1"))
1730
1731 get := client.Get(ctx, "key")
1732 Expect(get.Err()).NotTo(HaveOccurred())
1733 Expect(get.Val()).To(Equal("0"))
1734 })
1735
1736 It("should GetEX", func() {
1737 set := client.Set(ctx, "key", "value", 100*time.Second)
1738 Expect(set.Err()).NotTo(HaveOccurred())
1739 Expect(set.Val()).To(Equal("OK"))
1740
1741 ttl := client.TTL(ctx, "key")
1742 Expect(ttl.Err()).NotTo(HaveOccurred())
1743 Expect(ttl.Val()).To(BeNumerically("~", 100*time.Second, 3*time.Second))
1744
1745 getEX := client.GetEx(ctx, "key", 200*time.Second)
1746 Expect(getEX.Err()).NotTo(HaveOccurred())
1747 Expect(getEX.Val()).To(Equal("value"))
1748
1749 ttl = client.TTL(ctx, "key")
1750 Expect(ttl.Err()).NotTo(HaveOccurred())
1751 Expect(ttl.Val()).To(BeNumerically("~", 200*time.Second, 3*time.Second))
1752 })
1753
1754 It("should GetDel", func() {
1755 set := client.Set(ctx, "key", "value", 0)
1756 Expect(set.Err()).NotTo(HaveOccurred())
1757 Expect(set.Val()).To(Equal("OK"))
1758
1759 getDel := client.GetDel(ctx, "key")
1760 Expect(getDel.Err()).NotTo(HaveOccurred())
1761 Expect(getDel.Val()).To(Equal("value"))
1762
1763 get := client.Get(ctx, "key")
1764 Expect(get.Err()).To(Equal(redis.Nil))
1765 })
1766
1767 It("should Incr", func() {
1768 set := client.Set(ctx, "key", "10", 0)
1769 Expect(set.Err()).NotTo(HaveOccurred())
1770 Expect(set.Val()).To(Equal("OK"))
1771
1772 incr := client.Incr(ctx, "key")
1773 Expect(incr.Err()).NotTo(HaveOccurred())
1774 Expect(incr.Val()).To(Equal(int64(11)))
1775
1776 get := client.Get(ctx, "key")
1777 Expect(get.Err()).NotTo(HaveOccurred())
1778 Expect(get.Val()).To(Equal("11"))
1779 })
1780
1781 It("should IncrBy", func() {
1782 set := client.Set(ctx, "key", "10", 0)
1783 Expect(set.Err()).NotTo(HaveOccurred())
1784 Expect(set.Val()).To(Equal("OK"))
1785
1786 incrBy := client.IncrBy(ctx, "key", 5)
1787 Expect(incrBy.Err()).NotTo(HaveOccurred())
1788 Expect(incrBy.Val()).To(Equal(int64(15)))
1789 })
1790
1791 It("should IncrByFloat", func() {
1792 set := client.Set(ctx, "key", "10.50", 0)
1793 Expect(set.Err()).NotTo(HaveOccurred())
1794 Expect(set.Val()).To(Equal("OK"))
1795
1796 incrByFloat := client.IncrByFloat(ctx, "key", 0.1)
1797 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
1798 Expect(incrByFloat.Val()).To(Equal(10.6))
1799
1800 set = client.Set(ctx, "key", "5.0e3", 0)
1801 Expect(set.Err()).NotTo(HaveOccurred())
1802 Expect(set.Val()).To(Equal("OK"))
1803
1804 incrByFloat = client.IncrByFloat(ctx, "key", 2.0e2)
1805 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
1806 Expect(incrByFloat.Val()).To(Equal(float64(5200)))
1807 })
1808
1809 It("should IncrByFloatOverflow", func() {
1810 incrByFloat := client.IncrByFloat(ctx, "key", 996945661)
1811 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
1812 Expect(incrByFloat.Val()).To(Equal(float64(996945661)))
1813 })
1814
1815 It("should MSetMGet", func() {
1816 mSet := client.MSet(ctx, "key1", "hello1", "key2", "hello2")
1817 Expect(mSet.Err()).NotTo(HaveOccurred())
1818 Expect(mSet.Val()).To(Equal("OK"))
1819
1820 mGet := client.MGet(ctx, "key1", "key2", "_")
1821 Expect(mGet.Err()).NotTo(HaveOccurred())
1822 Expect(mGet.Val()).To(Equal([]interface{}{"hello1", "hello2", nil}))
1823
1824
1825 type set struct {
1826 Set1 string `redis:"set1"`
1827 Set2 int16 `redis:"set2"`
1828 Set3 time.Duration `redis:"set3"`
1829 Set4 interface{} `redis:"set4"`
1830 Set5 map[string]interface{} `redis:"-"`
1831 }
1832 mSet = client.MSet(ctx, &set{
1833 Set1: "val1",
1834 Set2: 1024,
1835 Set3: 2 * time.Millisecond,
1836 Set4: nil,
1837 Set5: map[string]interface{}{"k1": 1},
1838 })
1839 Expect(mSet.Err()).NotTo(HaveOccurred())
1840 Expect(mSet.Val()).To(Equal("OK"))
1841
1842 mGet = client.MGet(ctx, "set1", "set2", "set3", "set4")
1843 Expect(mGet.Err()).NotTo(HaveOccurred())
1844 Expect(mGet.Val()).To(Equal([]interface{}{
1845 "val1",
1846 "1024",
1847 strconv.Itoa(int(2 * time.Millisecond.Nanoseconds())),
1848 "",
1849 }))
1850 })
1851
1852 It("should scan Mget", func() {
1853 now := time.Now()
1854
1855 err := client.MSet(ctx, "key1", "hello1", "key2", 123, "time", now.Format(time.RFC3339Nano)).Err()
1856 Expect(err).NotTo(HaveOccurred())
1857
1858 res := client.MGet(ctx, "key1", "key2", "_", "time")
1859 Expect(res.Err()).NotTo(HaveOccurred())
1860
1861 type data struct {
1862 Key1 string `redis:"key1"`
1863 Key2 int `redis:"key2"`
1864 Time TimeValue `redis:"time"`
1865 }
1866 var d data
1867 Expect(res.Scan(&d)).NotTo(HaveOccurred())
1868 Expect(d.Time.UnixNano()).To(Equal(now.UnixNano()))
1869 d.Time.Time = time.Time{}
1870 Expect(d).To(Equal(data{
1871 Key1: "hello1",
1872 Key2: 123,
1873 Time: TimeValue{Time: time.Time{}},
1874 }))
1875 })
1876
1877 It("should MSetNX", Label("NonRedisEnterprise"), func() {
1878 mSetNX := client.MSetNX(ctx, "key1", "hello1", "key2", "hello2")
1879 Expect(mSetNX.Err()).NotTo(HaveOccurred())
1880 Expect(mSetNX.Val()).To(Equal(true))
1881
1882 mSetNX = client.MSetNX(ctx, "key2", "hello1", "key3", "hello2")
1883 Expect(mSetNX.Err()).NotTo(HaveOccurred())
1884 Expect(mSetNX.Val()).To(Equal(false))
1885
1886
1887
1888 type set struct {
1889 Set1 string `redis:"set1"`
1890 Set2 int16 `redis:"set2"`
1891 Set3 time.Duration `redis:"set3"`
1892 Set4 interface{} `redis:"set4"`
1893 Set5 map[string]interface{} `redis:"-"`
1894 }
1895 mSetNX = client.MSetNX(ctx, &set{
1896 Set1: "val1",
1897 Set2: 1024,
1898 Set3: 2 * time.Millisecond,
1899 Set4: nil,
1900 Set5: map[string]interface{}{"k1": 1},
1901 })
1902 Expect(mSetNX.Err()).NotTo(HaveOccurred())
1903 Expect(mSetNX.Val()).To(Equal(true))
1904 })
1905
1906 It("should SetWithArgs with TTL", func() {
1907 args := redis.SetArgs{
1908 TTL: 500 * time.Millisecond,
1909 }
1910 err := client.SetArgs(ctx, "key", "hello", args).Err()
1911 Expect(err).NotTo(HaveOccurred())
1912
1913 val, err := client.Get(ctx, "key").Result()
1914 Expect(err).NotTo(HaveOccurred())
1915 Expect(val).To(Equal("hello"))
1916
1917 Eventually(func() error {
1918 return client.Get(ctx, "key").Err()
1919 }, "2s", "100ms").Should(Equal(redis.Nil))
1920 })
1921
1922 It("should SetWithArgs with expiration date", func() {
1923 expireAt := time.Now().AddDate(1, 1, 1)
1924 args := redis.SetArgs{
1925 ExpireAt: expireAt,
1926 }
1927 err := client.SetArgs(ctx, "key", "hello", args).Err()
1928 Expect(err).NotTo(HaveOccurred())
1929
1930 val, err := client.Get(ctx, "key").Result()
1931 Expect(err).NotTo(HaveOccurred())
1932 Expect(val).To(Equal("hello"))
1933
1934
1935
1936 ttl := client.TTL(ctx, "key")
1937 Expect(ttl.Err()).NotTo(HaveOccurred())
1938 Expect(ttl.Val()).ToNot(Equal(-1))
1939 })
1940
1941 It("should SetWithArgs with negative expiration date", func() {
1942 args := redis.SetArgs{
1943 ExpireAt: time.Now().AddDate(-3, 1, 1),
1944 }
1945
1946
1947 err := client.SetArgs(ctx, "key", "hello", args).Err()
1948 Expect(err).NotTo(HaveOccurred())
1949
1950 val, err := client.Get(ctx, "key").Result()
1951 Expect(err).To(Equal(redis.Nil))
1952 Expect(val).To(Equal(""))
1953 })
1954
1955 It("should SetWithArgs with keepttl", func() {
1956
1957 argsWithTTL := redis.SetArgs{
1958 TTL: 5 * time.Second,
1959 }
1960 set := client.SetArgs(ctx, "key", "hello", argsWithTTL)
1961 Expect(set.Err()).NotTo(HaveOccurred())
1962 Expect(set.Result()).To(Equal("OK"))
1963
1964
1965 argsWithKeepTTL := redis.SetArgs{
1966 KeepTTL: true,
1967 }
1968 set = client.SetArgs(ctx, "key", "hello", argsWithKeepTTL)
1969 Expect(set.Err()).NotTo(HaveOccurred())
1970 Expect(set.Result()).To(Equal("OK"))
1971
1972 ttl := client.TTL(ctx, "key")
1973 Expect(ttl.Err()).NotTo(HaveOccurred())
1974
1975 Expect(ttl.Val().Nanoseconds()).NotTo(Equal(-1))
1976 })
1977
1978 It("should SetWithArgs with NX mode and key exists", func() {
1979 err := client.Set(ctx, "key", "hello", 0).Err()
1980 Expect(err).NotTo(HaveOccurred())
1981
1982 args := redis.SetArgs{
1983 Mode: "nx",
1984 }
1985 val, err := client.SetArgs(ctx, "key", "hello", args).Result()
1986 Expect(err).To(Equal(redis.Nil))
1987 Expect(val).To(Equal(""))
1988 })
1989
1990 It("should SetWithArgs with NX mode and key does not exist", func() {
1991 args := redis.SetArgs{
1992 Mode: "nx",
1993 }
1994 val, err := client.SetArgs(ctx, "key", "hello", args).Result()
1995 Expect(err).NotTo(HaveOccurred())
1996 Expect(val).To(Equal("OK"))
1997 })
1998
1999 It("should SetWithArgs with NX mode and GET option", func() {
2000 args := redis.SetArgs{
2001 Mode: "nx",
2002 Get: true,
2003 }
2004 val, err := client.SetArgs(ctx, "key", "hello", args).Result()
2005 Expect(err).To(Equal(redis.Nil))
2006 Expect(val).To(Equal(""))
2007 })
2008
2009 It("should SetWithArgs with expiration, NX mode, and key does not exist", func() {
2010 args := redis.SetArgs{
2011 TTL: 500 * time.Millisecond,
2012 Mode: "nx",
2013 }
2014 val, err := client.SetArgs(ctx, "key", "hello", args).Result()
2015 Expect(err).NotTo(HaveOccurred())
2016 Expect(val).To(Equal("OK"))
2017
2018 Eventually(func() error {
2019 return client.Get(ctx, "key").Err()
2020 }, "1s", "100ms").Should(Equal(redis.Nil))
2021 })
2022
2023 It("should SetWithArgs with expiration, NX mode, and key exists", func() {
2024 e := client.Set(ctx, "key", "hello", 0)
2025 Expect(e.Err()).NotTo(HaveOccurred())
2026
2027 args := redis.SetArgs{
2028 TTL: 500 * time.Millisecond,
2029 Mode: "nx",
2030 }
2031 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2032 Expect(err).To(Equal(redis.Nil))
2033 Expect(val).To(Equal(""))
2034 })
2035
2036 It("should SetWithArgs with expiration, NX mode, and GET option", func() {
2037 args := redis.SetArgs{
2038 TTL: 500 * time.Millisecond,
2039 Mode: "nx",
2040 Get: true,
2041 }
2042 val, err := client.SetArgs(ctx, "key", "hello", args).Result()
2043 Expect(err).To(Equal(redis.Nil))
2044 Expect(val).To(Equal(""))
2045 })
2046
2047 It("should SetWithArgs with XX mode and key does not exist", func() {
2048 args := redis.SetArgs{
2049 Mode: "xx",
2050 }
2051 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2052 Expect(err).To(Equal(redis.Nil))
2053 Expect(val).To(Equal(""))
2054 })
2055
2056 It("should SetWithArgs with XX mode and key exists", func() {
2057 e := client.Set(ctx, "key", "hello", 0).Err()
2058 Expect(e).NotTo(HaveOccurred())
2059
2060 args := redis.SetArgs{
2061 Mode: "xx",
2062 }
2063 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2064 Expect(err).NotTo(HaveOccurred())
2065 Expect(val).To(Equal("OK"))
2066 })
2067
2068 It("should SetWithArgs with XX mode and GET option, and key exists", func() {
2069 e := client.Set(ctx, "key", "hello", 0).Err()
2070 Expect(e).NotTo(HaveOccurred())
2071
2072 args := redis.SetArgs{
2073 Mode: "xx",
2074 Get: true,
2075 }
2076 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2077 Expect(err).NotTo(HaveOccurred())
2078 Expect(val).To(Equal("hello"))
2079 })
2080
2081 It("should SetWithArgs with XX mode and GET option, and key does not exist", func() {
2082 args := redis.SetArgs{
2083 Mode: "xx",
2084 Get: true,
2085 }
2086
2087 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2088 Expect(err).To(Equal(redis.Nil))
2089 Expect(val).To(Equal(""))
2090 })
2091
2092 It("should SetWithArgs with expiration, XX mode, GET option, and key does not exist", func() {
2093 args := redis.SetArgs{
2094 TTL: 500 * time.Millisecond,
2095 Mode: "xx",
2096 Get: true,
2097 }
2098
2099 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2100 Expect(err).To(Equal(redis.Nil))
2101 Expect(val).To(Equal(""))
2102 })
2103
2104 It("should SetWithArgs with expiration, XX mode, GET option, and key exists", func() {
2105 e := client.Set(ctx, "key", "hello", 0)
2106 Expect(e.Err()).NotTo(HaveOccurred())
2107
2108 args := redis.SetArgs{
2109 TTL: 500 * time.Millisecond,
2110 Mode: "xx",
2111 Get: true,
2112 }
2113
2114 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2115 Expect(err).NotTo(HaveOccurred())
2116 Expect(val).To(Equal("hello"))
2117
2118 Eventually(func() error {
2119 return client.Get(ctx, "key").Err()
2120 }, "1s", "100ms").Should(Equal(redis.Nil))
2121 })
2122
2123 It("should SetWithArgs with Get and key does not exist yet", func() {
2124 args := redis.SetArgs{
2125 Get: true,
2126 }
2127
2128 val, err := client.SetArgs(ctx, "key", "hello", args).Result()
2129 Expect(err).To(Equal(redis.Nil))
2130 Expect(val).To(Equal(""))
2131 })
2132
2133 It("should SetWithArgs with Get and key exists", func() {
2134 e := client.Set(ctx, "key", "hello", 0)
2135 Expect(e.Err()).NotTo(HaveOccurred())
2136
2137 args := redis.SetArgs{
2138 Get: true,
2139 }
2140
2141 val, err := client.SetArgs(ctx, "key", "world", args).Result()
2142 Expect(err).NotTo(HaveOccurred())
2143 Expect(val).To(Equal("hello"))
2144 })
2145
2146 It("should Pipelined SetArgs with Get and key exists", func() {
2147 e := client.Set(ctx, "key", "hello", 0)
2148 Expect(e.Err()).NotTo(HaveOccurred())
2149
2150 args := redis.SetArgs{
2151 Get: true,
2152 }
2153
2154 pipe := client.Pipeline()
2155 setArgs := pipe.SetArgs(ctx, "key", "world", args)
2156 _, err := pipe.Exec(ctx)
2157 Expect(err).NotTo(HaveOccurred())
2158
2159 Expect(setArgs.Err()).NotTo(HaveOccurred())
2160 Expect(setArgs.Val()).To(Equal("hello"))
2161 })
2162
2163 It("should Set with expiration", func() {
2164 err := client.Set(ctx, "key", "hello", 100*time.Millisecond).Err()
2165 Expect(err).NotTo(HaveOccurred())
2166
2167 val, err := client.Get(ctx, "key").Result()
2168 Expect(err).NotTo(HaveOccurred())
2169 Expect(val).To(Equal("hello"))
2170
2171 Eventually(func() error {
2172 return client.Get(ctx, "key").Err()
2173 }, "1s", "100ms").Should(Equal(redis.Nil))
2174 })
2175
2176 It("should Set with keepttl", func() {
2177
2178 set := client.Set(ctx, "key", "hello", 5*time.Second)
2179 Expect(set.Err()).NotTo(HaveOccurred())
2180 Expect(set.Val()).To(Equal("OK"))
2181
2182
2183 set = client.Set(ctx, "key", "hello1", redis.KeepTTL)
2184 Expect(set.Err()).NotTo(HaveOccurred())
2185 Expect(set.Val()).To(Equal("OK"))
2186
2187 ttl := client.TTL(ctx, "key")
2188 Expect(ttl.Err()).NotTo(HaveOccurred())
2189
2190 Expect(ttl.Val().Nanoseconds()).NotTo(Equal(-1))
2191 })
2192
2193 It("should SetGet", func() {
2194 set := client.Set(ctx, "key", "hello", 0)
2195 Expect(set.Err()).NotTo(HaveOccurred())
2196 Expect(set.Val()).To(Equal("OK"))
2197
2198 get := client.Get(ctx, "key")
2199 Expect(get.Err()).NotTo(HaveOccurred())
2200 Expect(get.Val()).To(Equal("hello"))
2201 })
2202
2203 It("should SetEX", func() {
2204 err := client.SetEx(ctx, "key", "hello", 1*time.Second).Err()
2205 Expect(err).NotTo(HaveOccurred())
2206
2207 val, err := client.Get(ctx, "key").Result()
2208 Expect(err).NotTo(HaveOccurred())
2209 Expect(val).To(Equal("hello"))
2210
2211 Eventually(func() error {
2212 return client.Get(ctx, "foo").Err()
2213 }, "2s", "100ms").Should(Equal(redis.Nil))
2214 })
2215
2216 It("should SetNX", func() {
2217 setNX := client.SetNX(ctx, "key", "hello", 0)
2218 Expect(setNX.Err()).NotTo(HaveOccurred())
2219 Expect(setNX.Val()).To(Equal(true))
2220
2221 setNX = client.SetNX(ctx, "key", "hello2", 0)
2222 Expect(setNX.Err()).NotTo(HaveOccurred())
2223 Expect(setNX.Val()).To(Equal(false))
2224
2225 get := client.Get(ctx, "key")
2226 Expect(get.Err()).NotTo(HaveOccurred())
2227 Expect(get.Val()).To(Equal("hello"))
2228 })
2229
2230 It("should SetNX with expiration", func() {
2231 isSet, err := client.SetNX(ctx, "key", "hello", time.Second).Result()
2232 Expect(err).NotTo(HaveOccurred())
2233 Expect(isSet).To(Equal(true))
2234
2235 isSet, err = client.SetNX(ctx, "key", "hello2", time.Second).Result()
2236 Expect(err).NotTo(HaveOccurred())
2237 Expect(isSet).To(Equal(false))
2238
2239 val, err := client.Get(ctx, "key").Result()
2240 Expect(err).NotTo(HaveOccurred())
2241 Expect(val).To(Equal("hello"))
2242 })
2243
2244 It("should SetNX with keepttl", func() {
2245 isSet, err := client.SetNX(ctx, "key", "hello1", redis.KeepTTL).Result()
2246 Expect(err).NotTo(HaveOccurred())
2247 Expect(isSet).To(Equal(true))
2248
2249 ttl := client.TTL(ctx, "key")
2250 Expect(ttl.Err()).NotTo(HaveOccurred())
2251 Expect(ttl.Val().Nanoseconds()).To(Equal(int64(-1)))
2252 })
2253
2254 It("should SetXX", func() {
2255 isSet, err := client.SetXX(ctx, "key", "hello2", 0).Result()
2256 Expect(err).NotTo(HaveOccurred())
2257 Expect(isSet).To(Equal(false))
2258
2259 err = client.Set(ctx, "key", "hello", 0).Err()
2260 Expect(err).NotTo(HaveOccurred())
2261
2262 isSet, err = client.SetXX(ctx, "key", "hello2", 0).Result()
2263 Expect(err).NotTo(HaveOccurred())
2264 Expect(isSet).To(Equal(true))
2265
2266 val, err := client.Get(ctx, "key").Result()
2267 Expect(err).NotTo(HaveOccurred())
2268 Expect(val).To(Equal("hello2"))
2269 })
2270
2271 It("should SetXX with expiration", func() {
2272 isSet, err := client.SetXX(ctx, "key", "hello2", time.Second).Result()
2273 Expect(err).NotTo(HaveOccurred())
2274 Expect(isSet).To(Equal(false))
2275
2276 err = client.Set(ctx, "key", "hello", time.Second).Err()
2277 Expect(err).NotTo(HaveOccurred())
2278
2279 isSet, err = client.SetXX(ctx, "key", "hello2", time.Second).Result()
2280 Expect(err).NotTo(HaveOccurred())
2281 Expect(isSet).To(Equal(true))
2282
2283 val, err := client.Get(ctx, "key").Result()
2284 Expect(err).NotTo(HaveOccurred())
2285 Expect(val).To(Equal("hello2"))
2286 })
2287
2288 It("should SetXX with keepttl", func() {
2289 isSet, err := client.SetXX(ctx, "key", "hello2", time.Second).Result()
2290 Expect(err).NotTo(HaveOccurred())
2291 Expect(isSet).To(Equal(false))
2292
2293 err = client.Set(ctx, "key", "hello", time.Second).Err()
2294 Expect(err).NotTo(HaveOccurred())
2295
2296 isSet, err = client.SetXX(ctx, "key", "hello2", 5*time.Second).Result()
2297 Expect(err).NotTo(HaveOccurred())
2298 Expect(isSet).To(Equal(true))
2299
2300 isSet, err = client.SetXX(ctx, "key", "hello3", redis.KeepTTL).Result()
2301 Expect(err).NotTo(HaveOccurred())
2302 Expect(isSet).To(Equal(true))
2303
2304 val, err := client.Get(ctx, "key").Result()
2305 Expect(err).NotTo(HaveOccurred())
2306 Expect(val).To(Equal("hello3"))
2307
2308
2309 ttl, err := client.TTL(ctx, "key").Result()
2310 Expect(err).NotTo(HaveOccurred())
2311 Expect(ttl).NotTo(Equal(-1))
2312 })
2313
2314 It("should SetRange", func() {
2315 set := client.Set(ctx, "key", "Hello World", 0)
2316 Expect(set.Err()).NotTo(HaveOccurred())
2317 Expect(set.Val()).To(Equal("OK"))
2318
2319 range_ := client.SetRange(ctx, "key", 6, "Redis")
2320 Expect(range_.Err()).NotTo(HaveOccurred())
2321 Expect(range_.Val()).To(Equal(int64(11)))
2322
2323 get := client.Get(ctx, "key")
2324 Expect(get.Err()).NotTo(HaveOccurred())
2325 Expect(get.Val()).To(Equal("Hello Redis"))
2326 })
2327
2328 It("should StrLen", func() {
2329 set := client.Set(ctx, "key", "hello", 0)
2330 Expect(set.Err()).NotTo(HaveOccurred())
2331 Expect(set.Val()).To(Equal("OK"))
2332
2333 strLen := client.StrLen(ctx, "key")
2334 Expect(strLen.Err()).NotTo(HaveOccurred())
2335 Expect(strLen.Val()).To(Equal(int64(5)))
2336
2337 strLen = client.StrLen(ctx, "_")
2338 Expect(strLen.Err()).NotTo(HaveOccurred())
2339 Expect(strLen.Val()).To(Equal(int64(0)))
2340 })
2341
2342 It("should Copy", Label("NonRedisEnterprise"), func() {
2343 set := client.Set(ctx, "key", "hello", 0)
2344 Expect(set.Err()).NotTo(HaveOccurred())
2345 Expect(set.Val()).To(Equal("OK"))
2346
2347 copy := client.Copy(ctx, "key", "newKey", redisOptions().DB, false)
2348 Expect(copy.Err()).NotTo(HaveOccurred())
2349 Expect(copy.Val()).To(Equal(int64(1)))
2350
2351
2352 getOld := client.Get(ctx, "key")
2353 Expect(getOld.Err()).NotTo(HaveOccurred())
2354 Expect(getOld.Val()).To(Equal("hello"))
2355 getNew := client.Get(ctx, "newKey")
2356 Expect(getNew.Err()).NotTo(HaveOccurred())
2357 Expect(getNew.Val()).To(Equal("hello"))
2358
2359
2360 overwrite := client.Copy(ctx, "newKey", "key", redisOptions().DB, false)
2361 Expect(overwrite.Val()).To(Equal(int64(0)))
2362
2363
2364 replace := client.Copy(ctx, "newKey", "key", redisOptions().DB, true)
2365 Expect(replace.Val()).To(Equal(int64(1)))
2366 })
2367
2368 It("should fail module loadex", Label("NonRedisEnterprise"), func() {
2369 dryRun := client.ModuleLoadex(ctx, &redis.ModuleLoadexConfig{
2370 Path: "/path/to/non-existent-library.so",
2371 Conf: map[string]interface{}{
2372 "param1": "value1",
2373 },
2374 Args: []interface{}{
2375 "arg1",
2376 },
2377 })
2378 Expect(dryRun.Err()).To(HaveOccurred())
2379 Expect(dryRun.Err().Error()).To(Equal("ERR Error loading the extension. Please check the server logs."))
2380 })
2381
2382 It("converts the module loadex configuration to a slice of arguments correctly", func() {
2383 conf := &redis.ModuleLoadexConfig{
2384 Path: "/path/to/your/module.so",
2385 Conf: map[string]interface{}{
2386 "param1": "value1",
2387 },
2388 Args: []interface{}{
2389 "arg1",
2390 "arg2",
2391 3,
2392 },
2393 }
2394
2395 args := conf.ToArgs()
2396
2397
2398 expectedArgs := []interface{}{
2399 "MODULE",
2400 "LOADEX",
2401 "/path/to/your/module.so",
2402 "CONFIG",
2403 "param1",
2404 "value1",
2405 "ARGS",
2406 "arg1",
2407 "ARGS",
2408 "arg2",
2409 "ARGS",
2410 3,
2411 }
2412
2413 Expect(args).To(Equal(expectedArgs))
2414 })
2415
2416 It("should IncrByFloat with edge cases", func() {
2417
2418 set := client.Set(ctx, "key", "10.5", 0)
2419 Expect(set.Err()).NotTo(HaveOccurred())
2420
2421 incrByFloat := client.IncrByFloat(ctx, "key", -2.3)
2422 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2423 Expect(incrByFloat.Val()).To(BeNumerically("~", 8.2, 0.0001))
2424
2425
2426 incrByFloat = client.IncrByFloat(ctx, "key", 0.0)
2427 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2428 Expect(incrByFloat.Val()).To(BeNumerically("~", 8.2, 0.0001))
2429
2430
2431 incrByFloat = client.IncrByFloat(ctx, "key", 0.0001)
2432 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2433 Expect(incrByFloat.Val()).To(BeNumerically("~", 8.2001, 0.00001))
2434
2435
2436 incrByFloat = client.IncrByFloat(ctx, "nonexistent", 5.5)
2437 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2438 Expect(incrByFloat.Val()).To(Equal(5.5))
2439
2440
2441 set = client.Set(ctx, "intkey", "42", 0)
2442 Expect(set.Err()).NotTo(HaveOccurred())
2443
2444 incrByFloat = client.IncrByFloat(ctx, "intkey", 0.5)
2445 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2446 Expect(incrByFloat.Val()).To(Equal(42.5))
2447
2448
2449 set = client.Set(ctx, "scikey", "1.5e2", 0)
2450 Expect(set.Err()).NotTo(HaveOccurred())
2451
2452 incrByFloat = client.IncrByFloat(ctx, "scikey", 5.0)
2453 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2454 Expect(incrByFloat.Val()).To(Equal(155.0))
2455
2456
2457 incrByFloat = client.IncrByFloat(ctx, "scikey", -1.5e1)
2458 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2459 Expect(incrByFloat.Val()).To(Equal(140.0))
2460
2461
2462 set = client.Set(ctx, "stringkey", "notanumber", 0)
2463 Expect(set.Err()).NotTo(HaveOccurred())
2464
2465 incrByFloat = client.IncrByFloat(ctx, "stringkey", 1.0)
2466 Expect(incrByFloat.Err()).To(HaveOccurred())
2467 Expect(incrByFloat.Err().Error()).To(ContainSubstring("value is not a valid float"))
2468
2469
2470 set = client.Set(ctx, "largekey", "1.7976931348623157e+308", 0)
2471 Expect(set.Err()).NotTo(HaveOccurred())
2472
2473
2474 incrByFloat = client.IncrByFloat(ctx, "largekey", -1.0e+308)
2475 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2476 Expect(incrByFloat.Val()).To(BeNumerically("~", 7.976931348623157e+307, 1e+300))
2477
2478
2479 set = client.Set(ctx, "smallkey", "1e-10", 0)
2480 Expect(set.Err()).NotTo(HaveOccurred())
2481
2482 incrByFloat = client.IncrByFloat(ctx, "smallkey", 1e-10)
2483 Expect(incrByFloat.Err()).NotTo(HaveOccurred())
2484 Expect(incrByFloat.Val()).To(BeNumerically("~", 2e-10, 1e-15))
2485 })
2486 })
2487
2488 Describe("hashes", func() {
2489 It("should HDel", func() {
2490 hSet := client.HSet(ctx, "hash", "key", "hello")
2491 Expect(hSet.Err()).NotTo(HaveOccurred())
2492
2493 hDel := client.HDel(ctx, "hash", "key")
2494 Expect(hDel.Err()).NotTo(HaveOccurred())
2495 Expect(hDel.Val()).To(Equal(int64(1)))
2496
2497 hDel = client.HDel(ctx, "hash", "key")
2498 Expect(hDel.Err()).NotTo(HaveOccurred())
2499 Expect(hDel.Val()).To(Equal(int64(0)))
2500 })
2501
2502 It("should HExists", func() {
2503 hSet := client.HSet(ctx, "hash", "key", "hello")
2504 Expect(hSet.Err()).NotTo(HaveOccurred())
2505
2506 hExists := client.HExists(ctx, "hash", "key")
2507 Expect(hExists.Err()).NotTo(HaveOccurred())
2508 Expect(hExists.Val()).To(Equal(true))
2509
2510 hExists = client.HExists(ctx, "hash", "key1")
2511 Expect(hExists.Err()).NotTo(HaveOccurred())
2512 Expect(hExists.Val()).To(Equal(false))
2513 })
2514
2515 It("should HGet", func() {
2516 hSet := client.HSet(ctx, "hash", "key", "hello")
2517 Expect(hSet.Err()).NotTo(HaveOccurred())
2518
2519 hGet := client.HGet(ctx, "hash", "key")
2520 Expect(hGet.Err()).NotTo(HaveOccurred())
2521 Expect(hGet.Val()).To(Equal("hello"))
2522
2523 hGet = client.HGet(ctx, "hash", "key1")
2524 Expect(hGet.Err()).To(Equal(redis.Nil))
2525 Expect(hGet.Val()).To(Equal(""))
2526 })
2527
2528 It("should HGetAll", func() {
2529 err := client.HSet(ctx, "hash", "key1", "hello1").Err()
2530 Expect(err).NotTo(HaveOccurred())
2531 err = client.HSet(ctx, "hash", "key2", "hello2").Err()
2532 Expect(err).NotTo(HaveOccurred())
2533
2534 m, err := client.HGetAll(ctx, "hash").Result()
2535 Expect(err).NotTo(HaveOccurred())
2536 Expect(m).To(Equal(map[string]string{"key1": "hello1", "key2": "hello2"}))
2537 })
2538
2539 It("should scan", func() {
2540 now := time.Now()
2541
2542 err := client.HMSet(ctx, "hash", "key1", "hello1", "key2", 123, "time", now.Format(time.RFC3339Nano)).Err()
2543 Expect(err).NotTo(HaveOccurred())
2544
2545 res := client.HGetAll(ctx, "hash")
2546 Expect(res.Err()).NotTo(HaveOccurred())
2547
2548 type data struct {
2549 Key1 string `redis:"key1"`
2550 Key2 int `redis:"key2"`
2551 Time TimeValue `redis:"time"`
2552 }
2553 var d data
2554 Expect(res.Scan(&d)).NotTo(HaveOccurred())
2555 Expect(d.Time.UnixNano()).To(Equal(now.UnixNano()))
2556 d.Time.Time = time.Time{}
2557 Expect(d).To(Equal(data{
2558 Key1: "hello1",
2559 Key2: 123,
2560 Time: TimeValue{Time: time.Time{}},
2561 }))
2562
2563 type data2 struct {
2564 Key1 string `redis:"key1"`
2565 Key2 int `redis:"key2"`
2566 Time time.Time `redis:"time"`
2567 }
2568 err = client.HSet(ctx, "hash", &data2{
2569 Key1: "hello2",
2570 Key2: 200,
2571 Time: now,
2572 }).Err()
2573 Expect(err).NotTo(HaveOccurred())
2574
2575 var d2 data2
2576 err = client.HMGet(ctx, "hash", "key1", "key2", "time").Scan(&d2)
2577 Expect(err).NotTo(HaveOccurred())
2578 Expect(d2.Key1).To(Equal("hello2"))
2579 Expect(d2.Key2).To(Equal(200))
2580 Expect(d2.Time.Unix()).To(Equal(now.Unix()))
2581 })
2582
2583 It("should HIncrBy", func() {
2584 hSet := client.HSet(ctx, "hash", "key", "5")
2585 Expect(hSet.Err()).NotTo(HaveOccurred())
2586
2587 hIncrBy := client.HIncrBy(ctx, "hash", "key", 1)
2588 Expect(hIncrBy.Err()).NotTo(HaveOccurred())
2589 Expect(hIncrBy.Val()).To(Equal(int64(6)))
2590
2591 hIncrBy = client.HIncrBy(ctx, "hash", "key", -1)
2592 Expect(hIncrBy.Err()).NotTo(HaveOccurred())
2593 Expect(hIncrBy.Val()).To(Equal(int64(5)))
2594
2595 hIncrBy = client.HIncrBy(ctx, "hash", "key", -10)
2596 Expect(hIncrBy.Err()).NotTo(HaveOccurred())
2597 Expect(hIncrBy.Val()).To(Equal(int64(-5)))
2598 })
2599
2600 It("should HIncrByFloat", func() {
2601 hSet := client.HSet(ctx, "hash", "field", "10.50")
2602 Expect(hSet.Err()).NotTo(HaveOccurred())
2603 Expect(hSet.Val()).To(Equal(int64(1)))
2604
2605 hIncrByFloat := client.HIncrByFloat(ctx, "hash", "field", 0.1)
2606 Expect(hIncrByFloat.Err()).NotTo(HaveOccurred())
2607 Expect(hIncrByFloat.Val()).To(Equal(10.6))
2608
2609 hSet = client.HSet(ctx, "hash", "field", "5.0e3")
2610 Expect(hSet.Err()).NotTo(HaveOccurred())
2611 Expect(hSet.Val()).To(Equal(int64(0)))
2612
2613 hIncrByFloat = client.HIncrByFloat(ctx, "hash", "field", 2.0e2)
2614 Expect(hIncrByFloat.Err()).NotTo(HaveOccurred())
2615 Expect(hIncrByFloat.Val()).To(Equal(float64(5200)))
2616 })
2617
2618 It("should HKeys", func() {
2619 hkeys := client.HKeys(ctx, "hash")
2620 Expect(hkeys.Err()).NotTo(HaveOccurred())
2621 Expect(hkeys.Val()).To(Equal([]string{}))
2622
2623 hset := client.HSet(ctx, "hash", "key1", "hello1")
2624 Expect(hset.Err()).NotTo(HaveOccurred())
2625 hset = client.HSet(ctx, "hash", "key2", "hello2")
2626 Expect(hset.Err()).NotTo(HaveOccurred())
2627
2628 hkeys = client.HKeys(ctx, "hash")
2629 Expect(hkeys.Err()).NotTo(HaveOccurred())
2630 Expect(hkeys.Val()).To(Equal([]string{"key1", "key2"}))
2631 })
2632
2633 It("should HLen", func() {
2634 hSet := client.HSet(ctx, "hash", "key1", "hello1")
2635 Expect(hSet.Err()).NotTo(HaveOccurred())
2636 hSet = client.HSet(ctx, "hash", "key2", "hello2")
2637 Expect(hSet.Err()).NotTo(HaveOccurred())
2638
2639 hLen := client.HLen(ctx, "hash")
2640 Expect(hLen.Err()).NotTo(HaveOccurred())
2641 Expect(hLen.Val()).To(Equal(int64(2)))
2642 })
2643
2644 It("should HMGet", func() {
2645 err := client.HSet(ctx, "hash", "key1", "hello1", "key2", "hello2").Err()
2646 Expect(err).NotTo(HaveOccurred())
2647
2648 vals, err := client.HMGet(ctx, "hash", "key1", "key2", "_").Result()
2649 Expect(err).NotTo(HaveOccurred())
2650 Expect(vals).To(Equal([]interface{}{"hello1", "hello2", nil}))
2651 })
2652
2653 It("should HSet", func() {
2654 ok, err := client.HSet(ctx, "hash", map[string]interface{}{
2655 "key1": "hello1",
2656 "key2": "hello2",
2657 }).Result()
2658 Expect(err).NotTo(HaveOccurred())
2659 Expect(ok).To(Equal(int64(2)))
2660
2661 v, err := client.HGet(ctx, "hash", "key1").Result()
2662 Expect(err).NotTo(HaveOccurred())
2663 Expect(v).To(Equal("hello1"))
2664
2665 v, err = client.HGet(ctx, "hash", "key2").Result()
2666 Expect(err).NotTo(HaveOccurred())
2667 Expect(v).To(Equal("hello2"))
2668
2669 keys, err := client.HKeys(ctx, "hash").Result()
2670 Expect(err).NotTo(HaveOccurred())
2671 Expect(keys).To(ConsistOf([]string{"key1", "key2"}))
2672 })
2673
2674 It("should HSet", func() {
2675 hSet := client.HSet(ctx, "hash", "key", "hello")
2676 Expect(hSet.Err()).NotTo(HaveOccurred())
2677 Expect(hSet.Val()).To(Equal(int64(1)))
2678
2679 hGet := client.HGet(ctx, "hash", "key")
2680 Expect(hGet.Err()).NotTo(HaveOccurred())
2681 Expect(hGet.Val()).To(Equal("hello"))
2682
2683
2684
2685 type set struct {
2686 Set1 string `redis:"set1"`
2687 Set2 int16 `redis:"set2"`
2688 Set3 time.Duration `redis:"set3"`
2689 Set4 interface{} `redis:"set4"`
2690 Set5 map[string]interface{} `redis:"-"`
2691 Set6 string `redis:"set6,omitempty"`
2692 }
2693
2694 hSet = client.HSet(ctx, "hash", &set{
2695 Set1: "val1",
2696 Set2: 1024,
2697 Set3: 2 * time.Millisecond,
2698 Set4: nil,
2699 Set5: map[string]interface{}{"k1": 1},
2700 })
2701 Expect(hSet.Err()).NotTo(HaveOccurred())
2702 Expect(hSet.Val()).To(Equal(int64(4)))
2703
2704 hMGet := client.HMGet(ctx, "hash", "set1", "set2", "set3", "set4", "set5", "set6")
2705 Expect(hMGet.Err()).NotTo(HaveOccurred())
2706 Expect(hMGet.Val()).To(Equal([]interface{}{
2707 "val1",
2708 "1024",
2709 strconv.Itoa(int(2 * time.Millisecond.Nanoseconds())),
2710 "",
2711 nil,
2712 nil,
2713 }))
2714
2715 hSet = client.HSet(ctx, "hash2", &set{
2716 Set1: "val2",
2717 Set6: "val",
2718 })
2719 Expect(hSet.Err()).NotTo(HaveOccurred())
2720 Expect(hSet.Val()).To(Equal(int64(5)))
2721
2722 hMGet = client.HMGet(ctx, "hash2", "set1", "set6")
2723 Expect(hMGet.Err()).NotTo(HaveOccurred())
2724 Expect(hMGet.Val()).To(Equal([]interface{}{
2725 "val2",
2726 "val",
2727 }))
2728
2729 type setOmitEmpty struct {
2730 Set1 string `redis:"set1"`
2731 Set2 int `redis:"set2,omitempty"`
2732 Set3 time.Duration `redis:"set3,omitempty"`
2733 Set4 string `redis:"set4,omitempty"`
2734 Set5 time.Time `redis:"set5,omitempty"`
2735 Set6 *numberStruct `redis:"set6,omitempty"`
2736 Set7 numberStruct `redis:"set7,omitempty"`
2737 }
2738
2739 hSet = client.HSet(ctx, "hash3", &setOmitEmpty{
2740 Set1: "val",
2741 })
2742 Expect(hSet.Err()).NotTo(HaveOccurred())
2743
2744
2745 Expect(hSet.Val()).To(Equal(int64(2)))
2746
2747 hGetAll := client.HGetAll(ctx, "hash3")
2748 Expect(hGetAll.Err()).NotTo(HaveOccurred())
2749 Expect(hGetAll.Val()).To(Equal(map[string]string{
2750 "set1": "val",
2751 "set7": `{"Number":0}`,
2752 }))
2753 var hash3 setOmitEmpty
2754 Expect(hGetAll.Scan(&hash3)).NotTo(HaveOccurred())
2755 Expect(hash3.Set1).To(Equal("val"))
2756 Expect(hash3.Set2).To(Equal(0))
2757 Expect(hash3.Set3).To(Equal(time.Duration(0)))
2758 Expect(hash3.Set4).To(Equal(""))
2759 Expect(hash3.Set5).To(Equal(time.Time{}))
2760 Expect(hash3.Set6).To(BeNil())
2761 Expect(hash3.Set7).To(Equal(numberStruct{}))
2762
2763 now := time.Now()
2764 hSet = client.HSet(ctx, "hash4", setOmitEmpty{
2765 Set1: "val",
2766 Set5: now,
2767 Set6: &numberStruct{
2768 Number: 5,
2769 },
2770 Set7: numberStruct{
2771 Number: 3,
2772 },
2773 })
2774 Expect(hSet.Err()).NotTo(HaveOccurred())
2775 Expect(hSet.Val()).To(Equal(int64(4)))
2776
2777 hGetAll = client.HGetAll(ctx, "hash4")
2778 Expect(hGetAll.Err()).NotTo(HaveOccurred())
2779 Expect(hGetAll.Val()).To(Equal(map[string]string{
2780 "set1": "val",
2781 "set5": now.Format(time.RFC3339Nano),
2782 "set6": `{"Number":5}`,
2783 "set7": `{"Number":3}`,
2784 }))
2785 })
2786
2787 It("should HSetNX", func() {
2788 hSetNX := client.HSetNX(ctx, "hash", "key", "hello")
2789 Expect(hSetNX.Err()).NotTo(HaveOccurred())
2790 Expect(hSetNX.Val()).To(Equal(true))
2791
2792 hSetNX = client.HSetNX(ctx, "hash", "key", "hello")
2793 Expect(hSetNX.Err()).NotTo(HaveOccurred())
2794 Expect(hSetNX.Val()).To(Equal(false))
2795
2796 hGet := client.HGet(ctx, "hash", "key")
2797 Expect(hGet.Err()).NotTo(HaveOccurred())
2798 Expect(hGet.Val()).To(Equal("hello"))
2799 })
2800
2801 It("should HVals", func() {
2802 err := client.HSet(ctx, "hash", "key1", "hello1").Err()
2803 Expect(err).NotTo(HaveOccurred())
2804 err = client.HSet(ctx, "hash", "key2", "hello2").Err()
2805 Expect(err).NotTo(HaveOccurred())
2806
2807 v, err := client.HVals(ctx, "hash").Result()
2808 Expect(err).NotTo(HaveOccurred())
2809 Expect(v).To(Equal([]string{"hello1", "hello2"}))
2810
2811 var slice []string
2812 err = client.HVals(ctx, "hash").ScanSlice(&slice)
2813 Expect(err).NotTo(HaveOccurred())
2814 Expect(slice).To(Equal([]string{"hello1", "hello2"}))
2815 })
2816
2817 It("should HRandField", func() {
2818 err := client.HSet(ctx, "hash", "key1", "hello1").Err()
2819 Expect(err).NotTo(HaveOccurred())
2820 err = client.HSet(ctx, "hash", "key2", "hello2").Err()
2821 Expect(err).NotTo(HaveOccurred())
2822
2823 v := client.HRandField(ctx, "hash", 1)
2824 Expect(v.Err()).NotTo(HaveOccurred())
2825 Expect(v.Val()).To(Or(Equal([]string{"key1"}), Equal([]string{"key2"})))
2826
2827 v = client.HRandField(ctx, "hash", 0)
2828 Expect(v.Err()).NotTo(HaveOccurred())
2829 Expect(v.Val()).To(HaveLen(0))
2830
2831 kv, err := client.HRandFieldWithValues(ctx, "hash", 1).Result()
2832 Expect(err).NotTo(HaveOccurred())
2833 Expect(kv).To(Or(
2834 Equal([]redis.KeyValue{{Key: "key1", Value: "hello1"}}),
2835 Equal([]redis.KeyValue{{Key: "key2", Value: "hello2"}}),
2836 ))
2837 })
2838
2839 It("should HStrLen", func() {
2840 hSet := client.HSet(ctx, "hash", "key", "hello")
2841 Expect(hSet.Err()).NotTo(HaveOccurred())
2842
2843 hStrLen := client.HStrLen(ctx, "hash", "key")
2844 Expect(hStrLen.Err()).NotTo(HaveOccurred())
2845 Expect(hStrLen.Val()).To(Equal(int64(len("hello"))))
2846
2847 nonHStrLen := client.HStrLen(ctx, "hash", "keyNon")
2848 Expect(hStrLen.Err()).NotTo(HaveOccurred())
2849 Expect(nonHStrLen.Val()).To(Equal(int64(0)))
2850
2851 hDel := client.HDel(ctx, "hash", "key")
2852 Expect(hDel.Err()).NotTo(HaveOccurred())
2853 Expect(hDel.Val()).To(Equal(int64(1)))
2854 })
2855
2856 It("should HExpire", Label("hash-expiration", "NonRedisEnterprise"), func() {
2857 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2858 res, err := client.HExpire(ctx, "no_such_key", 10*time.Second, "field1", "field2", "field3").Result()
2859 Expect(err).To(BeNil())
2860 Expect(res).To(BeEquivalentTo([]int64{-2, -2, -2}))
2861
2862 for i := 0; i < 100; i++ {
2863 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2864 Expect(sadd.Err()).NotTo(HaveOccurred())
2865 }
2866
2867 res, err = client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key2", "key200").Result()
2868 Expect(err).NotTo(HaveOccurred())
2869 Expect(res).To(Equal([]int64{1, 1, -2}))
2870 })
2871
2872 It("should HPExpire", Label("hash-expiration", "NonRedisEnterprise"), func() {
2873 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2874 res, err := client.HPExpire(ctx, "no_such_key", 10*time.Second, "field1", "field2", "field3").Result()
2875 Expect(err).To(BeNil())
2876 Expect(res).To(BeEquivalentTo([]int64{-2, -2, -2}))
2877
2878 for i := 0; i < 100; i++ {
2879 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2880 Expect(sadd.Err()).NotTo(HaveOccurred())
2881 }
2882
2883 res, err = client.HPExpire(ctx, "myhash", 10*time.Second, "key1", "key2", "key200").Result()
2884 Expect(err).NotTo(HaveOccurred())
2885 Expect(res).To(Equal([]int64{1, 1, -2}))
2886 })
2887
2888 It("should HExpireAt", Label("hash-expiration", "NonRedisEnterprise"), func() {
2889 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2890 resEmpty, err := client.HExpireAt(ctx, "no_such_key", time.Now().Add(10*time.Second), "field1", "field2", "field3").Result()
2891 Expect(err).To(BeNil())
2892 Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
2893
2894 for i := 0; i < 100; i++ {
2895 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2896 Expect(sadd.Err()).NotTo(HaveOccurred())
2897 }
2898
2899 res, err := client.HExpireAt(ctx, "myhash", time.Now().Add(10*time.Second), "key1", "key2", "key200").Result()
2900 Expect(err).NotTo(HaveOccurred())
2901 Expect(res).To(Equal([]int64{1, 1, -2}))
2902 })
2903
2904 It("should HPExpireAt", Label("hash-expiration", "NonRedisEnterprise"), func() {
2905 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2906 resEmpty, err := client.HPExpireAt(ctx, "no_such_key", time.Now().Add(10*time.Second), "field1", "field2", "field3").Result()
2907 Expect(err).To(BeNil())
2908 Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
2909
2910 for i := 0; i < 100; i++ {
2911 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2912 Expect(sadd.Err()).NotTo(HaveOccurred())
2913 }
2914
2915 res, err := client.HPExpireAt(ctx, "myhash", time.Now().Add(10*time.Second), "key1", "key2", "key200").Result()
2916 Expect(err).NotTo(HaveOccurred())
2917 Expect(res).To(Equal([]int64{1, 1, -2}))
2918 })
2919
2920 It("should HPersist", Label("hash-expiration", "NonRedisEnterprise"), func() {
2921 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2922 resEmpty, err := client.HPersist(ctx, "no_such_key", "field1", "field2", "field3").Result()
2923 Expect(err).To(BeNil())
2924 Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
2925
2926 for i := 0; i < 100; i++ {
2927 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2928 Expect(sadd.Err()).NotTo(HaveOccurred())
2929 }
2930
2931 res, err := client.HPersist(ctx, "myhash", "key1", "key2", "key200").Result()
2932 Expect(err).NotTo(HaveOccurred())
2933 Expect(res).To(Equal([]int64{-1, -1, -2}))
2934
2935 res, err = client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
2936 Expect(err).NotTo(HaveOccurred())
2937 Expect(res).To(Equal([]int64{1, -2}))
2938
2939 res, err = client.HPersist(ctx, "myhash", "key1", "key2", "key200").Result()
2940 Expect(err).NotTo(HaveOccurred())
2941 Expect(res).To(Equal([]int64{1, -1, -2}))
2942 })
2943
2944 It("should HExpireTime", Label("hash-expiration", "NonRedisEnterprise"), func() {
2945 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2946 resEmpty, err := client.HExpireTime(ctx, "no_such_key", "field1", "field2", "field3").Result()
2947 Expect(err).To(BeNil())
2948 Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
2949
2950 for i := 0; i < 100; i++ {
2951 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2952 Expect(sadd.Err()).NotTo(HaveOccurred())
2953 }
2954
2955 res, err := client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
2956 Expect(err).NotTo(HaveOccurred())
2957 Expect(res).To(Equal([]int64{1, -2}))
2958
2959 res, err = client.HExpireTime(ctx, "myhash", "key1", "key2", "key200").Result()
2960 Expect(err).NotTo(HaveOccurred())
2961 Expect(res[0]).To(BeNumerically("~", time.Now().Add(10*time.Second).Unix(), 1))
2962 })
2963
2964 It("should HPExpireTime", Label("hash-expiration", "NonRedisEnterprise"), func() {
2965 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2966 resEmpty, err := client.HPExpireTime(ctx, "no_such_key", "field1", "field2", "field3").Result()
2967 Expect(err).To(BeNil())
2968 Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
2969
2970 for i := 0; i < 100; i++ {
2971 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2972 Expect(sadd.Err()).NotTo(HaveOccurred())
2973 }
2974
2975 expireAt := time.Now().Add(10 * time.Second)
2976 res, err := client.HPExpireAt(ctx, "myhash", expireAt, "key1", "key200").Result()
2977 Expect(err).NotTo(HaveOccurred())
2978 Expect(res).To(Equal([]int64{1, -2}))
2979
2980 res, err = client.HPExpireTime(ctx, "myhash", "key1", "key2", "key200").Result()
2981 Expect(err).NotTo(HaveOccurred())
2982 Expect(res).To(BeEquivalentTo([]int64{expireAt.UnixMilli(), -1, -2}))
2983 })
2984
2985 It("should HTTL", Label("hash-expiration", "NonRedisEnterprise"), func() {
2986 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
2987 resEmpty, err := client.HTTL(ctx, "no_such_key", "field1", "field2", "field3").Result()
2988 Expect(err).To(BeNil())
2989 Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
2990
2991 for i := 0; i < 100; i++ {
2992 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2993 Expect(sadd.Err()).NotTo(HaveOccurred())
2994 }
2995
2996 res, err := client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
2997 Expect(err).NotTo(HaveOccurred())
2998 Expect(res).To(Equal([]int64{1, -2}))
2999
3000 res, err = client.HTTL(ctx, "myhash", "key1", "key2", "key200").Result()
3001 Expect(err).NotTo(HaveOccurred())
3002 Expect(res).To(Equal([]int64{10, -1, -2}))
3003 })
3004
3005 It("should HPTTL", Label("hash-expiration", "NonRedisEnterprise"), func() {
3006 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
3007 resEmpty, err := client.HPTTL(ctx, "no_such_key", "field1", "field2", "field3").Result()
3008 Expect(err).To(BeNil())
3009 Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
3010
3011 for i := 0; i < 100; i++ {
3012 sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
3013 Expect(sadd.Err()).NotTo(HaveOccurred())
3014 }
3015
3016 res, err := client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
3017 Expect(err).NotTo(HaveOccurred())
3018 Expect(res).To(Equal([]int64{1, -2}))
3019
3020 res, err = client.HPTTL(ctx, "myhash", "key1", "key2", "key200").Result()
3021 Expect(err).NotTo(HaveOccurred())
3022 Expect(res[0]).To(BeNumerically("~", 10*time.Second.Milliseconds(), 1))
3023 })
3024
3025 It("should HGETDEL", Label("hash", "HGETDEL"), func() {
3026 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3027
3028 err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2", "f3", "val3").Err()
3029 Expect(err).NotTo(HaveOccurred())
3030
3031
3032 res, err := client.HGetDel(ctx, "myhash", "f1", "f2").Result()
3033 Expect(err).NotTo(HaveOccurred())
3034
3035 Expect(res).To(Equal([]string{"val1", "val2"}))
3036
3037
3038 remaining, err := client.HMGet(ctx, "myhash", "f1", "f2", "f3").Result()
3039 Expect(err).NotTo(HaveOccurred())
3040 Expect(remaining[0]).To(BeNil())
3041 Expect(remaining[1]).To(BeNil())
3042 Expect(remaining[2]).To(Equal("val3"))
3043 })
3044
3045 It("should return nil responses for HGETDEL on non-existent key", Label("hash", "HGETDEL"), func() {
3046 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3047
3048 res, err := client.HGetDel(ctx, "nonexistent", "f1", "f2").Result()
3049 Expect(err).To(BeNil())
3050 Expect(res).To(Equal([]string{"", ""}))
3051 })
3052
3053
3054
3055
3056 It("should HGETEX with EX option", Label("hash", "HGETEX"), func() {
3057 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3058
3059 err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
3060 Expect(err).NotTo(HaveOccurred())
3061
3062
3063 opt := redis.HGetEXOptions{
3064 ExpirationType: redis.HGetEXExpirationEX,
3065 ExpirationVal: 60,
3066 }
3067 res, err := client.HGetEXWithArgs(ctx, "myhash", &opt, "f1", "f2").Result()
3068 Expect(err).NotTo(HaveOccurred())
3069 Expect(res).To(Equal([]string{"val1", "val2"}))
3070 })
3071
3072 It("should HGETEX with PERSIST option", Label("hash", "HGETEX"), func() {
3073 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3074
3075 err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
3076 Expect(err).NotTo(HaveOccurred())
3077
3078
3079 opt := redis.HGetEXOptions{ExpirationType: redis.HGetEXExpirationPERSIST}
3080 res, err := client.HGetEXWithArgs(ctx, "myhash", &opt, "f1", "f2").Result()
3081 Expect(err).NotTo(HaveOccurred())
3082 Expect(res).To(Equal([]string{"val1", "val2"}))
3083 })
3084
3085 It("should HGETEX with EXAT option", Label("hash", "HGETEX"), func() {
3086 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3087
3088 err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
3089 Expect(err).NotTo(HaveOccurred())
3090
3091
3092 expireAt := time.Now().Add(60 * time.Second).Unix()
3093 opt := redis.HGetEXOptions{
3094 ExpirationType: redis.HGetEXExpirationEXAT,
3095 ExpirationVal: expireAt,
3096 }
3097 res, err := client.HGetEXWithArgs(ctx, "myhash", &opt, "f1", "f2").Result()
3098 Expect(err).NotTo(HaveOccurred())
3099 Expect(res).To(Equal([]string{"val1", "val2"}))
3100 })
3101
3102
3103
3104
3105 It("should HSETEX with FNX condition", Label("hash", "HSETEX"), func() {
3106 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3107
3108 opt := redis.HSetEXOptions{
3109 Condition: redis.HSetEXFNX,
3110 ExpirationType: redis.HSetEXExpirationEX,
3111 ExpirationVal: 60,
3112 }
3113 res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val1").Result()
3114 Expect(err).NotTo(HaveOccurred())
3115 Expect(res).To(Equal(int64(1)))
3116
3117 opt = redis.HSetEXOptions{
3118 Condition: redis.HSetEXFNX,
3119 ExpirationType: redis.HSetEXExpirationEX,
3120 ExpirationVal: 60,
3121 }
3122 res, err = client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val2").Result()
3123 Expect(err).NotTo(HaveOccurred())
3124 Expect(res).To(Equal(int64(0)))
3125 })
3126
3127 It("should HSETEX with FXX condition", Label("hash", "HSETEX"), func() {
3128 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3129
3130 err := client.HSet(ctx, "myhash", "f2", "val1").Err()
3131 Expect(err).NotTo(HaveOccurred())
3132
3133 opt := redis.HSetEXOptions{
3134 Condition: redis.HSetEXFXX,
3135 ExpirationType: redis.HSetEXExpirationEX,
3136 ExpirationVal: 60,
3137 }
3138 res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f2", "val2").Result()
3139 Expect(err).NotTo(HaveOccurred())
3140 Expect(res).To(Equal(int64(1)))
3141 opt = redis.HSetEXOptions{
3142 Condition: redis.HSetEXFXX,
3143 ExpirationType: redis.HSetEXExpirationEX,
3144 ExpirationVal: 60,
3145 }
3146 res, err = client.HSetEXWithArgs(ctx, "myhash", &opt, "f3", "val3").Result()
3147 Expect(err).NotTo(HaveOccurred())
3148 Expect(res).To(Equal(int64(0)))
3149 })
3150
3151 It("should HSETEX with multiple field operations", Label("hash", "HSETEX"), func() {
3152 SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
3153
3154 opt := redis.HSetEXOptions{
3155 ExpirationType: redis.HSetEXExpirationEX,
3156 ExpirationVal: 60,
3157 }
3158 res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val1", "f2", "val2").Result()
3159 Expect(err).NotTo(HaveOccurred())
3160 Expect(res).To(Equal(int64(1)))
3161
3162 values, err := client.HMGet(ctx, "myhash", "f1", "f2").Result()
3163 Expect(err).NotTo(HaveOccurred())
3164 Expect(values).To(Equal([]interface{}{"val1", "val2"}))
3165 })
3166 })
3167
3168 Describe("hyperloglog", func() {
3169 It("should PFMerge", Label("NonRedisEnterprise"), func() {
3170 pfAdd := client.PFAdd(ctx, "hll1", "1", "2", "3", "4", "5")
3171 Expect(pfAdd.Err()).NotTo(HaveOccurred())
3172
3173 pfCount := client.PFCount(ctx, "hll1")
3174 Expect(pfCount.Err()).NotTo(HaveOccurred())
3175 Expect(pfCount.Val()).To(Equal(int64(5)))
3176
3177 pfAdd = client.PFAdd(ctx, "hll2", "a", "b", "c", "d", "e")
3178 Expect(pfAdd.Err()).NotTo(HaveOccurred())
3179
3180 pfMerge := client.PFMerge(ctx, "hllMerged", "hll1", "hll2")
3181 Expect(pfMerge.Err()).NotTo(HaveOccurred())
3182
3183 pfCount = client.PFCount(ctx, "hllMerged")
3184 Expect(pfCount.Err()).NotTo(HaveOccurred())
3185 Expect(pfCount.Val()).To(Equal(int64(10)))
3186
3187 pfCount = client.PFCount(ctx, "hll1", "hll2")
3188 Expect(pfCount.Err()).NotTo(HaveOccurred())
3189 Expect(pfCount.Val()).To(Equal(int64(10)))
3190 })
3191 })
3192
3193 Describe("lists", func() {
3194 It("should BLPop", Label("NonRedisEnterprise"), func() {
3195 rPush := client.RPush(ctx, "list1", "a", "b", "c")
3196 Expect(rPush.Err()).NotTo(HaveOccurred())
3197
3198 bLPop := client.BLPop(ctx, 0, "list1", "list2")
3199 Expect(bLPop.Err()).NotTo(HaveOccurred())
3200 Expect(bLPop.Val()).To(Equal([]string{"list1", "a"}))
3201 })
3202
3203 It("should BLPopBlocks", func() {
3204 started := make(chan bool)
3205 done := make(chan bool)
3206 go func() {
3207 defer GinkgoRecover()
3208
3209 started <- true
3210 bLPop := client.BLPop(ctx, 0, "list")
3211 Expect(bLPop.Err()).NotTo(HaveOccurred())
3212 Expect(bLPop.Val()).To(Equal([]string{"list", "a"}))
3213 done <- true
3214 }()
3215 <-started
3216
3217 select {
3218 case <-done:
3219 Fail("BLPop is not blocked")
3220 case <-time.After(time.Second):
3221
3222 }
3223
3224 rPush := client.RPush(ctx, "list", "a")
3225 Expect(rPush.Err()).NotTo(HaveOccurred())
3226
3227 select {
3228 case <-done:
3229
3230 case <-time.After(time.Second):
3231 Fail("BLPop is still blocked")
3232 }
3233 })
3234
3235 It("should BLPop timeout", func() {
3236 val, err := client.BLPop(ctx, time.Second, "list1").Result()
3237 Expect(err).To(Equal(redis.Nil))
3238 Expect(val).To(BeNil())
3239
3240 Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
3241
3242 stats := client.PoolStats()
3243 Expect(stats.Hits).To(Equal(uint32(2)))
3244 Expect(stats.Misses).To(Equal(uint32(1)))
3245 Expect(stats.Timeouts).To(Equal(uint32(0)))
3246 })
3247
3248 It("should BRPop", Label("NonRedisEnterprise"), func() {
3249 rPush := client.RPush(ctx, "list1", "a", "b", "c")
3250 Expect(rPush.Err()).NotTo(HaveOccurred())
3251
3252 bRPop := client.BRPop(ctx, 0, "list1", "list2")
3253 Expect(bRPop.Err()).NotTo(HaveOccurred())
3254 Expect(bRPop.Val()).To(Equal([]string{"list1", "c"}))
3255 })
3256
3257 It("should BRPop blocks", func() {
3258 started := make(chan bool)
3259 done := make(chan bool)
3260 go func() {
3261 defer GinkgoRecover()
3262
3263 started <- true
3264 brpop := client.BRPop(ctx, 0, "list")
3265 Expect(brpop.Err()).NotTo(HaveOccurred())
3266 Expect(brpop.Val()).To(Equal([]string{"list", "a"}))
3267 done <- true
3268 }()
3269 <-started
3270
3271 select {
3272 case <-done:
3273 Fail("BRPop is not blocked")
3274 case <-time.After(time.Second):
3275
3276 }
3277
3278 rPush := client.RPush(ctx, "list", "a")
3279 Expect(rPush.Err()).NotTo(HaveOccurred())
3280
3281 select {
3282 case <-done:
3283
3284 case <-time.After(time.Second):
3285 Fail("BRPop is still blocked")
3286
3287 }
3288 })
3289
3290 It("should BRPopLPush", Label("NonRedisEnterprise"), func() {
3291 _, err := client.BRPopLPush(ctx, "list1", "list2", time.Second).Result()
3292 Expect(err).To(Equal(redis.Nil))
3293
3294 err = client.RPush(ctx, "list1", "a", "b", "c").Err()
3295 Expect(err).NotTo(HaveOccurred())
3296
3297 v, err := client.BRPopLPush(ctx, "list1", "list2", 0).Result()
3298 Expect(err).NotTo(HaveOccurred())
3299 Expect(v).To(Equal("c"))
3300 })
3301
3302 It("should LCS", Label("NonRedisEnterprise"), func() {
3303 err := client.MSet(ctx, "key1", "ohmytext", "key2", "mynewtext").Err()
3304 Expect(err).NotTo(HaveOccurred())
3305
3306 lcs, err := client.LCS(ctx, &redis.LCSQuery{
3307 Key1: "key1",
3308 Key2: "key2",
3309 }).Result()
3310
3311 Expect(err).NotTo(HaveOccurred())
3312 Expect(lcs.MatchString).To(Equal("mytext"))
3313
3314 lcs, err = client.LCS(ctx, &redis.LCSQuery{
3315 Key1: "nonexistent_key1",
3316 Key2: "key2",
3317 }).Result()
3318
3319 Expect(err).NotTo(HaveOccurred())
3320 Expect(lcs.MatchString).To(Equal(""))
3321
3322 lcs, err = client.LCS(ctx, &redis.LCSQuery{
3323 Key1: "key1",
3324 Key2: "key2",
3325 Len: true,
3326 }).Result()
3327 Expect(err).NotTo(HaveOccurred())
3328 Expect(lcs.MatchString).To(Equal(""))
3329 Expect(lcs.Len).To(Equal(int64(6)))
3330
3331 lcs, err = client.LCS(ctx, &redis.LCSQuery{
3332 Key1: "key1",
3333 Key2: "key2",
3334 Idx: true,
3335 }).Result()
3336 Expect(err).NotTo(HaveOccurred())
3337 Expect(lcs.MatchString).To(Equal(""))
3338 Expect(lcs.Len).To(Equal(int64(6)))
3339 Expect(lcs.Matches).To(Equal([]redis.LCSMatchedPosition{
3340 {
3341 Key1: redis.LCSPosition{Start: 4, End: 7},
3342 Key2: redis.LCSPosition{Start: 5, End: 8},
3343 MatchLen: 0,
3344 },
3345 {
3346 Key1: redis.LCSPosition{Start: 2, End: 3},
3347 Key2: redis.LCSPosition{Start: 0, End: 1},
3348 MatchLen: 0,
3349 },
3350 }))
3351
3352 lcs, err = client.LCS(ctx, &redis.LCSQuery{
3353 Key1: "key1",
3354 Key2: "key2",
3355 Idx: true,
3356 MinMatchLen: 3,
3357 WithMatchLen: true,
3358 }).Result()
3359 Expect(err).NotTo(HaveOccurred())
3360 Expect(lcs.MatchString).To(Equal(""))
3361 Expect(lcs.Len).To(Equal(int64(6)))
3362 Expect(lcs.Matches).To(Equal([]redis.LCSMatchedPosition{
3363 {
3364 Key1: redis.LCSPosition{Start: 4, End: 7},
3365 Key2: redis.LCSPosition{Start: 5, End: 8},
3366 MatchLen: 4,
3367 },
3368 }))
3369
3370 _, err = client.Set(ctx, "keywithstringvalue", "golang", 0).Result()
3371 Expect(err).NotTo(HaveOccurred())
3372 _, err = client.LPush(ctx, "keywithnonstringvalue", "somevalue").Result()
3373 Expect(err).NotTo(HaveOccurred())
3374 _, err = client.LCS(ctx, &redis.LCSQuery{
3375 Key1: "keywithstringvalue",
3376 Key2: "keywithnonstringvalue",
3377 }).Result()
3378 Expect(err).To(HaveOccurred())
3379 Expect(err.Error()).To(Equal("ERR The specified keys must contain string values"))
3380 })
3381
3382 It("should LIndex", func() {
3383 lPush := client.LPush(ctx, "list", "World")
3384 Expect(lPush.Err()).NotTo(HaveOccurred())
3385 lPush = client.LPush(ctx, "list", "Hello")
3386 Expect(lPush.Err()).NotTo(HaveOccurred())
3387
3388 lIndex := client.LIndex(ctx, "list", 0)
3389 Expect(lIndex.Err()).NotTo(HaveOccurred())
3390 Expect(lIndex.Val()).To(Equal("Hello"))
3391
3392 lIndex = client.LIndex(ctx, "list", -1)
3393 Expect(lIndex.Err()).NotTo(HaveOccurred())
3394 Expect(lIndex.Val()).To(Equal("World"))
3395
3396 lIndex = client.LIndex(ctx, "list", 3)
3397 Expect(lIndex.Err()).To(Equal(redis.Nil))
3398 Expect(lIndex.Val()).To(Equal(""))
3399 })
3400
3401 It("should LInsert", func() {
3402 rPush := client.RPush(ctx, "list", "Hello")
3403 Expect(rPush.Err()).NotTo(HaveOccurred())
3404 rPush = client.RPush(ctx, "list", "World")
3405 Expect(rPush.Err()).NotTo(HaveOccurred())
3406
3407 lInsert := client.LInsert(ctx, "list", "BEFORE", "World", "There")
3408 Expect(lInsert.Err()).NotTo(HaveOccurred())
3409 Expect(lInsert.Val()).To(Equal(int64(3)))
3410
3411 lRange := client.LRange(ctx, "list", 0, -1)
3412 Expect(lRange.Err()).NotTo(HaveOccurred())
3413 Expect(lRange.Val()).To(Equal([]string{"Hello", "There", "World"}))
3414 })
3415
3416 It("should LMPop", Label("NonRedisEnterprise"), func() {
3417 err := client.LPush(ctx, "list1", "one", "two", "three", "four", "five").Err()
3418 Expect(err).NotTo(HaveOccurred())
3419
3420 err = client.LPush(ctx, "list2", "a", "b", "c", "d", "e").Err()
3421 Expect(err).NotTo(HaveOccurred())
3422
3423 key, val, err := client.LMPop(ctx, "left", 3, "list1", "list2").Result()
3424 Expect(err).NotTo(HaveOccurred())
3425 Expect(key).To(Equal("list1"))
3426 Expect(val).To(Equal([]string{"five", "four", "three"}))
3427
3428 key, val, err = client.LMPop(ctx, "right", 3, "list1", "list2").Result()
3429 Expect(err).NotTo(HaveOccurred())
3430 Expect(key).To(Equal("list1"))
3431 Expect(val).To(Equal([]string{"one", "two"}))
3432
3433 key, val, err = client.LMPop(ctx, "left", 1, "list1", "list2").Result()
3434 Expect(err).NotTo(HaveOccurred())
3435 Expect(key).To(Equal("list2"))
3436 Expect(val).To(Equal([]string{"e"}))
3437
3438 key, val, err = client.LMPop(ctx, "right", 10, "list1", "list2").Result()
3439 Expect(err).NotTo(HaveOccurred())
3440 Expect(key).To(Equal("list2"))
3441 Expect(val).To(Equal([]string{"a", "b", "c", "d"}))
3442
3443 err = client.LMPop(ctx, "left", 10, "list1", "list2").Err()
3444 Expect(err).To(Equal(redis.Nil))
3445
3446 err = client.Set(ctx, "list3", 1024, 0).Err()
3447 Expect(err).NotTo(HaveOccurred())
3448
3449 err = client.LMPop(ctx, "left", 10, "list1", "list2", "list3").Err()
3450 Expect(err.Error()).To(Equal("WRONGTYPE Operation against a key holding the wrong kind of value"))
3451
3452 err = client.LMPop(ctx, "right", 0, "list1", "list2").Err()
3453 Expect(err).To(HaveOccurred())
3454 })
3455
3456 It("should BLMPop", Label("NonRedisEnterprise"), func() {
3457 err := client.LPush(ctx, "list1", "one", "two", "three", "four", "five").Err()
3458 Expect(err).NotTo(HaveOccurred())
3459
3460 err = client.LPush(ctx, "list2", "a", "b", "c", "d", "e").Err()
3461 Expect(err).NotTo(HaveOccurred())
3462
3463 key, val, err := client.BLMPop(ctx, 0, "left", 3, "list1", "list2").Result()
3464 Expect(err).NotTo(HaveOccurred())
3465 Expect(key).To(Equal("list1"))
3466 Expect(val).To(Equal([]string{"five", "four", "three"}))
3467
3468 key, val, err = client.BLMPop(ctx, 0, "right", 3, "list1", "list2").Result()
3469 Expect(err).NotTo(HaveOccurred())
3470 Expect(key).To(Equal("list1"))
3471 Expect(val).To(Equal([]string{"one", "two"}))
3472
3473 key, val, err = client.BLMPop(ctx, 0, "left", 1, "list1", "list2").Result()
3474 Expect(err).NotTo(HaveOccurred())
3475 Expect(key).To(Equal("list2"))
3476 Expect(val).To(Equal([]string{"e"}))
3477
3478 key, val, err = client.BLMPop(ctx, 0, "right", 10, "list1", "list2").Result()
3479 Expect(err).NotTo(HaveOccurred())
3480 Expect(key).To(Equal("list2"))
3481 Expect(val).To(Equal([]string{"a", "b", "c", "d"}))
3482 })
3483
3484 It("should BLMPopBlocks", func() {
3485 started := make(chan bool)
3486 done := make(chan bool)
3487 go func() {
3488 defer GinkgoRecover()
3489
3490 started <- true
3491 key, val, err := client.BLMPop(ctx, 0, "left", 1, "list_list").Result()
3492 Expect(err).NotTo(HaveOccurred())
3493 Expect(key).To(Equal("list_list"))
3494 Expect(val).To(Equal([]string{"a"}))
3495 done <- true
3496 }()
3497 <-started
3498
3499 select {
3500 case <-done:
3501 Fail("BLMPop is not blocked")
3502 case <-time.After(time.Second):
3503
3504 }
3505
3506 _, err := client.LPush(ctx, "list_list", "a").Result()
3507 Expect(err).NotTo(HaveOccurred())
3508
3509 select {
3510 case <-done:
3511
3512 case <-time.After(time.Second):
3513 Fail("BLMPop is still blocked")
3514 }
3515 })
3516
3517 It("should BLMPop timeout", func() {
3518 _, val, err := client.BLMPop(ctx, time.Second, "left", 1, "list1").Result()
3519 Expect(err).To(Equal(redis.Nil))
3520 Expect(val).To(BeNil())
3521
3522 Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
3523
3524 stats := client.PoolStats()
3525 Expect(stats.Hits).To(Equal(uint32(2)))
3526 Expect(stats.Misses).To(Equal(uint32(1)))
3527 Expect(stats.Timeouts).To(Equal(uint32(0)))
3528 })
3529
3530 It("should LLen", func() {
3531 lPush := client.LPush(ctx, "list", "World")
3532 Expect(lPush.Err()).NotTo(HaveOccurred())
3533 lPush = client.LPush(ctx, "list", "Hello")
3534 Expect(lPush.Err()).NotTo(HaveOccurred())
3535
3536 lLen := client.LLen(ctx, "list")
3537 Expect(lLen.Err()).NotTo(HaveOccurred())
3538 Expect(lLen.Val()).To(Equal(int64(2)))
3539 })
3540
3541 It("should LPop", func() {
3542 rPush := client.RPush(ctx, "list", "one")
3543 Expect(rPush.Err()).NotTo(HaveOccurred())
3544 rPush = client.RPush(ctx, "list", "two")
3545 Expect(rPush.Err()).NotTo(HaveOccurred())
3546 rPush = client.RPush(ctx, "list", "three")
3547 Expect(rPush.Err()).NotTo(HaveOccurred())
3548
3549 lPop := client.LPop(ctx, "list")
3550 Expect(lPop.Err()).NotTo(HaveOccurred())
3551 Expect(lPop.Val()).To(Equal("one"))
3552
3553 lRange := client.LRange(ctx, "list", 0, -1)
3554 Expect(lRange.Err()).NotTo(HaveOccurred())
3555 Expect(lRange.Val()).To(Equal([]string{"two", "three"}))
3556 })
3557
3558 It("should LPopCount", func() {
3559 rPush := client.RPush(ctx, "list", "one")
3560 Expect(rPush.Err()).NotTo(HaveOccurred())
3561 rPush = client.RPush(ctx, "list", "two")
3562 Expect(rPush.Err()).NotTo(HaveOccurred())
3563 rPush = client.RPush(ctx, "list", "three")
3564 Expect(rPush.Err()).NotTo(HaveOccurred())
3565 rPush = client.RPush(ctx, "list", "four")
3566 Expect(rPush.Err()).NotTo(HaveOccurred())
3567
3568 lPopCount := client.LPopCount(ctx, "list", 2)
3569 Expect(lPopCount.Err()).NotTo(HaveOccurred())
3570 Expect(lPopCount.Val()).To(Equal([]string{"one", "two"}))
3571
3572 lRange := client.LRange(ctx, "list", 0, -1)
3573 Expect(lRange.Err()).NotTo(HaveOccurred())
3574 Expect(lRange.Val()).To(Equal([]string{"three", "four"}))
3575 })
3576
3577 It("should LPos", func() {
3578 rPush := client.RPush(ctx, "list", "a")
3579 Expect(rPush.Err()).NotTo(HaveOccurred())
3580 rPush = client.RPush(ctx, "list", "b")
3581 Expect(rPush.Err()).NotTo(HaveOccurred())
3582 rPush = client.RPush(ctx, "list", "c")
3583 Expect(rPush.Err()).NotTo(HaveOccurred())
3584 rPush = client.RPush(ctx, "list", "b")
3585 Expect(rPush.Err()).NotTo(HaveOccurred())
3586
3587 lPos := client.LPos(ctx, "list", "b", redis.LPosArgs{})
3588 Expect(lPos.Err()).NotTo(HaveOccurred())
3589 Expect(lPos.Val()).To(Equal(int64(1)))
3590
3591 lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: 2})
3592 Expect(lPos.Err()).NotTo(HaveOccurred())
3593 Expect(lPos.Val()).To(Equal(int64(3)))
3594
3595 lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: -2})
3596 Expect(lPos.Err()).NotTo(HaveOccurred())
3597 Expect(lPos.Val()).To(Equal(int64(1)))
3598
3599 lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: 2, MaxLen: 1})
3600 Expect(lPos.Err()).To(Equal(redis.Nil))
3601
3602 lPos = client.LPos(ctx, "list", "z", redis.LPosArgs{})
3603 Expect(lPos.Err()).To(Equal(redis.Nil))
3604 })
3605
3606 It("should LPosCount", func() {
3607 rPush := client.RPush(ctx, "list", "a")
3608 Expect(rPush.Err()).NotTo(HaveOccurred())
3609 rPush = client.RPush(ctx, "list", "b")
3610 Expect(rPush.Err()).NotTo(HaveOccurred())
3611 rPush = client.RPush(ctx, "list", "c")
3612 Expect(rPush.Err()).NotTo(HaveOccurred())
3613 rPush = client.RPush(ctx, "list", "b")
3614 Expect(rPush.Err()).NotTo(HaveOccurred())
3615
3616 lPos := client.LPosCount(ctx, "list", "b", 2, redis.LPosArgs{})
3617 Expect(lPos.Err()).NotTo(HaveOccurred())
3618 Expect(lPos.Val()).To(Equal([]int64{1, 3}))
3619
3620 lPos = client.LPosCount(ctx, "list", "b", 2, redis.LPosArgs{Rank: 2})
3621 Expect(lPos.Err()).NotTo(HaveOccurred())
3622 Expect(lPos.Val()).To(Equal([]int64{3}))
3623
3624 lPos = client.LPosCount(ctx, "list", "b", 1, redis.LPosArgs{Rank: 1, MaxLen: 1})
3625 Expect(lPos.Err()).NotTo(HaveOccurred())
3626 Expect(lPos.Val()).To(Equal([]int64{}))
3627
3628 lPos = client.LPosCount(ctx, "list", "b", 1, redis.LPosArgs{Rank: 1, MaxLen: 0})
3629 Expect(lPos.Err()).NotTo(HaveOccurred())
3630 Expect(lPos.Val()).To(Equal([]int64{1}))
3631 })
3632
3633 It("should LPush", func() {
3634 lPush := client.LPush(ctx, "list", "World")
3635 Expect(lPush.Err()).NotTo(HaveOccurred())
3636 lPush = client.LPush(ctx, "list", "Hello")
3637 Expect(lPush.Err()).NotTo(HaveOccurred())
3638
3639 lRange := client.LRange(ctx, "list", 0, -1)
3640 Expect(lRange.Err()).NotTo(HaveOccurred())
3641 Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
3642 })
3643
3644 It("should LPushX", func() {
3645 lPush := client.LPush(ctx, "list", "World")
3646 Expect(lPush.Err()).NotTo(HaveOccurred())
3647
3648 lPushX := client.LPushX(ctx, "list", "Hello")
3649 Expect(lPushX.Err()).NotTo(HaveOccurred())
3650 Expect(lPushX.Val()).To(Equal(int64(2)))
3651
3652 lPush = client.LPush(ctx, "list1", "three")
3653 Expect(lPush.Err()).NotTo(HaveOccurred())
3654 Expect(lPush.Val()).To(Equal(int64(1)))
3655
3656 lPushX = client.LPushX(ctx, "list1", "two", "one")
3657 Expect(lPushX.Err()).NotTo(HaveOccurred())
3658 Expect(lPushX.Val()).To(Equal(int64(3)))
3659
3660 lPushX = client.LPushX(ctx, "list2", "Hello")
3661 Expect(lPushX.Err()).NotTo(HaveOccurred())
3662 Expect(lPushX.Val()).To(Equal(int64(0)))
3663
3664 lRange := client.LRange(ctx, "list", 0, -1)
3665 Expect(lRange.Err()).NotTo(HaveOccurred())
3666 Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
3667
3668 lRange = client.LRange(ctx, "list1", 0, -1)
3669 Expect(lRange.Err()).NotTo(HaveOccurred())
3670 Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
3671
3672 lRange = client.LRange(ctx, "list2", 0, -1)
3673 Expect(lRange.Err()).NotTo(HaveOccurred())
3674 Expect(lRange.Val()).To(Equal([]string{}))
3675 })
3676
3677 It("should LRange", func() {
3678 rPush := client.RPush(ctx, "list", "one")
3679 Expect(rPush.Err()).NotTo(HaveOccurred())
3680 rPush = client.RPush(ctx, "list", "two")
3681 Expect(rPush.Err()).NotTo(HaveOccurred())
3682 rPush = client.RPush(ctx, "list", "three")
3683 Expect(rPush.Err()).NotTo(HaveOccurred())
3684
3685 lRange := client.LRange(ctx, "list", 0, 0)
3686 Expect(lRange.Err()).NotTo(HaveOccurred())
3687 Expect(lRange.Val()).To(Equal([]string{"one"}))
3688
3689 lRange = client.LRange(ctx, "list", -3, 2)
3690 Expect(lRange.Err()).NotTo(HaveOccurred())
3691 Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
3692
3693 lRange = client.LRange(ctx, "list", -100, 100)
3694 Expect(lRange.Err()).NotTo(HaveOccurred())
3695 Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
3696
3697 lRange = client.LRange(ctx, "list", 5, 10)
3698 Expect(lRange.Err()).NotTo(HaveOccurred())
3699 Expect(lRange.Val()).To(Equal([]string{}))
3700 })
3701
3702 It("should LRem", func() {
3703 rPush := client.RPush(ctx, "list", "hello")
3704 Expect(rPush.Err()).NotTo(HaveOccurred())
3705 rPush = client.RPush(ctx, "list", "hello")
3706 Expect(rPush.Err()).NotTo(HaveOccurred())
3707 rPush = client.RPush(ctx, "list", "key")
3708 Expect(rPush.Err()).NotTo(HaveOccurred())
3709 rPush = client.RPush(ctx, "list", "hello")
3710 Expect(rPush.Err()).NotTo(HaveOccurred())
3711
3712 lRem := client.LRem(ctx, "list", -2, "hello")
3713 Expect(lRem.Err()).NotTo(HaveOccurred())
3714 Expect(lRem.Val()).To(Equal(int64(2)))
3715
3716 lRange := client.LRange(ctx, "list", 0, -1)
3717 Expect(lRange.Err()).NotTo(HaveOccurred())
3718 Expect(lRange.Val()).To(Equal([]string{"hello", "key"}))
3719 })
3720
3721 It("should LSet", func() {
3722 rPush := client.RPush(ctx, "list", "one")
3723 Expect(rPush.Err()).NotTo(HaveOccurred())
3724 rPush = client.RPush(ctx, "list", "two")
3725 Expect(rPush.Err()).NotTo(HaveOccurred())
3726 rPush = client.RPush(ctx, "list", "three")
3727 Expect(rPush.Err()).NotTo(HaveOccurred())
3728
3729 lSet := client.LSet(ctx, "list", 0, "four")
3730 Expect(lSet.Err()).NotTo(HaveOccurred())
3731 Expect(lSet.Val()).To(Equal("OK"))
3732
3733 lSet = client.LSet(ctx, "list", -2, "five")
3734 Expect(lSet.Err()).NotTo(HaveOccurred())
3735 Expect(lSet.Val()).To(Equal("OK"))
3736
3737 lRange := client.LRange(ctx, "list", 0, -1)
3738 Expect(lRange.Err()).NotTo(HaveOccurred())
3739 Expect(lRange.Val()).To(Equal([]string{"four", "five", "three"}))
3740 })
3741
3742 It("should LTrim", func() {
3743 rPush := client.RPush(ctx, "list", "one")
3744 Expect(rPush.Err()).NotTo(HaveOccurred())
3745 rPush = client.RPush(ctx, "list", "two")
3746 Expect(rPush.Err()).NotTo(HaveOccurred())
3747 rPush = client.RPush(ctx, "list", "three")
3748 Expect(rPush.Err()).NotTo(HaveOccurred())
3749
3750 lTrim := client.LTrim(ctx, "list", 1, -1)
3751 Expect(lTrim.Err()).NotTo(HaveOccurred())
3752 Expect(lTrim.Val()).To(Equal("OK"))
3753
3754 lRange := client.LRange(ctx, "list", 0, -1)
3755 Expect(lRange.Err()).NotTo(HaveOccurred())
3756 Expect(lRange.Val()).To(Equal([]string{"two", "three"}))
3757 })
3758
3759 It("should RPop", func() {
3760 rPush := client.RPush(ctx, "list", "one")
3761 Expect(rPush.Err()).NotTo(HaveOccurred())
3762 rPush = client.RPush(ctx, "list", "two")
3763 Expect(rPush.Err()).NotTo(HaveOccurred())
3764 rPush = client.RPush(ctx, "list", "three")
3765 Expect(rPush.Err()).NotTo(HaveOccurred())
3766
3767 rPop := client.RPop(ctx, "list")
3768 Expect(rPop.Err()).NotTo(HaveOccurred())
3769 Expect(rPop.Val()).To(Equal("three"))
3770
3771 lRange := client.LRange(ctx, "list", 0, -1)
3772 Expect(lRange.Err()).NotTo(HaveOccurred())
3773 Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
3774 })
3775
3776 It("should RPopCount", func() {
3777 rPush := client.RPush(ctx, "list", "one", "two", "three", "four")
3778 Expect(rPush.Err()).NotTo(HaveOccurred())
3779 Expect(rPush.Val()).To(Equal(int64(4)))
3780
3781 rPopCount := client.RPopCount(ctx, "list", 2)
3782 Expect(rPopCount.Err()).NotTo(HaveOccurred())
3783 Expect(rPopCount.Val()).To(Equal([]string{"four", "three"}))
3784
3785 lRange := client.LRange(ctx, "list", 0, -1)
3786 Expect(lRange.Err()).NotTo(HaveOccurred())
3787 Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
3788 })
3789
3790 It("should RPopLPush", Label("NonRedisEnterprise"), func() {
3791 rPush := client.RPush(ctx, "list", "one")
3792 Expect(rPush.Err()).NotTo(HaveOccurred())
3793 rPush = client.RPush(ctx, "list", "two")
3794 Expect(rPush.Err()).NotTo(HaveOccurred())
3795 rPush = client.RPush(ctx, "list", "three")
3796 Expect(rPush.Err()).NotTo(HaveOccurred())
3797
3798 rPopLPush := client.RPopLPush(ctx, "list", "list2")
3799 Expect(rPopLPush.Err()).NotTo(HaveOccurred())
3800 Expect(rPopLPush.Val()).To(Equal("three"))
3801
3802 lRange := client.LRange(ctx, "list", 0, -1)
3803 Expect(lRange.Err()).NotTo(HaveOccurred())
3804 Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
3805
3806 lRange = client.LRange(ctx, "list2", 0, -1)
3807 Expect(lRange.Err()).NotTo(HaveOccurred())
3808 Expect(lRange.Val()).To(Equal([]string{"three"}))
3809 })
3810
3811 It("should RPush", func() {
3812 rPush := client.RPush(ctx, "list", "Hello")
3813 Expect(rPush.Err()).NotTo(HaveOccurred())
3814 Expect(rPush.Val()).To(Equal(int64(1)))
3815
3816 rPush = client.RPush(ctx, "list", "World")
3817 Expect(rPush.Err()).NotTo(HaveOccurred())
3818 Expect(rPush.Val()).To(Equal(int64(2)))
3819
3820 lRange := client.LRange(ctx, "list", 0, -1)
3821 Expect(lRange.Err()).NotTo(HaveOccurred())
3822 Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
3823 })
3824
3825 It("should RPushX", func() {
3826 rPush := client.RPush(ctx, "list", "Hello")
3827 Expect(rPush.Err()).NotTo(HaveOccurred())
3828 Expect(rPush.Val()).To(Equal(int64(1)))
3829
3830 rPushX := client.RPushX(ctx, "list", "World")
3831 Expect(rPushX.Err()).NotTo(HaveOccurred())
3832 Expect(rPushX.Val()).To(Equal(int64(2)))
3833
3834 rPush = client.RPush(ctx, "list1", "one")
3835 Expect(rPush.Err()).NotTo(HaveOccurred())
3836 Expect(rPush.Val()).To(Equal(int64(1)))
3837
3838 rPushX = client.RPushX(ctx, "list1", "two", "three")
3839 Expect(rPushX.Err()).NotTo(HaveOccurred())
3840 Expect(rPushX.Val()).To(Equal(int64(3)))
3841
3842 rPushX = client.RPushX(ctx, "list2", "World")
3843 Expect(rPushX.Err()).NotTo(HaveOccurred())
3844 Expect(rPushX.Val()).To(Equal(int64(0)))
3845
3846 lRange := client.LRange(ctx, "list", 0, -1)
3847 Expect(lRange.Err()).NotTo(HaveOccurred())
3848 Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
3849
3850 lRange = client.LRange(ctx, "list1", 0, -1)
3851 Expect(lRange.Err()).NotTo(HaveOccurred())
3852 Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
3853
3854 lRange = client.LRange(ctx, "list2", 0, -1)
3855 Expect(lRange.Err()).NotTo(HaveOccurred())
3856 Expect(lRange.Val()).To(Equal([]string{}))
3857 })
3858
3859 It("should LMove", Label("NonRedisEnterprise"), func() {
3860 rPush := client.RPush(ctx, "lmove1", "ichi")
3861 Expect(rPush.Err()).NotTo(HaveOccurred())
3862 Expect(rPush.Val()).To(Equal(int64(1)))
3863
3864 rPush = client.RPush(ctx, "lmove1", "ni")
3865 Expect(rPush.Err()).NotTo(HaveOccurred())
3866 Expect(rPush.Val()).To(Equal(int64(2)))
3867
3868 rPush = client.RPush(ctx, "lmove1", "san")
3869 Expect(rPush.Err()).NotTo(HaveOccurred())
3870 Expect(rPush.Val()).To(Equal(int64(3)))
3871
3872 lMove := client.LMove(ctx, "lmove1", "lmove2", "RIGHT", "LEFT")
3873 Expect(lMove.Err()).NotTo(HaveOccurred())
3874 Expect(lMove.Val()).To(Equal("san"))
3875
3876 lRange := client.LRange(ctx, "lmove2", 0, -1)
3877 Expect(lRange.Err()).NotTo(HaveOccurred())
3878 Expect(lRange.Val()).To(Equal([]string{"san"}))
3879 })
3880
3881 It("should BLMove", Label("NonRedisEnterprise"), func() {
3882 rPush := client.RPush(ctx, "blmove1", "ichi")
3883 Expect(rPush.Err()).NotTo(HaveOccurred())
3884 Expect(rPush.Val()).To(Equal(int64(1)))
3885
3886 rPush = client.RPush(ctx, "blmove1", "ni")
3887 Expect(rPush.Err()).NotTo(HaveOccurred())
3888 Expect(rPush.Val()).To(Equal(int64(2)))
3889
3890 rPush = client.RPush(ctx, "blmove1", "san")
3891 Expect(rPush.Err()).NotTo(HaveOccurred())
3892 Expect(rPush.Val()).To(Equal(int64(3)))
3893
3894 blMove := client.BLMove(ctx, "blmove1", "blmove2", "RIGHT", "LEFT", time.Second)
3895 Expect(blMove.Err()).NotTo(HaveOccurred())
3896 Expect(blMove.Val()).To(Equal("san"))
3897
3898 lRange := client.LRange(ctx, "blmove2", 0, -1)
3899 Expect(lRange.Err()).NotTo(HaveOccurred())
3900 Expect(lRange.Val()).To(Equal([]string{"san"}))
3901 })
3902 })
3903
3904 Describe("sets", func() {
3905 It("should SAdd", func() {
3906 sAdd := client.SAdd(ctx, "set", "Hello")
3907 Expect(sAdd.Err()).NotTo(HaveOccurred())
3908 Expect(sAdd.Val()).To(Equal(int64(1)))
3909
3910 sAdd = client.SAdd(ctx, "set", "World")
3911 Expect(sAdd.Err()).NotTo(HaveOccurred())
3912 Expect(sAdd.Val()).To(Equal(int64(1)))
3913
3914 sAdd = client.SAdd(ctx, "set", "World")
3915 Expect(sAdd.Err()).NotTo(HaveOccurred())
3916 Expect(sAdd.Val()).To(Equal(int64(0)))
3917
3918 sMembers := client.SMembers(ctx, "set")
3919 Expect(sMembers.Err()).NotTo(HaveOccurred())
3920 Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"}))
3921 })
3922
3923 It("should SAdd strings", func() {
3924 set := []string{"Hello", "World", "World"}
3925 sAdd := client.SAdd(ctx, "set", set)
3926 Expect(sAdd.Err()).NotTo(HaveOccurred())
3927 Expect(sAdd.Val()).To(Equal(int64(2)))
3928
3929 sMembers := client.SMembers(ctx, "set")
3930 Expect(sMembers.Err()).NotTo(HaveOccurred())
3931 Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"}))
3932 })
3933
3934 It("should SCard", func() {
3935 sAdd := client.SAdd(ctx, "set", "Hello")
3936 Expect(sAdd.Err()).NotTo(HaveOccurred())
3937 Expect(sAdd.Val()).To(Equal(int64(1)))
3938
3939 sAdd = client.SAdd(ctx, "set", "World")
3940 Expect(sAdd.Err()).NotTo(HaveOccurred())
3941 Expect(sAdd.Val()).To(Equal(int64(1)))
3942
3943 sCard := client.SCard(ctx, "set")
3944 Expect(sCard.Err()).NotTo(HaveOccurred())
3945 Expect(sCard.Val()).To(Equal(int64(2)))
3946 })
3947
3948 It("should SDiff", Label("NonRedisEnterprise"), func() {
3949 sAdd := client.SAdd(ctx, "set1", "a")
3950 Expect(sAdd.Err()).NotTo(HaveOccurred())
3951 sAdd = client.SAdd(ctx, "set1", "b")
3952 Expect(sAdd.Err()).NotTo(HaveOccurred())
3953 sAdd = client.SAdd(ctx, "set1", "c")
3954 Expect(sAdd.Err()).NotTo(HaveOccurred())
3955
3956 sAdd = client.SAdd(ctx, "set2", "c")
3957 Expect(sAdd.Err()).NotTo(HaveOccurred())
3958 sAdd = client.SAdd(ctx, "set2", "d")
3959 Expect(sAdd.Err()).NotTo(HaveOccurred())
3960 sAdd = client.SAdd(ctx, "set2", "e")
3961 Expect(sAdd.Err()).NotTo(HaveOccurred())
3962
3963 sDiff := client.SDiff(ctx, "set1", "set2")
3964 Expect(sDiff.Err()).NotTo(HaveOccurred())
3965 Expect(sDiff.Val()).To(ConsistOf([]string{"a", "b"}))
3966 })
3967
3968 It("should SDiffStore", Label("NonRedisEnterprise"), func() {
3969 sAdd := client.SAdd(ctx, "set1", "a")
3970 Expect(sAdd.Err()).NotTo(HaveOccurred())
3971 sAdd = client.SAdd(ctx, "set1", "b")
3972 Expect(sAdd.Err()).NotTo(HaveOccurred())
3973 sAdd = client.SAdd(ctx, "set1", "c")
3974 Expect(sAdd.Err()).NotTo(HaveOccurred())
3975
3976 sAdd = client.SAdd(ctx, "set2", "c")
3977 Expect(sAdd.Err()).NotTo(HaveOccurred())
3978 sAdd = client.SAdd(ctx, "set2", "d")
3979 Expect(sAdd.Err()).NotTo(HaveOccurred())
3980 sAdd = client.SAdd(ctx, "set2", "e")
3981 Expect(sAdd.Err()).NotTo(HaveOccurred())
3982
3983 sDiffStore := client.SDiffStore(ctx, "set", "set1", "set2")
3984 Expect(sDiffStore.Err()).NotTo(HaveOccurred())
3985 Expect(sDiffStore.Val()).To(Equal(int64(2)))
3986
3987 sMembers := client.SMembers(ctx, "set")
3988 Expect(sMembers.Err()).NotTo(HaveOccurred())
3989 Expect(sMembers.Val()).To(ConsistOf([]string{"a", "b"}))
3990 })
3991
3992 It("should SInter", Label("NonRedisEnterprise"), func() {
3993 sAdd := client.SAdd(ctx, "set1", "a")
3994 Expect(sAdd.Err()).NotTo(HaveOccurred())
3995 sAdd = client.SAdd(ctx, "set1", "b")
3996 Expect(sAdd.Err()).NotTo(HaveOccurred())
3997 sAdd = client.SAdd(ctx, "set1", "c")
3998 Expect(sAdd.Err()).NotTo(HaveOccurred())
3999
4000 sAdd = client.SAdd(ctx, "set2", "c")
4001 Expect(sAdd.Err()).NotTo(HaveOccurred())
4002 sAdd = client.SAdd(ctx, "set2", "d")
4003 Expect(sAdd.Err()).NotTo(HaveOccurred())
4004 sAdd = client.SAdd(ctx, "set2", "e")
4005 Expect(sAdd.Err()).NotTo(HaveOccurred())
4006
4007 sInter := client.SInter(ctx, "set1", "set2")
4008 Expect(sInter.Err()).NotTo(HaveOccurred())
4009 Expect(sInter.Val()).To(Equal([]string{"c"}))
4010 })
4011
4012 It("should SInterCard", Label("NonRedisEnterprise"), func() {
4013 sAdd := client.SAdd(ctx, "set1", "a")
4014 Expect(sAdd.Err()).NotTo(HaveOccurred())
4015 sAdd = client.SAdd(ctx, "set1", "b")
4016 Expect(sAdd.Err()).NotTo(HaveOccurred())
4017 sAdd = client.SAdd(ctx, "set1", "c")
4018 Expect(sAdd.Err()).NotTo(HaveOccurred())
4019
4020 sAdd = client.SAdd(ctx, "set2", "b")
4021 Expect(sAdd.Err()).NotTo(HaveOccurred())
4022 sAdd = client.SAdd(ctx, "set2", "c")
4023 Expect(sAdd.Err()).NotTo(HaveOccurred())
4024 sAdd = client.SAdd(ctx, "set2", "d")
4025 Expect(sAdd.Err()).NotTo(HaveOccurred())
4026 sAdd = client.SAdd(ctx, "set2", "e")
4027 Expect(sAdd.Err()).NotTo(HaveOccurred())
4028
4029 sInterCard := client.SInterCard(ctx, 0, "set1", "set2")
4030 Expect(sInterCard.Err()).NotTo(HaveOccurred())
4031 Expect(sInterCard.Val()).To(Equal(int64(2)))
4032
4033 sInterCard = client.SInterCard(ctx, 1, "set1", "set2")
4034 Expect(sInterCard.Err()).NotTo(HaveOccurred())
4035 Expect(sInterCard.Val()).To(Equal(int64(1)))
4036
4037 sInterCard = client.SInterCard(ctx, 3, "set1", "set2")
4038 Expect(sInterCard.Err()).NotTo(HaveOccurred())
4039 Expect(sInterCard.Val()).To(Equal(int64(2)))
4040 })
4041
4042 It("should SInterStore", Label("NonRedisEnterprise"), func() {
4043 sAdd := client.SAdd(ctx, "set1", "a")
4044 Expect(sAdd.Err()).NotTo(HaveOccurred())
4045 sAdd = client.SAdd(ctx, "set1", "b")
4046 Expect(sAdd.Err()).NotTo(HaveOccurred())
4047 sAdd = client.SAdd(ctx, "set1", "c")
4048 Expect(sAdd.Err()).NotTo(HaveOccurred())
4049
4050 sAdd = client.SAdd(ctx, "set2", "c")
4051 Expect(sAdd.Err()).NotTo(HaveOccurred())
4052 sAdd = client.SAdd(ctx, "set2", "d")
4053 Expect(sAdd.Err()).NotTo(HaveOccurred())
4054 sAdd = client.SAdd(ctx, "set2", "e")
4055 Expect(sAdd.Err()).NotTo(HaveOccurred())
4056
4057 sInterStore := client.SInterStore(ctx, "set", "set1", "set2")
4058 Expect(sInterStore.Err()).NotTo(HaveOccurred())
4059 Expect(sInterStore.Val()).To(Equal(int64(1)))
4060
4061 sMembers := client.SMembers(ctx, "set")
4062 Expect(sMembers.Err()).NotTo(HaveOccurred())
4063 Expect(sMembers.Val()).To(Equal([]string{"c"}))
4064 })
4065
4066 It("should IsMember", func() {
4067 sAdd := client.SAdd(ctx, "set", "one")
4068 Expect(sAdd.Err()).NotTo(HaveOccurred())
4069
4070 sIsMember := client.SIsMember(ctx, "set", "one")
4071 Expect(sIsMember.Err()).NotTo(HaveOccurred())
4072 Expect(sIsMember.Val()).To(Equal(true))
4073
4074 sIsMember = client.SIsMember(ctx, "set", "two")
4075 Expect(sIsMember.Err()).NotTo(HaveOccurred())
4076 Expect(sIsMember.Val()).To(Equal(false))
4077 })
4078
4079 It("should SMIsMember", func() {
4080 sAdd := client.SAdd(ctx, "set", "one")
4081 Expect(sAdd.Err()).NotTo(HaveOccurred())
4082
4083 sMIsMember := client.SMIsMember(ctx, "set", "one", "two")
4084 Expect(sMIsMember.Err()).NotTo(HaveOccurred())
4085 Expect(sMIsMember.Val()).To(Equal([]bool{true, false}))
4086 })
4087
4088 It("should SMembers", func() {
4089 sAdd := client.SAdd(ctx, "set", "Hello")
4090 Expect(sAdd.Err()).NotTo(HaveOccurred())
4091 sAdd = client.SAdd(ctx, "set", "World")
4092 Expect(sAdd.Err()).NotTo(HaveOccurred())
4093
4094 sMembers := client.SMembers(ctx, "set")
4095 Expect(sMembers.Err()).NotTo(HaveOccurred())
4096 Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"}))
4097 })
4098
4099 It("should SMembersMap", func() {
4100 sAdd := client.SAdd(ctx, "set", "Hello")
4101 Expect(sAdd.Err()).NotTo(HaveOccurred())
4102 sAdd = client.SAdd(ctx, "set", "World")
4103 Expect(sAdd.Err()).NotTo(HaveOccurred())
4104
4105 sMembersMap := client.SMembersMap(ctx, "set")
4106 Expect(sMembersMap.Err()).NotTo(HaveOccurred())
4107 Expect(sMembersMap.Val()).To(Equal(map[string]struct{}{"Hello": {}, "World": {}}))
4108 })
4109
4110 It("should SMove", Label("NonRedisEnterprise"), func() {
4111 sAdd := client.SAdd(ctx, "set1", "one")
4112 Expect(sAdd.Err()).NotTo(HaveOccurred())
4113 sAdd = client.SAdd(ctx, "set1", "two")
4114 Expect(sAdd.Err()).NotTo(HaveOccurred())
4115
4116 sAdd = client.SAdd(ctx, "set2", "three")
4117 Expect(sAdd.Err()).NotTo(HaveOccurred())
4118
4119 sMove := client.SMove(ctx, "set1", "set2", "two")
4120 Expect(sMove.Err()).NotTo(HaveOccurred())
4121 Expect(sMove.Val()).To(Equal(true))
4122
4123 sMembers := client.SMembers(ctx, "set1")
4124 Expect(sMembers.Err()).NotTo(HaveOccurred())
4125 Expect(sMembers.Val()).To(Equal([]string{"one"}))
4126
4127 sMembers = client.SMembers(ctx, "set2")
4128 Expect(sMembers.Err()).NotTo(HaveOccurred())
4129 Expect(sMembers.Val()).To(ConsistOf([]string{"three", "two"}))
4130 })
4131
4132 It("should SPop", func() {
4133 sAdd := client.SAdd(ctx, "set", "one")
4134 Expect(sAdd.Err()).NotTo(HaveOccurred())
4135 sAdd = client.SAdd(ctx, "set", "two")
4136 Expect(sAdd.Err()).NotTo(HaveOccurred())
4137 sAdd = client.SAdd(ctx, "set", "three")
4138 Expect(sAdd.Err()).NotTo(HaveOccurred())
4139
4140 sPop := client.SPop(ctx, "set")
4141 Expect(sPop.Err()).NotTo(HaveOccurred())
4142 Expect(sPop.Val()).NotTo(Equal(""))
4143
4144 sMembers := client.SMembers(ctx, "set")
4145 Expect(sMembers.Err()).NotTo(HaveOccurred())
4146 Expect(sMembers.Val()).To(HaveLen(2))
4147 })
4148
4149 It("should SPopN", func() {
4150 sAdd := client.SAdd(ctx, "set", "one")
4151 Expect(sAdd.Err()).NotTo(HaveOccurred())
4152 sAdd = client.SAdd(ctx, "set", "two")
4153 Expect(sAdd.Err()).NotTo(HaveOccurred())
4154 sAdd = client.SAdd(ctx, "set", "three")
4155 Expect(sAdd.Err()).NotTo(HaveOccurred())
4156 sAdd = client.SAdd(ctx, "set", "four")
4157 Expect(sAdd.Err()).NotTo(HaveOccurred())
4158
4159 sPopN := client.SPopN(ctx, "set", 1)
4160 Expect(sPopN.Err()).NotTo(HaveOccurred())
4161 Expect(sPopN.Val()).NotTo(Equal([]string{""}))
4162
4163 sMembers := client.SMembers(ctx, "set")
4164 Expect(sMembers.Err()).NotTo(HaveOccurred())
4165 Expect(sMembers.Val()).To(HaveLen(3))
4166
4167 sPopN = client.SPopN(ctx, "set", 4)
4168 Expect(sPopN.Err()).NotTo(HaveOccurred())
4169 Expect(sPopN.Val()).To(HaveLen(3))
4170
4171 sMembers = client.SMembers(ctx, "set")
4172 Expect(sMembers.Err()).NotTo(HaveOccurred())
4173 Expect(sMembers.Val()).To(HaveLen(0))
4174 })
4175
4176 It("should SRandMember and SRandMemberN", func() {
4177 err := client.SAdd(ctx, "set", "one").Err()
4178 Expect(err).NotTo(HaveOccurred())
4179 err = client.SAdd(ctx, "set", "two").Err()
4180 Expect(err).NotTo(HaveOccurred())
4181 err = client.SAdd(ctx, "set", "three").Err()
4182 Expect(err).NotTo(HaveOccurred())
4183
4184 members, err := client.SMembers(ctx, "set").Result()
4185 Expect(err).NotTo(HaveOccurred())
4186 Expect(members).To(HaveLen(3))
4187
4188 member, err := client.SRandMember(ctx, "set").Result()
4189 Expect(err).NotTo(HaveOccurred())
4190 Expect(member).NotTo(Equal(""))
4191
4192 members, err = client.SRandMemberN(ctx, "set", 2).Result()
4193 Expect(err).NotTo(HaveOccurred())
4194 Expect(members).To(HaveLen(2))
4195 })
4196
4197 It("should SRem", func() {
4198 sAdd := client.SAdd(ctx, "set", "one")
4199 Expect(sAdd.Err()).NotTo(HaveOccurred())
4200 sAdd = client.SAdd(ctx, "set", "two")
4201 Expect(sAdd.Err()).NotTo(HaveOccurred())
4202 sAdd = client.SAdd(ctx, "set", "three")
4203 Expect(sAdd.Err()).NotTo(HaveOccurred())
4204
4205 sRem := client.SRem(ctx, "set", "one")
4206 Expect(sRem.Err()).NotTo(HaveOccurred())
4207 Expect(sRem.Val()).To(Equal(int64(1)))
4208
4209 sRem = client.SRem(ctx, "set", "four")
4210 Expect(sRem.Err()).NotTo(HaveOccurred())
4211 Expect(sRem.Val()).To(Equal(int64(0)))
4212
4213 sMembers := client.SMembers(ctx, "set")
4214 Expect(sMembers.Err()).NotTo(HaveOccurred())
4215 Expect(sMembers.Val()).To(ConsistOf([]string{"three", "two"}))
4216 })
4217
4218 It("should SUnion", Label("NonRedisEnterprise"), func() {
4219 sAdd := client.SAdd(ctx, "set1", "a")
4220 Expect(sAdd.Err()).NotTo(HaveOccurred())
4221 sAdd = client.SAdd(ctx, "set1", "b")
4222 Expect(sAdd.Err()).NotTo(HaveOccurred())
4223 sAdd = client.SAdd(ctx, "set1", "c")
4224 Expect(sAdd.Err()).NotTo(HaveOccurred())
4225
4226 sAdd = client.SAdd(ctx, "set2", "c")
4227 Expect(sAdd.Err()).NotTo(HaveOccurred())
4228 sAdd = client.SAdd(ctx, "set2", "d")
4229 Expect(sAdd.Err()).NotTo(HaveOccurred())
4230 sAdd = client.SAdd(ctx, "set2", "e")
4231 Expect(sAdd.Err()).NotTo(HaveOccurred())
4232
4233 sUnion := client.SUnion(ctx, "set1", "set2")
4234 Expect(sUnion.Err()).NotTo(HaveOccurred())
4235 Expect(sUnion.Val()).To(HaveLen(5))
4236 })
4237
4238 It("should SUnionStore", Label("NonRedisEnterprise"), func() {
4239 sAdd := client.SAdd(ctx, "set1", "a")
4240 Expect(sAdd.Err()).NotTo(HaveOccurred())
4241 sAdd = client.SAdd(ctx, "set1", "b")
4242 Expect(sAdd.Err()).NotTo(HaveOccurred())
4243 sAdd = client.SAdd(ctx, "set1", "c")
4244 Expect(sAdd.Err()).NotTo(HaveOccurred())
4245
4246 sAdd = client.SAdd(ctx, "set2", "c")
4247 Expect(sAdd.Err()).NotTo(HaveOccurred())
4248 sAdd = client.SAdd(ctx, "set2", "d")
4249 Expect(sAdd.Err()).NotTo(HaveOccurred())
4250 sAdd = client.SAdd(ctx, "set2", "e")
4251 Expect(sAdd.Err()).NotTo(HaveOccurred())
4252
4253 sUnionStore := client.SUnionStore(ctx, "set", "set1", "set2")
4254 Expect(sUnionStore.Err()).NotTo(HaveOccurred())
4255 Expect(sUnionStore.Val()).To(Equal(int64(5)))
4256
4257 sMembers := client.SMembers(ctx, "set")
4258 Expect(sMembers.Err()).NotTo(HaveOccurred())
4259 Expect(sMembers.Val()).To(HaveLen(5))
4260 })
4261 })
4262
4263 Describe("sorted sets", func() {
4264 It("should BZPopMax", Label("NonRedisEnterprise"), func() {
4265 err := client.ZAdd(ctx, "zset1", redis.Z{
4266 Score: 1,
4267 Member: "one",
4268 }).Err()
4269 Expect(err).NotTo(HaveOccurred())
4270 err = client.ZAdd(ctx, "zset1", redis.Z{
4271 Score: 2,
4272 Member: "two",
4273 }).Err()
4274 Expect(err).NotTo(HaveOccurred())
4275 err = client.ZAdd(ctx, "zset1", redis.Z{
4276 Score: 3,
4277 Member: "three",
4278 }).Err()
4279 Expect(err).NotTo(HaveOccurred())
4280
4281 member, err := client.BZPopMax(ctx, 0, "zset1", "zset2").Result()
4282 Expect(err).NotTo(HaveOccurred())
4283 Expect(member).To(Equal(&redis.ZWithKey{
4284 Z: redis.Z{
4285 Score: 3,
4286 Member: "three",
4287 },
4288 Key: "zset1",
4289 }))
4290 })
4291
4292 It("should BZPopMax blocks", func() {
4293 started := make(chan bool)
4294 done := make(chan bool)
4295 go func() {
4296 defer GinkgoRecover()
4297
4298 started <- true
4299 bZPopMax := client.BZPopMax(ctx, 0, "zset")
4300 Expect(bZPopMax.Err()).NotTo(HaveOccurred())
4301 Expect(bZPopMax.Val()).To(Equal(&redis.ZWithKey{
4302 Z: redis.Z{
4303 Member: "a",
4304 Score: 1,
4305 },
4306 Key: "zset",
4307 }))
4308 done <- true
4309 }()
4310 <-started
4311
4312 select {
4313 case <-done:
4314 Fail("BZPopMax is not blocked")
4315 case <-time.After(time.Second):
4316
4317 }
4318
4319 zAdd := client.ZAdd(ctx, "zset", redis.Z{
4320 Member: "a",
4321 Score: 1,
4322 })
4323 Expect(zAdd.Err()).NotTo(HaveOccurred())
4324
4325 select {
4326 case <-done:
4327
4328 case <-time.After(time.Second):
4329 Fail("BZPopMax is still blocked")
4330 }
4331 })
4332
4333 It("should BZPopMax timeout", func() {
4334 val, err := client.BZPopMax(ctx, time.Second, "zset1").Result()
4335 Expect(err).To(Equal(redis.Nil))
4336 Expect(val).To(BeNil())
4337
4338 Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
4339
4340 stats := client.PoolStats()
4341 Expect(stats.Hits).To(Equal(uint32(2)))
4342 Expect(stats.Misses).To(Equal(uint32(1)))
4343 Expect(stats.Timeouts).To(Equal(uint32(0)))
4344 })
4345
4346 It("should BZPopMin", Label("NonRedisEnterprise"), func() {
4347 err := client.ZAdd(ctx, "zset1", redis.Z{
4348 Score: 1,
4349 Member: "one",
4350 }).Err()
4351 Expect(err).NotTo(HaveOccurred())
4352 err = client.ZAdd(ctx, "zset1", redis.Z{
4353 Score: 2,
4354 Member: "two",
4355 }).Err()
4356 Expect(err).NotTo(HaveOccurred())
4357 err = client.ZAdd(ctx, "zset1", redis.Z{
4358 Score: 3,
4359 Member: "three",
4360 }).Err()
4361 Expect(err).NotTo(HaveOccurred())
4362
4363 member, err := client.BZPopMin(ctx, 0, "zset1", "zset2").Result()
4364 Expect(err).NotTo(HaveOccurred())
4365 Expect(member).To(Equal(&redis.ZWithKey{
4366 Z: redis.Z{
4367 Score: 1,
4368 Member: "one",
4369 },
4370 Key: "zset1",
4371 }))
4372 })
4373
4374 It("should BZPopMin blocks", func() {
4375 started := make(chan bool)
4376 done := make(chan bool)
4377 go func() {
4378 defer GinkgoRecover()
4379
4380 started <- true
4381 bZPopMin := client.BZPopMin(ctx, 0, "zset")
4382 Expect(bZPopMin.Err()).NotTo(HaveOccurred())
4383 Expect(bZPopMin.Val()).To(Equal(&redis.ZWithKey{
4384 Z: redis.Z{
4385 Member: "a",
4386 Score: 1,
4387 },
4388 Key: "zset",
4389 }))
4390 done <- true
4391 }()
4392 <-started
4393
4394 select {
4395 case <-done:
4396 Fail("BZPopMin is not blocked")
4397 case <-time.After(time.Second):
4398
4399 }
4400
4401 zAdd := client.ZAdd(ctx, "zset", redis.Z{
4402 Member: "a",
4403 Score: 1,
4404 })
4405 Expect(zAdd.Err()).NotTo(HaveOccurred())
4406
4407 select {
4408 case <-done:
4409
4410 case <-time.After(time.Second):
4411 Fail("BZPopMin is still blocked")
4412 }
4413 })
4414
4415 It("should BZPopMin timeout", func() {
4416 val, err := client.BZPopMin(ctx, time.Second, "zset1").Result()
4417 Expect(err).To(Equal(redis.Nil))
4418 Expect(val).To(BeNil())
4419
4420 Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
4421
4422 stats := client.PoolStats()
4423 Expect(stats.Hits).To(Equal(uint32(2)))
4424 Expect(stats.Misses).To(Equal(uint32(1)))
4425 Expect(stats.Timeouts).To(Equal(uint32(0)))
4426 })
4427
4428 It("should ZAdd", func() {
4429 added, err := client.ZAdd(ctx, "zset", redis.Z{
4430 Score: 1,
4431 Member: "one",
4432 }).Result()
4433 Expect(err).NotTo(HaveOccurred())
4434 Expect(added).To(Equal(int64(1)))
4435
4436 added, err = client.ZAdd(ctx, "zset", redis.Z{
4437 Score: 1,
4438 Member: "uno",
4439 }).Result()
4440 Expect(err).NotTo(HaveOccurred())
4441 Expect(added).To(Equal(int64(1)))
4442
4443 added, err = client.ZAdd(ctx, "zset", redis.Z{
4444 Score: 2,
4445 Member: "two",
4446 }).Result()
4447 Expect(err).NotTo(HaveOccurred())
4448 Expect(added).To(Equal(int64(1)))
4449
4450 added, err = client.ZAdd(ctx, "zset", redis.Z{
4451 Score: 3,
4452 Member: "two",
4453 }).Result()
4454 Expect(err).NotTo(HaveOccurred())
4455 Expect(added).To(Equal(int64(0)))
4456
4457 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4458 Expect(err).NotTo(HaveOccurred())
4459 Expect(vals).To(Equal([]redis.Z{{
4460 Score: 1,
4461 Member: "one",
4462 }, {
4463 Score: 1,
4464 Member: "uno",
4465 }, {
4466 Score: 3,
4467 Member: "two",
4468 }}))
4469 })
4470
4471 It("should ZAdd bytes", func() {
4472 added, err := client.ZAdd(ctx, "zset", redis.Z{
4473 Score: 1,
4474 Member: []byte("one"),
4475 }).Result()
4476 Expect(err).NotTo(HaveOccurred())
4477 Expect(added).To(Equal(int64(1)))
4478
4479 added, err = client.ZAdd(ctx, "zset", redis.Z{
4480 Score: 1,
4481 Member: []byte("uno"),
4482 }).Result()
4483 Expect(err).NotTo(HaveOccurred())
4484 Expect(added).To(Equal(int64(1)))
4485
4486 added, err = client.ZAdd(ctx, "zset", redis.Z{
4487 Score: 2,
4488 Member: []byte("two"),
4489 }).Result()
4490 Expect(err).NotTo(HaveOccurred())
4491 Expect(added).To(Equal(int64(1)))
4492
4493 added, err = client.ZAdd(ctx, "zset", redis.Z{
4494 Score: 3,
4495 Member: []byte("two"),
4496 }).Result()
4497 Expect(err).NotTo(HaveOccurred())
4498 Expect(added).To(Equal(int64(0)))
4499
4500 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4501 Expect(err).NotTo(HaveOccurred())
4502 Expect(vals).To(Equal([]redis.Z{{
4503 Score: 1,
4504 Member: "one",
4505 }, {
4506 Score: 1,
4507 Member: "uno",
4508 }, {
4509 Score: 3,
4510 Member: "two",
4511 }}))
4512 })
4513
4514 It("should ZAddArgsGTAndLT", func() {
4515
4516 added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4517 GT: true,
4518 Members: []redis.Z{{Score: 1, Member: "one"}},
4519 }).Result()
4520 Expect(err).NotTo(HaveOccurred())
4521 Expect(added).To(Equal(int64(1)))
4522
4523 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4524 Expect(err).NotTo(HaveOccurred())
4525 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4526
4527 added, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4528 GT: true,
4529 Members: []redis.Z{{Score: 2, Member: "one"}},
4530 }).Result()
4531 Expect(err).NotTo(HaveOccurred())
4532 Expect(added).To(Equal(int64(0)))
4533
4534 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4535 Expect(err).NotTo(HaveOccurred())
4536 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4537
4538 added, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4539 LT: true,
4540 Members: []redis.Z{{Score: 1, Member: "one"}},
4541 }).Result()
4542 Expect(err).NotTo(HaveOccurred())
4543 Expect(added).To(Equal(int64(0)))
4544
4545 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4546 Expect(err).NotTo(HaveOccurred())
4547 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4548 })
4549
4550 It("should ZAddArgsLT", func() {
4551 added, err := client.ZAddLT(ctx, "zset", redis.Z{
4552 Score: 2,
4553 Member: "one",
4554 }).Result()
4555 Expect(err).NotTo(HaveOccurred())
4556 Expect(added).To(Equal(int64(1)))
4557
4558 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4559 Expect(err).NotTo(HaveOccurred())
4560 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4561
4562 added, err = client.ZAddLT(ctx, "zset", redis.Z{
4563 Score: 3,
4564 Member: "one",
4565 }).Result()
4566 Expect(err).NotTo(HaveOccurred())
4567 Expect(added).To(Equal(int64(0)))
4568
4569 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4570 Expect(err).NotTo(HaveOccurred())
4571 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4572
4573 added, err = client.ZAddLT(ctx, "zset", redis.Z{
4574 Score: 1,
4575 Member: "one",
4576 }).Result()
4577 Expect(err).NotTo(HaveOccurred())
4578 Expect(added).To(Equal(int64(0)))
4579
4580 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4581 Expect(err).NotTo(HaveOccurred())
4582 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4583 })
4584
4585 It("should ZAddArgsGT", func() {
4586 added, err := client.ZAddGT(ctx, "zset", redis.Z{
4587 Score: 2,
4588 Member: "one",
4589 }).Result()
4590 Expect(err).NotTo(HaveOccurred())
4591 Expect(added).To(Equal(int64(1)))
4592
4593 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4594 Expect(err).NotTo(HaveOccurred())
4595 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4596
4597 added, err = client.ZAddGT(ctx, "zset", redis.Z{
4598 Score: 3,
4599 Member: "one",
4600 }).Result()
4601 Expect(err).NotTo(HaveOccurred())
4602 Expect(added).To(Equal(int64(0)))
4603
4604 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4605 Expect(err).NotTo(HaveOccurred())
4606 Expect(vals).To(Equal([]redis.Z{{Score: 3, Member: "one"}}))
4607
4608 added, err = client.ZAddGT(ctx, "zset", redis.Z{
4609 Score: 1,
4610 Member: "one",
4611 }).Result()
4612 Expect(err).NotTo(HaveOccurred())
4613 Expect(added).To(Equal(int64(0)))
4614
4615 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4616 Expect(err).NotTo(HaveOccurred())
4617 Expect(vals).To(Equal([]redis.Z{{Score: 3, Member: "one"}}))
4618 })
4619
4620 It("should ZAddArgsNX", func() {
4621 added, err := client.ZAddNX(ctx, "zset", redis.Z{
4622 Score: 1,
4623 Member: "one",
4624 }).Result()
4625 Expect(err).NotTo(HaveOccurred())
4626 Expect(added).To(Equal(int64(1)))
4627
4628 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4629 Expect(err).NotTo(HaveOccurred())
4630 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4631
4632 added, err = client.ZAddNX(ctx, "zset", redis.Z{
4633 Score: 2,
4634 Member: "one",
4635 }).Result()
4636 Expect(err).NotTo(HaveOccurred())
4637 Expect(added).To(Equal(int64(0)))
4638
4639 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4640 Expect(err).NotTo(HaveOccurred())
4641 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4642 })
4643
4644 It("should ZAddArgsXX", func() {
4645 added, err := client.ZAddXX(ctx, "zset", redis.Z{
4646 Score: 1,
4647 Member: "one",
4648 }).Result()
4649 Expect(err).NotTo(HaveOccurred())
4650 Expect(added).To(Equal(int64(0)))
4651
4652 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4653 Expect(err).NotTo(HaveOccurred())
4654 Expect(vals).To(BeEmpty())
4655
4656 added, err = client.ZAdd(ctx, "zset", redis.Z{
4657 Score: 1,
4658 Member: "one",
4659 }).Result()
4660 Expect(err).NotTo(HaveOccurred())
4661 Expect(added).To(Equal(int64(1)))
4662
4663 added, err = client.ZAddXX(ctx, "zset", redis.Z{
4664 Score: 2,
4665 Member: "one",
4666 }).Result()
4667 Expect(err).NotTo(HaveOccurred())
4668 Expect(added).To(Equal(int64(0)))
4669
4670 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4671 Expect(err).NotTo(HaveOccurred())
4672 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4673 })
4674
4675 It("should ZAddArgsCh", func() {
4676 changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4677 Ch: true,
4678 Members: []redis.Z{
4679 {Score: 1, Member: "one"},
4680 },
4681 }).Result()
4682 Expect(err).NotTo(HaveOccurred())
4683 Expect(changed).To(Equal(int64(1)))
4684
4685 changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4686 Ch: true,
4687 Members: []redis.Z{
4688 {Score: 1, Member: "one"},
4689 },
4690 }).Result()
4691 Expect(err).NotTo(HaveOccurred())
4692 Expect(changed).To(Equal(int64(0)))
4693 })
4694
4695 It("should ZAddArgsNXCh", func() {
4696 changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4697 NX: true,
4698 Ch: true,
4699 Members: []redis.Z{
4700 {Score: 1, Member: "one"},
4701 },
4702 }).Result()
4703 Expect(err).NotTo(HaveOccurred())
4704 Expect(changed).To(Equal(int64(1)))
4705
4706 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4707 Expect(err).NotTo(HaveOccurred())
4708 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4709
4710 changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4711 NX: true,
4712 Ch: true,
4713 Members: []redis.Z{
4714 {Score: 2, Member: "one"},
4715 },
4716 }).Result()
4717 Expect(err).NotTo(HaveOccurred())
4718 Expect(changed).To(Equal(int64(0)))
4719
4720 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4721 Expect(err).NotTo(HaveOccurred())
4722 Expect(vals).To(Equal([]redis.Z{{
4723 Score: 1,
4724 Member: "one",
4725 }}))
4726 })
4727
4728 It("should ZAddArgsXXCh", func() {
4729 changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4730 XX: true,
4731 Ch: true,
4732 Members: []redis.Z{
4733 {Score: 1, Member: "one"},
4734 },
4735 }).Result()
4736 Expect(err).NotTo(HaveOccurred())
4737 Expect(changed).To(Equal(int64(0)))
4738
4739 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4740 Expect(err).NotTo(HaveOccurred())
4741 Expect(vals).To(BeEmpty())
4742
4743 added, err := client.ZAdd(ctx, "zset", redis.Z{
4744 Score: 1,
4745 Member: "one",
4746 }).Result()
4747 Expect(err).NotTo(HaveOccurred())
4748 Expect(added).To(Equal(int64(1)))
4749
4750 changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
4751 XX: true,
4752 Ch: true,
4753 Members: []redis.Z{
4754 {Score: 2, Member: "one"},
4755 },
4756 }).Result()
4757 Expect(err).NotTo(HaveOccurred())
4758 Expect(changed).To(Equal(int64(1)))
4759
4760 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4761 Expect(err).NotTo(HaveOccurred())
4762 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4763 })
4764
4765 It("should ZAddArgsIncr", func() {
4766 score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
4767 Members: []redis.Z{
4768 {Score: 1, Member: "one"},
4769 },
4770 }).Result()
4771 Expect(err).NotTo(HaveOccurred())
4772 Expect(score).To(Equal(float64(1)))
4773
4774 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4775 Expect(err).NotTo(HaveOccurred())
4776 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4777
4778 score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
4779 Members: []redis.Z{
4780 {Score: 1, Member: "one"},
4781 },
4782 }).Result()
4783 Expect(err).NotTo(HaveOccurred())
4784 Expect(score).To(Equal(float64(2)))
4785
4786 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4787 Expect(err).NotTo(HaveOccurred())
4788 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4789 })
4790
4791 It("should ZAddArgsIncrNX", func() {
4792 score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
4793 NX: true,
4794 Members: []redis.Z{
4795 {Score: 1, Member: "one"},
4796 },
4797 }).Result()
4798 Expect(err).NotTo(HaveOccurred())
4799 Expect(score).To(Equal(float64(1)))
4800
4801 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4802 Expect(err).NotTo(HaveOccurred())
4803 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4804
4805 score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
4806 NX: true,
4807 Members: []redis.Z{
4808 {Score: 1, Member: "one"},
4809 },
4810 }).Result()
4811 Expect(err).To(Equal(redis.Nil))
4812 Expect(score).To(Equal(float64(0)))
4813
4814 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4815 Expect(err).NotTo(HaveOccurred())
4816 Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
4817 })
4818
4819 It("should ZAddArgsIncrXX", func() {
4820 score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
4821 XX: true,
4822 Members: []redis.Z{
4823 {Score: 1, Member: "one"},
4824 },
4825 }).Result()
4826 Expect(err).To(Equal(redis.Nil))
4827 Expect(score).To(Equal(float64(0)))
4828
4829 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4830 Expect(err).NotTo(HaveOccurred())
4831 Expect(vals).To(BeEmpty())
4832
4833 added, err := client.ZAdd(ctx, "zset", redis.Z{
4834 Score: 1,
4835 Member: "one",
4836 }).Result()
4837 Expect(err).NotTo(HaveOccurred())
4838 Expect(added).To(Equal(int64(1)))
4839
4840 score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
4841 XX: true,
4842 Members: []redis.Z{
4843 {Score: 1, Member: "one"},
4844 },
4845 }).Result()
4846 Expect(err).NotTo(HaveOccurred())
4847 Expect(score).To(Equal(float64(2)))
4848
4849 vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4850 Expect(err).NotTo(HaveOccurred())
4851 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
4852 })
4853
4854 It("should ZCard", func() {
4855 err := client.ZAdd(ctx, "zset", redis.Z{
4856 Score: 1,
4857 Member: "one",
4858 }).Err()
4859 Expect(err).NotTo(HaveOccurred())
4860 err = client.ZAdd(ctx, "zset", redis.Z{
4861 Score: 2,
4862 Member: "two",
4863 }).Err()
4864 Expect(err).NotTo(HaveOccurred())
4865
4866 card, err := client.ZCard(ctx, "zset").Result()
4867 Expect(err).NotTo(HaveOccurred())
4868 Expect(card).To(Equal(int64(2)))
4869 })
4870
4871 It("should ZCount", func() {
4872 err := client.ZAdd(ctx, "zset", redis.Z{
4873 Score: 1,
4874 Member: "one",
4875 }).Err()
4876 Expect(err).NotTo(HaveOccurred())
4877 err = client.ZAdd(ctx, "zset", redis.Z{
4878 Score: 2,
4879 Member: "two",
4880 }).Err()
4881 Expect(err).NotTo(HaveOccurred())
4882 err = client.ZAdd(ctx, "zset", redis.Z{
4883 Score: 3,
4884 Member: "three",
4885 }).Err()
4886 Expect(err).NotTo(HaveOccurred())
4887
4888 count, err := client.ZCount(ctx, "zset", "-inf", "+inf").Result()
4889 Expect(err).NotTo(HaveOccurred())
4890 Expect(count).To(Equal(int64(3)))
4891
4892 count, err = client.ZCount(ctx, "zset", "(1", "3").Result()
4893 Expect(err).NotTo(HaveOccurred())
4894 Expect(count).To(Equal(int64(2)))
4895
4896 count, err = client.ZLexCount(ctx, "zset", "-", "+").Result()
4897 Expect(err).NotTo(HaveOccurred())
4898 Expect(count).To(Equal(int64(3)))
4899 })
4900
4901 It("should ZIncrBy", func() {
4902 err := client.ZAdd(ctx, "zset", redis.Z{
4903 Score: 1,
4904 Member: "one",
4905 }).Err()
4906 Expect(err).NotTo(HaveOccurred())
4907 err = client.ZAdd(ctx, "zset", redis.Z{
4908 Score: 2,
4909 Member: "two",
4910 }).Err()
4911 Expect(err).NotTo(HaveOccurred())
4912
4913 n, err := client.ZIncrBy(ctx, "zset", 2, "one").Result()
4914 Expect(err).NotTo(HaveOccurred())
4915 Expect(n).To(Equal(float64(3)))
4916
4917 val, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
4918 Expect(err).NotTo(HaveOccurred())
4919 Expect(val).To(Equal([]redis.Z{{
4920 Score: 2,
4921 Member: "two",
4922 }, {
4923 Score: 3,
4924 Member: "one",
4925 }}))
4926 })
4927
4928 It("should ZInterStore", Label("NonRedisEnterprise"), func() {
4929 err := client.ZAdd(ctx, "zset1", redis.Z{
4930 Score: 1,
4931 Member: "one",
4932 }).Err()
4933 Expect(err).NotTo(HaveOccurred())
4934 err = client.ZAdd(ctx, "zset1", redis.Z{
4935 Score: 2,
4936 Member: "two",
4937 }).Err()
4938 Expect(err).NotTo(HaveOccurred())
4939
4940 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
4941 Expect(err).NotTo(HaveOccurred())
4942 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
4943 Expect(err).NotTo(HaveOccurred())
4944 err = client.ZAdd(ctx, "zset3", redis.Z{Score: 3, Member: "two"}).Err()
4945 Expect(err).NotTo(HaveOccurred())
4946
4947 n, err := client.ZInterStore(ctx, "out", &redis.ZStore{
4948 Keys: []string{"zset1", "zset2"},
4949 Weights: []float64{2, 3},
4950 }).Result()
4951 Expect(err).NotTo(HaveOccurred())
4952 Expect(n).To(Equal(int64(2)))
4953
4954 vals, err := client.ZRangeWithScores(ctx, "out", 0, -1).Result()
4955 Expect(err).NotTo(HaveOccurred())
4956 Expect(vals).To(Equal([]redis.Z{{
4957 Score: 5,
4958 Member: "one",
4959 }, {
4960 Score: 10,
4961 Member: "two",
4962 }}))
4963 })
4964
4965 It("should ZMPop", Label("NonRedisEnterprise"), func() {
4966 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
4967 Expect(err).NotTo(HaveOccurred())
4968 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
4969 Expect(err).NotTo(HaveOccurred())
4970 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
4971 Expect(err).NotTo(HaveOccurred())
4972
4973 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
4974 Expect(err).NotTo(HaveOccurred())
4975 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
4976 Expect(err).NotTo(HaveOccurred())
4977 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
4978 Expect(err).NotTo(HaveOccurred())
4979
4980 key, elems, err := client.ZMPop(ctx, "min", 1, "zset").Result()
4981 Expect(err).NotTo(HaveOccurred())
4982 Expect(key).To(Equal("zset"))
4983 Expect(elems).To(Equal([]redis.Z{{
4984 Score: 1,
4985 Member: "one",
4986 }}))
4987
4988 _, _, err = client.ZMPop(ctx, "min", 1, "nosuchkey").Result()
4989 Expect(err).To(Equal(redis.Nil))
4990
4991 err = client.ZAdd(ctx, "myzset", redis.Z{Score: 1, Member: "one"}).Err()
4992 Expect(err).NotTo(HaveOccurred())
4993 err = client.ZAdd(ctx, "myzset", redis.Z{Score: 2, Member: "two"}).Err()
4994 Expect(err).NotTo(HaveOccurred())
4995 err = client.ZAdd(ctx, "myzset", redis.Z{Score: 3, Member: "three"}).Err()
4996 Expect(err).NotTo(HaveOccurred())
4997
4998 key, elems, err = client.ZMPop(ctx, "min", 1, "myzset").Result()
4999 Expect(err).NotTo(HaveOccurred())
5000 Expect(key).To(Equal("myzset"))
5001 Expect(elems).To(Equal([]redis.Z{{
5002 Score: 1,
5003 Member: "one",
5004 }}))
5005
5006 key, elems, err = client.ZMPop(ctx, "max", 10, "myzset").Result()
5007 Expect(err).NotTo(HaveOccurred())
5008 Expect(key).To(Equal("myzset"))
5009 Expect(elems).To(Equal([]redis.Z{{
5010 Score: 3,
5011 Member: "three",
5012 }, {
5013 Score: 2,
5014 Member: "two",
5015 }}))
5016
5017 err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 4, Member: "four"}).Err()
5018 Expect(err).NotTo(HaveOccurred())
5019 err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 5, Member: "five"}).Err()
5020 Expect(err).NotTo(HaveOccurred())
5021 err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 6, Member: "six"}).Err()
5022 Expect(err).NotTo(HaveOccurred())
5023
5024 key, elems, err = client.ZMPop(ctx, "min", 10, "myzset", "myzset2").Result()
5025 Expect(err).NotTo(HaveOccurred())
5026 Expect(key).To(Equal("myzset2"))
5027 Expect(elems).To(Equal([]redis.Z{{
5028 Score: 4,
5029 Member: "four",
5030 }, {
5031 Score: 5,
5032 Member: "five",
5033 }, {
5034 Score: 6,
5035 Member: "six",
5036 }}))
5037 })
5038
5039 It("should BZMPop", Label("NonRedisEnterprise"), func() {
5040 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5041 Expect(err).NotTo(HaveOccurred())
5042 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5043 Expect(err).NotTo(HaveOccurred())
5044 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5045 Expect(err).NotTo(HaveOccurred())
5046
5047 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
5048 Expect(err).NotTo(HaveOccurred())
5049 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
5050 Expect(err).NotTo(HaveOccurred())
5051 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
5052 Expect(err).NotTo(HaveOccurred())
5053
5054 key, elems, err := client.BZMPop(ctx, 0, "min", 1, "zset").Result()
5055 Expect(err).NotTo(HaveOccurred())
5056 Expect(key).To(Equal("zset"))
5057 Expect(elems).To(Equal([]redis.Z{{
5058 Score: 1,
5059 Member: "one",
5060 }}))
5061 key, elems, err = client.BZMPop(ctx, 0, "max", 1, "zset").Result()
5062 Expect(err).NotTo(HaveOccurred())
5063 Expect(key).To(Equal("zset"))
5064 Expect(elems).To(Equal([]redis.Z{{
5065 Score: 3,
5066 Member: "three",
5067 }}))
5068 key, elems, err = client.BZMPop(ctx, 0, "min", 10, "zset").Result()
5069 Expect(err).NotTo(HaveOccurred())
5070 Expect(key).To(Equal("zset"))
5071 Expect(elems).To(Equal([]redis.Z{{
5072 Score: 2,
5073 Member: "two",
5074 }}))
5075
5076 key, elems, err = client.BZMPop(ctx, 0, "max", 10, "zset2").Result()
5077 Expect(err).NotTo(HaveOccurred())
5078 Expect(key).To(Equal("zset2"))
5079 Expect(elems).To(Equal([]redis.Z{{
5080 Score: 3,
5081 Member: "three",
5082 }, {
5083 Score: 2,
5084 Member: "two",
5085 }, {
5086 Score: 1,
5087 Member: "one",
5088 }}))
5089
5090 err = client.ZAdd(ctx, "myzset", redis.Z{Score: 1, Member: "one"}).Err()
5091 Expect(err).NotTo(HaveOccurred())
5092 key, elems, err = client.BZMPop(ctx, 0, "min", 10, "myzset").Result()
5093 Expect(err).NotTo(HaveOccurred())
5094 Expect(key).To(Equal("myzset"))
5095 Expect(elems).To(Equal([]redis.Z{{
5096 Score: 1,
5097 Member: "one",
5098 }}))
5099
5100 err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 4, Member: "four"}).Err()
5101 Expect(err).NotTo(HaveOccurred())
5102 err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 5, Member: "five"}).Err()
5103 Expect(err).NotTo(HaveOccurred())
5104
5105 key, elems, err = client.BZMPop(ctx, 0, "min", 10, "myzset", "myzset2").Result()
5106 Expect(err).NotTo(HaveOccurred())
5107 Expect(key).To(Equal("myzset2"))
5108 Expect(elems).To(Equal([]redis.Z{{
5109 Score: 4,
5110 Member: "four",
5111 }, {
5112 Score: 5,
5113 Member: "five",
5114 }}))
5115 })
5116
5117 It("should BZMPopBlocks", func() {
5118 started := make(chan bool)
5119 done := make(chan bool)
5120 go func() {
5121 defer GinkgoRecover()
5122
5123 started <- true
5124 key, elems, err := client.BZMPop(ctx, 0, "min", 1, "list_list").Result()
5125 Expect(err).NotTo(HaveOccurred())
5126 Expect(key).To(Equal("list_list"))
5127 Expect(elems).To(Equal([]redis.Z{{
5128 Score: 1,
5129 Member: "one",
5130 }}))
5131 done <- true
5132 }()
5133 <-started
5134
5135 select {
5136 case <-done:
5137 Fail("BZMPop is not blocked")
5138 case <-time.After(time.Second):
5139
5140 }
5141
5142 err := client.ZAdd(ctx, "list_list", redis.Z{Score: 1, Member: "one"}).Err()
5143 Expect(err).NotTo(HaveOccurred())
5144
5145 select {
5146 case <-done:
5147
5148 case <-time.After(time.Second):
5149 Fail("BZMPop is still blocked")
5150 }
5151 })
5152
5153 It("should BZMPop timeout", func() {
5154 _, val, err := client.BZMPop(ctx, time.Second, "min", 1, "list1").Result()
5155 Expect(err).To(Equal(redis.Nil))
5156 Expect(val).To(BeNil())
5157
5158 Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
5159
5160 stats := client.PoolStats()
5161 Expect(stats.Hits).To(Equal(uint32(2)))
5162 Expect(stats.Misses).To(Equal(uint32(1)))
5163 Expect(stats.Timeouts).To(Equal(uint32(0)))
5164 })
5165
5166 It("should ZMScore", func() {
5167 zmScore := client.ZMScore(ctx, "zset", "one", "three")
5168 Expect(zmScore.Err()).NotTo(HaveOccurred())
5169 Expect(zmScore.Val()).To(HaveLen(2))
5170 Expect(zmScore.Val()[0]).To(Equal(float64(0)))
5171
5172 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5173 Expect(err).NotTo(HaveOccurred())
5174 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5175 Expect(err).NotTo(HaveOccurred())
5176 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5177 Expect(err).NotTo(HaveOccurred())
5178
5179 zmScore = client.ZMScore(ctx, "zset", "one", "three")
5180 Expect(zmScore.Err()).NotTo(HaveOccurred())
5181 Expect(zmScore.Val()).To(HaveLen(2))
5182 Expect(zmScore.Val()[0]).To(Equal(float64(1)))
5183
5184 zmScore = client.ZMScore(ctx, "zset", "four")
5185 Expect(zmScore.Err()).NotTo(HaveOccurred())
5186 Expect(zmScore.Val()).To(HaveLen(1))
5187
5188 zmScore = client.ZMScore(ctx, "zset", "four", "one")
5189 Expect(zmScore.Err()).NotTo(HaveOccurred())
5190 Expect(zmScore.Val()).To(HaveLen(2))
5191 })
5192
5193 It("should ZPopMax", func() {
5194 err := client.ZAdd(ctx, "zset", redis.Z{
5195 Score: 1,
5196 Member: "one",
5197 }).Err()
5198 Expect(err).NotTo(HaveOccurred())
5199 err = client.ZAdd(ctx, "zset", redis.Z{
5200 Score: 2,
5201 Member: "two",
5202 }).Err()
5203 Expect(err).NotTo(HaveOccurred())
5204 err = client.ZAdd(ctx, "zset", redis.Z{
5205 Score: 3,
5206 Member: "three",
5207 }).Err()
5208 Expect(err).NotTo(HaveOccurred())
5209
5210 members, err := client.ZPopMax(ctx, "zset").Result()
5211 Expect(err).NotTo(HaveOccurred())
5212 Expect(members).To(Equal([]redis.Z{{
5213 Score: 3,
5214 Member: "three",
5215 }}))
5216
5217
5218 err = client.ZAdd(ctx, "zset", redis.Z{
5219 Score: 3,
5220 Member: "three",
5221 }).Err()
5222 Expect(err).NotTo(HaveOccurred())
5223 members, err = client.ZPopMax(ctx, "zset", 2).Result()
5224 Expect(err).NotTo(HaveOccurred())
5225 Expect(members).To(Equal([]redis.Z{{
5226 Score: 3,
5227 Member: "three",
5228 }, {
5229 Score: 2,
5230 Member: "two",
5231 }}))
5232
5233
5234 err = client.ZAdd(ctx, "zset", redis.Z{
5235 Score: 3,
5236 Member: "three",
5237 }).Err()
5238 Expect(err).NotTo(HaveOccurred())
5239 err = client.ZAdd(ctx, "zset", redis.Z{
5240 Score: 2,
5241 Member: "two",
5242 }).Err()
5243 Expect(err).NotTo(HaveOccurred())
5244 members, err = client.ZPopMax(ctx, "zset", 10).Result()
5245 Expect(err).NotTo(HaveOccurred())
5246 Expect(members).To(Equal([]redis.Z{{
5247 Score: 3,
5248 Member: "three",
5249 }, {
5250 Score: 2,
5251 Member: "two",
5252 }, {
5253 Score: 1,
5254 Member: "one",
5255 }}))
5256 })
5257
5258 It("should ZPopMin", func() {
5259 err := client.ZAdd(ctx, "zset", redis.Z{
5260 Score: 1,
5261 Member: "one",
5262 }).Err()
5263 Expect(err).NotTo(HaveOccurred())
5264 err = client.ZAdd(ctx, "zset", redis.Z{
5265 Score: 2,
5266 Member: "two",
5267 }).Err()
5268 Expect(err).NotTo(HaveOccurred())
5269 err = client.ZAdd(ctx, "zset", redis.Z{
5270 Score: 3,
5271 Member: "three",
5272 }).Err()
5273 Expect(err).NotTo(HaveOccurred())
5274
5275 members, err := client.ZPopMin(ctx, "zset").Result()
5276 Expect(err).NotTo(HaveOccurred())
5277 Expect(members).To(Equal([]redis.Z{{
5278 Score: 1,
5279 Member: "one",
5280 }}))
5281
5282
5283 err = client.ZAdd(ctx, "zset", redis.Z{
5284 Score: 1,
5285 Member: "one",
5286 }).Err()
5287 Expect(err).NotTo(HaveOccurred())
5288 members, err = client.ZPopMin(ctx, "zset", 2).Result()
5289 Expect(err).NotTo(HaveOccurred())
5290 Expect(members).To(Equal([]redis.Z{{
5291 Score: 1,
5292 Member: "one",
5293 }, {
5294 Score: 2,
5295 Member: "two",
5296 }}))
5297
5298
5299 err = client.ZAdd(ctx, "zset", redis.Z{
5300 Score: 1,
5301 Member: "one",
5302 }).Err()
5303 Expect(err).NotTo(HaveOccurred())
5304
5305 err = client.ZAdd(ctx, "zset", redis.Z{
5306 Score: 2,
5307 Member: "two",
5308 }).Err()
5309 Expect(err).NotTo(HaveOccurred())
5310
5311 members, err = client.ZPopMin(ctx, "zset", 10).Result()
5312 Expect(err).NotTo(HaveOccurred())
5313 Expect(members).To(Equal([]redis.Z{{
5314 Score: 1,
5315 Member: "one",
5316 }, {
5317 Score: 2,
5318 Member: "two",
5319 }, {
5320 Score: 3,
5321 Member: "three",
5322 }}))
5323 })
5324
5325 It("should ZRange", func() {
5326 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5327 Expect(err).NotTo(HaveOccurred())
5328 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5329 Expect(err).NotTo(HaveOccurred())
5330 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5331 Expect(err).NotTo(HaveOccurred())
5332
5333 zRange := client.ZRange(ctx, "zset", 0, -1)
5334 Expect(zRange.Err()).NotTo(HaveOccurred())
5335 Expect(zRange.Val()).To(Equal([]string{"one", "two", "three"}))
5336
5337 zRange = client.ZRange(ctx, "zset", 2, 3)
5338 Expect(zRange.Err()).NotTo(HaveOccurred())
5339 Expect(zRange.Val()).To(Equal([]string{"three"}))
5340
5341 zRange = client.ZRange(ctx, "zset", -2, -1)
5342 Expect(zRange.Err()).NotTo(HaveOccurred())
5343 Expect(zRange.Val()).To(Equal([]string{"two", "three"}))
5344 })
5345
5346 It("should ZRangeWithScores", func() {
5347 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5348 Expect(err).NotTo(HaveOccurred())
5349 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5350 Expect(err).NotTo(HaveOccurred())
5351 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5352 Expect(err).NotTo(HaveOccurred())
5353
5354 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
5355 Expect(err).NotTo(HaveOccurred())
5356 Expect(vals).To(Equal([]redis.Z{{
5357 Score: 1,
5358 Member: "one",
5359 }, {
5360 Score: 2,
5361 Member: "two",
5362 }, {
5363 Score: 3,
5364 Member: "three",
5365 }}))
5366
5367 vals, err = client.ZRangeWithScores(ctx, "zset", 2, 3).Result()
5368 Expect(err).NotTo(HaveOccurred())
5369 Expect(vals).To(Equal([]redis.Z{{Score: 3, Member: "three"}}))
5370
5371 vals, err = client.ZRangeWithScores(ctx, "zset", -2, -1).Result()
5372 Expect(err).NotTo(HaveOccurred())
5373 Expect(vals).To(Equal([]redis.Z{{
5374 Score: 2,
5375 Member: "two",
5376 }, {
5377 Score: 3,
5378 Member: "three",
5379 }}))
5380 })
5381
5382 It("should ZRangeArgs", func() {
5383 added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
5384 Members: []redis.Z{
5385 {Score: 1, Member: "one"},
5386 {Score: 2, Member: "two"},
5387 {Score: 3, Member: "three"},
5388 {Score: 4, Member: "four"},
5389 },
5390 }).Result()
5391 Expect(err).NotTo(HaveOccurred())
5392 Expect(added).To(Equal(int64(4)))
5393
5394 zRange, err := client.ZRangeArgs(ctx, redis.ZRangeArgs{
5395 Key: "zset",
5396 Start: 1,
5397 Stop: 4,
5398 ByScore: true,
5399 Rev: true,
5400 Offset: 1,
5401 Count: 2,
5402 }).Result()
5403 Expect(err).NotTo(HaveOccurred())
5404 Expect(zRange).To(Equal([]string{"three", "two"}))
5405
5406 zRange, err = client.ZRangeArgs(ctx, redis.ZRangeArgs{
5407 Key: "zset",
5408 Start: "-",
5409 Stop: "+",
5410 ByLex: true,
5411 Rev: true,
5412 Offset: 2,
5413 Count: 2,
5414 }).Result()
5415 Expect(err).NotTo(HaveOccurred())
5416 Expect(zRange).To(Equal([]string{"two", "one"}))
5417
5418 zRange, err = client.ZRangeArgs(ctx, redis.ZRangeArgs{
5419 Key: "zset",
5420 Start: "(1",
5421 Stop: "(4",
5422 ByScore: true,
5423 }).Result()
5424 Expect(err).NotTo(HaveOccurred())
5425 Expect(zRange).To(Equal([]string{"two", "three"}))
5426
5427
5428 zSlice, err := client.ZRangeArgsWithScores(ctx, redis.ZRangeArgs{
5429 Key: "zset",
5430 Start: 1,
5431 Stop: 4,
5432 ByScore: true,
5433 Rev: true,
5434 Offset: 1,
5435 Count: 2,
5436 }).Result()
5437 Expect(err).NotTo(HaveOccurred())
5438 Expect(zSlice).To(Equal([]redis.Z{
5439 {Score: 3, Member: "three"},
5440 {Score: 2, Member: "two"},
5441 }))
5442 })
5443
5444 It("should ZRangeByScore", func() {
5445 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5446 Expect(err).NotTo(HaveOccurred())
5447 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5448 Expect(err).NotTo(HaveOccurred())
5449 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5450 Expect(err).NotTo(HaveOccurred())
5451
5452 zRangeByScore := client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
5453 Min: "-inf",
5454 Max: "+inf",
5455 })
5456 Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
5457 Expect(zRangeByScore.Val()).To(Equal([]string{"one", "two", "three"}))
5458
5459 zRangeByScore = client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
5460 Min: "1",
5461 Max: "2",
5462 })
5463 Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
5464 Expect(zRangeByScore.Val()).To(Equal([]string{"one", "two"}))
5465
5466 zRangeByScore = client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
5467 Min: "(1",
5468 Max: "2",
5469 })
5470 Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
5471 Expect(zRangeByScore.Val()).To(Equal([]string{"two"}))
5472
5473 zRangeByScore = client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
5474 Min: "(1",
5475 Max: "(2",
5476 })
5477 Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
5478 Expect(zRangeByScore.Val()).To(Equal([]string{}))
5479 })
5480
5481 It("should ZRangeByLex", func() {
5482 err := client.ZAdd(ctx, "zset", redis.Z{
5483 Score: 0,
5484 Member: "a",
5485 }).Err()
5486 Expect(err).NotTo(HaveOccurred())
5487 err = client.ZAdd(ctx, "zset", redis.Z{
5488 Score: 0,
5489 Member: "b",
5490 }).Err()
5491 Expect(err).NotTo(HaveOccurred())
5492 err = client.ZAdd(ctx, "zset", redis.Z{
5493 Score: 0,
5494 Member: "c",
5495 }).Err()
5496 Expect(err).NotTo(HaveOccurred())
5497
5498 zRangeByLex := client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
5499 Min: "-",
5500 Max: "+",
5501 })
5502 Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
5503 Expect(zRangeByLex.Val()).To(Equal([]string{"a", "b", "c"}))
5504
5505 zRangeByLex = client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
5506 Min: "[a",
5507 Max: "[b",
5508 })
5509 Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
5510 Expect(zRangeByLex.Val()).To(Equal([]string{"a", "b"}))
5511
5512 zRangeByLex = client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
5513 Min: "(a",
5514 Max: "[b",
5515 })
5516 Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
5517 Expect(zRangeByLex.Val()).To(Equal([]string{"b"}))
5518
5519 zRangeByLex = client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
5520 Min: "(a",
5521 Max: "(b",
5522 })
5523 Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
5524 Expect(zRangeByLex.Val()).To(Equal([]string{}))
5525 })
5526
5527 It("should ZRangeByScoreWithScoresMap", func() {
5528 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5529 Expect(err).NotTo(HaveOccurred())
5530 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5531 Expect(err).NotTo(HaveOccurred())
5532 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5533 Expect(err).NotTo(HaveOccurred())
5534
5535 vals, err := client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
5536 Min: "-inf",
5537 Max: "+inf",
5538 }).Result()
5539 Expect(err).NotTo(HaveOccurred())
5540 Expect(vals).To(Equal([]redis.Z{{
5541 Score: 1,
5542 Member: "one",
5543 }, {
5544 Score: 2,
5545 Member: "two",
5546 }, {
5547 Score: 3,
5548 Member: "three",
5549 }}))
5550
5551 vals, err = client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
5552 Min: "1",
5553 Max: "2",
5554 }).Result()
5555 Expect(err).NotTo(HaveOccurred())
5556 Expect(vals).To(Equal([]redis.Z{{
5557 Score: 1,
5558 Member: "one",
5559 }, {
5560 Score: 2,
5561 Member: "two",
5562 }}))
5563
5564 vals, err = client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
5565 Min: "(1",
5566 Max: "2",
5567 }).Result()
5568 Expect(err).NotTo(HaveOccurred())
5569 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "two"}}))
5570
5571 vals, err = client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
5572 Min: "(1",
5573 Max: "(2",
5574 }).Result()
5575 Expect(err).NotTo(HaveOccurred())
5576 Expect(vals).To(Equal([]redis.Z{}))
5577 })
5578
5579 It("should ZRangeStore", Label("NonRedisEnterprise"), func() {
5580 added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
5581 Members: []redis.Z{
5582 {Score: 1, Member: "one"},
5583 {Score: 2, Member: "two"},
5584 {Score: 3, Member: "three"},
5585 {Score: 4, Member: "four"},
5586 },
5587 }).Result()
5588 Expect(err).NotTo(HaveOccurred())
5589 Expect(added).To(Equal(int64(4)))
5590
5591 rangeStore, err := client.ZRangeStore(ctx, "new-zset", redis.ZRangeArgs{
5592 Key: "zset",
5593 Start: 1,
5594 Stop: 4,
5595 ByScore: true,
5596 Rev: true,
5597 Offset: 1,
5598 Count: 2,
5599 }).Result()
5600 Expect(err).NotTo(HaveOccurred())
5601 Expect(rangeStore).To(Equal(int64(2)))
5602
5603 zRange, err := client.ZRange(ctx, "new-zset", 0, -1).Result()
5604 Expect(err).NotTo(HaveOccurred())
5605 Expect(zRange).To(Equal([]string{"two", "three"}))
5606 })
5607
5608 It("should ZRank", func() {
5609 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5610 Expect(err).NotTo(HaveOccurred())
5611 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5612 Expect(err).NotTo(HaveOccurred())
5613 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5614 Expect(err).NotTo(HaveOccurred())
5615
5616 zRank := client.ZRank(ctx, "zset", "three")
5617 Expect(zRank.Err()).NotTo(HaveOccurred())
5618 Expect(zRank.Val()).To(Equal(int64(2)))
5619
5620 zRank = client.ZRank(ctx, "zset", "four")
5621 Expect(zRank.Err()).To(Equal(redis.Nil))
5622 Expect(zRank.Val()).To(Equal(int64(0)))
5623 })
5624
5625 It("should ZRankWithScore", func() {
5626 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5627 Expect(err).NotTo(HaveOccurred())
5628 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5629 Expect(err).NotTo(HaveOccurred())
5630 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5631 Expect(err).NotTo(HaveOccurred())
5632
5633 zRankWithScore := client.ZRankWithScore(ctx, "zset", "one")
5634 Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
5635 Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 0, Score: 1}))
5636
5637 zRankWithScore = client.ZRankWithScore(ctx, "zset", "two")
5638 Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
5639 Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 1, Score: 2}))
5640
5641 zRankWithScore = client.ZRankWithScore(ctx, "zset", "three")
5642 Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
5643 Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 2, Score: 3}))
5644
5645 zRankWithScore = client.ZRankWithScore(ctx, "zset", "four")
5646 Expect(zRankWithScore.Err()).To(HaveOccurred())
5647 Expect(zRankWithScore.Err()).To(Equal(redis.Nil))
5648 })
5649
5650 It("should ZRem", func() {
5651 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5652 Expect(err).NotTo(HaveOccurred())
5653 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5654 Expect(err).NotTo(HaveOccurred())
5655 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5656 Expect(err).NotTo(HaveOccurred())
5657
5658 zRem := client.ZRem(ctx, "zset", "two")
5659 Expect(zRem.Err()).NotTo(HaveOccurred())
5660 Expect(zRem.Val()).To(Equal(int64(1)))
5661
5662 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
5663 Expect(err).NotTo(HaveOccurred())
5664 Expect(vals).To(Equal([]redis.Z{{
5665 Score: 1,
5666 Member: "one",
5667 }, {
5668 Score: 3,
5669 Member: "three",
5670 }}))
5671 })
5672
5673 It("should ZRemRangeByRank", func() {
5674 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5675 Expect(err).NotTo(HaveOccurred())
5676 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5677 Expect(err).NotTo(HaveOccurred())
5678 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5679 Expect(err).NotTo(HaveOccurred())
5680
5681 zRemRangeByRank := client.ZRemRangeByRank(ctx, "zset", 0, 1)
5682 Expect(zRemRangeByRank.Err()).NotTo(HaveOccurred())
5683 Expect(zRemRangeByRank.Val()).To(Equal(int64(2)))
5684
5685 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
5686 Expect(err).NotTo(HaveOccurred())
5687 Expect(vals).To(Equal([]redis.Z{{
5688 Score: 3,
5689 Member: "three",
5690 }}))
5691 })
5692
5693 It("should ZRemRangeByScore", func() {
5694 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5695 Expect(err).NotTo(HaveOccurred())
5696 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5697 Expect(err).NotTo(HaveOccurred())
5698 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5699 Expect(err).NotTo(HaveOccurred())
5700
5701 zRemRangeByScore := client.ZRemRangeByScore(ctx, "zset", "-inf", "(2")
5702 Expect(zRemRangeByScore.Err()).NotTo(HaveOccurred())
5703 Expect(zRemRangeByScore.Val()).To(Equal(int64(1)))
5704
5705 vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
5706 Expect(err).NotTo(HaveOccurred())
5707 Expect(vals).To(Equal([]redis.Z{{
5708 Score: 2,
5709 Member: "two",
5710 }, {
5711 Score: 3,
5712 Member: "three",
5713 }}))
5714 })
5715
5716 It("should ZRemRangeByLex", func() {
5717 zz := []redis.Z{
5718 {Score: 0, Member: "aaaa"},
5719 {Score: 0, Member: "b"},
5720 {Score: 0, Member: "c"},
5721 {Score: 0, Member: "d"},
5722 {Score: 0, Member: "e"},
5723 {Score: 0, Member: "foo"},
5724 {Score: 0, Member: "zap"},
5725 {Score: 0, Member: "zip"},
5726 {Score: 0, Member: "ALPHA"},
5727 {Score: 0, Member: "alpha"},
5728 }
5729 for _, z := range zz {
5730 err := client.ZAdd(ctx, "zset", z).Err()
5731 Expect(err).NotTo(HaveOccurred())
5732 }
5733
5734 n, err := client.ZRemRangeByLex(ctx, "zset", "[alpha", "[omega").Result()
5735 Expect(err).NotTo(HaveOccurred())
5736 Expect(n).To(Equal(int64(6)))
5737
5738 vals, err := client.ZRange(ctx, "zset", 0, -1).Result()
5739 Expect(err).NotTo(HaveOccurred())
5740 Expect(vals).To(Equal([]string{"ALPHA", "aaaa", "zap", "zip"}))
5741 })
5742
5743 It("should ZRevRange", func() {
5744 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5745 Expect(err).NotTo(HaveOccurred())
5746 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5747 Expect(err).NotTo(HaveOccurred())
5748 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5749 Expect(err).NotTo(HaveOccurred())
5750
5751 zRevRange := client.ZRevRange(ctx, "zset", 0, -1)
5752 Expect(zRevRange.Err()).NotTo(HaveOccurred())
5753 Expect(zRevRange.Val()).To(Equal([]string{"three", "two", "one"}))
5754
5755 zRevRange = client.ZRevRange(ctx, "zset", 2, 3)
5756 Expect(zRevRange.Err()).NotTo(HaveOccurred())
5757 Expect(zRevRange.Val()).To(Equal([]string{"one"}))
5758
5759 zRevRange = client.ZRevRange(ctx, "zset", -2, -1)
5760 Expect(zRevRange.Err()).NotTo(HaveOccurred())
5761 Expect(zRevRange.Val()).To(Equal([]string{"two", "one"}))
5762 })
5763
5764 It("should ZRevRangeWithScoresMap", func() {
5765 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5766 Expect(err).NotTo(HaveOccurred())
5767 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5768 Expect(err).NotTo(HaveOccurred())
5769 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5770 Expect(err).NotTo(HaveOccurred())
5771
5772 val, err := client.ZRevRangeWithScores(ctx, "zset", 0, -1).Result()
5773 Expect(err).NotTo(HaveOccurred())
5774 Expect(val).To(Equal([]redis.Z{{
5775 Score: 3,
5776 Member: "three",
5777 }, {
5778 Score: 2,
5779 Member: "two",
5780 }, {
5781 Score: 1,
5782 Member: "one",
5783 }}))
5784
5785 val, err = client.ZRevRangeWithScores(ctx, "zset", 2, 3).Result()
5786 Expect(err).NotTo(HaveOccurred())
5787 Expect(val).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
5788
5789 val, err = client.ZRevRangeWithScores(ctx, "zset", -2, -1).Result()
5790 Expect(err).NotTo(HaveOccurred())
5791 Expect(val).To(Equal([]redis.Z{{
5792 Score: 2,
5793 Member: "two",
5794 }, {
5795 Score: 1,
5796 Member: "one",
5797 }}))
5798 })
5799
5800 It("should ZRevRangeByScore", func() {
5801 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5802 Expect(err).NotTo(HaveOccurred())
5803 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5804 Expect(err).NotTo(HaveOccurred())
5805 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5806 Expect(err).NotTo(HaveOccurred())
5807
5808 vals, err := client.ZRevRangeByScore(
5809 ctx, "zset", &redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
5810 Expect(err).NotTo(HaveOccurred())
5811 Expect(vals).To(Equal([]string{"three", "two", "one"}))
5812
5813 vals, err = client.ZRevRangeByScore(
5814 ctx, "zset", &redis.ZRangeBy{Max: "2", Min: "(1"}).Result()
5815 Expect(err).NotTo(HaveOccurred())
5816 Expect(vals).To(Equal([]string{"two"}))
5817
5818 vals, err = client.ZRevRangeByScore(
5819 ctx, "zset", &redis.ZRangeBy{Max: "(2", Min: "(1"}).Result()
5820 Expect(err).NotTo(HaveOccurred())
5821 Expect(vals).To(Equal([]string{}))
5822 })
5823
5824 It("should ZRevRangeByLex", func() {
5825 err := client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "a"}).Err()
5826 Expect(err).NotTo(HaveOccurred())
5827 err = client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "b"}).Err()
5828 Expect(err).NotTo(HaveOccurred())
5829 err = client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "c"}).Err()
5830 Expect(err).NotTo(HaveOccurred())
5831
5832 vals, err := client.ZRevRangeByLex(
5833 ctx, "zset", &redis.ZRangeBy{Max: "+", Min: "-"}).Result()
5834 Expect(err).NotTo(HaveOccurred())
5835 Expect(vals).To(Equal([]string{"c", "b", "a"}))
5836
5837 vals, err = client.ZRevRangeByLex(
5838 ctx, "zset", &redis.ZRangeBy{Max: "[b", Min: "(a"}).Result()
5839 Expect(err).NotTo(HaveOccurred())
5840 Expect(vals).To(Equal([]string{"b"}))
5841
5842 vals, err = client.ZRevRangeByLex(
5843 ctx, "zset", &redis.ZRangeBy{Max: "(b", Min: "(a"}).Result()
5844 Expect(err).NotTo(HaveOccurred())
5845 Expect(vals).To(Equal([]string{}))
5846 })
5847
5848 It("should ZRevRangeByScoreWithScores", func() {
5849 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5850 Expect(err).NotTo(HaveOccurred())
5851 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5852 Expect(err).NotTo(HaveOccurred())
5853 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5854 Expect(err).NotTo(HaveOccurred())
5855
5856 vals, err := client.ZRevRangeByScoreWithScores(
5857 ctx, "zset", &redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
5858 Expect(err).NotTo(HaveOccurred())
5859 Expect(vals).To(Equal([]redis.Z{{
5860 Score: 3,
5861 Member: "three",
5862 }, {
5863 Score: 2,
5864 Member: "two",
5865 }, {
5866 Score: 1,
5867 Member: "one",
5868 }}))
5869 })
5870
5871 It("should ZRevRangeByScoreWithScoresMap", func() {
5872 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5873 Expect(err).NotTo(HaveOccurred())
5874 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5875 Expect(err).NotTo(HaveOccurred())
5876 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5877 Expect(err).NotTo(HaveOccurred())
5878
5879 vals, err := client.ZRevRangeByScoreWithScores(
5880 ctx, "zset", &redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
5881 Expect(err).NotTo(HaveOccurred())
5882 Expect(vals).To(Equal([]redis.Z{{
5883 Score: 3,
5884 Member: "three",
5885 }, {
5886 Score: 2,
5887 Member: "two",
5888 }, {
5889 Score: 1,
5890 Member: "one",
5891 }}))
5892
5893 vals, err = client.ZRevRangeByScoreWithScores(
5894 ctx, "zset", &redis.ZRangeBy{Max: "2", Min: "(1"}).Result()
5895 Expect(err).NotTo(HaveOccurred())
5896 Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "two"}}))
5897
5898 vals, err = client.ZRevRangeByScoreWithScores(
5899 ctx, "zset", &redis.ZRangeBy{Max: "(2", Min: "(1"}).Result()
5900 Expect(err).NotTo(HaveOccurred())
5901 Expect(vals).To(Equal([]redis.Z{}))
5902 })
5903
5904 It("should ZRevRank", func() {
5905 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5906 Expect(err).NotTo(HaveOccurred())
5907 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5908 Expect(err).NotTo(HaveOccurred())
5909 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5910 Expect(err).NotTo(HaveOccurred())
5911
5912 zRevRank := client.ZRevRank(ctx, "zset", "one")
5913 Expect(zRevRank.Err()).NotTo(HaveOccurred())
5914 Expect(zRevRank.Val()).To(Equal(int64(2)))
5915
5916 zRevRank = client.ZRevRank(ctx, "zset", "four")
5917 Expect(zRevRank.Err()).To(Equal(redis.Nil))
5918 Expect(zRevRank.Val()).To(Equal(int64(0)))
5919 })
5920
5921 It("should ZRevRankWithScore", func() {
5922 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
5923 Expect(err).NotTo(HaveOccurred())
5924 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
5925 Expect(err).NotTo(HaveOccurred())
5926 err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
5927 Expect(err).NotTo(HaveOccurred())
5928
5929 zRevRankWithScore := client.ZRevRankWithScore(ctx, "zset", "one")
5930 Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
5931 Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 2, Score: 1}))
5932
5933 zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "two")
5934 Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
5935 Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 1, Score: 2}))
5936
5937 zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "three")
5938 Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
5939 Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 0, Score: 3}))
5940
5941 zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "four")
5942 Expect(zRevRankWithScore.Err()).To(HaveOccurred())
5943 Expect(zRevRankWithScore.Err()).To(Equal(redis.Nil))
5944 })
5945
5946 It("should ZScore", func() {
5947 zAdd := client.ZAdd(ctx, "zset", redis.Z{Score: 1.001, Member: "one"})
5948 Expect(zAdd.Err()).NotTo(HaveOccurred())
5949
5950 zScore := client.ZScore(ctx, "zset", "one")
5951 Expect(zScore.Err()).NotTo(HaveOccurred())
5952 Expect(zScore.Val()).To(Equal(1.001))
5953 })
5954
5955 It("should ZUnion", Label("NonRedisEnterprise"), func() {
5956 err := client.ZAddArgs(ctx, "zset1", redis.ZAddArgs{
5957 Members: []redis.Z{
5958 {Score: 1, Member: "one"},
5959 {Score: 2, Member: "two"},
5960 },
5961 }).Err()
5962 Expect(err).NotTo(HaveOccurred())
5963
5964 err = client.ZAddArgs(ctx, "zset2", redis.ZAddArgs{
5965 Members: []redis.Z{
5966 {Score: 1, Member: "one"},
5967 {Score: 2, Member: "two"},
5968 {Score: 3, Member: "three"},
5969 },
5970 }).Err()
5971 Expect(err).NotTo(HaveOccurred())
5972
5973 union, err := client.ZUnion(ctx, redis.ZStore{
5974 Keys: []string{"zset1", "zset2"},
5975 Weights: []float64{2, 3},
5976 Aggregate: "sum",
5977 }).Result()
5978 Expect(err).NotTo(HaveOccurred())
5979 Expect(union).To(Equal([]string{"one", "three", "two"}))
5980
5981 unionScores, err := client.ZUnionWithScores(ctx, redis.ZStore{
5982 Keys: []string{"zset1", "zset2"},
5983 Weights: []float64{2, 3},
5984 Aggregate: "sum",
5985 }).Result()
5986 Expect(err).NotTo(HaveOccurred())
5987 Expect(unionScores).To(Equal([]redis.Z{
5988 {Score: 5, Member: "one"},
5989 {Score: 9, Member: "three"},
5990 {Score: 10, Member: "two"},
5991 }))
5992 })
5993
5994 It("should ZUnionStore", Label("NonRedisEnterprise"), func() {
5995 err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
5996 Expect(err).NotTo(HaveOccurred())
5997 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
5998 Expect(err).NotTo(HaveOccurred())
5999
6000 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
6001 Expect(err).NotTo(HaveOccurred())
6002 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
6003 Expect(err).NotTo(HaveOccurred())
6004 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
6005 Expect(err).NotTo(HaveOccurred())
6006
6007 n, err := client.ZUnionStore(ctx, "out", &redis.ZStore{
6008 Keys: []string{"zset1", "zset2"},
6009 Weights: []float64{2, 3},
6010 }).Result()
6011 Expect(err).NotTo(HaveOccurred())
6012 Expect(n).To(Equal(int64(3)))
6013
6014 val, err := client.ZRangeWithScores(ctx, "out", 0, -1).Result()
6015 Expect(err).NotTo(HaveOccurred())
6016 Expect(val).To(Equal([]redis.Z{{
6017 Score: 5,
6018 Member: "one",
6019 }, {
6020 Score: 9,
6021 Member: "three",
6022 }, {
6023 Score: 10,
6024 Member: "two",
6025 }}))
6026 })
6027
6028 It("should ZRandMember", func() {
6029 err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
6030 Expect(err).NotTo(HaveOccurred())
6031 err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
6032 Expect(err).NotTo(HaveOccurred())
6033
6034 v := client.ZRandMember(ctx, "zset", 1)
6035 Expect(v.Err()).NotTo(HaveOccurred())
6036 Expect(v.Val()).To(Or(Equal([]string{"one"}), Equal([]string{"two"})))
6037
6038 v = client.ZRandMember(ctx, "zset", 0)
6039 Expect(v.Err()).NotTo(HaveOccurred())
6040 Expect(v.Val()).To(HaveLen(0))
6041
6042 kv, err := client.ZRandMemberWithScores(ctx, "zset", 1).Result()
6043 Expect(err).NotTo(HaveOccurred())
6044 Expect(kv).To(Or(
6045 Equal([]redis.Z{{Member: "one", Score: 1}}),
6046 Equal([]redis.Z{{Member: "two", Score: 2}}),
6047 ))
6048 })
6049
6050 It("should ZDiff", Label("NonRedisEnterprise"), func() {
6051 err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
6052 Expect(err).NotTo(HaveOccurred())
6053 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
6054 Expect(err).NotTo(HaveOccurred())
6055 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 3, Member: "three"}).Err()
6056 Expect(err).NotTo(HaveOccurred())
6057 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
6058 Expect(err).NotTo(HaveOccurred())
6059
6060 v, err := client.ZDiff(ctx, "zset1", "zset2").Result()
6061 Expect(err).NotTo(HaveOccurred())
6062 Expect(v).To(Equal([]string{"two", "three"}))
6063 })
6064
6065 It("should ZDiffWithScores", Label("NonRedisEnterprise"), func() {
6066 err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
6067 Expect(err).NotTo(HaveOccurred())
6068 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
6069 Expect(err).NotTo(HaveOccurred())
6070 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 3, Member: "three"}).Err()
6071 Expect(err).NotTo(HaveOccurred())
6072 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
6073 Expect(err).NotTo(HaveOccurred())
6074
6075 v, err := client.ZDiffWithScores(ctx, "zset1", "zset2").Result()
6076 Expect(err).NotTo(HaveOccurred())
6077 Expect(v).To(Equal([]redis.Z{
6078 {
6079 Member: "two",
6080 Score: 2,
6081 },
6082 {
6083 Member: "three",
6084 Score: 3,
6085 },
6086 }))
6087 })
6088
6089 It("should ZInter", Label("NonRedisEnterprise"), func() {
6090 err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
6091 Expect(err).NotTo(HaveOccurred())
6092 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
6093 Expect(err).NotTo(HaveOccurred())
6094 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
6095 Expect(err).NotTo(HaveOccurred())
6096 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
6097 Expect(err).NotTo(HaveOccurred())
6098 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
6099 Expect(err).NotTo(HaveOccurred())
6100
6101 v, err := client.ZInter(ctx, &redis.ZStore{
6102 Keys: []string{"zset1", "zset2"},
6103 }).Result()
6104 Expect(err).NotTo(HaveOccurred())
6105 Expect(v).To(Equal([]string{"one", "two"}))
6106 })
6107
6108 It("should ZInterCard", Label("NonRedisEnterprise"), func() {
6109 err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
6110 Expect(err).NotTo(HaveOccurred())
6111 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
6112 Expect(err).NotTo(HaveOccurred())
6113 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
6114 Expect(err).NotTo(HaveOccurred())
6115 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
6116 Expect(err).NotTo(HaveOccurred())
6117 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
6118 Expect(err).NotTo(HaveOccurred())
6119
6120
6121 sInterCard := client.ZInterCard(ctx, 0, "zset1", "zset2")
6122 Expect(sInterCard.Err()).NotTo(HaveOccurred())
6123 Expect(sInterCard.Val()).To(Equal(int64(2)))
6124
6125 sInterCard = client.ZInterCard(ctx, 1, "zset1", "zset2")
6126 Expect(sInterCard.Err()).NotTo(HaveOccurred())
6127 Expect(sInterCard.Val()).To(Equal(int64(1)))
6128
6129 sInterCard = client.ZInterCard(ctx, 3, "zset1", "zset2")
6130 Expect(sInterCard.Err()).NotTo(HaveOccurred())
6131 Expect(sInterCard.Val()).To(Equal(int64(2)))
6132 })
6133
6134 It("should ZInterWithScores", Label("NonRedisEnterprise"), func() {
6135 err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
6136 Expect(err).NotTo(HaveOccurred())
6137 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
6138 Expect(err).NotTo(HaveOccurred())
6139 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
6140 Expect(err).NotTo(HaveOccurred())
6141 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
6142 Expect(err).NotTo(HaveOccurred())
6143 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
6144 Expect(err).NotTo(HaveOccurred())
6145
6146 v, err := client.ZInterWithScores(ctx, &redis.ZStore{
6147 Keys: []string{"zset1", "zset2"},
6148 Weights: []float64{2, 3},
6149 Aggregate: "Max",
6150 }).Result()
6151 Expect(err).NotTo(HaveOccurred())
6152 Expect(v).To(Equal([]redis.Z{
6153 {
6154 Member: "one",
6155 Score: 3,
6156 },
6157 {
6158 Member: "two",
6159 Score: 6,
6160 },
6161 }))
6162 })
6163
6164 It("should ZDiffStore", Label("NonRedisEnterprise"), func() {
6165 err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
6166 Expect(err).NotTo(HaveOccurred())
6167 err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
6168 Expect(err).NotTo(HaveOccurred())
6169 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
6170 Expect(err).NotTo(HaveOccurred())
6171 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
6172 Expect(err).NotTo(HaveOccurred())
6173 err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
6174 Expect(err).NotTo(HaveOccurred())
6175 v, err := client.ZDiffStore(ctx, "out1", "zset1", "zset2").Result()
6176 Expect(err).NotTo(HaveOccurred())
6177 Expect(v).To(Equal(int64(0)))
6178 v, err = client.ZDiffStore(ctx, "out1", "zset2", "zset1").Result()
6179 Expect(err).NotTo(HaveOccurred())
6180 Expect(v).To(Equal(int64(1)))
6181 vals, err := client.ZRangeWithScores(ctx, "out1", 0, -1).Result()
6182 Expect(err).NotTo(HaveOccurred())
6183 Expect(vals).To(Equal([]redis.Z{{
6184 Score: 3,
6185 Member: "three",
6186 }}))
6187 })
6188 })
6189
6190 Describe("streams", func() {
6191 BeforeEach(func() {
6192 id, err := client.XAdd(ctx, &redis.XAddArgs{
6193 Stream: "stream",
6194 ID: "1-0",
6195 Values: map[string]interface{}{"uno": "un"},
6196 }).Result()
6197 Expect(err).NotTo(HaveOccurred())
6198 Expect(id).To(Equal("1-0"))
6199
6200
6201 id, err = client.XAdd(ctx, &redis.XAddArgs{
6202 Stream: "stream",
6203 ID: "2-0",
6204 Values: []interface{}{"dos", "deux"},
6205 }).Result()
6206 Expect(err).NotTo(HaveOccurred())
6207 Expect(id).To(Equal("2-0"))
6208
6209
6210 id, err = client.XAdd(ctx, &redis.XAddArgs{
6211 Stream: "stream",
6212 ID: "3-0",
6213 Values: []string{"tres", "troix"},
6214 }).Result()
6215 Expect(err).NotTo(HaveOccurred())
6216 Expect(id).To(Equal("3-0"))
6217 })
6218
6219 It("should XTrimMaxLen", func() {
6220 n, err := client.XTrimMaxLen(ctx, "stream", 0).Result()
6221 Expect(err).NotTo(HaveOccurred())
6222 Expect(n).To(Equal(int64(3)))
6223 })
6224
6225 It("should XTrimMaxLenApprox", func() {
6226 n, err := client.XTrimMaxLenApprox(ctx, "stream", 0, 0).Result()
6227 Expect(err).NotTo(HaveOccurred())
6228 Expect(n).To(Equal(int64(3)))
6229 })
6230
6231 It("should XTrimMinID", func() {
6232 n, err := client.XTrimMinID(ctx, "stream", "4-0").Result()
6233 Expect(err).NotTo(HaveOccurred())
6234 Expect(n).To(Equal(int64(3)))
6235 })
6236
6237 It("should XTrimMinIDApprox", func() {
6238 n, err := client.XTrimMinIDApprox(ctx, "stream", "4-0", 0).Result()
6239 Expect(err).NotTo(HaveOccurred())
6240 Expect(n).To(Equal(int64(3)))
6241 })
6242
6243 It("should XTrimMaxLenMode", func() {
6244 SkipBeforeRedisVersion(8.2, "doesn't work with older redis stack images")
6245 n, err := client.XTrimMaxLenMode(ctx, "stream", 0, "KEEPREF").Result()
6246 Expect(err).NotTo(HaveOccurred())
6247 Expect(n).To(BeNumerically(">=", 0))
6248 })
6249
6250 It("should XTrimMaxLenApproxMode", func() {
6251 SkipBeforeRedisVersion(8.2, "doesn't work with older redis stack images")
6252 n, err := client.XTrimMaxLenApproxMode(ctx, "stream", 0, 0, "KEEPREF").Result()
6253 Expect(err).NotTo(HaveOccurred())
6254 Expect(n).To(BeNumerically(">=", 0))
6255 })
6256
6257 It("should XTrimMinIDMode", func() {
6258 SkipBeforeRedisVersion(8.2, "doesn't work with older redis stack images")
6259 n, err := client.XTrimMinIDMode(ctx, "stream", "4-0", "KEEPREF").Result()
6260 Expect(err).NotTo(HaveOccurred())
6261 Expect(n).To(BeNumerically(">=", 0))
6262 })
6263
6264 It("should XTrimMinIDApproxMode", func() {
6265 SkipBeforeRedisVersion(8.2, "doesn't work with older redis stack images")
6266 n, err := client.XTrimMinIDApproxMode(ctx, "stream", "4-0", 0, "KEEPREF").Result()
6267 Expect(err).NotTo(HaveOccurred())
6268 Expect(n).To(BeNumerically(">=", 0))
6269 })
6270
6271 It("should XAdd", func() {
6272 id, err := client.XAdd(ctx, &redis.XAddArgs{
6273 Stream: "stream",
6274 Values: map[string]interface{}{"quatro": "quatre"},
6275 }).Result()
6276 Expect(err).NotTo(HaveOccurred())
6277
6278 vals, err := client.XRange(ctx, "stream", "-", "+").Result()
6279 Expect(err).NotTo(HaveOccurred())
6280 Expect(vals).To(Equal([]redis.XMessage{
6281 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6282 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6283 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6284 {ID: id, Values: map[string]interface{}{"quatro": "quatre"}},
6285 }))
6286 })
6287
6288 It("should XAdd with MaxLen", func() {
6289 id, err := client.XAdd(ctx, &redis.XAddArgs{
6290 Stream: "stream",
6291 MaxLen: 1,
6292 Values: map[string]interface{}{"quatro": "quatre"},
6293 }).Result()
6294 Expect(err).NotTo(HaveOccurred())
6295
6296 vals, err := client.XRange(ctx, "stream", "-", "+").Result()
6297 Expect(err).NotTo(HaveOccurred())
6298 Expect(vals).To(Equal([]redis.XMessage{
6299 {ID: id, Values: map[string]interface{}{"quatro": "quatre"}},
6300 }))
6301 })
6302
6303 It("should XAdd with MinID", func() {
6304 id, err := client.XAdd(ctx, &redis.XAddArgs{
6305 Stream: "stream",
6306 MinID: "5-0",
6307 ID: "4-0",
6308 Values: map[string]interface{}{"quatro": "quatre"},
6309 }).Result()
6310 Expect(err).NotTo(HaveOccurred())
6311 Expect(id).To(Equal("4-0"))
6312
6313 vals, err := client.XRange(ctx, "stream", "-", "+").Result()
6314 Expect(err).NotTo(HaveOccurred())
6315 Expect(vals).To(HaveLen(0))
6316 })
6317
6318 It("should XDel", func() {
6319 n, err := client.XDel(ctx, "stream", "1-0", "2-0", "3-0").Result()
6320 Expect(err).NotTo(HaveOccurred())
6321 Expect(n).To(Equal(int64(3)))
6322 })
6323
6324 It("should XAckDel", func() {
6325 SkipBeforeRedisVersion(8.2, "doesn't work with older redis stack images")
6326
6327 err := client.XGroupCreate(ctx, "stream", "testgroup", "0").Err()
6328 Expect(err).NotTo(HaveOccurred())
6329
6330
6331 _, err = client.XReadGroup(ctx, &redis.XReadGroupArgs{
6332 Group: "testgroup",
6333 Consumer: "testconsumer",
6334 Streams: []string{"stream", ">"},
6335 }).Result()
6336 Expect(err).NotTo(HaveOccurred())
6337
6338
6339 n, err := client.XAckDel(ctx, "stream", "testgroup", "KEEPREF", "1-0", "2-0").Result()
6340 Expect(err).NotTo(HaveOccurred())
6341 Expect(n).To(HaveLen(2))
6342
6343
6344 client.XGroupDestroy(ctx, "stream", "testgroup")
6345 })
6346
6347 It("should XDelEx", func() {
6348 SkipBeforeRedisVersion(8.2, "doesn't work with older redis stack images")
6349
6350 n, err := client.XDelEx(ctx, "stream", "KEEPREF", "1-0", "2-0").Result()
6351 Expect(err).NotTo(HaveOccurred())
6352 Expect(n).To(HaveLen(2))
6353 })
6354
6355 It("should XLen", func() {
6356 n, err := client.XLen(ctx, "stream").Result()
6357 Expect(err).NotTo(HaveOccurred())
6358 Expect(n).To(Equal(int64(3)))
6359 })
6360
6361 It("should XRange", func() {
6362 msgs, err := client.XRange(ctx, "stream", "-", "+").Result()
6363 Expect(err).NotTo(HaveOccurred())
6364 Expect(msgs).To(Equal([]redis.XMessage{
6365 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6366 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6367 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6368 }))
6369
6370 msgs, err = client.XRange(ctx, "stream", "2", "+").Result()
6371 Expect(err).NotTo(HaveOccurred())
6372 Expect(msgs).To(Equal([]redis.XMessage{
6373 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6374 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6375 }))
6376
6377 msgs, err = client.XRange(ctx, "stream", "-", "2").Result()
6378 Expect(err).NotTo(HaveOccurred())
6379 Expect(msgs).To(Equal([]redis.XMessage{
6380 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6381 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6382 }))
6383 })
6384
6385 It("should XRangeN", func() {
6386 msgs, err := client.XRangeN(ctx, "stream", "-", "+", 2).Result()
6387 Expect(err).NotTo(HaveOccurred())
6388 Expect(msgs).To(Equal([]redis.XMessage{
6389 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6390 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6391 }))
6392
6393 msgs, err = client.XRangeN(ctx, "stream", "2", "+", 1).Result()
6394 Expect(err).NotTo(HaveOccurred())
6395 Expect(msgs).To(Equal([]redis.XMessage{
6396 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6397 }))
6398
6399 msgs, err = client.XRangeN(ctx, "stream", "-", "2", 1).Result()
6400 Expect(err).NotTo(HaveOccurred())
6401 Expect(msgs).To(Equal([]redis.XMessage{
6402 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6403 }))
6404 })
6405
6406 It("should XRevRange", func() {
6407 msgs, err := client.XRevRange(ctx, "stream", "+", "-").Result()
6408 Expect(err).NotTo(HaveOccurred())
6409 Expect(msgs).To(Equal([]redis.XMessage{
6410 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6411 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6412 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6413 }))
6414
6415 msgs, err = client.XRevRange(ctx, "stream", "+", "2").Result()
6416 Expect(err).NotTo(HaveOccurred())
6417 Expect(msgs).To(Equal([]redis.XMessage{
6418 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6419 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6420 }))
6421 })
6422
6423 It("should XRevRangeN", func() {
6424 msgs, err := client.XRevRangeN(ctx, "stream", "+", "-", 2).Result()
6425 Expect(err).NotTo(HaveOccurred())
6426 Expect(msgs).To(Equal([]redis.XMessage{
6427 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6428 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6429 }))
6430
6431 msgs, err = client.XRevRangeN(ctx, "stream", "+", "2", 1).Result()
6432 Expect(err).NotTo(HaveOccurred())
6433 Expect(msgs).To(Equal([]redis.XMessage{
6434 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6435 }))
6436 })
6437
6438 It("should XRead", func() {
6439 res, err := client.XReadStreams(ctx, "stream", "0").Result()
6440 Expect(err).NotTo(HaveOccurred())
6441 Expect(res).To(Equal([]redis.XStream{
6442 {
6443 Stream: "stream",
6444 Messages: []redis.XMessage{
6445 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6446 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6447 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6448 },
6449 },
6450 }))
6451
6452 _, err = client.XReadStreams(ctx, "stream", "3").Result()
6453 Expect(err).To(Equal(redis.Nil))
6454 })
6455
6456 It("should XRead", func() {
6457 res, err := client.XRead(ctx, &redis.XReadArgs{
6458 Streams: []string{"stream", "0"},
6459 Count: 2,
6460 Block: 100 * time.Millisecond,
6461 }).Result()
6462 Expect(err).NotTo(HaveOccurred())
6463 Expect(res).To(Equal([]redis.XStream{
6464 {
6465 Stream: "stream",
6466 Messages: []redis.XMessage{
6467 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6468 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6469 },
6470 },
6471 }))
6472
6473 _, err = client.XRead(ctx, &redis.XReadArgs{
6474 Streams: []string{"stream", "3"},
6475 Count: 1,
6476 Block: 100 * time.Millisecond,
6477 }).Result()
6478 Expect(err).To(Equal(redis.Nil))
6479 })
6480
6481 It("should XRead LastEntry", Label("NonRedisEnterprise"), func() {
6482 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
6483 res, err := client.XRead(ctx, &redis.XReadArgs{
6484 Streams: []string{"stream"},
6485 Count: 2,
6486 ID: "+",
6487 }).Result()
6488 Expect(err).NotTo(HaveOccurred())
6489 Expect(res).To(Equal([]redis.XStream{
6490 {
6491 Stream: "stream",
6492 Messages: []redis.XMessage{
6493 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6494 },
6495 },
6496 }))
6497 })
6498
6499 It("should XRead LastEntry from two streams", Label("NonRedisEnterprise"), func() {
6500 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
6501 res, err := client.XRead(ctx, &redis.XReadArgs{
6502 Streams: []string{"stream", "stream"},
6503 ID: "+",
6504 }).Result()
6505 Expect(err).NotTo(HaveOccurred())
6506 Expect(res).To(Equal([]redis.XStream{
6507 {
6508 Stream: "stream",
6509 Messages: []redis.XMessage{
6510 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6511 },
6512 },
6513 {
6514 Stream: "stream",
6515 Messages: []redis.XMessage{
6516 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6517 },
6518 },
6519 }))
6520 })
6521
6522 It("should XRead LastEntry blocks", Label("NonRedisEnterprise"), func() {
6523 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
6524 start := time.Now()
6525 go func() {
6526 defer GinkgoRecover()
6527
6528 time.Sleep(100 * time.Millisecond)
6529 id, err := client.XAdd(ctx, &redis.XAddArgs{
6530 Stream: "empty",
6531 ID: "4-0",
6532 Values: map[string]interface{}{"quatro": "quatre"},
6533 }).Result()
6534 Expect(err).NotTo(HaveOccurred())
6535 Expect(id).To(Equal("4-0"))
6536 }()
6537
6538 res, err := client.XRead(ctx, &redis.XReadArgs{
6539 Streams: []string{"empty"},
6540 Block: 500 * time.Millisecond,
6541 ID: "+",
6542 }).Result()
6543 Expect(err).NotTo(HaveOccurred())
6544
6545 Expect(time.Since(start)).To(BeNumerically(">=", 100*time.Millisecond))
6546 Expect(res).To(Equal([]redis.XStream{
6547 {
6548 Stream: "empty",
6549 Messages: []redis.XMessage{
6550 {ID: "4-0", Values: map[string]interface{}{"quatro": "quatre"}},
6551 },
6552 },
6553 }))
6554 })
6555
6556 Describe("group", func() {
6557 BeforeEach(func() {
6558 err := client.XGroupCreate(ctx, "stream", "group", "0").Err()
6559 Expect(err).NotTo(HaveOccurred())
6560
6561 res, err := client.XReadGroup(ctx, &redis.XReadGroupArgs{
6562 Group: "group",
6563 Consumer: "consumer",
6564 Streams: []string{"stream", ">"},
6565 }).Result()
6566 Expect(err).NotTo(HaveOccurred())
6567 Expect(res).To(Equal([]redis.XStream{
6568 {
6569 Stream: "stream",
6570 Messages: []redis.XMessage{
6571 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6572 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6573 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6574 },
6575 },
6576 }))
6577 })
6578
6579 AfterEach(func() {
6580 n, err := client.XGroupDestroy(ctx, "stream", "group").Result()
6581 Expect(err).NotTo(HaveOccurred())
6582 Expect(n).To(Equal(int64(1)))
6583 })
6584
6585 It("should XReadGroup skip empty", func() {
6586 n, err := client.XDel(ctx, "stream", "2-0").Result()
6587 Expect(err).NotTo(HaveOccurred())
6588 Expect(n).To(Equal(int64(1)))
6589
6590 res, err := client.XReadGroup(ctx, &redis.XReadGroupArgs{
6591 Group: "group",
6592 Consumer: "consumer",
6593 Streams: []string{"stream", "0"},
6594 }).Result()
6595 Expect(err).NotTo(HaveOccurred())
6596 Expect(res).To(Equal([]redis.XStream{
6597 {
6598 Stream: "stream",
6599 Messages: []redis.XMessage{
6600 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6601 {ID: "2-0", Values: nil},
6602 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6603 },
6604 },
6605 }))
6606 })
6607
6608 It("should XGroupCreateMkStream", func() {
6609 err := client.XGroupCreateMkStream(ctx, "stream2", "group", "0").Err()
6610 Expect(err).NotTo(HaveOccurred())
6611
6612 err = client.XGroupCreateMkStream(ctx, "stream2", "group", "0").Err()
6613 Expect(err).To(Equal(proto.RedisError("BUSYGROUP Consumer Group name already exists")))
6614
6615 n, err := client.XGroupDestroy(ctx, "stream2", "group").Result()
6616 Expect(err).NotTo(HaveOccurred())
6617 Expect(n).To(Equal(int64(1)))
6618
6619 n, err = client.Del(ctx, "stream2").Result()
6620 Expect(err).NotTo(HaveOccurred())
6621 Expect(n).To(Equal(int64(1)))
6622 })
6623
6624 It("should XPending", func() {
6625 info, err := client.XPending(ctx, "stream", "group").Result()
6626 Expect(err).NotTo(HaveOccurred())
6627 Expect(info).To(Equal(&redis.XPending{
6628 Count: 3,
6629 Lower: "1-0",
6630 Higher: "3-0",
6631 Consumers: map[string]int64{"consumer": 3},
6632 }))
6633 args := &redis.XPendingExtArgs{
6634 Stream: "stream",
6635 Group: "group",
6636 Start: "-",
6637 End: "+",
6638 Count: 10,
6639 Consumer: "consumer",
6640 }
6641 infoExt, err := client.XPendingExt(ctx, args).Result()
6642 Expect(err).NotTo(HaveOccurred())
6643 for i := range infoExt {
6644 infoExt[i].Idle = 0
6645 }
6646 Expect(infoExt).To(Equal([]redis.XPendingExt{
6647 {ID: "1-0", Consumer: "consumer", Idle: 0, RetryCount: 1},
6648 {ID: "2-0", Consumer: "consumer", Idle: 0, RetryCount: 1},
6649 {ID: "3-0", Consumer: "consumer", Idle: 0, RetryCount: 1},
6650 }))
6651
6652 args.Idle = 72 * time.Hour
6653 infoExt, err = client.XPendingExt(ctx, args).Result()
6654 Expect(err).NotTo(HaveOccurred())
6655 Expect(infoExt).To(HaveLen(0))
6656 })
6657
6658 It("should XGroup Create Delete Consumer", func() {
6659 n, err := client.XGroupCreateConsumer(ctx, "stream", "group", "c1").Result()
6660 Expect(err).NotTo(HaveOccurred())
6661 Expect(n).To(Equal(int64(1)))
6662
6663 n, err = client.XGroupDelConsumer(ctx, "stream", "group", "consumer").Result()
6664 Expect(err).NotTo(HaveOccurred())
6665 Expect(n).To(Equal(int64(3)))
6666 })
6667
6668 It("should XAutoClaim", func() {
6669 xca := &redis.XAutoClaimArgs{
6670 Stream: "stream",
6671 Group: "group",
6672 Consumer: "consumer",
6673 Start: "-",
6674 Count: 2,
6675 }
6676 msgs, start, err := client.XAutoClaim(ctx, xca).Result()
6677 Expect(err).NotTo(HaveOccurred())
6678 Expect(start).To(Equal("3-0"))
6679 Expect(msgs).To(Equal([]redis.XMessage{{
6680 ID: "1-0",
6681 Values: map[string]interface{}{"uno": "un"},
6682 }, {
6683 ID: "2-0",
6684 Values: map[string]interface{}{"dos": "deux"},
6685 }}))
6686
6687 xca.Start = start
6688 msgs, start, err = client.XAutoClaim(ctx, xca).Result()
6689 Expect(err).NotTo(HaveOccurred())
6690 Expect(start).To(Equal("0-0"))
6691 Expect(msgs).To(Equal([]redis.XMessage{{
6692 ID: "3-0",
6693 Values: map[string]interface{}{"tres": "troix"},
6694 }}))
6695
6696 ids, start, err := client.XAutoClaimJustID(ctx, xca).Result()
6697 Expect(err).NotTo(HaveOccurred())
6698 Expect(start).To(Equal("0-0"))
6699 Expect(ids).To(Equal([]string{"3-0"}))
6700 })
6701
6702 It("should XClaim", func() {
6703 msgs, err := client.XClaim(ctx, &redis.XClaimArgs{
6704 Stream: "stream",
6705 Group: "group",
6706 Consumer: "consumer",
6707 Messages: []string{"1-0", "2-0", "3-0"},
6708 }).Result()
6709 Expect(err).NotTo(HaveOccurred())
6710 Expect(msgs).To(Equal([]redis.XMessage{{
6711 ID: "1-0",
6712 Values: map[string]interface{}{"uno": "un"},
6713 }, {
6714 ID: "2-0",
6715 Values: map[string]interface{}{"dos": "deux"},
6716 }, {
6717 ID: "3-0",
6718 Values: map[string]interface{}{"tres": "troix"},
6719 }}))
6720
6721 ids, err := client.XClaimJustID(ctx, &redis.XClaimArgs{
6722 Stream: "stream",
6723 Group: "group",
6724 Consumer: "consumer",
6725 Messages: []string{"1-0", "2-0", "3-0"},
6726 }).Result()
6727 Expect(err).NotTo(HaveOccurred())
6728 Expect(ids).To(Equal([]string{"1-0", "2-0", "3-0"}))
6729 })
6730
6731 It("should XAck", func() {
6732 n, err := client.XAck(ctx, "stream", "group", "1-0", "2-0", "4-0").Result()
6733 Expect(err).NotTo(HaveOccurred())
6734 Expect(n).To(Equal(int64(2)))
6735 })
6736 })
6737
6738 Describe("xinfo", func() {
6739 BeforeEach(func() {
6740 err := client.XGroupCreate(ctx, "stream", "group1", "0").Err()
6741 Expect(err).NotTo(HaveOccurred())
6742
6743 res, err := client.XReadGroup(ctx, &redis.XReadGroupArgs{
6744 Group: "group1",
6745 Consumer: "consumer1",
6746 Streams: []string{"stream", ">"},
6747 Count: 2,
6748 }).Result()
6749 Expect(err).NotTo(HaveOccurred())
6750 Expect(res).To(Equal([]redis.XStream{
6751 {
6752 Stream: "stream",
6753 Messages: []redis.XMessage{
6754 {ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
6755 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6756 },
6757 },
6758 }))
6759
6760 res, err = client.XReadGroup(ctx, &redis.XReadGroupArgs{
6761 Group: "group1",
6762 Consumer: "consumer2",
6763 Streams: []string{"stream", ">"},
6764 }).Result()
6765 Expect(err).NotTo(HaveOccurred())
6766 Expect(res).To(Equal([]redis.XStream{
6767 {
6768 Stream: "stream",
6769 Messages: []redis.XMessage{
6770 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6771 },
6772 },
6773 }))
6774
6775 err = client.XGroupCreate(ctx, "stream", "group2", "1-0").Err()
6776 Expect(err).NotTo(HaveOccurred())
6777
6778 res, err = client.XReadGroup(ctx, &redis.XReadGroupArgs{
6779 Group: "group2",
6780 Consumer: "consumer1",
6781 Streams: []string{"stream", ">"},
6782 }).Result()
6783 Expect(err).NotTo(HaveOccurred())
6784 Expect(res).To(Equal([]redis.XStream{
6785 {
6786 Stream: "stream",
6787 Messages: []redis.XMessage{
6788 {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
6789 {ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
6790 },
6791 },
6792 }))
6793 })
6794
6795 AfterEach(func() {
6796 n, err := client.XGroupDestroy(ctx, "stream", "group1").Result()
6797 Expect(err).NotTo(HaveOccurred())
6798 Expect(n).To(Equal(int64(1)))
6799 n, err = client.XGroupDestroy(ctx, "stream", "group2").Result()
6800 Expect(err).NotTo(HaveOccurred())
6801 Expect(n).To(Equal(int64(1)))
6802 })
6803
6804 It("should XINFO STREAM", func() {
6805 res, err := client.XInfoStream(ctx, "stream").Result()
6806 Expect(err).NotTo(HaveOccurred())
6807 res.RadixTreeKeys = 0
6808 res.RadixTreeNodes = 0
6809
6810 Expect(res).To(Equal(&redis.XInfoStream{
6811 Length: 3,
6812 RadixTreeKeys: 0,
6813 RadixTreeNodes: 0,
6814 Groups: 2,
6815 LastGeneratedID: "3-0",
6816 MaxDeletedEntryID: "0-0",
6817 EntriesAdded: 3,
6818 FirstEntry: redis.XMessage{
6819 ID: "1-0",
6820 Values: map[string]interface{}{"uno": "un"},
6821 },
6822 LastEntry: redis.XMessage{
6823 ID: "3-0",
6824 Values: map[string]interface{}{"tres": "troix"},
6825 },
6826 RecordedFirstEntryID: "1-0",
6827 }))
6828
6829
6830 n, err := client.XDel(ctx, "stream", "1-0", "2-0", "3-0").Result()
6831 Expect(err).NotTo(HaveOccurred())
6832 Expect(n).To(Equal(int64(3)))
6833
6834 res, err = client.XInfoStream(ctx, "stream").Result()
6835 Expect(err).NotTo(HaveOccurred())
6836 res.RadixTreeKeys = 0
6837 res.RadixTreeNodes = 0
6838
6839 Expect(res).To(Equal(&redis.XInfoStream{
6840 Length: 0,
6841 RadixTreeKeys: 0,
6842 RadixTreeNodes: 0,
6843 Groups: 2,
6844 LastGeneratedID: "3-0",
6845 MaxDeletedEntryID: "3-0",
6846 EntriesAdded: 3,
6847 FirstEntry: redis.XMessage{},
6848 LastEntry: redis.XMessage{},
6849 RecordedFirstEntryID: "0-0",
6850 }))
6851 })
6852
6853 It("should XINFO STREAM FULL", func() {
6854 res, err := client.XInfoStreamFull(ctx, "stream", 2).Result()
6855 Expect(err).NotTo(HaveOccurred())
6856 res.RadixTreeKeys = 0
6857 res.RadixTreeNodes = 0
6858
6859
6860 now := time.Now()
6861 maxElapsed := 10 * time.Minute
6862 for k, g := range res.Groups {
6863 for k2, p := range g.Pending {
6864 Expect(now.Sub(p.DeliveryTime)).To(BeNumerically("<=", maxElapsed))
6865 res.Groups[k].Pending[k2].DeliveryTime = time.Time{}
6866 }
6867 for k3, c := range g.Consumers {
6868 Expect(now.Sub(c.SeenTime)).To(BeNumerically("<=", maxElapsed))
6869 Expect(now.Sub(c.ActiveTime)).To(BeNumerically("<=", maxElapsed))
6870 res.Groups[k].Consumers[k3].SeenTime = time.Time{}
6871 res.Groups[k].Consumers[k3].ActiveTime = time.Time{}
6872
6873 for k4, p := range c.Pending {
6874 Expect(now.Sub(p.DeliveryTime)).To(BeNumerically("<=", maxElapsed))
6875 res.Groups[k].Consumers[k3].Pending[k4].DeliveryTime = time.Time{}
6876 }
6877 }
6878 }
6879
6880 Expect(res.Groups).To(Equal([]redis.XInfoStreamGroup{
6881 {
6882 Name: "group1",
6883 LastDeliveredID: "3-0",
6884 EntriesRead: 3,
6885 Lag: 0,
6886 PelCount: 3,
6887 Pending: []redis.XInfoStreamGroupPending{
6888 {ID: "1-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
6889 {ID: "2-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
6890 },
6891 Consumers: []redis.XInfoStreamConsumer{
6892 {
6893 Name: "consumer1",
6894 SeenTime: time.Time{},
6895 ActiveTime: time.Time{},
6896 PelCount: 2,
6897 Pending: []redis.XInfoStreamConsumerPending{
6898 {ID: "1-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
6899 {ID: "2-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
6900 },
6901 },
6902 {
6903 Name: "consumer2",
6904 SeenTime: time.Time{},
6905 ActiveTime: time.Time{},
6906 PelCount: 1,
6907 Pending: []redis.XInfoStreamConsumerPending{
6908 {ID: "3-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
6909 },
6910 },
6911 },
6912 },
6913 {
6914 Name: "group2",
6915 LastDeliveredID: "3-0",
6916 EntriesRead: 3,
6917 Lag: 0,
6918 PelCount: 2,
6919 Pending: []redis.XInfoStreamGroupPending{
6920 {ID: "2-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
6921 {ID: "3-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
6922 },
6923 Consumers: []redis.XInfoStreamConsumer{
6924 {
6925 Name: "consumer1",
6926 SeenTime: time.Time{},
6927 ActiveTime: time.Time{},
6928 PelCount: 2,
6929 Pending: []redis.XInfoStreamConsumerPending{
6930 {ID: "2-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
6931 {ID: "3-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
6932 },
6933 },
6934 },
6935 },
6936 }))
6937
6938
6939 Expect(client.Del(ctx, "xinfo-stream-full-stream").Err()).NotTo(HaveOccurred())
6940 id, err := client.XAdd(ctx, &redis.XAddArgs{
6941 Stream: "xinfo-stream-full-stream",
6942 ID: "*",
6943 Values: []any{"k1", "v1"},
6944 }).Result()
6945 Expect(err).NotTo(HaveOccurred())
6946 Expect(client.XGroupCreateMkStream(ctx, "xinfo-stream-full-stream", "xinfo-stream-full-group", "0").Err()).NotTo(HaveOccurred())
6947 res, err = client.XInfoStreamFull(ctx, "xinfo-stream-full-stream", 0).Result()
6948 Expect(err).NotTo(HaveOccurred())
6949 Expect(res).To(Equal(&redis.XInfoStreamFull{
6950 Length: 1,
6951 RadixTreeKeys: 1,
6952 RadixTreeNodes: 2,
6953 LastGeneratedID: id,
6954 MaxDeletedEntryID: "0-0",
6955 EntriesAdded: 1,
6956 Entries: []redis.XMessage{{ID: id, Values: map[string]any{"k1": "v1"}}},
6957 Groups: []redis.XInfoStreamGroup{
6958 {
6959 Name: "xinfo-stream-full-group",
6960 LastDeliveredID: "0-0",
6961 EntriesRead: 0,
6962 Lag: 1,
6963 PelCount: 0,
6964 Pending: []redis.XInfoStreamGroupPending{},
6965 Consumers: []redis.XInfoStreamConsumer{},
6966 },
6967 },
6968 RecordedFirstEntryID: id,
6969 }))
6970 })
6971
6972 It("should XINFO GROUPS", func() {
6973 res, err := client.XInfoGroups(ctx, "stream").Result()
6974 Expect(err).NotTo(HaveOccurred())
6975 Expect(res).To(Equal([]redis.XInfoGroup{
6976 {Name: "group1", Consumers: 2, Pending: 3, LastDeliveredID: "3-0", EntriesRead: 3},
6977 {Name: "group2", Consumers: 1, Pending: 2, LastDeliveredID: "3-0", EntriesRead: 3},
6978 }))
6979 })
6980
6981 It("should return -1 for nil lag in XINFO GROUPS", func() {
6982 _, err := client.XAdd(ctx, &redis.XAddArgs{Stream: "s", ID: "0-1", Values: []string{"foo", "1"}}).Result()
6983 Expect(err).NotTo(HaveOccurred())
6984
6985 client.XAdd(ctx, &redis.XAddArgs{Stream: "s", ID: "0-2", Values: []string{"foo", "2"}})
6986 Expect(err).NotTo(HaveOccurred())
6987 client.XAdd(ctx, &redis.XAddArgs{Stream: "s", ID: "0-3", Values: []string{"foo", "3"}})
6988 Expect(err).NotTo(HaveOccurred())
6989
6990 err = client.XGroupCreate(ctx, "s", "g", "0").Err()
6991 Expect(err).NotTo(HaveOccurred())
6992 err = client.XReadGroup(ctx, &redis.XReadGroupArgs{Group: "g", Consumer: "c", Streams: []string{"s", ">"}, Count: 1, Block: -1, NoAck: false}).Err()
6993 Expect(err).NotTo(HaveOccurred())
6994
6995 client.XDel(ctx, "s", "0-2")
6996
6997 res, err := client.XInfoGroups(ctx, "s").Result()
6998 Expect(err).NotTo(HaveOccurred())
6999 Expect(res).To(Equal([]redis.XInfoGroup{
7000 {
7001 Name: "g",
7002 Consumers: 1,
7003 Pending: 1,
7004 LastDeliveredID: "0-1",
7005 EntriesRead: 1,
7006 Lag: -1,
7007 },
7008 }))
7009 })
7010
7011 It("should XINFO CONSUMERS", func() {
7012 res, err := client.XInfoConsumers(ctx, "stream", "group1").Result()
7013 Expect(err).NotTo(HaveOccurred())
7014 for i := range res {
7015 res[i].Idle = 0
7016 res[i].Inactive = 0
7017 }
7018
7019 Expect(res).To(Equal([]redis.XInfoConsumer{
7020 {Name: "consumer1", Pending: 2, Idle: 0, Inactive: 0},
7021 {Name: "consumer2", Pending: 1, Idle: 0, Inactive: 0},
7022 }))
7023 })
7024 })
7025 })
7026
7027 Describe("Geo add and radius search", func() {
7028 BeforeEach(func() {
7029 n, err := client.GeoAdd(
7030 ctx,
7031 "Sicily",
7032 &redis.GeoLocation{Longitude: 13.361389, Latitude: 38.115556, Name: "Palermo"},
7033 &redis.GeoLocation{Longitude: 15.087269, Latitude: 37.502669, Name: "Catania"},
7034 ).Result()
7035 Expect(err).NotTo(HaveOccurred())
7036 Expect(n).To(Equal(int64(2)))
7037 })
7038
7039 It("should not add same geo location", func() {
7040 geoAdd := client.GeoAdd(
7041 ctx,
7042 "Sicily",
7043 &redis.GeoLocation{Longitude: 13.361389, Latitude: 38.115556, Name: "Palermo"},
7044 )
7045 Expect(geoAdd.Err()).NotTo(HaveOccurred())
7046 Expect(geoAdd.Val()).To(Equal(int64(0)))
7047 })
7048
7049 It("should search geo radius", func() {
7050 res, err := client.GeoRadius(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
7051 Radius: 200,
7052 }).Result()
7053 Expect(err).NotTo(HaveOccurred())
7054 Expect(res).To(HaveLen(2))
7055 Expect(res[0].Name).To(Equal("Palermo"))
7056 Expect(res[1].Name).To(Equal("Catania"))
7057 })
7058
7059 It("should geo radius and store the result", Label("NonRedisEnterprise"), func() {
7060 n, err := client.GeoRadiusStore(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
7061 Radius: 200,
7062 Store: "result",
7063 }).Result()
7064 Expect(err).NotTo(HaveOccurred())
7065 Expect(n).To(Equal(int64(2)))
7066
7067 res, err := client.ZRangeWithScores(ctx, "result", 0, -1).Result()
7068 Expect(err).NotTo(HaveOccurred())
7069 Expect(res).To(ContainElement(redis.Z{
7070 Score: 3.479099956230698e+15,
7071 Member: "Palermo",
7072 }))
7073 Expect(res).To(ContainElement(redis.Z{
7074 Score: 3.479447370796909e+15,
7075 Member: "Catania",
7076 }))
7077 })
7078
7079 It("should geo radius and store dist", Label("NonRedisEnterprise"), func() {
7080 n, err := client.GeoRadiusStore(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
7081 Radius: 200,
7082 StoreDist: "result",
7083 }).Result()
7084 Expect(err).NotTo(HaveOccurred())
7085 Expect(n).To(Equal(int64(2)))
7086
7087 res, err := client.ZRangeWithScores(ctx, "result", 0, -1).Result()
7088 Expect(err).NotTo(HaveOccurred())
7089 Expect(len(res)).To(Equal(2))
7090 var palermo, catania redis.Z
7091 Expect(res).To(ContainElement(HaveField("Member", "Palermo"), &palermo))
7092 Expect(res).To(ContainElement(HaveField("Member", "Catania"), &catania))
7093 Expect(palermo.Score).To(BeNumerically("~", 190, 1))
7094 Expect(catania.Score).To(BeNumerically("~", 56, 1))
7095 })
7096
7097 It("should search geo radius with options", func() {
7098 res, err := client.GeoRadius(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
7099 Radius: 200,
7100 Unit: "km",
7101 WithGeoHash: true,
7102 WithCoord: true,
7103 WithDist: true,
7104 Count: 2,
7105 Sort: "ASC",
7106 }).Result()
7107 Expect(err).NotTo(HaveOccurred())
7108 Expect(res).To(HaveLen(2))
7109 Expect(res[1].Name).To(Equal("Palermo"))
7110 Expect(res[1].Dist).To(Equal(190.4424))
7111 Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
7112 Expect(res[1].Longitude).To(Equal(13.361389338970184))
7113 Expect(res[1].Latitude).To(Equal(38.115556395496299))
7114 Expect(res[0].Name).To(Equal("Catania"))
7115 Expect(res[0].Dist).To(Equal(56.4413))
7116 Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
7117 Expect(res[0].Longitude).To(Equal(15.087267458438873))
7118 Expect(res[0].Latitude).To(Equal(37.50266842333162))
7119 })
7120
7121 It("should search geo radius with WithDist=false", func() {
7122 res, err := client.GeoRadius(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
7123 Radius: 200,
7124 Unit: "km",
7125 WithGeoHash: true,
7126 WithCoord: true,
7127 Count: 2,
7128 Sort: "ASC",
7129 }).Result()
7130 Expect(err).NotTo(HaveOccurred())
7131 Expect(res).To(HaveLen(2))
7132 Expect(res[1].Name).To(Equal("Palermo"))
7133 Expect(res[1].Dist).To(Equal(float64(0)))
7134 Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
7135 Expect(res[1].Longitude).To(Equal(13.361389338970184))
7136 Expect(res[1].Latitude).To(Equal(38.115556395496299))
7137 Expect(res[0].Name).To(Equal("Catania"))
7138 Expect(res[0].Dist).To(Equal(float64(0)))
7139 Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
7140 Expect(res[0].Longitude).To(Equal(15.087267458438873))
7141 Expect(res[0].Latitude).To(Equal(37.50266842333162))
7142 })
7143
7144 It("should search geo radius by member with options", func() {
7145 res, err := client.GeoRadiusByMember(ctx, "Sicily", "Catania", &redis.GeoRadiusQuery{
7146 Radius: 200,
7147 Unit: "km",
7148 WithGeoHash: true,
7149 WithCoord: true,
7150 WithDist: true,
7151 Count: 2,
7152 Sort: "ASC",
7153 }).Result()
7154 Expect(err).NotTo(HaveOccurred())
7155 Expect(res).To(HaveLen(2))
7156 Expect(res[0].Name).To(Equal("Catania"))
7157 Expect(res[0].Dist).To(Equal(0.0))
7158 Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
7159 Expect(res[0].Longitude).To(Equal(15.087267458438873))
7160 Expect(res[0].Latitude).To(Equal(37.50266842333162))
7161 Expect(res[1].Name).To(Equal("Palermo"))
7162 Expect(res[1].Dist).To(Equal(166.2742))
7163 Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
7164 Expect(res[1].Longitude).To(Equal(13.361389338970184))
7165 Expect(res[1].Latitude).To(Equal(38.115556395496299))
7166 })
7167
7168 It("should search geo radius with no results", func() {
7169 res, err := client.GeoRadius(ctx, "Sicily", 99, 37, &redis.GeoRadiusQuery{
7170 Radius: 200,
7171 Unit: "km",
7172 WithGeoHash: true,
7173 WithCoord: true,
7174 WithDist: true,
7175 }).Result()
7176 Expect(err).NotTo(HaveOccurred())
7177 Expect(res).To(HaveLen(0))
7178 })
7179
7180 It("should get geo distance with unit options", func() {
7181
7182
7183
7184
7185
7186
7187
7188
7189 dist, err := client.GeoDist(ctx, "Sicily", "Palermo", "Catania", "km").Result()
7190 Expect(err).NotTo(HaveOccurred())
7191 Expect(dist).To(BeNumerically("~", 166.27, 0.01))
7192
7193 dist, err = client.GeoDist(ctx, "Sicily", "Palermo", "Catania", "m").Result()
7194 Expect(err).NotTo(HaveOccurred())
7195 Expect(dist).To(BeNumerically("~", 166274.15, 0.01))
7196 })
7197
7198 It("should get geo hash in string representation", func() {
7199 hashes, err := client.GeoHash(ctx, "Sicily", "Palermo", "Catania").Result()
7200 Expect(err).NotTo(HaveOccurred())
7201 Expect(hashes).To(ConsistOf([]string{"sqc8b49rny0", "sqdtr74hyu0"}))
7202 })
7203
7204 It("should return geo position", func() {
7205 pos, err := client.GeoPos(ctx, "Sicily", "Palermo", "Catania", "NonExisting").Result()
7206 Expect(err).NotTo(HaveOccurred())
7207 Expect(pos).To(ConsistOf([]*redis.GeoPos{
7208 {
7209 Longitude: 13.361389338970184,
7210 Latitude: 38.1155563954963,
7211 },
7212 {
7213 Longitude: 15.087267458438873,
7214 Latitude: 37.50266842333162,
7215 },
7216 nil,
7217 }))
7218 })
7219
7220 It("should geo search", func() {
7221 q := &redis.GeoSearchQuery{
7222 Member: "Catania",
7223 BoxWidth: 400,
7224 BoxHeight: 100,
7225 BoxUnit: "km",
7226 Sort: "asc",
7227 }
7228 val, err := client.GeoSearch(ctx, "Sicily", q).Result()
7229 Expect(err).NotTo(HaveOccurred())
7230 Expect(val).To(Equal([]string{"Catania"}))
7231
7232 q.BoxHeight = 400
7233 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7234 Expect(err).NotTo(HaveOccurred())
7235 Expect(val).To(Equal([]string{"Catania", "Palermo"}))
7236
7237 q.Count = 1
7238 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7239 Expect(err).NotTo(HaveOccurred())
7240 Expect(val).To(Equal([]string{"Catania"}))
7241
7242 q.CountAny = true
7243 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7244 Expect(err).NotTo(HaveOccurred())
7245 Expect(val).To(Equal([]string{"Palermo"}))
7246
7247 q = &redis.GeoSearchQuery{
7248 Member: "Catania",
7249 Radius: 100,
7250 RadiusUnit: "km",
7251 Sort: "asc",
7252 }
7253 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7254 Expect(err).NotTo(HaveOccurred())
7255 Expect(val).To(Equal([]string{"Catania"}))
7256
7257 q.Radius = 400
7258 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7259 Expect(err).NotTo(HaveOccurred())
7260 Expect(val).To(Equal([]string{"Catania", "Palermo"}))
7261
7262 q.Count = 1
7263 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7264 Expect(err).NotTo(HaveOccurred())
7265 Expect(val).To(Equal([]string{"Catania"}))
7266
7267 q.CountAny = true
7268 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7269 Expect(err).NotTo(HaveOccurred())
7270 Expect(val).To(Equal([]string{"Palermo"}))
7271
7272 q = &redis.GeoSearchQuery{
7273 Longitude: 15,
7274 Latitude: 37,
7275 BoxWidth: 200,
7276 BoxHeight: 200,
7277 BoxUnit: "km",
7278 Sort: "asc",
7279 }
7280 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7281 Expect(err).NotTo(HaveOccurred())
7282 Expect(val).To(Equal([]string{"Catania"}))
7283
7284 q.BoxWidth, q.BoxHeight = 400, 400
7285 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7286 Expect(err).NotTo(HaveOccurred())
7287 Expect(val).To(Equal([]string{"Catania", "Palermo"}))
7288
7289 q.Count = 1
7290 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7291 Expect(err).NotTo(HaveOccurred())
7292 Expect(val).To(Equal([]string{"Catania"}))
7293
7294 q.CountAny = true
7295 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7296 Expect(err).NotTo(HaveOccurred())
7297 Expect(val).To(Equal([]string{"Palermo"}))
7298
7299 q = &redis.GeoSearchQuery{
7300 Longitude: 15,
7301 Latitude: 37,
7302 Radius: 100,
7303 RadiusUnit: "km",
7304 Sort: "asc",
7305 }
7306 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7307 Expect(err).NotTo(HaveOccurred())
7308 Expect(val).To(Equal([]string{"Catania"}))
7309
7310 q.Radius = 200
7311 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7312 Expect(err).NotTo(HaveOccurred())
7313 Expect(val).To(Equal([]string{"Catania", "Palermo"}))
7314
7315 q.Count = 1
7316 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7317 Expect(err).NotTo(HaveOccurred())
7318 Expect(val).To(Equal([]string{"Catania"}))
7319
7320 q.CountAny = true
7321 val, err = client.GeoSearch(ctx, "Sicily", q).Result()
7322 Expect(err).NotTo(HaveOccurred())
7323 Expect(val).To(Equal([]string{"Palermo"}))
7324 })
7325
7326 It("should geo search with options", func() {
7327 q := &redis.GeoSearchLocationQuery{
7328 GeoSearchQuery: redis.GeoSearchQuery{
7329 Longitude: 15,
7330 Latitude: 37,
7331 Radius: 200,
7332 RadiusUnit: "km",
7333 Sort: "asc",
7334 },
7335 WithHash: true,
7336 WithDist: true,
7337 WithCoord: true,
7338 }
7339 val, err := client.GeoSearchLocation(ctx, "Sicily", q).Result()
7340 Expect(err).NotTo(HaveOccurred())
7341 Expect(val).To(Equal([]redis.GeoLocation{
7342 {
7343 Name: "Catania",
7344 Longitude: 15.08726745843887329,
7345 Latitude: 37.50266842333162032,
7346 Dist: 56.4413,
7347 GeoHash: 3479447370796909,
7348 },
7349 {
7350 Name: "Palermo",
7351 Longitude: 13.36138933897018433,
7352 Latitude: 38.11555639549629859,
7353 Dist: 190.4424,
7354 GeoHash: 3479099956230698,
7355 },
7356 }))
7357 })
7358
7359 It("should geo search store", Label("NonRedisEnterprise"), func() {
7360 q := &redis.GeoSearchStoreQuery{
7361 GeoSearchQuery: redis.GeoSearchQuery{
7362 Longitude: 15,
7363 Latitude: 37,
7364 Radius: 200,
7365 RadiusUnit: "km",
7366 Sort: "asc",
7367 },
7368 StoreDist: false,
7369 }
7370
7371 val, err := client.GeoSearchStore(ctx, "Sicily", "key1", q).Result()
7372 Expect(err).NotTo(HaveOccurred())
7373 Expect(val).To(Equal(int64(2)))
7374
7375 q.StoreDist = true
7376 val, err = client.GeoSearchStore(ctx, "Sicily", "key2", q).Result()
7377 Expect(err).NotTo(HaveOccurred())
7378 Expect(val).To(Equal(int64(2)))
7379
7380 loc, err := client.GeoSearchLocation(ctx, "key1", &redis.GeoSearchLocationQuery{
7381 GeoSearchQuery: q.GeoSearchQuery,
7382 WithCoord: true,
7383 WithDist: true,
7384 WithHash: true,
7385 }).Result()
7386 Expect(err).NotTo(HaveOccurred())
7387 Expect(loc).To(Equal([]redis.GeoLocation{
7388 {
7389 Name: "Catania",
7390 Longitude: 15.08726745843887329,
7391 Latitude: 37.50266842333162032,
7392 Dist: 56.4413,
7393 GeoHash: 3479447370796909,
7394 },
7395 {
7396 Name: "Palermo",
7397 Longitude: 13.36138933897018433,
7398 Latitude: 38.11555639549629859,
7399 Dist: 190.4424,
7400 GeoHash: 3479099956230698,
7401 },
7402 }))
7403
7404 v, err := client.ZRangeWithScores(ctx, "key2", 0, -1).Result()
7405 Expect(err).NotTo(HaveOccurred())
7406
7407 Expect(len(v)).To(Equal(2))
7408 var palermo, catania redis.Z
7409 Expect(v).To(ContainElement(HaveField("Member", "Palermo"), &palermo))
7410 Expect(v).To(ContainElement(HaveField("Member", "Catania"), &catania))
7411 Expect(palermo.Score).To(BeNumerically("~", 190, 1))
7412 Expect(catania.Score).To(BeNumerically("~", 56, 1))
7413 })
7414 })
7415
7416 Describe("marshaling/unmarshaling", func() {
7417 type convTest struct {
7418 value interface{}
7419 wanted string
7420 dest interface{}
7421 }
7422
7423 convTests := []convTest{
7424 {nil, "", nil},
7425 {"hello", "hello", new(string)},
7426 {[]byte("hello"), "hello", new([]byte)},
7427 {1, "1", new(int)},
7428 {int8(1), "1", new(int8)},
7429 {int16(1), "1", new(int16)},
7430 {int32(1), "1", new(int32)},
7431 {int64(1), "1", new(int64)},
7432 {uint(1), "1", new(uint)},
7433 {uint8(1), "1", new(uint8)},
7434 {uint16(1), "1", new(uint16)},
7435 {uint32(1), "1", new(uint32)},
7436 {uint64(1), "1", new(uint64)},
7437 {float32(1.0), "1", new(float32)},
7438 {1.0, "1", new(float64)},
7439 {true, "1", new(bool)},
7440 {false, "0", new(bool)},
7441 }
7442
7443 It("should convert to string", func() {
7444 for _, test := range convTests {
7445 err := client.Set(ctx, "key", test.value, 0).Err()
7446 Expect(err).NotTo(HaveOccurred())
7447
7448 s, err := client.Get(ctx, "key").Result()
7449 Expect(err).NotTo(HaveOccurred())
7450 Expect(s).To(Equal(test.wanted))
7451
7452 if test.dest == nil {
7453 continue
7454 }
7455
7456 err = client.Get(ctx, "key").Scan(test.dest)
7457 Expect(err).NotTo(HaveOccurred())
7458 Expect(deref(test.dest)).To(Equal(test.value))
7459 }
7460 })
7461 })
7462
7463 Describe("json marshaling/unmarshaling", func() {
7464 BeforeEach(func() {
7465 value := &numberStruct{Number: 42}
7466 err := client.Set(ctx, "key", value, 0).Err()
7467 Expect(err).NotTo(HaveOccurred())
7468 })
7469
7470 It("should marshal custom values using json", func() {
7471 s, err := client.Get(ctx, "key").Result()
7472 Expect(err).NotTo(HaveOccurred())
7473 Expect(s).To(Equal(`{"Number":42}`))
7474 })
7475
7476 It("should scan custom values using json", func() {
7477 value := &numberStruct{}
7478 err := client.Get(ctx, "key").Scan(value)
7479 Expect(err).NotTo(HaveOccurred())
7480 Expect(value.Number).To(Equal(42))
7481 })
7482 })
7483
7484 Describe("Eval", func() {
7485 It("returns keys and values", func() {
7486 vals, err := client.Eval(
7487 ctx,
7488 "return {KEYS[1],ARGV[1]}",
7489 []string{"key"},
7490 "hello",
7491 ).Result()
7492 Expect(err).NotTo(HaveOccurred())
7493 Expect(vals).To(Equal([]interface{}{"key", "hello"}))
7494 })
7495
7496 It("returns all values after an error", func() {
7497 vals, err := client.Eval(
7498 ctx,
7499 `return {12, {err="error"}, "abc"}`,
7500 nil,
7501 ).Result()
7502 Expect(err).NotTo(HaveOccurred())
7503 Expect(vals).To(Equal([]interface{}{int64(12), proto.RedisError("error"), "abc"}))
7504 })
7505
7506 It("returns empty values when args are nil", func() {
7507 vals, err := client.Eval(
7508 ctx,
7509 "return {ARGV[1]}",
7510 []string{},
7511 nil,
7512 ).Result()
7513 Expect(err).NotTo(HaveOccurred())
7514 Expect(vals).To(BeEmpty())
7515 })
7516 })
7517
7518 Describe("EvalRO", func() {
7519 It("returns keys and values", func() {
7520 vals, err := client.EvalRO(
7521 ctx,
7522 "return {KEYS[1],ARGV[1]}",
7523 []string{"key"},
7524 "hello",
7525 ).Result()
7526 Expect(err).NotTo(HaveOccurred())
7527 Expect(vals).To(Equal([]interface{}{"key", "hello"}))
7528 })
7529
7530 It("returns all values after an error", func() {
7531 vals, err := client.EvalRO(
7532 ctx,
7533 `return {12, {err="error"}, "abc"}`,
7534 nil,
7535 ).Result()
7536 Expect(err).NotTo(HaveOccurred())
7537 Expect(vals).To(Equal([]interface{}{int64(12), proto.RedisError("error"), "abc"}))
7538 })
7539
7540 It("returns empty values when args are nil", func() {
7541 vals, err := client.EvalRO(
7542 ctx,
7543 "return {ARGV[1]}",
7544 []string{},
7545 nil,
7546 ).Result()
7547 Expect(err).NotTo(HaveOccurred())
7548 Expect(vals).To(BeEmpty())
7549 })
7550 })
7551
7552 Describe("Functions", func() {
7553 var (
7554 q redis.FunctionListQuery
7555 lib1Code string
7556 lib2Code string
7557 lib1 redis.Library
7558 lib2 redis.Library
7559 )
7560
7561 BeforeEach(func() {
7562 flush := client.FunctionFlush(ctx)
7563 Expect(flush.Err()).NotTo(HaveOccurred())
7564
7565 lib1 = redis.Library{
7566 Name: "mylib1",
7567 Engine: "LUA",
7568 Functions: []redis.Function{
7569 {
7570 Name: "lib1_func1",
7571 Description: "This is the func-1 of lib 1",
7572 Flags: []string{"allow-oom", "allow-stale"},
7573 },
7574 },
7575 Code: `#!lua name=%s
7576
7577 local function f1(keys, args)
7578 local hash = keys[1] -- Get the key name
7579 local time = redis.call('TIME')[1] -- Get the current time from the Redis server
7580
7581 -- Add the current timestamp to the arguments that the user passed to the function, stored in args
7582 table.insert(args, '_updated_at')
7583 table.insert(args, time)
7584
7585 -- Run HSET with the updated argument list
7586 return redis.call('HSET', hash, unpack(args))
7587 end
7588
7589 redis.register_function{
7590 function_name='%s',
7591 description ='%s',
7592 callback=f1,
7593 flags={'%s', '%s'}
7594 }`,
7595 }
7596
7597 lib2 = redis.Library{
7598 Name: "mylib2",
7599 Engine: "LUA",
7600 Functions: []redis.Function{
7601 {
7602 Name: "lib2_func1",
7603 Flags: []string{},
7604 },
7605 {
7606 Name: "lib2_func2",
7607 Description: "This is the func-2 of lib 2",
7608 Flags: []string{"no-writes"},
7609 },
7610 },
7611 Code: `#!lua name=%s
7612
7613 local function f1(keys, args)
7614 return 'Function 1'
7615 end
7616
7617 local function f2(keys, args)
7618 return 'Function 2'
7619 end
7620
7621 redis.register_function('%s', f1)
7622 redis.register_function{
7623 function_name='%s',
7624 description ='%s',
7625 callback=f2,
7626 flags={'%s'}
7627 }`,
7628 }
7629
7630 lib1Code = fmt.Sprintf(lib1.Code, lib1.Name, lib1.Functions[0].Name,
7631 lib1.Functions[0].Description, lib1.Functions[0].Flags[0], lib1.Functions[0].Flags[1])
7632 lib2Code = fmt.Sprintf(lib2.Code, lib2.Name, lib2.Functions[0].Name,
7633 lib2.Functions[1].Name, lib2.Functions[1].Description, lib2.Functions[1].Flags[0])
7634
7635 q = redis.FunctionListQuery{}
7636 })
7637
7638 It("Loads a new library", Label("NonRedisEnterprise"), func() {
7639 functionLoad := client.FunctionLoad(ctx, lib1Code)
7640 Expect(functionLoad.Err()).NotTo(HaveOccurred())
7641 Expect(functionLoad.Val()).To(Equal(lib1.Name))
7642
7643 functionList := client.FunctionList(ctx, q)
7644 Expect(functionList.Err()).NotTo(HaveOccurred())
7645 Expect(functionList.Val()).To(HaveLen(1))
7646 })
7647
7648 It("Loads and replaces a new library", Label("NonRedisEnterprise"), func() {
7649
7650 err := client.FunctionLoad(ctx, lib1Code).Err()
7651 Expect(err).NotTo(HaveOccurred())
7652
7653 newFuncName := "replaces_func_name"
7654 newFuncDesc := "replaces_func_desc"
7655 flag1, flag2 := "allow-stale", "no-cluster"
7656 newCode := fmt.Sprintf(lib1.Code, lib1.Name, newFuncName, newFuncDesc, flag1, flag2)
7657
7658
7659 functionLoadReplace := client.FunctionLoadReplace(ctx, newCode)
7660 Expect(functionLoadReplace.Err()).NotTo(HaveOccurred())
7661 Expect(functionLoadReplace.Val()).To(Equal(lib1.Name))
7662
7663 lib, err := client.FunctionList(ctx, q).First()
7664 Expect(err).NotTo(HaveOccurred())
7665 Expect(lib.Functions).To(Equal([]redis.Function{
7666 {
7667 Name: newFuncName,
7668 Description: newFuncDesc,
7669 Flags: []string{flag1, flag2},
7670 },
7671 }))
7672 })
7673
7674 It("Deletes a library", func() {
7675 err := client.FunctionLoad(ctx, lib1Code).Err()
7676 Expect(err).NotTo(HaveOccurred())
7677
7678 err = client.FunctionDelete(ctx, lib1.Name).Err()
7679 Expect(err).NotTo(HaveOccurred())
7680
7681 val, err := client.FunctionList(ctx, redis.FunctionListQuery{
7682 LibraryNamePattern: lib1.Name,
7683 }).Result()
7684 Expect(err).NotTo(HaveOccurred())
7685 Expect(val).To(HaveLen(0))
7686 })
7687
7688 It("Flushes all libraries", func() {
7689 err := client.FunctionLoad(ctx, lib1Code).Err()
7690 Expect(err).NotTo(HaveOccurred())
7691
7692 err = client.FunctionLoad(ctx, lib2Code).Err()
7693 Expect(err).NotTo(HaveOccurred())
7694
7695 err = client.FunctionFlush(ctx).Err()
7696 Expect(err).NotTo(HaveOccurred())
7697
7698 val, err := client.FunctionList(ctx, q).Result()
7699 Expect(err).NotTo(HaveOccurred())
7700 Expect(val).To(HaveLen(0))
7701 })
7702
7703 It("Flushes all libraries asynchronously", func() {
7704 functionLoad := client.FunctionLoad(ctx, lib1Code)
7705 Expect(functionLoad.Err()).NotTo(HaveOccurred())
7706
7707
7708 functionFlush := client.FunctionFlushAsync(ctx)
7709 Expect(functionFlush.Err()).NotTo(HaveOccurred())
7710 })
7711
7712 It("Kills a running function", func() {
7713 functionKill := client.FunctionKill(ctx)
7714 Expect(functionKill.Err()).To(MatchError("NOTBUSY No scripts in execution right now."))
7715
7716
7717 })
7718
7719 It("Lists registered functions", Label("NonRedisEnterprise"), func() {
7720 err := client.FunctionLoad(ctx, lib1Code).Err()
7721 Expect(err).NotTo(HaveOccurred())
7722
7723 val, err := client.FunctionList(ctx, redis.FunctionListQuery{
7724 LibraryNamePattern: "*",
7725 WithCode: true,
7726 }).Result()
7727 Expect(err).NotTo(HaveOccurred())
7728 Expect(val).To(HaveLen(1))
7729 Expect(val[0].Name).To(Equal(lib1.Name))
7730 Expect(val[0].Engine).To(Equal(lib1.Engine))
7731 Expect(val[0].Code).To(Equal(lib1Code))
7732 Expect(val[0].Functions).Should(ConsistOf(lib1.Functions))
7733
7734 err = client.FunctionLoad(ctx, lib2Code).Err()
7735 Expect(err).NotTo(HaveOccurred())
7736
7737 val, err = client.FunctionList(ctx, redis.FunctionListQuery{
7738 WithCode: true,
7739 }).Result()
7740 Expect(err).NotTo(HaveOccurred())
7741 Expect(val).To(HaveLen(2))
7742
7743 lib, err := client.FunctionList(ctx, redis.FunctionListQuery{
7744 LibraryNamePattern: lib2.Name,
7745 WithCode: false,
7746 }).First()
7747 Expect(err).NotTo(HaveOccurred())
7748 Expect(lib.Name).To(Equal(lib2.Name))
7749 Expect(lib.Code).To(Equal(""))
7750
7751 _, err = client.FunctionList(ctx, redis.FunctionListQuery{
7752 LibraryNamePattern: "non_lib",
7753 WithCode: true,
7754 }).First()
7755 Expect(err).To(Equal(redis.Nil))
7756 })
7757
7758 It("Dump and restores all libraries", Label("NonRedisEnterprise"), func() {
7759 err := client.FunctionLoad(ctx, lib1Code).Err()
7760 Expect(err).NotTo(HaveOccurred())
7761 err = client.FunctionLoad(ctx, lib2Code).Err()
7762 Expect(err).NotTo(HaveOccurred())
7763
7764 dump, err := client.FunctionDump(ctx).Result()
7765 Expect(err).NotTo(HaveOccurred())
7766 Expect(dump).NotTo(BeEmpty())
7767
7768 err = client.FunctionRestore(ctx, dump).Err()
7769 Expect(err).To(HaveOccurred())
7770
7771 err = client.FunctionFlush(ctx).Err()
7772 Expect(err).NotTo(HaveOccurred())
7773
7774 list, err := client.FunctionList(ctx, q).Result()
7775 Expect(err).NotTo(HaveOccurred())
7776 Expect(list).To(HaveLen(0))
7777
7778 err = client.FunctionRestore(ctx, dump).Err()
7779 Expect(err).NotTo(HaveOccurred())
7780
7781 list, err = client.FunctionList(ctx, q).Result()
7782 Expect(err).NotTo(HaveOccurred())
7783 Expect(list).To(HaveLen(2))
7784 })
7785
7786 It("Calls a function", func() {
7787 lib1Code = fmt.Sprintf(lib1.Code, lib1.Name, lib1.Functions[0].Name,
7788 lib1.Functions[0].Description, lib1.Functions[0].Flags[0], lib1.Functions[0].Flags[1])
7789
7790 err := client.FunctionLoad(ctx, lib1Code).Err()
7791 Expect(err).NotTo(HaveOccurred())
7792
7793 x := client.FCall(ctx, lib1.Functions[0].Name, []string{"my_hash"}, "a", 1, "b", 2)
7794 Expect(x.Err()).NotTo(HaveOccurred())
7795 Expect(x.Int()).To(Equal(3))
7796 })
7797
7798 It("Calls a function as read-only", func() {
7799 lib1Code = fmt.Sprintf(lib1.Code, lib1.Name, lib1.Functions[0].Name,
7800 lib1.Functions[0].Description, lib1.Functions[0].Flags[0], lib1.Functions[0].Flags[1])
7801
7802 err := client.FunctionLoad(ctx, lib1Code).Err()
7803 Expect(err).NotTo(HaveOccurred())
7804
7805
7806 x := client.FCallRo(ctx, lib1.Functions[0].Name, []string{"my_hash"}, "a", 1, "b", 2)
7807
7808 Expect(x.Err()).To(HaveOccurred())
7809
7810 lib2Code = fmt.Sprintf(lib2.Code, lib2.Name, lib2.Functions[0].Name, lib2.Functions[1].Name,
7811 lib2.Functions[1].Description, lib2.Functions[1].Flags[0])
7812
7813
7814 err = client.FunctionLoad(ctx, lib2Code).Err()
7815 Expect(err).NotTo(HaveOccurred())
7816
7817 x = client.FCallRo(ctx, lib2.Functions[1].Name, []string{})
7818
7819 Expect(x.Err()).NotTo(HaveOccurred())
7820 Expect(x.Text()).To(Equal("Function 2"))
7821 })
7822
7823 It("Shows function stats", func() {
7824 SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
7825 defer client.FunctionKill(ctx)
7826
7827
7828
7829 lib := redis.Library{
7830 Name: "mylib1",
7831 Engine: "LUA",
7832 Functions: []redis.Function{
7833 {
7834 Name: "lib1_func1",
7835 Description: "This is the func-1 of lib 1",
7836 Flags: []string{"no-writes"},
7837 },
7838 },
7839 Code: `#!lua name=%s
7840 local function f1(keys, args)
7841 local i = 0
7842 while true do
7843 i = i + 1
7844 end
7845 end
7846
7847 redis.register_function{
7848 function_name='%s',
7849 description ='%s',
7850 callback=f1,
7851 flags={'%s'}
7852 }`,
7853 }
7854 libCode := fmt.Sprintf(lib.Code, lib.Name, lib.Functions[0].Name,
7855 lib.Functions[0].Description, lib.Functions[0].Flags[0])
7856 err := client.FunctionLoad(ctx, libCode).Err()
7857
7858 Expect(err).NotTo(HaveOccurred())
7859
7860 r, err := client.FunctionStats(ctx).Result()
7861 Expect(err).NotTo(HaveOccurred())
7862 Expect(len(r.Engines)).To(Equal(1))
7863 Expect(r.Running()).To(BeFalse())
7864
7865 started := make(chan bool)
7866 go func() {
7867 defer GinkgoRecover()
7868
7869 client2 := redis.NewClient(redisOptions())
7870
7871 started <- true
7872 _, err = client2.FCall(ctx, lib.Functions[0].Name, nil).Result()
7873 Expect(err).To(HaveOccurred())
7874 }()
7875
7876 <-started
7877 time.Sleep(1 * time.Second)
7878 r, err = client.FunctionStats(ctx).Result()
7879
7880 Expect(err).NotTo(HaveOccurred())
7881 Expect(len(r.Engines)).To(Equal(1))
7882 rs, isRunning := r.RunningScript()
7883 Expect(isRunning).To(BeTrue())
7884 Expect(rs.Name).To(Equal(lib.Functions[0].Name))
7885 Expect(rs.Duration > 0).To(BeTrue())
7886
7887 close(started)
7888 })
7889 })
7890
7891 Describe("SlowLogGet", func() {
7892 It("returns slow query result", func() {
7893 const key = "slowlog-log-slower-than"
7894
7895 old := client.ConfigGet(ctx, key).Val()
7896 client.ConfigSet(ctx, key, "0")
7897 defer client.ConfigSet(ctx, key, old[key])
7898
7899 err := client.Do(ctx, "slowlog", "reset").Err()
7900 Expect(err).NotTo(HaveOccurred())
7901
7902 client.Set(ctx, "test", "true", 0)
7903
7904 result, err := client.SlowLogGet(ctx, -1).Result()
7905 Expect(err).NotTo(HaveOccurred())
7906 Expect(len(result)).NotTo(BeZero())
7907 })
7908 })
7909 })
7910
7911 type numberStruct struct {
7912 Number int
7913 }
7914
7915 func (n numberStruct) MarshalBinary() ([]byte, error) {
7916 return json.Marshal(n)
7917 }
7918
7919 func (n *numberStruct) UnmarshalBinary(b []byte) error {
7920 return json.Unmarshal(b, n)
7921 }
7922
7923 func (n *numberStruct) ScanRedis(str string) error {
7924 return json.Unmarshal([]byte(str), n)
7925 }
7926
7927 func deref(viface interface{}) interface{} {
7928 v := reflect.ValueOf(viface)
7929 for v.Kind() == reflect.Ptr {
7930 v = v.Elem()
7931 }
7932 return v.Interface()
7933 }
7934
View as plain text