1package simplelru 2 3import "testing" 4 5func TestLRU(t *testing.T) { 6 evictCounter := 0 7 onEvicted := func(k interface{}, v interface{}) { 8 if k != v { 9 t.Fatalf("Evict values not equal (%v!=%v)", k, v) 10 } 11 evictCounter++ 12 } 13 l, err := NewLRU(128, onEvicted) 14 if err != nil { 15 t.Fatalf("err: %v", err) 16 } 17 18 for i := 0; i < 256; i++ { 19 l.Add(i, i) 20 } 21 if l.Len() != 128 { 22 t.Fatalf("bad len: %v", l.Len()) 23 } 24 25 if evictCounter != 128 { 26 t.Fatalf("bad evict count: %v", evictCounter) 27 } 28 29 for i, k := range l.Keys() { 30 if v, ok := l.Get(k); !ok || v != k || v != i+128 { 31 t.Fatalf("bad key: %v", k) 32 } 33 } 34 for i := 0; i < 128; i++ { 35 _, ok := l.Get(i) 36 if ok { 37 t.Fatalf("should be evicted") 38 } 39 } 40 for i := 128; i < 256; i++ { 41 _, ok := l.Get(i) 42 if !ok { 43 t.Fatalf("should not be evicted") 44 } 45 } 46 for i := 128; i < 192; i++ { 47 ok := l.Remove(i) 48 if !ok { 49 t.Fatalf("should be contained") 50 } 51 ok = l.Remove(i) 52 if ok { 53 t.Fatalf("should not be contained") 54 } 55 _, ok = l.Get(i) 56 if ok { 57 t.Fatalf("should be deleted") 58 } 59 } 60 61 l.Get(192) // expect 192 to be last key in l.Keys() 62 63 for i, k := range l.Keys() { 64 if (i < 63 && k != i+193) || (i == 63 && k != 192) { 65 t.Fatalf("out of order key: %v", k) 66 } 67 } 68 69 l.Purge() 70 if l.Len() != 0 { 71 t.Fatalf("bad len: %v", l.Len()) 72 } 73 if _, ok := l.Get(200); ok { 74 t.Fatalf("should contain nothing") 75 } 76} 77 78func TestLRU_GetOldest_RemoveOldest(t *testing.T) { 79 l, err := NewLRU(128, nil) 80 if err != nil { 81 t.Fatalf("err: %v", err) 82 } 83 for i := 0; i < 256; i++ { 84 l.Add(i, i) 85 } 86 k, _, ok := l.GetOldest() 87 if !ok { 88 t.Fatalf("missing") 89 } 90 if k.(int) != 128 { 91 t.Fatalf("bad: %v", k) 92 } 93 94 k, _, ok = l.RemoveOldest() 95 if !ok { 96 t.Fatalf("missing") 97 } 98 if k.(int) != 128 { 99 t.Fatalf("bad: %v", k) 100 } 101 102 k, _, ok = l.RemoveOldest() 103 if !ok { 104 t.Fatalf("missing") 105 } 106 if k.(int) != 129 { 107 t.Fatalf("bad: %v", k) 108 } 109} 110 111// Test that Add returns true/false if an eviction occurred 112func TestLRU_Add(t *testing.T) { 113 evictCounter := 0 114 onEvicted := func(k interface{}, v interface{}) { 115 evictCounter++ 116 } 117 118 l, err := NewLRU(1, onEvicted) 119 if err != nil { 120 t.Fatalf("err: %v", err) 121 } 122 123 if l.Add(1, 1) == true || evictCounter != 0 { 124 t.Errorf("should not have an eviction") 125 } 126 if l.Add(2, 2) == false || evictCounter != 1 { 127 t.Errorf("should have an eviction") 128 } 129} 130 131// Test that Contains doesn't update recent-ness 132func TestLRU_Contains(t *testing.T) { 133 l, err := NewLRU(2, nil) 134 if err != nil { 135 t.Fatalf("err: %v", err) 136 } 137 138 l.Add(1, 1) 139 l.Add(2, 2) 140 if !l.Contains(1) { 141 t.Errorf("1 should be contained") 142 } 143 144 l.Add(3, 3) 145 if l.Contains(1) { 146 t.Errorf("Contains should not have updated recent-ness of 1") 147 } 148} 149 150// Test that Peek doesn't update recent-ness 151func TestLRU_Peek(t *testing.T) { 152 l, err := NewLRU(2, nil) 153 if err != nil { 154 t.Fatalf("err: %v", err) 155 } 156 157 l.Add(1, 1) 158 l.Add(2, 2) 159 if v, ok := l.Peek(1); !ok || v != 1 { 160 t.Errorf("1 should be set to 1: %v, %v", v, ok) 161 } 162 163 l.Add(3, 3) 164 if l.Contains(1) { 165 t.Errorf("should not have updated recent-ness of 1") 166 } 167} 168