From abb683af51dfcb036a0ed9eded8b2b7e6b948080 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Fri, 10 May 2024 15:38:25 -0500 Subject: [PATCH] build(ci): improve test workflow (#3) ## Description This PR improves the test workflow. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://docs.cosmos.network/v0.44/building-modules/intro.html) - [ ] included the necessary unit and integration [tests](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- .github/workflows/test.yml | 349 ++++++++++++++++++++++++++++++++----- Makefile | 60 +++++-- 2 files changed, 344 insertions(+), 65 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d8f335d..6ca28979 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,67 +1,322 @@ name: Build & Test on: pull_request: - paths: - - "**.go" - - "**.mv" - - "**.move" push: branches: - main - - "release/*" - paths: - - "**.go" - - "**.mv" - - "**.move" -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true +env: + GOPRIVATE: github.com/milkyway-labs + GH_ACCESS_TOKEN: ${{ secrets.GOPRIVATE_ACCESS_TOKEN }} jobs: - test-coverage-upload: - name: Run test and upload codecov - env: - # for private repo access - GOPRIVATE: github.com/initia-labs/* - GITHUB_ACCESS_TOKEN: ${{ secrets.GH_READ_TOKEN }} - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + Cleanup-runs: runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v3 + - name: Cleanup ๐Ÿงน + uses: rokroskar/workflow-run-cleanup-action@master + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/master'" + + Install-tparse: + runs-on: ubuntu-latest + steps: + - name: Setup Go ๐Ÿงฐ + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Display go version ๐Ÿ›‚ + run: go version + + - name: Setup GOPRIVATE ๐Ÿ›ก๏ธ + run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/ + + - name: Install tparse ๐Ÿ” + run: | + export GO111MODULE="on" && go install github.com/mfridman/tparse@v0.8.3 + + - name: Cache ๐Ÿ’พ + uses: actions/cache@v4 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-tparse-binary + + Build: + runs-on: ubuntu-latest + strategy: + matrix: + go-arch: [ "amd64" ] + steps: + - name: Checkout ๐Ÿ›Ž๏ธ + uses: actions/checkout@v4 + + - name: Setup Go ๐Ÿงฐ + uses: actions/setup-go@v5 with: - go-version: 1.22 - - name: Install openssl - run: sudo apt-get install libssl-dev - - uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v4 + go-version: '1.22' + + - name: Setup GOPRIVATE ๐Ÿ›ก๏ธ + run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/ + + - name: Compute diff ๐Ÿ“œ + uses: technote-space/get-diff-action@v6.1.2 + id: git_diff with: PATTERNS: | **/**.go go.mod go.sum - # for private repo access - - run: git config --global url.https://${GITHUB_ACCESS_TOKEN}:x-oauth-basic@github.com/.insteadOf https://github.com/ - - name: build + + - name: Build ๐Ÿ”จ + run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build + + Split-test-files: + runs-on: ubuntu-latest + steps: + - name: Checkout ๐Ÿ›Ž๏ธ + uses: actions/checkout@v4 + + - name: Setup Go ๐Ÿงฐ + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Setup GOPRIVATE ๐Ÿ›ก๏ธ + run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/ + + - name: Create a file with all the pkgs ๐Ÿ“œ + run: go mod tidy && go list ./... > pkgs.txt + + - name: Split pkgs into 4 files โœ‚๏ธ + run: split -d -n l/4 pkgs.txt pkgs.txt.part. + + - name: Upload part 00 ๐Ÿ“ค + uses: actions/upload-artifact@v4 + with: + name: "${{ github.sha }}-00" + path: ./pkgs.txt.part.00 + + - name: Upload part 01 ๐Ÿ“ค + uses: actions/upload-artifact@v4 + with: + name: "${{ github.sha }}-01" + path: ./pkgs.txt.part.01 + + - name: Upload part 02 ๐Ÿ“ค + uses: actions/upload-artifact@v4 + with: + name: "${{ github.sha }}-02" + path: ./pkgs.txt.part.02 + + - name: Upload part 03 ๐Ÿ“ค + uses: actions/upload-artifact@v4 + with: + name: "${{ github.sha }}-03" + path: ./pkgs.txt.part.03 + + Tests: + runs-on: ubuntu-latest + needs: split-test-files + strategy: + fail-fast: false + matrix: + part: [ "00", "01", "02", "03" ] + steps: + - name: Checkout ๐Ÿ›Ž๏ธ + uses: actions/checkout@v4 + + - name: Setup Go ๐Ÿงฐ + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Setup GOPRIVATE ๐Ÿ›ก๏ธ + run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/ + + - name: Compute diff ๐Ÿ“œ + uses: technote-space/get-diff-action@v6.1.2 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + + - name: Download packages file ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-${{ matrix.part }}" + if: env.GIT_DIFF + + - name: Test & coverage report creation ๐Ÿงช run: | - make build - - name: test & coverage report creation + cat pkgs.txt.part.${{ matrix.part }} | xargs go test -mod=readonly -timeout 30m -coverprofile=${{ matrix.part }}profile.out -covermode=atomic -tags='norace ledger test_ledger_mock' + if: env.GIT_DIFF + + - name: Upload coverage ๐Ÿ“ค + uses: actions/upload-artifact@v4 + with: + name: "${{ github.sha }}-${{ matrix.part }}-coverage" + path: ./${{ matrix.part }}profile.out + + Upload-coverage-report: + runs-on: ubuntu-latest + needs: tests + steps: + - name: Checkout ๐Ÿ›Ž๏ธ + uses: actions/checkout@v4 + + - name: Compute diff ๐Ÿ“œ + uses: technote-space/get-diff-action@v6.1.2 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + + - name: Download coverage 00 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-00-coverage" + if: env.GIT_DIFF + + - name: Download coverage 01 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-01-coverage" + if: env.GIT_DIFF + + - name: Download coverage 02 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-02-coverage" + if: env.GIT_DIFF + + - name: Download coverage 03 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-03-coverage" + if: env.GIT_DIFF + + - name: Join coverage ๐Ÿ“‹ + run: | + cat ./*profile.out | grep -v "mode: atomic" >> coverage.txt + if: env.GIT_DIFF + + - name: Filter out DONTCOVER ๐Ÿ” + run: | + module=$(cat go.mod | grep module) + module=$(echo $module | sed "s/module //g") + + excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')" + excludelist+=" $(find ./ -type f -name '*.pb.go')" + excludelist+=" $(find ./ -type f -name '*.pb.gw.go')" + excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')" + for filename in ${excludelist}; do + filename=$(echo $filename | sed "s|^.|$module|g") + echo "Excluding ${filename} from coverage report..." + sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt + done + if: env.GIT_DIFF + + - name: Upload coverage to Codecov ๐Ÿ“ค + uses: codecov/codecov-action@v4 + with: + file: ./coverage.txt + if: env.GIT_DIFF + + Test-race: + runs-on: ubuntu-latest + needs: split-test-files + strategy: + fail-fast: false + matrix: + part: [ "00", "01", "02", "03" ] + steps: + - name: Checkout ๐Ÿ›Ž๏ธ + uses: actions/checkout@v4 + + - name: Setup Go ๐Ÿงฐ + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Setup GOPRIVATE ๐Ÿ›ก๏ธ + run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/ + + - name: Compute diff ๐Ÿ“œ + uses: technote-space/get-diff-action@v6.1.2 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + + - name: Download packages file ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-${{ matrix.part }}" + if: env.GIT_DIFF + + - name: Test & coverage report creation ๐Ÿงช run: | - go test ./... -mod=readonly -timeout 12m -race -coverprofile=coverage.txt -covermode=atomic -tags='ledger test_ledger_mock' - if: env.GIT_DIFF - # - name: filter out DONTCOVER - # run: | - # excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')" - # excludelist+=" $(find ./ -type f -name '*.pb.go')" - # for filename in ${excludelist}; do - # filename=$(echo $filename | sed 's/^./github.com\/initia-labs\/initia/g') - # echo "Excluding ${filename} from coverage report..." - # sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt - # done - # if: env.GIT_DIFF - - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage.txt - fail_ci_if_error: true + xargs --arg-file=pkgs.txt.part.${{ matrix.part }} go test -mod=readonly -json -timeout 30m -race -tags='cgo ledger test_ledger_mock' | tee ${{ matrix.part }}-race-output.txt if: env.GIT_DIFF + + - name: Upload coverage ๐Ÿ“ค + uses: actions/upload-artifact@v4 + with: + name: "${{ github.sha }}-${{ matrix.part }}-race-output" + path: ./${{ matrix.part }}-race-output.txt + + Race-detector-report: + runs-on: ubuntu-latest + needs: [ test-race, install-tparse ] + timeout-minutes: 5 + steps: + - name: Checkout ๐Ÿ›Ž๏ธ + uses: actions/checkout@v4 + + - name: Compute diff ๐Ÿ“œ + uses: technote-space/get-diff-action@v6.1.2 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + + - name: Download coverage 00 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-00-race-output" + if: env.GIT_DIFF + + - name: Download coverage 01 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-01-race-output" + if: env.GIT_DIFF + + - name: Download coverage 02 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-02-race-output" + if: env.GIT_DIFF + + - name: Download coverage 03 ๐Ÿ“ฅ + uses: actions/download-artifact@v4 + with: + name: "${{ github.sha }}-03-race-output" + if: env.GIT_DIFF + + - name: Save cache ๐Ÿ’พ + uses: actions/cache@v4 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-tparse-binary + if: env.GIT_DIFF + + - name: Generate test report (go test -race) ๐Ÿ“œ + run: cat ./*-race-output.txt | ~/go/bin/tparse + if: env.GIT_DIFF \ No newline at end of file diff --git a/Makefile b/Makefile index 6afc84a0..00a3b670 100644 --- a/Makefile +++ b/Makefile @@ -196,8 +196,9 @@ proto-check-breaking: .PHONY: proto-all proto-gen proto-swagger-gen proto-pulsar-gen proto-format proto-lint proto-check-breaking -######################################## -### Tools & dependencies +############################################################################### +### Tools & Dependencies ### +############################################################################### go-mod-cache: go.sum @echo "--> Download go modules to local cache" @@ -209,40 +210,63 @@ go.sum: go.mod draw-deps: @# requires brew install graphviz or apt-get install graphviz - go install github.com/RobotsAndPencils/goviz + @go install github.com/RobotsAndPencils/goviz @goviz -i ./cmd/milkd -d 2 | dot -Tpng -o dependency-graph.png -distclean: clean tools-clean clean: rm -rf \ $(BUILDDIR)/ \ artifacts/ \ tmp-swagger-gen/ -.PHONY: distclean clean +distclean: clean tools-clean +.PHONY: distclean clean ############################################################################### -### Tests +### Tests & Simulation ### ############################################################################### test: test-unit +test-all: test-unit test-ledger-mock test-race test-cover + +TEST_PACKAGES=./... +TEST_TARGETS := test-unit test-unit-amino test-unit-proto test-ledger-mock test-race test-ledger test-race + +# Test runs-specific rules. To add a new test target, just add +# a new rule, customise ARGS or TEST_PACKAGES ad libitum, and +# append the new rule to the TEST_TARGETS list. +test-unit: test_tags += cgo ledger test_ledger_mock norace +test-unit-amino: test_tags += ledger test_ledger_mock test_amino norace +test-ledger: test_tags += cgo ledger norace +test-ledger-mock: test_tags += ledger test_ledger_mock norace +test-race: test_tags += cgo ledger test_ledger_mock +test-race: ARGS=-race +test-race: TEST_PACKAGES=$(PACKAGES_NOSIMULATION) +$(TEST_TARGETS): run-tests + +ARGS += -tags "$(test_tags)" +SUB_MODULES = $(shell find . -type f -name 'go.mod' -print0 | xargs -0 -n1 dirname | sort) +CURRENT_DIR = $(shell pwd) + +run-tests: +ifneq (,$(shell which tparse 2>/dev/null)) + go test -mod=readonly -json $(ARGS) $(TEST_PACKAGES) | tparse +else + go test -mod=readonly $(ARGS) $(TEST_PACKAGES) +endif -test-all: test-unit test-race test-cover - -test-unit: - @VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock' ./... - -test-race: - @VERSION=$(VERSION) go test -mod=readonly -race -tags='ledger test_ledger_mock' ./... +.PHONY: run-tests test test-all $(TEST_TARGETS) -test-cover: - @go test -mod=readonly -timeout 30m -race -coverprofile=coverage.txt -covermode=atomic -tags='ledger test_ledger_mock' ./... +############################################################################### +### Benchmark ### +############################################################################### +becnchstat_cmd=golang.org/x/perf/cmd/benchstat benchmark: - @go test -timeout 20m -mod=readonly -bench=. ./... - -.PHONY: test test-all test-cover test-unit test-race benchmark + @go test -mod=readonly -bench=. -count=$(BENCH_COUNT) -run=^a ./... > bench-$(REF_NAME).txt + @test -e bench-master.txt && go run $(becnchstat_cmd) bench-master.txt bench-$(REF_NAME).txt || go run $(becnchstat_cmd) bench-$(REF_NAME).txt +.PHONY: benchmark ############################################################################### ### Linting ###