terraform/internal/registry/regsrc/friendly_host_test.go

142 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package regsrc
import (
"strings"
"testing"
)
func TestFriendlyHost(t *testing.T) {
tests := []struct {
name string
source string
wantHost string
wantDisplay string
wantNorm string
wantValid bool
}{
{
name: "simple ascii",
source: "registry.terraform.io",
wantHost: "registry.terraform.io",
wantDisplay: "registry.terraform.io",
wantNorm: "registry.terraform.io",
wantValid: true,
},
{
name: "mixed-case ascii",
source: "Registry.TerraForm.io",
wantHost: "Registry.TerraForm.io",
wantDisplay: "registry.terraform.io", // Display case folded
wantNorm: "registry.terraform.io",
wantValid: true,
},
{
name: "IDN",
source: "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io",
wantHost: "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io",
wantDisplay: "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io",
wantNorm: "xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io",
wantValid: true,
},
{
name: "IDN TLD",
source: "zhongwen.中国",
wantHost: "zhongwen.中国",
wantDisplay: "zhongwen.中国",
wantNorm: "zhongwen.xn--fiqs8s",
wantValid: true,
},
{
name: "IDN Case Folding",
source: "Испытание.com",
wantHost: "Испытание.com", // Raw input retains case
wantDisplay: "испытание.com", // Display form is unicode but case-folded
wantNorm: "xn--80akhbyknj4f.com",
wantValid: true,
},
{
name: "Punycode is invalid as an input format",
source: "xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io",
wantHost: "xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io",
wantDisplay: "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io",
wantNorm: InvalidHostString,
wantValid: false,
},
{
name: "non-host prefix is left alone",
source: "foo/bar/baz",
wantHost: "",
wantDisplay: "",
wantNorm: "",
wantValid: false,
},
}
for _, tt := range tests {
// Matrix each test with prefix and total match variants
for _, sfx := range []string{"", "/", "/foo/bar/baz"} {
t.Run(tt.name+" suffix:"+sfx, func(t *testing.T) {
gotHost, gotRest := ParseFriendlyHost(tt.source + sfx)
if gotHost == nil {
if tt.wantHost != "" {
t.Fatalf("ParseFriendlyHost() gotHost = nil, want %v", tt.wantHost)
}
// If we return nil host, the whole input string should be in rest
if gotRest != (tt.source + sfx) {
t.Fatalf("ParseFriendlyHost() was nil rest = %s, want %v", gotRest, tt.source+sfx)
}
return
}
if tt.wantHost == "" {
t.Fatalf("ParseFriendlyHost() gotHost.Raw = %v, want nil", gotHost.Raw)
}
if v := gotHost.String(); v != tt.wantHost {
t.Fatalf("String() = %v, want %v", v, tt.wantHost)
}
if v := gotHost.Display(); v != tt.wantDisplay {
t.Fatalf("Display() = %v, want %v", v, tt.wantDisplay)
}
if v := gotHost.Normalized(); v != tt.wantNorm {
t.Fatalf("Normalized() = %v, want %v", v, tt.wantNorm)
}
if v := gotHost.Valid(); v != tt.wantValid {
t.Fatalf("Valid() = %v, want %v", v, tt.wantValid)
}
if gotRest != strings.TrimLeft(sfx, "/") {
t.Fatalf("ParseFriendlyHost() rest = %v, want %v", gotRest, strings.TrimLeft(sfx, "/"))
}
// Also verify that host compares equal with all the variants.
if gotHost.Valid() && !gotHost.Equal(&FriendlyHost{Raw: tt.wantDisplay}) {
t.Fatalf("Equal() should be true for %s and %s", tt.wantHost, tt.wantDisplay)
}
})
}
}
}
func TestInvalidHostEquals(t *testing.T) {
invalid := NewFriendlyHost("NOT_A_HOST_NAME")
valid := PublicRegistryHost
// invalid hosts are not comparable
if invalid.Equal(invalid) {
t.Fatal("invalid host names are not comparable")
}
if valid.Equal(invalid) {
t.Fatalf("%q is not equal to %q", valid, invalid)
}
puny := NewFriendlyHost("xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io")
display := NewFriendlyHost("ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io")
// The pre-normalized host is not a valid source, and therefore not
// comparable to the display version.
if display.Equal(puny) {
t.Fatalf("invalid host %q should not be comparable", puny)
}
}