github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/services/cache/lru/lru_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  // This files was copied/modified from https://github.com/hashicorp/golang-lru
     5  // which was (see below)
     6  
     7  // This package provides a simple LRU cache. It is based on the
     8  // LRU implementation in groupcache:
     9  // https://github.com/golang/groupcache/tree/master/lru
    10  
    11  package lru
    12  
    13  import (
    14  	"fmt"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func TestLRU(t *testing.T) {
    23  	l := New(128)
    24  
    25  	for i := 0; i < 256; i++ {
    26  		l.Add(fmt.Sprintf("%d", i), i)
    27  	}
    28  	require.Equalf(t, l.Len(), 128, "bad len: %v", l.Len())
    29  
    30  	for i, k := range l.Keys() {
    31  		v, ok := l.Get(k)
    32  		require.True(t, ok, "bad key: %v", k)
    33  		require.Equalf(t, fmt.Sprintf("%d", v), k, "bad key: %v", k)
    34  		require.Equalf(t, i+128, v, "bad key: %v", k)
    35  	}
    36  	for i := 0; i < 128; i++ {
    37  		_, ok := l.Get(fmt.Sprintf("%d", i))
    38  		require.False(t, ok, "should be evicted")
    39  	}
    40  	for i := 128; i < 256; i++ {
    41  		_, ok := l.Get(fmt.Sprintf("%d", i))
    42  		require.True(t, ok, "should not be evicted")
    43  	}
    44  	for i := 128; i < 192; i++ {
    45  		l.Remove(fmt.Sprintf("%d", i))
    46  		_, ok := l.Get(fmt.Sprintf("%d", i))
    47  		require.False(t, ok, "should be deleted")
    48  	}
    49  
    50  	l.Get("192") // expect 192 to be last key in l.Keys()
    51  
    52  	for i, k := range l.Keys() {
    53  		require.Falsef(t, i < 63 && k != fmt.Sprintf("%d", i+193), "out of order key: %v", k)
    54  		require.Falsef(t, i == 63 && k != "192", "out of order key: %v", k)
    55  	}
    56  
    57  	l.Purge()
    58  	require.Equalf(t, l.Len(), 0, "bad len: %v", l.Len())
    59  	_, ok := l.Get("200")
    60  	require.False(t, ok, "should contain nothing")
    61  }
    62  
    63  func TestLRUExpire(t *testing.T) {
    64  	l := New(128)
    65  
    66  	l.AddWithExpiresInSecs("1", 1, 1)
    67  	l.AddWithExpiresInSecs("2", 2, 1)
    68  	l.AddWithExpiresInSecs("3", 3, 0)
    69  
    70  	time.Sleep(time.Millisecond * 2100)
    71  
    72  	r1, ok := l.Get("1")
    73  	require.False(t, ok, r1)
    74  
    75  	_, ok2 := l.Get("3")
    76  	require.True(t, ok2, "should exist")
    77  }
    78  
    79  func TestLRUGetOrAdd(t *testing.T) {
    80  	l := New(128)
    81  
    82  	// First GetOrAdd should save
    83  	value, loaded := l.GetOrAdd("1", 1, 0)
    84  	assert.Equal(t, 1, value)
    85  	assert.False(t, loaded)
    86  
    87  	// Second GetOrAdd should load original value, ignoring new value
    88  	value, loaded = l.GetOrAdd("1", 10, 0)
    89  	assert.Equal(t, 1, value)
    90  	assert.True(t, loaded)
    91  
    92  	// Third GetOrAdd should still load original value
    93  	value, loaded = l.GetOrAdd("1", 1, 0)
    94  	assert.Equal(t, 1, value)
    95  	assert.True(t, loaded)
    96  
    97  	// First GetOrAdd on a new key should save
    98  	value, loaded = l.GetOrAdd("2", 2, 0)
    99  	assert.Equal(t, 2, value)
   100  	assert.False(t, loaded)
   101  
   102  	l.Remove("1")
   103  
   104  	// GetOrAdd after a remove should save
   105  	value, loaded = l.GetOrAdd("1", 10, 0)
   106  	assert.Equal(t, 10, value)
   107  	assert.False(t, loaded)
   108  
   109  	// GetOrAdd after another key was removed should load original value for key
   110  	value, loaded = l.GetOrAdd("2", 2, 0)
   111  	assert.Equal(t, 2, value)
   112  	assert.True(t, loaded)
   113  
   114  	// GetOrAdd should expire
   115  	value, loaded = l.GetOrAdd("3", 3, 500*time.Millisecond)
   116  	assert.Equal(t, 3, value)
   117  	assert.False(t, loaded)
   118  	value, loaded = l.GetOrAdd("3", 4, 500*time.Millisecond)
   119  	assert.Equal(t, 3, value)
   120  	assert.True(t, loaded)
   121  	time.Sleep(1 * time.Second)
   122  	value, loaded = l.GetOrAdd("3", 5, 500*time.Millisecond)
   123  	assert.Equal(t, 5, value)
   124  	assert.False(t, loaded)
   125  }