From c844fada747bbbd4a19dff1aeefa2163c49b71e2 Mon Sep 17 00:00:00 2001 From: Pascal Dennerly Date: Thu, 19 May 2022 22:54:53 +0100 Subject: [PATCH 1/6] Add coverage metrics for fully plumbed in app --- Makefile | 7 ++++++- cmd/wait-for/main.go | 34 +++++++++++++++++++++++++++++----- cmd/wait-for/main_test.go | 13 +++++++++++++ go.mod | 1 + go.sum | 5 +++++ test/Dockerfile | 4 ++-- test/cli_test.go | 35 ++++++++++++++++++++++++++--------- test/docker-compose.yml | 2 ++ test/files/godog.sh | 2 ++ 9 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 cmd/wait-for/main_test.go diff --git a/Makefile b/Makefile index 857fd17..036f375 100644 --- a/Makefile +++ b/Makefile @@ -66,9 +66,14 @@ ci-test: ## ci target - run tests to generate coverage data go test -race -coverprofile=coverage.txt -covermode=atomic ./... .PHONY: acceptance-test -acceptance-test: build ## run acceptance tests +acceptance-test: ## run acceptance tests + go test ./cmd/wait-for -coverpkg=./... -c -o wait-for.test cd test && godog .PHONY: acceptance-test-docker acceptance-test-docker: ## run acceptance tests in Docker (if you can't open local ports reliably) docker-compose -f test/docker-compose.yml up --build --abort-on-container-exit godog + +.PHONY: acceptance-test-docker-shell +acceptance-test-docker-shell: ## run a shell in the acceptance test docker container + docker-compose -f test/docker-compose.yml run godog bash diff --git a/cmd/wait-for/main.go b/cmd/wait-for/main.go index 4403142..91df86a 100644 --- a/cmd/wait-for/main.go +++ b/cmd/wait-for/main.go @@ -5,7 +5,9 @@ import ( "fmt" "log" "os" + "strings" + "github.com/confluentinc/bincover" waitfor "github.com/dnnrly/wait-for" "github.com/spf13/afero" ) @@ -18,11 +20,20 @@ func main() { configFile := "" var quiet bool + flag.CommandLine.Init(os.Args[0], flag.ContinueOnError) flag.StringVar(&timeoutParam, "timeout", timeoutParam, "time to wait for services to become available") flag.StringVar(&httpTimeoutParam, "http_timeout", httpTimeoutParam, "timeout for requests made by a http client") flag.StringVar(&configFile, "config", "", "configuration file to use") flag.BoolVar(&quiet, "quiet", false, "reduce output to the minimum") - flag.Parse() + err := flag.CommandLine.Parse(os.Args[1:]) + if err != nil { + if err == flag.ErrHelp { + exit(0) + } else { + exit(1) + } + return + } fs := afero.NewOsFs() @@ -36,13 +47,26 @@ func main() { config, err := waitfor.OpenConfig(configFile, timeoutParam, httpTimeoutParam, fs) if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%v", err) - os.Exit(1) + _, _ = fmt.Printf("%v", err) + exit(1) + return } err = waitfor.WaitOn(config, logger, flag.Args(), waitfor.SupportedWaiters) if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%v", err) - os.Exit(1) + _, _ = fmt.Printf("%v", err) + exit(1) + return + } +} + +func exit(code int) { + if val, found := os.LookupEnv("BINCOVER_EXIT"); found { + if strings.ToLower(val) == "true" { + bincover.ExitCode = code + return + } } + + os.Exit(code) } diff --git a/cmd/wait-for/main_test.go b/cmd/wait-for/main_test.go new file mode 100644 index 0000000..7008ab1 --- /dev/null +++ b/cmd/wait-for/main_test.go @@ -0,0 +1,13 @@ +package main + +import ( + "os" + "testing" + + "github.com/confluentinc/bincover" +) + +func TestBincoverRunMain(t *testing.T) { + os.Setenv("BINCOVER_EXIT", "true") + bincover.RunTest(main) +} diff --git a/go.mod b/go.mod index 9e60880..5ca2e5b 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/dnnrly/wait-for go 1.14 require ( + github.com/confluentinc/bincover v0.2.0 github.com/cucumber/godog v0.10.0 github.com/gofrs/uuid v3.3.0+incompatible // indirect github.com/hashicorp/go-memdb v1.3.0 // indirect diff --git a/go.sum b/go.sum index d748058..f8d4fc9 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ github.com/aslakhellesoy/gox v1.0.100/go.mod h1:AJl542QsKKG96COVsv0N74HHzVQgDIQPceVUh1aeU2M= +github.com/confluentinc/bincover v0.2.0 h1:WSS3MqzwJbosCLMOuF3tJ0pMpALzBfrm80Tb+/3gbQs= +github.com/confluentinc/bincover v0.2.0/go.mod h1:qeI1wx0RxdGTZtrJY0HVlgJ4NqC/X2Z+fHbvy87tgHE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/gherkin-go/v11 v11.0.0 h1:cwVwN1Qn2VRSfHZNLEh5x00tPBmZcjATBWDpxsR5Xug= github.com/cucumber/gherkin-go/v11 v11.0.0/go.mod h1:CX33k2XU2qog4e+TFjOValoq6mIUq0DmVccZs238R9w= @@ -30,6 +32,7 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -38,6 +41,7 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -66,6 +70,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= diff --git a/test/Dockerfile b/test/Dockerfile index f5ebf3c..fc0fab2 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -9,7 +9,7 @@ RUN go mod download RUN go install github.com/cucumber/godog/cmd/godog@v0.12.4 ADD . . -RUN go build -o wait-for ./cmd/wait-for +RUN go test ./cmd/wait-for -coverpkg=./... -c -o wait-for.test WORKDIR /app/test/ -ENTRYPOINT . files/godog.sh +CMD . files/godog.sh diff --git a/test/cli_test.go b/test/cli_test.go index be89903..62da013 100644 --- a/test/cli_test.go +++ b/test/cli_test.go @@ -1,7 +1,6 @@ package test import ( - "bytes" "context" "fmt" "log" @@ -12,10 +11,13 @@ import ( "sync" "time" + "github.com/confluentinc/bincover" "github.com/cucumber/godog" "github.com/stretchr/testify/assert" ) +var binPath string = "../wait-for.test" + type stepsData struct { assertError error @@ -120,17 +122,30 @@ func (s *stepsData) Errorf(format string, args ...interface{}) { } func (s *stepsData) iRunWaitforWithParameters(params string) error { - cmd := exec.Command("../wait-for", strings.Split(params, " ")...) - - var b bytes.Buffer - cmd.Stderr = &b - cmd.Stdout = &b + collector := bincover.NewCoverageCollector("wait-for_coverage.out", true) + err := collector.Setup() + if err != nil { + return err + } + defer func() { + err := collector.TearDown() + if err != nil { + panic(err) + } + }() start := time.Now() - _ = cmd.Run() - s.output = b.String() - s.statusCode = cmd.ProcessState.ExitCode() + _, s.statusCode, _ = collector.RunBinary( + binPath, + "TestBincoverRunMain", + []string{}, + strings.Split(params, " "), + bincover.PostExec(func(cmd *exec.Cmd, output string, err error) error { + s.output = output + return nil + }), + ) s.duration = time.Since(start) @@ -238,6 +253,8 @@ func (s *stepsData) listeningServerWaitsThenResponds(port int, duration string, func InitializeTestSuite(ctx *godog.TestSuiteContext) { ctx.BeforeSuite(func() { }) + ctx.AfterSuite(func() { + }) } func InitializeScenario(ctx *godog.ScenarioContext) { diff --git a/test/docker-compose.yml b/test/docker-compose.yml index c22dced..7491de6 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -4,3 +4,5 @@ services: build: context: .. dockerfile: test/Dockerfile + volumes: + - ../:/working diff --git a/test/files/godog.sh b/test/files/godog.sh index 7a534dd..ae74f63 100644 --- a/test/files/godog.sh +++ b/test/files/godog.sh @@ -1,3 +1,5 @@ #!/usr/bin/env sh godog $@ +chmod a+rw wait-for_coverage.out +cp wait-for_coverage.out /working From 6a67e3d117dd1717a75cbc1c5dd7db1ca7860fe1 Mon Sep 17 00:00:00 2001 From: Pascal Dennerly Date: Thu, 19 May 2022 23:34:31 +0100 Subject: [PATCH 2/6] Create combined coverage for upload --- .github/workflows/pr.yml | 2 ++ .gitignore | 1 + Makefile | 5 +++++ go.mod | 1 + go.sum | 2 ++ test/Dockerfile | 2 +- test/cli_test.go | 2 +- test/files/godog.sh | 6 ++++-- 8 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d4b691b..30990ed 100755 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -22,6 +22,8 @@ jobs: run: make lint - name: Acceptance test run: make build acceptance-test-docker + - name: Collect coverage data + run: make coverage > coverage.txt - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 env: diff --git a/.gitignore b/.gitignore index 4a55899..2b59b96 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ dist/ # Test binary, built with `go test -c` *.test /coverage.txt +/wait-for_coverage.txt # Output of the go coverage tool, specifically when used with LiteIDE *.out diff --git a/Makefile b/Makefile index 036f375..31a3d2b 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,7 @@ clean-deps: .PHONY: deps deps: ./bin/tparse ./bin/golangci-lint + go install github.com/wadey/gocovmerge@b5bfa59 go get -v ./... go mod tidy @@ -65,6 +66,10 @@ test: ## run unit tests ci-test: ## ci target - run tests to generate coverage data go test -race -coverprofile=coverage.txt -covermode=atomic ./... +.PHONY: coverage +coverage: ## combine coverage reports + gocovmerge coverage.txt wait-for_coverage.txt + .PHONY: acceptance-test acceptance-test: ## run acceptance tests go test ./cmd/wait-for -coverpkg=./... -c -o wait-for.test diff --git a/go.mod b/go.mod index 5ca2e5b..356f0f2 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/confluentinc/bincover v0.2.0 github.com/cucumber/godog v0.10.0 github.com/gofrs/uuid v3.3.0+incompatible // indirect + github.com/google/uuid v1.3.0 github.com/hashicorp/go-memdb v1.3.0 // indirect github.com/spf13/afero v1.4.1 github.com/stretchr/testify v1.6.1 diff --git a/go.sum b/go.sum index f8d4fc9..ccffa86 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6 github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= diff --git a/test/Dockerfile b/test/Dockerfile index fc0fab2..7378c2b 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -9,7 +9,7 @@ RUN go mod download RUN go install github.com/cucumber/godog/cmd/godog@v0.12.4 ADD . . -RUN go test ./cmd/wait-for -coverpkg=./... -c -o wait-for.test +RUN go test ./cmd/wait-for -covermode=atomic -coverpkg=./... -c -o wait-for.test WORKDIR /app/test/ CMD . files/godog.sh diff --git a/test/cli_test.go b/test/cli_test.go index 62da013..c8a339b 100644 --- a/test/cli_test.go +++ b/test/cli_test.go @@ -122,7 +122,7 @@ func (s *stepsData) Errorf(format string, args ...interface{}) { } func (s *stepsData) iRunWaitforWithParameters(params string) error { - collector := bincover.NewCoverageCollector("wait-for_coverage.out", true) + collector := bincover.NewCoverageCollector("wait-for_coverage.txt", true) err := collector.Setup() if err != nil { return err diff --git a/test/files/godog.sh b/test/files/godog.sh index ae74f63..d950f36 100644 --- a/test/files/godog.sh +++ b/test/files/godog.sh @@ -1,5 +1,7 @@ #!/usr/bin/env sh +set -o xtrace + godog $@ -chmod a+rw wait-for_coverage.out -cp wait-for_coverage.out /working +chmod a+rw wait-for_coverage.txt +cp wait-for_coverage.txt /working From 27e1dbe32cf934aeffdf2f7d2acecc2badb0aca9 Mon Sep 17 00:00:00 2001 From: Pascal Dennerly Date: Fri, 20 May 2022 22:42:35 +0100 Subject: [PATCH 3/6] Move linting to its own action --- .github/workflows/golangci-lint.yml | 27 +++++++++++++++++++++++++++ .github/workflows/pr.yml | 2 -- Makefile | 2 +- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/golangci-lint.yml diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..9a4eb2c --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,27 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - master + - main + pull_request: +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + # pull-requests: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.17 + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: v1.29 \ No newline at end of file diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 30990ed..753b011 100755 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -18,8 +18,6 @@ jobs: run: make deps - name: Unit test run: make ci-test - - name: Linting - run: make lint - name: Acceptance test run: make build acceptance-test-docker - name: Collect coverage data diff --git a/Makefile b/Makefile index 31a3d2b..8654084 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ clean-deps: mkdir -p ./tmp .PHONY: deps -deps: ./bin/tparse ./bin/golangci-lint +deps: go install github.com/wadey/gocovmerge@b5bfa59 go get -v ./... go mod tidy From 9d995f2971706b6fd8095caf04c9992fc62fa2b8 Mon Sep 17 00:00:00 2001 From: Pascal Dennerly Date: Fri, 20 May 2022 23:22:20 +0100 Subject: [PATCH 4/6] Add linter config --- .golangci.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .golangci.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..57819bb --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,5 @@ +issues: + exclude-rules: + - path: _test\.go + linters: + - unused \ No newline at end of file From f3dd0e15a04c49b6191b2e419185d0cfec059881 Mon Sep 17 00:00:00 2001 From: Pascal Dennerly Date: Fri, 20 May 2022 23:31:22 +0100 Subject: [PATCH 5/6] Fix coverage reports --- .github/workflows/pr.yml | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 753b011..f8d1dcc 100755 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -21,7 +21,7 @@ jobs: - name: Acceptance test run: make build acceptance-test-docker - name: Collect coverage data - run: make coverage > coverage.txt + run: make coverage - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 env: diff --git a/Makefile b/Makefile index 8654084..5e7ec45 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ ci-test: ## ci target - run tests to generate coverage data .PHONY: coverage coverage: ## combine coverage reports - gocovmerge coverage.txt wait-for_coverage.txt + gocovmerge coverage.txt wait-for_coverage.txt > coverage.txt .PHONY: acceptance-test acceptance-test: ## run acceptance tests From 670cfa753cbce674ac988a29932559ea81ff1c1d Mon Sep 17 00:00:00 2001 From: Pascal Dennerly Date: Sat, 21 May 2022 21:46:21 +0100 Subject: [PATCH 6/6] Revert to coverage from ci-tests only --- .github/workflows/pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index f8d1dcc..42385a1 100755 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -20,8 +20,8 @@ jobs: run: make ci-test - name: Acceptance test run: make build acceptance-test-docker - - name: Collect coverage data - run: make coverage + # - name: Collect coverage data + # run: make coverage - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 env: