| package registry |
| |
| import ( |
| "testing" |
| |
| cerrdefs "github.com/containerd/errdefs" |
| "gotest.tools/v3/assert" |
| is "gotest.tools/v3/assert/cmp" |
| ) |
| |
| func TestValidateMirror(t *testing.T) { |
| tests := []struct { |
| input string |
| output string |
| expectedErr string |
| }{ |
| // Valid cases |
| { |
| input: "http://mirror-1.example.com", |
| output: "http://mirror-1.example.com/", |
| }, |
| { |
| input: "http://mirror-1.example.com/", |
| output: "http://mirror-1.example.com/", |
| }, |
| { |
| input: "https://mirror-1.example.com", |
| output: "https://mirror-1.example.com/", |
| }, |
| { |
| input: "https://mirror-1.example.com/", |
| output: "https://mirror-1.example.com/", |
| }, |
| { |
| input: "http://localhost", |
| output: "http://localhost/", |
| }, |
| { |
| input: "https://localhost", |
| output: "https://localhost/", |
| }, |
| { |
| input: "http://localhost:5000", |
| output: "http://localhost:5000/", |
| }, |
| { |
| input: "https://localhost:5000", |
| output: "https://localhost:5000/", |
| }, |
| { |
| input: "http://127.0.0.1", |
| output: "http://127.0.0.1/", |
| }, |
| { |
| input: "https://127.0.0.1", |
| output: "https://127.0.0.1/", |
| }, |
| { |
| input: "http://127.0.0.1:5000", |
| output: "http://127.0.0.1:5000/", |
| }, |
| { |
| input: "https://127.0.0.1:5000", |
| output: "https://127.0.0.1:5000/", |
| }, |
| { |
| input: "http://mirror-1.example.com/v1/", |
| output: "http://mirror-1.example.com/v1/", |
| }, |
| { |
| input: "https://mirror-1.example.com/v1/", |
| output: "https://mirror-1.example.com/v1/", |
| }, |
| |
| // Invalid cases |
| { |
| input: "!invalid!://%as%", |
| expectedErr: `invalid mirror: "!invalid!://%as%" is not a valid URI: parse "!invalid!://%as%": first path segment in URL cannot contain colon`, |
| }, |
| { |
| input: "mirror-1.example.com", |
| expectedErr: `invalid mirror: no scheme specified for "mirror-1.example.com": must use either 'https://' or 'http://'`, |
| }, |
| { |
| input: "mirror-1.example.com:5000", |
| expectedErr: `invalid mirror: no scheme specified for "mirror-1.example.com:5000": must use either 'https://' or 'http://'`, |
| }, |
| { |
| input: "ftp://mirror-1.example.com", |
| expectedErr: `invalid mirror: unsupported scheme "ftp" in "ftp://mirror-1.example.com": must use either 'https://' or 'http://'`, |
| }, |
| { |
| input: "http://mirror-1.example.com/?q=foo", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "http://mirror-1.example.com/?q=foo"`, |
| }, |
| { |
| input: "http://mirror-1.example.com/v1/?q=foo", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "http://mirror-1.example.com/v1/?q=foo"`, |
| }, |
| { |
| input: "http://mirror-1.example.com/v1/?q=foo#frag", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "http://mirror-1.example.com/v1/?q=foo#frag"`, |
| }, |
| { |
| input: "http://mirror-1.example.com?q=foo", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "http://mirror-1.example.com?q=foo"`, |
| }, |
| { |
| input: "https://mirror-1.example.com#frag", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "https://mirror-1.example.com#frag"`, |
| }, |
| { |
| input: "https://mirror-1.example.com/#frag", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "https://mirror-1.example.com/#frag"`, |
| }, |
| { |
| input: "http://foo:bar@mirror-1.example.com/", |
| expectedErr: `invalid mirror: username/password not allowed in URI "http://foo:xxxxx@mirror-1.example.com/"`, |
| }, |
| { |
| input: "https://mirror-1.example.com/v1/#frag", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "https://mirror-1.example.com/v1/#frag"`, |
| }, |
| { |
| input: "https://mirror-1.example.com?q", |
| expectedErr: `invalid mirror: query or fragment at end of the URI "https://mirror-1.example.com?q"`, |
| }, |
| } |
| |
| for _, tc := range tests { |
| t.Run(tc.input, func(t *testing.T) { |
| out, err := ValidateMirror(tc.input) |
| if tc.expectedErr != "" { |
| assert.Error(t, err, tc.expectedErr) |
| } else { |
| assert.NilError(t, err) |
| } |
| assert.Check(t, is.Equal(out, tc.output)) |
| }) |
| } |
| } |
| |
| func TestLoadInsecureRegistries(t *testing.T) { |
| testCases := []struct { |
| registries []string |
| index string |
| err string |
| }{ |
| { |
| registries: []string{"127.0.0.1"}, |
| index: "127.0.0.1", |
| }, |
| { |
| registries: []string{"127.0.0.1:8080"}, |
| index: "127.0.0.1:8080", |
| }, |
| { |
| registries: []string{"2001:db8::1"}, |
| index: "2001:db8::1", |
| }, |
| { |
| registries: []string{"[2001:db8::1]:80"}, |
| index: "[2001:db8::1]:80", |
| }, |
| { |
| registries: []string{"http://myregistry.example.com"}, |
| index: "myregistry.example.com", |
| }, |
| { |
| registries: []string{"https://myregistry.example.com"}, |
| index: "myregistry.example.com", |
| }, |
| { |
| registries: []string{"HTTP://myregistry.example.com"}, |
| index: "myregistry.example.com", |
| }, |
| { |
| registries: []string{"svn://myregistry.example.com"}, |
| err: "insecure registry svn://myregistry.example.com should not contain '://'", |
| }, |
| { |
| registries: []string{"-invalid-registry"}, |
| err: "Cannot begin or end with a hyphen", |
| }, |
| { |
| registries: []string{`mytest-.com`}, |
| err: `insecure registry mytest-.com is not valid: invalid host "mytest-.com"`, |
| }, |
| { |
| registries: []string{`1200:0000:AB00:1234:0000:2552:7777:1313:8080`}, |
| err: `insecure registry 1200:0000:AB00:1234:0000:2552:7777:1313:8080 is not valid: invalid host "1200:0000:AB00:1234:0000:2552:7777:1313:8080"`, |
| }, |
| { |
| registries: []string{`myregistry.example.com:500000`}, |
| err: `insecure registry myregistry.example.com:500000 is not valid: invalid port "500000"`, |
| }, |
| { |
| registries: []string{`"myregistry.example.com"`}, |
| err: `insecure registry "myregistry.example.com" is not valid: invalid host "\"myregistry.example.com\""`, |
| }, |
| { |
| registries: []string{`"myregistry.example.com:5000"`}, |
| err: `insecure registry "myregistry.example.com:5000" is not valid: invalid host "\"myregistry.example.com"`, |
| }, |
| } |
| for _, testCase := range testCases { |
| config := &serviceConfig{} |
| err := config.loadInsecureRegistries(testCase.registries) |
| if testCase.err == "" { |
| if err != nil { |
| t.Fatalf("expect no error, got '%s'", err) |
| } |
| match := false |
| for index := range config.IndexConfigs { |
| if index == testCase.index { |
| match = true |
| } |
| } |
| if !match { |
| t.Fatalf("expect index configs to contain '%s', got %+v", testCase.index, config.IndexConfigs) |
| } |
| } else { |
| if err == nil { |
| t.Fatalf("expect error '%s', got no error", testCase.err) |
| } |
| assert.ErrorContains(t, err, testCase.err) |
| assert.Check(t, cerrdefs.IsInvalidArgument(err)) |
| } |
| } |
| } |
| |
| func TestNewServiceConfig(t *testing.T) { |
| tests := []struct { |
| doc string |
| opts ServiceOptions |
| errStr string |
| }{ |
| { |
| doc: "empty config", |
| }, |
| { |
| doc: "invalid mirror", |
| opts: ServiceOptions{ |
| Mirrors: []string{"example.com:5000"}, |
| }, |
| errStr: `invalid mirror: no scheme specified for "example.com:5000": must use either 'https://' or 'http://'`, |
| }, |
| { |
| doc: "valid mirror", |
| opts: ServiceOptions{ |
| Mirrors: []string{"https://example.com:5000"}, |
| }, |
| }, |
| { |
| doc: "invalid insecure registry", |
| opts: ServiceOptions{ |
| InsecureRegistries: []string{"[fe80::]/64"}, |
| }, |
| errStr: `insecure registry [fe80::]/64 is not valid: invalid host "[fe80::]/64"`, |
| }, |
| { |
| doc: "valid insecure registry", |
| opts: ServiceOptions{ |
| InsecureRegistries: []string{"102.10.8.1/24"}, |
| }, |
| }, |
| } |
| |
| for _, tc := range tests { |
| t.Run(tc.doc, func(t *testing.T) { |
| _, err := newServiceConfig(tc.opts) |
| if tc.errStr != "" { |
| assert.Check(t, is.Error(err, tc.errStr)) |
| assert.Check(t, cerrdefs.IsInvalidArgument(err)) |
| } else { |
| assert.Check(t, err) |
| } |
| }) |
| } |
| } |
| |
| func TestValidateIndexName(t *testing.T) { |
| valid := []struct { |
| index string |
| expect string |
| }{ |
| { |
| index: "index.docker.io", |
| expect: "docker.io", |
| }, |
| { |
| index: "example.com", |
| expect: "example.com", |
| }, |
| { |
| index: "127.0.0.1:8080", |
| expect: "127.0.0.1:8080", |
| }, |
| { |
| index: "mytest-1.com", |
| expect: "mytest-1.com", |
| }, |
| { |
| index: "mirror-1.example.com/v1/?q=foo", |
| expect: "mirror-1.example.com/v1/?q=foo", |
| }, |
| } |
| |
| for _, testCase := range valid { |
| result, err := ValidateIndexName(testCase.index) |
| if assert.Check(t, err) { |
| assert.Check(t, is.Equal(testCase.expect, result)) |
| } |
| } |
| } |
| |
| func TestValidateIndexNameWithError(t *testing.T) { |
| invalid := []struct { |
| index string |
| err string |
| }{ |
| { |
| index: "docker.io-", |
| err: "invalid index name (docker.io-). Cannot begin or end with a hyphen", |
| }, |
| { |
| index: "-example.com", |
| err: "invalid index name (-example.com). Cannot begin or end with a hyphen", |
| }, |
| { |
| index: "mirror-1.example.com/v1/?q=foo-", |
| err: "invalid index name (mirror-1.example.com/v1/?q=foo-). Cannot begin or end with a hyphen", |
| }, |
| } |
| for _, testCase := range invalid { |
| _, err := ValidateIndexName(testCase.index) |
| assert.Check(t, is.Error(err, testCase.err)) |
| assert.Check(t, cerrdefs.IsInvalidArgument(err)) |
| } |
| } |