github.com/shuguocloud/go-zero@v1.3.0/core/stores/cache/cachenode_test.go (about) 1 package cache 2 3 import ( 4 "errors" 5 "fmt" 6 "math/rand" 7 "strconv" 8 "sync" 9 "testing" 10 "time" 11 12 "github.com/alicebob/miniredis/v2" 13 "github.com/stretchr/testify/assert" 14 "github.com/shuguocloud/go-zero/core/logx" 15 "github.com/shuguocloud/go-zero/core/mathx" 16 "github.com/shuguocloud/go-zero/core/stat" 17 "github.com/shuguocloud/go-zero/core/stores/redis" 18 "github.com/shuguocloud/go-zero/core/stores/redis/redistest" 19 "github.com/shuguocloud/go-zero/core/syncx" 20 ) 21 22 var errTestNotFound = errors.New("not found") 23 24 func init() { 25 logx.Disable() 26 stat.SetReporter(nil) 27 } 28 29 func TestCacheNode_DelCache(t *testing.T) { 30 store, clean, err := redistest.CreateRedis() 31 assert.Nil(t, err) 32 store.Type = redis.ClusterType 33 defer clean() 34 35 cn := cacheNode{ 36 rds: store, 37 r: rand.New(rand.NewSource(time.Now().UnixNano())), 38 lock: new(sync.Mutex), 39 unstableExpiry: mathx.NewUnstable(expiryDeviation), 40 stat: NewStat("any"), 41 errNotFound: errTestNotFound, 42 } 43 assert.Nil(t, cn.Del()) 44 assert.Nil(t, cn.Del([]string{}...)) 45 assert.Nil(t, cn.Del(make([]string, 0)...)) 46 cn.Set("first", "one") 47 assert.Nil(t, cn.Del("first")) 48 cn.Set("first", "one") 49 cn.Set("second", "two") 50 assert.Nil(t, cn.Del("first", "second")) 51 } 52 53 func TestCacheNode_DelCacheWithErrors(t *testing.T) { 54 store, clean, err := redistest.CreateRedis() 55 assert.Nil(t, err) 56 defer clean() 57 store.Type = redis.ClusterType 58 59 cn := cacheNode{ 60 rds: store, 61 r: rand.New(rand.NewSource(time.Now().UnixNano())), 62 lock: new(sync.Mutex), 63 unstableExpiry: mathx.NewUnstable(expiryDeviation), 64 stat: NewStat("any"), 65 errNotFound: errTestNotFound, 66 } 67 assert.Nil(t, cn.Del("third", "fourth")) 68 } 69 70 func TestCacheNode_InvalidCache(t *testing.T) { 71 s, err := miniredis.Run() 72 assert.Nil(t, err) 73 defer s.Close() 74 75 cn := cacheNode{ 76 rds: redis.New(s.Addr()), 77 r: rand.New(rand.NewSource(time.Now().UnixNano())), 78 lock: new(sync.Mutex), 79 unstableExpiry: mathx.NewUnstable(expiryDeviation), 80 stat: NewStat("any"), 81 errNotFound: errTestNotFound, 82 } 83 s.Set("any", "value") 84 var str string 85 assert.NotNil(t, cn.Get("any", &str)) 86 assert.Equal(t, "", str) 87 _, err = s.Get("any") 88 assert.Equal(t, miniredis.ErrKeyNotFound, err) 89 } 90 91 func TestCacheNode_Take(t *testing.T) { 92 store, clean, err := redistest.CreateRedis() 93 assert.Nil(t, err) 94 defer clean() 95 96 cn := cacheNode{ 97 rds: store, 98 r: rand.New(rand.NewSource(time.Now().UnixNano())), 99 barrier: syncx.NewSingleFlight(), 100 lock: new(sync.Mutex), 101 unstableExpiry: mathx.NewUnstable(expiryDeviation), 102 stat: NewStat("any"), 103 errNotFound: errTestNotFound, 104 } 105 var str string 106 err = cn.Take(&str, "any", func(v interface{}) error { 107 *v.(*string) = "value" 108 return nil 109 }) 110 assert.Nil(t, err) 111 assert.Equal(t, "value", str) 112 assert.Nil(t, cn.Get("any", &str)) 113 val, err := store.Get("any") 114 assert.Nil(t, err) 115 assert.Equal(t, `"value"`, val) 116 } 117 118 func TestCacheNode_TakeNotFound(t *testing.T) { 119 store, clean, err := redistest.CreateRedis() 120 assert.Nil(t, err) 121 defer clean() 122 123 cn := cacheNode{ 124 rds: store, 125 r: rand.New(rand.NewSource(time.Now().UnixNano())), 126 barrier: syncx.NewSingleFlight(), 127 lock: new(sync.Mutex), 128 unstableExpiry: mathx.NewUnstable(expiryDeviation), 129 stat: NewStat("any"), 130 errNotFound: errTestNotFound, 131 } 132 var str string 133 err = cn.Take(&str, "any", func(v interface{}) error { 134 return errTestNotFound 135 }) 136 assert.True(t, cn.IsNotFound(err)) 137 assert.True(t, cn.IsNotFound(cn.Get("any", &str))) 138 val, err := store.Get("any") 139 assert.Nil(t, err) 140 assert.Equal(t, `*`, val) 141 142 store.Set("any", "*") 143 err = cn.Take(&str, "any", func(v interface{}) error { 144 return nil 145 }) 146 assert.True(t, cn.IsNotFound(err)) 147 assert.True(t, cn.IsNotFound(cn.Get("any", &str))) 148 149 store.Del("any") 150 errDummy := errors.New("dummy") 151 err = cn.Take(&str, "any", func(v interface{}) error { 152 return errDummy 153 }) 154 assert.Equal(t, errDummy, err) 155 } 156 157 func TestCacheNode_TakeWithExpire(t *testing.T) { 158 store, clean, err := redistest.CreateRedis() 159 assert.Nil(t, err) 160 defer clean() 161 162 cn := cacheNode{ 163 rds: store, 164 r: rand.New(rand.NewSource(time.Now().UnixNano())), 165 barrier: syncx.NewSingleFlight(), 166 lock: new(sync.Mutex), 167 unstableExpiry: mathx.NewUnstable(expiryDeviation), 168 stat: NewStat("any"), 169 errNotFound: errors.New("any"), 170 } 171 var str string 172 err = cn.TakeWithExpire(&str, "any", func(v interface{}, expire time.Duration) error { 173 *v.(*string) = "value" 174 return nil 175 }) 176 assert.Nil(t, err) 177 assert.Equal(t, "value", str) 178 assert.Nil(t, cn.Get("any", &str)) 179 val, err := store.Get("any") 180 assert.Nil(t, err) 181 assert.Equal(t, `"value"`, val) 182 } 183 184 func TestCacheNode_String(t *testing.T) { 185 store, clean, err := redistest.CreateRedis() 186 assert.Nil(t, err) 187 defer clean() 188 189 cn := cacheNode{ 190 rds: store, 191 r: rand.New(rand.NewSource(time.Now().UnixNano())), 192 barrier: syncx.NewSingleFlight(), 193 lock: new(sync.Mutex), 194 unstableExpiry: mathx.NewUnstable(expiryDeviation), 195 stat: NewStat("any"), 196 errNotFound: errors.New("any"), 197 } 198 assert.Equal(t, store.Addr, cn.String()) 199 } 200 201 func TestCacheValueWithBigInt(t *testing.T) { 202 store, clean, err := redistest.CreateRedis() 203 assert.Nil(t, err) 204 defer clean() 205 206 cn := cacheNode{ 207 rds: store, 208 r: rand.New(rand.NewSource(time.Now().UnixNano())), 209 barrier: syncx.NewSingleFlight(), 210 lock: new(sync.Mutex), 211 unstableExpiry: mathx.NewUnstable(expiryDeviation), 212 stat: NewStat("any"), 213 errNotFound: errors.New("any"), 214 } 215 216 const ( 217 key = "key" 218 value int64 = 323427211229009810 219 ) 220 221 assert.Nil(t, cn.Set(key, value)) 222 var val interface{} 223 assert.Nil(t, cn.Get(key, &val)) 224 assert.Equal(t, strconv.FormatInt(value, 10), fmt.Sprintf("%v", val)) 225 }