github.com/npaton/distribution@v2.3.1-rc.0+incompatible/digest/set_test.go (about) 1 package digest 2 3 import ( 4 "crypto/sha256" 5 "encoding/binary" 6 "math/rand" 7 "testing" 8 ) 9 10 func assertEqualDigests(t *testing.T, d1, d2 Digest) { 11 if d1 != d2 { 12 t.Fatalf("Digests do not match:\n\tActual: %s\n\tExpected: %s", d1, d2) 13 } 14 } 15 16 func TestLookup(t *testing.T) { 17 digests := []Digest{ 18 "sha256:1234511111111111111111111111111111111111111111111111111111111111", 19 "sha256:1234111111111111111111111111111111111111111111111111111111111111", 20 "sha256:1234611111111111111111111111111111111111111111111111111111111111", 21 "sha256:5432111111111111111111111111111111111111111111111111111111111111", 22 "sha256:6543111111111111111111111111111111111111111111111111111111111111", 23 "sha256:6432111111111111111111111111111111111111111111111111111111111111", 24 "sha256:6542111111111111111111111111111111111111111111111111111111111111", 25 "sha256:6532111111111111111111111111111111111111111111111111111111111111", 26 } 27 28 dset := NewSet() 29 for i := range digests { 30 if err := dset.Add(digests[i]); err != nil { 31 t.Fatal(err) 32 } 33 } 34 35 dgst, err := dset.Lookup("54") 36 if err != nil { 37 t.Fatal(err) 38 } 39 assertEqualDigests(t, dgst, digests[3]) 40 41 dgst, err = dset.Lookup("1234") 42 if err == nil { 43 t.Fatal("Expected ambiguous error looking up: 1234") 44 } 45 if err != ErrDigestAmbiguous { 46 t.Fatal(err) 47 } 48 49 dgst, err = dset.Lookup("9876") 50 if err == nil { 51 t.Fatal("Expected ambiguous error looking up: 9876") 52 } 53 if err != ErrDigestNotFound { 54 t.Fatal(err) 55 } 56 57 dgst, err = dset.Lookup("sha256:1234") 58 if err == nil { 59 t.Fatal("Expected ambiguous error looking up: sha256:1234") 60 } 61 if err != ErrDigestAmbiguous { 62 t.Fatal(err) 63 } 64 65 dgst, err = dset.Lookup("sha256:12345") 66 if err != nil { 67 t.Fatal(err) 68 } 69 assertEqualDigests(t, dgst, digests[0]) 70 71 dgst, err = dset.Lookup("sha256:12346") 72 if err != nil { 73 t.Fatal(err) 74 } 75 assertEqualDigests(t, dgst, digests[2]) 76 77 dgst, err = dset.Lookup("12346") 78 if err != nil { 79 t.Fatal(err) 80 } 81 assertEqualDigests(t, dgst, digests[2]) 82 83 dgst, err = dset.Lookup("12345") 84 if err != nil { 85 t.Fatal(err) 86 } 87 assertEqualDigests(t, dgst, digests[0]) 88 } 89 90 func TestAddDuplication(t *testing.T) { 91 digests := []Digest{ 92 "sha256:1234111111111111111111111111111111111111111111111111111111111111", 93 "sha256:1234511111111111111111111111111111111111111111111111111111111111", 94 "sha256:1234611111111111111111111111111111111111111111111111111111111111", 95 "sha256:5432111111111111111111111111111111111111111111111111111111111111", 96 "sha256:6543111111111111111111111111111111111111111111111111111111111111", 97 "sha512:65431111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", 98 "sha512:65421111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", 99 "sha512:65321111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", 100 } 101 102 dset := NewSet() 103 for i := range digests { 104 if err := dset.Add(digests[i]); err != nil { 105 t.Fatal(err) 106 } 107 } 108 109 if len(dset.entries) != 8 { 110 t.Fatal("Invalid dset size") 111 } 112 113 if err := dset.Add(Digest("sha256:1234511111111111111111111111111111111111111111111111111111111111")); err != nil { 114 t.Fatal(err) 115 } 116 117 if len(dset.entries) != 8 { 118 t.Fatal("Duplicate digest insert allowed") 119 } 120 121 if err := dset.Add(Digest("sha384:123451111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")); err != nil { 122 t.Fatal(err) 123 } 124 125 if len(dset.entries) != 9 { 126 t.Fatal("Insert with different algorithm not allowed") 127 } 128 } 129 130 func TestRemove(t *testing.T) { 131 digests, err := createDigests(10) 132 if err != nil { 133 t.Fatal(err) 134 } 135 136 dset := NewSet() 137 for i := range digests { 138 if err := dset.Add(digests[i]); err != nil { 139 t.Fatal(err) 140 } 141 } 142 143 dgst, err := dset.Lookup(digests[0].String()) 144 if err != nil { 145 t.Fatal(err) 146 } 147 if dgst != digests[0] { 148 t.Fatalf("Unexpected digest value:\n\tExpected: %s\n\tActual: %s", digests[0], dgst) 149 } 150 151 if err := dset.Remove(digests[0]); err != nil { 152 t.Fatal(err) 153 } 154 155 if _, err := dset.Lookup(digests[0].String()); err != ErrDigestNotFound { 156 t.Fatalf("Expected error %v when looking up removed digest, got %v", ErrDigestNotFound, err) 157 } 158 } 159 160 func TestAll(t *testing.T) { 161 digests, err := createDigests(100) 162 if err != nil { 163 t.Fatal(err) 164 } 165 166 dset := NewSet() 167 for i := range digests { 168 if err := dset.Add(digests[i]); err != nil { 169 t.Fatal(err) 170 } 171 } 172 173 all := map[Digest]struct{}{} 174 for _, dgst := range dset.All() { 175 all[dgst] = struct{}{} 176 } 177 178 if len(all) != len(digests) { 179 t.Fatalf("Unexpected number of unique digests found:\n\tExpected: %d\n\tActual: %d", len(digests), len(all)) 180 } 181 182 for i, dgst := range digests { 183 if _, ok := all[dgst]; !ok { 184 t.Fatalf("Missing element at position %d: %s", i, dgst) 185 } 186 } 187 188 } 189 190 func assertEqualShort(t *testing.T, actual, expected string) { 191 if actual != expected { 192 t.Fatalf("Unexpected short value:\n\tExpected: %s\n\tActual: %s", expected, actual) 193 } 194 } 195 196 func TestShortCodeTable(t *testing.T) { 197 digests := []Digest{ 198 "sha256:1234111111111111111111111111111111111111111111111111111111111111", 199 "sha256:1234511111111111111111111111111111111111111111111111111111111111", 200 "sha256:1234611111111111111111111111111111111111111111111111111111111111", 201 "sha256:5432111111111111111111111111111111111111111111111111111111111111", 202 "sha256:6543111111111111111111111111111111111111111111111111111111111111", 203 "sha256:6432111111111111111111111111111111111111111111111111111111111111", 204 "sha256:6542111111111111111111111111111111111111111111111111111111111111", 205 "sha256:6532111111111111111111111111111111111111111111111111111111111111", 206 } 207 208 dset := NewSet() 209 for i := range digests { 210 if err := dset.Add(digests[i]); err != nil { 211 t.Fatal(err) 212 } 213 } 214 215 dump := ShortCodeTable(dset, 2) 216 217 if len(dump) < len(digests) { 218 t.Fatalf("Error unexpected size: %d, expecting %d", len(dump), len(digests)) 219 } 220 assertEqualShort(t, dump[digests[0]], "12341") 221 assertEqualShort(t, dump[digests[1]], "12345") 222 assertEqualShort(t, dump[digests[2]], "12346") 223 assertEqualShort(t, dump[digests[3]], "54") 224 assertEqualShort(t, dump[digests[4]], "6543") 225 assertEqualShort(t, dump[digests[5]], "64") 226 assertEqualShort(t, dump[digests[6]], "6542") 227 assertEqualShort(t, dump[digests[7]], "653") 228 } 229 230 func createDigests(count int) ([]Digest, error) { 231 r := rand.New(rand.NewSource(25823)) 232 digests := make([]Digest, count) 233 for i := range digests { 234 h := sha256.New() 235 if err := binary.Write(h, binary.BigEndian, r.Int63()); err != nil { 236 return nil, err 237 } 238 digests[i] = NewDigest("sha256", h) 239 } 240 return digests, nil 241 } 242 243 func benchAddNTable(b *testing.B, n int) { 244 digests, err := createDigests(n) 245 if err != nil { 246 b.Fatal(err) 247 } 248 b.ResetTimer() 249 for i := 0; i < b.N; i++ { 250 dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))} 251 for j := range digests { 252 if err = dset.Add(digests[j]); err != nil { 253 b.Fatal(err) 254 } 255 } 256 } 257 } 258 259 func benchLookupNTable(b *testing.B, n int, shortLen int) { 260 digests, err := createDigests(n) 261 if err != nil { 262 b.Fatal(err) 263 } 264 dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))} 265 for i := range digests { 266 if err := dset.Add(digests[i]); err != nil { 267 b.Fatal(err) 268 } 269 } 270 shorts := make([]string, 0, n) 271 for _, short := range ShortCodeTable(dset, shortLen) { 272 shorts = append(shorts, short) 273 } 274 275 b.ResetTimer() 276 for i := 0; i < b.N; i++ { 277 if _, err = dset.Lookup(shorts[i%n]); err != nil { 278 b.Fatal(err) 279 } 280 } 281 } 282 283 func benchRemoveNTable(b *testing.B, n int) { 284 digests, err := createDigests(n) 285 if err != nil { 286 b.Fatal(err) 287 } 288 b.ResetTimer() 289 for i := 0; i < b.N; i++ { 290 dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))} 291 b.StopTimer() 292 for j := range digests { 293 if err = dset.Add(digests[j]); err != nil { 294 b.Fatal(err) 295 } 296 } 297 b.StartTimer() 298 for j := range digests { 299 if err = dset.Remove(digests[j]); err != nil { 300 b.Fatal(err) 301 } 302 } 303 } 304 } 305 306 func benchShortCodeNTable(b *testing.B, n int, shortLen int) { 307 digests, err := createDigests(n) 308 if err != nil { 309 b.Fatal(err) 310 } 311 dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))} 312 for i := range digests { 313 if err := dset.Add(digests[i]); err != nil { 314 b.Fatal(err) 315 } 316 } 317 318 b.ResetTimer() 319 for i := 0; i < b.N; i++ { 320 ShortCodeTable(dset, shortLen) 321 } 322 } 323 324 func BenchmarkAdd10(b *testing.B) { 325 benchAddNTable(b, 10) 326 } 327 328 func BenchmarkAdd100(b *testing.B) { 329 benchAddNTable(b, 100) 330 } 331 332 func BenchmarkAdd1000(b *testing.B) { 333 benchAddNTable(b, 1000) 334 } 335 336 func BenchmarkRemove10(b *testing.B) { 337 benchRemoveNTable(b, 10) 338 } 339 340 func BenchmarkRemove100(b *testing.B) { 341 benchRemoveNTable(b, 100) 342 } 343 344 func BenchmarkRemove1000(b *testing.B) { 345 benchRemoveNTable(b, 1000) 346 } 347 348 func BenchmarkLookup10(b *testing.B) { 349 benchLookupNTable(b, 10, 12) 350 } 351 352 func BenchmarkLookup100(b *testing.B) { 353 benchLookupNTable(b, 100, 12) 354 } 355 356 func BenchmarkLookup1000(b *testing.B) { 357 benchLookupNTable(b, 1000, 12) 358 } 359 360 func BenchmarkShortCode10(b *testing.B) { 361 benchShortCodeNTable(b, 10, 12) 362 } 363 func BenchmarkShortCode100(b *testing.B) { 364 benchShortCodeNTable(b, 100, 12) 365 } 366 func BenchmarkShortCode1000(b *testing.B) { 367 benchShortCodeNTable(b, 1000, 12) 368 }