github.com/rudderlabs/rudder-go-kit@v0.30.0/cachettl/cachettl_test.go (about)

     1  package cachettl
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestCacheTTL(t *testing.T) {
    11  	now := time.Now()
    12  
    13  	c := New[string, string]()
    14  	c.now = func() time.Time { return now }
    15  
    16  	// nothing done so far, we expect the cache to be empty
    17  	require.Nil(t, c.slice())
    18  
    19  	// insert the very first value
    20  	c.Put("two", "222", 2)
    21  	require.Equal(t, []string{"222"}, c.slice())
    22  
    23  	// insert the second value with an expiration higher than the first one
    24  	c.Put("three", "333", 3)
    25  	require.Equal(t, []string{"222", "333"}, c.slice())
    26  
    27  	// insert the third value with an expiration lower than all other values
    28  	c.Put("one", "111", 1)
    29  	require.Equal(t, []string{"111", "222", "333"}, c.slice())
    30  
    31  	// update "111" to have a higher expiration than all values
    32  	c.Put("one", "111", 4)
    33  	require.Equal(t, []string{"222", "333", "111"}, c.slice())
    34  
    35  	// update "333" to have a higher expiration than all values
    36  	c.Put("three", "333", 5)
    37  	require.Equal(t, []string{"222", "111", "333"}, c.slice())
    38  
    39  	// move time forward to expire "222"
    40  	c.now = func() time.Time { return now.Add(1) } // "222" should still be there
    41  	require.Empty(t, c.Get("whatever"))            // trigger the cleanup
    42  	require.Equal(t, []string{"222", "111", "333"}, c.slice())
    43  
    44  	c.now = func() time.Time { return now.Add(2) } // "222" should still be there
    45  	require.Empty(t, c.Get("whatever"))            // trigger the cleanup
    46  	require.Equal(t, []string{"222", "111", "333"}, c.slice())
    47  
    48  	c.now = func() time.Time { return now.Add(3) } // "222" should be expired!
    49  	require.Empty(t, c.Get("whatever"))            // trigger the cleanup
    50  	require.Equal(t, []string{"111", "333"}, c.slice())
    51  
    52  	// let's move a lot forward to expire everything
    53  	c.now = func() time.Time { return now.Add(6) }
    54  	require.Empty(t, c.Get("whatever")) // trigger the cleanup
    55  	require.Nil(t, c.slice())
    56  	require.Len(t, c.m, 0)
    57  
    58  	// now let's set a key, then move forward and get it directly without triggering with a different key
    59  	c.now = func() time.Time { return now }
    60  	c.Put("last", "999", 1)
    61  	require.Equal(t, "999", c.Get("last"))
    62  	require.Equal(t, []string{"999"}, c.slice())
    63  	c.now = func() time.Time { return now.Add(2) }
    64  	require.Empty(t, c.Get("last")) // trigger the cleanup
    65  	require.Nil(t, c.slice())
    66  	require.Len(t, c.m, 0)
    67  }
    68  
    69  func TestRefreshTTL(t *testing.T) {
    70  	c := New[string, string]()
    71  
    72  	// nothing done so far, we expect the cache to be empty
    73  	require.Nil(t, c.slice())
    74  
    75  	c.Put("one", "111", time.Second)
    76  	c.Put("two", "222", time.Second)
    77  	c.Put("three", "333", time.Second)
    78  	require.Equal(t, []string{"111", "222", "333"}, c.slice())
    79  
    80  	require.Equal(t, "111", c.Get("one"))
    81  	require.Equal(t, []string{"222", "333", "111"}, c.slice())
    82  
    83  	require.Equal(t, "222", c.Get("two"))
    84  	require.Equal(t, []string{"333", "111", "222"}, c.slice())
    85  
    86  	require.Equal(t, "333", c.Get("three"))
    87  	require.Equal(t, []string{"111", "222", "333"}, c.slice())
    88  }