diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index f118ccd..a97f7e7 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -21,7 +21,7 @@ env: GO111MODULE: "on" CACHE_BENCHMARK: "off" # Enables benchmark result reuse between runs, may skew latency results. RUN_BASE_BENCHMARK: "on" # Runs benchmark for PR base in case benchmark result is missing. - GO_VERSION: 1.22.x + GO_VERSION: 1.23.x jobs: bench: runs-on: ubuntu-latest diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index dc96a70..9acf314 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -21,13 +21,13 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.22.x + go-version: 1.23.x - uses: actions/checkout@v2 - name: golangci-lint - uses: golangci/golangci-lint-action@v3.7.0 + uses: golangci/golangci-lint-action@v6.1.0 with: # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. - version: v1.55.2 + version: v1.61.0 # Optional: working directory, useful for monorepos # working-directory: somedir diff --git a/.github/workflows/gorelease.yml b/.github/workflows/gorelease.yml index 6356a9d..c031db4 100644 --- a/.github/workflows/gorelease.yml +++ b/.github/workflows/gorelease.yml @@ -9,7 +9,7 @@ concurrency: cancel-in-progress: true env: - GO_VERSION: 1.22.x + GO_VERSION: 1.23.x jobs: gorelease: runs-on: ubuntu-latest diff --git a/.github/workflows/release-assets.yml b/.github/workflows/release-assets.yml index 980b985..348a44a 100644 --- a/.github/workflows/release-assets.yml +++ b/.github/workflows/release-assets.yml @@ -8,7 +8,7 @@ on: - created env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GO_VERSION: 1.22.x + GO_VERSION: 1.23.x jobs: build: name: Upload Release Assets diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index b02de5f..4451ef3 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -21,7 +21,7 @@ jobs: test: strategy: matrix: - go-version: [ 1.19.x, 1.20.x, 1.21.x, 1.22.x ] + go-version: [ 1.22.x, 1.23.x ] runs-on: ubuntu-latest steps: - name: Install Go stable diff --git a/.golangci.yml b/.golangci.yml index f6bff92..4094d8c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,60 +20,59 @@ linters-settings: linters: enable-all: true disable: + - err113 - noctx - errorlint - cyclop - - goerr113 - gomnd - gocyclo - gochecknoglobals - funlen - gocognit - lll - - maligned - gochecknoglobals - gomnd - wrapcheck - paralleltest - forbidigo - - exhaustivestruct - - interfacer # deprecated - forcetypeassert - - scopelint # deprecated - - ifshort # too many false positives - - golint # deprecated - varnamelen - tagliatelle - errname - ireturn - exhaustruct - nonamedreturns - - nosnakecase - - structcheck - - varcheck - - deadcode - testableexamples - dupword - depguard - tagalign + - execinquery + - mnd + - testifylint + - intrange issues: exclude-use-default: false exclude-rules: - linters: - gomnd + - mnd - goconst - - goerr113 - noctx - funlen - dupl - - structcheck - unused - unparam - - nosnakecase path: "_test.go" - linters: - errcheck # Error checking omitted for brevity. - gosec path: "example_" + - linters: + - errcheck + text: "Error return value of `fmt.Fprint" + - linters: + - revive + text: "unused-parameter: parameter" + diff --git a/Makefile b/Makefile index 06ec521..162f04e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -#GOLANGCI_LINT_VERSION := "v1.55.2" # Optional configuration to pinpoint golangci-lint version. +#GOLANGCI_LINT_VERSION := "v1.61.0" # Optional configuration to pinpoint golangci-lint version. # The head of Makefile determines location of dev-go to include standard targets. GO ?= go diff --git a/_examples/cplt/cplt.go b/_examples/cplt/cplt.go index 22964c5..54f7e1b 100644 --- a/_examples/cplt/cplt.go +++ b/_examples/cplt/cplt.go @@ -4,7 +4,7 @@ import ( "net/http" "strconv" - "github.com/alecthomas/kingpin" + "github.com/alecthomas/kingpin/v2" "github.com/vearutop/plt/curl" "github.com/vearutop/plt/loadgen" "github.com/vearutop/plt/nethttp" diff --git a/curl/cmd.go b/curl/cmd.go index 7d5e17d..dda7547 100644 --- a/curl/cmd.go +++ b/curl/cmd.go @@ -5,18 +5,19 @@ import ( "encoding/base64" "errors" "fmt" - "log" "net/http" "regexp" "strings" - "github.com/alecthomas/kingpin" + "github.com/alecthomas/kingpin/v2" "github.com/vearutop/plt/fasthttp" "github.com/vearutop/plt/loadgen" "github.com/vearutop/plt/nethttp" ) // AddCommand registers curl command into CLI app. +// +//nolint:maintidx func AddCommand(lf *loadgen.Flags, options ...func(lf *loadgen.Flags, f *nethttp.Flags, j loadgen.JobProducer)) { var ( flags nethttp.Flags @@ -25,6 +26,8 @@ func AddCommand(lf *loadgen.Flags, options ...func(lf *loadgen.Flags, f *nethttp data []string compressed bool user string + output string + head bool } captureStrings = map[string]*[]string{ "header": &capture.header, @@ -38,11 +41,13 @@ func AddCommand(lf *loadgen.Flags, options ...func(lf *loadgen.Flags, f *nethttp "url": &flags.URL, "request": &flags.Method, "user": &capture.user, + "output": &capture.output, } captureBool = map[string]*bool{ "compressed": &capture.compressed, "no-keepalive": &flags.NoKeepalive, "http2": &flags.HTTP2, + "head": &capture.head, } ignoredString = map[string]*string{} ignoredBool = map[string]*bool{} @@ -118,18 +123,21 @@ func AddCommand(lf *loadgen.Flags, options ...func(lf *loadgen.Flags, f *nethttp curl.Action(func(kp *kingpin.ParseContext) error { ignoredFlags := make([]string, 0) + for f, v := range ignoredString { if v != nil && *v != "" { ignoredFlags = append(ignoredFlags, f) } } + for f, v := range ignoredBool { if v != nil && *v { ignoredFlags = append(ignoredFlags, f) } } + if len(ignoredFlags) > 0 { - log.Printf("Warning, these Flags are ignored: %v\n", ignoredFlags) + return fmt.Errorf("these flags are ignored: %v", ignoredFlags) } if len(capture.data) == 1 { @@ -139,13 +147,19 @@ func AddCommand(lf *loadgen.Flags, options ...func(lf *loadgen.Flags, f *nethttp } flags.HeaderMap = make(map[string]string, len(capture.header)) + if capture.user != "" { if !strings.Contains(capture.user, ":") { return errors.New("user parameter must be in form user:pass") } + flags.HeaderMap["Authorization"] = "Basic " + base64.StdEncoding.EncodeToString([]byte(capture.user)) } + if capture.head { + flags.Method = http.MethodHead + } + if flags.Body != "" { flags.HeaderMap["Content-Type"] = "application/x-www-form-urlencoded" @@ -159,13 +173,20 @@ func AddCommand(lf *loadgen.Flags, options ...func(lf *loadgen.Flags, f *nethttp if len(parts) != 2 { continue } + flags.HeaderMap[http.CanonicalHeaderKey(parts[0])] = strings.Trim(parts[1], " ") } + if capture.compressed { if _, ok := flags.HeaderMap["Accept-Encoding"]; !ok { flags.HeaderMap["Accept-Encoding"] = "gzip, deflate" } } + + if flags.NoKeepalive && (capture.output == "/dev/null" || capture.output == "nul") { + flags.IgnoreResponseBody = true + } + if !strings.HasPrefix(strings.ToLower(flags.URL), "http://") && !strings.HasPrefix(strings.ToLower(flags.URL), "https://") { flags.URL = "http://" + flags.URL diff --git a/fasthttp/job_test.go b/fasthttp/job_test.go index c9a386e..07e49f1 100644 --- a/fasthttp/job_test.go +++ b/fasthttp/job_test.go @@ -16,7 +16,7 @@ import ( ) func TestNewJobProducer(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + srv := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { require.Equal(t, "/?foo=bar", r.URL.RequestURI()) })) defer srv.Close() @@ -43,7 +43,7 @@ func TestNewJobProducer(t *testing.T) { j, err := fh.NewJobProducer(f) require.NoError(t, err) - j.PrepareRequest = func(i int, req *fasthttp.Request) error { + j.PrepareRequest = func(_ int, req *fasthttp.Request) error { req.SetRequestURI(srv.URL + "/?foo=bar") return nil @@ -56,7 +56,7 @@ func TestNewJobProducer(t *testing.T) { } func BenchmarkJobProducer_Job(b *testing.B) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + srv := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { require.Equal(b, "/?foo=bar", r.URL.RequestURI()) })) defer srv.Close() @@ -82,7 +82,7 @@ func BenchmarkJobProducer_Job(b *testing.B) { j, err := fh.NewJobProducer(f) require.NoError(b, err) - j.PrepareRequest = func(i int, req *fasthttp.Request) error { + j.PrepareRequest = func(_ int, req *fasthttp.Request) error { req.SetRequestURI(srv.URL + "/?foo=bar") return nil diff --git a/go.mod b/go.mod index 5884ad6..44fbf44 100644 --- a/go.mod +++ b/go.mod @@ -1,45 +1,48 @@ module github.com/vearutop/plt -go 1.21 +go 1.22.0 + +toolchain go1.23.0 require ( - github.com/alecthomas/kingpin v2.2.6+incompatible - github.com/aws/aws-sdk-go v1.50.21 - github.com/bool64/dev v0.2.33 + github.com/alecthomas/kingpin/v2 v2.4.0 + github.com/aws/aws-sdk-go v1.55.5 + github.com/bool64/dev v0.2.36 github.com/gizak/termui/v3 v3.1.0 github.com/nsf/termbox-go v1.1.1 - github.com/quic-go/quic-go v0.41.0 - github.com/stretchr/testify v1.8.4 - github.com/valyala/fasthttp v1.52.0 + github.com/quic-go/quic-go v0.47.0 + github.com/stretchr/testify v1.9.0 + github.com/valyala/fasthttp v1.55.0 github.com/vearutop/dynhist-go v1.2.2 - golang.org/x/net v0.21.0 - golang.org/x/time v0.5.0 + golang.org/x/net v0.29.0 + golang.org/x/time v0.6.0 ) require ( - github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect - github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/onsi/ginkgo/v2 v2.20.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qpack v0.5.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/xhit/go-str2duration/v2 v2.1.0 // indirect go.uber.org/mock v0.4.0 // indirect - golang.org/x/crypto v0.19.0 // indirect - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.18.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/tools v0.25.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d30282f..540871e 100644 --- a/go.sum +++ b/go.sum @@ -1,37 +1,33 @@ -github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI= -github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= +github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/aws/aws-sdk-go v1.50.21 h1:W8awpwiInOt4qHQE6JghRYQJhHcf/cDJS3mlZYqioSQ= -github.com/aws/aws-sdk-go v1.50.21/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/bool64/dev v0.2.33 h1:ETAcSa8H9w4talcCdSQCCnLX7PMHmuxdLcDl6TpSDj4= -github.com/bool64/dev v0.2.33/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/bool64/dev v0.2.36 h1:yU3bbOTujoxhWnt8ig8t94PVmZXIkCaRj9C57OtqJBY= +github.com/bool64/dev v0.2.36/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc= github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 h1:q5g0N9eal4bmJwXHC5z0QCKs8qhS35hFfq0BAYsIwZI= +github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -45,53 +41,60 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY= github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= 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/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k= -github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.47.0 h1:yXs3v7r2bm1wmPTYNLKAAJTHMYkPEsfYJmTazXrCZ7Y= +github.com/quic-go/quic-go v0.47.0/go.mod h1:3bCapYsJvXGZcipOHuu7plYtaV6tnF+z7wIFsU0WK9E= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= -github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= +github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8= +github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= github.com/vearutop/dynhist-go v1.2.2 h1:pKPC2rYHdzpkasztNJmjE7m9DbUJDbMhZi2ZxaUvmS4= github.com/vearutop/dynhist-go v1.2.2/go.mod h1:liiiYiwAi8ixC3DbkxooEhASTF6ysJSXy+piCrBtxEg= +github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= +golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/loadgen/app.go b/loadgen/app.go index ac378ad..0e73095 100644 --- a/loadgen/app.go +++ b/loadgen/app.go @@ -1,7 +1,7 @@ package loadgen import ( - "github.com/alecthomas/kingpin" + "github.com/alecthomas/kingpin/v2" "github.com/bool64/dev/version" ) diff --git a/loadgen/job_test.go b/loadgen/job_test.go index 899b457..a7b671c 100644 --- a/loadgen/job_test.go +++ b/loadgen/job_test.go @@ -41,7 +41,7 @@ func TestNewJobProducer(t *testing.T) { j, err := nethttp.NewJobProducer(f, lf) require.NoError(t, err) - j.PrepareRequest = func(i int, req *http.Request) error { + j.PrepareRequest = func(_ int, req *http.Request) error { req.URL.RawQuery = "foo=bar" return nil diff --git a/loadgen/run.go b/loadgen/run.go index 6f2671d..23434de 100644 --- a/loadgen/run.go +++ b/loadgen/run.go @@ -62,9 +62,7 @@ func Run(lf Flags, jobProducer JobProducer) error { } // Main loop. - for i := 0; i < r.n; i++ { - i := i - + for i := range r.n { r.mu.Lock() rl := r.rl r.mu.Unlock() @@ -239,12 +237,12 @@ func (r *runner) captureLiveUI() { return } - var buf []byte + var buf []byte //nolint:prealloc w, h := termbox.Size() - for y := 0; y < h; y++ { - for x := 0; x < w; x++ { + for y := range h { + for x := range w { c := termbox.GetCell(x, y) buf = append(buf, []byte(string(c.Ch))...) diff --git a/nethttp/job.go b/nethttp/job.go index 57f6ccb..463a182 100644 --- a/nethttp/job.go +++ b/nethttp/job.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "crypto/tls" + "errors" "fmt" "io" "net" @@ -147,7 +148,7 @@ func (j *JobProducer) makeTransport2() *http2.Transport { AllowHTTP: true, } - t.DialTLSContext = func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) { + t.DialTLSContext = func(_ context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) { c, err := tls.DialWithDialer(new(net.Dialer), network, addr, cfg) if err != nil { return c, err @@ -304,14 +305,14 @@ func (j *JobProducer) Job(i int) (time.Duration, error) { } trace := &httptrace.ClientTrace{ - DNSStart: func(info httptrace.DNSStartInfo) { + DNSStart: func(_ httptrace.DNSStartInfo) { dnsStart = time.Now() }, DNSDone: func(dnsInfo httptrace.DNSDoneInfo) { j.dnsHist.Add(1000 * time.Since(dnsStart).Seconds()) }, - ConnectStart: func(network, addr string) { + ConnectStart: func(_, _ string) { connStart = time.Now() }, ConnectDone: func(network, addr string, err error) { @@ -326,11 +327,14 @@ func (j *JobProducer) Job(i int) (time.Duration, error) { }, WroteRequest: func(_ httptrace.WroteRequestInfo) { + dlStart = time.Now() + atomic.AddInt64(&j.writeTime, int64(time.Since(start))) }, GotFirstResponseByte: func() { dlStart = time.Now() + j.ttfbHist.Add(1000 * time.Since(start).Seconds()) }, } @@ -349,6 +353,7 @@ func (j *JobProducer) Job(i int) (time.Duration, error) { } start = time.Now() + dlStart = start resp, err := tr.RoundTrip(req) if err != nil { @@ -372,7 +377,7 @@ func (j *JobProducer) Job(i int) (time.Duration, error) { body := make([]byte, SampleSize+1) n, err := io.ReadAtLeast(resp.Body, body, SampleSize+1) - if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { + if err != nil && err != io.EOF && !errors.Is(err, io.ErrUnexpectedEOF) { return 0, err } @@ -390,9 +395,11 @@ func (j *JobProducer) Job(i int) (time.Duration, error) { j.mu.Unlock() } - _, err = io.Copy(io.Discard, resp.Body) - if err != nil { - return 0, err + if !j.f.IgnoreResponseBody { + _, err = io.Copy(io.Discard, resp.Body) + if err != nil { + return 0, err + } } err = resp.Body.Close() @@ -412,13 +419,14 @@ func (j *JobProducer) Job(i int) (time.Duration, error) { // Flags control HTTP load setup. type Flags struct { - HeaderMap map[string]string - URL string - Body string - Method string - NoKeepalive bool - Compressed bool - Fast bool - HTTP2 bool - HTTP3 bool + HeaderMap map[string]string + URL string + Body string + Method string + NoKeepalive bool + Compressed bool + Fast bool + IgnoreResponseBody bool + HTTP2 bool + HTTP3 bool } diff --git a/plt.go b/plt.go index a2d9c8f..ad5ad98 100644 --- a/plt.go +++ b/plt.go @@ -2,7 +2,7 @@ package main import ( - "github.com/alecthomas/kingpin" + "github.com/alecthomas/kingpin/v2" "github.com/vearutop/plt/curl" "github.com/vearutop/plt/loadgen" "github.com/vearutop/plt/s3" diff --git a/s3/cmd.go b/s3/cmd.go index 2e0c79e..ceb3c59 100644 --- a/s3/cmd.go +++ b/s3/cmd.go @@ -2,7 +2,7 @@ package s3 import ( - "github.com/alecthomas/kingpin" + "github.com/alecthomas/kingpin/v2" "github.com/vearutop/plt/loadgen" ) @@ -43,7 +43,7 @@ func AddCommand(lf *loadgen.Flags) { s3.Flag("save", "Path to local file to save the entry.").StringVar(&f.Save) s3.Flag("upload", "Path to local file to upload to S3, enables upload load testing.").StringVar(&f.Upload) - s3.Action(func(kp *kingpin.ParseContext) error { + s3.Action(func(_ *kingpin.ParseContext) error { return run(*lf, f) }) }