package reference import ( "fmt" "strings" "testing" ) func TestParseNamedDockerImageReference(t *testing.T) { testCases := []struct { From string Registry, Namespace, Name, Tag, ID string Err bool }{ { From: "foo", Name: "foo", }, { From: "foo:tag", Name: "foo", Tag: "tag", }, { From: "sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", Name: "sha256", Tag: "3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", }, { From: "foo@sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", Name: "foo", ID: "sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", }, { From: "bar/foo", Namespace: "bar", Name: "foo", }, { From: "bar/foo:tag", Namespace: "bar", Name: "foo", Tag: "tag", }, { From: "bar/foo@sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", Namespace: "bar", Name: "foo", ID: "sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", }, { From: "bar/foo/baz", Namespace: "bar", Name: "foo/baz", }, { From: "bar/library/baz", Namespace: "bar", Name: "library/baz", }, { From: "bar/foo/baz:tag", Namespace: "bar", Name: "foo/baz", Tag: "tag", }, { From: "bar/foo/baz@sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", Namespace: "bar", Name: "foo/baz", ID: "sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", }, { From: "bar:5000/foo/baz", Registry: "bar:5000", Namespace: "foo", Name: "baz", }, { From: "bar:5000/library/baz", Registry: "bar:5000", Namespace: "library", Name: "baz", }, { From: "bar:5000/baz", Registry: "bar:5000", Name: "baz", }, { From: "bar:5000/foo/baz:tag", Registry: "bar:5000", Namespace: "foo", Name: "baz", Tag: "tag", }, { From: "bar:5000/foo/baz@sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", Registry: "bar:5000", Namespace: "foo", Name: "baz", ID: "sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", }, { From: "myregistry.io/foo", Registry: "myregistry.io", Name: "foo", }, { From: "localhost/bar", Registry: "localhost", Name: "bar", }, { From: "docker.io/library/myapp", Registry: "docker.io", Namespace: "library", Name: "myapp", }, { From: "docker.io/myapp", Registry: "docker.io", Name: "myapp", }, { From: "docker.io/user/myapp", Registry: "docker.io", Namespace: "user", Name: "myapp", }, { From: "docker.io/user/project/myapp", Registry: "docker.io", Namespace: "user", Name: "project/myapp", }, { From: "index.docker.io/bar", Registry: "index.docker.io", Name: "bar", }, { // registry/namespace/name == 255 chars From: fmt.Sprintf("bar:5000/%s/%s:tag", strings.Repeat("a", 63), strings.Repeat("b", 182)), Registry: "bar:5000", Namespace: strings.Repeat("a", 63), Name: strings.Repeat("b", 182), Tag: "tag", }, { // docker.io/namespace/name == 255 chars with explicit namespace From: fmt.Sprintf("docker.io/library/%s:tag", strings.Repeat("b", 231)), Registry: "docker.io", Namespace: "library", Name: strings.Repeat("b", 231), Tag: "tag", }, { // docker.io/namespace/name == 255 chars with implicit namespace From: fmt.Sprintf("docker.io/%s:tag", strings.Repeat("b", 231)), Registry: "docker.io", Name: strings.Repeat("b", 231), Tag: "tag", }, { // registry/namespace/name > 255 chars From: fmt.Sprintf("bar:5000/%s/%s:tag", strings.Repeat("a", 63), strings.Repeat("b", 183)), Err: true, }, { // docker.io/name > 255 chars with implicit namespace From: fmt.Sprintf("docker.io/%s:tag", strings.Repeat("b", 246)), Err: true, }, { From: "registry.io/foo/bar/:Tag", Err: true, }, { From: "https://bar:5000/foo/baz", Err: true, }, { From: "http://bar:5000/foo/baz@sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", Err: true, }, { From: "registry:3000/integration/imageStream:success", Err: true, }, { From: "registry:5000/integration/test-image-stream@sha256:00000000000000000000000000000001", Err: true, }, { From: "abc@badid", Err: true, }, { From: "index.docker.io/mysql@sha256:bad", Err: true, }, { From: "@sha256:3c87c572822935df60f0f5d3665bd376841a7fcfeb806b5f212de6a00e9a7b25", Err: true, }, { From: ":tag", Err: true, }, { From: "bar/foo/baz/biz", Namespace: "bar", Name: "foo/baz/biz", }, { From: "bar/foo/baz////biz", Err: true, }, { From: "//foo/baz/biz", Err: true, }, { From: "ftp://baz/baz/biz", Err: true, }, { From: "", Err: true, }, } for _, testCase := range testCases { ref, err := ParseNamedDockerImageReference(testCase.From) switch { case err != nil && !testCase.Err: t.Errorf("%s: unexpected error: %v", testCase.From, err) continue case err == nil && testCase.Err: t.Errorf("%s: unexpected non-error: %#+v", testCase.From, ref) continue case err != nil && testCase.Err: continue } if e, a := testCase.Registry, ref.Registry; e != a { t.Errorf("%s: registry: expected %q, got %q", testCase.From, e, a) } if e, a := testCase.Namespace, ref.Namespace; e != a { t.Errorf("%s: namespace: expected %q, got %q", testCase.From, e, a) } if e, a := testCase.Name, ref.Name; e != a { t.Errorf("%s: name: expected %q, got %q", testCase.From, e, a) } if e, a := testCase.Tag, ref.Tag; e != a { t.Errorf("%s: tag: expected %q, got %q", testCase.From, e, a) } if e, a := testCase.ID, ref.ID; e != a { t.Errorf("%s: id: expected %q, got %q", testCase.From, e, a) } } }