github.com/michael-k/docker@v1.7.0-rc2/pkg/truncindex/truncindex_test.go (about) 1 package truncindex 2 3 import ( 4 "math/rand" 5 "testing" 6 7 "github.com/docker/docker/pkg/stringid" 8 ) 9 10 // Test the behavior of TruncIndex, an index for querying IDs from a non-conflicting prefix. 11 func TestTruncIndex(t *testing.T) { 12 ids := []string{} 13 index := NewTruncIndex(ids) 14 // Get on an empty index 15 if _, err := index.Get("foobar"); err == nil { 16 t.Fatal("Get on an empty index should return an error") 17 } 18 19 // Spaces should be illegal in an id 20 if err := index.Add("I have a space"); err == nil { 21 t.Fatalf("Adding an id with ' ' should return an error") 22 } 23 24 id := "99b36c2c326ccc11e726eee6ee78a0baf166ef96" 25 // Add an id 26 if err := index.Add(id); err != nil { 27 t.Fatal(err) 28 } 29 30 // Add an empty id (should fail) 31 if err := index.Add(""); err == nil { 32 t.Fatalf("Adding an empty id should return an error") 33 } 34 35 // Get a non-existing id 36 assertIndexGet(t, index, "abracadabra", "", true) 37 // Get an empty id 38 assertIndexGet(t, index, "", "", true) 39 // Get the exact id 40 assertIndexGet(t, index, id, id, false) 41 // The first letter should match 42 assertIndexGet(t, index, id[:1], id, false) 43 // The first half should match 44 assertIndexGet(t, index, id[:len(id)/2], id, false) 45 // The second half should NOT match 46 assertIndexGet(t, index, id[len(id)/2:], "", true) 47 48 id2 := id[:6] + "blabla" 49 // Add an id 50 if err := index.Add(id2); err != nil { 51 t.Fatal(err) 52 } 53 // Both exact IDs should work 54 assertIndexGet(t, index, id, id, false) 55 assertIndexGet(t, index, id2, id2, false) 56 57 // 6 characters or less should conflict 58 assertIndexGet(t, index, id[:6], "", true) 59 assertIndexGet(t, index, id[:4], "", true) 60 assertIndexGet(t, index, id[:1], "", true) 61 62 // An ambiguous id prefix should return an error 63 if _, err := index.Get(id[:4]); err == nil { 64 t.Fatal("An ambiguous id prefix should return an error") 65 } 66 67 // 7 characters should NOT conflict 68 assertIndexGet(t, index, id[:7], id, false) 69 assertIndexGet(t, index, id2[:7], id2, false) 70 71 // Deleting a non-existing id should return an error 72 if err := index.Delete("non-existing"); err == nil { 73 t.Fatalf("Deleting a non-existing id should return an error") 74 } 75 76 // Deleting an empty id should return an error 77 if err := index.Delete(""); err == nil { 78 t.Fatal("Deleting an empty id should return an error") 79 } 80 81 // Deleting id2 should remove conflicts 82 if err := index.Delete(id2); err != nil { 83 t.Fatal(err) 84 } 85 // id2 should no longer work 86 assertIndexGet(t, index, id2, "", true) 87 assertIndexGet(t, index, id2[:7], "", true) 88 assertIndexGet(t, index, id2[:11], "", true) 89 90 // conflicts between id and id2 should be gone 91 assertIndexGet(t, index, id[:6], id, false) 92 assertIndexGet(t, index, id[:4], id, false) 93 assertIndexGet(t, index, id[:1], id, false) 94 95 // non-conflicting substrings should still not conflict 96 assertIndexGet(t, index, id[:7], id, false) 97 assertIndexGet(t, index, id[:15], id, false) 98 assertIndexGet(t, index, id, id, false) 99 } 100 101 func assertIndexGet(t *testing.T, index *TruncIndex, input, expectedResult string, expectError bool) { 102 if result, err := index.Get(input); err != nil && !expectError { 103 t.Fatalf("Unexpected error getting '%s': %s", input, err) 104 } else if err == nil && expectError { 105 t.Fatalf("Getting '%s' should return an error, not '%s'", input, result) 106 } else if result != expectedResult { 107 t.Fatalf("Getting '%s' returned '%s' instead of '%s'", input, result, expectedResult) 108 } 109 } 110 111 func BenchmarkTruncIndexAdd100(b *testing.B) { 112 var testSet []string 113 for i := 0; i < 100; i++ { 114 testSet = append(testSet, stringid.GenerateRandomID()) 115 } 116 b.ResetTimer() 117 for i := 0; i < b.N; i++ { 118 index := NewTruncIndex([]string{}) 119 for _, id := range testSet { 120 if err := index.Add(id); err != nil { 121 b.Fatal(err) 122 } 123 } 124 } 125 } 126 127 func BenchmarkTruncIndexAdd250(b *testing.B) { 128 var testSet []string 129 for i := 0; i < 250; i++ { 130 testSet = append(testSet, stringid.GenerateRandomID()) 131 } 132 b.ResetTimer() 133 for i := 0; i < b.N; i++ { 134 index := NewTruncIndex([]string{}) 135 for _, id := range testSet { 136 if err := index.Add(id); err != nil { 137 b.Fatal(err) 138 } 139 } 140 } 141 } 142 143 func BenchmarkTruncIndexAdd500(b *testing.B) { 144 var testSet []string 145 for i := 0; i < 500; i++ { 146 testSet = append(testSet, stringid.GenerateRandomID()) 147 } 148 b.ResetTimer() 149 for i := 0; i < b.N; i++ { 150 index := NewTruncIndex([]string{}) 151 for _, id := range testSet { 152 if err := index.Add(id); err != nil { 153 b.Fatal(err) 154 } 155 } 156 } 157 } 158 159 func BenchmarkTruncIndexGet100(b *testing.B) { 160 var testSet []string 161 var testKeys []string 162 for i := 0; i < 100; i++ { 163 testSet = append(testSet, stringid.GenerateRandomID()) 164 } 165 index := NewTruncIndex([]string{}) 166 for _, id := range testSet { 167 if err := index.Add(id); err != nil { 168 b.Fatal(err) 169 } 170 l := rand.Intn(12) + 12 171 testKeys = append(testKeys, id[:l]) 172 } 173 b.ResetTimer() 174 for i := 0; i < b.N; i++ { 175 for _, id := range testKeys { 176 if res, err := index.Get(id); err != nil { 177 b.Fatal(res, err) 178 } 179 } 180 } 181 } 182 183 func BenchmarkTruncIndexGet250(b *testing.B) { 184 var testSet []string 185 var testKeys []string 186 for i := 0; i < 250; i++ { 187 testSet = append(testSet, stringid.GenerateRandomID()) 188 } 189 index := NewTruncIndex([]string{}) 190 for _, id := range testSet { 191 if err := index.Add(id); err != nil { 192 b.Fatal(err) 193 } 194 l := rand.Intn(12) + 12 195 testKeys = append(testKeys, id[:l]) 196 } 197 b.ResetTimer() 198 for i := 0; i < b.N; i++ { 199 for _, id := range testKeys { 200 if res, err := index.Get(id); err != nil { 201 b.Fatal(res, err) 202 } 203 } 204 } 205 } 206 207 func BenchmarkTruncIndexGet500(b *testing.B) { 208 var testSet []string 209 var testKeys []string 210 for i := 0; i < 500; i++ { 211 testSet = append(testSet, stringid.GenerateRandomID()) 212 } 213 index := NewTruncIndex([]string{}) 214 for _, id := range testSet { 215 if err := index.Add(id); err != nil { 216 b.Fatal(err) 217 } 218 l := rand.Intn(12) + 12 219 testKeys = append(testKeys, id[:l]) 220 } 221 b.ResetTimer() 222 for i := 0; i < b.N; i++ { 223 for _, id := range testKeys { 224 if res, err := index.Get(id); err != nil { 225 b.Fatal(res, err) 226 } 227 } 228 } 229 } 230 231 func BenchmarkTruncIndexDelete100(b *testing.B) { 232 var testSet []string 233 for i := 0; i < 100; i++ { 234 testSet = append(testSet, stringid.GenerateRandomID()) 235 } 236 b.ResetTimer() 237 for i := 0; i < b.N; i++ { 238 b.StopTimer() 239 index := NewTruncIndex([]string{}) 240 for _, id := range testSet { 241 if err := index.Add(id); err != nil { 242 b.Fatal(err) 243 } 244 } 245 b.StartTimer() 246 for _, id := range testSet { 247 if err := index.Delete(id); err != nil { 248 b.Fatal(err) 249 } 250 } 251 } 252 } 253 254 func BenchmarkTruncIndexDelete250(b *testing.B) { 255 var testSet []string 256 for i := 0; i < 250; i++ { 257 testSet = append(testSet, stringid.GenerateRandomID()) 258 } 259 b.ResetTimer() 260 for i := 0; i < b.N; i++ { 261 b.StopTimer() 262 index := NewTruncIndex([]string{}) 263 for _, id := range testSet { 264 if err := index.Add(id); err != nil { 265 b.Fatal(err) 266 } 267 } 268 b.StartTimer() 269 for _, id := range testSet { 270 if err := index.Delete(id); err != nil { 271 b.Fatal(err) 272 } 273 } 274 } 275 } 276 277 func BenchmarkTruncIndexDelete500(b *testing.B) { 278 var testSet []string 279 for i := 0; i < 500; i++ { 280 testSet = append(testSet, stringid.GenerateRandomID()) 281 } 282 b.ResetTimer() 283 for i := 0; i < b.N; i++ { 284 b.StopTimer() 285 index := NewTruncIndex([]string{}) 286 for _, id := range testSet { 287 if err := index.Add(id); err != nil { 288 b.Fatal(err) 289 } 290 } 291 b.StartTimer() 292 for _, id := range testSet { 293 if err := index.Delete(id); err != nil { 294 b.Fatal(err) 295 } 296 } 297 } 298 } 299 300 func BenchmarkTruncIndexNew100(b *testing.B) { 301 var testSet []string 302 for i := 0; i < 100; i++ { 303 testSet = append(testSet, stringid.GenerateRandomID()) 304 } 305 b.ResetTimer() 306 for i := 0; i < b.N; i++ { 307 NewTruncIndex(testSet) 308 } 309 } 310 311 func BenchmarkTruncIndexNew250(b *testing.B) { 312 var testSet []string 313 for i := 0; i < 250; i++ { 314 testSet = append(testSet, stringid.GenerateRandomID()) 315 } 316 b.ResetTimer() 317 for i := 0; i < b.N; i++ { 318 NewTruncIndex(testSet) 319 } 320 } 321 322 func BenchmarkTruncIndexNew500(b *testing.B) { 323 var testSet []string 324 for i := 0; i < 500; i++ { 325 testSet = append(testSet, stringid.GenerateRandomID()) 326 } 327 b.ResetTimer() 328 for i := 0; i < b.N; i++ { 329 NewTruncIndex(testSet) 330 } 331 } 332 333 func BenchmarkTruncIndexAddGet100(b *testing.B) { 334 var testSet []string 335 var testKeys []string 336 for i := 0; i < 500; i++ { 337 id := stringid.GenerateRandomID() 338 testSet = append(testSet, id) 339 l := rand.Intn(12) + 12 340 testKeys = append(testKeys, id[:l]) 341 } 342 b.ResetTimer() 343 for i := 0; i < b.N; i++ { 344 index := NewTruncIndex([]string{}) 345 for _, id := range testSet { 346 if err := index.Add(id); err != nil { 347 b.Fatal(err) 348 } 349 } 350 for _, id := range testKeys { 351 if res, err := index.Get(id); err != nil { 352 b.Fatal(res, err) 353 } 354 } 355 } 356 } 357 358 func BenchmarkTruncIndexAddGet250(b *testing.B) { 359 var testSet []string 360 var testKeys []string 361 for i := 0; i < 500; i++ { 362 id := stringid.GenerateRandomID() 363 testSet = append(testSet, id) 364 l := rand.Intn(12) + 12 365 testKeys = append(testKeys, id[:l]) 366 } 367 b.ResetTimer() 368 for i := 0; i < b.N; i++ { 369 index := NewTruncIndex([]string{}) 370 for _, id := range testSet { 371 if err := index.Add(id); err != nil { 372 b.Fatal(err) 373 } 374 } 375 for _, id := range testKeys { 376 if res, err := index.Get(id); err != nil { 377 b.Fatal(res, err) 378 } 379 } 380 } 381 } 382 383 func BenchmarkTruncIndexAddGet500(b *testing.B) { 384 var testSet []string 385 var testKeys []string 386 for i := 0; i < 500; i++ { 387 id := stringid.GenerateRandomID() 388 testSet = append(testSet, id) 389 l := rand.Intn(12) + 12 390 testKeys = append(testKeys, id[:l]) 391 } 392 b.ResetTimer() 393 for i := 0; i < b.N; i++ { 394 index := NewTruncIndex([]string{}) 395 for _, id := range testSet { 396 if err := index.Add(id); err != nil { 397 b.Fatal(err) 398 } 399 } 400 for _, id := range testKeys { 401 if res, err := index.Get(id); err != nil { 402 b.Fatal(res, err) 403 } 404 } 405 } 406 }