github.com/lingyao2333/mo-zero@v1.4.1/core/collection/cache_test.go (about) 1 package collection 2 3 import ( 4 "errors" 5 "strconv" 6 "sync" 7 "sync/atomic" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 ) 13 14 var errDummy = errors.New("dummy") 15 16 func TestCacheSet(t *testing.T) { 17 cache, err := NewCache(time.Second*2, WithName("any")) 18 assert.Nil(t, err) 19 20 cache.Set("first", "first element") 21 cache.SetWithExpire("second", "second element", time.Second*3) 22 23 value, ok := cache.Get("first") 24 assert.True(t, ok) 25 assert.Equal(t, "first element", value) 26 value, ok = cache.Get("second") 27 assert.True(t, ok) 28 assert.Equal(t, "second element", value) 29 } 30 31 func TestCacheDel(t *testing.T) { 32 cache, err := NewCache(time.Second * 2) 33 assert.Nil(t, err) 34 35 cache.Set("first", "first element") 36 cache.Set("second", "second element") 37 cache.Del("first") 38 39 _, ok := cache.Get("first") 40 assert.False(t, ok) 41 value, ok := cache.Get("second") 42 assert.True(t, ok) 43 assert.Equal(t, "second element", value) 44 } 45 46 func TestCacheTake(t *testing.T) { 47 cache, err := NewCache(time.Second * 2) 48 assert.Nil(t, err) 49 50 var count int32 51 var wg sync.WaitGroup 52 for i := 0; i < 100; i++ { 53 wg.Add(1) 54 go func() { 55 cache.Take("first", func() (interface{}, error) { 56 atomic.AddInt32(&count, 1) 57 time.Sleep(time.Millisecond * 100) 58 return "first element", nil 59 }) 60 wg.Done() 61 }() 62 } 63 wg.Wait() 64 65 assert.Equal(t, 1, cache.size()) 66 assert.Equal(t, int32(1), atomic.LoadInt32(&count)) 67 } 68 69 func TestCacheTakeExists(t *testing.T) { 70 cache, err := NewCache(time.Second * 2) 71 assert.Nil(t, err) 72 73 var count int32 74 var wg sync.WaitGroup 75 for i := 0; i < 100; i++ { 76 wg.Add(1) 77 go func() { 78 cache.Set("first", "first element") 79 cache.Take("first", func() (interface{}, error) { 80 atomic.AddInt32(&count, 1) 81 time.Sleep(time.Millisecond * 100) 82 return "first element", nil 83 }) 84 wg.Done() 85 }() 86 } 87 wg.Wait() 88 89 assert.Equal(t, 1, cache.size()) 90 assert.Equal(t, int32(0), atomic.LoadInt32(&count)) 91 } 92 93 func TestCacheTakeError(t *testing.T) { 94 cache, err := NewCache(time.Second * 2) 95 assert.Nil(t, err) 96 97 var count int32 98 var wg sync.WaitGroup 99 for i := 0; i < 100; i++ { 100 wg.Add(1) 101 go func() { 102 _, err := cache.Take("first", func() (interface{}, error) { 103 atomic.AddInt32(&count, 1) 104 time.Sleep(time.Millisecond * 100) 105 return "", errDummy 106 }) 107 assert.Equal(t, errDummy, err) 108 wg.Done() 109 }() 110 } 111 wg.Wait() 112 113 assert.Equal(t, 0, cache.size()) 114 assert.Equal(t, int32(1), atomic.LoadInt32(&count)) 115 } 116 117 func TestCacheWithLruEvicts(t *testing.T) { 118 cache, err := NewCache(time.Minute, WithLimit(3)) 119 assert.Nil(t, err) 120 121 cache.Set("first", "first element") 122 cache.Set("second", "second element") 123 cache.Set("third", "third element") 124 cache.Set("fourth", "fourth element") 125 126 _, ok := cache.Get("first") 127 assert.False(t, ok) 128 value, ok := cache.Get("second") 129 assert.True(t, ok) 130 assert.Equal(t, "second element", value) 131 value, ok = cache.Get("third") 132 assert.True(t, ok) 133 assert.Equal(t, "third element", value) 134 value, ok = cache.Get("fourth") 135 assert.True(t, ok) 136 assert.Equal(t, "fourth element", value) 137 } 138 139 func TestCacheWithLruEvicted(t *testing.T) { 140 cache, err := NewCache(time.Minute, WithLimit(3)) 141 assert.Nil(t, err) 142 143 cache.Set("first", "first element") 144 cache.Set("second", "second element") 145 cache.Set("third", "third element") 146 cache.Set("fourth", "fourth element") 147 148 _, ok := cache.Get("first") 149 assert.False(t, ok) 150 value, ok := cache.Get("second") 151 assert.True(t, ok) 152 assert.Equal(t, "second element", value) 153 cache.Set("fifth", "fifth element") 154 cache.Set("sixth", "sixth element") 155 _, ok = cache.Get("third") 156 assert.False(t, ok) 157 _, ok = cache.Get("fourth") 158 assert.False(t, ok) 159 value, ok = cache.Get("second") 160 assert.True(t, ok) 161 assert.Equal(t, "second element", value) 162 } 163 164 func BenchmarkCache(b *testing.B) { 165 cache, err := NewCache(time.Second*5, WithLimit(100000)) 166 if err != nil { 167 b.Fatal(err) 168 } 169 170 for i := 0; i < 10000; i++ { 171 for j := 0; j < 10; j++ { 172 index := strconv.Itoa(i*10000 + j) 173 cache.Set("key:"+index, "value:"+index) 174 } 175 } 176 177 time.Sleep(time.Second * 5) 178 179 b.RunParallel(func(pb *testing.PB) { 180 for pb.Next() { 181 for i := 0; i < b.N; i++ { 182 index := strconv.Itoa(i % 10000) 183 cache.Get("key:" + index) 184 if i%100 == 0 { 185 cache.Set("key1:"+index, "value1:"+index) 186 } 187 } 188 } 189 }) 190 }