| package reference | |
| import ( | |
| "testing" | |
| digest "github.com/opencontainers/go-digest" | |
| ) | |
| func TestReferenceParser(t *testing.T) { | |
| for _, testcase := range []struct { | |
| Skip bool | |
| Name string | |
| Input string | |
| Normalized string | |
| Digest digest.Digest | |
| Hostname string | |
| Expected Spec | |
| Err error | |
| }{ | |
| { | |
| Name: "Basic", | |
| Input: "docker.io/library/redis:foo?fooo=asdf", | |
| Normalized: "docker.io/library/redis:foo", | |
| Hostname: "docker.io", | |
| Expected: Spec{ | |
| Locator: "docker.io/library/redis", | |
| Object: "foo", | |
| }, | |
| }, | |
| { | |
| Name: "BasicWithDigest", | |
| Input: "docker.io/library/redis:foo@sha256:abcdef?fooo=asdf", | |
| Normalized: "docker.io/library/redis:foo@sha256:abcdef", | |
| Hostname: "docker.io", | |
| Digest: "sha256:abcdef", | |
| Expected: Spec{ | |
| Locator: "docker.io/library/redis", | |
| Object: "foo@sha256:abcdef", | |
| }, | |
| }, | |
| { | |
| Name: "DigestOnly", | |
| Input: "docker.io/library/redis@sha256:abcdef?fooo=asdf", | |
| Expected: Spec{ | |
| Locator: "docker.io/library/redis", | |
| Object: "@sha256:abcdef", | |
| }, | |
| Hostname: "docker.io", | |
| Normalized: "docker.io/library/redis@sha256:abcdef", | |
| Digest: "sha256:abcdef", | |
| }, | |
| { | |
| Name: "AtShortDigest", | |
| Input: "docker.io/library/redis:obj@abcdef?fooo=asdf", | |
| Normalized: "docker.io/library/redis:obj@abcdef", | |
| Hostname: "docker.io", | |
| Digest: "abcdef", | |
| Expected: Spec{ | |
| Locator: "docker.io/library/redis", | |
| Object: "obj@abcdef", | |
| }, | |
| }, | |
| { | |
| Name: "HostWithPort", | |
| Input: "localhost:5000/library/redis:obj@abcdef?fooo=asdf", | |
| Normalized: "localhost:5000/library/redis:obj@abcdef", | |
| Hostname: "localhost:5000", | |
| Digest: "abcdef", | |
| Expected: Spec{ | |
| Locator: "localhost:5000/library/redis", | |
| Object: "obj@abcdef", | |
| }, | |
| }, | |
| { | |
| Name: "HostnameRequired", | |
| Input: "/docker.io/library/redis:obj@abcdef?fooo=asdf", | |
| Err: ErrHostnameRequired, | |
| }, | |
| { | |
| Name: "ErrObjectRequired", | |
| Input: "docker.io/library/redis?fooo=asdf", | |
| Err: ErrObjectRequired, | |
| }, | |
| { | |
| Name: "Subdomain", | |
| Input: "sub-dom1.foo.com/bar/baz/quux:latest", | |
| Hostname: "sub-dom1.foo.com", | |
| Expected: Spec{ | |
| Locator: "sub-dom1.foo.com/bar/baz/quux", | |
| Object: "latest", | |
| }, | |
| }, | |
| { | |
| Name: "SubdomainWithLongTag", | |
| Input: "sub-dom1.foo.com/bar/baz/quux:some-long-tag", | |
| Hostname: "sub-dom1.foo.com", | |
| Expected: Spec{ | |
| Locator: "sub-dom1.foo.com/bar/baz/quux", | |
| Object: "some-long-tag", | |
| }, | |
| }, | |
| { | |
| Name: "AGCRAppears", | |
| Input: "b.gcr.io/test.example.com/my-app:test.example.com", | |
| Hostname: "b.gcr.io", | |
| Expected: Spec{ | |
| Locator: "b.gcr.io/test.example.com/my-app", | |
| Object: "test.example.com", | |
| }, | |
| }, | |
| { | |
| Name: "Punycode", | |
| Input: "xn--n3h.com/myimage:xn--n3h.com", // ☃.com in punycode | |
| Hostname: "xn--n3h.com", | |
| Expected: Spec{ | |
| Locator: "xn--n3h.com/myimage", | |
| Object: "xn--n3h.com", | |
| }, | |
| }, | |
| { | |
| Name: "PunycodeWithDigest", | |
| Input: "xn--7o8h.com/myimage:xn--7o8h.com@sha512:fffffff", | |
| Hostname: "xn--7o8h.com", | |
| Digest: "sha512:fffffff", | |
| Expected: Spec{ | |
| Locator: "xn--7o8h.com/myimage", | |
| Object: "xn--7o8h.com@sha512:fffffff", | |
| }, | |
| }, | |
| { | |
| Skip: true, // TODO(stevvooe): Implement this case. | |
| Name: "SchemeDefined", | |
| Input: "http://xn--7o8h.com/myimage:xn--7o8h.com@sha512:fffffff", | |
| Hostname: "xn--7o8h.com", | |
| Digest: "sha512:fffffff", | |
| Err: ErrInvalid, | |
| }, | |
| } { | |
| t.Run(testcase.Name, func(t *testing.T) { | |
| if testcase.Skip { | |
| t.Skip("testcase disabled") | |
| return | |
| } | |
| ref, err := Parse(testcase.Input) | |
| if err != testcase.Err { | |
| if testcase.Err != nil { | |
| t.Fatalf("expected error %v for %q, got %v, %#v", testcase.Err, testcase.Input, err, ref) | |
| } else { | |
| t.Fatalf("unexpected error %v", err) | |
| } | |
| } else if testcase.Err != nil { | |
| return | |
| } | |
| if ref != testcase.Expected { | |
| t.Fatalf("%#v != %#v", ref, testcase.Expected) | |
| } | |
| if testcase.Normalized == "" { | |
| testcase.Normalized = testcase.Input | |
| } | |
| if ref.String() != testcase.Normalized { | |
| t.Fatalf("normalization failed: %v != %v", ref.String(), testcase.Normalized) | |
| } | |
| if ref.Digest() != testcase.Digest { | |
| t.Fatalf("digest extraction failed: %v != %v", ref.Digest(), testcase.Digest) | |
| } | |
| if ref.Hostname() != testcase.Hostname { | |
| t.Fatalf("unexpected hostname: %v != %v", ref.Hostname(), testcase.Hostname) | |
| } | |
| }) | |
| } | |
| } |