github.com/etecs-ru/ristretto@v0.9.1/policy_test.go (about) 1 package ristretto 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/stretchr/testify/require" 8 ) 9 10 func TestPolicy(t *testing.T) { 11 defer func() { 12 require.Nil(t, recover()) 13 }() 14 newPolicy(100, 10) 15 } 16 17 func TestPolicyMetrics(t *testing.T) { 18 p := newPolicy(100, 10) 19 p.CollectMetrics(newMetrics()) 20 require.NotNil(t, p.metrics) 21 require.NotNil(t, p.costs.metrics) 22 } 23 24 func TestPolicyProcessItems(t *testing.T) { 25 p := newPolicy(100, 10) 26 p.itemsCh <- []uint64{1, 2, 2} 27 time.Sleep(wait) 28 p.Lock() 29 require.Equal(t, int64(2), p.admit.Estimate(2)) 30 require.Equal(t, int64(1), p.admit.Estimate(1)) 31 p.Unlock() 32 33 p.stop <- struct{}{} 34 p.itemsCh <- []uint64{3, 3, 3} 35 time.Sleep(wait) 36 p.Lock() 37 require.Equal(t, int64(0), p.admit.Estimate(3)) 38 p.Unlock() 39 } 40 41 func TestPolicyPush(t *testing.T) { 42 p := newPolicy(100, 10) 43 require.True(t, p.Push([]uint64{})) 44 45 keepCount := 0 46 for i := 0; i < 10; i++ { 47 if p.Push([]uint64{1, 2, 3, 4, 5}) { 48 keepCount++ 49 } 50 } 51 require.NotEqual(t, 0, keepCount) 52 } 53 54 func TestPolicyAdd(t *testing.T) { 55 p := newPolicy(1000, 100) 56 if victims, added := p.Add(1, 101); victims != nil || added { 57 t.Fatal("can't add an item bigger than entire cache") 58 } 59 p.Lock() 60 p.costs.add(1, 1) 61 p.admit.Increment(1) 62 p.admit.Increment(2) 63 p.admit.Increment(3) 64 p.Unlock() 65 66 victims, added := p.Add(1, 1) 67 require.Nil(t, victims) 68 require.False(t, added) 69 70 victims, added = p.Add(2, 20) 71 require.Nil(t, victims) 72 require.True(t, added) 73 74 victims, added = p.Add(3, 90) 75 require.NotNil(t, victims) 76 require.True(t, added) 77 78 victims, added = p.Add(4, 20) 79 require.NotNil(t, victims) 80 require.False(t, added) 81 } 82 83 func TestPolicyHas(t *testing.T) { 84 p := newPolicy(100, 10) 85 p.Add(1, 1) 86 require.True(t, p.Has(1)) 87 require.False(t, p.Has(2)) 88 } 89 90 func TestPolicyDel(t *testing.T) { 91 p := newPolicy(100, 10) 92 p.Add(1, 1) 93 p.Del(1) 94 p.Del(2) 95 require.False(t, p.Has(1)) 96 require.False(t, p.Has(2)) 97 } 98 99 func TestPolicyCap(t *testing.T) { 100 p := newPolicy(100, 10) 101 p.Add(1, 1) 102 require.Equal(t, int64(9), p.Cap()) 103 } 104 105 func TestPolicyUpdate(t *testing.T) { 106 p := newPolicy(100, 10) 107 p.Add(1, 1) 108 p.Update(1, 2) 109 p.Lock() 110 require.Equal(t, int64(2), p.costs.keyCosts[1]) 111 p.Unlock() 112 } 113 114 func TestPolicyCost(t *testing.T) { 115 p := newPolicy(100, 10) 116 p.Add(1, 2) 117 require.Equal(t, int64(2), p.Cost(1)) 118 require.Equal(t, int64(-1), p.Cost(2)) 119 } 120 121 func TestPolicyClear(t *testing.T) { 122 p := newPolicy(100, 10) 123 p.Add(1, 1) 124 p.Add(2, 2) 125 p.Add(3, 3) 126 p.Clear() 127 require.Equal(t, int64(10), p.Cap()) 128 require.False(t, p.Has(1)) 129 require.False(t, p.Has(2)) 130 require.False(t, p.Has(3)) 131 } 132 133 func TestPolicyClose(t *testing.T) { 134 defer func() { 135 require.NotNil(t, recover()) 136 }() 137 138 p := newPolicy(100, 10) 139 p.Add(1, 1) 140 p.Close() 141 p.itemsCh <- []uint64{1} 142 } 143 144 func TestPushAfterClose(t *testing.T) { 145 p := newPolicy(100, 10) 146 p.Close() 147 require.False(t, p.Push([]uint64{1, 2})) 148 } 149 150 func TestAddAfterClose(t *testing.T) { 151 p := newPolicy(100, 10) 152 p.Close() 153 p.Add(1, 1) 154 } 155 156 func TestSampledLFUAdd(t *testing.T) { 157 e := newSampledLFU(4) 158 e.add(1, 1) 159 e.add(2, 2) 160 e.add(3, 1) 161 require.Equal(t, int64(4), e.used) 162 require.Equal(t, int64(2), e.keyCosts[2]) 163 } 164 165 func TestSampledLFUDel(t *testing.T) { 166 e := newSampledLFU(4) 167 e.add(1, 1) 168 e.add(2, 2) 169 e.del(2) 170 require.Equal(t, int64(1), e.used) 171 _, ok := e.keyCosts[2] 172 require.False(t, ok) 173 e.del(4) 174 } 175 176 func TestSampledLFUUpdate(t *testing.T) { 177 e := newSampledLFU(4) 178 e.add(1, 1) 179 require.True(t, e.updateIfHas(1, 2)) 180 require.Equal(t, int64(2), e.used) 181 require.False(t, e.updateIfHas(2, 2)) 182 } 183 184 func TestSampledLFUClear(t *testing.T) { 185 e := newSampledLFU(4) 186 e.add(1, 1) 187 e.add(2, 2) 188 e.add(3, 1) 189 e.clear() 190 require.Equal(t, 0, len(e.keyCosts)) 191 require.Equal(t, int64(0), e.used) 192 } 193 194 func TestSampledLFURoom(t *testing.T) { 195 e := newSampledLFU(16) 196 e.add(1, 1) 197 e.add(2, 2) 198 e.add(3, 3) 199 require.Equal(t, int64(6), e.roomLeft(4)) 200 } 201 202 func TestSampledLFUSample(t *testing.T) { 203 e := newSampledLFU(16) 204 e.add(4, 4) 205 e.add(5, 5) 206 sample := e.fillSample([]*policyPair{ 207 {1, 1}, 208 {2, 2}, 209 {3, 3}, 210 }) 211 k := sample[len(sample)-1].key 212 require.Equal(t, 5, len(sample)) 213 require.NotEqual(t, 1, k) 214 require.NotEqual(t, 2, k) 215 require.NotEqual(t, 3, k) 216 require.Equal(t, len(sample), len(e.fillSample(sample))) 217 e.del(5) 218 sample = e.fillSample(sample[:len(sample)-2]) 219 require.Equal(t, 4, len(sample)) 220 } 221 222 func TestTinyLFUIncrement(t *testing.T) { 223 a := newTinyLFU(4) 224 a.Increment(1) 225 a.Increment(1) 226 a.Increment(1) 227 require.True(t, a.door.Has(1)) 228 require.Equal(t, int64(2), a.freq.Estimate(1)) 229 230 a.Increment(1) 231 require.False(t, a.door.Has(1)) 232 require.Equal(t, int64(1), a.freq.Estimate(1)) 233 } 234 235 func TestTinyLFUEstimate(t *testing.T) { 236 a := newTinyLFU(8) 237 a.Increment(1) 238 a.Increment(1) 239 a.Increment(1) 240 require.Equal(t, int64(3), a.Estimate(1)) 241 require.Equal(t, int64(0), a.Estimate(2)) 242 } 243 244 func TestTinyLFUPush(t *testing.T) { 245 a := newTinyLFU(16) 246 a.Push([]uint64{1, 2, 2, 3, 3, 3}) 247 require.Equal(t, int64(1), a.Estimate(1)) 248 require.Equal(t, int64(2), a.Estimate(2)) 249 require.Equal(t, int64(3), a.Estimate(3)) 250 require.Equal(t, int64(6), a.incrs) 251 } 252 253 func TestTinyLFUClear(t *testing.T) { 254 a := newTinyLFU(16) 255 a.Push([]uint64{1, 3, 3, 3}) 256 a.clear() 257 require.Equal(t, int64(0), a.incrs) 258 require.Equal(t, int64(0), a.Estimate(3)) 259 }