github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/framework/cache/read_through_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 "errors" 24 "fmt" 25 "testing" 26 "time" 27 28 "github.com/stretchr/testify/assert" 29 30 "github.com/mdaxf/iac/framework/berror" 31 ) 32 33 func TestReadThroughCache_Memory_Get(t *testing.T) { 34 bm, err := NewCache("memory", `{"interval":20}`) 35 assert.Nil(t, err) 36 testReadThroughCacheGet(t, bm) 37 } 38 39 func TestReadThroughCache_file_Get(t *testing.T) { 40 fc := NewFileCache().(*FileCache) 41 fc.CachePath = "////aaa" 42 err := fc.Init() 43 assert.NotNil(t, err) 44 fc.CachePath = getTestCacheFilePath() 45 err = fc.Init() 46 assert.Nil(t, err) 47 testReadThroughCacheGet(t, fc) 48 } 49 50 func testReadThroughCacheGet(t *testing.T, bm Cache) { 51 testCases := []struct { 52 name string 53 key string 54 value string 55 cache Cache 56 wantErr error 57 }{ 58 { 59 name: "Get load err", 60 key: "key0", 61 cache: func() Cache { 62 kvs := map[string]any{"key0": "value0"} 63 db := &MockOrm{kvs: kvs} 64 loadfunc := func(ctx context.Context, key string) (any, error) { 65 val, er := db.Load(key) 66 if er != nil { 67 return nil, er 68 } 69 return val, nil 70 } 71 c, err := NewReadThroughCache(bm, 3*time.Second, loadfunc) 72 assert.Nil(t, err) 73 return c 74 }(), 75 wantErr: func() error { 76 err := errors.New("the key not exist") 77 return berror.Wrap( 78 err, LoadFuncFailed, "cache unable to load data") 79 }(), 80 }, 81 { 82 name: "Get cache exist", 83 key: "key1", 84 value: "value1", 85 cache: func() Cache { 86 keysMap := map[string]int{"key1": 1} 87 kvs := map[string]any{"key1": "value1"} 88 db := &MockOrm{keysMap: keysMap, kvs: kvs} 89 loadfunc := func(ctx context.Context, key string) (any, error) { 90 val, er := db.Load(key) 91 if er != nil { 92 return nil, er 93 } 94 return val, nil 95 } 96 c, err := NewReadThroughCache(bm, 3*time.Second, loadfunc) 97 assert.Nil(t, err) 98 err = c.Put(context.Background(), "key1", "value1", 3*time.Second) 99 assert.Nil(t, err) 100 return c 101 }(), 102 }, 103 { 104 name: "Get loadFunc exist", 105 key: "key2", 106 value: "value2", 107 cache: func() Cache { 108 keysMap := map[string]int{"key2": 1} 109 kvs := map[string]any{"key2": "value2"} 110 db := &MockOrm{keysMap: keysMap, kvs: kvs} 111 loadfunc := func(ctx context.Context, key string) (any, error) { 112 val, er := db.Load(key) 113 if er != nil { 114 return nil, er 115 } 116 return val, nil 117 } 118 c, err := NewReadThroughCache(bm, 3*time.Second, loadfunc) 119 assert.Nil(t, err) 120 return c 121 }(), 122 }, 123 } 124 _, err := NewReadThroughCache(bm, 3*time.Second, nil) 125 assert.Equal(t, berror.Error(InvalidLoadFunc, "loadFunc cannot be nil"), err) 126 for _, tc := range testCases { 127 t.Run(tc.name, func(t *testing.T) { 128 c := tc.cache 129 val, err := c.Get(context.Background(), tc.key) 130 if err != nil { 131 assert.EqualError(t, tc.wantErr, err.Error()) 132 return 133 } 134 assert.Equal(t, tc.value, val) 135 }) 136 } 137 } 138 139 type MockOrm struct { 140 keysMap map[string]int 141 kvs map[string]any 142 } 143 144 func (m *MockOrm) Load(key string) (any, error) { 145 _, ok := m.keysMap[key] 146 if !ok { 147 return nil, errors.New("the key not exist") 148 } 149 return m.kvs[key], nil 150 } 151 152 func ExampleNewReadThroughCache() { 153 c := NewMemoryCache() 154 var err error 155 c, err = NewReadThroughCache(c, 156 // expiration, same as the expiration of key 157 time.Minute, 158 // load func, how to load data if the key is absent. 159 // in general, you should load data from database. 160 func(ctx context.Context, key string) (any, error) { 161 return fmt.Sprintf("hello, %s", key), nil 162 }) 163 if err != nil { 164 panic(err) 165 } 166 167 val, err := c.Get(context.Background(), "Beego") 168 if err != nil { 169 panic(err) 170 } 171 fmt.Print(val) 172 173 // Output: 174 // hello, Beego 175 }