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)
}
}
}