...

Source file src/github.com/redis/go-redis/v9/commands_test.go

Documentation: github.com/redis/go-redis/v9

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

View as plain text