sigs.k8s.io/cluster-api-provider-azure@v1.14.3/util/cache/ttllru/ttllru_test.go (about) 1 /* 2 Copyright 2020 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 ttllru 18 19 import ( 20 "fmt" 21 "testing" 22 "time" 23 24 . "github.com/onsi/gomega" 25 "go.uber.org/mock/gomock" 26 gomockinternal "sigs.k8s.io/cluster-api-provider-azure/internal/test/matchers/gomock" 27 mockttllru "sigs.k8s.io/cluster-api-provider-azure/util/cache/ttllru/mocks" 28 ) 29 30 const ( 31 defaultCacheDuration = 30 * time.Second 32 ) 33 34 func TestNew(t *testing.T) { 35 g := NewWithT(t) 36 subject, err := New(128, defaultCacheDuration) 37 g.Expect(err).NotTo(HaveOccurred()) 38 g.Expect(subject).ShouldNot(BeNil()) 39 } 40 41 func TestCache_Add(t *testing.T) { 42 g := NewWithT(t) 43 mockCtrl := gomock.NewController(t) 44 mockCache := mockttllru.NewMockCacher(mockCtrl) 45 defer mockCtrl.Finish() 46 subject, err := newCache(defaultCacheDuration, mockCache) 47 g.Expect(err).NotTo(HaveOccurred()) 48 49 key, value := "foo", "bar" 50 mockCache.EXPECT().Add(gomock.Eq(key), gomockinternal.CustomMatcher( 51 func(val interface{}, state map[string]interface{}) bool { 52 ttl, ok := val.(*timeToLiveItem) 53 if !ok { 54 state["error"] = "value was not a time to live item" 55 return false 56 } 57 58 if ttl.Value != value || time.Since(ttl.LastTouch) >= defaultCacheDuration { 59 state["error"] = fmt.Sprintf("failed matching %+v", ttl) 60 return false 61 } 62 63 return true 64 }, 65 func(state map[string]interface{}) string { 66 return state["error"].(string) 67 }, 68 )) 69 subject.Add(key, value) 70 } 71 72 func TestCache_Get(t *testing.T) { 73 const ( 74 key = "key" 75 value = "value" 76 ) 77 78 cases := []struct { 79 Name string 80 TestCase func(g *GomegaWithT, subject PeekingCacher, mock *mockttllru.MockCacher) 81 }{ 82 { 83 Name: "NoItemsInCache", 84 TestCase: func(g *GomegaWithT, subject PeekingCacher, mock *mockttllru.MockCacher) { 85 key := "not_there" 86 mock.EXPECT().Get(key).Return(nil, false) 87 val, ok := subject.Get(key) 88 g.Expect(ok).To(BeFalse()) 89 g.Expect(val).To(BeNil()) 90 }, 91 }, 92 { 93 Name: "ExistingItemNotExpired", 94 TestCase: func(g *GomegaWithT, subject PeekingCacher, mock *mockttllru.MockCacher) { 95 mock.EXPECT().Get(key).Return(&timeToLiveItem{ 96 LastTouch: time.Now(), 97 Value: value, 98 }, true) 99 val, ok := subject.Get(key) 100 g.Expect(ok).To(BeTrue()) 101 g.Expect(val).To(Equal(value)) 102 }, 103 }, 104 { 105 Name: "ExistingItemExpired", 106 TestCase: func(g *GomegaWithT, subject PeekingCacher, mock *mockttllru.MockCacher) { 107 mock.EXPECT().Get(key).Return(&timeToLiveItem{ 108 LastTouch: time.Now().Add(-(10*time.Second + defaultCacheDuration)), 109 Value: value, 110 }, true) 111 mock.EXPECT().Remove(key).Return(false) 112 val, ok := subject.Get(key) 113 g.Expect(ok).To(BeFalse()) 114 g.Expect(val).To(BeNil()) 115 }, 116 }, 117 { 118 Name: "ExistingItemGetAdvancesLastTouch", 119 TestCase: func(g *GomegaWithT, subject PeekingCacher, mock *mockttllru.MockCacher) { 120 lastTouch := time.Now().Add(defaultCacheDuration - 10*time.Second) 121 item := &timeToLiveItem{ 122 LastTouch: lastTouch, 123 Value: value, 124 } 125 126 mock.EXPECT().Get(key).Return(item, true) 127 val, ok := subject.Get(key) 128 g.Expect(ok).To(BeTrue()) 129 g.Expect(val).To(Equal(value)) 130 g.Expect(lastTouch.After(item.LastTouch)).To(BeTrue()) 131 }, 132 }, 133 { 134 Name: "ExistingItemIsNotTTLItem", 135 TestCase: func(g *GomegaWithT, subject PeekingCacher, mock *mockttllru.MockCacher) { 136 item := &struct { 137 Value string 138 }{ 139 Value: value, 140 } 141 142 mock.EXPECT().Get(key).Return(item, true) 143 val, ok := subject.Get(key) 144 g.Expect(ok).To(BeFalse()) 145 g.Expect(val).To(BeNil()) 146 }, 147 }, 148 } 149 150 for _, c := range cases { 151 c := c 152 t.Run(c.Name, func(t *testing.T) { 153 g := NewWithT(t) 154 mockCtrl := gomock.NewController(t) 155 mockCache := mockttllru.NewMockCacher(mockCtrl) 156 defer mockCtrl.Finish() 157 subject, err := newCache(defaultCacheDuration, mockCache) 158 g.Expect(err).NotTo(HaveOccurred()) 159 c.TestCase(g, subject, mockCache) 160 }) 161 } 162 }