github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/cache/fastcache/file_test.go (about) 1 package fastcache 2 3 import ( 4 "fmt" 5 "os" 6 "sync" 7 "testing" 8 ) 9 10 func TestSaveLoadSmall(t *testing.T) { 11 const filePath = "TestSaveLoadSmall.fastcache" 12 defer os.RemoveAll(filePath) 13 14 c := New(1) 15 defer c.Reset() 16 17 key := []byte("foobar") 18 value := []byte("abcdef") 19 c.Set(key, value) 20 if err := c.SaveToFile(filePath); err != nil { 21 t.Fatalf("SaveToFile error: %s", err) 22 } 23 24 c1, err := LoadFromFile(filePath) 25 if err != nil { 26 t.Fatalf("LoadFromFile error: %s", err) 27 } 28 vv := c1.Get(nil, key) 29 if string(vv) != string(value) { 30 t.Fatalf("unexpected value obtained from cache; got %q; want %q", vv, value) 31 } 32 33 // Verify that key can be overwritten. 34 newValue := []byte("234fdfd") 35 c1.Set(key, newValue) 36 vv = c1.Get(nil, key) 37 if string(vv) != string(newValue) { 38 t.Fatalf("unexpected new value obtained from cache; got %q; want %q", vv, newValue) 39 } 40 } 41 42 func TestSaveLoadFile(t *testing.T) { 43 for _, concurrency := range []int{0, 1, 2, 4, 10} { 44 t.Run(fmt.Sprintf("concurrency_%d", concurrency), func(t *testing.T) { 45 testSaveLoadFile(t, concurrency) 46 }) 47 } 48 } 49 50 func testSaveLoadFile(t *testing.T, concurrency int) { 51 var s Stats 52 filePath := fmt.Sprintf("TestSaveLoadFile.%d.fastcache", concurrency) 53 defer os.RemoveAll(filePath) 54 55 const itemsCount = 10000 56 const maxBytes = bucketsCount * chunkSize * 2 57 c := New(maxBytes) 58 for i := 0; i < itemsCount; i++ { 59 k := []byte(fmt.Sprintf("key %d", i)) 60 v := []byte(fmt.Sprintf("value %d", i)) 61 c.Set(k, v) 62 vv := c.Get(nil, k) 63 if string(v) != string(vv) { 64 t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0]) 65 } 66 } 67 if concurrency == 1 { 68 if err := c.SaveToFile(filePath); err != nil { 69 t.Fatalf("SaveToFile error: %s", err) 70 } 71 } else { 72 if err := c.SaveToFileConcurrent(filePath, concurrency); err != nil { 73 t.Fatalf("SaveToFileConcurrent(%d) error: %s", concurrency, err) 74 } 75 } 76 s.Reset() 77 c.UpdateStats(&s) 78 if s.EntriesCount != itemsCount { 79 t.Fatalf("unexpected entriesCount; got %d; want %d", s.EntriesCount, itemsCount) 80 } 81 c.Reset() 82 83 // Verify LoadFromFile 84 c, err := LoadFromFile(filePath) 85 if err != nil { 86 t.Fatalf("unexpected error: %s", err) 87 } 88 s.Reset() 89 c.UpdateStats(&s) 90 if s.EntriesCount != itemsCount { 91 t.Fatalf("unexpected entriesCount; got %d; want %d", s.EntriesCount, itemsCount) 92 } 93 for i := 0; i < itemsCount; i++ { 94 k := []byte(fmt.Sprintf("key %d", i)) 95 v := []byte(fmt.Sprintf("value %d", i)) 96 vv := c.Get(nil, k) 97 if string(v) != string(vv) { 98 t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0]) 99 } 100 } 101 c.Reset() 102 103 // Verify LoadFromFileOrNew 104 c = LoadFromFileOrNew(filePath, maxBytes) 105 s.Reset() 106 c.UpdateStats(&s) 107 if s.EntriesCount != itemsCount { 108 t.Fatalf("unexpected entriesCount; got %d; want %d", s.EntriesCount, itemsCount) 109 } 110 for i := 0; i < itemsCount; i++ { 111 k := []byte(fmt.Sprintf("key %d", i)) 112 v := []byte(fmt.Sprintf("value %d", i)) 113 vv := c.Get(nil, k) 114 if string(v) != string(vv) { 115 t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0]) 116 } 117 } 118 c.Reset() 119 120 // Overwrite existing keys 121 for i := 0; i < itemsCount; i++ { 122 k := []byte(fmt.Sprintf("key %d", i)) 123 v := []byte(fmt.Sprintf("value %d", i)) 124 c.Set(k, v) 125 vv := c.Get(nil, k) 126 if string(v) != string(vv) { 127 t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0]) 128 } 129 } 130 131 // Add new keys 132 for i := 0; i < itemsCount; i++ { 133 k := []byte(fmt.Sprintf("new key %d", i)) 134 v := []byte(fmt.Sprintf("new value %d", i)) 135 c.Set(k, v) 136 vv := c.Get(nil, k) 137 if string(v) != string(vv) { 138 t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0]) 139 } 140 } 141 142 // Verify all the keys exist 143 for i := 0; i < itemsCount; i++ { 144 k := []byte(fmt.Sprintf("key %d", i)) 145 v := []byte(fmt.Sprintf("value %d", i)) 146 vv := c.Get(nil, k) 147 if string(v) != string(vv) { 148 t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0]) 149 } 150 k = []byte(fmt.Sprintf("new key %d", i)) 151 v = []byte(fmt.Sprintf("new value %d", i)) 152 vv = c.Get(nil, k) 153 if string(v) != string(vv) { 154 t.Fatalf("unexpected cache value for k=%q; got %q; want %q; bucket[0]=%#v", k, vv, v, &c.buckets[0]) 155 } 156 } 157 158 // Verify incorrect maxBytes passed to LoadFromFileOrNew 159 c = LoadFromFileOrNew(filePath, maxBytes*10) 160 s.Reset() 161 c.UpdateStats(&s) 162 if s.EntriesCount != 0 { 163 t.Fatalf("unexpected non-zero entriesCount; got %d", s.EntriesCount) 164 } 165 c.Reset() 166 } 167 168 func TestSaveLoadConcurrent(t *testing.T) { 169 c := New(1024) 170 defer c.Reset() 171 c.Set([]byte("foo"), []byte("bar")) 172 173 stopCh := make(chan struct{}) 174 175 // Start concurrent workers that run Get and Set on c. 176 var wgWorkers sync.WaitGroup 177 for i := 0; i < 5; i++ { 178 wgWorkers.Add(1) 179 go func() { 180 defer wgWorkers.Done() 181 var buf []byte 182 j := 0 183 for { 184 k := []byte(fmt.Sprintf("key %d", j)) 185 v := []byte(fmt.Sprintf("value %d", j)) 186 c.Set(k, v) 187 buf = c.Get(buf[:0], k) 188 if string(buf) != string(v) { 189 panic(fmt.Errorf("unexpected value for key %q; got %q; want %q", k, buf, v)) 190 } 191 j++ 192 select { 193 case <-stopCh: 194 return 195 default: 196 } 197 } 198 }() 199 } 200 201 // Start concurrent SaveToFile and LoadFromFile calls. 202 var wgSavers sync.WaitGroup 203 for i := 0; i < 4; i++ { 204 wgSavers.Add(1) 205 filePath := fmt.Sprintf("TestSaveToFileConcurrent.%d.fastcache", i) 206 go func() { 207 defer wgSavers.Done() 208 defer os.RemoveAll(filePath) 209 for j := 0; j < 3; j++ { 210 if err := c.SaveToFileConcurrent(filePath, 3); err != nil { 211 panic(fmt.Errorf("cannot save cache to %q: %s", filePath, err)) 212 } 213 cc, err := LoadFromFile(filePath) 214 if err != nil { 215 panic(fmt.Errorf("cannot load cache from %q: %s", filePath, err)) 216 } 217 var s Stats 218 cc.UpdateStats(&s) 219 if s.EntriesCount == 0 { 220 panic(fmt.Errorf("unexpected empty cache loaded from %q", filePath)) 221 } 222 cc.Reset() 223 } 224 }() 225 } 226 227 wgSavers.Wait() 228 229 close(stopCh) 230 wgWorkers.Wait() 231 }