diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a5968f8..7df06ed 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -27,26 +27,7 @@ jobs: run: make build - name: Run Go tests run: make test - - name: Code Coverage Report - uses: irongut/CodeCoverageSummary@v1.3.0 - with: - filename: coverage.xml - badge: true - fail_below_min: false - format: markdown - hide_branch_rate: false - hide_complexity: true - indicators: true - output: both - thresholds: '60 80' - - uses: jwalton/gh-find-current-pr@v1 - id: finder - - name: Add Coverage PR Comment - uses: marocchino/sticky-pull-request-comment@v2 - with: - number: ${{ steps.finder.outputs.pr }} - path: code-coverage-results.md - recreate: true + - name: Upload artifact uses: actions/upload-artifact@v4 with: @@ -156,6 +137,75 @@ jobs: - name: Run Debian package tests run: make debian-test-ci + coverage: + name: Test Coverage + needs: go + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + env: + BATS_LIB_PATH: "${{ github.workspace }}/test/bats/lib/" + PGHOST: localhost + PGUSER: postgres + PGPASSWORD: hackme + PGDATABASE: unittest + services: + postgres: + image: postgres:14 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + --hostname postgres + env: + POSTGRES_PASSWORD: hackme + ports: + - 5432:5432 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.21' + - name: Install dependencies + run: | + go get . + - name: Build + run: make build + + - name: Setup Bats and bats libs + uses: bats-core/bats-action@2.0.0 + with: + support-path: ${{ github.workspace }}/test/bats/lib/bats-support + assert-path: ${{ github.workspace }}/test/bats/lib/bats-assert + file-install: false # Unused + detik-install: false # Unused + + - name: Run Go and e2e tests + run: make coverage + + - name: Code Coverage Report + uses: irongut/CodeCoverageSummary@v1.3.0 + with: + filename: coverage.xml + badge: true + fail_below_min: false + format: markdown + hide_branch_rate: false + hide_complexity: true + indicators: true + output: both + thresholds: '60 80' + - uses: jwalton/gh-find-current-pr@v1 + id: finder + - name: Add Coverage PR Comment + uses: marocchino/sticky-pull-request-comment@v2 + with: + number: ${{ steps.finder.outputs.pr }} + path: code-coverage-results.md + recreate: true + # checkcov: # permissions: # security-events: write # for github/codeql-action/upload-sarif to upload SARIF results diff --git a/Makefile b/Makefile index 32a126a..1aeaac2 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ BUILD_INFO_PACKAGE_PATH=github.com/qonto/postgresql-partition-manager/internal/i BUILD_DATE=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') GIT_COMMIT_SHA=$(shell git rev-parse HEAD) BINARY=postgresql-partition-manager +COVER_BINARY=test-postgresql-partition-manager ARCHITECTURE=$(shell uname -m) HELM_CHART_NAME=postgresql-partition-manager-chart RELEASE_VERSION=$(shell jq .tag dist/metadata.json) @@ -18,6 +19,23 @@ format: build: CGO_ENABLED=0 go build -v -ldflags="-X '$(BUILD_INFO_PACKAGE_PATH).Version=development' -X '$(BUILD_INFO_PACKAGE_PATH).CommitSHA=$(GIT_COMMIT_SHA)' -X '$(BUILD_INFO_PACKAGE_PATH).Date=$(BUILD_DATE)'" -o $(BINARY) +coverage: $(COVER_BINARY) + test -d ./coverage-data || mkdir ./coverage-data + rm -f ./coverage-data/cov* +# run tests with the testing package + go test -v ./... -cover -test.gocoverdir=$(PWD)/coverage-data -covermode set +# run e2e test collecting coverage data + cd scripts/bats && GOCOVERDIR=$(PWD)/coverage-data bats *.bats +# merge the collected traces + go tool covdata textfmt -i=./coverage-data -o coverage.txt + go run github.com/boumenot/gocover-cobertura@latest < coverage.txt > coverage.xml + go tool cover -html coverage.txt -o cover.html + + +# build for coverage +$(COVER_BINARY): build + CGO_ENABLED=0 go build -cover -v -ldflags="-X '$(BUILD_INFO_PACKAGE_PATH).Version=development' -X '$(BUILD_INFO_PACKAGE_PATH).CommitSHA=$(GIT_COMMIT_SHA)' -X '$(BUILD_INFO_PACKAGE_PATH).Date=$(BUILD_DATE)'" -o $(COVER_BINARY) + .PHONY: run run: ./$(BINARY) $(args) @@ -27,8 +45,9 @@ install: build GOBIN=/usr/local/bin/ go install -v -ldflags="-X '$(BUILD_INFO_PACKAGE_PATH).Version=development' -X '$(BUILD_INFO_PACKAGE_PATH).CommitSHA=$(GIT_COMMIT_SHA)' -X '$(BUILD_INFO_PACKAGE_PATH).Date=$(BUILD_DATE)'" .PHONY: bats-test -bats-test: - cd scripts/bats && bats *.bats +bats-test: build $(COVER_BINARY) + test -d ./coverage-data || mkdir ./coverage-data + cd scripts/bats && GOCOVERDIR=$(PWD)/coverage-data bats *.bats .PHONY: helm-test helm-test: @@ -60,9 +79,8 @@ checkcov: .PHONY: test test: - go test -race -v ./... -coverprofile=coverage.txt -covermode atomic - go run github.com/boumenot/gocover-cobertura@latest < coverage.txt > coverage.xml - go tool cover -html coverage.txt -o cover.html + test -d ./coverage-data || mkdir ./coverage-data + go test -v ./... -cover -test.gocoverdir=$(PWD)/coverage-data -covermode set .PHONY: lint lint: diff --git a/scripts/bats/00_cli.bats b/scripts/bats/00_cli.bats index 60e35c1..07ee334 100644 --- a/scripts/bats/00_cli.bats +++ b/scripts/bats/00_cli.bats @@ -1,17 +1,20 @@ +load 'test/libs/startup' + setup() { - bats_load_library bats-support - bats_load_library bats-assert + bats_load_library bats-support + bats_load_library bats-assert + ppm_setup } @test "Test returns its version" { - run postgresql-partition-manager --version + run "$PPM_PROG" --version assert_success assert_output --partial "postgresql-partition-manager version development" } @test "Test help message" { - run postgresql-partition-manager --help + run "$PPM_PROG" --help assert_success assert_output --partial "Simplified PostgreSQL partitioning management" diff --git a/scripts/bats/10_validate.bats b/scripts/bats/10_validate.bats index 2f57e54..28132cb 100644 --- a/scripts/bats/10_validate.bats +++ b/scripts/bats/10_validate.bats @@ -1,11 +1,14 @@ +load 'test/libs/startup' + setup() { bats_load_library bats-support bats_load_library bats-assert + ppm_setup } # Test for program's behavior when the configuration file is empty @test "Program should exit when passed an empty configuration file" { - run postgresql-partition-manager validate -c /dev/null + run "$PPM_PROG" validate -c /dev/null assert_failure assert_equal "$status" 1 @@ -15,7 +18,7 @@ setup() { } @test "Ensure validate command executes successfully with a valid configuration file" { - run postgresql-partition-manager validate -c configuration/valid.yaml + run "$PPM_PROG" validate -c configuration/valid.yaml assert_success assert_output --partial "Configuration is valid" diff --git a/scripts/bats/20_check.bats b/scripts/bats/20_check.bats index b7b54be..72c7761 100644 --- a/scripts/bats/20_check.bats +++ b/scripts/bats/20_check.bats @@ -1,3 +1,4 @@ +load 'test/libs/startup' load 'test/libs/dependencies' load 'test/libs/partitions' load 'test/libs/seeds' @@ -10,10 +11,11 @@ setup_file() { setup() { bats_load_library bats-support bats_load_library bats-assert + ppm_setup } @test "Test exit code on PostgreSQL connection error" { - run postgresql-partition-manager run check -c configuration/valid.yaml --connection-url an-invalid-connection-url + run "$PPM_PROG" run check -c configuration/valid.yaml --connection-url an-invalid-connection-url assert_failure assert_equal "$status" 3 @@ -43,7 +45,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - run postgresql-partition-manager run check -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run check -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly configured" @@ -73,7 +75,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - run postgresql-partition-manager run check -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run check -c ${CONFIGURATION_FILE} assert_failure assert_output --partial "Found missing tables" @@ -103,7 +105,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - run postgresql-partition-manager run check -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run check -c ${CONFIGURATION_FILE} assert_failure assert_output --partial "Found missing tables" @@ -141,7 +143,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - PPM_WORK_DATE="2025-02-10" run postgresql-partition-manager run check -c ${CONFIGURATION_FILE} + PPM_WORK_DATE="2025-02-10" run "$PPM_PROG" run check -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly configured" diff --git a/scripts/bats/30_provisioning.bats b/scripts/bats/30_provisioning.bats index 2765450..a2e9fb8 100644 --- a/scripts/bats/30_provisioning.bats +++ b/scripts/bats/30_provisioning.bats @@ -1,3 +1,4 @@ +load 'test/libs/startup' load 'test/libs/dependencies' load 'test/libs/partitions' load 'test/libs/seeds' @@ -11,6 +12,7 @@ setup_file() { setup() { bats_load_library bats-support bats_load_library bats-assert + ppm_setup } @test "Test that provisioning succeed on up-to-date partitioning" { @@ -36,7 +38,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly provisioned" @@ -68,7 +70,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly provisioned" @@ -82,7 +84,7 @@ EOF yq eval ".partitions.unittest.retention = ${NEW_RETENTION}" -i ${CONFIGURATION_FILE} yq eval ".partitions.unittest.preProvisioned = ${NEW_PREPROVISIONED}" -i ${CONFIGURATION_FILE} - run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly provisioned" @@ -118,7 +120,7 @@ EOF cat ${CONFIGURATION_FILE} - run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly provisioned" @@ -153,7 +155,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success @@ -189,7 +191,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly provisioned" @@ -222,7 +224,7 @@ EOF ) local CONFIGURATION_FILE=$(generate_configuration_file "${CONFIGURATION}") - PPM_WORK_DATE="2025-01-20" run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + PPM_WORK_DATE="2025-01-20" run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success assert_output --partial "All partitions are correctly provisioned" @@ -242,7 +244,7 @@ EOF yq eval ".partitions.unittest.retention = 2" -i ${CONFIGURATION_FILE} yq eval ".partitions.unittest.preProvisioned = 10" -i ${CONFIGURATION_FILE} - PPM_WORK_DATE="2025-02-01" run postgresql-partition-manager run provisioning -c ${CONFIGURATION_FILE} + PPM_WORK_DATE="2025-02-01" run "$PPM_PROG" run provisioning -c ${CONFIGURATION_FILE} assert_success local expected_mix=$(cat </dev/null 2>&1 && pwd )" + PPM_PROG="$DIR/../../test-postgresql-partition-manager" +}