github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/pkg/blobserver/localdisk/enumerate_test.go (about) 1 /* 2 Copyright 2011 Google 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 localdisk 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "os" 23 "sort" 24 "testing" 25 26 "camlistore.org/pkg/blob" 27 "camlistore.org/pkg/context" 28 "camlistore.org/pkg/test" 29 . "camlistore.org/pkg/test/asserts" 30 ) 31 32 func TestEnumerate(t *testing.T) { 33 ds := NewStorage(t) 34 defer cleanUp(ds) 35 36 // For test simplicity foo, bar, and baz all have ascending 37 // sha1s and lengths. 38 foo := &test.Blob{"foo"} // 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 39 bar := &test.Blob{"baar"} // b23361951dde70cb3eca44c0c674181673a129dc 40 baz := &test.Blob{"bazzz"} // e0eb17003ce1c2812ca8f19089fff44ca32b3710 41 foo.MustUpload(t, ds) 42 bar.MustUpload(t, ds) 43 baz.MustUpload(t, ds) 44 45 limit := 5000 46 ch := make(chan blob.SizedRef) 47 errCh := make(chan error) 48 go func() { 49 errCh <- ds.EnumerateBlobs(context.New(), ch, "", limit) 50 }() 51 52 var ( 53 sb blob.SizedRef 54 ok bool 55 ) 56 sb, ok = <-ch 57 Assert(t, ok, "got 1st blob") 58 ExpectInt(t, 3, int(sb.Size), "1st blob size") 59 sb, ok = <-ch 60 Assert(t, ok, "got 2nd blob") 61 ExpectInt(t, 4, int(sb.Size), "2nd blob size") 62 sb, ok = <-ch 63 Assert(t, ok, "got 3rd blob") 64 ExpectInt(t, 5, int(sb.Size), "3rd blob size") 65 sb, ok = <-ch 66 Assert(t, !ok, "got channel close") 67 ExpectNil(t, <-errCh, "EnumerateBlobs return value") 68 69 // Now again, but skipping foo's blob 70 ch = make(chan blob.SizedRef) 71 go func() { 72 errCh <- ds.EnumerateBlobs(context.New(), 73 ch, 74 foo.BlobRef().String(), 75 limit) 76 }() 77 sb, ok = <-ch 78 Assert(t, ok, "got 1st blob, skipping foo") 79 ExpectInt(t, 4, int(sb.Size), "blob size") 80 sb, ok = <-ch 81 Assert(t, ok, "got 2nd blob, skipping foo") 82 ExpectInt(t, 5, int(sb.Size), "blob size") 83 sb, ok = <-ch 84 Assert(t, !ok, "got final nil") 85 ExpectNil(t, <-errCh, "EnumerateBlobs return value") 86 } 87 88 func TestEnumerateEmpty(t *testing.T) { 89 ds := NewStorage(t) 90 defer cleanUp(ds) 91 92 limit := 5000 93 ch := make(chan blob.SizedRef) 94 errCh := make(chan error) 95 go func() { 96 errCh <- ds.EnumerateBlobs(context.New(), ch, "", limit) 97 }() 98 99 _, ok := <-ch 100 Expect(t, !ok, "no first blob") 101 ExpectNil(t, <-errCh, "EnumerateBlobs return value") 102 } 103 104 type SortedSizedBlobs []blob.SizedRef 105 106 func (sb SortedSizedBlobs) Len() int { 107 return len(sb) 108 } 109 110 func (sb SortedSizedBlobs) Less(i, j int) bool { 111 return sb[i].Ref.String() < sb[j].Ref.String() 112 } 113 114 func (sb SortedSizedBlobs) Swap(i, j int) { 115 panic("not needed") 116 } 117 118 func TestEnumerateIsSorted(t *testing.T) { 119 ds := NewStorage(t) 120 defer cleanUp(ds) 121 122 const blobsToMake = 250 123 t.Logf("Uploading test blobs...") 124 for i := 0; i < blobsToMake; i++ { 125 blob := &test.Blob{fmt.Sprintf("blob-%d", i)} 126 blob.MustUpload(t, ds) 127 } 128 129 // Make some fake blobs in other partitions to confuse the 130 // enumerate code. 131 // TODO(bradfitz): remove this eventually. 132 fakeDir := ds.root + "/partition/queue-indexer/sha1/1f0/710" 133 ExpectNil(t, os.MkdirAll(fakeDir, 0755), "creating fakeDir") 134 ExpectNil(t, ioutil.WriteFile(fakeDir+"/sha1-1f07105465650aa243cfc1b1bbb1c68ea95c6812.dat", 135 []byte("fake file"), 0644), "writing fake blob") 136 137 // And the same for a "cache" directory, used by the default configuration. 138 fakeDir = ds.root + "/cache/sha1/1f0/710" 139 ExpectNil(t, os.MkdirAll(fakeDir, 0755), "creating cache fakeDir") 140 ExpectNil(t, ioutil.WriteFile(fakeDir+"/sha1-1f07105465650aa243cfc1b1bbb1c68ea95c6812.dat", 141 []byte("fake file"), 0644), "writing fake blob") 142 143 var tests = []struct { 144 limit int 145 after string 146 }{ 147 {200, ""}, 148 {blobsToMake, ""}, 149 {200, "sha1-2"}, 150 {200, "sha1-3"}, 151 {200, "sha1-4"}, 152 {200, "sha1-5"}, 153 {200, "sha1-e"}, 154 {200, "sha1-f"}, 155 {200, "sha1-ff"}, 156 } 157 for _, test := range tests { 158 limit := test.limit 159 ch := make(chan blob.SizedRef) 160 errCh := make(chan error) 161 go func() { 162 errCh <- ds.EnumerateBlobs(context.New(), ch, test.after, limit) 163 }() 164 got := make([]blob.SizedRef, 0, blobsToMake) 165 for sb := range ch { 166 got = append(got, sb) 167 } 168 if err := <-errCh; err != nil { 169 t.Errorf("case %+v; enumerate error: %v", test, err) 170 continue 171 } 172 if !sort.IsSorted(SortedSizedBlobs(got)) { 173 t.Errorf("case %+v: expected sorted; got: %q", test, got) 174 } 175 } 176 }