storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/metacache-stream_test.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2020 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package cmd 18 19 import ( 20 "bytes" 21 "context" 22 "io" 23 "io/ioutil" 24 "reflect" 25 "sync" 26 "testing" 27 ) 28 29 var loadMetacacheSampleNames = []string{"src/compress/bzip2/", "src/compress/bzip2/bit_reader.go", "src/compress/bzip2/bzip2.go", "src/compress/bzip2/bzip2_test.go", "src/compress/bzip2/huffman.go", "src/compress/bzip2/move_to_front.go", "src/compress/bzip2/testdata/", "src/compress/bzip2/testdata/Isaac.Newton-Opticks.txt.bz2", "src/compress/bzip2/testdata/e.txt.bz2", "src/compress/bzip2/testdata/fail-issue5747.bz2", "src/compress/bzip2/testdata/pass-random1.bin", "src/compress/bzip2/testdata/pass-random1.bz2", "src/compress/bzip2/testdata/pass-random2.bin", "src/compress/bzip2/testdata/pass-random2.bz2", "src/compress/bzip2/testdata/pass-sawtooth.bz2", "src/compress/bzip2/testdata/random.data.bz2", "src/compress/flate/", "src/compress/flate/deflate.go", "src/compress/flate/deflate_test.go", "src/compress/flate/deflatefast.go", "src/compress/flate/dict_decoder.go", "src/compress/flate/dict_decoder_test.go", "src/compress/flate/example_test.go", "src/compress/flate/flate_test.go", "src/compress/flate/huffman_bit_writer.go", "src/compress/flate/huffman_bit_writer_test.go", "src/compress/flate/huffman_code.go", "src/compress/flate/inflate.go", "src/compress/flate/inflate_test.go", "src/compress/flate/reader_test.go", "src/compress/flate/testdata/", "src/compress/flate/testdata/huffman-null-max.dyn.expect", "src/compress/flate/testdata/huffman-null-max.dyn.expect-noinput", "src/compress/flate/testdata/huffman-null-max.golden", "src/compress/flate/testdata/huffman-null-max.in", "src/compress/flate/testdata/huffman-null-max.wb.expect", "src/compress/flate/testdata/huffman-null-max.wb.expect-noinput", "src/compress/flate/testdata/huffman-pi.dyn.expect", "src/compress/flate/testdata/huffman-pi.dyn.expect-noinput", "src/compress/flate/testdata/huffman-pi.golden", "src/compress/flate/testdata/huffman-pi.in", "src/compress/flate/testdata/huffman-pi.wb.expect", "src/compress/flate/testdata/huffman-pi.wb.expect-noinput", "src/compress/flate/testdata/huffman-rand-1k.dyn.expect", "src/compress/flate/testdata/huffman-rand-1k.dyn.expect-noinput", "src/compress/flate/testdata/huffman-rand-1k.golden", "src/compress/flate/testdata/huffman-rand-1k.in", "src/compress/flate/testdata/huffman-rand-1k.wb.expect", "src/compress/flate/testdata/huffman-rand-1k.wb.expect-noinput", "src/compress/flate/testdata/huffman-rand-limit.dyn.expect", "src/compress/flate/testdata/huffman-rand-limit.dyn.expect-noinput", "src/compress/flate/testdata/huffman-rand-limit.golden", "src/compress/flate/testdata/huffman-rand-limit.in", "src/compress/flate/testdata/huffman-rand-limit.wb.expect", "src/compress/flate/testdata/huffman-rand-limit.wb.expect-noinput", "src/compress/flate/testdata/huffman-rand-max.golden", "src/compress/flate/testdata/huffman-rand-max.in", "src/compress/flate/testdata/huffman-shifts.dyn.expect", "src/compress/flate/testdata/huffman-shifts.dyn.expect-noinput", "src/compress/flate/testdata/huffman-shifts.golden", "src/compress/flate/testdata/huffman-shifts.in", "src/compress/flate/testdata/huffman-shifts.wb.expect", "src/compress/flate/testdata/huffman-shifts.wb.expect-noinput", "src/compress/flate/testdata/huffman-text-shift.dyn.expect", "src/compress/flate/testdata/huffman-text-shift.dyn.expect-noinput", "src/compress/flate/testdata/huffman-text-shift.golden", "src/compress/flate/testdata/huffman-text-shift.in", "src/compress/flate/testdata/huffman-text-shift.wb.expect", "src/compress/flate/testdata/huffman-text-shift.wb.expect-noinput", "src/compress/flate/testdata/huffman-text.dyn.expect", "src/compress/flate/testdata/huffman-text.dyn.expect-noinput", "src/compress/flate/testdata/huffman-text.golden", "src/compress/flate/testdata/huffman-text.in", "src/compress/flate/testdata/huffman-text.wb.expect", "src/compress/flate/testdata/huffman-text.wb.expect-noinput", "src/compress/flate/testdata/huffman-zero.dyn.expect", "src/compress/flate/testdata/huffman-zero.dyn.expect-noinput", "src/compress/flate/testdata/huffman-zero.golden", "src/compress/flate/testdata/huffman-zero.in", "src/compress/flate/testdata/huffman-zero.wb.expect", "src/compress/flate/testdata/huffman-zero.wb.expect-noinput", "src/compress/flate/testdata/null-long-match.dyn.expect-noinput", "src/compress/flate/testdata/null-long-match.wb.expect-noinput", "src/compress/flate/token.go", "src/compress/flate/writer_test.go", "src/compress/gzip/", "src/compress/gzip/example_test.go", "src/compress/gzip/gunzip.go", "src/compress/gzip/gunzip_test.go", "src/compress/gzip/gzip.go", "src/compress/gzip/gzip_test.go", "src/compress/gzip/issue14937_test.go", "src/compress/gzip/testdata/", "src/compress/gzip/testdata/issue6550.gz.base64", "src/compress/lzw/", "src/compress/lzw/reader.go", "src/compress/lzw/reader_test.go", "src/compress/lzw/writer.go", "src/compress/lzw/writer_test.go", "src/compress/testdata/", "src/compress/testdata/e.txt", "src/compress/testdata/gettysburg.txt", "src/compress/testdata/pi.txt", "src/compress/zlib/", "src/compress/zlib/example_test.go", "src/compress/zlib/reader.go", "src/compress/zlib/reader_test.go", "src/compress/zlib/writer.go", "src/compress/zlib/writer_test.go"} 30 31 func loadMetacacheSample(t testing.TB) *metacacheReader { 32 b, err := ioutil.ReadFile("testdata/metacache.s2") 33 if err != nil { 34 t.Fatal(err) 35 } 36 r, err := newMetacacheReader(bytes.NewReader(b)) 37 if err != nil { 38 t.Fatal(err) 39 } 40 return r 41 } 42 43 func loadMetacacheSampleEntries(t testing.TB) metaCacheEntriesSorted { 44 r := loadMetacacheSample(t) 45 defer r.Close() 46 entries, err := r.readN(-1, false, true, "") 47 if err != io.EOF { 48 t.Fatal(err) 49 } 50 51 return entries 52 } 53 54 func Test_metacacheReader_readNames(t *testing.T) { 55 r := loadMetacacheSample(t) 56 defer r.Close() 57 names, err := r.readNames(-1) 58 if err != io.EOF { 59 t.Fatal(err) 60 } 61 want := loadMetacacheSampleNames 62 if !reflect.DeepEqual(names, want) { 63 t.Errorf("got unexpected result: %#v", names) 64 } 65 } 66 67 func Test_metacacheReader_readN(t *testing.T) { 68 r := loadMetacacheSample(t) 69 defer r.Close() 70 entries, err := r.readN(-1, false, true, "") 71 if err != io.EOF { 72 t.Fatal(err, entries.len()) 73 } 74 want := loadMetacacheSampleNames 75 for i, entry := range entries.entries() { 76 if entry.name != want[i] { 77 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 78 } 79 } 80 if entries.len() != len(want) { 81 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 82 } 83 84 want = want[:0] 85 entries, err = r.readN(0, false, true, "") 86 if err != nil { 87 t.Fatal(err, entries.len()) 88 } 89 if entries.len() != len(want) { 90 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 91 } 92 93 // Reload. 94 r = loadMetacacheSample(t) 95 defer r.Close() 96 entries, err = r.readN(0, false, true, "") 97 if err != nil { 98 t.Fatal(err, entries.len()) 99 } 100 if entries.len() != len(want) { 101 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 102 } 103 104 entries, err = r.readN(5, false, true, "") 105 if err != nil { 106 t.Fatal(err, entries.len()) 107 } 108 want = loadMetacacheSampleNames[:5] 109 if entries.len() != len(want) { 110 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 111 } 112 113 for i, entry := range entries.entries() { 114 if entry.name != want[i] { 115 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 116 } 117 } 118 } 119 120 func Test_metacacheReader_readNDirs(t *testing.T) { 121 r := loadMetacacheSample(t) 122 defer r.Close() 123 entries, err := r.readN(-1, false, true, "") 124 if err != io.EOF { 125 t.Fatal(err, entries.len()) 126 } 127 want := loadMetacacheSampleNames 128 var noDirs []string 129 for i, entry := range entries.entries() { 130 if entry.name != want[i] { 131 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 132 } 133 if !entry.isDir() { 134 noDirs = append(noDirs, entry.name) 135 } 136 } 137 if entries.len() != len(want) { 138 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 139 } 140 141 want = noDirs 142 r = loadMetacacheSample(t) 143 defer r.Close() 144 entries, err = r.readN(-1, false, false, "") 145 if err != io.EOF { 146 t.Fatal(err, entries.len()) 147 } 148 for i, entry := range entries.entries() { 149 if entry.name != want[i] { 150 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 151 } 152 } 153 if entries.len() != len(want) { 154 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 155 } 156 157 want = want[:0] 158 entries, err = r.readN(0, false, false, "") 159 if err != nil { 160 t.Fatal(err, entries.len()) 161 } 162 if entries.len() != len(want) { 163 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 164 } 165 166 // Reload. 167 r = loadMetacacheSample(t) 168 defer r.Close() 169 entries, err = r.readN(0, false, false, "") 170 if err != nil { 171 t.Fatal(err, entries.len()) 172 } 173 if entries.len() != len(want) { 174 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 175 } 176 177 entries, err = r.readN(5, false, false, "") 178 if err != nil { 179 t.Fatal(err, entries.len()) 180 } 181 want = noDirs[:5] 182 if entries.len() != len(want) { 183 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 184 } 185 186 for i, entry := range entries.entries() { 187 if entry.name != want[i] { 188 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 189 } 190 } 191 } 192 193 func Test_metacacheReader_readNPrefix(t *testing.T) { 194 r := loadMetacacheSample(t) 195 defer r.Close() 196 entries, err := r.readN(-1, false, true, "src/compress/bzip2/") 197 if err != io.EOF { 198 t.Fatal(err, entries.len()) 199 } 200 want := loadMetacacheSampleNames[:16] 201 for i, entry := range entries.entries() { 202 if entry.name != want[i] { 203 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 204 } 205 } 206 if entries.len() != len(want) { 207 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 208 } 209 210 r = loadMetacacheSample(t) 211 defer r.Close() 212 entries, err = r.readN(-1, false, true, "src/nonexist") 213 if err != io.EOF { 214 t.Fatal(err, entries.len()) 215 } 216 want = loadMetacacheSampleNames[:0] 217 if entries.len() != len(want) { 218 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 219 } 220 for i, entry := range entries.entries() { 221 if entry.name != want[i] { 222 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 223 } 224 } 225 226 r = loadMetacacheSample(t) 227 defer r.Close() 228 entries, err = r.readN(-1, false, true, "src/a") 229 if err != io.EOF { 230 t.Fatal(err, entries.len()) 231 } 232 want = loadMetacacheSampleNames[:0] 233 if entries.len() != len(want) { 234 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 235 } 236 for i, entry := range entries.entries() { 237 if entry.name != want[i] { 238 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 239 } 240 } 241 242 r = loadMetacacheSample(t) 243 defer r.Close() 244 entries, err = r.readN(-1, false, true, "src/compress/zlib/e") 245 if err != io.EOF { 246 t.Fatal(err, entries.len()) 247 } 248 want = []string{"src/compress/zlib/example_test.go"} 249 if entries.len() != len(want) { 250 t.Fatal("unexpected length:", entries.len(), "want:", len(want)) 251 } 252 for i, entry := range entries.entries() { 253 if entry.name != want[i] { 254 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 255 } 256 } 257 } 258 259 func Test_metacacheReader_readFn(t *testing.T) { 260 r := loadMetacacheSample(t) 261 defer r.Close() 262 i := 0 263 err := r.readFn(func(entry metaCacheEntry) bool { 264 want := loadMetacacheSampleNames[i] 265 if entry.name != want { 266 t.Errorf("entry %d, want %q, got %q", i, want, entry.name) 267 } 268 i++ 269 return true 270 }) 271 if err != io.EOF { 272 t.Fatal(err) 273 } 274 } 275 276 func Test_metacacheReader_readAll(t *testing.T) { 277 r := loadMetacacheSample(t) 278 defer r.Close() 279 var readErr error 280 objs := make(chan metaCacheEntry, 1) 281 var wg sync.WaitGroup 282 wg.Add(1) 283 go func() { 284 readErr = r.readAll(context.Background(), objs) 285 wg.Done() 286 }() 287 want := loadMetacacheSampleNames 288 i := 0 289 for entry := range objs { 290 if entry.name != want[i] { 291 t.Errorf("entry %d, want %q, got %q", i, want[i], entry.name) 292 } 293 i++ 294 } 295 wg.Wait() 296 if readErr != nil { 297 t.Fatal(readErr) 298 } 299 } 300 301 func Test_metacacheReader_forwardTo(t *testing.T) { 302 r := loadMetacacheSample(t) 303 defer r.Close() 304 err := r.forwardTo("src/compress/zlib/reader_test.go") 305 if err != nil { 306 t.Fatal(err) 307 } 308 names, err := r.readNames(-1) 309 if err != io.EOF { 310 t.Fatal(err) 311 } 312 want := []string{"src/compress/zlib/reader_test.go", "src/compress/zlib/writer.go", "src/compress/zlib/writer_test.go"} 313 if !reflect.DeepEqual(names, want) { 314 t.Errorf("got unexpected result: %#v", names) 315 } 316 317 // Try with prefix 318 r = loadMetacacheSample(t) 319 err = r.forwardTo("src/compress/zlib/reader_t") 320 if err != nil { 321 t.Fatal(err) 322 } 323 names, err = r.readNames(-1) 324 if err != io.EOF { 325 t.Fatal(err) 326 } 327 if !reflect.DeepEqual(names, want) { 328 t.Errorf("got unexpected result: %#v", names) 329 } 330 } 331 332 func Test_metacacheReader_next(t *testing.T) { 333 r := loadMetacacheSample(t) 334 defer r.Close() 335 for i, want := range loadMetacacheSampleNames { 336 gotObj, err := r.next() 337 if err != nil { 338 t.Fatal(err) 339 } 340 if gotObj.name != want { 341 t.Errorf("entry %d, want %q, got %q", i, want, gotObj.name) 342 } 343 } 344 } 345 func Test_metacacheReader_peek(t *testing.T) { 346 r := loadMetacacheSample(t) 347 defer r.Close() 348 for i, want := range loadMetacacheSampleNames { 349 got, err := r.peek() 350 if err == io.EOF { 351 break 352 } 353 if err != nil { 354 t.Fatal(err) 355 } 356 if got.name != want { 357 t.Errorf("entry %d, want %q, got %q", i, want, got.name) 358 } 359 gotObj, err := r.next() 360 if err != nil { 361 t.Fatal(err) 362 } 363 if gotObj.name != want { 364 t.Errorf("entry %d, want %q, got %q", i, want, gotObj.name) 365 } 366 } 367 } 368 369 func Test_newMetacacheStream(t *testing.T) { 370 r := loadMetacacheSample(t) 371 var buf bytes.Buffer 372 w := newMetacacheWriter(&buf, 1<<20) 373 defer w.Close() 374 err := r.readFn(func(object metaCacheEntry) bool { 375 err := w.write(object) 376 if err != nil { 377 t.Fatal(err) 378 } 379 return true 380 }) 381 r.Close() 382 if err != io.EOF { 383 t.Fatal(err) 384 } 385 err = w.Close() 386 if err != nil { 387 t.Fatal(err) 388 } 389 390 r, err = newMetacacheReader(&buf) 391 if err != nil { 392 t.Fatal(err) 393 } 394 defer r.Close() 395 names, err := r.readNames(-1) 396 if err != io.EOF { 397 t.Fatal(err) 398 } 399 want := loadMetacacheSampleNames 400 if !reflect.DeepEqual(names, want) { 401 t.Errorf("got unexpected result: %#v", names) 402 } 403 } 404 405 func Test_metacacheReader_skip(t *testing.T) { 406 r := loadMetacacheSample(t) 407 defer r.Close() 408 names, err := r.readNames(5) 409 if err != nil { 410 t.Fatal(err) 411 } 412 want := loadMetacacheSampleNames[:5] 413 if !reflect.DeepEqual(names, want) { 414 t.Errorf("got unexpected result: %#v", names) 415 } 416 err = r.skip(5) 417 if err != nil { 418 t.Fatal(err) 419 } 420 names, err = r.readNames(5) 421 if err != nil { 422 t.Fatal(err) 423 } 424 want = loadMetacacheSampleNames[10:15] 425 if !reflect.DeepEqual(names, want) { 426 t.Errorf("got unexpected result: %#v", names) 427 } 428 429 err = r.skip(len(loadMetacacheSampleNames)) 430 if err != io.EOF { 431 t.Fatal(err) 432 } 433 }