mirror of https://github.com/cloudreve/Cloudreve
Test: redis cache
parent
cb61945125
commit
6d6255e759
2
go.mod
2
go.mod
|
@ -12,6 +12,7 @@ require (
|
||||||
github.com/gin-contrib/sessions v0.0.1
|
github.com/gin-contrib/sessions v0.0.1
|
||||||
github.com/gin-gonic/gin v1.4.0
|
github.com/gin-gonic/gin v1.4.0
|
||||||
github.com/go-ini/ini v1.50.0
|
github.com/go-ini/ini v1.50.0
|
||||||
|
github.com/gomodule/redigo v2.0.0+incompatible
|
||||||
github.com/jinzhu/gorm v1.9.11
|
github.com/jinzhu/gorm v1.9.11
|
||||||
github.com/juju/ratelimit v1.0.1
|
github.com/juju/ratelimit v1.0.1
|
||||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||||
|
@ -20,6 +21,7 @@ require (
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/pkg/errors v0.8.0
|
github.com/pkg/errors v0.8.0
|
||||||
github.com/qiniu/api.v7/v7 v7.4.0
|
github.com/qiniu/api.v7/v7 v7.4.0
|
||||||
|
github.com/rafaeljusto/redigomock v0.0.0-20191117212112-00b2509252a1
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
gopkg.in/go-playground/validator.v8 v8.18.2
|
gopkg.in/go-playground/validator.v8 v8.18.2
|
||||||
|
|
|
@ -37,17 +37,16 @@ func GetSettingByName(name string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSettingByNames 用多个 Name 获取设置值
|
// GetSettingByNames 用多个 Name 获取设置值
|
||||||
// TODO 其他设置获取也使用缓存
|
|
||||||
func GetSettingByNames(names []string) map[string]string {
|
func GetSettingByNames(names []string) map[string]string {
|
||||||
var queryRes []Setting
|
var queryRes []Setting
|
||||||
res, miss := cache.GetsSettingByName(names)
|
res, miss := cache.GetSettings(names, "setting_")
|
||||||
|
|
||||||
DB.Where("name IN (?)", miss).Find(&queryRes)
|
DB.Where("name IN (?)", miss).Find(&queryRes)
|
||||||
for _, setting := range queryRes {
|
for _, setting := range queryRes {
|
||||||
res[setting.Name] = setting.Value
|
res[setting.Name] = setting.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = cache.SetSettings(res)
|
_ = cache.SetSettings(res, "setting_")
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,18 @@ import (
|
||||||
var Store Driver
|
var Store Driver
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Store = NewRedisStore(10, "tcp", "127.0.0.1:6379", "", "0")
|
//Store = NewRedisStore(10, "tcp", "127.0.0.1:6379", "", "0")
|
||||||
return
|
//return
|
||||||
|
|
||||||
if conf.RedisConfig.Server == "" || gin.Mode() == gin.TestMode {
|
if conf.RedisConfig.Server == "" || gin.Mode() == gin.TestMode {
|
||||||
Store = NewMemoStore()
|
Store = NewMemoStore()
|
||||||
} else {
|
} else {
|
||||||
Store = NewRedisStore(10, "tcp", conf.RedisConfig.Server, conf.RedisConfig.Password, conf.RedisConfig.DB)
|
Store = NewRedisStore(
|
||||||
|
10,
|
||||||
|
"tcp",
|
||||||
|
conf.RedisConfig.Server,
|
||||||
|
conf.RedisConfig.Password,
|
||||||
|
conf.RedisConfig.DB,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,9 +46,9 @@ func Get(key string) (interface{}, bool) {
|
||||||
return Store.Get(key)
|
return Store.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetsSettingByName 根据名称批量获取设置项缓存
|
// GetSettings 根据名称批量获取设置项缓存
|
||||||
func GetsSettingByName(keys []string) (map[string]string, []string) {
|
func GetSettings(keys []string, prefix string) (map[string]string, []string) {
|
||||||
raw, miss := Store.Gets(keys, "setting_")
|
raw, miss := Store.Gets(keys, prefix)
|
||||||
|
|
||||||
res := make(map[string]string, len(raw))
|
res := make(map[string]string, len(raw))
|
||||||
for k, v := range raw {
|
for k, v := range raw {
|
||||||
|
@ -54,10 +59,10 @@ func GetsSettingByName(keys []string) (map[string]string, []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSettings 批量设置站点设置缓存
|
// SetSettings 批量设置站点设置缓存
|
||||||
func SetSettings(values map[string]string) error {
|
func SetSettings(values map[string]string, prefix string) error {
|
||||||
var toBeSet = make(map[string]interface{}, len(values))
|
var toBeSet = make(map[string]interface{}, len(values))
|
||||||
for key, value := range values {
|
for key, value := range values {
|
||||||
toBeSet[key] = interface{}(value)
|
toBeSet[key] = interface{}(value)
|
||||||
}
|
}
|
||||||
return Store.Sets(toBeSet, "setting_")
|
return Store.Sets(toBeSet, prefix)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSet(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
|
||||||
|
asserts.NoError(Set("123", "321"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGet(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
asserts.NoError(Set("123", "321"))
|
||||||
|
|
||||||
|
value, ok := Get("123")
|
||||||
|
asserts.True(ok)
|
||||||
|
asserts.Equal("321", value)
|
||||||
|
|
||||||
|
value, ok = Get("not_exist")
|
||||||
|
asserts.False(ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSettings(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
asserts.NoError(Set("test_1", "1"))
|
||||||
|
|
||||||
|
values, missed := GetSettings([]string{"1", "2"}, "test_")
|
||||||
|
asserts.Equal(map[string]string{"1": "1"}, values)
|
||||||
|
asserts.Equal([]string{"2"}, missed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetSettings(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
|
||||||
|
err := SetSettings(map[string]string{"3": "3", "4": "4"}, "test_")
|
||||||
|
asserts.NoError(err)
|
||||||
|
value1, _ := Get("test_3")
|
||||||
|
value2, _ := Get("test_4")
|
||||||
|
asserts.Equal("3", value1)
|
||||||
|
asserts.Equal("4", value2)
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"github.com/HFO4/cloudreve/pkg/util"
|
"github.com/HFO4/cloudreve/pkg/util"
|
||||||
"github.com/garyburd/redigo/redis"
|
"github.com/gomodule/redigo/redis"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -18,6 +18,30 @@ type item struct {
|
||||||
Value interface{}
|
Value interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serializer(value interface{}) ([]byte, error) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
enc := gob.NewEncoder(&buffer)
|
||||||
|
storeValue := item{
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
err := enc.Encode(storeValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buffer.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deserializer(value []byte) (interface{}, error) {
|
||||||
|
var res item
|
||||||
|
buffer := bytes.NewReader(value)
|
||||||
|
dec := gob.NewDecoder(buffer)
|
||||||
|
err := dec.Decode(&res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return res.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewRedisStore 创建新的redis存储
|
// NewRedisStore 创建新的redis存储
|
||||||
func NewRedisStore(size int, network, address, password, database string) *RedisStore {
|
func NewRedisStore(size int, network, address, password, database string) *RedisStore {
|
||||||
return &RedisStore{
|
return &RedisStore{
|
||||||
|
@ -55,46 +79,42 @@ func (store *RedisStore) Set(key string, value interface{}) error {
|
||||||
rc := store.pool.Get()
|
rc := store.pool.Get()
|
||||||
defer rc.Close()
|
defer rc.Close()
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
serialized, err := serializer(value)
|
||||||
enc := gob.NewEncoder(&buffer)
|
|
||||||
storeValue := item{
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
err := enc.Encode(storeValue)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if rc.Err() == nil {
|
if rc.Err() != nil {
|
||||||
_, err := rc.Do("SET", key, buffer.Bytes())
|
return rc.Err()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc.Err()
|
_, err = rc.Do("SET", key, serialized)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get 取值
|
// Get 取值
|
||||||
func (store *RedisStore) Get(key string) (interface{}, bool) {
|
func (store *RedisStore) Get(key string) (interface{}, bool) {
|
||||||
rc := store.pool.Get()
|
rc := store.pool.Get()
|
||||||
defer rc.Close()
|
defer rc.Close()
|
||||||
|
if rc.Err() != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
v, err := redis.Bytes(rc.Do("GET", key))
|
v, err := redis.Bytes(rc.Do("GET", key))
|
||||||
|
if err != nil || v == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
finalValue, err := deserializer(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
var res item
|
return finalValue, true
|
||||||
buffer := bytes.NewReader(v)
|
|
||||||
dec := gob.NewDecoder(buffer)
|
|
||||||
err = dec.Decode(&res)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.Value, true
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +122,9 @@ func (store *RedisStore) Get(key string) (interface{}, bool) {
|
||||||
func (store *RedisStore) Gets(keys []string, prefix string) (map[string]interface{}, []string) {
|
func (store *RedisStore) Gets(keys []string, prefix string) (map[string]interface{}, []string) {
|
||||||
rc := store.pool.Get()
|
rc := store.pool.Get()
|
||||||
defer rc.Close()
|
defer rc.Close()
|
||||||
|
if rc.Err() != nil {
|
||||||
|
return nil, keys
|
||||||
|
}
|
||||||
|
|
||||||
var queryKeys = make([]string, len(keys))
|
var queryKeys = make([]string, len(keys))
|
||||||
for key, value := range keys {
|
for key, value := range keys {
|
||||||
|
@ -117,14 +140,11 @@ func (store *RedisStore) Gets(keys []string, prefix string) (map[string]interfac
|
||||||
var missed = make([]string, 0, len(keys))
|
var missed = make([]string, 0, len(keys))
|
||||||
|
|
||||||
for key, value := range v {
|
for key, value := range v {
|
||||||
var decoded item
|
decoded, err := deserializer(value)
|
||||||
buffer := bytes.NewReader(value)
|
if err != nil || decoded == nil {
|
||||||
dec := gob.NewDecoder(buffer)
|
|
||||||
err = dec.Decode(&decoded)
|
|
||||||
if err != nil || decoded.Value == nil {
|
|
||||||
missed = append(missed, keys[key])
|
missed = append(missed, keys[key])
|
||||||
} else {
|
} else {
|
||||||
res[keys[key]] = decoded.Value
|
res[keys[key]] = decoded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 解码所得值
|
// 解码所得值
|
||||||
|
@ -135,20 +155,18 @@ func (store *RedisStore) Gets(keys []string, prefix string) (map[string]interfac
|
||||||
func (store *RedisStore) Sets(values map[string]interface{}, prefix string) error {
|
func (store *RedisStore) Sets(values map[string]interface{}, prefix string) error {
|
||||||
rc := store.pool.Get()
|
rc := store.pool.Get()
|
||||||
defer rc.Close()
|
defer rc.Close()
|
||||||
|
if rc.Err() != nil {
|
||||||
|
return rc.Err()
|
||||||
|
}
|
||||||
var setValues = make(map[string]interface{})
|
var setValues = make(map[string]interface{})
|
||||||
|
|
||||||
// 编码待设置值
|
// 编码待设置值
|
||||||
for key, value := range values {
|
for key, value := range values {
|
||||||
var buffer bytes.Buffer
|
serialized, err := serializer(value)
|
||||||
enc := gob.NewEncoder(&buffer)
|
|
||||||
storeValue := item{
|
|
||||||
Value: value,
|
|
||||||
}
|
|
||||||
err := enc.Encode(storeValue)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
setValues[prefix+key] = buffer.Bytes()
|
setValues[prefix+key] = serialized
|
||||||
}
|
}
|
||||||
|
|
||||||
if rc.Err() == nil {
|
if rc.Err() == nil {
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/gomodule/redigo/redis"
|
||||||
|
"github.com/rafaeljusto/redigomock"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewRedisStore(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
|
||||||
|
store := NewRedisStore(10, "tcp", ":2333", "", "0")
|
||||||
|
asserts.NotNil(store)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRedisStore_Set(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
conn := redigomock.NewConn()
|
||||||
|
pool := &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return conn, nil },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
store := &RedisStore{pool: pool}
|
||||||
|
|
||||||
|
// 正常情况
|
||||||
|
{
|
||||||
|
cmd := conn.Command("SET", "test", redigomock.NewAnyData()).ExpectStringSlice("OK")
|
||||||
|
err := store.Set("test", "test val")
|
||||||
|
asserts.NoError(err)
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 序列化出错
|
||||||
|
{
|
||||||
|
value := struct {
|
||||||
|
Key string
|
||||||
|
}{
|
||||||
|
Key: "123",
|
||||||
|
}
|
||||||
|
err := store.Set("test", value)
|
||||||
|
asserts.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令执行失败
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
cmd := conn.Command("SET", "test", redigomock.NewAnyData()).ExpectError(errors.New("error"))
|
||||||
|
err := store.Set("test", "test val")
|
||||||
|
asserts.Error(err)
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取连接失败
|
||||||
|
{
|
||||||
|
store.pool = &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return nil, errors.New("error") },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
err := store.Set("test", "123")
|
||||||
|
asserts.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRedisStore_Get(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
conn := redigomock.NewConn()
|
||||||
|
pool := &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return conn, nil },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
store := &RedisStore{pool: pool}
|
||||||
|
|
||||||
|
// 正常情况
|
||||||
|
{
|
||||||
|
expectVal, _ := serializer("test val")
|
||||||
|
cmd := conn.Command("GET", "test").Expect(expectVal)
|
||||||
|
val, ok := store.Get("test")
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.True(ok)
|
||||||
|
asserts.Equal("test val", val.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key不存在
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
cmd := conn.Command("GET", "test").Expect(nil)
|
||||||
|
val, ok := store.Get("test")
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.False(ok)
|
||||||
|
asserts.Nil(val)
|
||||||
|
}
|
||||||
|
// 解码错误
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
cmd := conn.Command("GET", "test").Expect([]byte{0x20})
|
||||||
|
val, ok := store.Get("test")
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.False(ok)
|
||||||
|
asserts.Nil(val)
|
||||||
|
}
|
||||||
|
// 获取连接失败
|
||||||
|
{
|
||||||
|
store.pool = &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return nil, errors.New("error") },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
val, ok := store.Get("test")
|
||||||
|
asserts.False(ok)
|
||||||
|
asserts.Nil(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRedisStore_Gets(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
conn := redigomock.NewConn()
|
||||||
|
pool := &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return conn, nil },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
store := &RedisStore{pool: pool}
|
||||||
|
|
||||||
|
// 全部命中
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
value1, _ := serializer("1")
|
||||||
|
value2, _ := serializer("2")
|
||||||
|
cmd := conn.Command("MGET", "test_1", "test_2").ExpectSlice(
|
||||||
|
value1, value2)
|
||||||
|
res, missed := store.Gets([]string{"1", "2"}, "test_")
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.Len(missed, 0)
|
||||||
|
asserts.Len(res, 2)
|
||||||
|
asserts.Equal("1", res["1"].(string))
|
||||||
|
asserts.Equal("2", res["2"].(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命中一个
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
value2, _ := serializer("2")
|
||||||
|
cmd := conn.Command("MGET", "test_1", "test_2").ExpectSlice(
|
||||||
|
nil, value2)
|
||||||
|
res, missed := store.Gets([]string{"1", "2"}, "test_")
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.Len(missed, 1)
|
||||||
|
asserts.Len(res, 1)
|
||||||
|
asserts.Equal("1", missed[0])
|
||||||
|
asserts.Equal("2", res["2"].(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令出错
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
cmd := conn.Command("MGET", "test_1", "test_2").ExpectError(errors.New("error"))
|
||||||
|
res, missed := store.Gets([]string{"1", "2"}, "test_")
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.Len(missed, 2)
|
||||||
|
asserts.Len(res, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接出错
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
store.pool = &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return nil, errors.New("error") },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
res, missed := store.Gets([]string{"1", "2"}, "test_")
|
||||||
|
asserts.Len(missed, 2)
|
||||||
|
asserts.Len(res, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRedisStore_Sets(t *testing.T) {
|
||||||
|
asserts := assert.New(t)
|
||||||
|
conn := redigomock.NewConn()
|
||||||
|
pool := &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return conn, nil },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
store := &RedisStore{pool: pool}
|
||||||
|
|
||||||
|
// 正常
|
||||||
|
{
|
||||||
|
cmd := conn.Command("MSET", redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData()).ExpectSlice("OK")
|
||||||
|
err := store.Sets(map[string]interface{}{"1": "1", "2": "2"}, "test_")
|
||||||
|
asserts.NoError(err)
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 序列化失败
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
value := struct {
|
||||||
|
Key string
|
||||||
|
}{
|
||||||
|
Key: "123",
|
||||||
|
}
|
||||||
|
err := store.Sets(map[string]interface{}{"1": value, "2": "2"}, "test_")
|
||||||
|
asserts.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行失败
|
||||||
|
{
|
||||||
|
cmd := conn.Command("MSET", redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData(), redigomock.NewAnyData()).ExpectError(errors.New("error"))
|
||||||
|
err := store.Sets(map[string]interface{}{"1": "1", "2": "2"}, "test_")
|
||||||
|
asserts.Error(err)
|
||||||
|
if conn.Stats(cmd) != 1 {
|
||||||
|
fmt.Println("Command was not used")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接失败
|
||||||
|
{
|
||||||
|
conn.Clear()
|
||||||
|
store.pool = &redis.Pool{
|
||||||
|
Dial: func() (redis.Conn, error) { return nil, errors.New("error") },
|
||||||
|
MaxIdle: 10,
|
||||||
|
}
|
||||||
|
err := store.Sets(map[string]interface{}{"1": "1", "2": "2"}, "test_")
|
||||||
|
asserts.Error(err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue