...

Source file src/k8s.io/apimachinery/pkg/util/cache/lruexpirecache_test.go

Documentation: k8s.io/apimachinery/pkg/util/cache

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cache
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	testingclock "k8s.io/utils/clock/testing"
    25  )
    26  
    27  func expectEntry(t *testing.T, c *LRUExpireCache, key interface{}, value interface{}) {
    28  	t.Helper()
    29  	result, ok := c.Get(key)
    30  	if !ok || result != value {
    31  		t.Errorf("Expected cache[%v]: %v, got %v", key, value, result)
    32  	}
    33  }
    34  
    35  func expectNotEntry(t *testing.T, c *LRUExpireCache, key interface{}) {
    36  	t.Helper()
    37  	if result, ok := c.Get(key); ok {
    38  		t.Errorf("Expected cache[%v] to be empty, got %v", key, result)
    39  	}
    40  }
    41  
    42  // Note: Check keys before checking individual entries, because Get() changes
    43  // the eviction list.
    44  func assertKeys(t *testing.T, gotKeys, wantKeys []interface{}) {
    45  	t.Helper()
    46  	if diff := cmp.Diff(gotKeys, wantKeys); diff != "" {
    47  		t.Errorf("Wrong result for keys: diff (-got +want):\n%s", diff)
    48  	}
    49  }
    50  
    51  func TestSimpleGet(t *testing.T) {
    52  	c := NewLRUExpireCache(10)
    53  	c.Add("long-lived", "12345", 10*time.Hour)
    54  
    55  	assertKeys(t, c.Keys(), []interface{}{"long-lived"})
    56  
    57  	expectEntry(t, c, "long-lived", "12345")
    58  }
    59  
    60  func TestSimpleRemove(t *testing.T) {
    61  	c := NewLRUExpireCache(10)
    62  	c.Add("long-lived", "12345", 10*time.Hour)
    63  	c.Remove("long-lived")
    64  
    65  	assertKeys(t, c.Keys(), []interface{}{})
    66  
    67  	expectNotEntry(t, c, "long-lived")
    68  }
    69  
    70  func TestSimpleRemoveAll(t *testing.T) {
    71  	c := NewLRUExpireCache(10)
    72  	c.Add("long-lived", "12345", 10*time.Hour)
    73  	c.Add("other-long-lived", "12345", 10*time.Hour)
    74  	c.RemoveAll(func(k any) bool {
    75  		return k.(string) == "long-lived"
    76  	})
    77  
    78  	assertKeys(t, c.Keys(), []any{"other-long-lived"})
    79  
    80  	expectNotEntry(t, c, "long-lived")
    81  	expectEntry(t, c, "other-long-lived", "12345")
    82  }
    83  
    84  func TestExpiredGet(t *testing.T) {
    85  	fakeClock := testingclock.NewFakeClock(time.Now())
    86  	c := NewLRUExpireCacheWithClock(10, fakeClock)
    87  	c.Add("short-lived", "12345", 1*time.Millisecond)
    88  	// ensure the entry expired
    89  	fakeClock.Step(2 * time.Millisecond)
    90  
    91  	// Keys() should not return expired keys.
    92  	assertKeys(t, c.Keys(), []interface{}{})
    93  
    94  	expectNotEntry(t, c, "short-lived")
    95  }
    96  
    97  func TestLRUOverflow(t *testing.T) {
    98  	c := NewLRUExpireCache(4)
    99  	c.Add("elem1", "1", 10*time.Hour)
   100  	c.Add("elem2", "2", 10*time.Hour)
   101  	c.Add("elem3", "3", 10*time.Hour)
   102  	c.Add("elem4", "4", 10*time.Hour)
   103  	c.Add("elem5", "5", 10*time.Hour)
   104  
   105  	assertKeys(t, c.Keys(), []interface{}{"elem2", "elem3", "elem4", "elem5"})
   106  
   107  	expectNotEntry(t, c, "elem1")
   108  	expectEntry(t, c, "elem2", "2")
   109  	expectEntry(t, c, "elem3", "3")
   110  	expectEntry(t, c, "elem4", "4")
   111  	expectEntry(t, c, "elem5", "5")
   112  }
   113  
   114  func TestAddBringsToFront(t *testing.T) {
   115  	c := NewLRUExpireCache(4)
   116  	c.Add("elem1", "1", 10*time.Hour)
   117  	c.Add("elem2", "2", 10*time.Hour)
   118  	c.Add("elem3", "3", 10*time.Hour)
   119  	c.Add("elem4", "4", 10*time.Hour)
   120  
   121  	c.Add("elem1", "1-new", 10*time.Hour)
   122  
   123  	c.Add("elem5", "5", 10*time.Hour)
   124  
   125  	assertKeys(t, c.Keys(), []interface{}{"elem3", "elem4", "elem1", "elem5"})
   126  
   127  	expectNotEntry(t, c, "elem2")
   128  	expectEntry(t, c, "elem1", "1-new")
   129  	expectEntry(t, c, "elem3", "3")
   130  	expectEntry(t, c, "elem4", "4")
   131  	expectEntry(t, c, "elem5", "5")
   132  }
   133  
   134  func TestGetBringsToFront(t *testing.T) {
   135  	c := NewLRUExpireCache(4)
   136  	c.Add("elem1", "1", 10*time.Hour)
   137  	c.Add("elem2", "2", 10*time.Hour)
   138  	c.Add("elem3", "3", 10*time.Hour)
   139  	c.Add("elem4", "4", 10*time.Hour)
   140  
   141  	c.Get("elem1")
   142  
   143  	c.Add("elem5", "5", 10*time.Hour)
   144  
   145  	assertKeys(t, c.Keys(), []interface{}{"elem3", "elem4", "elem1", "elem5"})
   146  
   147  	expectNotEntry(t, c, "elem2")
   148  	expectEntry(t, c, "elem1", "1")
   149  	expectEntry(t, c, "elem3", "3")
   150  	expectEntry(t, c, "elem4", "4")
   151  	expectEntry(t, c, "elem5", "5")
   152  }
   153  
   154  func TestLRUKeys(t *testing.T) {
   155  	c := NewLRUExpireCache(4)
   156  	c.Add("elem1", "1", 10*time.Hour)
   157  	c.Add("elem2", "2", 10*time.Hour)
   158  	c.Add("elem3", "3", 10*time.Hour)
   159  	c.Add("elem4", "4", 10*time.Hour)
   160  
   161  	assertKeys(t, c.Keys(), []interface{}{"elem1", "elem2", "elem3", "elem4"})
   162  }
   163  

View as plain text