diff --git a/pkg/events/events_test.go b/pkg/events/events_test.go index 6c587b2da1a8..0642c4a6fbd4 100644 --- a/pkg/events/events_test.go +++ b/pkg/events/events_test.go @@ -4,7 +4,8 @@ import ( "testing" "time" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type TestEvent struct { @@ -12,13 +13,12 @@ type TestEvent struct { } func TestEventCreation(t *testing.T) { - Convey("Event to wire event", t, func() { - e := TestEvent{ - Timestamp: time.Unix(1231421123, 223), - } + e := TestEvent{ + Timestamp: time.Unix(1231421123, 223), + } - wire, _ := ToOnWriteEvent(&e) - So(e.Timestamp.Unix(), ShouldEqual, wire.Timestamp.Unix()) - So(wire.EventType, ShouldEqual, "TestEvent") - }) + wire, err := ToOnWriteEvent(&e) + require.NoError(t, err) + assert.Equal(t, e.Timestamp.Unix(), wire.Timestamp.Unix()) + assert.Equal(t, "TestEvent", wire.EventType) } diff --git a/pkg/util/encoding_test.go b/pkg/util/encoding_test.go index dc1ba07965f1..b7e0d2616b08 100644 --- a/pkg/util/encoding_test.go +++ b/pkg/util/encoding_test.go @@ -3,28 +3,32 @@ package util import ( "testing" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -func TestEncoding(t *testing.T) { - Convey("When generating base64 header", t, func() { +func TestGetBasicAuthHeader_Encoding(t *testing.T) { + t.Run("generating base64 header", func(t *testing.T) { result := GetBasicAuthHeader("grafana", "1234") - - So(result, ShouldEqual, "Basic Z3JhZmFuYToxMjM0") + assert.Equal(t, "Basic Z3JhZmFuYToxMjM0", result) }) - Convey("When decoding basic auth header", t, func() { + t.Run("decoding basic auth header", func(t *testing.T) { header := GetBasicAuthHeader("grafana", "1234") username, password, err := DecodeBasicAuthHeader(header) - So(err, ShouldBeNil) + require.NoError(t, err) - So(username, ShouldEqual, "grafana") - So(password, ShouldEqual, "1234") + assert.Equal(t, "grafana", username) + assert.Equal(t, "1234", password) }) +} - Convey("When encoding password", t, func() { - encodedPassword, err := EncodePassword("iamgod", "pepper") - So(err, ShouldBeNil) - So(encodedPassword, ShouldEqual, "e59c568621e57756495a468f47c74e07c911b037084dd464bb2ed72410970dc849cabd71b48c394faf08a5405dae53741ce9") - }) +func TestEncodePassword(t *testing.T) { + encodedPassword, err := EncodePassword("iamgod", "pepper") + require.NoError(t, err) + assert.Equal( + t, + "e59c568621e57756495a468f47c74e07c911b037084dd464bb2ed72410970dc849cabd71b48c394faf08a5405dae53741ce9", + encodedPassword, + ) } diff --git a/pkg/util/encryption_test.go b/pkg/util/encryption_test.go index 59919de8e542..2d8ee534c7ab 100644 --- a/pkg/util/encryption_test.go +++ b/pkg/util/encryption_test.go @@ -3,26 +3,28 @@ package util import ( "testing" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestEncryption(t *testing.T) { - Convey("When getting encryption key", t, func() { + t.Run("getting encryption key", func(t *testing.T) { key, err := encryptionKeyToBytes("secret", "salt") - So(err, ShouldBeNil) - So(len(key), ShouldEqual, 32) + require.NoError(t, err) + assert.Len(t, key, 32) key, err = encryptionKeyToBytes("a very long secret key that is larger then 32bytes", "salt") - So(err, ShouldBeNil) - So(len(key), ShouldEqual, 32) + require.NoError(t, err) + assert.Len(t, key, 32) }) - Convey("When decrypting basic payload", t, func() { - encrypted, encryptErr := Encrypt([]byte("grafana"), "1234") - decrypted, decryptErr := Decrypt(encrypted, "1234") + t.Run("decrypting basic payload", func(t *testing.T) { + encrypted, err := Encrypt([]byte("grafana"), "1234") + require.NoError(t, err) - So(encryptErr, ShouldBeNil) - So(decryptErr, ShouldBeNil) - So(string(decrypted), ShouldEqual, "grafana") + decrypted, err := Decrypt(encrypted, "1234") + require.NoError(t, err) + + assert.Equal(t, []byte("grafana"), decrypted) }) } diff --git a/pkg/util/ip_address_test.go b/pkg/util/ip_address_test.go index 3d0660ecf3dc..247797bb395c 100644 --- a/pkg/util/ip_address_test.go +++ b/pkg/util/ip_address_test.go @@ -1,135 +1,100 @@ package util import ( - "fmt" "testing" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -func TestParseIPAddress(t *testing.T) { - Convey("Test parse ip address", t, func() { - addr, err := ParseIPAddress("192.168.0.140:456") - So(err, ShouldBeNil) - So(addr, ShouldEqual, "192.168.0.140") - - addr, err = ParseIPAddress("192.168.0.140") - So(err, ShouldBeNil) - So(addr, ShouldEqual, "192.168.0.140") - - addr, err = ParseIPAddress("[::1]:456") - So(err, ShouldBeNil) - So(addr, ShouldEqual, "::1") - - addr, err = ParseIPAddress("[::1]") - So(err, ShouldBeNil) - So(addr, ShouldEqual, "::1") - }) - - Convey("Invalid address", t, func() { - _, err := ParseIPAddress("[::1") - So(err, ShouldBeError, fmt.Errorf( - `failed to split network address "[::1" by host and port: Malformed IPv6 address: '[::1'`)) - - _, err = ParseIPAddress("::1]") - So(err, ShouldBeError, fmt.Errorf( - `failed to split network address "::1]" by host and port: net.SplitHostPort failed for '::1]': address ::1]: too many colons in address`)) - - _, err = ParseIPAddress("") - So(err, ShouldBeError, fmt.Errorf( - `failed to split network address "" by host and port: Input is empty`)) - }) - - Convey("Loopback address", t, func() { - addr, err := ParseIPAddress("127.0.0.1") - So(err, ShouldBeNil) - So(addr, ShouldEqual, "127.0.0.1") - - addr, err = ParseIPAddress("[::1]") - So(err, ShouldBeNil) - So(addr, ShouldEqual, "::1") - }) +func TestParseIPAddress_Valid(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {input: "127.0.0.1", expected: "127.0.0.1"}, + {input: "192.168.0.140:456", expected: "192.168.0.140"}, + {input: "192.168.0.140", expected: "192.168.0.140"}, + {input: "[::1]:456", expected: "::1"}, + {input: "[::1]", expected: "::1"}, + } + for _, testcase := range tests { + addr, err := ParseIPAddress(testcase.input) + require.NoError(t, err) + assert.Equal(t, testcase.expected, addr) + } } -func TestSplitHostPortDefault(t *testing.T) { - Convey("Test split ip address to host and port", t, func() { - addr, err := SplitHostPortDefault("192.168.0.140:456", "", "") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "192.168.0.140") - So(addr.Port, ShouldEqual, "456") - - addr, err = SplitHostPortDefault("192.168.0.140", "", "123") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "192.168.0.140") - So(addr.Port, ShouldEqual, "123") - - addr, err = SplitHostPortDefault("[::1]:456", "", "") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "::1") - So(addr.Port, ShouldEqual, "456") - - addr, err = SplitHostPortDefault("[::1]", "", "123") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "::1") - So(addr.Port, ShouldEqual, "123") - - addr, err = SplitHostPortDefault(":456", "1.2.3.4", "") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "1.2.3.4") - So(addr.Port, ShouldEqual, "456") - - addr, err = SplitHostPortDefault("xyz.rds.amazonaws.com", "", "123") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "xyz.rds.amazonaws.com") - So(addr.Port, ShouldEqual, "123") - - addr, err = SplitHostPortDefault("xyz.rds.amazonaws.com:123", "", "") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "xyz.rds.amazonaws.com") - So(addr.Port, ShouldEqual, "123") - - addr, err = SplitHostPortDefault("", "localhost", "1433") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "localhost") - So(addr.Port, ShouldEqual, "1433") - }) +func TestParseIPAddress_Invalid(t *testing.T) { + tests := []struct { + input string + err string + }{ + { + input: "[::1", + err: "failed to split network address \"[::1\" by host and port: Malformed IPv6 address: '[::1'", + }, + { + input: "::1]", + err: "failed to split network address \"::1]\" by host and port: net.SplitHostPort failed for '::1]': address ::1]: too many colons in address", + }, + { + input: "", + err: "failed to split network address \"\" by host and port: Input is empty", + }, + } + for _, testcase := range tests { + addr, err := ParseIPAddress(testcase.input) + assert.EqualError(t, err, testcase.err) + assert.Empty(t, addr) + } } -func TestSplitHostPort(t *testing.T) { - Convey("Test split ip address to host and port", t, func() { - addr, err := SplitHostPort("192.168.0.140:456") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "192.168.0.140") - So(addr.Port, ShouldEqual, "456") - - addr, err = SplitHostPort("192.168.0.140") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "192.168.0.140") - So(addr.Port, ShouldEqual, "") - - addr, err = SplitHostPort("[::1]:456") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "::1") - So(addr.Port, ShouldEqual, "456") - - addr, err = SplitHostPort("[::1]") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "::1") - So(addr.Port, ShouldEqual, "") - - addr, err = SplitHostPort(":456") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "") - So(addr.Port, ShouldEqual, "456") - - addr, err = SplitHostPort("xyz.rds.amazonaws.com") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "xyz.rds.amazonaws.com") - So(addr.Port, ShouldEqual, "") +func TestSplitHostPortDefault_Valid(t *testing.T) { + tests := []struct { + input string + defaultHost string + defaultPort string + + host string + port string + }{ + {input: "192.168.0.140:456", defaultHost: "", defaultPort: "", host: "192.168.0.140", port: "456"}, + {input: "192.168.0.140", defaultHost: "", defaultPort: "123", host: "192.168.0.140", port: "123"}, + {input: "[::1]:456", defaultHost: "", defaultPort: "", host: "::1", port: "456"}, + {input: "[::1]", defaultHost: "", defaultPort: "123", host: "::1", port: "123"}, + {input: ":456", defaultHost: "1.2.3.4", defaultPort: "", host: "1.2.3.4", port: "456"}, + {input: "xyz.rds.amazonaws.com", defaultHost: "", defaultPort: "123", host: "xyz.rds.amazonaws.com", port: "123"}, + {input: "xyz.rds.amazonaws.com:123", defaultHost: "", defaultPort: "", host: "xyz.rds.amazonaws.com", port: "123"}, + {input: "", defaultHost: "localhost", defaultPort: "1433", host: "localhost", port: "1433"}, + } + + for _, testcase := range tests { + addr, err := SplitHostPortDefault(testcase.input, testcase.defaultHost, testcase.defaultPort) + assert.NoError(t, err) + assert.Equal(t, testcase.host, addr.Host) + assert.Equal(t, testcase.port, addr.Port) + } +} - addr, err = SplitHostPort("xyz.rds.amazonaws.com:123") - So(err, ShouldBeNil) - So(addr.Host, ShouldEqual, "xyz.rds.amazonaws.com") - So(addr.Port, ShouldEqual, "123") - }) +func TestSplitHostPort_Valid(t *testing.T) { + tests := []struct { + input string + host string + port string + }{ + {input: "192.168.0.140:456", host: "192.168.0.140", port: "456"}, + {input: "192.168.0.140", host: "192.168.0.140", port: ""}, + {input: "[::1]:456", host: "::1", port: "456"}, + {input: "[::1]", host: "::1", port: ""}, + {input: ":456", host: "", port: "456"}, + {input: "xyz.rds.amazonaws.com", host: "xyz.rds.amazonaws.com", port: ""}, + {input: "xyz.rds.amazonaws.com:123", host: "xyz.rds.amazonaws.com", port: "123"}, + } + for _, testcase := range tests { + addr, err := SplitHostPort(testcase.input) + require.NoError(t, err) + assert.Equal(t, testcase.host, addr.Host) + assert.Equal(t, testcase.port, addr.Port) + } } diff --git a/pkg/util/strings_test.go b/pkg/util/strings_test.go index 4bc52ee75217..0187a37bc639 100644 --- a/pkg/util/strings_test.go +++ b/pkg/util/strings_test.go @@ -4,45 +4,92 @@ import ( "testing" "time" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" ) -func TestStringsUtil(t *testing.T) { - Convey("Falling back until none empty string", t, func() { - So(StringsFallback2("1", "2"), ShouldEqual, "1") - So(StringsFallback2("", "2"), ShouldEqual, "2") - So(StringsFallback3("", "", "3"), ShouldEqual, "3") - }) +func TestStringsFallback2(t *testing.T) { + tests := []struct { + val1 string + val2 string + expected string + }{ + // testing every scenario + {"", "", ""}, + {"1", "", "1"}, + {"1", "2", "1"}, + {"", "2", "2"}, + } + for _, testcase := range tests { + assert.EqualValues(t, testcase.expected, StringsFallback2(testcase.val1, testcase.val2)) + } +} + +func TestStringsFallback3(t *testing.T) { + tests := []struct { + val1 string + val2 string + val3 string + expected string + }{ + {"", "", "", ""}, + {"1", "", "", "1"}, + {"1", "2", "", "1"}, + {"1", "2", "3", "1"}, + {"", "2", "", "2"}, + {"", "2", "3", "2"}, + {"", "", "3", "3"}, + } + for _, testcase := range tests { + assert.EqualValues(t, testcase.expected, StringsFallback3(testcase.val1, testcase.val2, testcase.val3)) + } } func TestSplitString(t *testing.T) { - Convey("Splits strings correctly", t, func() { - So(SplitString(""), ShouldResemble, []string{}) - So(SplitString("test"), ShouldResemble, []string{"test"}) - So(SplitString("test1 test2 test3"), ShouldResemble, []string{"test1", "test2", "test3"}) - So(SplitString("test1,test2,test3"), ShouldResemble, []string{"test1", "test2", "test3"}) - So(SplitString("test1, test2, test3"), ShouldResemble, []string{"test1", "test2", "test3"}) - So(SplitString("test1 , test2 test3"), ShouldResemble, []string{"test1", "test2", "test3"}) - }) + tests := map[string][]string{ + "": {}, + "test": {"test"}, + "test1 test2 test3": {"test1", "test2", "test3"}, + "test1,test2,test3": {"test1", "test2", "test3"}, + "test1, test2, test3": {"test1", "test2", "test3"}, + "test1 , test2 test3": {"test1", "test2", "test3"}, + } + for input, expected := range tests { + assert.EqualValues(t, expected, SplitString(input)) + } } func TestDateAge(t *testing.T) { - Convey("GetAgeString", t, func() { - So(GetAgeString(time.Time{}), ShouldEqual, "?") - So(GetAgeString(time.Now().Add(-time.Second*2)), ShouldEqual, "< 1m") - So(GetAgeString(time.Now().Add(-time.Minute*2)), ShouldEqual, "2m") - So(GetAgeString(time.Now().Add(-time.Hour*2)), ShouldEqual, "2h") - So(GetAgeString(time.Now().Add(-time.Hour*24*3)), ShouldEqual, "3d") - So(GetAgeString(time.Now().Add(-time.Hour*24*67)), ShouldEqual, "2M") - So(GetAgeString(time.Now().Add(-time.Hour*24*409)), ShouldEqual, "1y") - }) + assert.Equal(t, "?", GetAgeString(time.Time{})) // base case + + tests := map[time.Duration]string{ + -1 * time.Hour: "< 1m", // one hour in the future + 0: "< 1m", + 2 * time.Second: "< 1m", + 2 * time.Minute: "2m", + 2 * time.Hour: "2h", + 3 * 24 * time.Hour: "3d", + 67 * 24 * time.Hour: "2M", + 409 * 24 * time.Hour: "1y", + } + for elapsed, expected := range tests { + assert.Equalf( + t, + expected, + GetAgeString(time.Now().Add(-elapsed)), + "duration '%s'", + elapsed.String(), + ) + } } func TestToCamelCase(t *testing.T) { - Convey("ToCamelCase", t, func() { - So(ToCamelCase("kebab-case-string"), ShouldEqual, "kebabCaseString") - So(ToCamelCase("snake_case_string"), ShouldEqual, "snakeCaseString") - So(ToCamelCase("mixed-case_string"), ShouldEqual, "mixedCaseString") - So(ToCamelCase("alreadyCamelCase"), ShouldEqual, "alreadyCamelCase") - }) + tests := map[string]string{ + "kebab-case-string": "kebabCaseString", + "snake_case_string": "snakeCaseString", + "mixed-case_string": "mixedCaseString", + "alreadyCamelCase": "alreadyCamelCase", + } + for input, expected := range tests { + assert.Equal(t, expected, ToCamelCase(input)) + } } diff --git a/pkg/util/url_test.go b/pkg/util/url_test.go index 7602d0badb28..4c5e7134aa3b 100644 --- a/pkg/util/url_test.go +++ b/pkg/util/url_test.go @@ -4,69 +4,78 @@ import ( "net/url" "testing" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -func TestUrl(t *testing.T) { - Convey("When joining two urls where right hand side is empty", t, func() { - result := JoinURLFragments("http://localhost:8080", "") - - So(result, ShouldEqual, "http://localhost:8080") - }) - - Convey("When joining two urls where right hand side is empty and lefthand side has a trailing slash", t, func() { - result := JoinURLFragments("http://localhost:8080/", "") - - So(result, ShouldEqual, "http://localhost:8080/") - }) - - Convey("When joining two urls where neither has a trailing slash", t, func() { - result := JoinURLFragments("http://localhost:8080", "api") - - So(result, ShouldEqual, "http://localhost:8080/api") - }) - - Convey("When joining two urls where lefthand side has a trailing slash", t, func() { - result := JoinURLFragments("http://localhost:8080/", "api") - - So(result, ShouldEqual, "http://localhost:8080/api") - }) - - Convey("When joining two urls where righthand side has preceding slash", t, func() { - result := JoinURLFragments("http://localhost:8080", "/api") - - So(result, ShouldEqual, "http://localhost:8080/api") - }) - - Convey("When joining two urls where righthand side has trailing slash", t, func() { - result := JoinURLFragments("http://localhost:8080", "api/") - - So(result, ShouldEqual, "http://localhost:8080/api/") - }) - - Convey("When joining two urls where lefthand side has a trailing slash and righthand side has preceding slash", t, func() { - result := JoinURLFragments("http://localhost:8080/", "/api/") - - So(result, ShouldEqual, "http://localhost:8080/api/") - }) +func TestJoinURLFragments(t *testing.T) { + t.Parallel() + + tests := []struct { + description string + base string + path string + expected string + }{ + { + description: "RHS is empty", + base: "http://localhost:8080", + path: "", + expected: "http://localhost:8080", + }, + { + description: "RHS is empty and LHS has trailing slash", + base: "http://localhost:8080/", + path: "", + expected: "http://localhost:8080/", + }, + { + description: "neither has trailing slash", + base: "http://localhost:8080", + path: "api", + expected: "http://localhost:8080/api", + }, + { + description: "LHS has trailing slash", + base: "http://localhost:8080/", + path: "api", + expected: "http://localhost:8080/api", + }, + { + description: "LHS and RHS has trailing slash", + base: "http://localhost:8080/", + path: "api/", + expected: "http://localhost:8080/api/", + }, + { + description: "LHS has trailing slash and RHS has preceding slash", + base: "http://localhost:8080/", + path: "/api/", + expected: "http://localhost:8080/api/", + }, + } + for _, testcase := range tests { + t.Run("where "+testcase.description, func(t *testing.T) { + assert.Equalf( + t, + testcase.expected, + JoinURLFragments(testcase.base, testcase.path), + "base: '%s', path: '%s'", + testcase.base, + testcase.path, + ) + }) + } } func TestNewURLQueryReader(t *testing.T) { - u, _ := url.Parse("http://www.abc.com/foo?bar=baz&bar2=baz2") - uqr, _ := NewURLQueryReader(u) - - Convey("when trying to retrieve the first query value", t, func() { - result := uqr.Get("bar", "foodef") - So(result, ShouldEqual, "baz") - }) + u, err := url.Parse("http://www.abc.com/foo?bar=baz&bar2=baz2") + require.NoError(t, err) - Convey("when trying to retrieve the second query value", t, func() { - result := uqr.Get("bar2", "foodef") - So(result, ShouldEqual, "baz2") - }) + uqr, err := NewURLQueryReader(u) + require.NoError(t, err) - Convey("when trying to retrieve from a non-existent key, the default value is returned", t, func() { - result := uqr.Get("bar3", "foodef") - So(result, ShouldEqual, "foodef") - }) + assert.Equal(t, "baz", uqr.Get("bar", "foodef"), "first param") + assert.Equal(t, "baz2", uqr.Get("bar2", "foodef"), "second param") + assert.Equal(t, "foodef", uqr.Get("bar3", "foodef"), "non-existing param, use fallback") } diff --git a/pkg/util/validation_test.go b/pkg/util/validation_test.go index dfd5fa12148b..165364e766c4 100644 --- a/pkg/util/validation_test.go +++ b/pkg/util/validation_test.go @@ -1,21 +1,38 @@ package util import ( + "fmt" "testing" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" ) func TestIsEmail(t *testing.T) { - Convey("When validating a string that is a valid email", t, func() { - result := IsEmail("abc@def.com") + t.Parallel() - So(result, ShouldEqual, true) - }) + emails := map[string]struct { + description string + valid bool + }{ + "": {description: "the empty string", valid: false}, + "@.": {description: "at dot", valid: false}, + "me@": {description: "no domain", valid: false}, + "abcdef.com": {description: "only a domain name", valid: false}, + "@example.org": {description: "no recipient", valid: false}, + "please\x0Ano@example.org": {description: "new line", valid: false}, - Convey("When validating a string that is not a valid email", t, func() { - result := IsEmail("abcdef.com") + "abc@def.com": {description: "a simple valid email", valid: true}, + "grapher+grafana@example.org": {description: "a gmail style alias", valid: true}, + "öhnej@example.se": {description: "non-ASCII characters", valid: true}, + } + for input, testcase := range emails { + validity := "invalid" + if testcase.valid { + validity = "valid" + } - So(result, ShouldEqual, false) - }) + t.Run(fmt.Sprintf("validating that %s is %s", testcase.description, validity), func(t *testing.T) { + assert.Equal(t, testcase.valid, IsEmail(input)) + }) + } }