github.com/rish1988/moby@v25.0.2+incompatible/registry/registry_test.go (about) 1 package registry // import "github.com/docker/docker/registry" 2 3 import ( 4 "testing" 5 6 "github.com/distribution/reference" 7 "github.com/docker/docker/api/types/registry" 8 "gotest.tools/v3/assert" 9 is "gotest.tools/v3/assert/cmp" 10 ) 11 12 func TestParseRepositoryInfo(t *testing.T) { 13 type staticRepositoryInfo struct { 14 Index *registry.IndexInfo 15 RemoteName string 16 CanonicalName string 17 LocalName string 18 Official bool 19 } 20 21 expectedRepoInfos := map[string]staticRepositoryInfo{ 22 "fooo/bar": { 23 Index: ®istry.IndexInfo{ 24 Name: IndexName, 25 Official: true, 26 }, 27 RemoteName: "fooo/bar", 28 LocalName: "fooo/bar", 29 CanonicalName: "docker.io/fooo/bar", 30 Official: false, 31 }, 32 "library/ubuntu": { 33 Index: ®istry.IndexInfo{ 34 Name: IndexName, 35 Official: true, 36 }, 37 RemoteName: "library/ubuntu", 38 LocalName: "ubuntu", 39 CanonicalName: "docker.io/library/ubuntu", 40 Official: true, 41 }, 42 "nonlibrary/ubuntu": { 43 Index: ®istry.IndexInfo{ 44 Name: IndexName, 45 Official: true, 46 }, 47 RemoteName: "nonlibrary/ubuntu", 48 LocalName: "nonlibrary/ubuntu", 49 CanonicalName: "docker.io/nonlibrary/ubuntu", 50 Official: false, 51 }, 52 "ubuntu": { 53 Index: ®istry.IndexInfo{ 54 Name: IndexName, 55 Official: true, 56 }, 57 RemoteName: "library/ubuntu", 58 LocalName: "ubuntu", 59 CanonicalName: "docker.io/library/ubuntu", 60 Official: true, 61 }, 62 "other/library": { 63 Index: ®istry.IndexInfo{ 64 Name: IndexName, 65 Official: true, 66 }, 67 RemoteName: "other/library", 68 LocalName: "other/library", 69 CanonicalName: "docker.io/other/library", 70 Official: false, 71 }, 72 "127.0.0.1:8000/private/moonbase": { 73 Index: ®istry.IndexInfo{ 74 Name: "127.0.0.1:8000", 75 Official: false, 76 }, 77 RemoteName: "private/moonbase", 78 LocalName: "127.0.0.1:8000/private/moonbase", 79 CanonicalName: "127.0.0.1:8000/private/moonbase", 80 Official: false, 81 }, 82 "127.0.0.1:8000/privatebase": { 83 Index: ®istry.IndexInfo{ 84 Name: "127.0.0.1:8000", 85 Official: false, 86 }, 87 RemoteName: "privatebase", 88 LocalName: "127.0.0.1:8000/privatebase", 89 CanonicalName: "127.0.0.1:8000/privatebase", 90 Official: false, 91 }, 92 "localhost:8000/private/moonbase": { 93 Index: ®istry.IndexInfo{ 94 Name: "localhost:8000", 95 Official: false, 96 }, 97 RemoteName: "private/moonbase", 98 LocalName: "localhost:8000/private/moonbase", 99 CanonicalName: "localhost:8000/private/moonbase", 100 Official: false, 101 }, 102 "localhost:8000/privatebase": { 103 Index: ®istry.IndexInfo{ 104 Name: "localhost:8000", 105 Official: false, 106 }, 107 RemoteName: "privatebase", 108 LocalName: "localhost:8000/privatebase", 109 CanonicalName: "localhost:8000/privatebase", 110 Official: false, 111 }, 112 "example.com/private/moonbase": { 113 Index: ®istry.IndexInfo{ 114 Name: "example.com", 115 Official: false, 116 }, 117 RemoteName: "private/moonbase", 118 LocalName: "example.com/private/moonbase", 119 CanonicalName: "example.com/private/moonbase", 120 Official: false, 121 }, 122 "example.com/privatebase": { 123 Index: ®istry.IndexInfo{ 124 Name: "example.com", 125 Official: false, 126 }, 127 RemoteName: "privatebase", 128 LocalName: "example.com/privatebase", 129 CanonicalName: "example.com/privatebase", 130 Official: false, 131 }, 132 "example.com:8000/private/moonbase": { 133 Index: ®istry.IndexInfo{ 134 Name: "example.com:8000", 135 Official: false, 136 }, 137 RemoteName: "private/moonbase", 138 LocalName: "example.com:8000/private/moonbase", 139 CanonicalName: "example.com:8000/private/moonbase", 140 Official: false, 141 }, 142 "example.com:8000/privatebase": { 143 Index: ®istry.IndexInfo{ 144 Name: "example.com:8000", 145 Official: false, 146 }, 147 RemoteName: "privatebase", 148 LocalName: "example.com:8000/privatebase", 149 CanonicalName: "example.com:8000/privatebase", 150 Official: false, 151 }, 152 "localhost/private/moonbase": { 153 Index: ®istry.IndexInfo{ 154 Name: "localhost", 155 Official: false, 156 }, 157 RemoteName: "private/moonbase", 158 LocalName: "localhost/private/moonbase", 159 CanonicalName: "localhost/private/moonbase", 160 Official: false, 161 }, 162 "localhost/privatebase": { 163 Index: ®istry.IndexInfo{ 164 Name: "localhost", 165 Official: false, 166 }, 167 RemoteName: "privatebase", 168 LocalName: "localhost/privatebase", 169 CanonicalName: "localhost/privatebase", 170 Official: false, 171 }, 172 IndexName + "/public/moonbase": { 173 Index: ®istry.IndexInfo{ 174 Name: IndexName, 175 Official: true, 176 }, 177 RemoteName: "public/moonbase", 178 LocalName: "public/moonbase", 179 CanonicalName: "docker.io/public/moonbase", 180 Official: false, 181 }, 182 "index." + IndexName + "/public/moonbase": { 183 Index: ®istry.IndexInfo{ 184 Name: IndexName, 185 Official: true, 186 }, 187 RemoteName: "public/moonbase", 188 LocalName: "public/moonbase", 189 CanonicalName: "docker.io/public/moonbase", 190 Official: false, 191 }, 192 "ubuntu-12.04-base": { 193 Index: ®istry.IndexInfo{ 194 Name: IndexName, 195 Official: true, 196 }, 197 RemoteName: "library/ubuntu-12.04-base", 198 LocalName: "ubuntu-12.04-base", 199 CanonicalName: "docker.io/library/ubuntu-12.04-base", 200 Official: true, 201 }, 202 IndexName + "/ubuntu-12.04-base": { 203 Index: ®istry.IndexInfo{ 204 Name: IndexName, 205 Official: true, 206 }, 207 RemoteName: "library/ubuntu-12.04-base", 208 LocalName: "ubuntu-12.04-base", 209 CanonicalName: "docker.io/library/ubuntu-12.04-base", 210 Official: true, 211 }, 212 "index." + IndexName + "/ubuntu-12.04-base": { 213 Index: ®istry.IndexInfo{ 214 Name: IndexName, 215 Official: true, 216 }, 217 RemoteName: "library/ubuntu-12.04-base", 218 LocalName: "ubuntu-12.04-base", 219 CanonicalName: "docker.io/library/ubuntu-12.04-base", 220 Official: true, 221 }, 222 } 223 224 for reposName, expectedRepoInfo := range expectedRepoInfos { 225 named, err := reference.ParseNormalizedNamed(reposName) 226 if err != nil { 227 t.Error(err) 228 } 229 230 repoInfo, err := ParseRepositoryInfo(named) 231 if err != nil { 232 t.Error(err) 233 } else { 234 assert.Check(t, is.Equal(repoInfo.Index.Name, expectedRepoInfo.Index.Name), reposName) 235 assert.Check(t, is.Equal(reference.Path(repoInfo.Name), expectedRepoInfo.RemoteName), reposName) 236 assert.Check(t, is.Equal(reference.FamiliarName(repoInfo.Name), expectedRepoInfo.LocalName), reposName) 237 assert.Check(t, is.Equal(repoInfo.Name.Name(), expectedRepoInfo.CanonicalName), reposName) 238 assert.Check(t, is.Equal(repoInfo.Index.Official, expectedRepoInfo.Index.Official), reposName) 239 assert.Check(t, is.Equal(repoInfo.Official, expectedRepoInfo.Official), reposName) 240 } 241 } 242 } 243 244 func TestNewIndexInfo(t *testing.T) { 245 testIndexInfo := func(config *serviceConfig, expectedIndexInfos map[string]*registry.IndexInfo) { 246 for indexName, expectedIndexInfo := range expectedIndexInfos { 247 index, err := newIndexInfo(config, indexName) 248 if err != nil { 249 t.Fatal(err) 250 } else { 251 assert.Check(t, is.Equal(index.Name, expectedIndexInfo.Name), indexName+" name") 252 assert.Check(t, is.Equal(index.Official, expectedIndexInfo.Official), indexName+" is official") 253 assert.Check(t, is.Equal(index.Secure, expectedIndexInfo.Secure), indexName+" is secure") 254 assert.Check(t, is.Equal(len(index.Mirrors), len(expectedIndexInfo.Mirrors)), indexName+" mirrors") 255 } 256 } 257 } 258 259 config := emptyServiceConfig 260 var noMirrors []string 261 expectedIndexInfos := map[string]*registry.IndexInfo{ 262 IndexName: { 263 Name: IndexName, 264 Official: true, 265 Secure: true, 266 Mirrors: noMirrors, 267 }, 268 "index." + IndexName: { 269 Name: IndexName, 270 Official: true, 271 Secure: true, 272 Mirrors: noMirrors, 273 }, 274 "example.com": { 275 Name: "example.com", 276 Official: false, 277 Secure: true, 278 Mirrors: noMirrors, 279 }, 280 "127.0.0.1:5000": { 281 Name: "127.0.0.1:5000", 282 Official: false, 283 Secure: false, 284 Mirrors: noMirrors, 285 }, 286 } 287 testIndexInfo(config, expectedIndexInfos) 288 289 publicMirrors := []string{"http://mirror1.local", "http://mirror2.local"} 290 var err error 291 config, err = makeServiceConfig(publicMirrors, []string{"example.com"}) 292 if err != nil { 293 t.Fatal(err) 294 } 295 296 expectedIndexInfos = map[string]*registry.IndexInfo{ 297 IndexName: { 298 Name: IndexName, 299 Official: true, 300 Secure: true, 301 Mirrors: publicMirrors, 302 }, 303 "index." + IndexName: { 304 Name: IndexName, 305 Official: true, 306 Secure: true, 307 Mirrors: publicMirrors, 308 }, 309 "example.com": { 310 Name: "example.com", 311 Official: false, 312 Secure: false, 313 Mirrors: noMirrors, 314 }, 315 "example.com:5000": { 316 Name: "example.com:5000", 317 Official: false, 318 Secure: true, 319 Mirrors: noMirrors, 320 }, 321 "127.0.0.1": { 322 Name: "127.0.0.1", 323 Official: false, 324 Secure: false, 325 Mirrors: noMirrors, 326 }, 327 "127.0.0.1:5000": { 328 Name: "127.0.0.1:5000", 329 Official: false, 330 Secure: false, 331 Mirrors: noMirrors, 332 }, 333 "other.com": { 334 Name: "other.com", 335 Official: false, 336 Secure: true, 337 Mirrors: noMirrors, 338 }, 339 } 340 testIndexInfo(config, expectedIndexInfos) 341 342 config, err = makeServiceConfig(nil, []string{"42.42.0.0/16"}) 343 if err != nil { 344 t.Fatal(err) 345 } 346 expectedIndexInfos = map[string]*registry.IndexInfo{ 347 "example.com": { 348 Name: "example.com", 349 Official: false, 350 Secure: false, 351 Mirrors: noMirrors, 352 }, 353 "example.com:5000": { 354 Name: "example.com:5000", 355 Official: false, 356 Secure: false, 357 Mirrors: noMirrors, 358 }, 359 "127.0.0.1": { 360 Name: "127.0.0.1", 361 Official: false, 362 Secure: false, 363 Mirrors: noMirrors, 364 }, 365 "127.0.0.1:5000": { 366 Name: "127.0.0.1:5000", 367 Official: false, 368 Secure: false, 369 Mirrors: noMirrors, 370 }, 371 "other.com": { 372 Name: "other.com", 373 Official: false, 374 Secure: true, 375 Mirrors: noMirrors, 376 }, 377 } 378 testIndexInfo(config, expectedIndexInfos) 379 } 380 381 func TestMirrorEndpointLookup(t *testing.T) { 382 containsMirror := func(endpoints []APIEndpoint) bool { 383 for _, pe := range endpoints { 384 if pe.URL.Host == "my.mirror" { 385 return true 386 } 387 } 388 return false 389 } 390 cfg, err := makeServiceConfig([]string{"https://my.mirror"}, nil) 391 if err != nil { 392 t.Fatal(err) 393 } 394 s := Service{config: cfg} 395 396 imageName, err := reference.WithName(IndexName + "/test/image") 397 if err != nil { 398 t.Error(err) 399 } 400 pushAPIEndpoints, err := s.LookupPushEndpoints(reference.Domain(imageName)) 401 if err != nil { 402 t.Fatal(err) 403 } 404 if containsMirror(pushAPIEndpoints) { 405 t.Fatal("Push endpoint should not contain mirror") 406 } 407 408 pullAPIEndpoints, err := s.LookupPullEndpoints(reference.Domain(imageName)) 409 if err != nil { 410 t.Fatal(err) 411 } 412 if !containsMirror(pullAPIEndpoints) { 413 t.Fatal("Pull endpoint should contain mirror") 414 } 415 } 416 417 func TestAllowNondistributableArtifacts(t *testing.T) { 418 tests := []struct { 419 addr string 420 registries []string 421 expected bool 422 }{ 423 {IndexName, nil, false}, 424 {"example.com", []string{}, false}, 425 {"example.com", []string{"example.com"}, true}, 426 {"localhost", []string{"localhost:5000"}, false}, 427 {"localhost:5000", []string{"localhost:5000"}, true}, 428 {"localhost", []string{"example.com"}, false}, 429 {"127.0.0.1:5000", []string{"127.0.0.1:5000"}, true}, 430 {"localhost", nil, false}, 431 {"localhost:5000", nil, false}, 432 {"127.0.0.1", nil, false}, 433 {"localhost", []string{"example.com"}, false}, 434 {"127.0.0.1", []string{"example.com"}, false}, 435 {"example.com", nil, false}, 436 {"example.com", []string{"example.com"}, true}, 437 {"127.0.0.1", []string{"example.com"}, false}, 438 {"127.0.0.1:5000", []string{"example.com"}, false}, 439 {"example.com:5000", []string{"42.42.0.0/16"}, true}, 440 {"example.com", []string{"42.42.0.0/16"}, true}, 441 {"example.com:5000", []string{"42.42.42.42/8"}, true}, 442 {"127.0.0.1:5000", []string{"127.0.0.0/8"}, true}, 443 {"42.42.42.42:5000", []string{"42.1.1.1/8"}, true}, 444 {"invalid.example.com", []string{"42.42.0.0/16"}, false}, 445 {"invalid.example.com", []string{"invalid.example.com"}, true}, 446 {"invalid.example.com:5000", []string{"invalid.example.com"}, false}, 447 {"invalid.example.com:5000", []string{"invalid.example.com:5000"}, true}, 448 } 449 for _, tt := range tests { 450 config, err := newServiceConfig(ServiceOptions{ 451 AllowNondistributableArtifacts: tt.registries, 452 }) 453 if err != nil { 454 t.Error(err) 455 } 456 if v := config.allowNondistributableArtifacts(tt.addr); v != tt.expected { 457 t.Errorf("allowNondistributableArtifacts failed for %q %v, expected %v got %v", tt.addr, tt.registries, tt.expected, v) 458 } 459 } 460 } 461 462 func TestIsSecureIndex(t *testing.T) { 463 tests := []struct { 464 addr string 465 insecureRegistries []string 466 expected bool 467 }{ 468 {IndexName, nil, true}, 469 {"example.com", []string{}, true}, 470 {"example.com", []string{"example.com"}, false}, 471 {"localhost", []string{"localhost:5000"}, false}, 472 {"localhost:5000", []string{"localhost:5000"}, false}, 473 {"localhost", []string{"example.com"}, false}, 474 {"127.0.0.1:5000", []string{"127.0.0.1:5000"}, false}, 475 {"localhost", nil, false}, 476 {"localhost:5000", nil, false}, 477 {"127.0.0.1", nil, false}, 478 {"localhost", []string{"example.com"}, false}, 479 {"127.0.0.1", []string{"example.com"}, false}, 480 {"example.com", nil, true}, 481 {"example.com", []string{"example.com"}, false}, 482 {"127.0.0.1", []string{"example.com"}, false}, 483 {"127.0.0.1:5000", []string{"example.com"}, false}, 484 {"example.com:5000", []string{"42.42.0.0/16"}, false}, 485 {"example.com", []string{"42.42.0.0/16"}, false}, 486 {"example.com:5000", []string{"42.42.42.42/8"}, false}, 487 {"127.0.0.1:5000", []string{"127.0.0.0/8"}, false}, 488 {"42.42.42.42:5000", []string{"42.1.1.1/8"}, false}, 489 {"invalid.example.com", []string{"42.42.0.0/16"}, true}, 490 {"invalid.example.com", []string{"invalid.example.com"}, false}, 491 {"invalid.example.com:5000", []string{"invalid.example.com"}, true}, 492 {"invalid.example.com:5000", []string{"invalid.example.com:5000"}, false}, 493 } 494 for _, tt := range tests { 495 config, err := makeServiceConfig(nil, tt.insecureRegistries) 496 if err != nil { 497 t.Error(err) 498 } 499 if sec := config.isSecureIndex(tt.addr); sec != tt.expected { 500 t.Errorf("isSecureIndex failed for %q %v, expected %v got %v", tt.addr, tt.insecureRegistries, tt.expected, sec) 501 } 502 } 503 }