storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/metacache-entries_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  	"reflect"
    22  	"sort"
    23  	"testing"
    24  )
    25  
    26  func Test_metaCacheEntries_sort(t *testing.T) {
    27  	entries := loadMetacacheSampleEntries(t)
    28  
    29  	o := entries.entries()
    30  	if !o.isSorted() {
    31  		t.Fatal("Expected sorted objects")
    32  	}
    33  
    34  	// Swap first and last
    35  	o[0], o[len(o)-1] = o[len(o)-1], o[0]
    36  	if o.isSorted() {
    37  		t.Fatal("Expected unsorted objects")
    38  	}
    39  
    40  	sorted := o.sort()
    41  	if !o.isSorted() {
    42  		t.Fatal("Expected sorted o objects")
    43  	}
    44  	if !sorted.entries().isSorted() {
    45  		t.Fatal("Expected sorted wrapped objects")
    46  	}
    47  	want := loadMetacacheSampleNames
    48  	for i, got := range o {
    49  		if got.name != want[i] {
    50  			t.Errorf("entry %d, want %q, got %q", i, want[i], got.name)
    51  		}
    52  	}
    53  }
    54  
    55  func Test_metaCacheEntries_forwardTo(t *testing.T) {
    56  	org := loadMetacacheSampleEntries(t)
    57  	entries := org
    58  	want := []string{"src/compress/zlib/reader_test.go", "src/compress/zlib/writer.go", "src/compress/zlib/writer_test.go"}
    59  	entries.forwardTo("src/compress/zlib/reader_test.go")
    60  	got := entries.entries().names()
    61  	if !reflect.DeepEqual(got, want) {
    62  		t.Errorf("got unexpected result: %#v", got)
    63  	}
    64  
    65  	// Try with prefix
    66  	entries = org
    67  	entries.forwardTo("src/compress/zlib/reader_t")
    68  	got = entries.entries().names()
    69  	if !reflect.DeepEqual(got, want) {
    70  		t.Errorf("got unexpected result: %#v", got)
    71  	}
    72  }
    73  
    74  func Test_metaCacheEntries_merge(t *testing.T) {
    75  	org := loadMetacacheSampleEntries(t)
    76  	a, b := org.shallowClone(), org.shallowClone()
    77  	be := b.entries()
    78  	for i := range be {
    79  		//  Modify b so it isn't deduplicated.
    80  		be[i].metadata = []byte("something-else")
    81  	}
    82  	// Merge b into a
    83  	a.merge(b, -1)
    84  	want := append(loadMetacacheSampleNames, loadMetacacheSampleNames...)
    85  	sort.Strings(want)
    86  	got := a.entries().names()
    87  	if len(got) != len(want) {
    88  		t.Errorf("unexpected count, want %v, got %v", len(want), len(got))
    89  	}
    90  
    91  	for i, name := range got {
    92  		if want[i] != name {
    93  			t.Errorf("unexpected name, want %q, got %q", want[i], name)
    94  		}
    95  	}
    96  }
    97  
    98  func Test_metaCacheEntries_dedupe(t *testing.T) {
    99  	org := loadMetacacheSampleEntries(t)
   100  	a, b := org.shallowClone(), org.shallowClone()
   101  
   102  	// Merge b into a
   103  	a.merge(b, -1)
   104  	if a.deduplicate(nil) {
   105  		t.Fatal("deduplicate returned duplicate entries left")
   106  	}
   107  	want := loadMetacacheSampleNames
   108  	got := a.entries().names()
   109  	if !reflect.DeepEqual(want, got) {
   110  		t.Errorf("got unexpected result: %#v", got)
   111  	}
   112  }
   113  
   114  func Test_metaCacheEntries_dedupe2(t *testing.T) {
   115  	org := loadMetacacheSampleEntries(t)
   116  	a, b := org.shallowClone(), org.shallowClone()
   117  
   118  	// Replace metadata in b
   119  	testMarker := []byte("sampleset")
   120  	for i := range b.o {
   121  		b.o[i].metadata = testMarker
   122  	}
   123  
   124  	// Merge b into a
   125  	a.merge(b, -1)
   126  	if a.deduplicate(func(existing, other *metaCacheEntry) (replace bool) {
   127  		a := bytes.Equal(existing.metadata, testMarker)
   128  		b := bytes.Equal(other.metadata, testMarker)
   129  		if a == b {
   130  			t.Fatal("got same number of testmarkers, only one should be given", a, b)
   131  		}
   132  		return b
   133  	}) {
   134  		t.Fatal("deduplicate returned duplicate entries left, we should always resolve")
   135  	}
   136  	want := loadMetacacheSampleNames
   137  	got := a.entries().names()
   138  	if !reflect.DeepEqual(want, got) {
   139  		t.Errorf("got unexpected result: %#v", got)
   140  	}
   141  }
   142  
   143  func Test_metaCacheEntries_filterObjects(t *testing.T) {
   144  	data := loadMetacacheSampleEntries(t)
   145  	data.filterObjectsOnly()
   146  	got := data.entries().names()
   147  	want := []string{"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/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/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/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/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/issue6550.gz.base64", "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/e.txt", "src/compress/testdata/gettysburg.txt", "src/compress/testdata/pi.txt", "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"}
   148  	if !reflect.DeepEqual(want, got) {
   149  		t.Errorf("got unexpected result: %#v", got)
   150  	}
   151  }
   152  
   153  func Test_metaCacheEntries_filterPrefixes(t *testing.T) {
   154  	data := loadMetacacheSampleEntries(t)
   155  	data.filterPrefixesOnly()
   156  	got := data.entries().names()
   157  	want := []string{"src/compress/bzip2/", "src/compress/bzip2/testdata/", "src/compress/flate/", "src/compress/flate/testdata/", "src/compress/gzip/", "src/compress/gzip/testdata/", "src/compress/lzw/", "src/compress/testdata/", "src/compress/zlib/"}
   158  	if !reflect.DeepEqual(want, got) {
   159  		t.Errorf("got unexpected result: %#v", got)
   160  	}
   161  }
   162  
   163  func Test_metaCacheEntries_filterRecursive(t *testing.T) {
   164  	data := loadMetacacheSampleEntries(t)
   165  	data.filterRecursiveEntries("src/compress/bzip2/", slashSeparator)
   166  	got := data.entries().names()
   167  	want := []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"}
   168  	if !reflect.DeepEqual(want, got) {
   169  		t.Errorf("got unexpected result: %#v", got)
   170  	}
   171  }
   172  
   173  func Test_metaCacheEntries_filterRecursiveRoot(t *testing.T) {
   174  	data := loadMetacacheSampleEntries(t)
   175  	data.filterRecursiveEntries("", slashSeparator)
   176  	got := data.entries().names()
   177  	want := []string{}
   178  	if !reflect.DeepEqual(want, got) {
   179  		t.Errorf("got unexpected result: %#v", got)
   180  	}
   181  }
   182  
   183  func Test_metaCacheEntries_filterRecursiveRootSep(t *testing.T) {
   184  	data := loadMetacacheSampleEntries(t)
   185  	// This will remove anything with "bzip2/" in the path since it is separator
   186  	data.filterRecursiveEntries("", "bzip2/")
   187  	got := data.entries().names()
   188  	want := []string{"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"}
   189  	if !reflect.DeepEqual(want, got) {
   190  		t.Errorf("got unexpected result: %#v", got)
   191  	}
   192  }
   193  
   194  func Test_metaCacheEntries_filterPrefix(t *testing.T) {
   195  	data := loadMetacacheSampleEntries(t)
   196  	data.filterPrefix("src/compress/bzip2/")
   197  	got := data.entries().names()
   198  	want := []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"}
   199  	if !reflect.DeepEqual(want, got) {
   200  		t.Errorf("got unexpected result: %#v", got)
   201  	}
   202  }
   203  
   204  func Test_metaCacheEntry_isInDir(t *testing.T) {
   205  	tests := []struct {
   206  		testName string
   207  		entry    string
   208  		dir      string
   209  		sep      string
   210  		want     bool
   211  	}{
   212  		{
   213  			testName: "basic-file",
   214  			entry:    "src/file",
   215  			dir:      "src/",
   216  			sep:      slashSeparator,
   217  			want:     true,
   218  		},
   219  		{
   220  			testName: "basic-dir",
   221  			entry:    "src/dir/",
   222  			dir:      "src/",
   223  			sep:      slashSeparator,
   224  			want:     true,
   225  		},
   226  		{
   227  			testName: "deeper-file",
   228  			entry:    "src/dir/somewhere.ext",
   229  			dir:      "src/",
   230  			sep:      slashSeparator,
   231  			want:     false,
   232  		},
   233  		{
   234  			testName: "deeper-dir",
   235  			entry:    "src/dir/somewhere/",
   236  			dir:      "src/",
   237  			sep:      slashSeparator,
   238  			want:     false,
   239  		},
   240  		{
   241  			testName: "root-dir",
   242  			entry:    "doc/",
   243  			dir:      "",
   244  			sep:      slashSeparator,
   245  			want:     true,
   246  		},
   247  		{
   248  			testName: "root-file",
   249  			entry:    "word.doc",
   250  			dir:      "",
   251  			sep:      slashSeparator,
   252  			want:     true,
   253  		},
   254  	}
   255  	for _, tt := range tests {
   256  		t.Run(tt.testName, func(t *testing.T) {
   257  			e := metaCacheEntry{
   258  				name: tt.entry,
   259  			}
   260  			if got := e.isInDir(tt.dir, tt.sep); got != tt.want {
   261  				t.Errorf("isInDir() = %v, want %v", got, tt.want)
   262  			}
   263  		})
   264  	}
   265  }