github.com/shuguocloud/go-zero@v1.3.0/core/stores/kv/store_test.go (about)

     1  package kv
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/alicebob/miniredis/v2"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/shuguocloud/go-zero/core/hash"
    10  	"github.com/shuguocloud/go-zero/core/stores/cache"
    11  	"github.com/shuguocloud/go-zero/core/stores/redis"
    12  	"github.com/shuguocloud/go-zero/core/stringx"
    13  )
    14  
    15  var (
    16  	s1, _ = miniredis.Run()
    17  	s2, _ = miniredis.Run()
    18  )
    19  
    20  func TestRedis_Decr(t *testing.T) {
    21  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
    22  	_, err := store.Decr("a")
    23  	assert.NotNil(t, err)
    24  
    25  	runOnCluster(t, func(client Store) {
    26  		val, err := client.Decr("a")
    27  		assert.Nil(t, err)
    28  		assert.Equal(t, int64(-1), val)
    29  		val, err = client.Decr("a")
    30  		assert.Nil(t, err)
    31  		assert.Equal(t, int64(-2), val)
    32  	})
    33  }
    34  
    35  func TestRedis_DecrBy(t *testing.T) {
    36  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
    37  	_, err := store.Incrby("a", 2)
    38  	assert.NotNil(t, err)
    39  
    40  	runOnCluster(t, func(client Store) {
    41  		val, err := client.Decrby("a", 2)
    42  		assert.Nil(t, err)
    43  		assert.Equal(t, int64(-2), val)
    44  		val, err = client.Decrby("a", 3)
    45  		assert.Nil(t, err)
    46  		assert.Equal(t, int64(-5), val)
    47  	})
    48  }
    49  
    50  func TestRedis_Exists(t *testing.T) {
    51  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
    52  	_, err := store.Exists("foo")
    53  	assert.NotNil(t, err)
    54  
    55  	runOnCluster(t, func(client Store) {
    56  		ok, err := client.Exists("a")
    57  		assert.Nil(t, err)
    58  		assert.False(t, ok)
    59  		assert.Nil(t, client.Set("a", "b"))
    60  		ok, err = client.Exists("a")
    61  		assert.Nil(t, err)
    62  		assert.True(t, ok)
    63  	})
    64  }
    65  
    66  func TestRedis_Eval(t *testing.T) {
    67  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
    68  	_, err := store.Eval(`redis.call("EXISTS", KEYS[1])`, "key1")
    69  	assert.NotNil(t, err)
    70  
    71  	runOnCluster(t, func(client Store) {
    72  		_, err := client.Eval(`redis.call("EXISTS", KEYS[1])`, "notexist")
    73  		assert.Equal(t, redis.Nil, err)
    74  		err = client.Set("key1", "value1")
    75  		assert.Nil(t, err)
    76  		_, err = client.Eval(`redis.call("EXISTS", KEYS[1])`, "key1")
    77  		assert.Equal(t, redis.Nil, err)
    78  		val, err := client.Eval(`return redis.call("EXISTS", KEYS[1])`, "key1")
    79  		assert.Nil(t, err)
    80  		assert.Equal(t, int64(1), val)
    81  	})
    82  }
    83  
    84  func TestRedis_Hgetall(t *testing.T) {
    85  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
    86  	err := store.Hset("a", "aa", "aaa")
    87  	assert.NotNil(t, err)
    88  	_, err = store.Hgetall("a")
    89  	assert.NotNil(t, err)
    90  
    91  	runOnCluster(t, func(client Store) {
    92  		assert.Nil(t, client.Hset("a", "aa", "aaa"))
    93  		assert.Nil(t, client.Hset("a", "bb", "bbb"))
    94  		vals, err := client.Hgetall("a")
    95  		assert.Nil(t, err)
    96  		assert.EqualValues(t, map[string]string{
    97  			"aa": "aaa",
    98  			"bb": "bbb",
    99  		}, vals)
   100  	})
   101  }
   102  
   103  func TestRedis_Hvals(t *testing.T) {
   104  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   105  	_, err := store.Hvals("a")
   106  	assert.NotNil(t, err)
   107  
   108  	runOnCluster(t, func(client Store) {
   109  		assert.Nil(t, client.Hset("a", "aa", "aaa"))
   110  		assert.Nil(t, client.Hset("a", "bb", "bbb"))
   111  		vals, err := client.Hvals("a")
   112  		assert.Nil(t, err)
   113  		assert.ElementsMatch(t, []string{"aaa", "bbb"}, vals)
   114  	})
   115  }
   116  
   117  func TestRedis_Hsetnx(t *testing.T) {
   118  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   119  	_, err := store.Hsetnx("a", "dd", "ddd")
   120  	assert.NotNil(t, err)
   121  
   122  	runOnCluster(t, func(client Store) {
   123  		assert.Nil(t, client.Hset("a", "aa", "aaa"))
   124  		assert.Nil(t, client.Hset("a", "bb", "bbb"))
   125  		ok, err := client.Hsetnx("a", "bb", "ccc")
   126  		assert.Nil(t, err)
   127  		assert.False(t, ok)
   128  		ok, err = client.Hsetnx("a", "dd", "ddd")
   129  		assert.Nil(t, err)
   130  		assert.True(t, ok)
   131  		vals, err := client.Hvals("a")
   132  		assert.Nil(t, err)
   133  		assert.ElementsMatch(t, []string{"aaa", "bbb", "ddd"}, vals)
   134  	})
   135  }
   136  
   137  func TestRedis_HdelHlen(t *testing.T) {
   138  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   139  	_, err := store.Hdel("a", "aa")
   140  	assert.NotNil(t, err)
   141  	_, err = store.Hlen("a")
   142  	assert.NotNil(t, err)
   143  
   144  	runOnCluster(t, func(client Store) {
   145  		assert.Nil(t, client.Hset("a", "aa", "aaa"))
   146  		assert.Nil(t, client.Hset("a", "bb", "bbb"))
   147  		num, err := client.Hlen("a")
   148  		assert.Nil(t, err)
   149  		assert.Equal(t, 2, num)
   150  		val, err := client.Hdel("a", "aa")
   151  		assert.Nil(t, err)
   152  		assert.True(t, val)
   153  		vals, err := client.Hvals("a")
   154  		assert.Nil(t, err)
   155  		assert.ElementsMatch(t, []string{"bbb"}, vals)
   156  	})
   157  }
   158  
   159  func TestRedis_HIncrBy(t *testing.T) {
   160  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   161  	_, err := store.Hincrby("key", "field", 3)
   162  	assert.NotNil(t, err)
   163  
   164  	runOnCluster(t, func(client Store) {
   165  		val, err := client.Hincrby("key", "field", 2)
   166  		assert.Nil(t, err)
   167  		assert.Equal(t, 2, val)
   168  		val, err = client.Hincrby("key", "field", 3)
   169  		assert.Nil(t, err)
   170  		assert.Equal(t, 5, val)
   171  	})
   172  }
   173  
   174  func TestRedis_Hkeys(t *testing.T) {
   175  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   176  	_, err := store.Hkeys("a")
   177  	assert.NotNil(t, err)
   178  
   179  	runOnCluster(t, func(client Store) {
   180  		assert.Nil(t, client.Hset("a", "aa", "aaa"))
   181  		assert.Nil(t, client.Hset("a", "bb", "bbb"))
   182  		vals, err := client.Hkeys("a")
   183  		assert.Nil(t, err)
   184  		assert.ElementsMatch(t, []string{"aa", "bb"}, vals)
   185  	})
   186  }
   187  
   188  func TestRedis_Hmget(t *testing.T) {
   189  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   190  	_, err := store.Hmget("a", "aa", "bb")
   191  	assert.NotNil(t, err)
   192  
   193  	runOnCluster(t, func(client Store) {
   194  		assert.Nil(t, client.Hset("a", "aa", "aaa"))
   195  		assert.Nil(t, client.Hset("a", "bb", "bbb"))
   196  		vals, err := client.Hmget("a", "aa", "bb")
   197  		assert.Nil(t, err)
   198  		assert.EqualValues(t, []string{"aaa", "bbb"}, vals)
   199  		vals, err = client.Hmget("a", "aa", "no", "bb")
   200  		assert.Nil(t, err)
   201  		assert.EqualValues(t, []string{"aaa", "", "bbb"}, vals)
   202  	})
   203  }
   204  
   205  func TestRedis_Hmset(t *testing.T) {
   206  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   207  	err := store.Hmset("a", map[string]string{
   208  		"aa": "aaa",
   209  	})
   210  	assert.NotNil(t, err)
   211  
   212  	runOnCluster(t, func(client Store) {
   213  		assert.Nil(t, client.Hmset("a", map[string]string{
   214  			"aa": "aaa",
   215  			"bb": "bbb",
   216  		}))
   217  		vals, err := client.Hmget("a", "aa", "bb")
   218  		assert.Nil(t, err)
   219  		assert.EqualValues(t, []string{"aaa", "bbb"}, vals)
   220  	})
   221  }
   222  
   223  func TestRedis_Incr(t *testing.T) {
   224  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   225  	_, err := store.Incr("a")
   226  	assert.NotNil(t, err)
   227  
   228  	runOnCluster(t, func(client Store) {
   229  		val, err := client.Incr("a")
   230  		assert.Nil(t, err)
   231  		assert.Equal(t, int64(1), val)
   232  		val, err = client.Incr("a")
   233  		assert.Nil(t, err)
   234  		assert.Equal(t, int64(2), val)
   235  	})
   236  }
   237  
   238  func TestRedis_IncrBy(t *testing.T) {
   239  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   240  	_, err := store.Incrby("a", 2)
   241  	assert.NotNil(t, err)
   242  
   243  	runOnCluster(t, func(client Store) {
   244  		val, err := client.Incrby("a", 2)
   245  		assert.Nil(t, err)
   246  		assert.Equal(t, int64(2), val)
   247  		val, err = client.Incrby("a", 3)
   248  		assert.Nil(t, err)
   249  		assert.Equal(t, int64(5), val)
   250  	})
   251  }
   252  
   253  func TestRedis_List(t *testing.T) {
   254  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   255  	_, err := store.Lpush("key", "value1", "value2")
   256  	assert.NotNil(t, err)
   257  	_, err = store.Rpush("key", "value3", "value4")
   258  	assert.NotNil(t, err)
   259  	_, err = store.Llen("key")
   260  	assert.NotNil(t, err)
   261  	_, err = store.Lrange("key", 0, 10)
   262  	assert.NotNil(t, err)
   263  	_, err = store.Lpop("key")
   264  	assert.NotNil(t, err)
   265  	_, err = store.Lrem("key", 0, "val")
   266  	assert.NotNil(t, err)
   267  	_, err = store.Lindex("key", 0)
   268  	assert.NotNil(t, err)
   269  
   270  	runOnCluster(t, func(client Store) {
   271  		val, err := client.Lpush("key", "value1", "value2")
   272  		assert.Nil(t, err)
   273  		assert.Equal(t, 2, val)
   274  		val, err = client.Rpush("key", "value3", "value4")
   275  		assert.Nil(t, err)
   276  		assert.Equal(t, 4, val)
   277  		val, err = client.Llen("key")
   278  		assert.Nil(t, err)
   279  		assert.Equal(t, 4, val)
   280  		value, err := client.Lindex("key", 0)
   281  		assert.Nil(t, err)
   282  		assert.Equal(t, "value2", value)
   283  		vals, err := client.Lrange("key", 0, 10)
   284  		assert.Nil(t, err)
   285  		assert.EqualValues(t, []string{"value2", "value1", "value3", "value4"}, vals)
   286  		v, err := client.Lpop("key")
   287  		assert.Nil(t, err)
   288  		assert.Equal(t, "value2", v)
   289  		val, err = client.Lpush("key", "value1", "value2")
   290  		assert.Nil(t, err)
   291  		assert.Equal(t, 5, val)
   292  		val, err = client.Rpush("key", "value3", "value3")
   293  		assert.Nil(t, err)
   294  		assert.Equal(t, 7, val)
   295  		n, err := client.Lrem("key", 2, "value1")
   296  		assert.Nil(t, err)
   297  		assert.Equal(t, 2, n)
   298  		vals, err = client.Lrange("key", 0, 10)
   299  		assert.Nil(t, err)
   300  		assert.EqualValues(t, []string{"value2", "value3", "value4", "value3", "value3"}, vals)
   301  		n, err = client.Lrem("key", -2, "value3")
   302  		assert.Nil(t, err)
   303  		assert.Equal(t, 2, n)
   304  		vals, err = client.Lrange("key", 0, 10)
   305  		assert.Nil(t, err)
   306  		assert.EqualValues(t, []string{"value2", "value3", "value4"}, vals)
   307  	})
   308  }
   309  
   310  func TestRedis_Persist(t *testing.T) {
   311  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   312  	_, err := store.Persist("key")
   313  	assert.NotNil(t, err)
   314  	err = store.Expire("key", 5)
   315  	assert.NotNil(t, err)
   316  	err = store.Expireat("key", time.Now().Unix()+5)
   317  	assert.NotNil(t, err)
   318  
   319  	runOnCluster(t, func(client Store) {
   320  		ok, err := client.Persist("key")
   321  		assert.Nil(t, err)
   322  		assert.False(t, ok)
   323  		err = client.Set("key", "value")
   324  		assert.Nil(t, err)
   325  		ok, err = client.Persist("key")
   326  		assert.Nil(t, err)
   327  		assert.False(t, ok)
   328  		err = client.Expire("key", 5)
   329  		assert.Nil(t, err)
   330  		ok, err = client.Persist("key")
   331  		assert.Nil(t, err)
   332  		assert.True(t, ok)
   333  		err = client.Expireat("key", time.Now().Unix()+5)
   334  		assert.Nil(t, err)
   335  		ok, err = client.Persist("key")
   336  		assert.Nil(t, err)
   337  		assert.True(t, ok)
   338  	})
   339  }
   340  
   341  func TestRedis_Sscan(t *testing.T) {
   342  	key := "list"
   343  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   344  	_, err := store.Sadd(key, nil)
   345  	assert.NotNil(t, err)
   346  	_, _, err = store.Sscan(key, 0, "", 100)
   347  	assert.NotNil(t, err)
   348  	_, err = store.Del(key)
   349  	assert.NotNil(t, err)
   350  
   351  	runOnCluster(t, func(client Store) {
   352  		var list []string
   353  		for i := 0; i < 1550; i++ {
   354  			list = append(list, stringx.Randn(i))
   355  		}
   356  		lens, err := client.Sadd(key, list)
   357  		assert.Nil(t, err)
   358  		assert.Equal(t, lens, 1550)
   359  
   360  		var cursor uint64 = 0
   361  		sum := 0
   362  		for {
   363  			keys, next, err := client.Sscan(key, cursor, "", 100)
   364  			assert.Nil(t, err)
   365  			sum += len(keys)
   366  			if next == 0 {
   367  				break
   368  			}
   369  			cursor = next
   370  		}
   371  
   372  		assert.Equal(t, sum, 1550)
   373  		_, err = client.Del(key)
   374  		assert.Nil(t, err)
   375  	})
   376  }
   377  
   378  func TestRedis_Set(t *testing.T) {
   379  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   380  	_, err := store.Scard("key")
   381  	assert.NotNil(t, err)
   382  	_, err = store.Sismember("key", 2)
   383  	assert.NotNil(t, err)
   384  	_, err = store.Srem("key", 3, 4)
   385  	assert.NotNil(t, err)
   386  	_, err = store.Smembers("key")
   387  	assert.NotNil(t, err)
   388  	_, err = store.Srandmember("key", 1)
   389  	assert.NotNil(t, err)
   390  	_, err = store.Spop("key")
   391  	assert.NotNil(t, err)
   392  
   393  	runOnCluster(t, func(client Store) {
   394  		num, err := client.Sadd("key", 1, 2, 3, 4)
   395  		assert.Nil(t, err)
   396  		assert.Equal(t, 4, num)
   397  		val, err := client.Scard("key")
   398  		assert.Nil(t, err)
   399  		assert.Equal(t, int64(4), val)
   400  		ok, err := client.Sismember("key", 2)
   401  		assert.Nil(t, err)
   402  		assert.True(t, ok)
   403  		num, err = client.Srem("key", 3, 4)
   404  		assert.Nil(t, err)
   405  		assert.Equal(t, 2, num)
   406  		vals, err := client.Smembers("key")
   407  		assert.Nil(t, err)
   408  		assert.ElementsMatch(t, []string{"1", "2"}, vals)
   409  		members, err := client.Srandmember("key", 1)
   410  		assert.Nil(t, err)
   411  		assert.Len(t, members, 1)
   412  		assert.Contains(t, []string{"1", "2"}, members[0])
   413  		member, err := client.Spop("key")
   414  		assert.Nil(t, err)
   415  		assert.Contains(t, []string{"1", "2"}, member)
   416  		vals, err = client.Smembers("key")
   417  		assert.Nil(t, err)
   418  		assert.NotContains(t, vals, member)
   419  		num, err = client.Sadd("key1", 1, 2, 3, 4)
   420  		assert.Nil(t, err)
   421  		assert.Equal(t, 4, num)
   422  		num, err = client.Sadd("key2", 2, 3, 4, 5)
   423  		assert.Nil(t, err)
   424  		assert.Equal(t, 4, num)
   425  	})
   426  }
   427  
   428  func TestRedis_SetGetDel(t *testing.T) {
   429  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   430  	err := store.Set("hello", "world")
   431  	assert.NotNil(t, err)
   432  	_, err = store.Get("hello")
   433  	assert.NotNil(t, err)
   434  	_, err = store.Del("hello")
   435  	assert.NotNil(t, err)
   436  
   437  	runOnCluster(t, func(client Store) {
   438  		err := client.Set("hello", "world")
   439  		assert.Nil(t, err)
   440  		val, err := client.Get("hello")
   441  		assert.Nil(t, err)
   442  		assert.Equal(t, "world", val)
   443  		ret, err := client.Del("hello")
   444  		assert.Nil(t, err)
   445  		assert.Equal(t, 1, ret)
   446  	})
   447  }
   448  
   449  func TestRedis_SetExNx(t *testing.T) {
   450  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   451  	err := store.Setex("hello", "world", 5)
   452  	assert.NotNil(t, err)
   453  	_, err = store.Setnx("newhello", "newworld")
   454  	assert.NotNil(t, err)
   455  	_, err = store.Ttl("hello")
   456  	assert.NotNil(t, err)
   457  	_, err = store.SetnxEx("newhello", "newworld", 5)
   458  	assert.NotNil(t, err)
   459  
   460  	runOnCluster(t, func(client Store) {
   461  		err := client.Setex("hello", "world", 5)
   462  		assert.Nil(t, err)
   463  		ok, err := client.Setnx("hello", "newworld")
   464  		assert.Nil(t, err)
   465  		assert.False(t, ok)
   466  		ok, err = client.Setnx("newhello", "newworld")
   467  		assert.Nil(t, err)
   468  		assert.True(t, ok)
   469  		val, err := client.Get("hello")
   470  		assert.Nil(t, err)
   471  		assert.Equal(t, "world", val)
   472  		val, err = client.Get("newhello")
   473  		assert.Nil(t, err)
   474  		assert.Equal(t, "newworld", val)
   475  		ttl, err := client.Ttl("hello")
   476  		assert.Nil(t, err)
   477  		assert.True(t, ttl > 0)
   478  		ok, err = client.SetnxEx("newhello", "newworld", 5)
   479  		assert.Nil(t, err)
   480  		assert.False(t, ok)
   481  		num, err := client.Del("newhello")
   482  		assert.Nil(t, err)
   483  		assert.Equal(t, 1, num)
   484  		ok, err = client.SetnxEx("newhello", "newworld", 5)
   485  		assert.Nil(t, err)
   486  		assert.True(t, ok)
   487  		val, err = client.Get("newhello")
   488  		assert.Nil(t, err)
   489  		assert.Equal(t, "newworld", val)
   490  	})
   491  }
   492  
   493  func TestRedis_SetGetDelHashField(t *testing.T) {
   494  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   495  	err := store.Hset("key", "field", "value")
   496  	assert.NotNil(t, err)
   497  	_, err = store.Hget("key", "field")
   498  	assert.NotNil(t, err)
   499  	_, err = store.Hexists("key", "field")
   500  	assert.NotNil(t, err)
   501  	_, err = store.Hdel("key", "field")
   502  	assert.NotNil(t, err)
   503  
   504  	runOnCluster(t, func(client Store) {
   505  		err := client.Hset("key", "field", "value")
   506  		assert.Nil(t, err)
   507  		val, err := client.Hget("key", "field")
   508  		assert.Nil(t, err)
   509  		assert.Equal(t, "value", val)
   510  		ok, err := client.Hexists("key", "field")
   511  		assert.Nil(t, err)
   512  		assert.True(t, ok)
   513  		ret, err := client.Hdel("key", "field")
   514  		assert.Nil(t, err)
   515  		assert.True(t, ret)
   516  		ok, err = client.Hexists("key", "field")
   517  		assert.Nil(t, err)
   518  		assert.False(t, ok)
   519  	})
   520  }
   521  
   522  func TestRedis_SortedSet(t *testing.T) {
   523  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   524  	_, err := store.Zadd("key", 1, "value1")
   525  	assert.NotNil(t, err)
   526  	_, err = store.Zscore("key", "value1")
   527  	assert.NotNil(t, err)
   528  	_, err = store.Zcount("key", 6, 7)
   529  	assert.NotNil(t, err)
   530  	_, err = store.Zincrby("key", 3, "value1")
   531  	assert.NotNil(t, err)
   532  	_, err = store.Zrank("key", "value2")
   533  	assert.NotNil(t, err)
   534  	_, err = store.Zrem("key", "value2", "value3")
   535  	assert.NotNil(t, err)
   536  	_, err = store.Zremrangebyscore("key", 6, 7)
   537  	assert.NotNil(t, err)
   538  	_, err = store.Zremrangebyrank("key", 1, 2)
   539  	assert.NotNil(t, err)
   540  	_, err = store.Zcard("key")
   541  	assert.NotNil(t, err)
   542  	_, err = store.Zrange("key", 0, -1)
   543  	assert.NotNil(t, err)
   544  	_, err = store.Zrevrange("key", 0, -1)
   545  	assert.NotNil(t, err)
   546  	_, err = store.ZrangeWithScores("key", 0, -1)
   547  	assert.NotNil(t, err)
   548  	_, err = store.ZrangebyscoreWithScores("key", 5, 8)
   549  	assert.NotNil(t, err)
   550  	_, err = store.ZrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   551  	assert.NotNil(t, err)
   552  	_, err = store.ZrevrangebyscoreWithScores("key", 5, 8)
   553  	assert.NotNil(t, err)
   554  	_, err = store.ZrevrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   555  	assert.NotNil(t, err)
   556  	_, err = store.Zrevrank("key", "value")
   557  	assert.NotNil(t, err)
   558  	_, err = store.Zadds("key", redis.Pair{
   559  		Key:   "value2",
   560  		Score: 6,
   561  	}, redis.Pair{
   562  		Key:   "value3",
   563  		Score: 7,
   564  	})
   565  	assert.NotNil(t, err)
   566  
   567  	runOnCluster(t, func(client Store) {
   568  		ok, err := client.Zadd("key", 1, "value1")
   569  		assert.Nil(t, err)
   570  		assert.True(t, ok)
   571  		ok, err = client.Zadd("key", 2, "value1")
   572  		assert.Nil(t, err)
   573  		assert.False(t, ok)
   574  		val, err := client.Zscore("key", "value1")
   575  		assert.Nil(t, err)
   576  		assert.Equal(t, int64(2), val)
   577  		val, err = client.Zincrby("key", 3, "value1")
   578  		assert.Nil(t, err)
   579  		assert.Equal(t, int64(5), val)
   580  		val, err = client.Zscore("key", "value1")
   581  		assert.Nil(t, err)
   582  		assert.Equal(t, int64(5), val)
   583  		ok, err = client.Zadd("key", 6, "value2")
   584  		assert.Nil(t, err)
   585  		assert.True(t, ok)
   586  		ok, err = client.Zadd("key", 7, "value3")
   587  		assert.Nil(t, err)
   588  		assert.True(t, ok)
   589  		rank, err := client.Zrank("key", "value2")
   590  		assert.Nil(t, err)
   591  		assert.Equal(t, int64(1), rank)
   592  		_, err = client.Zrank("key", "value4")
   593  		assert.Equal(t, redis.Nil, err)
   594  		num, err := client.Zrem("key", "value2", "value3")
   595  		assert.Nil(t, err)
   596  		assert.Equal(t, 2, num)
   597  		ok, err = client.Zadd("key", 6, "value2")
   598  		assert.Nil(t, err)
   599  		assert.True(t, ok)
   600  		ok, err = client.Zadd("key", 7, "value3")
   601  		assert.Nil(t, err)
   602  		assert.True(t, ok)
   603  		ok, err = client.Zadd("key", 8, "value4")
   604  		assert.Nil(t, err)
   605  		assert.True(t, ok)
   606  		num, err = client.Zremrangebyscore("key", 6, 7)
   607  		assert.Nil(t, err)
   608  		assert.Equal(t, 2, num)
   609  		ok, err = client.Zadd("key", 6, "value2")
   610  		assert.Nil(t, err)
   611  		assert.True(t, ok)
   612  		ok, err = client.Zadd("key", 7, "value3")
   613  		assert.Nil(t, err)
   614  		assert.True(t, ok)
   615  		num, err = client.Zcount("key", 6, 7)
   616  		assert.Nil(t, err)
   617  		assert.Equal(t, 2, num)
   618  		num, err = client.Zremrangebyrank("key", 1, 2)
   619  		assert.Nil(t, err)
   620  		assert.Equal(t, 2, num)
   621  		card, err := client.Zcard("key")
   622  		assert.Nil(t, err)
   623  		assert.Equal(t, 2, card)
   624  		vals, err := client.Zrange("key", 0, -1)
   625  		assert.Nil(t, err)
   626  		assert.EqualValues(t, []string{"value1", "value4"}, vals)
   627  		vals, err = client.Zrevrange("key", 0, -1)
   628  		assert.Nil(t, err)
   629  		assert.EqualValues(t, []string{"value4", "value1"}, vals)
   630  		pairs, err := client.ZrangeWithScores("key", 0, -1)
   631  		assert.Nil(t, err)
   632  		assert.EqualValues(t, []redis.Pair{
   633  			{
   634  				Key:   "value1",
   635  				Score: 5,
   636  			},
   637  			{
   638  				Key:   "value4",
   639  				Score: 8,
   640  			},
   641  		}, pairs)
   642  		pairs, err = client.ZrangebyscoreWithScores("key", 5, 8)
   643  		assert.Nil(t, err)
   644  		assert.EqualValues(t, []redis.Pair{
   645  			{
   646  				Key:   "value1",
   647  				Score: 5,
   648  			},
   649  			{
   650  				Key:   "value4",
   651  				Score: 8,
   652  			},
   653  		}, pairs)
   654  		pairs, err = client.ZrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   655  		assert.Nil(t, err)
   656  		assert.EqualValues(t, []redis.Pair{
   657  			{
   658  				Key:   "value4",
   659  				Score: 8,
   660  			},
   661  		}, pairs)
   662  		pairs, err = client.ZrevrangebyscoreWithScores("key", 5, 8)
   663  		assert.Nil(t, err)
   664  		assert.EqualValues(t, []redis.Pair{
   665  			{
   666  				Key:   "value4",
   667  				Score: 8,
   668  			},
   669  			{
   670  				Key:   "value1",
   671  				Score: 5,
   672  			},
   673  		}, pairs)
   674  		pairs, err = client.ZrevrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   675  		assert.Nil(t, err)
   676  		assert.EqualValues(t, []redis.Pair{
   677  			{
   678  				Key:   "value1",
   679  				Score: 5,
   680  			},
   681  		}, pairs)
   682  		rank, err = client.Zrevrank("key", "value1")
   683  		assert.Nil(t, err)
   684  		assert.Equal(t, int64(1), rank)
   685  		val, err = client.Zadds("key", redis.Pair{
   686  			Key:   "value2",
   687  			Score: 6,
   688  		}, redis.Pair{
   689  			Key:   "value3",
   690  			Score: 7,
   691  		})
   692  		assert.Nil(t, err)
   693  		assert.Equal(t, int64(2), val)
   694  	})
   695  }
   696  
   697  func TestRedis_HyperLogLog(t *testing.T) {
   698  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   699  	_, err := store.Pfadd("key")
   700  	assert.NotNil(t, err)
   701  	_, err = store.Pfcount("key")
   702  	assert.NotNil(t, err)
   703  
   704  	runOnCluster(t, func(cluster Store) {
   705  		ok, err := cluster.Pfadd("key", "value")
   706  		assert.Nil(t, err)
   707  		assert.True(t, ok)
   708  		val, err := cluster.Pfcount("key")
   709  		assert.Nil(t, err)
   710  		assert.Equal(t, int64(1), val)
   711  	})
   712  }
   713  
   714  func runOnCluster(t *testing.T, fn func(cluster Store)) {
   715  	s1.FlushAll()
   716  	s2.FlushAll()
   717  
   718  	store := NewStore([]cache.NodeConf{
   719  		{
   720  			RedisConf: redis.RedisConf{
   721  				Host: s1.Addr(),
   722  				Type: redis.NodeType,
   723  			},
   724  			Weight: 100,
   725  		},
   726  		{
   727  			RedisConf: redis.RedisConf{
   728  				Host: s2.Addr(),
   729  				Type: redis.NodeType,
   730  			},
   731  			Weight: 100,
   732  		},
   733  	})
   734  
   735  	fn(store)
   736  }