github.com/lingyao2333/mo-zero@v1.4.1/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/lingyao2333/mo-zero/core/hash"
     9  	"github.com/lingyao2333/mo-zero/core/stores/cache"
    10  	"github.com/lingyao2333/mo-zero/core/stores/redis"
    11  	"github.com/lingyao2333/mo-zero/core/stringx"
    12  	"github.com/stretchr/testify/assert"
    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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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_Getset(t *testing.T) {
   494  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   495  	_, err := store.GetSet("hello", "world")
   496  	assert.NotNil(t, err)
   497  
   498  	runOnCluster(func(client Store) {
   499  		val, err := client.GetSet("hello", "world")
   500  		assert.Nil(t, err)
   501  		assert.Equal(t, "", val)
   502  		val, err = client.Get("hello")
   503  		assert.Nil(t, err)
   504  		assert.Equal(t, "world", val)
   505  		val, err = client.GetSet("hello", "newworld")
   506  		assert.Nil(t, err)
   507  		assert.Equal(t, "world", val)
   508  		val, err = client.Get("hello")
   509  		assert.Nil(t, err)
   510  		assert.Equal(t, "newworld", val)
   511  		_, err = client.Del("hello")
   512  		assert.Nil(t, err)
   513  	})
   514  }
   515  
   516  func TestRedis_SetGetDelHashField(t *testing.T) {
   517  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   518  	err := store.Hset("key", "field", "value")
   519  	assert.NotNil(t, err)
   520  	_, err = store.Hget("key", "field")
   521  	assert.NotNil(t, err)
   522  	_, err = store.Hexists("key", "field")
   523  	assert.NotNil(t, err)
   524  	_, err = store.Hdel("key", "field")
   525  	assert.NotNil(t, err)
   526  
   527  	runOnCluster(func(client Store) {
   528  		err := client.Hset("key", "field", "value")
   529  		assert.Nil(t, err)
   530  		val, err := client.Hget("key", "field")
   531  		assert.Nil(t, err)
   532  		assert.Equal(t, "value", val)
   533  		ok, err := client.Hexists("key", "field")
   534  		assert.Nil(t, err)
   535  		assert.True(t, ok)
   536  		ret, err := client.Hdel("key", "field")
   537  		assert.Nil(t, err)
   538  		assert.True(t, ret)
   539  		ok, err = client.Hexists("key", "field")
   540  		assert.Nil(t, err)
   541  		assert.False(t, ok)
   542  	})
   543  }
   544  
   545  func TestRedis_SortedSet(t *testing.T) {
   546  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   547  	_, err := store.Zadd("key", 1, "value1")
   548  	assert.NotNil(t, err)
   549  	_, err = store.Zscore("key", "value1")
   550  	assert.NotNil(t, err)
   551  	_, err = store.Zcount("key", 6, 7)
   552  	assert.NotNil(t, err)
   553  	_, err = store.Zincrby("key", 3, "value1")
   554  	assert.NotNil(t, err)
   555  	_, err = store.Zrank("key", "value2")
   556  	assert.NotNil(t, err)
   557  	_, err = store.Zrem("key", "value2", "value3")
   558  	assert.NotNil(t, err)
   559  	_, err = store.Zremrangebyscore("key", 6, 7)
   560  	assert.NotNil(t, err)
   561  	_, err = store.Zremrangebyrank("key", 1, 2)
   562  	assert.NotNil(t, err)
   563  	_, err = store.Zcard("key")
   564  	assert.NotNil(t, err)
   565  	_, err = store.Zrange("key", 0, -1)
   566  	assert.NotNil(t, err)
   567  	_, err = store.Zrevrange("key", 0, -1)
   568  	assert.NotNil(t, err)
   569  	_, err = store.ZrangeWithScores("key", 0, -1)
   570  	assert.NotNil(t, err)
   571  	_, err = store.ZrangebyscoreWithScores("key", 5, 8)
   572  	assert.NotNil(t, err)
   573  	_, err = store.ZrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   574  	assert.NotNil(t, err)
   575  	_, err = store.ZrevrangebyscoreWithScores("key", 5, 8)
   576  	assert.NotNil(t, err)
   577  	_, err = store.ZrevrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   578  	assert.NotNil(t, err)
   579  	_, err = store.Zrevrank("key", "value")
   580  	assert.NotNil(t, err)
   581  	_, err = store.Zadds("key", redis.Pair{
   582  		Key:   "value2",
   583  		Score: 6,
   584  	}, redis.Pair{
   585  		Key:   "value3",
   586  		Score: 7,
   587  	})
   588  	assert.NotNil(t, err)
   589  
   590  	runOnCluster(func(client Store) {
   591  		ok, err := client.ZaddFloat("key", 1, "value1")
   592  		assert.Nil(t, err)
   593  		assert.True(t, ok)
   594  		ok, err = client.Zadd("key", 2, "value1")
   595  		assert.Nil(t, err)
   596  		assert.False(t, ok)
   597  		val, err := client.Zscore("key", "value1")
   598  		assert.Nil(t, err)
   599  		assert.Equal(t, int64(2), val)
   600  		val, err = client.Zincrby("key", 3, "value1")
   601  		assert.Nil(t, err)
   602  		assert.Equal(t, int64(5), val)
   603  		val, err = client.Zscore("key", "value1")
   604  		assert.Nil(t, err)
   605  		assert.Equal(t, int64(5), val)
   606  		ok, err = client.Zadd("key", 6, "value2")
   607  		assert.Nil(t, err)
   608  		assert.True(t, ok)
   609  		ok, err = client.Zadd("key", 7, "value3")
   610  		assert.Nil(t, err)
   611  		assert.True(t, ok)
   612  		rank, err := client.Zrank("key", "value2")
   613  		assert.Nil(t, err)
   614  		assert.Equal(t, int64(1), rank)
   615  		_, err = client.Zrank("key", "value4")
   616  		assert.Equal(t, redis.Nil, err)
   617  		num, err := client.Zrem("key", "value2", "value3")
   618  		assert.Nil(t, err)
   619  		assert.Equal(t, 2, num)
   620  		ok, err = client.Zadd("key", 6, "value2")
   621  		assert.Nil(t, err)
   622  		assert.True(t, ok)
   623  		ok, err = client.Zadd("key", 7, "value3")
   624  		assert.Nil(t, err)
   625  		assert.True(t, ok)
   626  		ok, err = client.Zadd("key", 8, "value4")
   627  		assert.Nil(t, err)
   628  		assert.True(t, ok)
   629  		num, err = client.Zremrangebyscore("key", 6, 7)
   630  		assert.Nil(t, err)
   631  		assert.Equal(t, 2, num)
   632  		ok, err = client.Zadd("key", 6, "value2")
   633  		assert.Nil(t, err)
   634  		assert.True(t, ok)
   635  		ok, err = client.Zadd("key", 7, "value3")
   636  		assert.Nil(t, err)
   637  		assert.True(t, ok)
   638  		num, err = client.Zcount("key", 6, 7)
   639  		assert.Nil(t, err)
   640  		assert.Equal(t, 2, num)
   641  		num, err = client.Zremrangebyrank("key", 1, 2)
   642  		assert.Nil(t, err)
   643  		assert.Equal(t, 2, num)
   644  		card, err := client.Zcard("key")
   645  		assert.Nil(t, err)
   646  		assert.Equal(t, 2, card)
   647  		vals, err := client.Zrange("key", 0, -1)
   648  		assert.Nil(t, err)
   649  		assert.EqualValues(t, []string{"value1", "value4"}, vals)
   650  		vals, err = client.Zrevrange("key", 0, -1)
   651  		assert.Nil(t, err)
   652  		assert.EqualValues(t, []string{"value4", "value1"}, vals)
   653  		pairs, err := client.ZrangeWithScores("key", 0, -1)
   654  		assert.Nil(t, err)
   655  		assert.EqualValues(t, []redis.Pair{
   656  			{
   657  				Key:   "value1",
   658  				Score: 5,
   659  			},
   660  			{
   661  				Key:   "value4",
   662  				Score: 8,
   663  			},
   664  		}, pairs)
   665  		pairs, err = client.ZrangebyscoreWithScores("key", 5, 8)
   666  		assert.Nil(t, err)
   667  		assert.EqualValues(t, []redis.Pair{
   668  			{
   669  				Key:   "value1",
   670  				Score: 5,
   671  			},
   672  			{
   673  				Key:   "value4",
   674  				Score: 8,
   675  			},
   676  		}, pairs)
   677  		pairs, err = client.ZrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   678  		assert.Nil(t, err)
   679  		assert.EqualValues(t, []redis.Pair{
   680  			{
   681  				Key:   "value4",
   682  				Score: 8,
   683  			},
   684  		}, pairs)
   685  		pairs, err = client.ZrevrangebyscoreWithScores("key", 5, 8)
   686  		assert.Nil(t, err)
   687  		assert.EqualValues(t, []redis.Pair{
   688  			{
   689  				Key:   "value4",
   690  				Score: 8,
   691  			},
   692  			{
   693  				Key:   "value1",
   694  				Score: 5,
   695  			},
   696  		}, pairs)
   697  		pairs, err = client.ZrevrangebyscoreWithScoresAndLimit("key", 5, 8, 1, 1)
   698  		assert.Nil(t, err)
   699  		assert.EqualValues(t, []redis.Pair{
   700  			{
   701  				Key:   "value1",
   702  				Score: 5,
   703  			},
   704  		}, pairs)
   705  		rank, err = client.Zrevrank("key", "value1")
   706  		assert.Nil(t, err)
   707  		assert.Equal(t, int64(1), rank)
   708  		val, err = client.Zadds("key", redis.Pair{
   709  			Key:   "value2",
   710  			Score: 6,
   711  		}, redis.Pair{
   712  			Key:   "value3",
   713  			Score: 7,
   714  		})
   715  		assert.Nil(t, err)
   716  		assert.Equal(t, int64(2), val)
   717  	})
   718  }
   719  
   720  func TestRedis_HyperLogLog(t *testing.T) {
   721  	store := clusterStore{dispatcher: hash.NewConsistentHash()}
   722  	_, err := store.Pfadd("key")
   723  	assert.NotNil(t, err)
   724  	_, err = store.Pfcount("key")
   725  	assert.NotNil(t, err)
   726  
   727  	runOnCluster(func(cluster Store) {
   728  		ok, err := cluster.Pfadd("key", "value")
   729  		assert.Nil(t, err)
   730  		assert.True(t, ok)
   731  		val, err := cluster.Pfcount("key")
   732  		assert.Nil(t, err)
   733  		assert.Equal(t, int64(1), val)
   734  	})
   735  }
   736  
   737  func runOnCluster(fn func(cluster Store)) {
   738  	s1.FlushAll()
   739  	s2.FlushAll()
   740  
   741  	store := NewStore([]cache.NodeConf{
   742  		{
   743  			RedisConf: redis.RedisConf{
   744  				Host: s1.Addr(),
   745  				Type: redis.NodeType,
   746  			},
   747  			Weight: 100,
   748  		},
   749  		{
   750  			RedisConf: redis.RedisConf{
   751  				Host: s2.Addr(),
   752  				Type: redis.NodeType,
   753  			},
   754  			Weight: 100,
   755  		},
   756  	})
   757  
   758  	fn(store)
   759  }