redis/commands_test.go

7301 lines
224 KiB
Go
Raw Normal View History

2015-01-15 18:51:22 +03:00
package redis_test
import (
2020-03-11 17:26:42 +03:00
"context"
"encoding/json"
2015-01-15 18:51:22 +03:00
"fmt"
"reflect"
"strconv"
2015-01-15 18:51:22 +03:00
"time"
2023-01-27 18:00:49 +03:00
. "github.com/bsm/ginkgo/v2"
. "github.com/bsm/gomega"
2015-05-14 15:19:29 +03:00
2023-01-23 09:48:54 +03:00
"github.com/redis/go-redis/v9"
"github.com/redis/go-redis/v9/internal/proto"
2015-01-15 18:51:22 +03:00
)
type TimeValue struct {
time.Time
}
func (t *TimeValue) ScanRedis(s string) (err error) {
t.Time, err = time.Parse(time.RFC3339Nano, s)
return
}
2015-01-15 18:51:22 +03:00
var _ = Describe("Commands", func() {
2020-03-11 17:26:42 +03:00
ctx := context.TODO()
2015-01-15 18:51:22 +03:00
var client *redis.Client
BeforeEach(func() {
client = redis.NewClient(redisOptions())
2020-03-11 17:26:42 +03:00
Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
})
AfterEach(func() {
Expect(client.Close()).NotTo(HaveOccurred())
})
Describe("server", func() {
It("should Auth", func() {
2020-03-11 17:26:42 +03:00
cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Auth(ctx, "password")
pipe.Auth(ctx, "")
return nil
})
2020-06-05 09:30:21 +03:00
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("ERR AUTH"))
Expect(cmds[0].Err().Error()).To(ContainSubstring("ERR AUTH"))
Expect(cmds[1].Err().Error()).To(ContainSubstring("ERR AUTH"))
2017-08-31 15:22:47 +03:00
stats := client.PoolStats()
2017-08-31 15:22:47 +03:00
Expect(stats.Hits).To(Equal(uint32(1)))
Expect(stats.Misses).To(Equal(uint32(1)))
2017-08-31 15:22:47 +03:00
Expect(stats.Timeouts).To(Equal(uint32(0)))
Expect(stats.TotalConns).To(Equal(uint32(1)))
2018-08-12 10:08:21 +03:00
Expect(stats.IdleConns).To(Equal(uint32(1)))
})
2015-01-15 18:51:22 +03:00
It("should hello", func() {
cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Hello(ctx, 3, "", "", "")
return nil
})
Expect(err).NotTo(HaveOccurred())
m, err := cmds[0].(*redis.MapStringInterfaceCmd).Result()
Expect(err).NotTo(HaveOccurred())
Expect(m["proto"]).To(Equal(int64(3)))
})
2015-01-15 18:51:22 +03:00
It("should Echo", func() {
pipe := client.Pipeline()
2020-03-11 17:26:42 +03:00
echo := pipe.Echo(ctx, "hello")
_, err := pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
Expect(echo.Err()).NotTo(HaveOccurred())
Expect(echo.Val()).To(Equal("hello"))
})
It("should Ping", func() {
2020-03-11 17:26:42 +03:00
ping := client.Ping(ctx)
2015-01-15 18:51:22 +03:00
Expect(ping.Err()).NotTo(HaveOccurred())
Expect(ping.Val()).To(Equal("PONG"))
})
It("should Wait", func() {
2018-02-22 16:01:48 +03:00
const wait = 3 * time.Second
// assume testing on single redis instance
start := time.Now()
2020-03-11 17:26:42 +03:00
val, err := client.Wait(ctx, 1, wait).Result()
2018-02-22 16:01:48 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal(int64(0)))
2018-11-21 12:09:21 +03:00
Expect(time.Now()).To(BeTemporally("~", start.Add(wait), 3*time.Second))
})
It("should WaitAOF", func() {
const waitAOF = 3 * time.Second
Skip("flaky test")
// assuming that the redis instance doesn't have AOF enabled
start := time.Now()
val, err := client.WaitAOF(ctx, 1, 1, waitAOF).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).NotTo(ContainSubstring("ERR WAITAOF cannot be used when numlocal is set but appendonly is disabled"))
Expect(time.Now()).To(BeTemporally("~", start.Add(waitAOF), 3*time.Second))
})
It("should Select", Label("NonRedisEnterprise"), func() {
pipe := client.Pipeline()
2020-03-11 17:26:42 +03:00
sel := pipe.Select(ctx, 1)
_, err := pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(sel.Err()).NotTo(HaveOccurred())
Expect(sel.Val()).To(Equal("OK"))
})
2015-01-15 18:51:22 +03:00
It("should SwapDB", Label("NonRedisEnterprise"), func() {
2018-02-14 07:42:19 +03:00
pipe := client.Pipeline()
2020-03-11 17:26:42 +03:00
sel := pipe.SwapDB(ctx, 1, 2)
_, err := pipe.Exec(ctx)
2018-02-14 07:42:19 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(sel.Err()).NotTo(HaveOccurred())
Expect(sel.Val()).To(Equal("OK"))
})
2015-01-15 18:51:22 +03:00
It("should BgRewriteAOF", func() {
2016-03-14 17:51:46 +03:00
Skip("flaky test")
2020-03-11 17:26:42 +03:00
val, err := client.BgRewriteAOF(ctx).Result()
2016-03-14 17:51:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(val).To(ContainSubstring("Background append only file rewriting"))
2015-01-15 18:51:22 +03:00
})
It("should BgSave", func() {
2016-03-14 17:51:46 +03:00
Skip("flaky test")
2015-01-15 18:51:22 +03:00
// workaround for "ERR Can't BGSAVE while AOF log rewriting is in progress"
Eventually(func() string {
2020-03-11 17:26:42 +03:00
return client.BgSave(ctx).Val()
2016-03-14 17:51:46 +03:00
}, "30s").Should(Equal("Background saving started"))
2015-01-15 18:51:22 +03:00
})
It("Should CommandGetKeys", func() {
keys, err := client.CommandGetKeys(ctx, "MSET", "a", "b", "c", "d", "e", "f").Result()
Expect(err).NotTo(HaveOccurred())
Expect(keys).To(Equal([]string{"a", "c", "e"}))
keys, err = client.CommandGetKeys(ctx, "EVAL", "not consulted", "3", "key1", "key2", "key3", "arg1", "arg2", "arg3", "argN").Result()
Expect(err).NotTo(HaveOccurred())
Expect(keys).To(Equal([]string{"key1", "key2", "key3"}))
keys, err = client.CommandGetKeys(ctx, "SORT", "mylist", "ALPHA", "STORE", "outlist").Result()
Expect(err).NotTo(HaveOccurred())
Expect(keys).To(Equal([]string{"mylist", "outlist"}))
_, err = client.CommandGetKeys(ctx, "FAKECOMMAND", "arg1", "arg2").Result()
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError("ERR Invalid command specified"))
})
It("should CommandGetKeysAndFlags", func() {
keysAndFlags, err := client.CommandGetKeysAndFlags(ctx, "LMOVE", "mylist1", "mylist2", "left", "left").Result()
Expect(err).NotTo(HaveOccurred())
Expect(keysAndFlags).To(Equal([]redis.KeyFlags{
{
Key: "mylist1",
Flags: []string{"RW", "access", "delete"},
},
{
Key: "mylist2",
Flags: []string{"RW", "insert"},
},
}))
_, err = client.CommandGetKeysAndFlags(ctx, "FAKECOMMAND", "arg1", "arg2").Result()
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError("ERR Invalid command specified"))
})
2015-01-15 18:51:22 +03:00
It("should ClientKill", func() {
2020-03-11 17:26:42 +03:00
r := client.ClientKill(ctx, "1.1.1.1:1111")
2015-01-15 18:51:22 +03:00
Expect(r.Err()).To(MatchError("ERR No such client"))
Expect(r.Val()).To(Equal(""))
})
It("should ClientKillByFilter", func() {
2020-03-11 17:26:42 +03:00
r := client.ClientKillByFilter(ctx, "TYPE", "test")
Expect(r.Err()).To(MatchError("ERR Unknown client type 'test'"))
Expect(r.Val()).To(Equal(int64(0)))
})
2024-06-20 02:25:49 +03:00
It("should ClientKillByFilter with MAXAGE", Label("NonRedisEnterprise"), func() {
var s []string
started := make(chan bool)
done := make(chan bool)
go func() {
defer GinkgoRecover()
started <- true
blpop := client.BLPop(ctx, 0, "list")
Expect(blpop.Val()).To(Equal(s))
done <- true
}()
<-started
select {
case <-done:
Fail("BLPOP is not blocked.")
case <-time.After(2 * time.Second):
// ok
}
killed := client.ClientKillByFilter(ctx, "MAXAGE", "1")
Expect(killed.Err()).NotTo(HaveOccurred())
2024-06-20 02:25:49 +03:00
Expect(killed.Val()).To(SatisfyAny(Equal(int64(2)), Equal(int64(3))))
select {
case <-done:
// ok
case <-time.After(time.Second):
Fail("BLPOP is still blocked.")
}
})
2018-12-11 14:17:41 +03:00
It("should ClientID", func() {
2020-03-11 17:26:42 +03:00
err := client.ClientID(ctx).Err()
2018-12-11 13:43:54 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
Expect(client.ClientID(ctx).Val()).To(BeNumerically(">=", 0))
2018-12-11 13:43:54 +03:00
})
2018-12-11 23:26:48 +03:00
It("should ClientUnblock", func() {
2020-03-11 17:26:42 +03:00
id := client.ClientID(ctx).Val()
r, err := client.ClientUnblock(ctx, id).Result()
2018-12-14 17:46:15 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(r).To(Equal(int64(0)))
})
It("should ClientUnblockWithError", func() {
2020-03-11 17:26:42 +03:00
id := client.ClientID(ctx).Val()
r, err := client.ClientUnblockWithError(ctx, id).Result()
2018-12-11 23:26:48 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(r).To(Equal(int64(0)))
})
It("should ClientInfo", func() {
info, err := client.ClientInfo(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(info).NotTo(BeNil())
})
It("should ClientPause", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
err := client.ClientPause(ctx, time.Second).Err()
2015-05-15 15:11:22 +03:00
Expect(err).NotTo(HaveOccurred())
2015-11-22 15:44:38 +03:00
start := time.Now()
2020-03-11 17:26:42 +03:00
err = client.Ping(ctx).Err()
2015-11-22 15:44:38 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(time.Now()).To(BeTemporally("~", start.Add(time.Second), 800*time.Millisecond))
2015-05-15 15:11:22 +03:00
})
2015-10-22 14:15:47 +03:00
It("should ClientSetName and ClientGetName", func() {
pipe := client.Pipeline()
2020-03-11 17:26:42 +03:00
set := pipe.ClientSetName(ctx, "theclientname")
get := pipe.ClientGetName(ctx)
_, err := pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(BeTrue())
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("theclientname"))
})
It("should ClientSetInfo", func() {
pipe := client.Pipeline()
// Test setting the libName
libName := "go-redis"
libInfo := redis.WithLibraryName(libName)
setInfo := pipe.ClientSetInfo(ctx, libInfo)
_, err := pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(setInfo.Err()).NotTo(HaveOccurred())
Expect(setInfo.Val()).To(Equal("OK"))
// Test setting the libVer
libVer := "vX.x"
libInfo = redis.WithLibraryVersion(libVer)
setInfo = pipe.ClientSetInfo(ctx, libInfo)
_, err = pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(setInfo.Err()).NotTo(HaveOccurred())
Expect(setInfo.Val()).To(Equal("OK"))
// Test setting both fields, expect a panic
libInfo = redis.LibraryInfo{LibName: &libName, LibVer: &libVer}
Expect(func() {
defer func() {
if r := recover(); r != nil {
err := r.(error)
Expect(err).To(MatchError("both LibName and LibVer cannot be set at the same time"))
}
}()
pipe.ClientSetInfo(ctx, libInfo)
}).To(Panic())
// Test setting neither field, expect a panic
libInfo = redis.LibraryInfo{}
Expect(func() {
defer func() {
if r := recover(); r != nil {
err := r.(error)
Expect(err).To(MatchError("at least one of LibName and LibVer should be set"))
}
}()
pipe.ClientSetInfo(ctx, libInfo)
}).To(Panic())
// Test setting the default options for libName, libName suffix and libVer
clientInfo := client.ClientInfo(ctx).Val()
Expect(clientInfo.LibName).To(ContainSubstring("go-redis(go-redis,"))
// Test setting the libName suffix in options
opt := redisOptions()
opt.IdentitySuffix = "suffix"
client2 := redis.NewClient(opt)
defer client2.Close()
clientInfo = client2.ClientInfo(ctx).Val()
Expect(clientInfo.LibName).To(ContainSubstring("go-redis(suffix,"))
})
2015-01-15 18:51:22 +03:00
It("should ConfigGet", func() {
2020-03-11 17:26:42 +03:00
val, err := client.ConfigGet(ctx, "*").Result()
2017-05-24 15:53:41 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(val).NotTo(BeEmpty())
2015-01-15 18:51:22 +03:00
})
It("should ConfigResetStat", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
r := client.ConfigResetStat(ctx)
2015-01-15 18:51:22 +03:00
Expect(r.Err()).NotTo(HaveOccurred())
Expect(r.Val()).To(Equal("OK"))
})
It("should ConfigSet", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
configGet := client.ConfigGet(ctx, "maxmemory")
2015-01-15 18:51:22 +03:00
Expect(configGet.Err()).NotTo(HaveOccurred())
Expect(configGet.Val()).To(HaveLen(1))
_, ok := configGet.Val()["maxmemory"]
Expect(ok).To(BeTrue())
2015-01-15 18:51:22 +03:00
configSet := client.ConfigSet(ctx, "maxmemory", configGet.Val()["maxmemory"])
2015-01-15 18:51:22 +03:00
Expect(configSet.Err()).NotTo(HaveOccurred())
Expect(configSet.Val()).To(Equal("OK"))
})
It("should ConfigRewrite", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
configRewrite := client.ConfigRewrite(ctx)
Expect(configRewrite.Err()).NotTo(HaveOccurred())
Expect(configRewrite.Val()).To(Equal("OK"))
})
2017-08-15 10:34:05 +03:00
It("should DBSize", func() {
2020-03-11 17:26:42 +03:00
size, err := client.DBSize(ctx).Result()
2017-08-15 10:34:05 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(0)))
2015-01-15 18:51:22 +03:00
})
It("should Info", func() {
2020-03-11 17:26:42 +03:00
info := client.Info(ctx)
2015-01-15 18:51:22 +03:00
Expect(info.Err()).NotTo(HaveOccurred())
Expect(info.Val()).NotTo(Equal(""))
})
It("should InfoMap", Label("redis.info"), func() {
info := client.InfoMap(ctx)
Expect(info.Err()).NotTo(HaveOccurred())
Expect(info.Val()).NotTo(BeNil())
info = client.InfoMap(ctx, "dummy")
Expect(info.Err()).NotTo(HaveOccurred())
Expect(info.Val()).To(BeNil())
info = client.InfoMap(ctx, "server")
Expect(info.Err()).NotTo(HaveOccurred())
Expect(info.Val()).To(HaveLen(1))
})
It("should Info cpu", func() {
2020-03-11 17:26:42 +03:00
info := client.Info(ctx, "cpu")
Expect(info.Err()).NotTo(HaveOccurred())
Expect(info.Val()).NotTo(Equal(""))
Expect(info.Val()).To(ContainSubstring(`used_cpu_sys`))
})
2022-10-07 22:40:51 +03:00
It("should Info cpu and memory", func() {
info := client.Info(ctx, "cpu", "memory")
Expect(info.Err()).NotTo(HaveOccurred())
Expect(info.Val()).NotTo(Equal(""))
Expect(info.Val()).To(ContainSubstring(`used_cpu_sys`))
Expect(info.Val()).To(ContainSubstring(`memory`))
})
It("should LastSave", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
lastSave := client.LastSave(ctx)
2015-01-15 18:51:22 +03:00
Expect(lastSave.Err()).NotTo(HaveOccurred())
Expect(lastSave.Val()).NotTo(Equal(0))
})
It("should Save", Label("NonRedisEnterprise"), func() {
2015-01-15 18:51:22 +03:00
// workaround for "ERR Background save already in progress"
Eventually(func() string {
2020-03-11 17:26:42 +03:00
return client.Save(ctx).Val()
2015-01-24 15:12:48 +03:00
}, "10s").Should(Equal("OK"))
2015-01-15 18:51:22 +03:00
})
It("should SlaveOf", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
slaveOf := client.SlaveOf(ctx, "localhost", "8888")
2015-01-15 18:51:22 +03:00
Expect(slaveOf.Err()).NotTo(HaveOccurred())
Expect(slaveOf.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
slaveOf = client.SlaveOf(ctx, "NO", "ONE")
2015-01-15 18:51:22 +03:00
Expect(slaveOf.Err()).NotTo(HaveOccurred())
Expect(slaveOf.Val()).To(Equal("OK"))
})
It("should Time", func() {
2020-03-11 17:26:42 +03:00
tm, err := client.Time(ctx).Result()
2016-10-14 14:39:02 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(tm).To(BeTemporally("~", time.Now(), 3*time.Second))
2015-01-15 18:51:22 +03:00
})
It("should Command", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
cmds, err := client.Command(ctx).Result()
2017-08-31 15:22:47 +03:00
Expect(err).NotTo(HaveOccurred())
2022-06-04 17:25:12 +03:00
Expect(len(cmds)).To(BeNumerically("~", 240, 25))
2017-08-31 15:22:47 +03:00
cmd := cmds["mget"]
Expect(cmd.Name).To(Equal("mget"))
Expect(cmd.Arity).To(Equal(int8(-2)))
Expect(cmd.Flags).To(ContainElement("readonly"))
Expect(cmd.FirstKeyPos).To(Equal(int8(1)))
Expect(cmd.LastKeyPos).To(Equal(int8(-1)))
Expect(cmd.StepCount).To(Equal(int8(1)))
cmd = cmds["ping"]
Expect(cmd.Name).To(Equal("ping"))
Expect(cmd.Arity).To(Equal(int8(-1)))
Expect(cmd.Flags).To(ContainElement("fast"))
Expect(cmd.FirstKeyPos).To(Equal(int8(0)))
Expect(cmd.LastKeyPos).To(Equal(int8(0)))
Expect(cmd.StepCount).To(Equal(int8(0)))
})
It("should return all command names", func() {
cmdList := client.CommandList(ctx, nil)
Expect(cmdList.Err()).NotTo(HaveOccurred())
cmdNames := cmdList.Val()
Expect(cmdNames).NotTo(BeEmpty())
// Assert that some expected commands are present in the list
Expect(cmdNames).To(ContainElement("get"))
Expect(cmdNames).To(ContainElement("set"))
Expect(cmdNames).To(ContainElement("hset"))
})
It("should filter commands by module", func() {
filter := &redis.FilterBy{
Module: "JSON",
}
cmdList := client.CommandList(ctx, filter)
Expect(cmdList.Err()).NotTo(HaveOccurred())
Expect(cmdList.Val()).To(HaveLen(0))
})
It("should filter commands by ACL category", func() {
filter := &redis.FilterBy{
ACLCat: "admin",
}
cmdList := client.CommandList(ctx, filter)
Expect(cmdList.Err()).NotTo(HaveOccurred())
cmdNames := cmdList.Val()
// Assert that the returned list only contains commands from the admin ACL category
Expect(len(cmdNames)).To(BeNumerically(">", 10))
})
It("should filter commands by pattern", func() {
filter := &redis.FilterBy{
Pattern: "*GET*",
}
cmdList := client.CommandList(ctx, filter)
Expect(cmdList.Err()).NotTo(HaveOccurred())
cmdNames := cmdList.Val()
// Assert that the returned list only contains commands that match the given pattern
Expect(cmdNames).To(ContainElement("get"))
Expect(cmdNames).To(ContainElement("getbit"))
Expect(cmdNames).To(ContainElement("getrange"))
Expect(cmdNames).NotTo(ContainElement("set"))
})
2015-01-15 18:51:22 +03:00
})
Describe("debugging", func() {
2022-06-04 17:25:12 +03:00
PIt("should DebugObject", func() {
2020-03-11 17:26:42 +03:00
err := client.DebugObject(ctx, "foo").Err()
2018-07-22 09:46:29 +03:00
Expect(err).To(MatchError("ERR no such key"))
2020-03-11 17:26:42 +03:00
err = client.Set(ctx, "foo", "bar", 0).Err()
2018-07-22 09:46:29 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
s, err := client.DebugObject(ctx, "foo").Result()
2018-07-22 09:46:29 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(s).To(ContainSubstring("serializedlength:4"))
})
It("should MemoryUsage", func() {
2020-03-11 17:26:42 +03:00
err := client.MemoryUsage(ctx, "foo").Err()
2018-07-22 09:46:29 +03:00
Expect(err).To(Equal(redis.Nil))
2020-03-11 17:26:42 +03:00
err = client.Set(ctx, "foo", "bar", 0).Err()
2018-07-22 09:46:29 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
n, err := client.MemoryUsage(ctx, "foo").Result()
2018-07-22 09:46:29 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-10 16:15:54 +03:00
Expect(n).NotTo(BeZero())
2018-07-22 09:46:29 +03:00
2020-03-11 17:26:42 +03:00
n, err = client.MemoryUsage(ctx, "foo", 0).Result()
2018-07-22 09:46:29 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-10 16:15:54 +03:00
Expect(n).NotTo(BeZero())
2015-01-15 18:51:22 +03:00
})
})
Describe("keys", func() {
It("should Del", func() {
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "key1", "Hello", 0).Err()
2016-12-22 14:42:05 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.Set(ctx, "key2", "World", 0).Err()
2016-12-22 14:42:05 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
n, err := client.Del(ctx, "key1", "key2", "key3").Result()
2016-12-22 14:42:05 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
})
It("should Unlink", func() {
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "key1", "Hello", 0).Err()
2016-12-22 14:42:05 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.Set(ctx, "key2", "World", 0).Err()
2016-12-22 14:42:05 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
n, err := client.Unlink(ctx, "key1", "key2", "key3").Result()
2016-12-22 14:42:05 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
2015-01-15 18:51:22 +03:00
})
It("should Dump", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
dump := client.Dump(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(dump.Err()).NotTo(HaveOccurred())
2015-09-28 11:13:32 +03:00
Expect(dump.Val()).NotTo(BeEmpty())
2015-01-15 18:51:22 +03:00
})
It("should Exists", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key1", "Hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
n, err := client.Exists(ctx, "key1").Result()
2017-02-18 17:32:39 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
n, err = client.Exists(ctx, "key2").Result()
2017-02-18 17:32:39 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(0)))
2017-02-10 13:15:25 +03:00
2020-03-11 17:26:42 +03:00
n, err = client.Exists(ctx, "key1", "key2").Result()
2017-02-18 17:32:39 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
2017-02-10 13:15:25 +03:00
2020-03-11 17:26:42 +03:00
n, err = client.Exists(ctx, "key1", "key1").Result()
2017-02-18 17:32:39 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
2015-01-15 18:51:22 +03:00
})
It("should Expire", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "Hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
expire := client.Expire(ctx, "key", 10*time.Second)
2015-01-15 18:51:22 +03:00
Expect(expire.Err()).NotTo(HaveOccurred())
Expect(expire.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
ttl := client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(Equal(10 * time.Second))
2020-03-11 17:26:42 +03:00
set = client.Set(ctx, "key", "Hello World", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
ttl = client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
2019-05-31 13:16:10 +03:00
Expect(ttl.Val()).To(Equal(time.Duration(-1)))
2020-03-11 17:26:42 +03:00
ttl = client.TTL(ctx, "nonexistent_key")
2019-05-31 13:16:10 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(Equal(time.Duration(-2)))
2015-01-15 18:51:22 +03:00
})
It("should ExpireAt", func() {
setCmd := client.Set(ctx, "key", "Hello", 0)
Expect(setCmd.Err()).NotTo(HaveOccurred())
Expect(setCmd.Val()).To(Equal("OK"))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
n, err := client.Exists(ctx, "key").Result()
2017-02-18 17:32:39 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
2015-01-15 18:51:22 +03:00
// Check correct expiration time is set in the future
expireAt := time.Now().Add(time.Minute)
expireAtCmd := client.ExpireAt(ctx, "key", expireAt)
Expect(expireAtCmd.Err()).NotTo(HaveOccurred())
Expect(expireAtCmd.Val()).To(Equal(true))
timeCmd := client.ExpireTime(ctx, "key")
Expect(timeCmd.Err()).NotTo(HaveOccurred())
Expect(timeCmd.Val().Seconds()).To(BeNumerically("==", expireAt.Unix()))
// Check correct expiration in the past
expireAtCmd = client.ExpireAt(ctx, "key", time.Now().Add(-time.Hour))
Expect(expireAtCmd.Err()).NotTo(HaveOccurred())
Expect(expireAtCmd.Val()).To(Equal(true))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
n, err = client.Exists(ctx, "key").Result()
2017-02-18 17:32:39 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(0)))
2015-01-15 18:51:22 +03:00
})
It("should Keys", func() {
2020-03-11 17:26:42 +03:00
mset := client.MSet(ctx, "one", "1", "two", "2", "three", "3", "four", "4")
2015-01-15 18:51:22 +03:00
Expect(mset.Err()).NotTo(HaveOccurred())
Expect(mset.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
keys := client.Keys(ctx, "*o*")
2015-01-15 18:51:22 +03:00
Expect(keys.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(keys.Val()).To(ConsistOf([]string{"four", "one", "two"}))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
keys = client.Keys(ctx, "t??")
2015-01-15 18:51:22 +03:00
Expect(keys.Err()).NotTo(HaveOccurred())
Expect(keys.Val()).To(Equal([]string{"two"}))
2020-03-11 17:26:42 +03:00
keys = client.Keys(ctx, "*")
2015-01-15 18:51:22 +03:00
Expect(keys.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(keys.Val()).To(ConsistOf([]string{"four", "one", "three", "two"}))
2015-01-15 18:51:22 +03:00
})
It("should Migrate", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
migrate := client.Migrate(ctx, "localhost", redisSecondaryPort, "key", 0, 0)
2015-01-15 18:51:22 +03:00
Expect(migrate.Err()).NotTo(HaveOccurred())
Expect(migrate.Val()).To(Equal("NOKEY"))
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
migrate = client.Migrate(ctx, "localhost", redisSecondaryPort, "key", 0, 0)
2015-01-15 18:51:22 +03:00
Expect(migrate.Err()).To(MatchError("IOERR error or timeout writing to target instance"))
Expect(migrate.Val()).To(Equal(""))
})
It("should Move", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
move := client.Move(ctx, "key", 2)
2015-01-15 18:51:22 +03:00
Expect(move.Err()).NotTo(HaveOccurred())
Expect(move.Val()).To(Equal(false))
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
move = client.Move(ctx, "key", 2)
2015-01-15 18:51:22 +03:00
Expect(move.Err()).NotTo(HaveOccurred())
Expect(move.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).To(Equal(redis.Nil))
Expect(get.Val()).To(Equal(""))
pipe := client.Pipeline()
2020-03-11 17:26:42 +03:00
pipe.Select(ctx, 2)
get = pipe.Get(ctx, "key")
pipe.FlushDB(ctx)
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
_, err := pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
Expect(get.Val()).To(Equal("hello"))
})
It("should Object", Label("NonRedisEnterprise"), func() {
start := time.Now()
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
refCount := client.ObjectRefCount(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(refCount.Err()).NotTo(HaveOccurred())
Expect(refCount.Val()).To(Equal(int64(1)))
client.ConfigSet(ctx, "maxmemory-policy", "volatile-lfu")
freq := client.ObjectFreq(ctx, "key")
Expect(freq.Err()).NotTo(HaveOccurred())
client.ConfigSet(ctx, "maxmemory-policy", "noeviction") // default
2020-03-11 17:26:42 +03:00
err := client.ObjectEncoding(ctx, "key").Err()
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
idleTime := client.ObjectIdleTime(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(idleTime.Err()).NotTo(HaveOccurred())
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
// Redis returned milliseconds/1000, which may cause ObjectIdleTime to be at a critical value,
// should be +1s to deal with the critical value problem.
// if too much time (>1s) is used during command execution, it may also cause the test to fail.
// so the ObjectIdleTime result should be <=now-start+1s
// link: https://github.com/redis/redis/blob/5b48d900498c85bbf4772c1d466c214439888115/src/object.c#L1265-L1272
2023-07-02 14:38:52 +03:00
Expect(idleTime.Val()).To(BeNumerically("<=", time.Since(start)+time.Second))
2015-01-15 18:51:22 +03:00
})
It("should Persist", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "Hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
expire := client.Expire(ctx, "key", 10*time.Second)
2015-01-15 18:51:22 +03:00
Expect(expire.Err()).NotTo(HaveOccurred())
Expect(expire.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
ttl := client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(Equal(10 * time.Second))
2020-03-11 17:26:42 +03:00
persist := client.Persist(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(persist.Err()).NotTo(HaveOccurred())
Expect(persist.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
ttl = client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val() < 0).To(Equal(true))
})
It("should PExpire", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "Hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
expiration := 900 * time.Millisecond
2020-03-11 17:26:42 +03:00
pexpire := client.PExpire(ctx, "key", expiration)
2015-01-15 18:51:22 +03:00
Expect(pexpire.Err()).NotTo(HaveOccurred())
Expect(pexpire.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
ttl := client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(Equal(time.Second))
2020-03-11 17:26:42 +03:00
pttl := client.PTTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(pttl.Err()).NotTo(HaveOccurred())
Expect(pttl.Val()).To(BeNumerically("~", expiration, 100*time.Millisecond))
2015-01-15 18:51:22 +03:00
})
It("should PExpireAt", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "Hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
expiration := 900 * time.Millisecond
2020-03-11 17:26:42 +03:00
pexpireat := client.PExpireAt(ctx, "key", time.Now().Add(expiration))
2015-01-15 18:51:22 +03:00
Expect(pexpireat.Err()).NotTo(HaveOccurred())
Expect(pexpireat.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
ttl := client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(Equal(time.Second))
2020-03-11 17:26:42 +03:00
pttl := client.PTTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(pttl.Err()).NotTo(HaveOccurred())
Expect(pttl.Val()).To(BeNumerically("~", expiration, 100*time.Millisecond))
2015-01-15 18:51:22 +03:00
})
It("should PExpireTime", func() {
// The command returns -1 if the key exists but has no associated expiration time.
// The command returns -2 if the key does not exist.
pExpireTime := client.PExpireTime(ctx, "key")
Expect(pExpireTime.Err()).NotTo(HaveOccurred())
Expect(pExpireTime.Val() < 0).To(Equal(true))
set := client.Set(ctx, "key", "hello", 0)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
timestamp := time.Now().Add(time.Minute)
expireAt := client.PExpireAt(ctx, "key", timestamp)
Expect(expireAt.Err()).NotTo(HaveOccurred())
Expect(expireAt.Val()).To(Equal(true))
pExpireTime = client.PExpireTime(ctx, "key")
Expect(pExpireTime.Err()).NotTo(HaveOccurred())
Expect(pExpireTime.Val().Milliseconds()).To(BeNumerically("==", timestamp.UnixMilli()))
})
2015-01-15 18:51:22 +03:00
It("should PTTL", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "Hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
expiration := time.Second
2020-03-11 17:26:42 +03:00
expire := client.Expire(ctx, "key", expiration)
2015-01-15 18:51:22 +03:00
Expect(expire.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
pttl := client.PTTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(pttl.Err()).NotTo(HaveOccurred())
Expect(pttl.Val()).To(BeNumerically("~", expiration, 100*time.Millisecond))
2015-01-15 18:51:22 +03:00
})
It("should RandomKey", func() {
2020-03-11 17:26:42 +03:00
randomKey := client.RandomKey(ctx)
2015-01-15 18:51:22 +03:00
Expect(randomKey.Err()).To(Equal(redis.Nil))
Expect(randomKey.Val()).To(Equal(""))
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
randomKey = client.RandomKey(ctx)
2015-01-15 18:51:22 +03:00
Expect(randomKey.Err()).NotTo(HaveOccurred())
Expect(randomKey.Val()).To(Equal("key"))
})
It("should Rename", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
status := client.Rename(ctx, "key", "key1")
2015-01-15 18:51:22 +03:00
Expect(status.Err()).NotTo(HaveOccurred())
Expect(status.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key1")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("hello"))
})
It("should RenameNX", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
renameNX := client.RenameNX(ctx, "key", "key1")
2015-01-15 18:51:22 +03:00
Expect(renameNX.Err()).NotTo(HaveOccurred())
Expect(renameNX.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key1")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("hello"))
})
It("should Restore", func() {
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "key", "hello", 0).Err()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
dump := client.Dump(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(dump.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.Del(ctx, "key").Err()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
restore, err := client.Restore(ctx, "key", 0, dump.Val()).Result()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(restore).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
type_, err := client.Type(ctx, "key").Result()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(type_).To(Equal("string"))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
val, err := client.Get(ctx, "key").Result()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
})
2015-01-15 18:51:22 +03:00
2015-07-11 12:23:04 +03:00
It("should RestoreReplace", func() {
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "key", "hello", 0).Err()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
dump := client.Dump(ctx, "key")
2015-07-11 12:23:04 +03:00
Expect(dump.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
restore, err := client.RestoreReplace(ctx, "key", 0, dump.Val()).Result()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(restore).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
type_, err := client.Type(ctx, "key").Result()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(type_).To(Equal("string"))
2020-03-11 17:26:42 +03:00
val, err := client.Get(ctx, "key").Result()
2015-07-11 12:23:04 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
2015-01-15 18:51:22 +03:00
})
2023-01-18 14:13:55 +03:00
It("should Sort RO", func() {
size, err := client.LPush(ctx, "list", "1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(1)))
size, err = client.LPush(ctx, "list", "3").Result()
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(2)))
size, err = client.LPush(ctx, "list", "2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(3)))
els, err := client.SortRO(ctx, "list", &redis.Sort{
Offset: 0,
Count: 2,
Order: "ASC",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(els).To(Equal([]string{"1", "2"}))
})
2015-01-15 18:51:22 +03:00
It("should Sort", func() {
2020-03-11 17:26:42 +03:00
size, err := client.LPush(ctx, "list", "1").Result()
2016-01-22 13:29:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
size, err = client.LPush(ctx, "list", "3").Result()
2016-01-22 13:29:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
size, err = client.LPush(ctx, "list", "2").Result()
2016-01-22 13:29:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(3)))
2020-03-11 17:26:42 +03:00
els, err := client.Sort(ctx, "list", &redis.Sort{
2016-01-22 13:29:23 +03:00
Offset: 0,
Count: 2,
Order: "ASC",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(els).To(Equal([]string{"1", "2"}))
})
It("should Sort and Get", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
size, err := client.LPush(ctx, "list", "1").Result()
2016-01-22 13:29:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
size, err = client.LPush(ctx, "list", "3").Result()
2016-01-22 13:29:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
size, err = client.LPush(ctx, "list", "2").Result()
2016-01-22 13:29:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(3)))
2020-03-11 17:26:42 +03:00
err = client.Set(ctx, "object_2", "value2", 0).Err()
2016-01-22 13:29:23 +03:00
Expect(err).NotTo(HaveOccurred())
{
2020-03-11 17:26:42 +03:00
els, err := client.Sort(ctx, "list", &redis.Sort{
2016-01-22 13:29:23 +03:00
Get: []string{"object_*"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(els).To(Equal([]string{"", "value2", ""}))
}
{
2020-03-11 17:26:42 +03:00
els, err := client.SortInterfaces(ctx, "list", &redis.Sort{
2016-01-22 13:29:23 +03:00
Get: []string{"object_*"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(els).To(Equal([]interface{}{nil, "value2", nil}))
}
2015-01-15 18:51:22 +03:00
})
It("should Sort and Store", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
size, err := client.LPush(ctx, "list", "1").Result()
2018-02-13 17:08:11 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
size, err = client.LPush(ctx, "list", "3").Result()
2018-02-13 17:08:11 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
size, err = client.LPush(ctx, "list", "2").Result()
2018-02-13 17:08:11 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(size).To(Equal(int64(3)))
2020-03-11 17:26:42 +03:00
n, err := client.SortStore(ctx, "list", "list2", &redis.Sort{
2018-02-13 17:08:11 +03:00
Offset: 0,
Count: 2,
Order: "ASC",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
els, err := client.LRange(ctx, "list2", 0, -1).Result()
2018-02-13 17:08:11 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(els).To(Equal([]string{"1", "2"}))
})
2018-02-14 07:42:19 +03:00
It("should Touch", func() {
2020-03-11 17:26:42 +03:00
set1 := client.Set(ctx, "touch1", "hello", 0)
2018-02-14 07:42:19 +03:00
Expect(set1.Err()).NotTo(HaveOccurred())
Expect(set1.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
set2 := client.Set(ctx, "touch2", "hello", 0)
2018-02-14 07:42:19 +03:00
Expect(set2.Err()).NotTo(HaveOccurred())
Expect(set2.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
touch := client.Touch(ctx, "touch1", "touch2", "touch3")
2018-02-14 07:42:19 +03:00
Expect(touch.Err()).NotTo(HaveOccurred())
Expect(touch.Val()).To(Equal(int64(2)))
})
It("should ExpireTime", func() {
// The command returns -1 if the key exists but has no associated expiration time.
// The command returns -2 if the key does not exist.
expireTimeCmd := client.ExpireTime(ctx, "key")
Expect(expireTimeCmd.Err()).NotTo(HaveOccurred())
Expect(expireTimeCmd.Val() < 0).To(Equal(true))
set := client.Set(ctx, "key", "hello", 0)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
expireAt := time.Now().Add(time.Minute)
expireAtCmd := client.ExpireAt(ctx, "key", expireAt)
Expect(expireAtCmd.Err()).NotTo(HaveOccurred())
Expect(expireAtCmd.Val()).To(Equal(true))
expireTimeCmd = client.ExpireTime(ctx, "key")
Expect(expireTimeCmd.Err()).NotTo(HaveOccurred())
Expect(expireTimeCmd.Val().Seconds()).To(BeNumerically("==", expireAt.Unix()))
})
2015-01-15 18:51:22 +03:00
It("should TTL", func() {
// The command returns -1 if the key exists but has no associated expire
// The command returns -2 if the key does not exist.
2020-03-11 17:26:42 +03:00
ttl := client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val() < 0).To(Equal(true))
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
expire := client.Expire(ctx, "key", 60*time.Second)
2015-01-15 18:51:22 +03:00
Expect(expire.Err()).NotTo(HaveOccurred())
Expect(expire.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
ttl = client.TTL(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(Equal(60 * time.Second))
})
It("should Type", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
type_ := client.Type(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(type_.Err()).NotTo(HaveOccurred())
Expect(type_.Val()).To(Equal("string"))
})
})
Describe("scanning", func() {
It("should Scan", func() {
for i := 0; i < 1000; i++ {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, fmt.Sprintf("key%d", i), "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
}
2020-03-11 17:26:42 +03:00
keys, cursor, err := client.Scan(ctx, 0, "", 0).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(keys).NotTo(BeEmpty())
Expect(cursor).NotTo(BeZero())
2015-01-15 18:51:22 +03:00
})
It("should ScanType", func() {
for i := 0; i < 1000; i++ {
set := client.Set(ctx, fmt.Sprintf("key%d", i), "hello", 0)
Expect(set.Err()).NotTo(HaveOccurred())
}
keys, cursor, err := client.ScanType(ctx, 0, "", 0, "string").Result()
Expect(err).NotTo(HaveOccurred())
Expect(keys).NotTo(BeEmpty())
Expect(cursor).NotTo(BeZero())
})
2015-01-15 18:51:22 +03:00
It("should SScan", func() {
for i := 0; i < 1000; i++ {
2020-03-11 17:26:42 +03:00
sadd := client.SAdd(ctx, "myset", fmt.Sprintf("member%d", i))
2015-01-15 18:51:22 +03:00
Expect(sadd.Err()).NotTo(HaveOccurred())
}
2020-03-11 17:26:42 +03:00
keys, cursor, err := client.SScan(ctx, "myset", 0, "", 0).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(keys).NotTo(BeEmpty())
Expect(cursor).NotTo(BeZero())
2015-01-15 18:51:22 +03:00
})
It("should HScan", func() {
for i := 0; i < 1000; i++ {
2020-03-11 17:26:42 +03:00
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
2015-01-15 18:51:22 +03:00
Expect(sadd.Err()).NotTo(HaveOccurred())
}
2020-03-11 17:26:42 +03:00
keys, cursor, err := client.HScan(ctx, "myhash", 0, "", 0).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
// If we don't get at least two items back, it's really strange.
Expect(cursor).To(BeNumerically(">=", 2))
Expect(len(keys)).To(BeNumerically(">=", 2))
Expect(keys[0]).To(HavePrefix("key"))
Expect(keys[1]).To(Equal("hello"))
})
2024-06-20 02:25:49 +03:00
It("should HScan without values", Label("NonRedisEnterprise"), func() {
for i := 0; i < 1000; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
keys, cursor, err := client.HScanNoValues(ctx, "myhash", 0, "", 0).Result()
Expect(err).NotTo(HaveOccurred())
// If we don't get at least two items back, it's really strange.
Expect(cursor).To(BeNumerically(">=", 2))
Expect(len(keys)).To(BeNumerically(">=", 2))
Expect(keys[0]).To(HavePrefix("key"))
Expect(keys[1]).To(HavePrefix("key"))
2024-06-20 02:25:49 +03:00
Expect(keys).NotTo(BeEmpty())
Expect(cursor).NotTo(BeZero())
2015-01-15 18:51:22 +03:00
})
It("should ZScan", func() {
for i := 0; i < 1000; i++ {
err := client.ZAdd(ctx, "myset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: float64(i),
Member: fmt.Sprintf("member%d", i),
}).Err()
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
}
2020-03-11 17:26:42 +03:00
keys, cursor, err := client.ZScan(ctx, "myset", 0, "", 0).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(keys).NotTo(BeEmpty())
Expect(cursor).NotTo(BeZero())
2015-01-15 18:51:22 +03:00
})
})
Describe("strings", func() {
It("should Append", func() {
2020-03-11 17:26:42 +03:00
n, err := client.Exists(ctx, "key").Result()
2017-02-18 17:32:39 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(0)))
2015-01-15 18:51:22 +03:00
appendRes := client.Append(ctx, "key", "Hello")
Expect(appendRes.Err()).NotTo(HaveOccurred())
Expect(appendRes.Val()).To(Equal(int64(5)))
2015-01-15 18:51:22 +03:00
appendRes = client.Append(ctx, "key", " World")
Expect(appendRes.Err()).NotTo(HaveOccurred())
Expect(appendRes.Val()).To(Equal(int64(11)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("Hello World"))
})
It("should BitCount", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "foobar", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
bitCount := client.BitCount(ctx, "key", nil)
2015-01-15 18:51:22 +03:00
Expect(bitCount.Err()).NotTo(HaveOccurred())
Expect(bitCount.Val()).To(Equal(int64(26)))
2020-03-11 17:26:42 +03:00
bitCount = client.BitCount(ctx, "key", &redis.BitCount{
2018-03-07 12:56:24 +03:00
Start: 0,
End: 0,
})
2015-01-15 18:51:22 +03:00
Expect(bitCount.Err()).NotTo(HaveOccurred())
Expect(bitCount.Val()).To(Equal(int64(4)))
2020-03-11 17:26:42 +03:00
bitCount = client.BitCount(ctx, "key", &redis.BitCount{
2018-03-07 12:56:24 +03:00
Start: 1,
End: 1,
})
2015-01-15 18:51:22 +03:00
Expect(bitCount.Err()).NotTo(HaveOccurred())
Expect(bitCount.Val()).To(Equal(int64(6)))
})
It("should BitOpAnd", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key1", "1", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
set = client.Set(ctx, "key2", "0", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
bitOpAnd := client.BitOpAnd(ctx, "dest", "key1", "key2")
2015-01-15 18:51:22 +03:00
Expect(bitOpAnd.Err()).NotTo(HaveOccurred())
Expect(bitOpAnd.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "dest")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("0"))
})
It("should BitOpOr", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key1", "1", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
set = client.Set(ctx, "key2", "0", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
bitOpOr := client.BitOpOr(ctx, "dest", "key1", "key2")
2015-01-15 18:51:22 +03:00
Expect(bitOpOr.Err()).NotTo(HaveOccurred())
Expect(bitOpOr.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "dest")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("1"))
})
It("should BitOpXor", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key1", "\xff", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
set = client.Set(ctx, "key2", "\x0f", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
bitOpXor := client.BitOpXor(ctx, "dest", "key1", "key2")
2015-01-15 18:51:22 +03:00
Expect(bitOpXor.Err()).NotTo(HaveOccurred())
Expect(bitOpXor.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "dest")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("\xf0"))
})
It("should BitOpNot", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key1", "\x00", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
bitOpNot := client.BitOpNot(ctx, "dest", "key1")
2015-01-15 18:51:22 +03:00
Expect(bitOpNot.Err()).NotTo(HaveOccurred())
Expect(bitOpNot.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "dest")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("\xff"))
})
2014-10-07 14:54:43 +04:00
It("should BitPos", func() {
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "mykey", "\xff\xf0\x00", 0).Err()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
pos, err := client.BitPos(ctx, "mykey", 0).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(12)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 1).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 0, 2).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(16)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 1, 2).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(-1)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 0, -1).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(16)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 1, -1).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(-1)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 0, 2, 1).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(-1)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 0, 0, -3).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(-1)))
2020-03-11 17:26:42 +03:00
pos, err = client.BitPos(ctx, "mykey", 0, 0, 0).Result()
2014-10-07 14:54:43 +04:00
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(-1)))
})
It("should BitPosSpan", func() {
err := client.Set(ctx, "mykey", "\x00\xff\x00", 0).Err()
Expect(err).NotTo(HaveOccurred())
pos, err := client.BitPosSpan(ctx, "mykey", 0, 1, 3, "byte").Result()
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(16)))
pos, err = client.BitPosSpan(ctx, "mykey", 0, 1, 3, "bit").Result()
Expect(err).NotTo(HaveOccurred())
Expect(pos).To(Equal(int64(1)))
})
2019-06-26 14:45:38 +03:00
It("should BitField", func() {
2020-03-11 17:26:42 +03:00
nn, err := client.BitField(ctx, "mykey", "INCRBY", "i5", 100, 1, "GET", "u4", 0).Result()
2019-06-26 14:45:38 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(nn).To(Equal([]int64{1, 0}))
nn, err = client.BitField(ctx, "mykey", "set", "i1", 1, 1, "GET", "u4", 0).Result()
Expect(err).NotTo(HaveOccurred())
Expect(nn).To(Equal([]int64{0, 4}))
2019-06-26 14:45:38 +03:00
})
It("should BitFieldRO", func() {
nn, err := client.BitField(ctx, "mykey", "SET", "u8", 8, 255).Result()
Expect(err).NotTo(HaveOccurred())
Expect(nn).To(Equal([]int64{0}))
nn, err = client.BitFieldRO(ctx, "mykey", "u8", 0).Result()
Expect(err).NotTo(HaveOccurred())
Expect(nn).To(Equal([]int64{0}))
nn, err = client.BitFieldRO(ctx, "mykey", "u8", 0, "u4", 8, "u4", 12, "u4", 13).Result()
Expect(err).NotTo(HaveOccurred())
Expect(nn).To(Equal([]int64{0, 15, 15, 14}))
})
2015-01-15 18:51:22 +03:00
It("should Decr", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "10", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
decr := client.Decr(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(decr.Err()).NotTo(HaveOccurred())
Expect(decr.Val()).To(Equal(int64(9)))
2020-03-11 17:26:42 +03:00
set = client.Set(ctx, "key", "234293482390480948029348230948", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
decr = client.Decr(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(decr.Err()).To(MatchError("ERR value is not an integer or out of range"))
Expect(decr.Val()).To(Equal(int64(0)))
})
It("should DecrBy", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "10", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
decrBy := client.DecrBy(ctx, "key", 5)
2015-01-15 18:51:22 +03:00
Expect(decrBy.Err()).NotTo(HaveOccurred())
Expect(decrBy.Val()).To(Equal(int64(5)))
})
It("should Get", func() {
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "_")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).To(Equal(redis.Nil))
Expect(get.Val()).To(Equal(""))
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
get = client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("hello"))
})
It("should GetBit", func() {
2020-03-11 17:26:42 +03:00
setBit := client.SetBit(ctx, "key", 7, 1)
2015-01-15 18:51:22 +03:00
Expect(setBit.Err()).NotTo(HaveOccurred())
Expect(setBit.Val()).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
getBit := client.GetBit(ctx, "key", 0)
2015-01-15 18:51:22 +03:00
Expect(getBit.Err()).NotTo(HaveOccurred())
Expect(getBit.Val()).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
getBit = client.GetBit(ctx, "key", 7)
2015-01-15 18:51:22 +03:00
Expect(getBit.Err()).NotTo(HaveOccurred())
Expect(getBit.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
getBit = client.GetBit(ctx, "key", 100)
2015-01-15 18:51:22 +03:00
Expect(getBit.Err()).NotTo(HaveOccurred())
Expect(getBit.Val()).To(Equal(int64(0)))
})
It("should GetRange", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "This is a string", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
getRange := client.GetRange(ctx, "key", 0, 3)
2015-01-15 18:51:22 +03:00
Expect(getRange.Err()).NotTo(HaveOccurred())
Expect(getRange.Val()).To(Equal("This"))
2020-03-11 17:26:42 +03:00
getRange = client.GetRange(ctx, "key", -3, -1)
2015-01-15 18:51:22 +03:00
Expect(getRange.Err()).NotTo(HaveOccurred())
Expect(getRange.Val()).To(Equal("ing"))
2020-03-11 17:26:42 +03:00
getRange = client.GetRange(ctx, "key", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(getRange.Err()).NotTo(HaveOccurred())
Expect(getRange.Val()).To(Equal("This is a string"))
2020-03-11 17:26:42 +03:00
getRange = client.GetRange(ctx, "key", 10, 100)
2015-01-15 18:51:22 +03:00
Expect(getRange.Err()).NotTo(HaveOccurred())
Expect(getRange.Val()).To(Equal("string"))
})
It("should GetSet", func() {
2020-03-11 17:26:42 +03:00
incr := client.Incr(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(incr.Err()).NotTo(HaveOccurred())
Expect(incr.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
getSet := client.GetSet(ctx, "key", "0")
2015-01-15 18:51:22 +03:00
Expect(getSet.Err()).NotTo(HaveOccurred())
Expect(getSet.Val()).To(Equal("1"))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("0"))
})
It("should GetEX", func() {
set := client.Set(ctx, "key", "value", 100*time.Second)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
ttl := client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(BeNumerically("~", 100*time.Second, 3*time.Second))
getEX := client.GetEx(ctx, "key", 200*time.Second)
Expect(getEX.Err()).NotTo(HaveOccurred())
Expect(getEX.Val()).To(Equal("value"))
ttl = client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(BeNumerically("~", 200*time.Second, 3*time.Second))
})
It("should GetDel", func() {
set := client.Set(ctx, "key", "value", 0)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
getDel := client.GetDel(ctx, "key")
Expect(getDel.Err()).NotTo(HaveOccurred())
Expect(getDel.Val()).To(Equal("value"))
get := client.Get(ctx, "key")
Expect(get.Err()).To(Equal(redis.Nil))
})
2015-01-15 18:51:22 +03:00
It("should Incr", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "10", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
incr := client.Incr(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(incr.Err()).NotTo(HaveOccurred())
Expect(incr.Val()).To(Equal(int64(11)))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("11"))
})
It("should IncrBy", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "10", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
incrBy := client.IncrBy(ctx, "key", 5)
2015-01-15 18:51:22 +03:00
Expect(incrBy.Err()).NotTo(HaveOccurred())
Expect(incrBy.Val()).To(Equal(int64(15)))
})
It("should IncrByFloat", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "10.50", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
incrByFloat := client.IncrByFloat(ctx, "key", 0.1)
2015-01-15 18:51:22 +03:00
Expect(incrByFloat.Err()).NotTo(HaveOccurred())
Expect(incrByFloat.Val()).To(Equal(10.6))
2020-03-11 17:26:42 +03:00
set = client.Set(ctx, "key", "5.0e3", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
incrByFloat = client.IncrByFloat(ctx, "key", 2.0e2)
2015-01-15 18:51:22 +03:00
Expect(incrByFloat.Err()).NotTo(HaveOccurred())
Expect(incrByFloat.Val()).To(Equal(float64(5200)))
})
It("should IncrByFloatOverflow", func() {
2020-03-11 17:26:42 +03:00
incrByFloat := client.IncrByFloat(ctx, "key", 996945661)
2015-01-15 18:51:22 +03:00
Expect(incrByFloat.Err()).NotTo(HaveOccurred())
Expect(incrByFloat.Val()).To(Equal(float64(996945661)))
})
It("should MSetMGet", func() {
2020-03-11 17:26:42 +03:00
mSet := client.MSet(ctx, "key1", "hello1", "key2", "hello2")
2015-01-15 18:51:22 +03:00
Expect(mSet.Err()).NotTo(HaveOccurred())
Expect(mSet.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
mGet := client.MGet(ctx, "key1", "key2", "_")
2015-01-15 18:51:22 +03:00
Expect(mGet.Err()).NotTo(HaveOccurred())
Expect(mGet.Val()).To(Equal([]interface{}{"hello1", "hello2", nil}))
// MSet struct
type set struct {
Set1 string `redis:"set1"`
Set2 int16 `redis:"set2"`
Set3 time.Duration `redis:"set3"`
Set4 interface{} `redis:"set4"`
Set5 map[string]interface{} `redis:"-"`
}
mSet = client.MSet(ctx, &set{
Set1: "val1",
Set2: 1024,
Set3: 2 * time.Millisecond,
Set4: nil,
Set5: map[string]interface{}{"k1": 1},
})
Expect(mSet.Err()).NotTo(HaveOccurred())
Expect(mSet.Val()).To(Equal("OK"))
mGet = client.MGet(ctx, "set1", "set2", "set3", "set4")
Expect(mGet.Err()).NotTo(HaveOccurred())
Expect(mGet.Val()).To(Equal([]interface{}{
"val1",
"1024",
strconv.Itoa(int(2 * time.Millisecond.Nanoseconds())),
"",
}))
2015-01-15 18:51:22 +03:00
})
2021-02-03 14:40:01 +03:00
It("should scan Mget", func() {
now := time.Now()
err := client.MSet(ctx, "key1", "hello1", "key2", 123, "time", now.Format(time.RFC3339Nano)).Err()
2021-02-03 14:40:01 +03:00
Expect(err).NotTo(HaveOccurred())
res := client.MGet(ctx, "key1", "key2", "_", "time")
2021-02-03 14:40:01 +03:00
Expect(res.Err()).NotTo(HaveOccurred())
type data struct {
Key1 string `redis:"key1"`
Key2 int `redis:"key2"`
Time TimeValue `redis:"time"`
2021-02-03 14:40:01 +03:00
}
var d data
Expect(res.Scan(&d)).NotTo(HaveOccurred())
Expect(d.Time.UnixNano()).To(Equal(now.UnixNano()))
d.Time.Time = time.Time{}
Expect(d).To(Equal(data{
Key1: "hello1",
Key2: 123,
Time: TimeValue{Time: time.Time{}},
}))
2021-02-03 14:40:01 +03:00
})
It("should MSetNX", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
mSetNX := client.MSetNX(ctx, "key1", "hello1", "key2", "hello2")
2015-01-15 18:51:22 +03:00
Expect(mSetNX.Err()).NotTo(HaveOccurred())
Expect(mSetNX.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
mSetNX = client.MSetNX(ctx, "key2", "hello1", "key3", "hello2")
2015-01-15 18:51:22 +03:00
Expect(mSetNX.Err()).NotTo(HaveOccurred())
Expect(mSetNX.Val()).To(Equal(false))
// set struct
// MSet struct
type set struct {
Set1 string `redis:"set1"`
Set2 int16 `redis:"set2"`
Set3 time.Duration `redis:"set3"`
Set4 interface{} `redis:"set4"`
Set5 map[string]interface{} `redis:"-"`
}
mSetNX = client.MSetNX(ctx, &set{
Set1: "val1",
Set2: 1024,
Set3: 2 * time.Millisecond,
Set4: nil,
Set5: map[string]interface{}{"k1": 1},
})
Expect(mSetNX.Err()).NotTo(HaveOccurred())
Expect(mSetNX.Val()).To(Equal(true))
2015-01-15 18:51:22 +03:00
})
It("should SetWithArgs with TTL", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
TTL: 500 * time.Millisecond,
}
err := client.SetArgs(ctx, "key", "hello", args).Err()
Expect(err).NotTo(HaveOccurred())
val, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
Eventually(func() error {
return client.Get(ctx, "key").Err()
}, "2s", "100ms").Should(Equal(redis.Nil))
})
It("should SetWithArgs with expiration date", func() {
expireAt := time.Now().AddDate(1, 1, 1)
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
ExpireAt: expireAt,
}
err := client.SetArgs(ctx, "key", "hello", args).Err()
Expect(err).NotTo(HaveOccurred())
val, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
// check the key has an expiration date
// (so a TTL value different of -1)
ttl := client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).ToNot(Equal(-1))
})
It("should SetWithArgs with negative expiration date", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
ExpireAt: time.Now().AddDate(-3, 1, 1),
}
// redis accepts a timestamp less than the current date
// but returns nil when trying to get the key
err := client.SetArgs(ctx, "key", "hello", args).Err()
Expect(err).NotTo(HaveOccurred())
val, err := client.Get(ctx, "key").Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with keepttl", func() {
// Set with ttl
2021-02-17 16:12:10 +03:00
argsWithTTL := redis.SetArgs{
TTL: 5 * time.Second,
}
set := client.SetArgs(ctx, "key", "hello", argsWithTTL)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Result()).To(Equal("OK"))
// Set with keepttl
2021-02-17 16:12:10 +03:00
argsWithKeepTTL := redis.SetArgs{
KeepTTL: true,
}
set = client.SetArgs(ctx, "key", "hello", argsWithKeepTTL)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Result()).To(Equal("OK"))
ttl := client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
// set keepttl will Retain the ttl associated with the key
Expect(ttl.Val().Nanoseconds()).NotTo(Equal(-1))
})
It("should SetWithArgs with NX mode and key exists", func() {
err := client.Set(ctx, "key", "hello", 0).Err()
Expect(err).NotTo(HaveOccurred())
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Mode: "nx",
}
val, err := client.SetArgs(ctx, "key", "hello", args).Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with NX mode and key does not exist", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Mode: "nx",
}
val, err := client.SetArgs(ctx, "key", "hello", args).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("OK"))
})
It("should SetWithArgs with NX mode and GET option", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Mode: "nx",
Get: true,
}
val, err := client.SetArgs(ctx, "key", "hello", args).Result()
2022-06-04 17:25:12 +03:00
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with expiration, NX mode, and key does not exist", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
TTL: 500 * time.Millisecond,
Mode: "nx",
}
val, err := client.SetArgs(ctx, "key", "hello", args).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("OK"))
Eventually(func() error {
return client.Get(ctx, "key").Err()
}, "1s", "100ms").Should(Equal(redis.Nil))
})
It("should SetWithArgs with expiration, NX mode, and key exists", func() {
e := client.Set(ctx, "key", "hello", 0)
Expect(e.Err()).NotTo(HaveOccurred())
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
TTL: 500 * time.Millisecond,
Mode: "nx",
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with expiration, NX mode, and GET option", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
TTL: 500 * time.Millisecond,
Mode: "nx",
Get: true,
}
val, err := client.SetArgs(ctx, "key", "hello", args).Result()
2022-06-04 17:25:12 +03:00
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with XX mode and key does not exist", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Mode: "xx",
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with XX mode and key exists", func() {
e := client.Set(ctx, "key", "hello", 0).Err()
Expect(e).NotTo(HaveOccurred())
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Mode: "xx",
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("OK"))
})
It("should SetWithArgs with XX mode and GET option, and key exists", func() {
e := client.Set(ctx, "key", "hello", 0).Err()
Expect(e).NotTo(HaveOccurred())
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Mode: "xx",
Get: true,
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
})
It("should SetWithArgs with XX mode and GET option, and key does not exist", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Mode: "xx",
Get: true,
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with expiration, XX mode, GET option, and key does not exist", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
TTL: 500 * time.Millisecond,
Mode: "xx",
Get: true,
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with expiration, XX mode, GET option, and key exists", func() {
e := client.Set(ctx, "key", "hello", 0)
Expect(e.Err()).NotTo(HaveOccurred())
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
TTL: 500 * time.Millisecond,
Mode: "xx",
Get: true,
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
Eventually(func() error {
return client.Get(ctx, "key").Err()
}, "1s", "100ms").Should(Equal(redis.Nil))
})
It("should SetWithArgs with Get and key does not exist yet", func() {
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Get: true,
}
val, err := client.SetArgs(ctx, "key", "hello", args).Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(Equal(""))
})
It("should SetWithArgs with Get and key exists", func() {
e := client.Set(ctx, "key", "hello", 0)
Expect(e.Err()).NotTo(HaveOccurred())
2021-02-17 16:12:10 +03:00
args := redis.SetArgs{
Get: true,
}
val, err := client.SetArgs(ctx, "key", "world", args).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
})
It("should Pipelined SetArgs with Get and key exists", func() {
e := client.Set(ctx, "key", "hello", 0)
Expect(e.Err()).NotTo(HaveOccurred())
args := redis.SetArgs{
Get: true,
}
pipe := client.Pipeline()
setArgs := pipe.SetArgs(ctx, "key", "world", args)
_, err := pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(setArgs.Err()).NotTo(HaveOccurred())
Expect(setArgs.Val()).To(Equal("hello"))
})
It("should Set with expiration", func() {
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "key", "hello", 100*time.Millisecond).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
val, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
Eventually(func() error {
return client.Get(ctx, "key").Err()
}, "1s", "100ms").Should(Equal(redis.Nil))
})
It("should Set with keepttl", func() {
// set with ttl
2020-10-22 21:38:36 +03:00
set := client.Set(ctx, "key", "hello", 5*time.Second)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
// set with keepttl
set = client.Set(ctx, "key", "hello1", redis.KeepTTL)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
ttl := client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
// set keepttl will Retain the ttl associated with the key
Expect(ttl.Val().Nanoseconds()).NotTo(Equal(-1))
})
2015-01-15 18:51:22 +03:00
It("should SetGet", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("hello"))
})
2020-10-22 21:38:36 +03:00
It("should SetEX", func() {
err := client.SetEx(ctx, "key", "hello", 1*time.Second).Err()
2020-10-22 21:38:36 +03:00
Expect(err).NotTo(HaveOccurred())
val, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
Eventually(func() error {
return client.Get(ctx, "foo").Err()
}, "2s", "100ms").Should(Equal(redis.Nil))
2020-10-22 21:38:36 +03:00
})
2015-01-15 18:51:22 +03:00
It("should SetNX", func() {
2020-03-11 17:26:42 +03:00
setNX := client.SetNX(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(setNX.Err()).NotTo(HaveOccurred())
Expect(setNX.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
setNX = client.SetNX(ctx, "key", "hello2", 0)
2015-01-15 18:51:22 +03:00
Expect(setNX.Err()).NotTo(HaveOccurred())
Expect(setNX.Val()).To(Equal(false))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("hello"))
})
It("should SetNX with expiration", func() {
2020-03-11 17:26:42 +03:00
isSet, err := client.SetNX(ctx, "key", "hello", time.Second).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(true))
2020-03-11 17:26:42 +03:00
isSet, err = client.SetNX(ctx, "key", "hello2", time.Second).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(false))
2020-03-11 17:26:42 +03:00
val, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello"))
})
It("should SetNX with keepttl", func() {
isSet, err := client.SetNX(ctx, "key", "hello1", redis.KeepTTL).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(true))
ttl := client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val().Nanoseconds()).To(Equal(int64(-1)))
})
It("should SetXX", func() {
2020-03-11 17:26:42 +03:00
isSet, err := client.SetXX(ctx, "key", "hello2", 0).Result()
2016-10-21 17:14:51 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(false))
2020-03-11 17:26:42 +03:00
err = client.Set(ctx, "key", "hello", 0).Err()
2016-10-21 17:14:51 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
isSet, err = client.SetXX(ctx, "key", "hello2", 0).Result()
2016-10-21 17:14:51 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(true))
2020-03-11 17:26:42 +03:00
val, err := client.Get(ctx, "key").Result()
2016-10-21 17:14:51 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello2"))
})
It("should SetXX with expiration", func() {
2020-03-11 17:26:42 +03:00
isSet, err := client.SetXX(ctx, "key", "hello2", time.Second).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(false))
2020-03-11 17:26:42 +03:00
err = client.Set(ctx, "key", "hello", time.Second).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
isSet, err = client.SetXX(ctx, "key", "hello2", time.Second).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(true))
2020-03-11 17:26:42 +03:00
val, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello2"))
})
It("should SetXX with keepttl", func() {
isSet, err := client.SetXX(ctx, "key", "hello2", time.Second).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(false))
err = client.Set(ctx, "key", "hello", time.Second).Err()
Expect(err).NotTo(HaveOccurred())
isSet, err = client.SetXX(ctx, "key", "hello2", 5*time.Second).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(true))
isSet, err = client.SetXX(ctx, "key", "hello3", redis.KeepTTL).Result()
Expect(err).NotTo(HaveOccurred())
Expect(isSet).To(Equal(true))
val, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal("hello3"))
// set keepttl will Retain the ttl associated with the key
ttl, err := client.TTL(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(ttl).NotTo(Equal(-1))
})
2015-01-15 18:51:22 +03:00
It("should SetRange", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "Hello World", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
range_ := client.SetRange(ctx, "key", 6, "Redis")
2015-01-15 18:51:22 +03:00
Expect(range_.Err()).NotTo(HaveOccurred())
Expect(range_.Val()).To(Equal(int64(11)))
2020-03-11 17:26:42 +03:00
get := client.Get(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(get.Err()).NotTo(HaveOccurred())
Expect(get.Val()).To(Equal("Hello Redis"))
})
It("should StrLen", func() {
2020-03-11 17:26:42 +03:00
set := client.Set(ctx, "key", "hello", 0)
2015-01-15 18:51:22 +03:00
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
strLen := client.StrLen(ctx, "key")
2015-01-15 18:51:22 +03:00
Expect(strLen.Err()).NotTo(HaveOccurred())
Expect(strLen.Val()).To(Equal(int64(5)))
2020-03-11 17:26:42 +03:00
strLen = client.StrLen(ctx, "_")
2015-01-15 18:51:22 +03:00
Expect(strLen.Err()).NotTo(HaveOccurred())
Expect(strLen.Val()).To(Equal(int64(0)))
})
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
It("should Copy", Label("NonRedisEnterprise"), func() {
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
set := client.Set(ctx, "key", "hello", 0)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
copy := client.Copy(ctx, "key", "newKey", redisOptions().DB, false)
Expect(copy.Err()).NotTo(HaveOccurred())
Expect(copy.Val()).To(Equal(int64(1)))
// Value is available by both keys now
getOld := client.Get(ctx, "key")
Expect(getOld.Err()).NotTo(HaveOccurred())
Expect(getOld.Val()).To(Equal("hello"))
getNew := client.Get(ctx, "newKey")
Expect(getNew.Err()).NotTo(HaveOccurred())
Expect(getNew.Val()).To(Equal("hello"))
// Overwriting an existing key should not succeed
overwrite := client.Copy(ctx, "newKey", "key", redisOptions().DB, false)
Expect(overwrite.Val()).To(Equal(int64(0)))
// Overwrite is allowed when replace=rue
replace := client.Copy(ctx, "newKey", "key", redisOptions().DB, true)
Expect(replace.Val()).To(Equal(int64(1)))
})
It("should acl dryrun", func() {
dryRun := client.ACLDryRun(ctx, "default", "get", "randomKey")
Expect(dryRun.Err()).NotTo(HaveOccurred())
Expect(dryRun.Val()).To(Equal("OK"))
})
It("should fail module loadex", Label("NonRedisEnterprise"), func() {
dryRun := client.ModuleLoadex(ctx, &redis.ModuleLoadexConfig{
Path: "/path/to/non-existent-library.so",
Conf: map[string]interface{}{
"param1": "value1",
},
Args: []interface{}{
"arg1",
},
})
Expect(dryRun.Err()).To(HaveOccurred())
Expect(dryRun.Err().Error()).To(Equal("ERR Error loading the extension. Please check the server logs."))
})
It("converts the module loadex configuration to a slice of arguments correctly", func() {
conf := &redis.ModuleLoadexConfig{
Path: "/path/to/your/module.so",
Conf: map[string]interface{}{
"param1": "value1",
},
Args: []interface{}{
"arg1",
"arg2",
3,
},
}
args := conf.ToArgs()
// Test if the arguments are in the correct order
expectedArgs := []interface{}{
"MODULE",
"LOADEX",
"/path/to/your/module.so",
"CONFIG",
"param1",
"value1",
"ARGS",
"arg1",
"ARGS",
"arg2",
"ARGS",
3,
}
Expect(args).To(Equal(expectedArgs))
})
It("should ACL LOG", Label("NonRedisEnterprise"), func() {
err := client.Do(ctx, "acl", "setuser", "test", ">test", "on", "allkeys", "+get").Err()
Expect(err).NotTo(HaveOccurred())
clientAcl := redis.NewClient(redisOptions())
clientAcl.Options().Username = "test"
clientAcl.Options().Password = "test"
clientAcl.Options().DB = 0
_ = clientAcl.Set(ctx, "mystring", "foo", 0).Err()
_ = clientAcl.HSet(ctx, "myhash", "foo", "bar").Err()
_ = clientAcl.SAdd(ctx, "myset", "foo", "bar").Err()
logEntries, err := client.ACLLog(ctx, 10).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(logEntries)).To(Equal(4))
for _, entry := range logEntries {
Expect(entry.Reason).To(Equal("command"))
Expect(entry.Context).To(Equal("toplevel"))
Expect(entry.Object).NotTo(BeEmpty())
Expect(entry.Username).To(Equal("test"))
Expect(entry.AgeSeconds).To(BeNumerically(">=", 0))
Expect(entry.ClientInfo).NotTo(BeNil())
Expect(entry.EntryID).To(BeNumerically(">=", 0))
Expect(entry.TimestampCreated).To(BeNumerically(">=", 0))
Expect(entry.TimestampLastUpdated).To(BeNumerically(">=", 0))
}
limitedLogEntries, err := client.ACLLog(ctx, 2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(limitedLogEntries)).To(Equal(2))
})
It("should ACL LOG RESET", Label("NonRedisEnterprise"), func() {
// Call ACL LOG RESET
resetCmd := client.ACLLogReset(ctx)
Expect(resetCmd.Err()).NotTo(HaveOccurred())
Expect(resetCmd.Val()).To(Equal("OK"))
// Verify that the log is empty after the reset
logEntries, err := client.ACLLog(ctx, 10).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(logEntries)).To(Equal(0))
})
2015-01-15 18:51:22 +03:00
})
Describe("hashes", func() {
It("should HDel", func() {
2020-03-11 17:26:42 +03:00
hSet := client.HSet(ctx, "hash", "key", "hello")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hDel := client.HDel(ctx, "hash", "key")
2015-01-15 18:51:22 +03:00
Expect(hDel.Err()).NotTo(HaveOccurred())
Expect(hDel.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
hDel = client.HDel(ctx, "hash", "key")
2015-01-15 18:51:22 +03:00
Expect(hDel.Err()).NotTo(HaveOccurred())
Expect(hDel.Val()).To(Equal(int64(0)))
})
It("should HExists", func() {
2020-03-11 17:26:42 +03:00
hSet := client.HSet(ctx, "hash", "key", "hello")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hExists := client.HExists(ctx, "hash", "key")
2015-01-15 18:51:22 +03:00
Expect(hExists.Err()).NotTo(HaveOccurred())
Expect(hExists.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
hExists = client.HExists(ctx, "hash", "key1")
2015-01-15 18:51:22 +03:00
Expect(hExists.Err()).NotTo(HaveOccurred())
Expect(hExists.Val()).To(Equal(false))
})
It("should HGet", func() {
2020-03-11 17:26:42 +03:00
hSet := client.HSet(ctx, "hash", "key", "hello")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hGet := client.HGet(ctx, "hash", "key")
2015-01-15 18:51:22 +03:00
Expect(hGet.Err()).NotTo(HaveOccurred())
Expect(hGet.Val()).To(Equal("hello"))
2020-03-11 17:26:42 +03:00
hGet = client.HGet(ctx, "hash", "key1")
2015-01-15 18:51:22 +03:00
Expect(hGet.Err()).To(Equal(redis.Nil))
Expect(hGet.Val()).To(Equal(""))
})
It("should HGetAll", func() {
2020-03-11 17:26:42 +03:00
err := client.HSet(ctx, "hash", "key1", "hello1").Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.HSet(ctx, "hash", "key2", "hello2").Err()
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
m, err := client.HGetAll(ctx, "hash").Result()
Expect(err).NotTo(HaveOccurred())
Expect(m).To(Equal(map[string]string{"key1": "hello1", "key2": "hello2"}))
2015-01-15 18:51:22 +03:00
})
It("should scan", func() {
now := time.Now()
err := client.HMSet(ctx, "hash", "key1", "hello1", "key2", 123, "time", now.Format(time.RFC3339Nano)).Err()
Expect(err).NotTo(HaveOccurred())
res := client.HGetAll(ctx, "hash")
Expect(res.Err()).NotTo(HaveOccurred())
type data struct {
Key1 string `redis:"key1"`
Key2 int `redis:"key2"`
Time TimeValue `redis:"time"`
}
var d data
Expect(res.Scan(&d)).NotTo(HaveOccurred())
Expect(d.Time.UnixNano()).To(Equal(now.UnixNano()))
d.Time.Time = time.Time{}
Expect(d).To(Equal(data{
Key1: "hello1",
Key2: 123,
Time: TimeValue{Time: time.Time{}},
}))
type data2 struct {
Key1 string `redis:"key1"`
Key2 int `redis:"key2"`
Time time.Time `redis:"time"`
}
err = client.HSet(ctx, "hash", &data2{
Key1: "hello2",
Key2: 200,
Time: now,
}).Err()
Expect(err).NotTo(HaveOccurred())
var d2 data2
err = client.HMGet(ctx, "hash", "key1", "key2", "time").Scan(&d2)
Expect(err).NotTo(HaveOccurred())
Expect(d2.Key1).To(Equal("hello2"))
Expect(d2.Key2).To(Equal(200))
Expect(d2.Time.Unix()).To(Equal(now.Unix()))
})
2015-01-15 18:51:22 +03:00
It("should HIncrBy", func() {
2020-03-11 17:26:42 +03:00
hSet := client.HSet(ctx, "hash", "key", "5")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hIncrBy := client.HIncrBy(ctx, "hash", "key", 1)
2015-01-15 18:51:22 +03:00
Expect(hIncrBy.Err()).NotTo(HaveOccurred())
Expect(hIncrBy.Val()).To(Equal(int64(6)))
2020-03-11 17:26:42 +03:00
hIncrBy = client.HIncrBy(ctx, "hash", "key", -1)
2015-01-15 18:51:22 +03:00
Expect(hIncrBy.Err()).NotTo(HaveOccurred())
Expect(hIncrBy.Val()).To(Equal(int64(5)))
2020-03-11 17:26:42 +03:00
hIncrBy = client.HIncrBy(ctx, "hash", "key", -10)
2015-01-15 18:51:22 +03:00
Expect(hIncrBy.Err()).NotTo(HaveOccurred())
Expect(hIncrBy.Val()).To(Equal(int64(-5)))
})
It("should HIncrByFloat", func() {
2020-03-11 17:26:42 +03:00
hSet := client.HSet(ctx, "hash", "field", "10.50")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
Expect(hSet.Val()).To(Equal(int64(1)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
hIncrByFloat := client.HIncrByFloat(ctx, "hash", "field", 0.1)
2015-01-15 18:51:22 +03:00
Expect(hIncrByFloat.Err()).NotTo(HaveOccurred())
Expect(hIncrByFloat.Val()).To(Equal(10.6))
2020-03-11 17:26:42 +03:00
hSet = client.HSet(ctx, "hash", "field", "5.0e3")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
Expect(hSet.Val()).To(Equal(int64(0)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
hIncrByFloat = client.HIncrByFloat(ctx, "hash", "field", 2.0e2)
2015-01-15 18:51:22 +03:00
Expect(hIncrByFloat.Err()).NotTo(HaveOccurred())
Expect(hIncrByFloat.Val()).To(Equal(float64(5200)))
})
It("should HKeys", func() {
2020-03-11 17:26:42 +03:00
hkeys := client.HKeys(ctx, "hash")
2015-01-15 18:51:22 +03:00
Expect(hkeys.Err()).NotTo(HaveOccurred())
Expect(hkeys.Val()).To(Equal([]string{}))
2020-03-11 17:26:42 +03:00
hset := client.HSet(ctx, "hash", "key1", "hello1")
2015-01-15 18:51:22 +03:00
Expect(hset.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hset = client.HSet(ctx, "hash", "key2", "hello2")
2015-01-15 18:51:22 +03:00
Expect(hset.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hkeys = client.HKeys(ctx, "hash")
2015-01-15 18:51:22 +03:00
Expect(hkeys.Err()).NotTo(HaveOccurred())
Expect(hkeys.Val()).To(Equal([]string{"key1", "key2"}))
})
It("should HLen", func() {
2020-03-11 17:26:42 +03:00
hSet := client.HSet(ctx, "hash", "key1", "hello1")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hSet = client.HSet(ctx, "hash", "key2", "hello2")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
hLen := client.HLen(ctx, "hash")
2015-01-15 18:51:22 +03:00
Expect(hLen.Err()).NotTo(HaveOccurred())
Expect(hLen.Val()).To(Equal(int64(2)))
})
It("should HMGet", func() {
2020-03-11 17:26:42 +03:00
err := client.HSet(ctx, "hash", "key1", "hello1", "key2", "hello2").Err()
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err := client.HMGet(ctx, "hash", "key1", "key2", "_").Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]interface{}{"hello1", "hello2", nil}))
2015-01-15 18:51:22 +03:00
})
It("should HSet", func() {
2020-03-11 17:26:42 +03:00
ok, err := client.HSet(ctx, "hash", map[string]interface{}{
"key1": "hello1",
"key2": "hello2",
}).Result()
Expect(err).NotTo(HaveOccurred())
2019-12-24 13:23:32 +03:00
Expect(ok).To(Equal(int64(2)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
v, err := client.HGet(ctx, "hash", "key1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal("hello1"))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
v, err = client.HGet(ctx, "hash", "key2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal("hello2"))
2019-12-24 13:23:32 +03:00
2020-03-11 17:26:42 +03:00
keys, err := client.HKeys(ctx, "hash").Result()
2019-12-24 13:23:32 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(keys).To(ConsistOf([]string{"key1", "key2"}))
2015-01-15 18:51:22 +03:00
})
It("should HSet", func() {
2020-03-11 17:26:42 +03:00
hSet := client.HSet(ctx, "hash", "key", "hello")
2015-01-15 18:51:22 +03:00
Expect(hSet.Err()).NotTo(HaveOccurred())
Expect(hSet.Val()).To(Equal(int64(1)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
hGet := client.HGet(ctx, "hash", "key")
2015-01-15 18:51:22 +03:00
Expect(hGet.Err()).NotTo(HaveOccurred())
Expect(hGet.Val()).To(Equal("hello"))
// set struct
// MSet struct
type set struct {
Set1 string `redis:"set1"`
Set2 int16 `redis:"set2"`
Set3 time.Duration `redis:"set3"`
Set4 interface{} `redis:"set4"`
Set5 map[string]interface{} `redis:"-"`
Set6 string `redis:"set6,omitempty"`
}
hSet = client.HSet(ctx, "hash", &set{
Set1: "val1",
Set2: 1024,
Set3: 2 * time.Millisecond,
Set4: nil,
Set5: map[string]interface{}{"k1": 1},
})
Expect(hSet.Err()).NotTo(HaveOccurred())
Expect(hSet.Val()).To(Equal(int64(4)))
hMGet := client.HMGet(ctx, "hash", "set1", "set2", "set3", "set4", "set5", "set6")
Expect(hMGet.Err()).NotTo(HaveOccurred())
Expect(hMGet.Val()).To(Equal([]interface{}{
"val1",
"1024",
strconv.Itoa(int(2 * time.Millisecond.Nanoseconds())),
"",
nil,
nil,
}))
hSet = client.HSet(ctx, "hash2", &set{
Set1: "val2",
Set6: "val",
})
Expect(hSet.Err()).NotTo(HaveOccurred())
Expect(hSet.Val()).To(Equal(int64(5)))
hMGet = client.HMGet(ctx, "hash2", "set1", "set6")
Expect(hMGet.Err()).NotTo(HaveOccurred())
Expect(hMGet.Val()).To(Equal([]interface{}{
"val2",
"val",
}))
2015-01-15 18:51:22 +03:00
})
It("should HSetNX", func() {
2020-03-11 17:26:42 +03:00
hSetNX := client.HSetNX(ctx, "hash", "key", "hello")
2015-01-15 18:51:22 +03:00
Expect(hSetNX.Err()).NotTo(HaveOccurred())
Expect(hSetNX.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
hSetNX = client.HSetNX(ctx, "hash", "key", "hello")
2015-01-15 18:51:22 +03:00
Expect(hSetNX.Err()).NotTo(HaveOccurred())
Expect(hSetNX.Val()).To(Equal(false))
2020-03-11 17:26:42 +03:00
hGet := client.HGet(ctx, "hash", "key")
2015-01-15 18:51:22 +03:00
Expect(hGet.Err()).NotTo(HaveOccurred())
Expect(hGet.Val()).To(Equal("hello"))
})
It("should HVals", func() {
2020-03-11 17:26:42 +03:00
err := client.HSet(ctx, "hash", "key1", "hello1").Err()
2017-02-18 13:10:47 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.HSet(ctx, "hash", "key2", "hello2").Err()
2017-02-18 13:10:47 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
v, err := client.HVals(ctx, "hash").Result()
2017-02-18 13:10:47 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal([]string{"hello1", "hello2"}))
var slice []string
2020-03-11 17:26:42 +03:00
err = client.HVals(ctx, "hash").ScanSlice(&slice)
2017-02-18 13:10:47 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(slice).To(Equal([]string{"hello1", "hello2"}))
2015-01-15 18:51:22 +03:00
})
It("should HRandField", func() {
err := client.HSet(ctx, "hash", "key1", "hello1").Err()
Expect(err).NotTo(HaveOccurred())
err = client.HSet(ctx, "hash", "key2", "hello2").Err()
Expect(err).NotTo(HaveOccurred())
v := client.HRandField(ctx, "hash", 1)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(Or(Equal([]string{"key1"}), Equal([]string{"key2"})))
v = client.HRandField(ctx, "hash", 0)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(HaveLen(0))
kv, err := client.HRandFieldWithValues(ctx, "hash", 1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(kv).To(Or(
Equal([]redis.KeyValue{{Key: "key1", Value: "hello1"}}),
Equal([]redis.KeyValue{{Key: "key2", Value: "hello2"}}),
))
})
It("should HExpire", Label("hash-expiration", "NonRedisEnterprise"), func() {
res, err := client.HExpire(ctx, "no_such_key", 10*time.Second, "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(res).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err = client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, 1, -2}))
})
It("should HPExpire", Label("hash-expiration", "NonRedisEnterprise"), func() {
res, err := client.HPExpire(ctx, "no_such_key", 10*time.Second, "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(res).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err = client.HPExpire(ctx, "myhash", 10*time.Second, "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, 1, -2}))
})
It("should HExpireAt", Label("hash-expiration", "NonRedisEnterprise"), func() {
resEmpty, err := client.HExpireAt(ctx, "no_such_key", time.Now().Add(10*time.Second), "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err := client.HExpireAt(ctx, "myhash", time.Now().Add(10*time.Second), "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, 1, -2}))
})
It("should HPExpireAt", Label("hash-expiration", "NonRedisEnterprise"), func() {
resEmpty, err := client.HPExpireAt(ctx, "no_such_key", time.Now().Add(10*time.Second), "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err := client.HPExpireAt(ctx, "myhash", time.Now().Add(10*time.Second), "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, 1, -2}))
})
It("should HPersist", Label("hash-expiration", "NonRedisEnterprise"), func() {
resEmpty, err := client.HPersist(ctx, "no_such_key", "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err := client.HPersist(ctx, "myhash", "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{-1, -1, -2}))
res, err = client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, -2}))
res, err = client.HPersist(ctx, "myhash", "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, -1, -2}))
})
It("should HExpireTime", Label("hash-expiration", "NonRedisEnterprise"), func() {
resEmpty, err := client.HExpireTime(ctx, "no_such_key", "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err := client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, -2}))
res, err = client.HExpireTime(ctx, "myhash", "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res[0]).To(BeNumerically("~", time.Now().Add(10*time.Second).Unix(), 1))
})
It("should HPExpireTime", Label("hash-expiration", "NonRedisEnterprise"), func() {
resEmpty, err := client.HPExpireTime(ctx, "no_such_key", "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
expireAt := time.Now().Add(10 * time.Second)
res, err := client.HPExpireAt(ctx, "myhash", expireAt, "key1", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, -2}))
res, err = client.HPExpireTime(ctx, "myhash", "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(BeEquivalentTo([]int64{expireAt.UnixMilli(), -1, -2}))
})
It("should HTTL", Label("hash-expiration", "NonRedisEnterprise"), func() {
resEmpty, err := client.HTTL(ctx, "no_such_key", "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err := client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, -2}))
res, err = client.HTTL(ctx, "myhash", "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{10, -1, -2}))
})
It("should HPTTL", Label("hash-expiration", "NonRedisEnterprise"), func() {
resEmpty, err := client.HPTTL(ctx, "no_such_key", "field1", "field2", "field3").Result()
Expect(err).To(BeNil())
Expect(resEmpty).To(BeEquivalentTo([]int64{-2, -2, -2}))
for i := 0; i < 100; i++ {
sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello")
Expect(sadd.Err()).NotTo(HaveOccurred())
}
res, err := client.HExpire(ctx, "myhash", 10*time.Second, "key1", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]int64{1, -2}))
res, err = client.HPTTL(ctx, "myhash", "key1", "key2", "key200").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res[0]).To(BeNumerically("~", 10*time.Second.Milliseconds(), 1))
})
2015-01-15 18:51:22 +03:00
})
2015-11-04 10:34:58 +03:00
Describe("hyperloglog", func() {
It("should PFMerge", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
pfAdd := client.PFAdd(ctx, "hll1", "1", "2", "3", "4", "5")
2015-11-04 10:34:58 +03:00
Expect(pfAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
pfCount := client.PFCount(ctx, "hll1")
2015-11-04 10:34:58 +03:00
Expect(pfCount.Err()).NotTo(HaveOccurred())
Expect(pfCount.Val()).To(Equal(int64(5)))
2020-03-11 17:26:42 +03:00
pfAdd = client.PFAdd(ctx, "hll2", "a", "b", "c", "d", "e")
2015-11-04 10:34:58 +03:00
Expect(pfAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
pfMerge := client.PFMerge(ctx, "hllMerged", "hll1", "hll2")
2015-11-04 10:34:58 +03:00
Expect(pfMerge.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
pfCount = client.PFCount(ctx, "hllMerged")
2015-11-04 10:34:58 +03:00
Expect(pfCount.Err()).NotTo(HaveOccurred())
Expect(pfCount.Val()).To(Equal(int64(10)))
2020-03-11 17:26:42 +03:00
pfCount = client.PFCount(ctx, "hll1", "hll2")
Expect(pfCount.Err()).NotTo(HaveOccurred())
Expect(pfCount.Val()).To(Equal(int64(10)))
2015-11-04 10:34:58 +03:00
})
})
2015-01-15 18:51:22 +03:00
Describe("lists", func() {
It("should BLPop", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list1", "a", "b", "c")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
bLPop := client.BLPop(ctx, 0, "list1", "list2")
2015-01-15 18:51:22 +03:00
Expect(bLPop.Err()).NotTo(HaveOccurred())
Expect(bLPop.Val()).To(Equal([]string{"list1", "a"}))
})
It("should BLPopBlocks", func() {
started := make(chan bool)
done := make(chan bool)
go func() {
2015-01-31 16:20:37 +03:00
defer GinkgoRecover()
2015-01-15 18:51:22 +03:00
started <- true
2020-03-11 17:26:42 +03:00
bLPop := client.BLPop(ctx, 0, "list")
2015-01-15 18:51:22 +03:00
Expect(bLPop.Err()).NotTo(HaveOccurred())
Expect(bLPop.Val()).To(Equal([]string{"list", "a"}))
done <- true
}()
<-started
select {
case <-done:
Fail("BLPop is not blocked")
case <-time.After(time.Second):
// ok
}
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "a")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
select {
case <-done:
// ok
case <-time.After(time.Second):
Fail("BLPop is still blocked")
}
})
It("should BLPop timeout", func() {
2020-03-11 17:26:42 +03:00
val, err := client.BLPop(ctx, time.Second, "list1").Result()
2016-03-17 19:00:47 +03:00
Expect(err).To(Equal(redis.Nil))
Expect(val).To(BeNil())
2020-03-11 17:26:42 +03:00
Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
2016-03-17 19:00:47 +03:00
stats := client.PoolStats()
Expect(stats.Hits).To(Equal(uint32(2)))
Expect(stats.Misses).To(Equal(uint32(1)))
2016-03-17 19:00:47 +03:00
Expect(stats.Timeouts).To(Equal(uint32(0)))
2015-01-15 18:51:22 +03:00
})
It("should BRPop", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list1", "a", "b", "c")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
bRPop := client.BRPop(ctx, 0, "list1", "list2")
2015-01-15 18:51:22 +03:00
Expect(bRPop.Err()).NotTo(HaveOccurred())
Expect(bRPop.Val()).To(Equal([]string{"list1", "c"}))
})
2015-04-07 12:42:16 +03:00
It("should BRPop blocks", func() {
2015-01-15 18:51:22 +03:00
started := make(chan bool)
done := make(chan bool)
go func() {
2015-01-31 16:20:37 +03:00
defer GinkgoRecover()
2015-01-15 18:51:22 +03:00
started <- true
2020-03-11 17:26:42 +03:00
brpop := client.BRPop(ctx, 0, "list")
2015-01-15 18:51:22 +03:00
Expect(brpop.Err()).NotTo(HaveOccurred())
Expect(brpop.Val()).To(Equal([]string{"list", "a"}))
done <- true
}()
<-started
select {
case <-done:
Fail("BRPop is not blocked")
case <-time.After(time.Second):
// ok
}
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "a")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
select {
case <-done:
// ok
case <-time.After(time.Second):
Fail("BRPop is still blocked")
// ok
}
})
It("should BRPopLPush", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
_, err := client.BRPopLPush(ctx, "list1", "list2", time.Second).Result()
2015-12-22 12:02:18 +03:00
Expect(err).To(Equal(redis.Nil))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
err = client.RPush(ctx, "list1", "a", "b", "c").Err()
2015-12-22 12:02:18 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
v, err := client.BRPopLPush(ctx, "list1", "list2", 0).Result()
2015-12-22 12:02:18 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal("c"))
2015-01-15 18:51:22 +03:00
})
It("should LCS", Label("NonRedisEnterprise"), func() {
err := client.MSet(ctx, "key1", "ohmytext", "key2", "mynewtext").Err()
Expect(err).NotTo(HaveOccurred())
lcs, err := client.LCS(ctx, &redis.LCSQuery{
Key1: "key1",
Key2: "key2",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(lcs.MatchString).To(Equal("mytext"))
lcs, err = client.LCS(ctx, &redis.LCSQuery{
Key1: "nonexistent_key1",
Key2: "key2",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(lcs.MatchString).To(Equal(""))
lcs, err = client.LCS(ctx, &redis.LCSQuery{
Key1: "key1",
Key2: "key2",
Len: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(lcs.MatchString).To(Equal(""))
Expect(lcs.Len).To(Equal(int64(6)))
lcs, err = client.LCS(ctx, &redis.LCSQuery{
Key1: "key1",
Key2: "key2",
Idx: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(lcs.MatchString).To(Equal(""))
Expect(lcs.Len).To(Equal(int64(6)))
Expect(lcs.Matches).To(Equal([]redis.LCSMatchedPosition{
{
Key1: redis.LCSPosition{Start: 4, End: 7},
Key2: redis.LCSPosition{Start: 5, End: 8},
MatchLen: 0,
},
{
Key1: redis.LCSPosition{Start: 2, End: 3},
Key2: redis.LCSPosition{Start: 0, End: 1},
MatchLen: 0,
},
}))
lcs, err = client.LCS(ctx, &redis.LCSQuery{
Key1: "key1",
Key2: "key2",
Idx: true,
MinMatchLen: 3,
WithMatchLen: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(lcs.MatchString).To(Equal(""))
Expect(lcs.Len).To(Equal(int64(6)))
Expect(lcs.Matches).To(Equal([]redis.LCSMatchedPosition{
{
Key1: redis.LCSPosition{Start: 4, End: 7},
Key2: redis.LCSPosition{Start: 5, End: 8},
MatchLen: 4,
},
}))
_, err = client.Set(ctx, "keywithstringvalue", "golang", 0).Result()
Expect(err).NotTo(HaveOccurred())
_, err = client.LPush(ctx, "keywithnonstringvalue", "somevalue").Result()
Expect(err).NotTo(HaveOccurred())
_, err = client.LCS(ctx, &redis.LCSQuery{
Key1: "keywithstringvalue",
Key2: "keywithnonstringvalue",
}).Result()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal("ERR The specified keys must contain string values"))
})
2015-01-15 18:51:22 +03:00
It("should LIndex", func() {
2020-03-11 17:26:42 +03:00
lPush := client.LPush(ctx, "list", "World")
2015-01-15 18:51:22 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lPush = client.LPush(ctx, "list", "Hello")
2015-01-15 18:51:22 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lIndex := client.LIndex(ctx, "list", 0)
2015-01-15 18:51:22 +03:00
Expect(lIndex.Err()).NotTo(HaveOccurred())
Expect(lIndex.Val()).To(Equal("Hello"))
2020-03-11 17:26:42 +03:00
lIndex = client.LIndex(ctx, "list", -1)
2015-01-15 18:51:22 +03:00
Expect(lIndex.Err()).NotTo(HaveOccurred())
Expect(lIndex.Val()).To(Equal("World"))
2020-03-11 17:26:42 +03:00
lIndex = client.LIndex(ctx, "list", 3)
2015-01-15 18:51:22 +03:00
Expect(lIndex.Err()).To(Equal(redis.Nil))
Expect(lIndex.Val()).To(Equal(""))
})
It("should LInsert", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "Hello")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "World")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lInsert := client.LInsert(ctx, "list", "BEFORE", "World", "There")
2015-01-15 18:51:22 +03:00
Expect(lInsert.Err()).NotTo(HaveOccurred())
Expect(lInsert.Val()).To(Equal(int64(3)))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"Hello", "There", "World"}))
})
It("should LMPop", Label("NonRedisEnterprise"), func() {
err := client.LPush(ctx, "list1", "one", "two", "three", "four", "five").Err()
Expect(err).NotTo(HaveOccurred())
err = client.LPush(ctx, "list2", "a", "b", "c", "d", "e").Err()
Expect(err).NotTo(HaveOccurred())
key, val, err := client.LMPop(ctx, "left", 3, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list1"))
Expect(val).To(Equal([]string{"five", "four", "three"}))
key, val, err = client.LMPop(ctx, "right", 3, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list1"))
Expect(val).To(Equal([]string{"one", "two"}))
key, val, err = client.LMPop(ctx, "left", 1, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list2"))
Expect(val).To(Equal([]string{"e"}))
key, val, err = client.LMPop(ctx, "right", 10, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list2"))
Expect(val).To(Equal([]string{"a", "b", "c", "d"}))
err = client.LMPop(ctx, "left", 10, "list1", "list2").Err()
Expect(err).To(Equal(redis.Nil))
err = client.Set(ctx, "list3", 1024, 0).Err()
Expect(err).NotTo(HaveOccurred())
err = client.LMPop(ctx, "left", 10, "list1", "list2", "list3").Err()
Expect(err.Error()).To(Equal("WRONGTYPE Operation against a key holding the wrong kind of value"))
err = client.LMPop(ctx, "right", 0, "list1", "list2").Err()
Expect(err).To(HaveOccurred())
})
It("should BLMPop", Label("NonRedisEnterprise"), func() {
err := client.LPush(ctx, "list1", "one", "two", "three", "four", "five").Err()
Expect(err).NotTo(HaveOccurred())
err = client.LPush(ctx, "list2", "a", "b", "c", "d", "e").Err()
Expect(err).NotTo(HaveOccurred())
key, val, err := client.BLMPop(ctx, 0, "left", 3, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list1"))
Expect(val).To(Equal([]string{"five", "four", "three"}))
key, val, err = client.BLMPop(ctx, 0, "right", 3, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list1"))
Expect(val).To(Equal([]string{"one", "two"}))
key, val, err = client.BLMPop(ctx, 0, "left", 1, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list2"))
Expect(val).To(Equal([]string{"e"}))
key, val, err = client.BLMPop(ctx, 0, "right", 10, "list1", "list2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list2"))
Expect(val).To(Equal([]string{"a", "b", "c", "d"}))
})
It("should BLMPopBlocks", func() {
started := make(chan bool)
done := make(chan bool)
go func() {
defer GinkgoRecover()
started <- true
key, val, err := client.BLMPop(ctx, 0, "left", 1, "list_list").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list_list"))
Expect(val).To(Equal([]string{"a"}))
done <- true
}()
<-started
select {
case <-done:
Fail("BLMPop is not blocked")
case <-time.After(time.Second):
// ok
}
_, err := client.LPush(ctx, "list_list", "a").Result()
Expect(err).NotTo(HaveOccurred())
select {
case <-done:
// ok
case <-time.After(time.Second):
Fail("BLMPop is still blocked")
}
})
It("should BLMPop timeout", func() {
_, val, err := client.BLMPop(ctx, time.Second, "left", 1, "list1").Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(BeNil())
Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
stats := client.PoolStats()
Expect(stats.Hits).To(Equal(uint32(2)))
Expect(stats.Misses).To(Equal(uint32(1)))
Expect(stats.Timeouts).To(Equal(uint32(0)))
})
2015-01-15 18:51:22 +03:00
It("should LLen", func() {
2020-03-11 17:26:42 +03:00
lPush := client.LPush(ctx, "list", "World")
2015-01-15 18:51:22 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lPush = client.LPush(ctx, "list", "Hello")
2015-01-15 18:51:22 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lLen := client.LLen(ctx, "list")
2015-01-15 18:51:22 +03:00
Expect(lLen.Err()).NotTo(HaveOccurred())
Expect(lLen.Val()).To(Equal(int64(2)))
})
It("should LPop", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "one")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "two")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "three")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lPop := client.LPop(ctx, "list")
2015-01-15 18:51:22 +03:00
Expect(lPop.Err()).NotTo(HaveOccurred())
Expect(lPop.Val()).To(Equal("one"))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"two", "three"}))
})
It("should LPopCount", func() {
rPush := client.RPush(ctx, "list", "one")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "two")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "three")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "four")
Expect(rPush.Err()).NotTo(HaveOccurred())
lPopCount := client.LPopCount(ctx, "list", 2)
Expect(lPopCount.Err()).NotTo(HaveOccurred())
Expect(lPopCount.Val()).To(Equal([]string{"one", "two"}))
lRange := client.LRange(ctx, "list", 0, -1)
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"three", "four"}))
})
2020-11-17 09:48:46 +03:00
It("should LPos", func() {
rPush := client.RPush(ctx, "list", "a")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "b")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "c")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "b")
Expect(rPush.Err()).NotTo(HaveOccurred())
lPos := client.LPos(ctx, "list", "b", redis.LPosArgs{})
Expect(lPos.Err()).NotTo(HaveOccurred())
Expect(lPos.Val()).To(Equal(int64(1)))
lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: 2})
Expect(lPos.Err()).NotTo(HaveOccurred())
Expect(lPos.Val()).To(Equal(int64(3)))
lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: -2})
Expect(lPos.Err()).NotTo(HaveOccurred())
Expect(lPos.Val()).To(Equal(int64(1)))
lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: 2, MaxLen: 1})
Expect(lPos.Err()).To(Equal(redis.Nil))
lPos = client.LPos(ctx, "list", "z", redis.LPosArgs{})
Expect(lPos.Err()).To(Equal(redis.Nil))
})
It("should LPosCount", func() {
rPush := client.RPush(ctx, "list", "a")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "b")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "c")
Expect(rPush.Err()).NotTo(HaveOccurred())
rPush = client.RPush(ctx, "list", "b")
Expect(rPush.Err()).NotTo(HaveOccurred())
lPos := client.LPosCount(ctx, "list", "b", 2, redis.LPosArgs{})
Expect(lPos.Err()).NotTo(HaveOccurred())
Expect(lPos.Val()).To(Equal([]int64{1, 3}))
lPos = client.LPosCount(ctx, "list", "b", 2, redis.LPosArgs{Rank: 2})
Expect(lPos.Err()).NotTo(HaveOccurred())
Expect(lPos.Val()).To(Equal([]int64{3}))
lPos = client.LPosCount(ctx, "list", "b", 1, redis.LPosArgs{Rank: 1, MaxLen: 1})
Expect(lPos.Err()).NotTo(HaveOccurred())
Expect(lPos.Val()).To(Equal([]int64{}))
lPos = client.LPosCount(ctx, "list", "b", 1, redis.LPosArgs{Rank: 1, MaxLen: 0})
Expect(lPos.Err()).NotTo(HaveOccurred())
Expect(lPos.Val()).To(Equal([]int64{1}))
})
2015-01-15 18:51:22 +03:00
It("should LPush", func() {
2020-03-11 17:26:42 +03:00
lPush := client.LPush(ctx, "list", "World")
2015-01-15 18:51:22 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lPush = client.LPush(ctx, "list", "Hello")
2015-01-15 18:51:22 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
})
It("should LPushX", func() {
2020-03-11 17:26:42 +03:00
lPush := client.LPush(ctx, "list", "World")
2015-01-15 18:51:22 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lPushX := client.LPushX(ctx, "list", "Hello")
2015-01-15 18:51:22 +03:00
Expect(lPushX.Err()).NotTo(HaveOccurred())
Expect(lPushX.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
lPush = client.LPush(ctx, "list1", "three")
2019-07-18 14:18:09 +03:00
Expect(lPush.Err()).NotTo(HaveOccurred())
Expect(lPush.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
lPushX = client.LPushX(ctx, "list1", "two", "one")
2019-07-18 14:18:09 +03:00
Expect(lPushX.Err()).NotTo(HaveOccurred())
Expect(lPushX.Val()).To(Equal(int64(3)))
2020-03-11 17:26:42 +03:00
lPushX = client.LPushX(ctx, "list2", "Hello")
2015-01-15 18:51:22 +03:00
Expect(lPushX.Err()).NotTo(HaveOccurred())
Expect(lPushX.Val()).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list1", 0, -1)
2019-07-18 14:18:09 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list2", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{}))
})
It("should LRange", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "one")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "two")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "three")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, 0)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list", -3, 2)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list", -100, 100)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list", 5, 10)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{}))
})
It("should LRem", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "hello")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "hello")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "key")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "hello")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lRem := client.LRem(ctx, "list", -2, "hello")
2015-01-15 18:51:22 +03:00
Expect(lRem.Err()).NotTo(HaveOccurred())
Expect(lRem.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"hello", "key"}))
})
It("should LSet", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "one")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "two")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "three")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lSet := client.LSet(ctx, "list", 0, "four")
2015-01-15 18:51:22 +03:00
Expect(lSet.Err()).NotTo(HaveOccurred())
Expect(lSet.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
lSet = client.LSet(ctx, "list", -2, "five")
2015-01-15 18:51:22 +03:00
Expect(lSet.Err()).NotTo(HaveOccurred())
Expect(lSet.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"four", "five", "three"}))
})
It("should LTrim", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "one")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "two")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "three")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
lTrim := client.LTrim(ctx, "list", 1, -1)
2015-01-15 18:51:22 +03:00
Expect(lTrim.Err()).NotTo(HaveOccurred())
Expect(lTrim.Val()).To(Equal("OK"))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"two", "three"}))
})
It("should RPop", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "one")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "two")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "three")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPop := client.RPop(ctx, "list")
2015-01-15 18:51:22 +03:00
Expect(rPop.Err()).NotTo(HaveOccurred())
Expect(rPop.Val()).To(Equal("three"))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
})
It("should RPopCount", func() {
rPush := client.RPush(ctx, "list", "one", "two", "three", "four")
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(4)))
rPopCount := client.RPopCount(ctx, "list", 2)
Expect(rPopCount.Err()).NotTo(HaveOccurred())
Expect(rPopCount.Val()).To(Equal([]string{"four", "three"}))
lRange := client.LRange(ctx, "list", 0, -1)
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
})
It("should RPopLPush", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "one")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "two")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "three")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
rPopLPush := client.RPopLPush(ctx, "list", "list2")
2015-01-15 18:51:22 +03:00
Expect(rPopLPush.Err()).NotTo(HaveOccurred())
Expect(rPopLPush.Val()).To(Equal("three"))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list2", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"three"}))
})
It("should RPush", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "Hello")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list", "World")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
})
It("should RPushX", func() {
2020-03-11 17:26:42 +03:00
rPush := client.RPush(ctx, "list", "Hello")
2015-01-15 18:51:22 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
rPushX := client.RPushX(ctx, "list", "World")
2015-01-15 18:51:22 +03:00
Expect(rPushX.Err()).NotTo(HaveOccurred())
Expect(rPushX.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
rPush = client.RPush(ctx, "list1", "one")
2019-07-18 14:18:09 +03:00
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
rPushX = client.RPushX(ctx, "list1", "two", "three")
2019-07-18 14:18:09 +03:00
Expect(rPushX.Err()).NotTo(HaveOccurred())
Expect(rPushX.Val()).To(Equal(int64(3)))
2020-03-11 17:26:42 +03:00
rPushX = client.RPushX(ctx, "list2", "World")
2015-01-15 18:51:22 +03:00
Expect(rPushX.Err()).NotTo(HaveOccurred())
Expect(rPushX.Val()).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
lRange := client.LRange(ctx, "list", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list1", 0, -1)
2019-07-18 14:18:09 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
2020-03-11 17:26:42 +03:00
lRange = client.LRange(ctx, "list2", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{}))
})
2021-04-14 03:28:55 +03:00
It("should LMove", Label("NonRedisEnterprise"), func() {
2021-04-14 03:28:55 +03:00
rPush := client.RPush(ctx, "lmove1", "ichi")
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(1)))
rPush = client.RPush(ctx, "lmove1", "ni")
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(2)))
rPush = client.RPush(ctx, "lmove1", "san")
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(3)))
lMove := client.LMove(ctx, "lmove1", "lmove2", "RIGHT", "LEFT")
Expect(lMove.Err()).NotTo(HaveOccurred())
Expect(lMove.Val()).To(Equal("san"))
lRange := client.LRange(ctx, "lmove2", 0, -1)
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"san"}))
})
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
It("should BLMove", Label("NonRedisEnterprise"), func() {
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
rPush := client.RPush(ctx, "blmove1", "ichi")
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(1)))
rPush = client.RPush(ctx, "blmove1", "ni")
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(2)))
rPush = client.RPush(ctx, "blmove1", "san")
Expect(rPush.Err()).NotTo(HaveOccurred())
Expect(rPush.Val()).To(Equal(int64(3)))
blMove := client.BLMove(ctx, "blmove1", "blmove2", "RIGHT", "LEFT", time.Second)
Expect(blMove.Err()).NotTo(HaveOccurred())
Expect(blMove.Val()).To(Equal("san"))
lRange := client.LRange(ctx, "blmove2", 0, -1)
Expect(lRange.Err()).NotTo(HaveOccurred())
Expect(lRange.Val()).To(Equal([]string{"san"}))
})
2015-01-15 18:51:22 +03:00
})
Describe("sets", func() {
It("should SAdd", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "Hello")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
Expect(sAdd.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "World")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
Expect(sAdd.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "World")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
Expect(sAdd.Val()).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
Expect(sMembers.Err()).NotTo(HaveOccurred())
Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"}))
})
It("should SAdd strings", func() {
set := []string{"Hello", "World", "World"}
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", set)
Expect(sAdd.Err()).NotTo(HaveOccurred())
Expect(sAdd.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"}))
2015-01-15 18:51:22 +03:00
})
It("should SCard", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "Hello")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
Expect(sAdd.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "World")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
Expect(sAdd.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
sCard := client.SCard(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sCard.Err()).NotTo(HaveOccurred())
Expect(sCard.Val()).To(Equal(int64(2)))
})
It("should SDiff", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set1", "a")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "b")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "d")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "e")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sDiff := client.SDiff(ctx, "set1", "set2")
2015-01-15 18:51:22 +03:00
Expect(sDiff.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(sDiff.Val()).To(ConsistOf([]string{"a", "b"}))
2015-01-15 18:51:22 +03:00
})
It("should SDiffStore", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set1", "a")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "b")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "d")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "e")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sDiffStore := client.SDiffStore(ctx, "set", "set1", "set2")
2015-01-15 18:51:22 +03:00
Expect(sDiffStore.Err()).NotTo(HaveOccurred())
Expect(sDiffStore.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(sMembers.Val()).To(ConsistOf([]string{"a", "b"}))
2015-01-15 18:51:22 +03:00
})
It("should SInter", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set1", "a")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "b")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "d")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "e")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sInter := client.SInter(ctx, "set1", "set2")
2015-01-15 18:51:22 +03:00
Expect(sInter.Err()).NotTo(HaveOccurred())
Expect(sInter.Val()).To(Equal([]string{"c"}))
})
It("should SInterCard", Label("NonRedisEnterprise"), func() {
sAdd := client.SAdd(ctx, "set1", "a")
Expect(sAdd.Err()).NotTo(HaveOccurred())
sAdd = client.SAdd(ctx, "set1", "b")
Expect(sAdd.Err()).NotTo(HaveOccurred())
sAdd = client.SAdd(ctx, "set1", "c")
Expect(sAdd.Err()).NotTo(HaveOccurred())
sAdd = client.SAdd(ctx, "set2", "b")
Expect(sAdd.Err()).NotTo(HaveOccurred())
sAdd = client.SAdd(ctx, "set2", "c")
Expect(sAdd.Err()).NotTo(HaveOccurred())
sAdd = client.SAdd(ctx, "set2", "d")
Expect(sAdd.Err()).NotTo(HaveOccurred())
sAdd = client.SAdd(ctx, "set2", "e")
Expect(sAdd.Err()).NotTo(HaveOccurred())
2023-01-23 09:48:54 +03:00
// limit 0 means no limit,see https://redis.io/commands/sintercard/ for more details
sInterCard := client.SInterCard(ctx, 0, "set1", "set2")
Expect(sInterCard.Err()).NotTo(HaveOccurred())
Expect(sInterCard.Val()).To(Equal(int64(2)))
sInterCard = client.SInterCard(ctx, 1, "set1", "set2")
Expect(sInterCard.Err()).NotTo(HaveOccurred())
Expect(sInterCard.Val()).To(Equal(int64(1)))
sInterCard = client.SInterCard(ctx, 3, "set1", "set2")
Expect(sInterCard.Err()).NotTo(HaveOccurred())
Expect(sInterCard.Val()).To(Equal(int64(2)))
})
It("should SInterStore", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set1", "a")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "b")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "d")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "e")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sInterStore := client.SInterStore(ctx, "set", "set1", "set2")
2015-01-15 18:51:22 +03:00
Expect(sInterStore.Err()).NotTo(HaveOccurred())
Expect(sInterStore.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
Expect(sMembers.Val()).To(Equal([]string{"c"}))
})
It("should IsMember", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "one")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sIsMember := client.SIsMember(ctx, "set", "one")
2015-01-15 18:51:22 +03:00
Expect(sIsMember.Err()).NotTo(HaveOccurred())
Expect(sIsMember.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
sIsMember = client.SIsMember(ctx, "set", "two")
2015-01-15 18:51:22 +03:00
Expect(sIsMember.Err()).NotTo(HaveOccurred())
Expect(sIsMember.Val()).To(Equal(false))
})
2021-04-28 08:56:44 +03:00
It("should SMIsMember", func() {
sAdd := client.SAdd(ctx, "set", "one")
Expect(sAdd.Err()).NotTo(HaveOccurred())
sMIsMember := client.SMIsMember(ctx, "set", "one", "two")
Expect(sMIsMember.Err()).NotTo(HaveOccurred())
Expect(sMIsMember.Val()).To(Equal([]bool{true, false}))
})
2015-01-15 18:51:22 +03:00
It("should SMembers", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "Hello")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "World")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"}))
2015-01-15 18:51:22 +03:00
})
2017-11-19 19:36:23 +03:00
It("should SMembersMap", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "Hello")
2017-11-19 19:36:23 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "World")
2017-11-19 19:36:23 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sMembersMap := client.SMembersMap(ctx, "set")
2017-11-19 19:36:23 +03:00
Expect(sMembersMap.Err()).NotTo(HaveOccurred())
2018-10-11 13:54:30 +03:00
Expect(sMembersMap.Val()).To(Equal(map[string]struct{}{"Hello": {}, "World": {}}))
2017-11-19 19:36:23 +03:00
})
It("should SMove", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set1", "one")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "two")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "three")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sMove := client.SMove(ctx, "set1", "set2", "two")
2015-01-15 18:51:22 +03:00
Expect(sMove.Err()).NotTo(HaveOccurred())
Expect(sMove.Val()).To(Equal(true))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set1")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
Expect(sMembers.Val()).To(Equal([]string{"one"}))
2020-03-11 17:26:42 +03:00
sMembers = client.SMembers(ctx, "set2")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(sMembers.Val()).To(ConsistOf([]string{"three", "two"}))
2015-01-15 18:51:22 +03:00
})
It("should SPop", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "one")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "two")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "three")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sPop := client.SPop(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sPop.Err()).NotTo(HaveOccurred())
Expect(sPop.Val()).NotTo(Equal(""))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
Expect(sMembers.Val()).To(HaveLen(2))
})
It("should SPopN", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "one")
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "two")
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "three")
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "four")
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sPopN := client.SPopN(ctx, "set", 1)
Expect(sPopN.Err()).NotTo(HaveOccurred())
Expect(sPopN.Val()).NotTo(Equal([]string{""}))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
Expect(sMembers.Err()).NotTo(HaveOccurred())
Expect(sMembers.Val()).To(HaveLen(3))
2020-03-11 17:26:42 +03:00
sPopN = client.SPopN(ctx, "set", 4)
Expect(sPopN.Err()).NotTo(HaveOccurred())
Expect(sPopN.Val()).To(HaveLen(3))
2020-03-11 17:26:42 +03:00
sMembers = client.SMembers(ctx, "set")
Expect(sMembers.Err()).NotTo(HaveOccurred())
Expect(sMembers.Val()).To(HaveLen(0))
2015-01-15 18:51:22 +03:00
})
2015-08-25 14:02:16 +03:00
It("should SRandMember and SRandMemberN", func() {
2020-03-11 17:26:42 +03:00
err := client.SAdd(ctx, "set", "one").Err()
2015-08-25 14:02:16 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.SAdd(ctx, "set", "two").Err()
2015-08-25 14:02:16 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.SAdd(ctx, "set", "three").Err()
2015-08-25 14:02:16 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
members, err := client.SMembers(ctx, "set").Result()
2015-08-25 14:02:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(members).To(HaveLen(3))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
member, err := client.SRandMember(ctx, "set").Result()
2015-08-25 14:02:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(member).NotTo(Equal(""))
2020-03-11 17:26:42 +03:00
members, err = client.SRandMemberN(ctx, "set", 2).Result()
2015-08-25 14:02:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(members).To(HaveLen(2))
2015-01-15 18:51:22 +03:00
})
It("should SRem", func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set", "one")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "two")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set", "three")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sRem := client.SRem(ctx, "set", "one")
2015-01-15 18:51:22 +03:00
Expect(sRem.Err()).NotTo(HaveOccurred())
Expect(sRem.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
sRem = client.SRem(ctx, "set", "four")
2015-01-15 18:51:22 +03:00
Expect(sRem.Err()).NotTo(HaveOccurred())
Expect(sRem.Val()).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
2015-02-09 11:14:41 +03:00
Expect(sMembers.Val()).To(ConsistOf([]string{"three", "two"}))
2015-01-15 18:51:22 +03:00
})
It("should SUnion", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set1", "a")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "b")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "d")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "e")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sUnion := client.SUnion(ctx, "set1", "set2")
2015-01-15 18:51:22 +03:00
Expect(sUnion.Err()).NotTo(HaveOccurred())
Expect(sUnion.Val()).To(HaveLen(5))
})
It("should SUnionStore", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
sAdd := client.SAdd(ctx, "set1", "a")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "b")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set1", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "c")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "d")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sAdd = client.SAdd(ctx, "set2", "e")
2015-01-15 18:51:22 +03:00
Expect(sAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
sUnionStore := client.SUnionStore(ctx, "set", "set1", "set2")
2015-01-15 18:51:22 +03:00
Expect(sUnionStore.Err()).NotTo(HaveOccurred())
Expect(sUnionStore.Val()).To(Equal(int64(5)))
2020-03-11 17:26:42 +03:00
sMembers := client.SMembers(ctx, "set")
2015-01-15 18:51:22 +03:00
Expect(sMembers.Err()).NotTo(HaveOccurred())
Expect(sMembers.Val()).To(HaveLen(5))
})
})
Describe("sorted sets", func() {
It("should BZPopMax", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{
2018-10-31 16:35:23 +03:00
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{
2018-10-31 16:35:23 +03:00
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{
2018-10-31 16:35:23 +03:00
Score: 3,
Member: "three",
}).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
member, err := client.BZPopMax(ctx, 0, "zset1", "zset2").Result()
2018-10-31 16:35:23 +03:00
Expect(err).NotTo(HaveOccurred())
2019-05-16 16:27:19 +03:00
Expect(member).To(Equal(&redis.ZWithKey{
2018-11-03 13:07:25 +03:00
Z: redis.Z{
Score: 3,
Member: "three",
},
Key: "zset1",
2018-10-31 16:35:23 +03:00
}))
})
It("should BZPopMax blocks", func() {
started := make(chan bool)
done := make(chan bool)
go func() {
defer GinkgoRecover()
started <- true
2020-03-11 17:26:42 +03:00
bZPopMax := client.BZPopMax(ctx, 0, "zset")
2018-10-31 16:35:23 +03:00
Expect(bZPopMax.Err()).NotTo(HaveOccurred())
2019-05-16 16:27:19 +03:00
Expect(bZPopMax.Val()).To(Equal(&redis.ZWithKey{
2018-11-03 13:07:25 +03:00
Z: redis.Z{
Member: "a",
Score: 1,
},
Key: "zset",
2018-10-31 16:35:23 +03:00
}))
done <- true
}()
<-started
select {
case <-done:
Fail("BZPopMax is not blocked")
case <-time.After(time.Second):
// ok
}
zAdd := client.ZAdd(ctx, "zset", redis.Z{
2018-10-31 16:35:23 +03:00
Member: "a",
Score: 1,
})
Expect(zAdd.Err()).NotTo(HaveOccurred())
select {
case <-done:
// ok
case <-time.After(time.Second):
Fail("BZPopMax is still blocked")
}
})
It("should BZPopMax timeout", func() {
2020-03-11 17:26:42 +03:00
val, err := client.BZPopMax(ctx, time.Second, "zset1").Result()
2018-10-31 16:35:23 +03:00
Expect(err).To(Equal(redis.Nil))
2019-05-16 16:27:19 +03:00
Expect(val).To(BeNil())
2018-10-31 16:35:23 +03:00
2020-03-11 17:26:42 +03:00
Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
2018-10-31 16:35:23 +03:00
stats := client.PoolStats()
Expect(stats.Hits).To(Equal(uint32(2)))
Expect(stats.Misses).To(Equal(uint32(1)))
2018-10-31 16:35:23 +03:00
Expect(stats.Timeouts).To(Equal(uint32(0)))
})
It("should BZPopMin", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{
2018-10-31 16:35:23 +03:00
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{
2018-10-31 16:35:23 +03:00
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{
2018-10-31 16:35:23 +03:00
Score: 3,
Member: "three",
}).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
member, err := client.BZPopMin(ctx, 0, "zset1", "zset2").Result()
2018-10-31 16:35:23 +03:00
Expect(err).NotTo(HaveOccurred())
2019-05-16 16:27:19 +03:00
Expect(member).To(Equal(&redis.ZWithKey{
2018-11-03 13:07:25 +03:00
Z: redis.Z{
Score: 1,
Member: "one",
},
Key: "zset1",
2018-10-31 16:35:23 +03:00
}))
})
It("should BZPopMin blocks", func() {
started := make(chan bool)
done := make(chan bool)
go func() {
defer GinkgoRecover()
started <- true
2020-03-11 17:26:42 +03:00
bZPopMin := client.BZPopMin(ctx, 0, "zset")
2018-10-31 16:35:23 +03:00
Expect(bZPopMin.Err()).NotTo(HaveOccurred())
2019-05-16 16:27:19 +03:00
Expect(bZPopMin.Val()).To(Equal(&redis.ZWithKey{
2018-11-03 13:07:25 +03:00
Z: redis.Z{
Member: "a",
Score: 1,
},
Key: "zset",
2018-10-31 16:35:23 +03:00
}))
done <- true
}()
<-started
select {
case <-done:
Fail("BZPopMin is not blocked")
case <-time.After(time.Second):
// ok
}
zAdd := client.ZAdd(ctx, "zset", redis.Z{
2018-10-31 16:35:23 +03:00
Member: "a",
Score: 1,
})
Expect(zAdd.Err()).NotTo(HaveOccurred())
select {
case <-done:
// ok
case <-time.After(time.Second):
Fail("BZPopMin is still blocked")
}
})
It("should BZPopMin timeout", func() {
2020-03-11 17:26:42 +03:00
val, err := client.BZPopMin(ctx, time.Second, "zset1").Result()
2018-10-31 16:35:23 +03:00
Expect(err).To(Equal(redis.Nil))
2019-05-16 16:27:19 +03:00
Expect(val).To(BeNil())
2018-10-31 16:35:23 +03:00
2020-03-11 17:26:42 +03:00
Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
2018-10-31 16:35:23 +03:00
stats := client.PoolStats()
Expect(stats.Hits).To(Equal(uint32(2)))
Expect(stats.Misses).To(Equal(uint32(1)))
2018-10-31 16:35:23 +03:00
Expect(stats.Timeouts).To(Equal(uint32(0)))
})
2015-01-15 18:51:22 +03:00
It("should ZAdd", func() {
added, err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
2015-01-15 18:51:22 +03:00
added, err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "uno",
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
2015-01-15 18:51:22 +03:00
added, err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: "two",
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
2015-01-15 18:51:22 +03:00
added, err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 3,
Member: "two",
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 1,
Member: "uno",
}, {
Score: 3,
Member: "two",
}}))
2015-07-16 17:30:16 +03:00
})
It("should ZAdd bytes", func() {
added, err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: []byte("one"),
2018-03-07 12:56:24 +03:00
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
added, err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: []byte("uno"),
2018-03-07 12:56:24 +03:00
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
added, err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: []byte("two"),
2018-03-07 12:56:24 +03:00
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
added, err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 3,
Member: []byte("two"),
2018-03-07 12:56:24 +03:00
}).Result()
2015-07-16 17:30:16 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 1,
Member: "uno",
}, {
Score: 3,
Member: "two",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZAddArgsGTAndLT", func() {
// Test only the GT+LT options.
added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
GT: true,
Members: []redis.Z{{Score: 1, Member: "one"}},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
added, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
GT: true,
Members: []redis.Z{{Score: 2, Member: "one"}},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
added, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
LT: true,
Members: []redis.Z{{Score: 1, Member: "one"}},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
})
It("should ZAddArgsLT", func() {
added, err := client.ZAddLT(ctx, "zset", redis.Z{
Score: 2,
Member: "one",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
added, err = client.ZAddLT(ctx, "zset", redis.Z{
Score: 3,
Member: "one",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
added, err = client.ZAddLT(ctx, "zset", redis.Z{
Score: 1,
Member: "one",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
})
It("should ZAddArgsGT", func() {
added, err := client.ZAddGT(ctx, "zset", redis.Z{
Score: 2,
Member: "one",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
added, err = client.ZAddGT(ctx, "zset", redis.Z{
Score: 3,
Member: "one",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 3, Member: "one"}}))
added, err = client.ZAddGT(ctx, "zset", redis.Z{
Score: 1,
Member: "one",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{Score: 3, Member: "one"}}))
})
It("should ZAddArgsNX", func() {
added, err := client.ZAddNX(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
2015-08-29 13:08:27 +03:00
added, err = client.ZAddNX(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: "one",
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
2015-08-29 13:08:27 +03:00
})
It("should ZAddArgsXX", func() {
added, err := client.ZAddXX(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(BeEmpty())
added, err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
added, err = client.ZAddXX(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: "one",
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
2015-08-29 13:08:27 +03:00
})
It("should ZAddArgsCh", func() {
changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
Ch: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(1)))
changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
Ch: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(0)))
})
It("should ZAddArgsNXCh", func() {
changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
NX: true,
Ch: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
2015-08-29 13:08:27 +03:00
changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
NX: true,
Ch: true,
Members: []redis.Z{
{Score: 2, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}}))
2015-08-29 13:08:27 +03:00
})
It("should ZAddArgsXXCh", func() {
changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
XX: true,
Ch: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(0)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(BeEmpty())
added, err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
XX: true,
Ch: true,
Members: []redis.Z{
{Score: 2, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
2015-08-29 13:08:27 +03:00
})
It("should ZAddArgsIncr", func() {
score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(1)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
2015-08-29 13:08:27 +03:00
score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2020-03-11 17:26:42 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(2)))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
2015-08-29 13:08:27 +03:00
})
It("should ZAddArgsIncrNX", func() {
score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
NX: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(1)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
2015-08-29 13:08:27 +03:00
score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
NX: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).To(Equal(redis.Nil))
Expect(score).To(Equal(float64(0)))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
2015-08-29 13:08:27 +03:00
})
It("should ZAddArgsIncrXX", func() {
score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
XX: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).To(Equal(redis.Nil))
Expect(score).To(Equal(float64(0)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(BeEmpty())
added, err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{
XX: true,
Members: []redis.Z{
{Score: 1, Member: "one"},
},
2018-03-07 12:56:24 +03:00
}).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(2)))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-08-29 13:08:27 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}}))
2015-08-29 13:08:27 +03:00
})
2015-01-15 18:51:22 +03:00
It("should ZCard", func() {
err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
card, err := client.ZCard(ctx, "zset").Result()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(card).To(Equal(int64(2)))
2015-01-15 18:51:22 +03:00
})
It("should ZCount", func() {
err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Err()
2017-08-15 09:49:23 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: "two",
}).Err()
2017-08-15 09:49:23 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 3,
Member: "three",
}).Err()
2017-08-15 09:49:23 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
count, err := client.ZCount(ctx, "zset", "-inf", "+inf").Result()
2017-08-15 09:49:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(count).To(Equal(int64(3)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
count, err = client.ZCount(ctx, "zset", "(1", "3").Result()
2017-08-15 09:49:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(count).To(Equal(int64(2)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
count, err = client.ZLexCount(ctx, "zset", "-", "+").Result()
2017-08-15 09:49:23 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(count).To(Equal(int64(3)))
2015-01-15 18:51:22 +03:00
})
It("should ZIncrBy", func() {
err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
n, err := client.ZIncrBy(ctx, "zset", 2, "one").Result()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(float64(3)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
val, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(val).To(Equal([]redis.Z{{
Score: 2,
Member: "two",
}, {
Score: 3,
Member: "one",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZInterStore", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset3", redis.Z{Score: 3, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
n, err := client.ZInterStore(ctx, "out", &redis.ZStore{
2019-08-09 16:23:56 +03:00
Keys: []string{"zset1", "zset2"},
Weights: []float64{2, 3},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "out", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 5,
Member: "one",
}, {
Score: 10,
Member: "two",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZMPop", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
key, elems, err := client.ZMPop(ctx, "min", 1, "zset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("zset"))
Expect(elems).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}}))
_, _, err = client.ZMPop(ctx, "min", 1, "nosuchkey").Result()
Expect(err).To(Equal(redis.Nil))
err = client.ZAdd(ctx, "myzset", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "myzset", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "myzset", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
key, elems, err = client.ZMPop(ctx, "min", 1, "myzset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("myzset"))
Expect(elems).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}}))
key, elems, err = client.ZMPop(ctx, "max", 10, "myzset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("myzset"))
Expect(elems).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}, {
Score: 2,
Member: "two",
}}))
err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 4, Member: "four"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 5, Member: "five"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 6, Member: "six"}).Err()
Expect(err).NotTo(HaveOccurred())
key, elems, err = client.ZMPop(ctx, "min", 10, "myzset", "myzset2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("myzset2"))
Expect(elems).To(Equal([]redis.Z{{
Score: 4,
Member: "four",
}, {
Score: 5,
Member: "five",
}, {
Score: 6,
Member: "six",
}}))
})
It("should BZMPop", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
key, elems, err := client.BZMPop(ctx, 0, "min", 1, "zset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("zset"))
Expect(elems).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}}))
key, elems, err = client.BZMPop(ctx, 0, "max", 1, "zset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("zset"))
Expect(elems).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}}))
key, elems, err = client.BZMPop(ctx, 0, "min", 10, "zset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("zset"))
Expect(elems).To(Equal([]redis.Z{{
Score: 2,
Member: "two",
}}))
key, elems, err = client.BZMPop(ctx, 0, "max", 10, "zset2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("zset2"))
Expect(elems).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}, {
Score: 2,
Member: "two",
}, {
Score: 1,
Member: "one",
}}))
err = client.ZAdd(ctx, "myzset", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
key, elems, err = client.BZMPop(ctx, 0, "min", 10, "myzset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("myzset"))
Expect(elems).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}}))
err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 4, Member: "four"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "myzset2", redis.Z{Score: 5, Member: "five"}).Err()
Expect(err).NotTo(HaveOccurred())
key, elems, err = client.BZMPop(ctx, 0, "min", 10, "myzset", "myzset2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("myzset2"))
Expect(elems).To(Equal([]redis.Z{{
Score: 4,
Member: "four",
}, {
Score: 5,
Member: "five",
}}))
})
It("should BZMPopBlocks", func() {
started := make(chan bool)
done := make(chan bool)
go func() {
defer GinkgoRecover()
started <- true
key, elems, err := client.BZMPop(ctx, 0, "min", 1, "list_list").Result()
Expect(err).NotTo(HaveOccurred())
Expect(key).To(Equal("list_list"))
Expect(elems).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}}))
done <- true
}()
<-started
select {
case <-done:
Fail("BZMPop is not blocked")
case <-time.After(time.Second):
// ok
}
err := client.ZAdd(ctx, "list_list", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
select {
case <-done:
// ok
case <-time.After(time.Second):
Fail("BZMPop is still blocked")
}
})
It("should BZMPop timeout", func() {
_, val, err := client.BZMPop(ctx, time.Second, "min", 1, "list1").Result()
Expect(err).To(Equal(redis.Nil))
Expect(val).To(BeNil())
Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred())
stats := client.PoolStats()
Expect(stats.Hits).To(Equal(uint32(2)))
Expect(stats.Misses).To(Equal(uint32(1)))
Expect(stats.Timeouts).To(Equal(uint32(0)))
})
2021-03-05 21:02:53 +03:00
It("should ZMScore", func() {
zmScore := client.ZMScore(ctx, "zset", "one", "three")
Expect(zmScore.Err()).NotTo(HaveOccurred())
Expect(zmScore.Val()).To(HaveLen(2))
Expect(zmScore.Val()[0]).To(Equal(float64(0)))
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2021-03-05 21:02:53 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2021-03-05 21:02:53 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2021-03-05 21:02:53 +03:00
Expect(err).NotTo(HaveOccurred())
zmScore = client.ZMScore(ctx, "zset", "one", "three")
Expect(zmScore.Err()).NotTo(HaveOccurred())
Expect(zmScore.Val()).To(HaveLen(2))
Expect(zmScore.Val()[0]).To(Equal(float64(1)))
zmScore = client.ZMScore(ctx, "zset", "four")
Expect(zmScore.Err()).NotTo(HaveOccurred())
Expect(zmScore.Val()).To(HaveLen(1))
zmScore = client.ZMScore(ctx, "zset", "four", "one")
Expect(zmScore.Err()).NotTo(HaveOccurred())
Expect(zmScore.Val()).To(HaveLen(2))
})
It("should ZPopMax", func() {
err := client.ZAdd(ctx, "zset", redis.Z{
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 3,
Member: "three",
}).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
members, err := client.ZPopMax(ctx, "zset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(members).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}}))
// adding back 3
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 3,
Member: "three",
}).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
members, err = client.ZPopMax(ctx, "zset", 2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(members).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}, {
Score: 2,
Member: "two",
}}))
// adding back 2 & 3
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 3,
Member: "three",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
members, err = client.ZPopMax(ctx, "zset", 10).Result()
Expect(err).NotTo(HaveOccurred())
Expect(members).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}, {
Score: 2,
Member: "two",
}, {
Score: 1,
Member: "one",
}}))
})
It("should ZPopMin", func() {
err := client.ZAdd(ctx, "zset", redis.Z{
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 2,
Member: "two",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 3,
Member: "three",
}).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
members, err := client.ZPopMin(ctx, "zset").Result()
Expect(err).NotTo(HaveOccurred())
Expect(members).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}}))
// adding back 1
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
members, err = client.ZPopMin(ctx, "zset", 2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(members).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 2,
Member: "two",
}}))
// adding back 1 & 2
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 1,
Member: "one",
}).Err()
Expect(err).NotTo(HaveOccurred())
2018-11-21 12:09:21 +03:00
err = client.ZAdd(ctx, "zset", redis.Z{
Score: 2,
Member: "two",
}).Err()
2018-11-21 12:09:21 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
members, err = client.ZPopMin(ctx, "zset", 10).Result()
Expect(err).NotTo(HaveOccurred())
Expect(members).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 2,
Member: "two",
}, {
Score: 3,
Member: "three",
}}))
})
2015-01-15 18:51:22 +03:00
It("should ZRange", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRange := client.ZRange(ctx, "zset", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(zRange.Err()).NotTo(HaveOccurred())
Expect(zRange.Val()).To(Equal([]string{"one", "two", "three"}))
2020-03-11 17:26:42 +03:00
zRange = client.ZRange(ctx, "zset", 2, 3)
2015-01-15 18:51:22 +03:00
Expect(zRange.Err()).NotTo(HaveOccurred())
Expect(zRange.Val()).To(Equal([]string{"three"}))
2020-03-11 17:26:42 +03:00
zRange = client.ZRange(ctx, "zset", -2, -1)
2015-01-15 18:51:22 +03:00
Expect(zRange.Err()).NotTo(HaveOccurred())
Expect(zRange.Val()).To(Equal([]string{"two", "three"}))
})
It("should ZRangeWithScores", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 2,
Member: "two",
}, {
Score: 3,
Member: "three",
}}))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", 2, 3).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 3, Member: "three"}}))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeWithScores(ctx, "zset", -2, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 2,
Member: "two",
}, {
Score: 3,
Member: "three",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZRangeArgs", func() {
added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
Members: []redis.Z{
{Score: 1, Member: "one"},
{Score: 2, Member: "two"},
{Score: 3, Member: "three"},
{Score: 4, Member: "four"},
},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(4)))
zRange, err := client.ZRangeArgs(ctx, redis.ZRangeArgs{
Key: "zset",
Start: 1,
Stop: 4,
ByScore: true,
Rev: true,
Offset: 1,
Count: 2,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(zRange).To(Equal([]string{"three", "two"}))
zRange, err = client.ZRangeArgs(ctx, redis.ZRangeArgs{
Key: "zset",
Start: "-",
Stop: "+",
ByLex: true,
Rev: true,
Offset: 2,
Count: 2,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(zRange).To(Equal([]string{"two", "one"}))
zRange, err = client.ZRangeArgs(ctx, redis.ZRangeArgs{
Key: "zset",
Start: "(1",
Stop: "(4",
ByScore: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(zRange).To(Equal([]string{"two", "three"}))
// withScores.
zSlice, err := client.ZRangeArgsWithScores(ctx, redis.ZRangeArgs{
Key: "zset",
Start: 1,
Stop: 4,
ByScore: true,
Rev: true,
Offset: 1,
Count: 2,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(zSlice).To(Equal([]redis.Z{
{Score: 3, Member: "three"},
{Score: 2, Member: "two"},
}))
})
2015-01-15 18:51:22 +03:00
It("should ZRangeByScore", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRangeByScore := client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "-inf",
Max: "+inf",
})
Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
Expect(zRangeByScore.Val()).To(Equal([]string{"one", "two", "three"}))
2020-03-11 17:26:42 +03:00
zRangeByScore = client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "1",
Max: "2",
})
Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
Expect(zRangeByScore.Val()).To(Equal([]string{"one", "two"}))
2020-03-11 17:26:42 +03:00
zRangeByScore = client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "(1",
Max: "2",
})
Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
Expect(zRangeByScore.Val()).To(Equal([]string{"two"}))
2020-03-11 17:26:42 +03:00
zRangeByScore = client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "(1",
Max: "(2",
})
Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
Expect(zRangeByScore.Val()).To(Equal([]string{}))
})
2015-08-23 06:38:37 +03:00
It("should ZRangeByLex", func() {
err := client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 0,
Member: "a",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 0,
Member: "b",
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{
2018-03-07 12:56:24 +03:00
Score: 0,
Member: "c",
}).Err()
Expect(err).NotTo(HaveOccurred())
2015-08-23 06:38:37 +03:00
2020-03-11 17:26:42 +03:00
zRangeByLex := client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
2015-08-23 06:38:37 +03:00
Min: "-",
Max: "+",
})
Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
Expect(zRangeByLex.Val()).To(Equal([]string{"a", "b", "c"}))
2020-03-11 17:26:42 +03:00
zRangeByLex = client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
2015-08-23 06:38:37 +03:00
Min: "[a",
Max: "[b",
})
Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
Expect(zRangeByLex.Val()).To(Equal([]string{"a", "b"}))
2020-03-11 17:26:42 +03:00
zRangeByLex = client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
2015-08-23 06:38:37 +03:00
Min: "(a",
Max: "[b",
})
Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
Expect(zRangeByLex.Val()).To(Equal([]string{"b"}))
2020-03-11 17:26:42 +03:00
zRangeByLex = client.ZRangeByLex(ctx, "zset", &redis.ZRangeBy{
2015-08-23 06:38:37 +03:00
Min: "(a",
Max: "(b",
})
Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
Expect(zRangeByLex.Val()).To(Equal([]string{}))
})
2015-01-15 18:51:22 +03:00
It("should ZRangeByScoreWithScoresMap", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "-inf",
Max: "+inf",
}).Result()
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 2,
Member: "two",
}, {
Score: 3,
Member: "three",
}}))
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "1",
Max: "2",
}).Result()
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 2,
Member: "two",
}}))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "(1",
Max: "2",
}).Result()
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "two"}}))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
vals, err = client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{
2015-01-15 18:51:22 +03:00
Min: "(1",
Max: "(2",
}).Result()
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{}))
2015-01-15 18:51:22 +03:00
})
It("should ZRangeStore", Label("NonRedisEnterprise"), func() {
added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{
Members: []redis.Z{
{Score: 1, Member: "one"},
{Score: 2, Member: "two"},
{Score: 3, Member: "three"},
{Score: 4, Member: "four"},
},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(4)))
rangeStore, err := client.ZRangeStore(ctx, "new-zset", redis.ZRangeArgs{
Key: "zset",
Start: 1,
Stop: 4,
ByScore: true,
Rev: true,
Offset: 1,
Count: 2,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(rangeStore).To(Equal(int64(2)))
zRange, err := client.ZRange(ctx, "new-zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(zRange).To(Equal([]string{"two", "three"}))
})
2015-01-15 18:51:22 +03:00
It("should ZRank", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRank := client.ZRank(ctx, "zset", "three")
2015-01-15 18:51:22 +03:00
Expect(zRank.Err()).NotTo(HaveOccurred())
Expect(zRank.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
zRank = client.ZRank(ctx, "zset", "four")
2015-01-15 18:51:22 +03:00
Expect(zRank.Err()).To(Equal(redis.Nil))
Expect(zRank.Val()).To(Equal(int64(0)))
})
It("should ZRankWithScore", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
zRankWithScore := client.ZRankWithScore(ctx, "zset", "one")
Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 0, Score: 1}))
zRankWithScore = client.ZRankWithScore(ctx, "zset", "two")
Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 1, Score: 2}))
zRankWithScore = client.ZRankWithScore(ctx, "zset", "three")
Expect(zRankWithScore.Err()).NotTo(HaveOccurred())
Expect(zRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 2, Score: 3}))
zRankWithScore = client.ZRankWithScore(ctx, "zset", "four")
Expect(zRankWithScore.Err()).To(HaveOccurred())
Expect(zRankWithScore.Err()).To(Equal(redis.Nil))
})
2015-01-15 18:51:22 +03:00
It("should ZRem", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRem := client.ZRem(ctx, "zset", "two")
2015-01-15 18:51:22 +03:00
Expect(zRem.Err()).NotTo(HaveOccurred())
Expect(zRem.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 1,
Member: "one",
}, {
Score: 3,
Member: "three",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZRemRangeByRank", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRemRangeByRank := client.ZRemRangeByRank(ctx, "zset", 0, 1)
2015-01-15 18:51:22 +03:00
Expect(zRemRangeByRank.Err()).NotTo(HaveOccurred())
Expect(zRemRangeByRank.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZRemRangeByScore", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRemRangeByScore := client.ZRemRangeByScore(ctx, "zset", "-inf", "(2")
2015-01-15 18:51:22 +03:00
Expect(zRemRangeByScore.Err()).NotTo(HaveOccurred())
Expect(zRemRangeByScore.Val()).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 2,
Member: "two",
}, {
Score: 3,
Member: "three",
}}))
2015-01-15 18:51:22 +03:00
})
2017-01-26 16:51:34 +03:00
It("should ZRemRangeByLex", func() {
zz := []redis.Z{
2018-03-07 12:56:24 +03:00
{Score: 0, Member: "aaaa"},
{Score: 0, Member: "b"},
{Score: 0, Member: "c"},
{Score: 0, Member: "d"},
{Score: 0, Member: "e"},
{Score: 0, Member: "foo"},
{Score: 0, Member: "zap"},
{Score: 0, Member: "zip"},
{Score: 0, Member: "ALPHA"},
{Score: 0, Member: "alpha"},
2017-01-26 16:51:34 +03:00
}
for _, z := range zz {
2020-03-11 17:26:42 +03:00
err := client.ZAdd(ctx, "zset", z).Err()
2017-01-26 16:51:34 +03:00
Expect(err).NotTo(HaveOccurred())
}
2020-03-11 17:26:42 +03:00
n, err := client.ZRemRangeByLex(ctx, "zset", "[alpha", "[omega").Result()
2017-01-26 16:51:34 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(6)))
2020-03-11 17:26:42 +03:00
vals, err := client.ZRange(ctx, "zset", 0, -1).Result()
2017-01-26 16:51:34 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]string{"ALPHA", "aaaa", "zap", "zip"}))
})
2015-01-15 18:51:22 +03:00
It("should ZRevRange", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRevRange := client.ZRevRange(ctx, "zset", 0, -1)
2015-01-15 18:51:22 +03:00
Expect(zRevRange.Err()).NotTo(HaveOccurred())
Expect(zRevRange.Val()).To(Equal([]string{"three", "two", "one"}))
2020-03-11 17:26:42 +03:00
zRevRange = client.ZRevRange(ctx, "zset", 2, 3)
2015-01-15 18:51:22 +03:00
Expect(zRevRange.Err()).NotTo(HaveOccurred())
Expect(zRevRange.Val()).To(Equal([]string{"one"}))
2020-03-11 17:26:42 +03:00
zRevRange = client.ZRevRange(ctx, "zset", -2, -1)
2015-01-15 18:51:22 +03:00
Expect(zRevRange.Err()).NotTo(HaveOccurred())
Expect(zRevRange.Val()).To(Equal([]string{"two", "one"}))
})
It("should ZRevRangeWithScoresMap", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
val, err := client.ZRevRangeWithScores(ctx, "zset", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(val).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}, {
Score: 2,
Member: "two",
}, {
Score: 1,
Member: "one",
}}))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
val, err = client.ZRevRangeWithScores(ctx, "zset", 2, 3).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(val).To(Equal([]redis.Z{{Score: 1, Member: "one"}}))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
val, err = client.ZRevRangeWithScores(ctx, "zset", -2, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(val).To(Equal([]redis.Z{{
Score: 2,
Member: "two",
}, {
Score: 1,
Member: "one",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZRevRangeByScore", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
vals, err := client.ZRevRangeByScore(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]string{"three", "two", "one"}))
vals, err = client.ZRevRangeByScore(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "2", Min: "(1"}).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]string{"two"}))
vals, err = client.ZRevRangeByScore(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "(2", Min: "(1"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]string{}))
})
It("should ZRevRangeByLex", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "a"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "b"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "c"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
vals, err := client.ZRevRangeByLex(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "+", Min: "-"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]string{"c", "b", "a"}))
2015-08-25 22:18:17 +03:00
vals, err = client.ZRevRangeByLex(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "[b", Min: "(a"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]string{"b"}))
2015-08-25 22:18:17 +03:00
vals, err = client.ZRevRangeByLex(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "(b", Min: "(a"}).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]string{}))
})
It("should ZRevRangeByScoreWithScores", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
vals, err := client.ZRevRangeByScoreWithScores(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}, {
Score: 2,
Member: "two",
}, {
Score: 1,
Member: "one",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZRevRangeByScoreWithScoresMap", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2018-03-07 12:56:24 +03:00
vals, err := client.ZRevRangeByScoreWithScores(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}, {
Score: 2,
Member: "two",
}, {
Score: 1,
Member: "one",
}}))
vals, err = client.ZRevRangeByScoreWithScores(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "2", Min: "(1"}).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "two"}}))
2015-01-15 18:51:22 +03:00
2018-03-07 12:56:24 +03:00
vals, err = client.ZRevRangeByScoreWithScores(
2020-03-11 17:26:42 +03:00
ctx, "zset", &redis.ZRangeBy{Max: "(2", Min: "(1"}).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(vals).To(Equal([]redis.Z{}))
2015-01-15 18:51:22 +03:00
})
It("should ZRevRank", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
zRevRank := client.ZRevRank(ctx, "zset", "one")
2015-01-15 18:51:22 +03:00
Expect(zRevRank.Err()).NotTo(HaveOccurred())
Expect(zRevRank.Val()).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
zRevRank = client.ZRevRank(ctx, "zset", "four")
2015-01-15 18:51:22 +03:00
Expect(zRevRank.Err()).To(Equal(redis.Nil))
Expect(zRevRank.Val()).To(Equal(int64(0)))
})
It("should ZRevRankWithScore", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
zRevRankWithScore := client.ZRevRankWithScore(ctx, "zset", "one")
Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 2, Score: 1}))
zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "two")
Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 1, Score: 2}))
zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "three")
Expect(zRevRankWithScore.Err()).NotTo(HaveOccurred())
Expect(zRevRankWithScore.Result()).To(Equal(redis.RankScore{Rank: 0, Score: 3}))
zRevRankWithScore = client.ZRevRankWithScore(ctx, "zset", "four")
Expect(zRevRankWithScore.Err()).To(HaveOccurred())
Expect(zRevRankWithScore.Err()).To(Equal(redis.Nil))
})
2015-01-15 18:51:22 +03:00
It("should ZScore", func() {
zAdd := client.ZAdd(ctx, "zset", redis.Z{Score: 1.001, Member: "one"})
2015-01-15 18:51:22 +03:00
Expect(zAdd.Err()).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
zScore := client.ZScore(ctx, "zset", "one")
2015-01-15 18:51:22 +03:00
Expect(zScore.Err()).NotTo(HaveOccurred())
Expect(zScore.Val()).To(Equal(1.001))
})
It("should ZUnion", Label("NonRedisEnterprise"), func() {
err := client.ZAddArgs(ctx, "zset1", redis.ZAddArgs{
Members: []redis.Z{
{Score: 1, Member: "one"},
{Score: 2, Member: "two"},
},
}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAddArgs(ctx, "zset2", redis.ZAddArgs{
Members: []redis.Z{
{Score: 1, Member: "one"},
{Score: 2, Member: "two"},
{Score: 3, Member: "three"},
},
}).Err()
Expect(err).NotTo(HaveOccurred())
union, err := client.ZUnion(ctx, redis.ZStore{
Keys: []string{"zset1", "zset2"},
Weights: []float64{2, 3},
Aggregate: "sum",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(union).To(Equal([]string{"one", "three", "two"}))
unionScores, err := client.ZUnionWithScores(ctx, redis.ZStore{
Keys: []string{"zset1", "zset2"},
Weights: []float64{2, 3},
Aggregate: "sum",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(unionScores).To(Equal([]redis.Z{
{Score: 5, Member: "one"},
{Score: 9, Member: "three"},
{Score: 10, Member: "two"},
}))
2015-01-15 18:51:22 +03:00
})
It("should ZUnionStore", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
2018-03-07 12:56:24 +03:00
Expect(err).NotTo(HaveOccurred())
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
n, err := client.ZUnionStore(ctx, "out", &redis.ZStore{
2019-08-09 16:23:56 +03:00
Keys: []string{"zset1", "zset2"},
Weights: []float64{2, 3},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
2015-01-15 18:51:22 +03:00
2020-03-11 17:26:42 +03:00
val, err := client.ZRangeWithScores(ctx, "out", 0, -1).Result()
2015-01-15 18:51:22 +03:00
Expect(err).NotTo(HaveOccurred())
2018-03-07 12:56:24 +03:00
Expect(val).To(Equal([]redis.Z{{
Score: 5,
Member: "one",
}, {
Score: 9,
Member: "three",
}, {
Score: 10,
Member: "two",
}}))
2015-01-15 18:51:22 +03:00
})
It("should ZRandMember", func() {
err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
v := client.ZRandMember(ctx, "zset", 1)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(Or(Equal([]string{"one"}), Equal([]string{"two"})))
v = client.ZRandMember(ctx, "zset", 0)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(HaveLen(0))
kv, err := client.ZRandMemberWithScores(ctx, "zset", 1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(kv).To(Or(
Equal([]redis.Z{{Member: "one", Score: 1}}),
Equal([]redis.Z{{Member: "two", Score: 2}}),
))
})
It("should ZDiff", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
v, err := client.ZDiff(ctx, "zset1", "zset2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal([]string{"two", "three"}))
})
It("should ZDiffWithScores", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
v, err := client.ZDiffWithScores(ctx, "zset1", "zset2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal([]redis.Z{
{
Member: "two",
Score: 2,
},
{
Member: "three",
Score: 3,
},
}))
})
2021-05-29 16:11:47 +03:00
It("should ZInter", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
v, err := client.ZInter(ctx, &redis.ZStore{
Keys: []string{"zset1", "zset2"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal([]string{"one", "two"}))
})
It("should ZInterCard", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
Expect(err).NotTo(HaveOccurred())
// limit 0 means no limit
sInterCard := client.ZInterCard(ctx, 0, "zset1", "zset2")
Expect(sInterCard.Err()).NotTo(HaveOccurred())
Expect(sInterCard.Val()).To(Equal(int64(2)))
sInterCard = client.ZInterCard(ctx, 1, "zset1", "zset2")
Expect(sInterCard.Err()).NotTo(HaveOccurred())
Expect(sInterCard.Val()).To(Equal(int64(1)))
sInterCard = client.ZInterCard(ctx, 3, "zset1", "zset2")
Expect(sInterCard.Err()).NotTo(HaveOccurred())
Expect(sInterCard.Val()).To(Equal(int64(2)))
})
It("should ZInterWithScores", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
2021-05-29 16:11:47 +03:00
Expect(err).NotTo(HaveOccurred())
v, err := client.ZInterWithScores(ctx, &redis.ZStore{
Keys: []string{"zset1", "zset2"},
Weights: []float64{2, 3},
Aggregate: "Max",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal([]redis.Z{
{
Member: "one",
Score: 3,
},
{
Member: "two",
Score: 6,
},
}))
})
2021-06-01 05:02:09 +03:00
It("should ZDiffStore", Label("NonRedisEnterprise"), func() {
err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err()
2021-06-01 05:02:09 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err()
2021-06-01 05:02:09 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err()
2021-06-01 05:02:09 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err()
2021-06-01 05:02:09 +03:00
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err()
2021-06-01 05:02:09 +03:00
Expect(err).NotTo(HaveOccurred())
v, err := client.ZDiffStore(ctx, "out1", "zset1", "zset2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal(int64(0)))
v, err = client.ZDiffStore(ctx, "out1", "zset2", "zset1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal(int64(1)))
vals, err := client.ZRangeWithScores(ctx, "out1", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{
Score: 3,
Member: "three",
}}))
})
2015-01-15 18:51:22 +03:00
})
2017-11-25 05:06:13 +03:00
Describe("streams", func() {
2018-08-02 14:48:46 +03:00
BeforeEach(func() {
2020-03-11 17:26:42 +03:00
id, err := client.XAdd(ctx, &redis.XAddArgs{
2018-08-02 14:48:46 +03:00
Stream: "stream",
ID: "1-0",
Values: map[string]interface{}{"uno": "un"},
2017-11-25 05:06:13 +03:00
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(id).To(Equal("1-0"))
// Values supports []interface{}.
2020-03-11 17:26:42 +03:00
id, err = client.XAdd(ctx, &redis.XAddArgs{
2018-08-02 14:48:46 +03:00
Stream: "stream",
ID: "2-0",
Values: []interface{}{"dos", "deux"},
2017-11-25 05:06:13 +03:00
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(id).To(Equal("2-0"))
// Value supports []string.
2020-03-11 17:26:42 +03:00
id, err = client.XAdd(ctx, &redis.XAddArgs{
2018-08-02 14:48:46 +03:00
Stream: "stream",
ID: "3-0",
Values: []string{"tres", "troix"},
2017-11-25 05:06:13 +03:00
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(id).To(Equal("3-0"))
2018-08-02 14:48:46 +03:00
})
2017-11-25 05:06:13 +03:00
It("should XTrimMaxLen", func() {
n, err := client.XTrimMaxLen(ctx, "stream", 0).Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
})
It("should XTrimMaxLenApprox", func() {
n, err := client.XTrimMaxLenApprox(ctx, "stream", 0, 0).Result()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
})
2017-11-25 05:06:13 +03:00
It("should XTrimMinID", func() {
n, err := client.XTrimMinID(ctx, "stream", "4-0").Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
})
It("should XTrimMinIDApprox", func() {
n, err := client.XTrimMinIDApprox(ctx, "stream", "4-0", 0).Result()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
})
It("should XAdd", func() {
2020-03-11 17:26:42 +03:00
id, err := client.XAdd(ctx, &redis.XAddArgs{
2018-08-02 14:48:46 +03:00
Stream: "stream",
Values: map[string]interface{}{"quatro": "quatre"},
2017-11-25 05:06:13 +03:00
}).Result()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
vals, err := client.XRange(ctx, "stream", "-", "+").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(vals).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
{ID: id, Values: map[string]interface{}{"quatro": "quatre"}},
}))
})
2018-08-02 14:48:46 +03:00
It("should XAdd with MaxLen", func() {
2020-03-11 17:26:42 +03:00
id, err := client.XAdd(ctx, &redis.XAddArgs{
2017-11-25 05:06:13 +03:00
Stream: "stream",
MaxLen: 1,
Values: map[string]interface{}{"quatro": "quatre"},
}).Result()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
vals, err := client.XRange(ctx, "stream", "-", "+").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(vals).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: id, Values: map[string]interface{}{"quatro": "quatre"}},
}))
})
It("should XAdd with MinID", func() {
id, err := client.XAdd(ctx, &redis.XAddArgs{
Stream: "stream",
MinID: "5-0",
ID: "4-0",
Values: map[string]interface{}{"quatro": "quatre"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(id).To(Equal("4-0"))
vals, err := client.XRange(ctx, "stream", "-", "+").Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(HaveLen(0))
})
2018-11-13 15:22:50 +03:00
It("should XDel", func() {
2020-03-11 17:26:42 +03:00
n, err := client.XDel(ctx, "stream", "1-0", "2-0", "3-0").Result()
2018-11-13 15:22:50 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
})
2017-11-25 05:06:13 +03:00
It("should XLen", func() {
2020-03-11 17:26:42 +03:00
n, err := client.XLen(ctx, "stream").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
})
It("should XRange", func() {
2020-03-11 17:26:42 +03:00
msgs, err := client.XRange(ctx, "stream", "-", "+").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
}))
2020-03-11 17:26:42 +03:00
msgs, err = client.XRange(ctx, "stream", "2", "+").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
}))
2020-03-11 17:26:42 +03:00
msgs, err = client.XRange(ctx, "stream", "-", "2").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
}))
})
It("should XRangeN", func() {
2020-03-11 17:26:42 +03:00
msgs, err := client.XRangeN(ctx, "stream", "-", "+", 2).Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
}))
2020-03-11 17:26:42 +03:00
msgs, err = client.XRangeN(ctx, "stream", "2", "+", 1).Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
}))
2020-03-11 17:26:42 +03:00
msgs, err = client.XRangeN(ctx, "stream", "-", "2", 1).Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
}))
})
It("should XRevRange", func() {
2020-03-11 17:26:42 +03:00
msgs, err := client.XRevRange(ctx, "stream", "+", "-").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
}))
2020-03-11 17:26:42 +03:00
msgs, err = client.XRevRange(ctx, "stream", "+", "2").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
}))
})
It("should XRevRangeN", func() {
2020-03-11 17:26:42 +03:00
msgs, err := client.XRevRangeN(ctx, "stream", "+", "-", 2).Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
}))
2020-03-11 17:26:42 +03:00
msgs, err = client.XRevRangeN(ctx, "stream", "+", "2", 1).Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2018-08-02 14:48:46 +03:00
Expect(msgs).To(Equal([]redis.XMessage{
2017-11-25 05:06:13 +03:00
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
}))
})
It("should XRead", func() {
2020-03-11 17:26:42 +03:00
res, err := client.XReadStreams(ctx, "stream", "0").Result()
2017-11-25 05:06:13 +03:00
Expect(err).NotTo(HaveOccurred())
2020-07-16 09:52:07 +03:00
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
2017-11-25 05:06:13 +03:00
}))
2020-03-11 17:26:42 +03:00
_, err = client.XReadStreams(ctx, "stream", "3").Result()
2017-11-25 05:06:13 +03:00
Expect(err).To(Equal(redis.Nil))
})
2018-08-02 14:48:46 +03:00
It("should XRead", func() {
2020-03-11 17:26:42 +03:00
res, err := client.XRead(ctx, &redis.XReadArgs{
2017-11-25 05:06:13 +03:00
Streams: []string{"stream", "0"},
Count: 2,
Block: 100 * time.Millisecond,
}).Result()
Expect(err).NotTo(HaveOccurred())
2020-07-16 09:52:07 +03:00
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
},
},
2017-11-25 05:06:13 +03:00
}))
2020-03-11 17:26:42 +03:00
_, err = client.XRead(ctx, &redis.XReadArgs{
2017-11-25 05:06:13 +03:00
Streams: []string{"stream", "3"},
Count: 1,
Block: 100 * time.Millisecond,
}).Result()
Expect(err).To(Equal(redis.Nil))
})
2018-08-02 14:48:46 +03:00
It("should XRead LastEntry", Label("NonRedisEnterprise"), func() {
res, err := client.XRead(ctx, &redis.XReadArgs{
Streams: []string{"stream"},
Count: 2, // we expect 1 message
ID: "+",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
}))
})
It("should XRead LastEntry from two streams", Label("NonRedisEnterprise"), func() {
res, err := client.XRead(ctx, &redis.XReadArgs{
Streams: []string{"stream", "stream"},
ID: "+",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
}))
})
It("should XRead LastEntry blocks", Label("NonRedisEnterprise"), func() {
start := time.Now()
go func() {
defer GinkgoRecover()
time.Sleep(100 * time.Millisecond)
id, err := client.XAdd(ctx, &redis.XAddArgs{
Stream: "empty",
ID: "4-0",
Values: map[string]interface{}{"quatro": "quatre"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(id).To(Equal("4-0"))
}()
res, err := client.XRead(ctx, &redis.XReadArgs{
Streams: []string{"empty"},
Block: 500 * time.Millisecond,
ID: "+",
}).Result()
Expect(err).NotTo(HaveOccurred())
// Ensure that the XRead call with LastEntry option blocked for at least 100ms.
Expect(time.Since(start)).To(BeNumerically(">=", 100*time.Millisecond))
Expect(res).To(Equal([]redis.XStream{
{
Stream: "empty",
Messages: []redis.XMessage{
{ID: "4-0", Values: map[string]interface{}{"quatro": "quatre"}},
},
},
}))
})
2018-08-02 14:48:46 +03:00
Describe("group", func() {
BeforeEach(func() {
2020-03-11 17:26:42 +03:00
err := client.XGroupCreate(ctx, "stream", "group", "0").Err()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
res, err := client.XReadGroup(ctx, &redis.XReadGroupArgs{
2018-08-02 14:48:46 +03:00
Group: "group",
Consumer: "consumer",
2018-11-21 12:09:21 +03:00
Streams: []string{"stream", ">"},
2018-08-02 14:48:46 +03:00
}).Result()
2018-11-21 12:09:21 +03:00
Expect(err).NotTo(HaveOccurred())
2020-07-16 09:52:07 +03:00
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
2018-08-02 14:48:46 +03:00
}))
})
AfterEach(func() {
2020-03-11 17:26:42 +03:00
n, err := client.XGroupDestroy(ctx, "stream", "group").Result()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
})
It("should XReadGroup skip empty", func() {
2020-03-11 17:26:42 +03:00
n, err := client.XDel(ctx, "stream", "2-0").Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
res, err := client.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: "group",
Consumer: "consumer",
Streams: []string{"stream", "0"},
}).Result()
Expect(err).NotTo(HaveOccurred())
2020-07-16 09:52:07 +03:00
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: nil},
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
}))
})
2018-12-11 17:52:46 +03:00
It("should XGroupCreateMkStream", func() {
2020-03-11 17:26:42 +03:00
err := client.XGroupCreateMkStream(ctx, "stream2", "group", "0").Err()
2018-12-11 17:52:46 +03:00
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
err = client.XGroupCreateMkStream(ctx, "stream2", "group", "0").Err()
2018-12-11 17:52:46 +03:00
Expect(err).To(Equal(proto.RedisError("BUSYGROUP Consumer Group name already exists")))
2020-03-11 17:26:42 +03:00
n, err := client.XGroupDestroy(ctx, "stream2", "group").Result()
2018-12-11 17:52:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
2020-03-11 17:26:42 +03:00
n, err = client.Del(ctx, "stream2").Result()
2018-12-11 17:52:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
})
2018-08-02 14:48:46 +03:00
It("should XPending", func() {
2020-03-11 17:26:42 +03:00
info, err := client.XPending(ctx, "stream", "group").Result()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(info).To(Equal(&redis.XPending{
Count: 3,
Lower: "1-0",
Higher: "3-0",
Consumers: map[string]int64{"consumer": 3},
}))
args := &redis.XPendingExtArgs{
2018-08-02 14:48:46 +03:00
Stream: "stream",
Group: "group",
Start: "-",
End: "+",
Count: 10,
Consumer: "consumer",
}
infoExt, err := client.XPendingExt(ctx, args).Result()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
for i := range infoExt {
infoExt[i].Idle = 0
}
Expect(infoExt).To(Equal([]redis.XPendingExt{
2019-05-16 16:27:19 +03:00
{ID: "1-0", Consumer: "consumer", Idle: 0, RetryCount: 1},
{ID: "2-0", Consumer: "consumer", Idle: 0, RetryCount: 1},
{ID: "3-0", Consumer: "consumer", Idle: 0, RetryCount: 1},
2018-08-02 14:48:46 +03:00
}))
args.Idle = 72 * time.Hour
infoExt, err = client.XPendingExt(ctx, args).Result()
Expect(err).NotTo(HaveOccurred())
Expect(infoExt).To(HaveLen(0))
})
It("should XGroup Create Delete Consumer", func() {
n, err := client.XGroupCreateConsumer(ctx, "stream", "group", "c1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
n, err = client.XGroupDelConsumer(ctx, "stream", "group", "consumer").Result()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
})
It("should XAutoClaim", func() {
xca := &redis.XAutoClaimArgs{
Stream: "stream",
Group: "group",
Consumer: "consumer",
Start: "-",
Count: 2,
}
msgs, start, err := client.XAutoClaim(ctx, xca).Result()
Expect(err).NotTo(HaveOccurred())
Expect(start).To(Equal("3-0"))
Expect(msgs).To(Equal([]redis.XMessage{{
ID: "1-0",
Values: map[string]interface{}{"uno": "un"},
}, {
ID: "2-0",
Values: map[string]interface{}{"dos": "deux"},
}}))
xca.Start = start
msgs, start, err = client.XAutoClaim(ctx, xca).Result()
Expect(err).NotTo(HaveOccurred())
Expect(start).To(Equal("0-0"))
Expect(msgs).To(Equal([]redis.XMessage{{
ID: "3-0",
Values: map[string]interface{}{"tres": "troix"},
}}))
ids, start, err := client.XAutoClaimJustID(ctx, xca).Result()
Expect(err).NotTo(HaveOccurred())
Expect(start).To(Equal("0-0"))
Expect(ids).To(Equal([]string{"3-0"}))
})
2018-08-02 14:48:46 +03:00
It("should XClaim", func() {
2020-03-11 17:26:42 +03:00
msgs, err := client.XClaim(ctx, &redis.XClaimArgs{
2018-08-02 14:48:46 +03:00
Stream: "stream",
Group: "group",
Consumer: "consumer",
Messages: []string{"1-0", "2-0", "3-0"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(msgs).To(Equal([]redis.XMessage{{
ID: "1-0",
Values: map[string]interface{}{"uno": "un"},
}, {
ID: "2-0",
Values: map[string]interface{}{"dos": "deux"},
}, {
ID: "3-0",
Values: map[string]interface{}{"tres": "troix"},
}}))
2020-03-11 17:26:42 +03:00
ids, err := client.XClaimJustID(ctx, &redis.XClaimArgs{
2018-08-02 14:48:46 +03:00
Stream: "stream",
Group: "group",
Consumer: "consumer",
Messages: []string{"1-0", "2-0", "3-0"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(ids).To(Equal([]string{"1-0", "2-0", "3-0"}))
})
It("should XAck", func() {
2020-03-11 17:26:42 +03:00
n, err := client.XAck(ctx, "stream", "group", "1-0", "2-0", "4-0").Result()
2018-08-02 14:48:46 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
})
})
Describe("xinfo", func() {
BeforeEach(func() {
err := client.XGroupCreate(ctx, "stream", "group1", "0").Err()
Expect(err).NotTo(HaveOccurred())
res, err := client.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: "group1",
Consumer: "consumer1",
Streams: []string{"stream", ">"},
Count: 2,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "1-0", Values: map[string]interface{}{"uno": "un"}},
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
},
},
}))
res, err = client.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: "group1",
Consumer: "consumer2",
Streams: []string{"stream", ">"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
}))
err = client.XGroupCreate(ctx, "stream", "group2", "1-0").Err()
Expect(err).NotTo(HaveOccurred())
res, err = client.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: "group2",
Consumer: "consumer1",
Streams: []string{"stream", ">"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]redis.XStream{
{
Stream: "stream",
Messages: []redis.XMessage{
{ID: "2-0", Values: map[string]interface{}{"dos": "deux"}},
{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}},
},
},
}))
})
AfterEach(func() {
n, err := client.XGroupDestroy(ctx, "stream", "group1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
n, err = client.XGroupDestroy(ctx, "stream", "group2").Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(1)))
})
It("should XINFO STREAM", func() {
res, err := client.XInfoStream(ctx, "stream").Result()
Expect(err).NotTo(HaveOccurred())
res.RadixTreeKeys = 0
res.RadixTreeNodes = 0
Expect(res).To(Equal(&redis.XInfoStream{
2022-06-04 17:25:12 +03:00
Length: 3,
RadixTreeKeys: 0,
RadixTreeNodes: 0,
Groups: 2,
LastGeneratedID: "3-0",
MaxDeletedEntryID: "0-0",
EntriesAdded: 3,
FirstEntry: redis.XMessage{
ID: "1-0",
Values: map[string]interface{}{"uno": "un"},
},
LastEntry: redis.XMessage{
ID: "3-0",
Values: map[string]interface{}{"tres": "troix"},
},
RecordedFirstEntryID: "1-0",
}))
// stream is empty
n, err := client.XDel(ctx, "stream", "1-0", "2-0", "3-0").Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(3)))
res, err = client.XInfoStream(ctx, "stream").Result()
Expect(err).NotTo(HaveOccurred())
res.RadixTreeKeys = 0
res.RadixTreeNodes = 0
Expect(res).To(Equal(&redis.XInfoStream{
2022-06-04 17:25:12 +03:00
Length: 0,
RadixTreeKeys: 0,
RadixTreeNodes: 0,
Groups: 2,
LastGeneratedID: "3-0",
MaxDeletedEntryID: "3-0",
EntriesAdded: 3,
FirstEntry: redis.XMessage{},
LastEntry: redis.XMessage{},
RecordedFirstEntryID: "0-0",
}))
})
It("should XINFO STREAM FULL", func() {
res, err := client.XInfoStreamFull(ctx, "stream", 2).Result()
Expect(err).NotTo(HaveOccurred())
res.RadixTreeKeys = 0
res.RadixTreeNodes = 0
// Verify DeliveryTime
now := time.Now()
maxElapsed := 10 * time.Minute
for k, g := range res.Groups {
for k2, p := range g.Pending {
Expect(now.Sub(p.DeliveryTime)).To(BeNumerically("<=", maxElapsed))
res.Groups[k].Pending[k2].DeliveryTime = time.Time{}
}
for k3, c := range g.Consumers {
Expect(now.Sub(c.SeenTime)).To(BeNumerically("<=", maxElapsed))
Expect(now.Sub(c.ActiveTime)).To(BeNumerically("<=", maxElapsed))
res.Groups[k].Consumers[k3].SeenTime = time.Time{}
res.Groups[k].Consumers[k3].ActiveTime = time.Time{}
for k4, p := range c.Pending {
Expect(now.Sub(p.DeliveryTime)).To(BeNumerically("<=", maxElapsed))
res.Groups[k].Consumers[k3].Pending[k4].DeliveryTime = time.Time{}
}
}
}
Expect(res.Groups).To(Equal([]redis.XInfoStreamGroup{
{
Name: "group1",
LastDeliveredID: "3-0",
EntriesRead: 3,
Lag: 0,
PelCount: 3,
Pending: []redis.XInfoStreamGroupPending{
{ID: "1-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
{ID: "2-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
},
Consumers: []redis.XInfoStreamConsumer{
{
Name: "consumer1",
SeenTime: time.Time{},
ActiveTime: time.Time{},
PelCount: 2,
Pending: []redis.XInfoStreamConsumerPending{
{ID: "1-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
{ID: "2-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
},
},
{
Name: "consumer2",
SeenTime: time.Time{},
ActiveTime: time.Time{},
PelCount: 1,
Pending: []redis.XInfoStreamConsumerPending{
{ID: "3-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
},
},
},
},
{
Name: "group2",
LastDeliveredID: "3-0",
EntriesRead: 3,
Lag: 0,
PelCount: 2,
Pending: []redis.XInfoStreamGroupPending{
{ID: "2-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
{ID: "3-0", Consumer: "consumer1", DeliveryTime: time.Time{}, DeliveryCount: 1},
},
Consumers: []redis.XInfoStreamConsumer{
{
Name: "consumer1",
SeenTime: time.Time{},
ActiveTime: time.Time{},
PelCount: 2,
Pending: []redis.XInfoStreamConsumerPending{
{ID: "2-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
{ID: "3-0", DeliveryTime: time.Time{}, DeliveryCount: 1},
},
},
},
},
}))
// entries-read = nil
Expect(client.Del(ctx, "xinfo-stream-full-stream").Err()).NotTo(HaveOccurred())
id, err := client.XAdd(ctx, &redis.XAddArgs{
Stream: "xinfo-stream-full-stream",
ID: "*",
Values: []any{"k1", "v1"},
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(client.XGroupCreateMkStream(ctx, "xinfo-stream-full-stream", "xinfo-stream-full-group", "0").Err()).NotTo(HaveOccurred())
res, err = client.XInfoStreamFull(ctx, "xinfo-stream-full-stream", 0).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal(&redis.XInfoStreamFull{
Length: 1,
RadixTreeKeys: 1,
RadixTreeNodes: 2,
LastGeneratedID: id,
MaxDeletedEntryID: "0-0",
EntriesAdded: 1,
Entries: []redis.XMessage{{ID: id, Values: map[string]any{"k1": "v1"}}},
Groups: []redis.XInfoStreamGroup{
{
Name: "xinfo-stream-full-group",
LastDeliveredID: "0-0",
EntriesRead: 0,
Lag: 1,
PelCount: 0,
Pending: []redis.XInfoStreamGroupPending{},
Consumers: []redis.XInfoStreamConsumer{},
},
},
RecordedFirstEntryID: id,
}))
})
It("should XINFO GROUPS", func() {
res, err := client.XInfoGroups(ctx, "stream").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(Equal([]redis.XInfoGroup{
2022-06-04 17:25:12 +03:00
{Name: "group1", Consumers: 2, Pending: 3, LastDeliveredID: "3-0", EntriesRead: 3},
{Name: "group2", Consumers: 1, Pending: 2, LastDeliveredID: "3-0", EntriesRead: 3},
}))
})
It("should XINFO CONSUMERS", func() {
res, err := client.XInfoConsumers(ctx, "stream", "group1").Result()
Expect(err).NotTo(HaveOccurred())
for i := range res {
res[i].Idle = 0
res[i].Inactive = 0
}
Expect(res).To(Equal([]redis.XInfoConsumer{
{Name: "consumer1", Pending: 2, Idle: 0, Inactive: 0},
{Name: "consumer2", Pending: 1, Idle: 0, Inactive: 0},
}))
})
})
2017-11-25 05:06:13 +03:00
})
Describe("Geo add and radius search", func() {
2015-11-14 17:36:21 +03:00
BeforeEach(func() {
2018-08-02 14:48:46 +03:00
n, err := client.GeoAdd(
2020-03-11 17:26:42 +03:00
ctx,
"Sicily",
&redis.GeoLocation{Longitude: 13.361389, Latitude: 38.115556, Name: "Palermo"},
&redis.GeoLocation{Longitude: 15.087269, Latitude: 37.502669, Name: "Catania"},
2018-08-02 14:48:46 +03:00
).Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
})
2015-11-14 17:36:21 +03:00
It("should not add same geo location", func() {
geoAdd := client.GeoAdd(
2020-03-11 17:26:42 +03:00
ctx,
"Sicily",
&redis.GeoLocation{Longitude: 13.361389, Latitude: 38.115556, Name: "Palermo"},
)
Expect(geoAdd.Err()).NotTo(HaveOccurred())
2015-11-14 17:36:21 +03:00
Expect(geoAdd.Val()).To(Equal(int64(0)))
})
2015-11-14 17:36:21 +03:00
It("should search geo radius", func() {
2020-03-11 17:26:42 +03:00
res, err := client.GeoRadius(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
2015-11-14 17:36:21 +03:00
Radius: 200,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(HaveLen(2))
Expect(res[0].Name).To(Equal("Palermo"))
Expect(res[1].Name).To(Equal("Catania"))
})
It("should geo radius and store the result", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
n, err := client.GeoRadiusStore(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
Radius: 200,
Store: "result",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
res, err := client.ZRangeWithScores(ctx, "result", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(ContainElement(redis.Z{
Score: 3.479099956230698e+15,
Member: "Palermo",
}))
Expect(res).To(ContainElement(redis.Z{
Score: 3.479447370796909e+15,
Member: "Catania",
}))
})
It("should geo radius and store dist", Label("NonRedisEnterprise"), func() {
2020-03-11 17:26:42 +03:00
n, err := client.GeoRadiusStore(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
Radius: 200,
StoreDist: "result",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(n).To(Equal(int64(2)))
2020-03-11 17:26:42 +03:00
res, err := client.ZRangeWithScores(ctx, "result", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(ContainElement(redis.Z{
Score: 190.44242984775784,
Member: "Palermo",
}))
Expect(res).To(ContainElement(redis.Z{
Score: 56.4412578701582,
Member: "Catania",
}))
})
It("should search geo radius with options", func() {
2020-03-11 17:26:42 +03:00
res, err := client.GeoRadius(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
Radius: 200,
Unit: "km",
WithGeoHash: true,
WithCoord: true,
WithDist: true,
Count: 2,
Sort: "ASC",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(HaveLen(2))
Expect(res[1].Name).To(Equal("Palermo"))
2015-11-14 17:36:21 +03:00
Expect(res[1].Dist).To(Equal(190.4424))
Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
Expect(res[1].Longitude).To(Equal(13.361389338970184))
Expect(res[1].Latitude).To(Equal(38.115556395496299))
Expect(res[0].Name).To(Equal("Catania"))
2015-11-14 17:36:21 +03:00
Expect(res[0].Dist).To(Equal(56.4413))
Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
Expect(res[0].Longitude).To(Equal(15.087267458438873))
Expect(res[0].Latitude).To(Equal(37.50266842333162))
})
2015-11-14 17:36:21 +03:00
It("should search geo radius with WithDist=false", func() {
2020-03-11 17:26:42 +03:00
res, err := client.GeoRadius(ctx, "Sicily", 15, 37, &redis.GeoRadiusQuery{
2015-11-14 17:36:21 +03:00
Radius: 200,
Unit: "km",
WithGeoHash: true,
WithCoord: true,
Count: 2,
Sort: "ASC",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(HaveLen(2))
Expect(res[1].Name).To(Equal("Palermo"))
Expect(res[1].Dist).To(Equal(float64(0)))
Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
Expect(res[1].Longitude).To(Equal(13.361389338970184))
Expect(res[1].Latitude).To(Equal(38.115556395496299))
Expect(res[0].Name).To(Equal("Catania"))
Expect(res[0].Dist).To(Equal(float64(0)))
Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
Expect(res[0].Longitude).To(Equal(15.087267458438873))
Expect(res[0].Latitude).To(Equal(37.50266842333162))
})
2015-11-14 17:36:21 +03:00
It("should search geo radius by member with options", func() {
2020-03-11 17:26:42 +03:00
res, err := client.GeoRadiusByMember(ctx, "Sicily", "Catania", &redis.GeoRadiusQuery{
Radius: 200,
Unit: "km",
WithGeoHash: true,
WithCoord: true,
WithDist: true,
Count: 2,
Sort: "ASC",
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(HaveLen(2))
Expect(res[0].Name).To(Equal("Catania"))
2015-11-14 17:36:21 +03:00
Expect(res[0].Dist).To(Equal(0.0))
Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
Expect(res[0].Longitude).To(Equal(15.087267458438873))
Expect(res[0].Latitude).To(Equal(37.50266842333162))
Expect(res[1].Name).To(Equal("Palermo"))
2015-11-14 17:36:21 +03:00
Expect(res[1].Dist).To(Equal(166.2742))
Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
Expect(res[1].Longitude).To(Equal(13.361389338970184))
Expect(res[1].Latitude).To(Equal(38.115556395496299))
})
It("should search geo radius with no results", func() {
2020-03-11 17:26:42 +03:00
res, err := client.GeoRadius(ctx, "Sicily", 99, 37, &redis.GeoRadiusQuery{
Radius: 200,
Unit: "km",
WithGeoHash: true,
WithCoord: true,
WithDist: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(HaveLen(0))
})
It("should get geo distance with unit options", func() {
// From Redis CLI, note the difference in rounding in m vs
// km on Redis itself.
//
// GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
// GEODIST Sicily Palermo Catania m
// "166274.15156960033"
// GEODIST Sicily Palermo Catania km
// "166.27415156960032"
2020-03-11 17:26:42 +03:00
dist, err := client.GeoDist(ctx, "Sicily", "Palermo", "Catania", "km").Result()
2016-08-22 12:46:42 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(dist).To(BeNumerically("~", 166.27, 0.01))
2020-03-11 17:26:42 +03:00
dist, err = client.GeoDist(ctx, "Sicily", "Palermo", "Catania", "m").Result()
2016-08-22 12:46:42 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(dist).To(BeNumerically("~", 166274.15, 0.01))
})
It("should get geo hash in string representation", func() {
2020-03-11 17:26:42 +03:00
hashes, err := client.GeoHash(ctx, "Sicily", "Palermo", "Catania").Result()
2016-08-22 12:46:42 +03:00
Expect(err).NotTo(HaveOccurred())
Expect(hashes).To(ConsistOf([]string{"sqc8b49rny0", "sqdtr74hyu0"}))
})
It("should return geo position", func() {
2020-03-11 17:26:42 +03:00
pos, err := client.GeoPos(ctx, "Sicily", "Palermo", "Catania", "NonExisting").Result()
Expect(err).NotTo(HaveOccurred())
2016-08-22 12:46:42 +03:00
Expect(pos).To(ConsistOf([]*redis.GeoPos{
{
Longitude: 13.361389338970184,
Latitude: 38.1155563954963,
},
{
Longitude: 15.087267458438873,
Latitude: 37.50266842333162,
},
nil,
}))
})
It("should geo search", func() {
q := &redis.GeoSearchQuery{
Member: "Catania",
BoxWidth: 400,
BoxHeight: 100,
BoxUnit: "km",
Sort: "asc",
}
val, err := client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.BoxHeight = 400
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania", "Palermo"}))
q.Count = 1
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.CountAny = true
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Palermo"}))
q = &redis.GeoSearchQuery{
Member: "Catania",
Radius: 100,
RadiusUnit: "km",
Sort: "asc",
}
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.Radius = 400
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania", "Palermo"}))
q.Count = 1
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.CountAny = true
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Palermo"}))
q = &redis.GeoSearchQuery{
Longitude: 15,
Latitude: 37,
BoxWidth: 200,
BoxHeight: 200,
BoxUnit: "km",
Sort: "asc",
}
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.BoxWidth, q.BoxHeight = 400, 400
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania", "Palermo"}))
q.Count = 1
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.CountAny = true
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Palermo"}))
q = &redis.GeoSearchQuery{
Longitude: 15,
Latitude: 37,
Radius: 100,
RadiusUnit: "km",
Sort: "asc",
}
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.Radius = 200
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania", "Palermo"}))
q.Count = 1
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Catania"}))
q.CountAny = true
val, err = client.GeoSearch(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]string{"Palermo"}))
})
It("should geo search with options", func() {
q := &redis.GeoSearchLocationQuery{
GeoSearchQuery: redis.GeoSearchQuery{
Longitude: 15,
Latitude: 37,
Radius: 200,
RadiusUnit: "km",
Sort: "asc",
},
WithHash: true,
WithDist: true,
WithCoord: true,
}
val, err := client.GeoSearchLocation(ctx, "Sicily", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]redis.GeoLocation{
{
Name: "Catania",
Longitude: 15.08726745843887329,
Latitude: 37.50266842333162032,
Dist: 56.4413,
GeoHash: 3479447370796909,
},
{
Name: "Palermo",
Longitude: 13.36138933897018433,
Latitude: 38.11555639549629859,
Dist: 190.4424,
GeoHash: 3479099956230698,
},
}))
})
It("should geo search store", Label("NonRedisEnterprise"), func() {
q := &redis.GeoSearchStoreQuery{
GeoSearchQuery: redis.GeoSearchQuery{
Longitude: 15,
Latitude: 37,
Radius: 200,
RadiusUnit: "km",
Sort: "asc",
},
StoreDist: false,
}
val, err := client.GeoSearchStore(ctx, "Sicily", "key1", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal(int64(2)))
q.StoreDist = true
val, err = client.GeoSearchStore(ctx, "Sicily", "key2", q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal(int64(2)))
loc, err := client.GeoSearchLocation(ctx, "key1", &redis.GeoSearchLocationQuery{
GeoSearchQuery: q.GeoSearchQuery,
WithCoord: true,
WithDist: true,
WithHash: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(loc).To(Equal([]redis.GeoLocation{
{
Name: "Catania",
Longitude: 15.08726745843887329,
Latitude: 37.50266842333162032,
Dist: 56.4413,
GeoHash: 3479447370796909,
},
{
Name: "Palermo",
Longitude: 13.36138933897018433,
Latitude: 38.11555639549629859,
Dist: 190.4424,
GeoHash: 3479099956230698,
},
}))
v, err := client.ZRangeWithScores(ctx, "key2", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal([]redis.Z{
{
Score: 56.441257870158204,
Member: "Catania",
},
{
Score: 190.44242984775784,
Member: "Palermo",
},
}))
})
})
Describe("marshaling/unmarshaling", func() {
type convTest struct {
value interface{}
wanted string
dest interface{}
}
convTests := []convTest{
{nil, "", nil},
{"hello", "hello", new(string)},
{[]byte("hello"), "hello", new([]byte)},
{1, "1", new(int)},
{int8(1), "1", new(int8)},
{int16(1), "1", new(int16)},
{int32(1), "1", new(int32)},
{int64(1), "1", new(int64)},
{uint(1), "1", new(uint)},
{uint8(1), "1", new(uint8)},
{uint16(1), "1", new(uint16)},
{uint32(1), "1", new(uint32)},
{uint64(1), "1", new(uint64)},
{float32(1.0), "1", new(float32)},
{1.0, "1", new(float64)},
{true, "1", new(bool)},
{false, "0", new(bool)},
}
It("should convert to string", func() {
for _, test := range convTests {
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "key", test.value, 0).Err()
Expect(err).NotTo(HaveOccurred())
2020-03-11 17:26:42 +03:00
s, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(s).To(Equal(test.wanted))
if test.dest == nil {
continue
}
2020-03-11 17:26:42 +03:00
err = client.Get(ctx, "key").Scan(test.dest)
Expect(err).NotTo(HaveOccurred())
Expect(deref(test.dest)).To(Equal(test.value))
}
})
})
Describe("json marshaling/unmarshaling", func() {
BeforeEach(func() {
value := &numberStruct{Number: 42}
2020-03-11 17:26:42 +03:00
err := client.Set(ctx, "key", value, 0).Err()
Expect(err).NotTo(HaveOccurred())
})
It("should marshal custom values using json", func() {
2020-03-11 17:26:42 +03:00
s, err := client.Get(ctx, "key").Result()
Expect(err).NotTo(HaveOccurred())
Expect(s).To(Equal(`{"Number":42}`))
})
It("should scan custom values using json", func() {
value := &numberStruct{}
2020-03-11 17:26:42 +03:00
err := client.Get(ctx, "key").Scan(value)
Expect(err).NotTo(HaveOccurred())
Expect(value.Number).To(Equal(42))
})
})
2017-01-03 13:21:22 +03:00
Describe("Eval", func() {
It("returns keys and values", func() {
vals, err := client.Eval(
2020-03-11 17:26:42 +03:00
ctx,
2017-01-03 13:21:22 +03:00
"return {KEYS[1],ARGV[1]}",
[]string{"key"},
"hello",
).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]interface{}{"key", "hello"}))
})
It("returns all values after an error", func() {
vals, err := client.Eval(
2020-03-11 17:26:42 +03:00
ctx,
`return {12, {err="error"}, "abc"}`,
nil,
).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]interface{}{int64(12), proto.RedisError("error"), "abc"}))
})
})
Describe("EvalRO", func() {
It("returns keys and values", func() {
vals, err := client.EvalRO(
ctx,
"return {KEYS[1],ARGV[1]}",
[]string{"key"},
"hello",
).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]interface{}{"key", "hello"}))
})
It("returns all values after an error", func() {
vals, err := client.EvalRO(
ctx,
`return {12, {err="error"}, "abc"}`,
nil,
).Result()
Expect(err).NotTo(HaveOccurred())
2018-02-22 15:14:30 +03:00
Expect(vals).To(Equal([]interface{}{int64(12), proto.RedisError("error"), "abc"}))
})
2017-01-03 13:21:22 +03:00
})
2020-06-11 10:24:04 +03:00
Describe("Functions", func() {
var (
q redis.FunctionListQuery
lib1Code string
lib2Code string
lib1 redis.Library
lib2 redis.Library
)
BeforeEach(func() {
flush := client.FunctionFlush(ctx)
Expect(flush.Err()).NotTo(HaveOccurred())
lib1 = redis.Library{
Name: "mylib1",
Engine: "LUA",
Functions: []redis.Function{
{
Name: "lib1_func1",
Description: "This is the func-1 of lib 1",
Flags: []string{"allow-oom", "allow-stale"},
},
},
Code: `#!lua name=%s
local function f1(keys, args)
local hash = keys[1] -- Get the key name
local time = redis.call('TIME')[1] -- Get the current time from the Redis server
-- Add the current timestamp to the arguments that the user passed to the function, stored in args
table.insert(args, '_updated_at')
table.insert(args, time)
-- Run HSET with the updated argument list
return redis.call('HSET', hash, unpack(args))
end
redis.register_function{
function_name='%s',
description ='%s',
callback=f1,
flags={'%s', '%s'}
}`,
}
lib2 = redis.Library{
Name: "mylib2",
Engine: "LUA",
Functions: []redis.Function{
{
Name: "lib2_func1",
Flags: []string{},
},
{
Name: "lib2_func2",
Description: "This is the func-2 of lib 2",
Flags: []string{"no-writes"},
},
},
Code: `#!lua name=%s
local function f1(keys, args)
return 'Function 1'
end
local function f2(keys, args)
return 'Function 2'
end
redis.register_function('%s', f1)
redis.register_function{
function_name='%s',
description ='%s',
callback=f2,
flags={'%s'}
}`,
}
lib1Code = fmt.Sprintf(lib1.Code, lib1.Name, lib1.Functions[0].Name,
lib1.Functions[0].Description, lib1.Functions[0].Flags[0], lib1.Functions[0].Flags[1])
lib2Code = fmt.Sprintf(lib2.Code, lib2.Name, lib2.Functions[0].Name,
lib2.Functions[1].Name, lib2.Functions[1].Description, lib2.Functions[1].Flags[0])
q = redis.FunctionListQuery{}
})
It("Loads a new library", Label("NonRedisEnterprise"), func() {
functionLoad := client.FunctionLoad(ctx, lib1Code)
Expect(functionLoad.Err()).NotTo(HaveOccurred())
Expect(functionLoad.Val()).To(Equal(lib1.Name))
functionList := client.FunctionList(ctx, q)
Expect(functionList.Err()).NotTo(HaveOccurred())
Expect(functionList.Val()).To(HaveLen(1))
})
It("Loads and replaces a new library", Label("NonRedisEnterprise"), func() {
// Load a library for the first time
err := client.FunctionLoad(ctx, lib1Code).Err()
Expect(err).NotTo(HaveOccurred())
newFuncName := "replaces_func_name"
newFuncDesc := "replaces_func_desc"
flag1, flag2 := "allow-stale", "no-cluster"
newCode := fmt.Sprintf(lib1.Code, lib1.Name, newFuncName, newFuncDesc, flag1, flag2)
// And then replace it
functionLoadReplace := client.FunctionLoadReplace(ctx, newCode)
Expect(functionLoadReplace.Err()).NotTo(HaveOccurred())
Expect(functionLoadReplace.Val()).To(Equal(lib1.Name))
lib, err := client.FunctionList(ctx, q).First()
Expect(err).NotTo(HaveOccurred())
Expect(lib.Functions).To(Equal([]redis.Function{
{
Name: newFuncName,
Description: newFuncDesc,
Flags: []string{flag1, flag2},
},
}))
})
It("Deletes a library", func() {
err := client.FunctionLoad(ctx, lib1Code).Err()
Expect(err).NotTo(HaveOccurred())
err = client.FunctionDelete(ctx, lib1.Name).Err()
Expect(err).NotTo(HaveOccurred())
val, err := client.FunctionList(ctx, redis.FunctionListQuery{
LibraryNamePattern: lib1.Name,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(HaveLen(0))
})
It("Flushes all libraries", func() {
err := client.FunctionLoad(ctx, lib1Code).Err()
Expect(err).NotTo(HaveOccurred())
err = client.FunctionLoad(ctx, lib2Code).Err()
Expect(err).NotTo(HaveOccurred())
err = client.FunctionFlush(ctx).Err()
Expect(err).NotTo(HaveOccurred())
val, err := client.FunctionList(ctx, q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(HaveLen(0))
})
It("Flushes all libraries asynchronously", func() {
functionLoad := client.FunctionLoad(ctx, lib1Code)
Expect(functionLoad.Err()).NotTo(HaveOccurred())
// we only verify the command result.
functionFlush := client.FunctionFlushAsync(ctx)
Expect(functionFlush.Err()).NotTo(HaveOccurred())
})
It("Kills a running function", func() {
functionKill := client.FunctionKill(ctx)
Expect(functionKill.Err()).To(MatchError("NOTBUSY No scripts in execution right now."))
// Add test for a long-running function, once we make the test for `function stats` pass
})
It("Lists registered functions", Label("NonRedisEnterprise"), func() {
err := client.FunctionLoad(ctx, lib1Code).Err()
Expect(err).NotTo(HaveOccurred())
val, err := client.FunctionList(ctx, redis.FunctionListQuery{
LibraryNamePattern: "*",
WithCode: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(HaveLen(1))
Expect(val[0].Name).To(Equal(lib1.Name))
Expect(val[0].Engine).To(Equal(lib1.Engine))
Expect(val[0].Code).To(Equal(lib1Code))
Expect(val[0].Functions).Should(ConsistOf(lib1.Functions))
err = client.FunctionLoad(ctx, lib2Code).Err()
Expect(err).NotTo(HaveOccurred())
val, err = client.FunctionList(ctx, redis.FunctionListQuery{
WithCode: true,
}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(HaveLen(2))
lib, err := client.FunctionList(ctx, redis.FunctionListQuery{
LibraryNamePattern: lib2.Name,
WithCode: false,
}).First()
Expect(err).NotTo(HaveOccurred())
Expect(lib.Name).To(Equal(lib2.Name))
Expect(lib.Code).To(Equal(""))
_, err = client.FunctionList(ctx, redis.FunctionListQuery{
LibraryNamePattern: "non_lib",
WithCode: true,
}).First()
Expect(err).To(Equal(redis.Nil))
})
It("Dump and restores all libraries", Label("NonRedisEnterprise"), func() {
err := client.FunctionLoad(ctx, lib1Code).Err()
Expect(err).NotTo(HaveOccurred())
err = client.FunctionLoad(ctx, lib2Code).Err()
Expect(err).NotTo(HaveOccurred())
dump, err := client.FunctionDump(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(dump).NotTo(BeEmpty())
err = client.FunctionRestore(ctx, dump).Err()
Expect(err).To(HaveOccurred())
err = client.FunctionFlush(ctx).Err()
Expect(err).NotTo(HaveOccurred())
list, err := client.FunctionList(ctx, q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(list).To(HaveLen(0))
err = client.FunctionRestore(ctx, dump).Err()
Expect(err).NotTo(HaveOccurred())
list, err = client.FunctionList(ctx, q).Result()
Expect(err).NotTo(HaveOccurred())
Expect(list).To(HaveLen(2))
})
It("Calls a function", func() {
lib1Code = fmt.Sprintf(lib1.Code, lib1.Name, lib1.Functions[0].Name,
lib1.Functions[0].Description, lib1.Functions[0].Flags[0], lib1.Functions[0].Flags[1])
err := client.FunctionLoad(ctx, lib1Code).Err()
Expect(err).NotTo(HaveOccurred())
x := client.FCall(ctx, lib1.Functions[0].Name, []string{"my_hash"}, "a", 1, "b", 2)
Expect(x.Err()).NotTo(HaveOccurred())
Expect(x.Int()).To(Equal(3))
})
It("Calls a function as read-only", func() {
lib1Code = fmt.Sprintf(lib1.Code, lib1.Name, lib1.Functions[0].Name,
lib1.Functions[0].Description, lib1.Functions[0].Flags[0], lib1.Functions[0].Flags[1])
err := client.FunctionLoad(ctx, lib1Code).Err()
Expect(err).NotTo(HaveOccurred())
// This function doesn't have a "no-writes" flag
x := client.FCallRo(ctx, lib1.Functions[0].Name, []string{"my_hash"}, "a", 1, "b", 2)
Expect(x.Err()).To(HaveOccurred())
lib2Code = fmt.Sprintf(lib2.Code, lib2.Name, lib2.Functions[0].Name, lib2.Functions[1].Name,
lib2.Functions[1].Description, lib2.Functions[1].Flags[0])
// This function has a "no-writes" flag
err = client.FunctionLoad(ctx, lib2Code).Err()
Expect(err).NotTo(HaveOccurred())
x = client.FCallRo(ctx, lib2.Functions[1].Name, []string{})
Expect(x.Err()).NotTo(HaveOccurred())
Expect(x.Text()).To(Equal("Function 2"))
})
It("Shows function stats", func() {
defer client.FunctionKill(ctx)
// We can not run blocking commands in Redis functions, so we're using an infinite loop,
// but we're killing the function after calling FUNCTION STATS
lib := redis.Library{
Name: "mylib1",
Engine: "LUA",
Functions: []redis.Function{
{
Name: "lib1_func1",
Description: "This is the func-1 of lib 1",
Flags: []string{"no-writes"},
},
},
Code: `#!lua name=%s
local function f1(keys, args)
local i = 0
while true do
i = i + 1
end
end
redis.register_function{
function_name='%s',
description ='%s',
callback=f1,
flags={'%s'}
}`,
}
libCode := fmt.Sprintf(lib.Code, lib.Name, lib.Functions[0].Name,
lib.Functions[0].Description, lib.Functions[0].Flags[0])
err := client.FunctionLoad(ctx, libCode).Err()
Expect(err).NotTo(HaveOccurred())
r, err := client.FunctionStats(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(r.Engines)).To(Equal(1))
Expect(r.Running()).To(BeFalse())
started := make(chan bool)
go func() {
defer GinkgoRecover()
client2 := redis.NewClient(redisOptions())
started <- true
_, err = client2.FCall(ctx, lib.Functions[0].Name, nil).Result()
Expect(err).To(HaveOccurred())
}()
<-started
time.Sleep(1 * time.Second)
r, err = client.FunctionStats(ctx).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(r.Engines)).To(Equal(1))
rs, isRunning := r.RunningScript()
Expect(isRunning).To(BeTrue())
Expect(rs.Name).To(Equal(lib.Functions[0].Name))
Expect(rs.Duration > 0).To(BeTrue())
close(started)
})
})
2020-09-09 17:42:05 +03:00
Describe("SlowLogGet", func() {
2020-06-11 10:24:04 +03:00
It("returns slow query result", func() {
2020-09-09 12:49:45 +03:00
const key = "slowlog-log-slower-than"
old := client.ConfigGet(ctx, key).Val()
client.ConfigSet(ctx, key, "0")
defer client.ConfigSet(ctx, key, old[key])
2020-09-09 12:49:45 +03:00
2021-04-28 09:39:03 +03:00
err := client.Do(ctx, "slowlog", "reset").Err()
2020-09-09 12:49:45 +03:00
Expect(err).NotTo(HaveOccurred())
2020-06-11 10:24:04 +03:00
client.Set(ctx, "test", "true", 0)
2020-09-09 12:49:45 +03:00
2020-09-09 17:42:05 +03:00
result, err := client.SlowLogGet(ctx, -1).Result()
2020-06-11 10:24:04 +03:00
Expect(err).NotTo(HaveOccurred())
2020-09-09 17:39:13 +03:00
Expect(len(result)).NotTo(BeZero())
2020-06-11 10:24:04 +03:00
})
})
2015-01-15 18:51:22 +03:00
})
type numberStruct struct {
Number int
}
func (s *numberStruct) MarshalBinary() ([]byte, error) {
return json.Marshal(s)
}
func (s *numberStruct) UnmarshalBinary(b []byte) error {
return json.Unmarshal(b, s)
}
func deref(viface interface{}) interface{} {
v := reflect.ValueOf(viface)
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
return v.Interface()
}