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  }