From f01427daeb5574027d6f3c183f6ba0baef6f0764 Mon Sep 17 00:00:00 2001 From: Clete Blackwell II Date: Mon, 1 Nov 2021 11:27:45 -0400 Subject: [PATCH] Table testing to simplify tests --- go.mod | 4 +- go.sum | 25 +++++++++---- hey.go | 58 +++++++++++++++++++++++++++++ hey_test.go | 84 ++++++++++++++++++++++++++++++++++++++++++ requester/requester.go | 6 +++ 5 files changed, 168 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index fe8ca313..4c1aeba6 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/rakyll/hey require ( - golang.org/x/net v0.0.0-20191009170851-d66e71096ffb - golang.org/x/text v0.3.2 // indirect + github.com/stretchr/testify v1.7.0 + golang.org/x/net v0.0.0-20211030010942-bd5b1b8b281b ) go 1.13 diff --git a/go.sum b/go.sum index 19103d98..5572c820 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,19 @@ -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20191009170851-d66e71096ffb h1:TR699M2v0qoKTOHxeLgp6zPqaQNs74f01a/ob9W0qko= -golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/net v0.0.0-20211030010942-bd5b1b8b281b h1:8hX5oXUZu8QO6u5JPUnaj1QcEj8g+m2lGO3kAIaH1tw= +golang.org/x/net v0.0.0-20211030010942-bd5b1b8b281b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hey.go b/hey.go index f727e26b..06911389 100644 --- a/hey.go +++ b/hey.go @@ -16,6 +16,8 @@ package main import ( + "crypto/tls" + "errors" "flag" "fmt" "io/ioutil" @@ -60,6 +62,8 @@ var ( h2 = flag.Bool("h2", false, "") cpus = flag.Int("cpus", runtime.GOMAXPROCS(-1), "") + minTLSVersion = flag.String("min-tls-version", "", "") + maxTLSVersion = flag.String("max-tls-version", "", "") disableCompression = flag.Bool("disable-compression", false, "") disableKeepAlives = flag.Bool("disable-keepalive", false, "") disableRedirects = flag.Bool("disable-redirects", false, "") @@ -95,6 +99,8 @@ Options: -host HTTP Host header. + -min-tls-version Set minimum version for TLS. Allowed values: 1.0, 1.1, 1.2, 1.3 + -max-tls-version Set maximum version for TLS. Allowed values: 1.0, 1.1, 1.2, 1.3. Cannot be less than -max-tls-version -disable-compression Disable compression. -disable-keepalive Disable keep-alive, prevents re-use of TCP connections between different HTTP requests. @@ -221,6 +227,21 @@ func main() { req.Header = header + minTLSVersionInt, err := translateTLSVersion(*minTLSVersion) + if err != nil { + errAndExit(err.Error()) + } + + maxTLSVersionInt, err := translateTLSVersion(*maxTLSVersion) + if err != nil { + errAndExit(err.Error()) + } + + err = validateTLSVersions(minTLSVersionInt, maxTLSVersionInt) + if err != nil { + errAndExit(err.Error()) + } + w := &requester.Work{ Request: req, RequestBody: bodyAll, @@ -231,6 +252,8 @@ func main() { DisableCompression: *disableCompression, DisableKeepAlives: *disableKeepAlives, DisableRedirects: *disableRedirects, + MinTLSVersion: minTLSVersionInt, + MaxTLSVersion: maxTLSVersionInt, H2: *h2, ProxyAddr: proxyURL, Output: *output, @@ -287,3 +310,38 @@ func (h *headerSlice) Set(value string) error { *h = append(*h, value) return nil } + +func translateTLSVersion(commandLineArg string) (uint16, error) { + var version uint16 = math.MaxUint16 + + switch commandLineArg { + case "": + version = 0 + case "1.0": + version = tls.VersionTLS10 + case "1.1": + version = tls.VersionTLS11 + case "1.2": + version = tls.VersionTLS12 + case "1.3": + version = tls.VersionTLS13 + } + + if version == math.MaxUint16 { + return version, fmt.Errorf("could not parse TLS version: %v", commandLineArg) + } + + return version, nil +} + +func validateTLSVersions(minTLSVersion uint16, maxTLSVersion uint16) error { + if minTLSVersion == 0 || maxTLSVersion == 0 { + return nil + } + + if minTLSVersion > maxTLSVersion { + return errors.New("min TLS version cannot be greater than max TLS version") + } + + return nil +} diff --git a/hey_test.go b/hey_test.go index 97a6b5ba..f8f459e7 100644 --- a/hey_test.go +++ b/hey_test.go @@ -15,7 +15,12 @@ package main import ( + "crypto/tls" + "errors" + "math" "testing" + + "github.com/stretchr/testify/assert" ) func TestParseValidHeaderFlag(t *testing.T) { @@ -64,3 +69,82 @@ func TestParseAuthMetaCharacters(t *testing.T) { t.Errorf("Auth header with a plus sign in the user name errored: %v", err) } } + +func TestTranslateTLSVersions(t *testing.T) { + tests := []struct { + tlsVersion string + expectedResult uint16 + expectedError error + }{ + { // TLS 1.0 + tlsVersion: "1.0", + expectedResult: tls.VersionTLS10, + }, + { // TLS 1.1 + tlsVersion: "1.1", + expectedResult: tls.VersionTLS11, + }, + { // TLS 1.2 + tlsVersion: "1.2", + expectedResult: tls.VersionTLS12, + }, + { // TLS 1.3 + tlsVersion: "1.3", + expectedResult: tls.VersionTLS13, + }, + { // no version specified + tlsVersion: "", + expectedResult: 0, + }, + { // invalid version + tlsVersion: "1.4", + expectedResult: math.MaxUint16, + expectedError: errors.New("could not parse TLS version: 1.4"), + }, + } + + for _, test := range tests { + actualResult, actualError := translateTLSVersion(test.tlsVersion) + assert.Equal(t, test.expectedResult, actualResult) + assert.Equal(t, test.expectedError, actualError) + } +} + +func TestValidateTLSVersions(t *testing.T) { + tests := []struct { + minTLSVersion uint16 + maxTLSVersion uint16 + expectedError error + }{ + { // neither version specified + minTLSVersion: 0, + maxTLSVersion: 0, + }, + { // only min specified + minTLSVersion: tls.VersionTLS11, + maxTLSVersion: 0, + }, + { // only max specified + minTLSVersion: 0, + maxTLSVersion: tls.VersionTLS12, + }, + { // both specified + minTLSVersion: tls.VersionTLS12, + maxTLSVersion: tls.VersionTLS13, + }, + { // both specified and equal + minTLSVersion: tls.VersionTLS13, + maxTLSVersion: tls.VersionTLS13, + }, + { // invalid choices + minTLSVersion: tls.VersionTLS12, + maxTLSVersion: tls.VersionTLS10, + expectedError: errors.New("min TLS version cannot be greater than max TLS version"), + }, + } + + for _, test := range tests { + actualError := validateTLSVersions(test.minTLSVersion, test.maxTLSVersion) + assert.Equal(t, test.expectedError, actualError) + } +} diff --git a/requester/requester.go b/requester/requester.go index fd7277e7..abfac76d 100644 --- a/requester/requester.go +++ b/requester/requester.go @@ -72,6 +72,10 @@ type Work struct { // Qps is the rate limit in queries per second. QPS float64 + // Specify the minimum and maximum TLS versions + MinTLSVersion uint16 + MaxTLSVersion uint16 + // DisableCompression is an option to disable compression in response DisableCompression bool @@ -239,6 +243,8 @@ func (b *Work) runWorkers() { TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, ServerName: b.Request.Host, + MinVersion: b.MinTLSVersion, + MaxVersion: b.MaxTLSVersion, }, MaxIdleConnsPerHost: min(b.C, maxIdleConn), DisableCompression: b.DisableCompression,