github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/framework/cache/cache_test.go (about) 1 // The package is migrated from beego, you can get from following link: 2 // import( 3 // "github.com/beego/beego/v2/client/cache" 4 // ) 5 // Copyright 2023. All Rights Reserved. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 19 package cache 20 21 import ( 22 "context" 23 "math" 24 "os" 25 "strings" 26 "sync" 27 "testing" 28 "time" 29 30 "github.com/stretchr/testify/assert" 31 ) 32 33 func TestCacheIncr(t *testing.T) { 34 bm, err := NewCache("memory", `{"interval":20}`) 35 assert.Nil(t, err) 36 // timeoutDuration := 10 * time.Second 37 38 err = bm.Put(context.Background(), "edwardhey", 0, time.Second*20) 39 assert.Nil(t, err) 40 wg := sync.WaitGroup{} 41 wg.Add(10) 42 for i := 0; i < 10; i++ { 43 go func() { 44 defer wg.Done() 45 _ = bm.Incr(context.Background(), "edwardhey") 46 }() 47 } 48 wg.Wait() 49 val, _ := bm.Get(context.Background(), "edwardhey") 50 if val.(int) != 10 { 51 t.Error("Incr err") 52 } 53 } 54 55 func TestCache(t *testing.T) { 56 bm, err := NewCache("memory", `{"interval":1}`) 57 assert.Nil(t, err) 58 timeoutDuration := 5 * time.Second 59 if err = bm.Put(context.Background(), "astaxie", 1, timeoutDuration); err != nil { 60 t.Error("set Error", err) 61 } 62 if res, _ := bm.IsExist(context.Background(), "astaxie"); !res { 63 t.Error("check err") 64 } 65 66 if v, _ := bm.Get(context.Background(), "astaxie"); v.(int) != 1 { 67 t.Error("get err") 68 } 69 70 time.Sleep(7 * time.Second) 71 72 if res, _ := bm.IsExist(context.Background(), "astaxie"); res { 73 t.Error("check err") 74 } 75 76 if err = bm.Put(context.Background(), "astaxie", 1, timeoutDuration); err != nil { 77 t.Error("set Error", err) 78 } 79 80 // test different integer type for incr & decr 81 testMultiTypeIncrDecr(t, bm, timeoutDuration) 82 83 // test overflow of incr&decr 84 testIncrOverFlow(t, bm, timeoutDuration) 85 testDecrOverFlow(t, bm, timeoutDuration) 86 87 assert.Nil(t, bm.Delete(context.Background(), "astaxie")) 88 res, _ := bm.IsExist(context.Background(), "astaxie") 89 assert.False(t, res) 90 91 assert.Nil(t, bm.Put(context.Background(), "astaxie", "author", timeoutDuration)) 92 93 res, _ = bm.IsExist(context.Background(), "astaxie") 94 assert.True(t, res) 95 96 v, _ := bm.Get(context.Background(), "astaxie") 97 assert.Equal(t, "author", v) 98 99 assert.Nil(t, bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration)) 100 101 res, _ = bm.IsExist(context.Background(), "astaxie1") 102 assert.True(t, res) 103 104 vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"}) 105 assert.Equal(t, 2, len(vv)) 106 assert.Equal(t, "author", vv[0]) 107 assert.Equal(t, "author1", vv[1]) 108 109 vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"}) 110 assert.Equal(t, 2, len(vv)) 111 assert.Nil(t, vv[0]) 112 assert.Equal(t, "author1", vv[1]) 113 114 assert.NotNil(t, err) 115 assert.True(t, strings.Contains(err.Error(), "key isn't exist")) 116 } 117 118 func TestFileCache(t *testing.T) { 119 bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`) 120 assert.Nil(t, err) 121 timeoutDuration := 10 * time.Second 122 assert.Nil(t, bm.Put(context.Background(), "astaxie", 1, timeoutDuration)) 123 124 res, _ := bm.IsExist(context.Background(), "astaxie") 125 assert.True(t, res) 126 v, _ := bm.Get(context.Background(), "astaxie") 127 assert.Equal(t, 1, v) 128 129 // test different integer type for incr & decr 130 testMultiTypeIncrDecr(t, bm, timeoutDuration) 131 132 // test overflow of incr&decr 133 testIncrOverFlow(t, bm, timeoutDuration) 134 testDecrOverFlow(t, bm, timeoutDuration) 135 136 assert.Nil(t, bm.Delete(context.Background(), "astaxie")) 137 res, _ = bm.IsExist(context.Background(), "astaxie") 138 assert.False(t, res) 139 140 // test string 141 assert.Nil(t, bm.Put(context.Background(), "astaxie", "author", timeoutDuration)) 142 res, _ = bm.IsExist(context.Background(), "astaxie") 143 assert.True(t, res) 144 145 v, _ = bm.Get(context.Background(), "astaxie") 146 assert.Equal(t, "author", v) 147 148 // test GetMulti 149 assert.Nil(t, bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration)) 150 151 res, _ = bm.IsExist(context.Background(), "astaxie1") 152 assert.True(t, res) 153 154 vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"}) 155 assert.Equal(t, 2, len(vv)) 156 assert.Equal(t, "author", vv[0]) 157 assert.Equal(t, "author1", vv[1]) 158 159 vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"}) 160 assert.Equal(t, 2, len(vv)) 161 162 assert.Nil(t, vv[0]) 163 164 assert.Equal(t, "author1", vv[1]) 165 assert.NotNil(t, err) 166 assert.Nil(t, os.RemoveAll("cache")) 167 } 168 169 func testMultiTypeIncrDecr(t *testing.T, c Cache, timeout time.Duration) { 170 testIncrDecr(t, c, 1, 2, timeout) 171 testIncrDecr(t, c, int32(1), int32(2), timeout) 172 testIncrDecr(t, c, int64(1), int64(2), timeout) 173 testIncrDecr(t, c, uint(1), uint(2), timeout) 174 testIncrDecr(t, c, uint32(1), uint32(2), timeout) 175 testIncrDecr(t, c, uint64(1), uint64(2), timeout) 176 } 177 178 func testIncrDecr(t *testing.T, c Cache, beforeIncr interface{}, afterIncr interface{}, timeout time.Duration) { 179 ctx := context.Background() 180 key := "incDecKey" 181 182 assert.Nil(t, c.Put(ctx, key, beforeIncr, timeout)) 183 assert.Nil(t, c.Incr(ctx, key)) 184 185 v, _ := c.Get(ctx, key) 186 assert.Equal(t, afterIncr, v) 187 188 assert.Nil(t, c.Decr(ctx, key)) 189 190 v, _ = c.Get(ctx, key) 191 assert.Equal(t, v, beforeIncr) 192 assert.Nil(t, c.Delete(ctx, key)) 193 } 194 195 func testIncrOverFlow(t *testing.T, c Cache, timeout time.Duration) { 196 ctx := context.Background() 197 key := "incKey" 198 199 assert.Nil(t, c.Put(ctx, key, int64(math.MaxInt64), timeout)) 200 // int64 201 defer func() { 202 assert.Nil(t, c.Delete(ctx, key)) 203 }() 204 assert.NotNil(t, c.Incr(ctx, key)) 205 } 206 207 func testDecrOverFlow(t *testing.T, c Cache, timeout time.Duration) { 208 var err error 209 ctx := context.Background() 210 key := "decKey" 211 212 // int64 213 if err = c.Put(ctx, key, int64(math.MinInt64), timeout); err != nil { 214 t.Error("Put Error: ", err.Error()) 215 return 216 } 217 defer func() { 218 if err = c.Delete(ctx, key); err != nil { 219 t.Errorf("Delete error: %s", err.Error()) 220 } 221 }() 222 if err = c.Decr(ctx, key); err == nil { 223 t.Error("Decr error") 224 return 225 } 226 }