forked from TrueCloudLab/distribution
Merge pull request #3786 from thaJeztah/reference_subtests
This commit is contained in:
commit
85d4039064
4 changed files with 278 additions and 236 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateReferenceName(t *testing.T) {
|
func TestValidateReferenceName(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
validRepoNames := []string{
|
validRepoNames := []string{
|
||||||
"docker/docker",
|
"docker/docker",
|
||||||
"library/debian",
|
"library/debian",
|
||||||
|
@ -70,6 +71,7 @@ func TestValidateReferenceName(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateRemoteName(t *testing.T) {
|
func TestValidateRemoteName(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
validRepositoryNames := []string{
|
validRepositoryNames := []string{
|
||||||
// Sanity check.
|
// Sanity check.
|
||||||
"docker/docker",
|
"docker/docker",
|
||||||
|
@ -139,6 +141,7 @@ func TestValidateRemoteName(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseRepositoryInfo(t *testing.T) {
|
func TestParseRepositoryInfo(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
type tcase struct {
|
type tcase struct {
|
||||||
RemoteName, FamiliarName, FullName, AmbiguousName, Domain string
|
RemoteName, FamiliarName, FullName, AmbiguousName, Domain string
|
||||||
}
|
}
|
||||||
|
@ -292,6 +295,7 @@ func TestParseRepositoryInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseReferenceWithTagAndDigest(t *testing.T) {
|
func TestParseReferenceWithTagAndDigest(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
shortRef := "busybox:latest@sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa"
|
shortRef := "busybox:latest@sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa"
|
||||||
ref, err := ParseNormalizedNamed(shortRef)
|
ref, err := ParseNormalizedNamed(shortRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -313,6 +317,7 @@ func TestParseReferenceWithTagAndDigest(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidReferenceComponents(t *testing.T) {
|
func TestInvalidReferenceComponents(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
if _, err := ParseNormalizedNamed("-foo"); err == nil {
|
if _, err := ParseNormalizedNamed("-foo"); err == nil {
|
||||||
t.Fatal("Expected WithName to detect invalid name")
|
t.Fatal("Expected WithName to detect invalid name")
|
||||||
}
|
}
|
||||||
|
@ -355,6 +360,7 @@ func equalReference(r1, r2 Reference) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseAnyReference(t *testing.T) {
|
func TestParseAnyReference(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
tcases := []struct {
|
tcases := []struct {
|
||||||
Reference string
|
Reference string
|
||||||
Equivalent string
|
Equivalent string
|
||||||
|
@ -445,6 +451,7 @@ func TestParseAnyReference(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizedSplitHostname(t *testing.T) {
|
func TestNormalizedSplitHostname(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
input string
|
input string
|
||||||
domain string
|
domain string
|
||||||
|
@ -527,6 +534,7 @@ func TestNormalizedSplitHostname(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMatchError(t *testing.T) {
|
func TestMatchError(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
named, err := ParseAnyReference("foo")
|
named, err := ParseAnyReference("foo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -538,6 +546,7 @@ func TestMatchError(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMatch(t *testing.T) {
|
func TestMatch(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
matchCases := []struct {
|
matchCases := []struct {
|
||||||
reference string
|
reference string
|
||||||
pattern string
|
pattern string
|
||||||
|
@ -605,6 +614,7 @@ func TestMatch(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseDockerRef(t *testing.T) {
|
func TestParseDockerRef(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
name string
|
name string
|
||||||
input string
|
input string
|
||||||
|
@ -668,6 +678,7 @@ func TestParseDockerRef(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, test := range testcases {
|
for _, test := range testcases {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
normalized, err := ParseDockerRef(test.input)
|
normalized, err := ParseDockerRef(test.input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
_ "crypto/sha256"
|
_ "crypto/sha256"
|
||||||
_ "crypto/sha512"
|
_ "crypto/sha512"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -12,6 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReferenceParse(t *testing.T) {
|
func TestReferenceParse(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
// referenceTestcases is a unified set of testcases for
|
// referenceTestcases is a unified set of testcases for
|
||||||
// testing the parsing of references
|
// testing the parsing of references
|
||||||
referenceTestcases := []struct {
|
referenceTestcases := []struct {
|
||||||
|
@ -103,10 +103,10 @@ func TestReferenceParse(t *testing.T) {
|
||||||
},
|
},
|
||||||
// FIXME "Uppercase" is incorrectly handled as a domain-name here, therefore passes.
|
// FIXME "Uppercase" is incorrectly handled as a domain-name here, therefore passes.
|
||||||
// See https://github.com/distribution/distribution/pull/1778, and https://github.com/docker/docker/pull/20175
|
// See https://github.com/distribution/distribution/pull/1778, and https://github.com/docker/docker/pull/20175
|
||||||
//{
|
// {
|
||||||
// input: "Uppercase/lowercase:tag",
|
// input: "Uppercase/lowercase:tag",
|
||||||
// err: ErrNameContainsUppercase,
|
// err: ErrNameContainsUppercase,
|
||||||
//},
|
// },
|
||||||
{
|
{
|
||||||
input: "test:5000/Uppercase/lowercase:tag",
|
input: "test:5000/Uppercase/lowercase:tag",
|
||||||
err: ErrNameContainsUppercase,
|
err: ErrNameContainsUppercase,
|
||||||
|
@ -268,71 +268,70 @@ func TestReferenceParse(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testcase := range referenceTestcases {
|
for _, testcase := range referenceTestcases {
|
||||||
failf := func(format string, v ...interface{}) {
|
testcase := testcase
|
||||||
t.Logf(strconv.Quote(testcase.input)+": "+format, v...)
|
t.Run(testcase.input, func(t *testing.T) {
|
||||||
t.Fail()
|
t.Parallel()
|
||||||
}
|
repo, err := Parse(testcase.input)
|
||||||
|
if testcase.err != nil {
|
||||||
repo, err := Parse(testcase.input)
|
if err == nil {
|
||||||
if testcase.err != nil {
|
t.Errorf("missing expected error: %v", testcase.err)
|
||||||
if err == nil {
|
} else if testcase.err != err {
|
||||||
failf("missing expected error: %v", testcase.err)
|
t.Errorf("mismatched error: got %v, expected %v", err, testcase.err)
|
||||||
} else if testcase.err != err {
|
|
||||||
failf("mismatched error: got %v, expected %v", err, testcase.err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
} else if err != nil {
|
|
||||||
failf("unexpected parse error: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if repo.String() != testcase.input {
|
|
||||||
failf("mismatched repo: got %q, expected %q", repo.String(), testcase.input)
|
|
||||||
}
|
|
||||||
|
|
||||||
if named, ok := repo.(Named); ok {
|
|
||||||
if named.Name() != testcase.repository {
|
|
||||||
failf("unexpected repository: got %q, expected %q", named.Name(), testcase.repository)
|
|
||||||
}
|
|
||||||
domain, _ := SplitHostname(named)
|
|
||||||
if domain != testcase.domain {
|
|
||||||
failf("unexpected domain: got %q, expected %q", domain, testcase.domain)
|
|
||||||
}
|
|
||||||
} else if testcase.repository != "" || testcase.domain != "" {
|
|
||||||
failf("expected named type, got %T", repo)
|
|
||||||
}
|
|
||||||
|
|
||||||
tagged, ok := repo.(Tagged)
|
|
||||||
if testcase.tag != "" {
|
|
||||||
if ok {
|
|
||||||
if tagged.Tag() != testcase.tag {
|
|
||||||
failf("unexpected tag: got %q, expected %q", tagged.Tag(), testcase.tag)
|
|
||||||
}
|
}
|
||||||
} else {
|
return
|
||||||
failf("expected tagged type, got %T", repo)
|
} else if err != nil {
|
||||||
|
t.Errorf("unexpected parse error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if repo.String() != testcase.input {
|
||||||
|
t.Errorf("mismatched repo: got %q, expected %q", repo.String(), testcase.input)
|
||||||
}
|
}
|
||||||
} else if ok {
|
|
||||||
failf("unexpected tagged type")
|
|
||||||
}
|
|
||||||
|
|
||||||
digested, ok := repo.(Digested)
|
if named, ok := repo.(Named); ok {
|
||||||
if testcase.digest != "" {
|
if named.Name() != testcase.repository {
|
||||||
if ok {
|
t.Errorf("unexpected repository: got %q, expected %q", named.Name(), testcase.repository)
|
||||||
if digested.Digest().String() != testcase.digest {
|
|
||||||
failf("unexpected digest: got %q, expected %q", digested.Digest().String(), testcase.digest)
|
|
||||||
}
|
}
|
||||||
} else {
|
domain, _ := SplitHostname(named)
|
||||||
failf("expected digested type, got %T", repo)
|
if domain != testcase.domain {
|
||||||
|
t.Errorf("unexpected domain: got %q, expected %q", domain, testcase.domain)
|
||||||
|
}
|
||||||
|
} else if testcase.repository != "" || testcase.domain != "" {
|
||||||
|
t.Errorf("expected named type, got %T", repo)
|
||||||
}
|
}
|
||||||
} else if ok {
|
|
||||||
failf("unexpected digested type")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
tagged, ok := repo.(Tagged)
|
||||||
|
if testcase.tag != "" {
|
||||||
|
if ok {
|
||||||
|
if tagged.Tag() != testcase.tag {
|
||||||
|
t.Errorf("unexpected tag: got %q, expected %q", tagged.Tag(), testcase.tag)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("expected tagged type, got %T", repo)
|
||||||
|
}
|
||||||
|
} else if ok {
|
||||||
|
t.Errorf("unexpected tagged type")
|
||||||
|
}
|
||||||
|
|
||||||
|
digested, ok := repo.(Digested)
|
||||||
|
if testcase.digest != "" {
|
||||||
|
if ok {
|
||||||
|
if digested.Digest().String() != testcase.digest {
|
||||||
|
t.Errorf("unexpected digest: got %q, expected %q", digested.Digest().String(), testcase.digest)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("expected digested type, got %T", repo)
|
||||||
|
}
|
||||||
|
} else if ok {
|
||||||
|
t.Errorf("unexpected digested type")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestWithNameFailure tests cases where WithName should fail. Cases where it
|
// TestWithNameFailure tests cases where WithName should fail. Cases where it
|
||||||
// should succeed are covered by TestSplitHostname, below.
|
// should succeed are covered by TestSplitHostname, below.
|
||||||
func TestWithNameFailure(t *testing.T) {
|
func TestWithNameFailure(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
input string
|
input string
|
||||||
err error
|
err error
|
||||||
|
@ -363,19 +362,19 @@ func TestWithNameFailure(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
failf := func(format string, v ...interface{}) {
|
testcase := testcase
|
||||||
t.Logf(strconv.Quote(testcase.input)+": "+format, v...)
|
t.Run(testcase.input, func(t *testing.T) {
|
||||||
t.Fail()
|
t.Parallel()
|
||||||
}
|
_, err := WithName(testcase.input)
|
||||||
|
if err == nil {
|
||||||
_, err := WithName(testcase.input)
|
t.Errorf("no error parsing name. expected: %s", testcase.err)
|
||||||
if err == nil {
|
}
|
||||||
failf("no error parsing name. expected: %s", testcase.err)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSplitHostname(t *testing.T) {
|
func TestSplitHostname(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
input string
|
input string
|
||||||
domain string
|
domain string
|
||||||
|
@ -413,22 +412,21 @@ func TestSplitHostname(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
failf := func(format string, v ...interface{}) {
|
testcase := testcase
|
||||||
t.Logf(strconv.Quote(testcase.input)+": "+format, v...)
|
t.Run(testcase.input, func(t *testing.T) {
|
||||||
t.Fail()
|
t.Parallel()
|
||||||
}
|
named, err := WithName(testcase.input)
|
||||||
|
if err != nil {
|
||||||
named, err := WithName(testcase.input)
|
t.Errorf("error parsing name: %s", err)
|
||||||
if err != nil {
|
}
|
||||||
failf("error parsing name: %s", err)
|
domain, name := SplitHostname(named)
|
||||||
}
|
if domain != testcase.domain {
|
||||||
domain, name := SplitHostname(named)
|
t.Errorf("unexpected domain: got %q, expected %q", domain, testcase.domain)
|
||||||
if domain != testcase.domain {
|
}
|
||||||
failf("unexpected domain: got %q, expected %q", domain, testcase.domain)
|
if name != testcase.name {
|
||||||
}
|
t.Errorf("unexpected name: got %q, expected %q", name, testcase.name)
|
||||||
if name != testcase.name {
|
}
|
||||||
failf("unexpected name: got %q, expected %q", name, testcase.name)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,6 +436,7 @@ type serializationType struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSerialization(t *testing.T) {
|
func TestSerialization(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
description string
|
description string
|
||||||
input string
|
input string
|
||||||
|
@ -469,99 +468,98 @@ func TestSerialization(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
failf := func(format string, v ...interface{}) {
|
testcase := testcase
|
||||||
t.Logf(strconv.Quote(testcase.input)+": "+format, v...)
|
t.Run(testcase.description, func(t *testing.T) {
|
||||||
t.Fail()
|
t.Parallel()
|
||||||
}
|
m := map[string]string{
|
||||||
|
"Description": testcase.description,
|
||||||
m := map[string]string{
|
"Field": testcase.input,
|
||||||
"Description": testcase.description,
|
|
||||||
"Field": testcase.input,
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(m)
|
|
||||||
if err != nil {
|
|
||||||
failf("error marshalling: %v", err)
|
|
||||||
}
|
|
||||||
t := serializationType{}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(b, &t); err != nil {
|
|
||||||
if testcase.err == nil {
|
|
||||||
failf("error unmarshalling: %v", err)
|
|
||||||
}
|
}
|
||||||
if err != testcase.err {
|
b, err := json.Marshal(m)
|
||||||
failf("wrong error, expected %v, got %v", testcase.err, err)
|
if err != nil {
|
||||||
|
t.Errorf("error marshalling: %v", err)
|
||||||
}
|
}
|
||||||
|
st := serializationType{}
|
||||||
|
|
||||||
continue
|
if err := json.Unmarshal(b, &st); err != nil {
|
||||||
} else if testcase.err != nil {
|
if testcase.err == nil {
|
||||||
failf("expected error unmarshalling: %v", testcase.err)
|
t.Errorf("error unmarshalling: %v", err)
|
||||||
}
|
|
||||||
|
|
||||||
if t.Description != testcase.description {
|
|
||||||
failf("wrong description, expected %q, got %q", testcase.description, t.Description)
|
|
||||||
}
|
|
||||||
|
|
||||||
ref := t.Field.Reference()
|
|
||||||
|
|
||||||
if named, ok := ref.(Named); ok {
|
|
||||||
if named.Name() != testcase.name {
|
|
||||||
failf("unexpected repository: got %q, expected %q", named.Name(), testcase.name)
|
|
||||||
}
|
|
||||||
} else if testcase.name != "" {
|
|
||||||
failf("expected named type, got %T", ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
tagged, ok := ref.(Tagged)
|
|
||||||
if testcase.tag != "" {
|
|
||||||
if ok {
|
|
||||||
if tagged.Tag() != testcase.tag {
|
|
||||||
failf("unexpected tag: got %q, expected %q", tagged.Tag(), testcase.tag)
|
|
||||||
}
|
}
|
||||||
} else {
|
if err != testcase.err {
|
||||||
failf("expected tagged type, got %T", ref)
|
t.Errorf("wrong error, expected %v, got %v", testcase.err, err)
|
||||||
}
|
|
||||||
} else if ok {
|
|
||||||
failf("unexpected tagged type")
|
|
||||||
}
|
|
||||||
|
|
||||||
digested, ok := ref.(Digested)
|
|
||||||
if testcase.digest != "" {
|
|
||||||
if ok {
|
|
||||||
if digested.Digest().String() != testcase.digest {
|
|
||||||
failf("unexpected digest: got %q, expected %q", digested.Digest().String(), testcase.digest)
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
failf("expected digested type, got %T", ref)
|
return
|
||||||
|
} else if testcase.err != nil {
|
||||||
|
t.Errorf("expected error unmarshalling: %v", testcase.err)
|
||||||
}
|
}
|
||||||
} else if ok {
|
|
||||||
failf("unexpected digested type")
|
|
||||||
}
|
|
||||||
|
|
||||||
t = serializationType{
|
if st.Description != testcase.description {
|
||||||
Description: testcase.description,
|
t.Errorf("wrong description, expected %q, got %q", testcase.description, st.Description)
|
||||||
Field: AsField(ref),
|
}
|
||||||
}
|
|
||||||
|
|
||||||
b2, err := json.Marshal(t)
|
ref := st.Field.Reference()
|
||||||
if err != nil {
|
|
||||||
failf("error marshing serialization type: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(b) != string(b2) {
|
if named, ok := ref.(Named); ok {
|
||||||
failf("unexpected serialized value: expected %q, got %q", string(b), string(b2))
|
if named.Name() != testcase.name {
|
||||||
}
|
t.Errorf("unexpected repository: got %q, expected %q", named.Name(), testcase.name)
|
||||||
|
}
|
||||||
|
} else if testcase.name != "" {
|
||||||
|
t.Errorf("expected named type, got %T", ref)
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure t.Field is not implementing "Reference" directly, getting
|
tagged, ok := ref.(Tagged)
|
||||||
// around the Reference type system
|
if testcase.tag != "" {
|
||||||
var fieldInterface interface{} = t.Field
|
if ok {
|
||||||
if _, ok := fieldInterface.(Reference); ok {
|
if tagged.Tag() != testcase.tag {
|
||||||
failf("field should not implement Reference interface")
|
t.Errorf("unexpected tag: got %q, expected %q", tagged.Tag(), testcase.tag)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("expected tagged type, got %T", ref)
|
||||||
|
}
|
||||||
|
} else if ok {
|
||||||
|
t.Errorf("unexpected tagged type")
|
||||||
|
}
|
||||||
|
|
||||||
|
digested, ok := ref.(Digested)
|
||||||
|
if testcase.digest != "" {
|
||||||
|
if ok {
|
||||||
|
if digested.Digest().String() != testcase.digest {
|
||||||
|
t.Errorf("unexpected digest: got %q, expected %q", digested.Digest().String(), testcase.digest)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("expected digested type, got %T", ref)
|
||||||
|
}
|
||||||
|
} else if ok {
|
||||||
|
t.Errorf("unexpected digested type")
|
||||||
|
}
|
||||||
|
|
||||||
|
st = serializationType{
|
||||||
|
Description: testcase.description,
|
||||||
|
Field: AsField(ref),
|
||||||
|
}
|
||||||
|
|
||||||
|
b2, err := json.Marshal(st)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error marshing serialization type: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(b) != string(b2) {
|
||||||
|
t.Errorf("unexpected serialized value: expected %q, got %q", string(b), string(b2))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure st.Field is not implementing "Reference" directly, getting
|
||||||
|
// around the Reference type system
|
||||||
|
var fieldInterface interface{} = st.Field
|
||||||
|
if _, ok := fieldInterface.(Reference); ok {
|
||||||
|
t.Errorf("field should not implement Reference interface")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithTag(t *testing.T) {
|
func TestWithTag(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
name string
|
name string
|
||||||
digest digest.Digest
|
digest digest.Digest
|
||||||
|
@ -596,34 +594,34 @@ func TestWithTag(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
failf := func(format string, v ...interface{}) {
|
testcase := testcase
|
||||||
t.Logf(strconv.Quote(testcase.name)+": "+format, v...)
|
t.Run(testcase.combined, func(t *testing.T) {
|
||||||
t.Fail()
|
t.Parallel()
|
||||||
}
|
named, err := WithName(testcase.name)
|
||||||
|
|
||||||
named, err := WithName(testcase.name)
|
|
||||||
if err != nil {
|
|
||||||
failf("error parsing name: %s", err)
|
|
||||||
}
|
|
||||||
if testcase.digest != "" {
|
|
||||||
canonical, err := WithDigest(named, testcase.digest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failf("error adding digest")
|
t.Errorf("error parsing name: %s", err)
|
||||||
|
}
|
||||||
|
if testcase.digest != "" {
|
||||||
|
canonical, err := WithDigest(named, testcase.digest)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error adding digest")
|
||||||
|
}
|
||||||
|
named = canonical
|
||||||
}
|
}
|
||||||
named = canonical
|
|
||||||
}
|
|
||||||
|
|
||||||
tagged, err := WithTag(named, testcase.tag)
|
tagged, err := WithTag(named, testcase.tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failf("WithTag failed: %s", err)
|
t.Errorf("WithTag failed: %s", err)
|
||||||
}
|
}
|
||||||
if tagged.String() != testcase.combined {
|
if tagged.String() != testcase.combined {
|
||||||
failf("unexpected: got %q, expected %q", tagged.String(), testcase.combined)
|
t.Errorf("unexpected: got %q, expected %q", tagged.String(), testcase.combined)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWithDigest(t *testing.T) {
|
func TestWithDigest(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
name string
|
name string
|
||||||
digest digest.Digest
|
digest digest.Digest
|
||||||
|
@ -653,33 +651,33 @@ func TestWithDigest(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
failf := func(format string, v ...interface{}) {
|
testcase := testcase
|
||||||
t.Logf(strconv.Quote(testcase.name)+": "+format, v...)
|
t.Run(testcase.combined, func(t *testing.T) {
|
||||||
t.Fail()
|
t.Parallel()
|
||||||
}
|
named, err := WithName(testcase.name)
|
||||||
|
|
||||||
named, err := WithName(testcase.name)
|
|
||||||
if err != nil {
|
|
||||||
failf("error parsing name: %s", err)
|
|
||||||
}
|
|
||||||
if testcase.tag != "" {
|
|
||||||
tagged, err := WithTag(named, testcase.tag)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failf("error adding tag")
|
t.Errorf("error parsing name: %s", err)
|
||||||
}
|
}
|
||||||
named = tagged
|
if testcase.tag != "" {
|
||||||
}
|
tagged, err := WithTag(named, testcase.tag)
|
||||||
digested, err := WithDigest(named, testcase.digest)
|
if err != nil {
|
||||||
if err != nil {
|
t.Errorf("error adding tag")
|
||||||
failf("WithDigest failed: %s", err)
|
}
|
||||||
}
|
named = tagged
|
||||||
if digested.String() != testcase.combined {
|
}
|
||||||
failf("unexpected: got %q, expected %q", digested.String(), testcase.combined)
|
digested, err := WithDigest(named, testcase.digest)
|
||||||
}
|
if err != nil {
|
||||||
|
t.Errorf("WithDigest failed: %s", err)
|
||||||
|
}
|
||||||
|
if digested.String() != testcase.combined {
|
||||||
|
t.Errorf("unexpected: got %q, expected %q", digested.String(), testcase.combined)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseNamed(t *testing.T) {
|
func TestParseNamed(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
input string
|
input string
|
||||||
domain string
|
domain string
|
||||||
|
@ -724,31 +722,30 @@ func TestParseNamed(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
failf := func(format string, v ...interface{}) {
|
testcase := testcase
|
||||||
t.Logf(strconv.Quote(testcase.input)+": "+format, v...)
|
t.Run(testcase.input, func(t *testing.T) {
|
||||||
t.Fail()
|
t.Parallel()
|
||||||
}
|
named, err := ParseNamed(testcase.input)
|
||||||
|
if err != nil && testcase.err == nil {
|
||||||
|
t.Errorf("error parsing name: %s", err)
|
||||||
|
return
|
||||||
|
} else if err == nil && testcase.err != nil {
|
||||||
|
t.Errorf("parsing succeeded: expected error %v", testcase.err)
|
||||||
|
return
|
||||||
|
} else if err != testcase.err {
|
||||||
|
t.Errorf("unexpected error %v, expected %v", err, testcase.err)
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
named, err := ParseNamed(testcase.input)
|
domain, name := SplitHostname(named)
|
||||||
if err != nil && testcase.err == nil {
|
if domain != testcase.domain {
|
||||||
failf("error parsing name: %s", err)
|
t.Errorf("unexpected domain: got %q, expected %q", domain, testcase.domain)
|
||||||
continue
|
}
|
||||||
} else if err == nil && testcase.err != nil {
|
if name != testcase.name {
|
||||||
failf("parsing succeeded: expected error %v", testcase.err)
|
t.Errorf("unexpected name: got %q, expected %q", name, testcase.name)
|
||||||
continue
|
}
|
||||||
} else if err != testcase.err {
|
})
|
||||||
failf("unexpected error %v, expected %v", err, testcase.err)
|
|
||||||
continue
|
|
||||||
} else if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
domain, name := SplitHostname(named)
|
|
||||||
if domain != testcase.domain {
|
|
||||||
failf("unexpected domain: got %q, expected %q", domain, testcase.domain)
|
|
||||||
}
|
|
||||||
if name != testcase.name {
|
|
||||||
failf("unexpected name: got %q, expected %q", name, testcase.name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ type regexpMatch struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkRegexp(t *testing.T, r *regexp.Regexp, m regexpMatch) {
|
func checkRegexp(t *testing.T, r *regexp.Regexp, m regexpMatch) {
|
||||||
|
t.Helper()
|
||||||
matches := r.FindStringSubmatch(m.input)
|
matches := r.FindStringSubmatch(m.input)
|
||||||
if m.match && matches != nil {
|
if m.match && matches != nil {
|
||||||
if len(matches) != (r.NumSubexp()+1) || matches[0] != m.input {
|
if len(matches) != (r.NumSubexp()+1) || matches[0] != m.input {
|
||||||
|
@ -34,7 +35,11 @@ func checkRegexp(t *testing.T, r *regexp.Regexp, m regexpMatch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDomainRegexp(t *testing.T) {
|
func TestDomainRegexp(t *testing.T) {
|
||||||
hostcases := []regexpMatch{
|
t.Parallel()
|
||||||
|
hostcases := []struct {
|
||||||
|
input string
|
||||||
|
match bool
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
input: "test.com",
|
input: "test.com",
|
||||||
match: true,
|
match: true,
|
||||||
|
@ -157,12 +162,20 @@ func TestDomainRegexp(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
r := regexp.MustCompile(`^` + DomainRegexp.String() + `$`)
|
r := regexp.MustCompile(`^` + DomainRegexp.String() + `$`)
|
||||||
for i := range hostcases {
|
for _, tc := range hostcases {
|
||||||
checkRegexp(t, r, hostcases[i])
|
tc := tc
|
||||||
|
t.Run(tc.input, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
match := r.MatchString(tc.input)
|
||||||
|
if match != tc.match {
|
||||||
|
t.Errorf("Expected match=%t, got %t", tc.match, match)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFullNameRegexp(t *testing.T) {
|
func TestFullNameRegexp(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
if anchoredNameRegexp.NumSubexp() != 2 {
|
if anchoredNameRegexp.NumSubexp() != 2 {
|
||||||
t.Fatalf("anchored name regexp should have two submatches: %v, %v != 2",
|
t.Fatalf("anchored name regexp should have two submatches: %v, %v != 2",
|
||||||
anchoredNameRegexp, anchoredNameRegexp.NumSubexp())
|
anchoredNameRegexp, anchoredNameRegexp.NumSubexp())
|
||||||
|
@ -452,12 +465,17 @@ func TestFullNameRegexp(t *testing.T) {
|
||||||
match: false,
|
match: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range testcases {
|
for _, tc := range testcases {
|
||||||
checkRegexp(t, anchoredNameRegexp, testcases[i])
|
tc := tc
|
||||||
|
t.Run(tc.input, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
checkRegexp(t, anchoredNameRegexp, tc)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReferenceRegexp(t *testing.T) {
|
func TestReferenceRegexp(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
if ReferenceRegexp.NumSubexp() != 3 {
|
if ReferenceRegexp.NumSubexp() != 3 {
|
||||||
t.Fatalf("anchored name regexp should have three submatches: %v, %v != 3",
|
t.Fatalf("anchored name regexp should have three submatches: %v, %v != 3",
|
||||||
ReferenceRegexp, ReferenceRegexp.NumSubexp())
|
ReferenceRegexp, ReferenceRegexp.NumSubexp())
|
||||||
|
@ -522,13 +540,21 @@ func TestReferenceRegexp(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range testcases {
|
for _, tc := range testcases {
|
||||||
checkRegexp(t, ReferenceRegexp, testcases[i])
|
tc := tc
|
||||||
|
t.Run(tc.input, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
checkRegexp(t, ReferenceRegexp, tc)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIdentifierRegexp(t *testing.T) {
|
func TestIdentifierRegexp(t *testing.T) {
|
||||||
fullCases := []regexpMatch{
|
t.Parallel()
|
||||||
|
fullCases := []struct {
|
||||||
|
input string
|
||||||
|
match bool
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
input: "da304e823d8ca2b9d863a3c897baeb852ba21ea9a9f1414736394ae7fcaf9821",
|
input: "da304e823d8ca2b9d863a3c897baeb852ba21ea9a9f1414736394ae7fcaf9821",
|
||||||
match: true,
|
match: true,
|
||||||
|
@ -550,7 +576,14 @@ func TestIdentifierRegexp(t *testing.T) {
|
||||||
match: false,
|
match: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range fullCases {
|
for _, tc := range fullCases {
|
||||||
checkRegexp(t, anchoredIdentifierRegexp, fullCases[i])
|
tc := tc
|
||||||
|
t.Run(tc.input, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
match := anchoredIdentifierRegexp.MatchString(tc.input)
|
||||||
|
if match != tc.match {
|
||||||
|
t.Errorf("Expected match=%t, got %t", tc.match, match)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReferenceSorting(t *testing.T) {
|
func TestReferenceSorting(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
digested := func(seed int64) string {
|
digested := func(seed int64) string {
|
||||||
b, err := io.ReadAll(io.LimitReader(rand.New(rand.NewSource(seed)), 64))
|
b, err := io.ReadAll(io.LimitReader(rand.New(rand.NewSource(seed)), 64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue