github.com/vicanso/lru-ttl@v1.5.1/lru_ttl_test.go (about) 1 // Copyright 2020 tree xie 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lruttl 16 17 import ( 18 "sync" 19 "testing" 20 "time" 21 22 "github.com/stretchr/testify/assert" 23 ) 24 25 func TestLRUTTL(t *testing.T) { 26 assert := assert.New(t) 27 cache := New(1, 300*time.Millisecond) 28 key := "foo" 29 value := []byte("bar") 30 31 cache.Add(key, value) 32 assert.Equal(1, cache.Len()) 33 data, ok := cache.Get(key) 34 assert.True(ok) 35 assert.Equal(value, data) 36 37 data, ok = cache.Peek(key) 38 assert.True(ok) 39 assert.Equal(value, data) 40 41 // 添加新的数据 42 key1 := 123 43 value1 := []byte("bar1") 44 cache.Add(key1, value1, 100*time.Millisecond) 45 // 由于长度限制为1,因此原来的数据被清除 46 _, ok = cache.Get(key) 47 assert.False(ok) 48 assert.Equal(1, cache.Len()) 49 50 _, ok = cache.Get(key1) 51 assert.True(ok) 52 time.Sleep(500 * time.Millisecond) 53 // 数据过期,peek不清除,数据有返回 54 item, ok := cache.Peek(key1) 55 assert.False(ok) 56 assert.NotNil(item) 57 // 数据过期,get时清除,数据有返回 58 item, ok = cache.Get(key1) 59 assert.False(ok) 60 assert.NotNil(item) 61 62 // 添加数据 63 cache.Add(key, value) 64 assert.Equal(1, cache.Len()) 65 // 清除数据 66 cache.Remove(key) 67 assert.Equal(0, cache.Len()) 68 69 max := 10 70 cache = New(max, time.Minute) 71 for i := 0; i < 2*max; i++ { 72 cache.Add(i, i) 73 } 74 assert.Equal(max, cache.Len()) 75 assert.Equal(max, len(cache.Keys())) 76 } 77 78 func TestLRUTTLGetTTL(t *testing.T) { 79 assert := assert.New(t) 80 81 cache := New(10, time.Minute) 82 key := "test" 83 itemTTL := 100 * time.Millisecond 84 85 cache.Add(key, "a", itemTTL) 86 ttl := cache.TTL(key) 87 assert.True(ttl > (itemTTL/2) && ttl <= itemTTL) 88 // 等待过期 89 time.Sleep(2 * itemTTL) 90 ttl = cache.TTL(key) 91 assert.Equal(time.Duration(-1), ttl) 92 } 93 94 func TestLRUTTLParallelAdd(t *testing.T) { 95 assert := assert.New(t) 96 cache := New(10, time.Second) 97 key1 := "1" 98 value1 := "value1" 99 key2 := "2" 100 value2 := "value2" 101 wg := sync.WaitGroup{} 102 for i := 0; i < 100; i++ { 103 wg.Add(1) 104 if i%2 == 0 { 105 go func() { 106 cache.Add(key1, value1) 107 wg.Done() 108 }() 109 } else { 110 go func() { 111 cache.Add(key2, value2) 112 wg.Done() 113 }() 114 } 115 } 116 wg.Wait() 117 value, ok := cache.Get(key1) 118 assert.True(ok) 119 assert.Equal(value1, value) 120 121 value, ok = cache.Get(key2) 122 assert.True(ok) 123 assert.Equal(value2, value) 124 } 125 126 func TestLRUTTLParallelGet(t *testing.T) { 127 assert := assert.New(t) 128 cache := New(10, time.Second) 129 key1 := "1" 130 value1 := "value1" 131 cache.Add(key1, value1) 132 key2 := "2" 133 value2 := "value2" 134 cache.Add(key2, value2) 135 wg := sync.WaitGroup{} 136 for i := 0; i < 100; i++ { 137 wg.Add(1) 138 if i%2 == 0 { 139 go func() { 140 value, ok := cache.Get(key1) 141 assert.True(ok) 142 assert.Equal(value1, value) 143 wg.Done() 144 }() 145 } else { 146 go func() { 147 value, ok := cache.Get(key2) 148 assert.True(ok) 149 assert.Equal(value2, value) 150 wg.Done() 151 }() 152 } 153 } 154 wg.Wait() 155 } 156 157 func TestLRUTTLParallelPeek(t *testing.T) { 158 assert := assert.New(t) 159 cache := New(10, time.Second) 160 key1 := "1" 161 value1 := "value1" 162 cache.Add(key1, value1) 163 key2 := "2" 164 value2 := "value2" 165 cache.Add(key2, value2) 166 wg := sync.WaitGroup{} 167 for i := 0; i < 100; i++ { 168 wg.Add(1) 169 if i%2 == 0 { 170 go func() { 171 value, ok := cache.Peek(key1) 172 assert.True(ok) 173 assert.Equal(value1, value) 174 wg.Done() 175 }() 176 } else { 177 go func() { 178 value, ok := cache.Peek(key2) 179 assert.True(ok) 180 assert.Equal(value2, value) 181 wg.Done() 182 }() 183 } 184 } 185 wg.Wait() 186 } 187 188 func TestLRUTTLCacheOnEvicted(t *testing.T) { 189 assert := assert.New(t) 190 191 evictedCount := 0 192 evictedKeys := []string{ 193 "test1", 194 "test2", 195 } 196 cache := New(1, 300*time.Millisecond, CacheEvictedOption(func(key Key, value interface{}) { 197 assert.Equal(key, evictedKeys[evictedCount]) 198 evictedCount++ 199 })) 200 201 cache.Add("test1", "value1") 202 cache.Add("test2", "value2") 203 204 time.Sleep(500 * time.Millisecond) 205 // 此时再次获取,该key已过期,也会触发evicted 206 cache.Get("test2") 207 208 assert.Equal(2, evictedCount) 209 210 } 211 212 func TestGetAndPeekBytes(t *testing.T) { 213 assert := assert.New(t) 214 215 cache := New(10, time.Minute) 216 key := "key" 217 218 cache.Add(key, []byte("abc")) 219 220 data, ok := cache.GetBytes(key) 221 assert.True(ok) 222 assert.Equal([]byte("abc"), data) 223 224 data, ok = cache.PeekBytes(key) 225 assert.True(ok) 226 assert.Equal([]byte("abc"), data) 227 }