Older versions of Go do not format these comments, so we can already
reformat them ahead of time to prevent gofmt linting failing once
we update to Go 1.19 or up.
Result of:
gofmt -s -w $(find . -type f -name '*.go' | grep -v "/vendor/")
With some manual adjusting.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 82427d1a07)
Signed-off-by: Cory Snider <csnider@mirantis.com>
397 lines
9.6 KiB
Go
397 lines
9.6 KiB
Go
package opts
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
func TestValidateIPAddress(t *testing.T) {
|
|
if ret, err := ValidateIPAddress(`1.2.3.4`); err != nil || ret == "" {
|
|
t.Fatalf("ValidateIPAddress(`1.2.3.4`) got %s %s", ret, err)
|
|
}
|
|
|
|
if ret, err := ValidateIPAddress(`127.0.0.1`); err != nil || ret == "" {
|
|
t.Fatalf("ValidateIPAddress(`127.0.0.1`) got %s %s", ret, err)
|
|
}
|
|
|
|
if ret, err := ValidateIPAddress(`::1`); err != nil || ret == "" {
|
|
t.Fatalf("ValidateIPAddress(`::1`) got %s %s", ret, err)
|
|
}
|
|
|
|
if ret, err := ValidateIPAddress(`127`); err == nil || ret != "" {
|
|
t.Fatalf("ValidateIPAddress(`127`) got %s %s", ret, err)
|
|
}
|
|
|
|
if ret, err := ValidateIPAddress(`random invalid string`); err == nil || ret != "" {
|
|
t.Fatalf("ValidateIPAddress(`random invalid string`) got %s %s", ret, err)
|
|
}
|
|
|
|
}
|
|
|
|
func TestMapOpts(t *testing.T) {
|
|
tmpMap := make(map[string]string)
|
|
o := NewMapOpts(tmpMap, logOptsValidator)
|
|
o.Set("max-size=1")
|
|
if o.String() != "map[max-size:1]" {
|
|
t.Errorf("%s != [map[max-size:1]", o.String())
|
|
}
|
|
|
|
o.Set("max-file=2")
|
|
if len(tmpMap) != 2 {
|
|
t.Errorf("map length %d != 2", len(tmpMap))
|
|
}
|
|
|
|
if tmpMap["max-file"] != "2" {
|
|
t.Errorf("max-file = %s != 2", tmpMap["max-file"])
|
|
}
|
|
|
|
if tmpMap["max-size"] != "1" {
|
|
t.Errorf("max-size = %s != 1", tmpMap["max-size"])
|
|
}
|
|
if o.Set("dummy-val=3") == nil {
|
|
t.Error("validator is not being called")
|
|
}
|
|
}
|
|
|
|
func TestListOptsWithoutValidator(t *testing.T) {
|
|
o := NewListOpts(nil)
|
|
o.Set("foo")
|
|
if o.String() != "[foo]" {
|
|
t.Errorf("%s != [foo]", o.String())
|
|
}
|
|
o.Set("bar")
|
|
if o.Len() != 2 {
|
|
t.Errorf("%d != 2", o.Len())
|
|
}
|
|
o.Set("bar")
|
|
if o.Len() != 3 {
|
|
t.Errorf("%d != 3", o.Len())
|
|
}
|
|
if !o.Get("bar") {
|
|
t.Error("o.Get(\"bar\") == false")
|
|
}
|
|
if o.Get("baz") {
|
|
t.Error("o.Get(\"baz\") == true")
|
|
}
|
|
o.Delete("foo")
|
|
if o.String() != "[bar bar]" {
|
|
t.Errorf("%s != [bar bar]", o.String())
|
|
}
|
|
listOpts := o.GetAll()
|
|
if len(listOpts) != 2 || listOpts[0] != "bar" || listOpts[1] != "bar" {
|
|
t.Errorf("Expected [[bar bar]], got [%v]", listOpts)
|
|
}
|
|
mapListOpts := o.GetMap()
|
|
if len(mapListOpts) != 1 {
|
|
t.Errorf("Expected [map[bar:{}]], got [%v]", mapListOpts)
|
|
}
|
|
|
|
}
|
|
|
|
func TestListOptsWithValidator(t *testing.T) {
|
|
// Re-using logOptsvalidator (used by MapOpts)
|
|
o := NewListOpts(logOptsValidator)
|
|
o.Set("foo")
|
|
if o.String() != "" {
|
|
t.Errorf(`%s != ""`, o.String())
|
|
}
|
|
o.Set("foo=bar")
|
|
if o.String() != "" {
|
|
t.Errorf(`%s != ""`, o.String())
|
|
}
|
|
o.Set("max-file=2")
|
|
if o.Len() != 1 {
|
|
t.Errorf("%d != 1", o.Len())
|
|
}
|
|
if !o.Get("max-file=2") {
|
|
t.Error("o.Get(\"max-file=2\") == false")
|
|
}
|
|
if o.Get("baz") {
|
|
t.Error("o.Get(\"baz\") == true")
|
|
}
|
|
o.Delete("max-file=2")
|
|
if o.String() != "" {
|
|
t.Errorf(`%s != ""`, o.String())
|
|
}
|
|
}
|
|
|
|
//nolint:lll
|
|
func TestValidateDNSSearch(t *testing.T) {
|
|
valid := []string{
|
|
`.`,
|
|
`a`,
|
|
`a.`,
|
|
`1.foo`,
|
|
`17.foo`,
|
|
`foo.bar`,
|
|
`foo.bar.baz`,
|
|
`foo.bar.`,
|
|
`foo.bar.baz`,
|
|
`foo1.bar2`,
|
|
`foo1.bar2.baz`,
|
|
`1foo.2bar.`,
|
|
`1foo.2bar.baz`,
|
|
`foo-1.bar-2`,
|
|
`foo-1.bar-2.baz`,
|
|
`foo-1.bar-2.`,
|
|
`foo-1.bar-2.baz`,
|
|
`1-foo.2-bar`,
|
|
`1-foo.2-bar.baz`,
|
|
`1-foo.2-bar.`,
|
|
`1-foo.2-bar.baz`,
|
|
}
|
|
|
|
invalid := []string{
|
|
``,
|
|
` `,
|
|
` `,
|
|
`17`,
|
|
`17.`,
|
|
`.17`,
|
|
`17-.`,
|
|
`17-.foo`,
|
|
`.foo`,
|
|
`foo-.bar`,
|
|
`-foo.bar`,
|
|
`foo.bar-`,
|
|
`foo.bar-.baz`,
|
|
`foo.-bar`,
|
|
`foo.-bar.baz`,
|
|
`foo.bar.baz.this.should.fail.on.long.name.because.it.is.longer.thanisshouldbethis.should.fail.on.long.name.because.it.is.longer.thanisshouldbethis.should.fail.on.long.name.because.it.is.longer.thanisshouldbethis.should.fail.on.long.name.because.it.is.longer.thanisshouldbe`,
|
|
}
|
|
|
|
for _, domain := range valid {
|
|
if ret, err := ValidateDNSSearch(domain); err != nil || ret == "" {
|
|
t.Fatalf("ValidateDNSSearch(`"+domain+"`) got %s %s", ret, err)
|
|
}
|
|
}
|
|
|
|
for _, domain := range invalid {
|
|
if ret, err := ValidateDNSSearch(domain); err == nil || ret != "" {
|
|
t.Fatalf("ValidateDNSSearch(`"+domain+"`) got %s %s", ret, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateLabel(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
value string
|
|
expectedErr string
|
|
}{
|
|
{
|
|
name: "empty",
|
|
expectedErr: `invalid label '': empty name`,
|
|
},
|
|
{
|
|
name: "whitespace only ",
|
|
value: " ",
|
|
expectedErr: `invalid label ' ': empty name`,
|
|
},
|
|
{
|
|
name: "whitespace around equal-sign",
|
|
value: " = ",
|
|
expectedErr: `invalid label ' = ': empty name`,
|
|
},
|
|
{
|
|
name: "leading whitespace",
|
|
value: " label=value",
|
|
},
|
|
{
|
|
name: "whitespaces in key without value",
|
|
value: "this is a label without value",
|
|
expectedErr: `label 'this is a label without value' contains whitespaces`,
|
|
},
|
|
{
|
|
name: "whitespaces in key",
|
|
value: "this is a label=value",
|
|
expectedErr: `label 'this is a label' contains whitespaces`,
|
|
},
|
|
{
|
|
name: "whitespaces in value",
|
|
value: "label=a value that has whitespace",
|
|
},
|
|
{
|
|
name: "trailing whitespace in value",
|
|
value: "label=value ",
|
|
},
|
|
{
|
|
name: "leading whitespace in value",
|
|
value: "label= value",
|
|
},
|
|
{
|
|
name: "no value",
|
|
value: "label",
|
|
},
|
|
{
|
|
name: "no key",
|
|
value: "=label",
|
|
expectedErr: `invalid label '=label': empty name`,
|
|
},
|
|
{
|
|
name: "empty value",
|
|
value: "label=",
|
|
},
|
|
{
|
|
name: "key value",
|
|
value: "key1=value1",
|
|
},
|
|
{
|
|
name: "double equal-signs",
|
|
value: "key1=value1=value2",
|
|
},
|
|
{
|
|
name: "multiple equal-signs",
|
|
value: "key1=value1=value2=value",
|
|
},
|
|
{
|
|
name: "double quotes in key and value",
|
|
value: `key"with"quotes={"hello"}`,
|
|
},
|
|
{
|
|
name: "double quotes around key and value",
|
|
value: `"quoted-label"="quoted value"`,
|
|
},
|
|
{
|
|
name: "single quotes in key and value",
|
|
value: `key'with'quotes=hello'with'quotes`,
|
|
},
|
|
{
|
|
name: "single quotes around key and value",
|
|
value: `'quoted-label'='quoted value''`,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
val, err := ValidateLabel(tc.value)
|
|
if tc.expectedErr != "" {
|
|
assert.Error(t, err, tc.expectedErr)
|
|
return
|
|
}
|
|
assert.NilError(t, err)
|
|
assert.Equal(t, val, tc.value)
|
|
})
|
|
}
|
|
}
|
|
|
|
func logOptsValidator(val string) (string, error) {
|
|
allowedKeys := map[string]string{"max-size": "1", "max-file": "2"}
|
|
vals := strings.Split(val, "=")
|
|
if allowedKeys[vals[0]] != "" {
|
|
return val, nil
|
|
}
|
|
return "", fmt.Errorf("invalid key %s", vals[0])
|
|
}
|
|
|
|
func TestNamedListOpts(t *testing.T) {
|
|
var v []string
|
|
o := NewNamedListOptsRef("foo-name", &v, nil)
|
|
|
|
o.Set("foo")
|
|
if o.String() != "[foo]" {
|
|
t.Errorf("%s != [foo]", o.String())
|
|
}
|
|
if o.Name() != "foo-name" {
|
|
t.Errorf("%s != foo-name", o.Name())
|
|
}
|
|
if len(v) != 1 {
|
|
t.Errorf("expected foo to be in the values, got %v", v)
|
|
}
|
|
}
|
|
|
|
func TestNamedMapOpts(t *testing.T) {
|
|
tmpMap := make(map[string]string)
|
|
o := NewNamedMapOpts("max-name", tmpMap, nil)
|
|
|
|
o.Set("max-size=1")
|
|
if o.String() != "map[max-size:1]" {
|
|
t.Errorf("%s != [map[max-size:1]", o.String())
|
|
}
|
|
if o.Name() != "max-name" {
|
|
t.Errorf("%s != max-name", o.Name())
|
|
}
|
|
if _, exist := tmpMap["max-size"]; !exist {
|
|
t.Errorf("expected map-size to be in the values, got %v", tmpMap)
|
|
}
|
|
}
|
|
|
|
func TestValidateMACAddress(t *testing.T) {
|
|
if _, err := ValidateMACAddress(`92:d0:c6:0a:29:33`); err != nil {
|
|
t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:29:33`) got %s", err)
|
|
}
|
|
|
|
if _, err := ValidateMACAddress(`92:d0:c6:0a:33`); err == nil {
|
|
t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:33`) succeeded; expected failure on invalid MAC")
|
|
}
|
|
|
|
if _, err := ValidateMACAddress(`random invalid string`); err == nil {
|
|
t.Fatalf("ValidateMACAddress(`random invalid string`) succeeded; expected failure on invalid MAC")
|
|
}
|
|
}
|
|
|
|
func TestValidateLink(t *testing.T) {
|
|
valid := []string{
|
|
"name",
|
|
"dcdfbe62ecd0:alias",
|
|
"7a67485460b7642516a4ad82ecefe7f57d0c4916f530561b71a50a3f9c4e33da",
|
|
"angry_torvalds:linus",
|
|
}
|
|
invalid := map[string]string{
|
|
"": "empty string specified for links",
|
|
"too:much:of:it": "bad format for links: too:much:of:it",
|
|
}
|
|
|
|
for _, link := range valid {
|
|
if _, err := ValidateLink(link); err != nil {
|
|
t.Fatalf("ValidateLink(`%q`) should succeed: error %q", link, err)
|
|
}
|
|
}
|
|
|
|
for link, expectedError := range invalid {
|
|
if _, err := ValidateLink(link); err == nil {
|
|
t.Fatalf("ValidateLink(`%q`) should have failed validation", link)
|
|
} else {
|
|
if !strings.Contains(err.Error(), expectedError) {
|
|
t.Fatalf("ValidateLink(`%q`) error should contain %q", link, expectedError)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseLink(t *testing.T) {
|
|
name, alias, err := ParseLink("name:alias")
|
|
if err != nil {
|
|
t.Fatalf("Expected not to error out on a valid name:alias format but got: %v", err)
|
|
}
|
|
if name != "name" {
|
|
t.Fatalf("Link name should have been name, got %s instead", name)
|
|
}
|
|
if alias != "alias" {
|
|
t.Fatalf("Link alias should have been alias, got %s instead", alias)
|
|
}
|
|
// short format definition
|
|
name, alias, err = ParseLink("name")
|
|
if err != nil {
|
|
t.Fatalf("Expected not to error out on a valid name only format but got: %v", err)
|
|
}
|
|
if name != "name" {
|
|
t.Fatalf("Link name should have been name, got %s instead", name)
|
|
}
|
|
if alias != "name" {
|
|
t.Fatalf("Link alias should have been name, got %s instead", alias)
|
|
}
|
|
// empty string link definition is not allowed
|
|
if _, _, err := ParseLink(""); err == nil || !strings.Contains(err.Error(), "empty string specified for links") {
|
|
t.Fatalf("Expected error 'empty string specified for links' but got: %v", err)
|
|
}
|
|
// more than two colons are not allowed
|
|
if _, _, err := ParseLink("link:alias:wrong"); err == nil || !strings.Contains(err.Error(), "bad format for links: link:alias:wrong") {
|
|
t.Fatalf("Expected error 'bad format for links: link:alias:wrong' but got: %v", err)
|
|
}
|
|
}
|