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