github.com/attic-labs/noms@v0.0.0-20210827224422-e5fa29d95e8b/go/util/sizecache/size_cache_test.go (about) 1 // Copyright 2016 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package sizecache 6 7 import ( 8 "fmt" 9 "sort" 10 "sync" 11 "testing" 12 13 "github.com/attic-labs/noms/go/hash" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func hashFromString(s string) hash.Hash { 18 return hash.Of([]byte(s)) 19 } 20 21 func TestSizeCache(t *testing.T) { 22 assert := assert.New(t) 23 defSize := uint64(200) 24 25 c := New(1024) 26 for i, v := range []string{"data-1", "data-2", "data-3", "data-4", "data-5", "data-6", "data-7", "data-8", "data-9"} { 27 c.Add(hashFromString(v), defSize, v) 28 maxElements := uint64(i + 1) 29 if maxElements >= uint64(5) { 30 maxElements = uint64(5) 31 } 32 assert.Equal(maxElements*defSize, c.totalSize) 33 } 34 35 _, ok := c.Get(hashFromString("data-1")) 36 assert.False(ok) 37 assert.Equal(hashFromString("data-5"), c.lru.Front().Value) 38 39 v, ok := c.Get(hashFromString("data-5")) 40 assert.True(ok) 41 assert.Equal("data-5", v.(string)) 42 assert.Equal(hashFromString("data-5"), c.lru.Back().Value) 43 assert.Equal(hashFromString("data-6"), c.lru.Front().Value) 44 45 c.Add(hashFromString("data-7"), defSize, "data-7") 46 assert.Equal(hashFromString("data-7"), c.lru.Back().Value) 47 assert.Equal(uint64(1000), c.totalSize) 48 49 c.Add(hashFromString("no-data"), 0, nil) 50 v, ok = c.Get(hashFromString("no-data")) 51 assert.True(ok) 52 assert.Nil(v) 53 assert.Equal(hashFromString("no-data"), c.lru.Back().Value) 54 assert.Equal(uint64(1000), c.totalSize) 55 assert.Equal(6, c.lru.Len()) 56 assert.Equal(6, len(c.cache)) 57 58 for _, v := range []string{"data-5", "data-6", "data-7", "data-8", "data-9"} { 59 c.Get(hashFromString(v)) 60 assert.Equal(hashFromString(v), c.lru.Back().Value) 61 } 62 assert.Equal(hashFromString("no-data"), c.lru.Front().Value) 63 64 c.Add(hashFromString("data-10"), 200, "data-10") 65 assert.Equal(uint64(1000), c.totalSize) 66 assert.Equal(5, c.lru.Len()) 67 assert.Equal(5, len(c.cache)) 68 69 _, ok = c.Get(hashFromString("no-data")) 70 assert.False(ok) 71 _, ok = c.Get(hashFromString("data-5")) 72 assert.False(ok) 73 74 c.Drop(hashFromString("data-10")) 75 assert.Equal(uint64(800), c.totalSize) 76 assert.Equal(4, c.lru.Len()) 77 assert.Equal(4, len(c.cache)) 78 } 79 80 func TestSizeCacheWithExpiry(t *testing.T) { 81 expired := []string{} 82 expire := func(key interface{}) { 83 expired = append(expired, key.(string)) 84 } 85 86 c := NewWithExpireCallback(5, expire) 87 data := []string{"a", "b", "c", "d", "e"} 88 for i, k := range data { 89 c.Add(k, 1, i) 90 } 91 92 c.Add("big", 5, "thing") 93 sort.Sort(sort.StringSlice(expired)) 94 assert.Equal(t, data, expired) 95 } 96 97 func concurrencySizeCacheTest(data []string) { 98 dchan := make(chan string, 128) 99 go func() { 100 for _, d := range data { 101 dchan <- d 102 } 103 close(dchan) 104 }() 105 106 cache := New(25) 107 wg := sync.WaitGroup{} 108 109 for i := 0; i < 3; i++ { 110 wg.Add(1) 111 go func() { 112 for d := range dchan { 113 cache.Add(d, uint64(len(d)), d) 114 } 115 wg.Done() 116 }() 117 } 118 wg.Wait() 119 } 120 121 // I can't guarantee this will fail if the code isn't correct, but in the 122 // previous version of SizeCache, this was able to reliably repro bug #2663. 123 func TestConcurrency(t *testing.T) { 124 assert := assert.New(t) 125 generateDataStrings := func(numStrings, numValues int) []string { 126 l := []string{} 127 for i := 0; len(l) < numStrings; i++ { 128 for j := 0; j < numValues && len(l) < numStrings; j++ { 129 l = append(l, fmt.Sprintf("data-%d", i)) 130 } 131 } 132 return l 133 } 134 135 data := generateDataStrings(50, 3) 136 for i := 0; i < 100; i++ { 137 assert.NotPanics(func() { concurrencySizeCacheTest(data) }) 138 } 139 } 140 141 func TestTooLargeValue(t *testing.T) { 142 assert := assert.New(t) 143 144 c := New(1024) 145 c.Add(hashFromString("big-data"), 2048, "big-data") 146 _, ok := c.Get(hashFromString("big-data")) 147 assert.False(ok) 148 } 149 150 func TestZeroSizeCache(t *testing.T) { 151 assert := assert.New(t) 152 153 c := New(0) 154 c.Add(hashFromString("data1"), 200, "data1") 155 _, ok := c.Get(hashFromString("data1")) 156 assert.False(ok) 157 }