diff --git a/pkg/image/image_test.go b/pkg/image/image_test.go index f6b4bb708f..804b3bec48 100644 --- a/pkg/image/image_test.go +++ b/pkg/image/image_test.go @@ -2,6 +2,7 @@ package image import ( "sort" + "strings" "testing" "github.com/google/go-containerregistry/pkg/name" @@ -62,3 +63,73 @@ func TestParseReference_DoesNotSpecialCaseDockerInternalHost(t *testing.T) { ) } } + +func TestIsValidDockerTag(t *testing.T) { + longTag := strings.Repeat("a", DockerTagMaxSize) + overlongTag := strings.Repeat("a", DockerTagMaxSize+1) + const latestTag = "latest" + + tests := []struct { + name string + tag string + want bool + }{ + {"empty accepted as no-tag sentinel", "", true}, + {"single char", "a", true}, + {latestTag, latestTag, true}, + {"semver", "v1.0.0", true}, + {"numeric", "3.18", true}, + {"dotted and hyphenated", "ubuntu-20.04", true}, + {"underscore", "a_b", true}, + {"at max size", longTag, true}, + {"leading dot", ".latest", false}, + {"leading hyphen", "-v1", false}, + {"slash", "foo/bar", false}, + {"colon", "v1:0", false}, + {"space", "tag with space", false}, + {"at sign", "tag@2", false}, + {"non-ascii", "α", false}, + {"over max size", overlongTag, false}, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if got := IsValidDockerTag(tc.tag); got != tc.want { + t.Errorf("IsValidDockerTag(%q) = %v, want %v", tc.tag, got, tc.want) + } + }) + } +} + +func TestValidateTags(t *testing.T) { + t.Run("all valid", func(t *testing.T) { + if err := ValidateTags([]string{"latest", "v1.0.0", "3.18"}); err != nil { + t.Fatalf("unexpected error: %v", err) + } + }) + + t.Run("empty slice", func(t *testing.T) { + if err := ValidateTags(nil); err != nil { + t.Fatalf("unexpected error: %v", err) + } + }) + + t.Run("rejects invalid tag with offending value in message", func(t *testing.T) { + err := ValidateTags([]string{"latest", "foo/bar"}) + if err == nil { + t.Fatal("expected error for invalid tag, got nil") + } + if !strings.Contains(err.Error(), `"foo/bar"`) { + t.Errorf("expected error to quote the offending tag %q, got: %v", "foo/bar", err) + } + }) + + t.Run("reports first invalid tag", func(t *testing.T) { + err := ValidateTags([]string{".bad", "-also-bad"}) + if err == nil { + t.Fatal("expected error for invalid tag, got nil") + } + if !strings.Contains(err.Error(), `".bad"`) { + t.Errorf("expected first invalid tag in error, got: %v", err) + } + }) +}