From 0233c39a7f3b261fcfe465e2ce2dfb03c0e9bd4e Mon Sep 17 00:00:00 2001 From: Jev Forsberg <46619047+baldm0mma@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:00:13 -0600 Subject: [PATCH] Chore: Add Enterprise unit testing path (#101748) * Add backend unit tests for Grafana and Grafana Enterprise --------- Co-authored-by: Kevin Minehart --- .github/CODEOWNERS | 2 + .github/actions/setup-enterprise/action.yml | 48 +++++++ .github/workflows/pr-backend-coverage.yml | 69 ++++++++++ .github/workflows/pr-backend-unit-tests.yml | 132 ++++++++++++-------- Makefile | 14 ++- 5 files changed, 209 insertions(+), 56 deletions(-) create mode 100644 .github/actions/setup-enterprise/action.yml create mode 100644 .github/workflows/pr-backend-coverage.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d6ebd9a6a09..1b4b6f34d65 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -756,6 +756,7 @@ embed.go @grafana/grafana-as-code /.github/pr-checks.json @tolzhabayev /.github/pr-commands.json @tolzhabayev /.github/renovate.json5 @grafana/frontend-ops +/.github/actions/setup-enterprise/action.yml @grafana/grafana-backend-group /.github/actions/test-coverage-processor/action.yml @grafana/grafana-backend-group /.github/actions/setup-grafana-bench/ @Proximyst /.github/workflows/add-to-whats-new.yml @grafana/docs-tooling @@ -792,6 +793,7 @@ embed.go @grafana/grafana-as-code /.github/workflows/pr-commands.yml @tolzhabayev /.github/workflows/pr-patch-check.yml @grafana/grafana-developer-enablement-squad /.github/workflows/pr-backend-unit-tests.yml @grafana/grafana-backend-group +/.github/workflows/pr-backend-coverage.yml @grafana/grafana-backend-group /.github/workflows/sync-mirror.yml @grafana/grafana-developer-enablement-squad /.github/workflows/publish-technical-documentation-next.yml @grafana/docs-tooling /.github/workflows/publish-technical-documentation-release.yml @grafana/docs-tooling diff --git a/.github/actions/setup-enterprise/action.yml b/.github/actions/setup-enterprise/action.yml new file mode 100644 index 00000000000..e87d3d7bae9 --- /dev/null +++ b/.github/actions/setup-enterprise/action.yml @@ -0,0 +1,48 @@ +name: 'Setup Grafana Enterprise' +description: 'Clones and sets up Grafana Enterprise repository for testing' + +inputs: + github-app-name: + description: 'Name of the GitHub App in Vault' + required: false + default: 'grafana-ci-bot' + +runs: + using: "composite" + steps: + - name: Retrieve GitHub App secrets + id: get-secrets + uses: grafana/shared-workflows/actions/get-vault-secrets@get-vault-secrets-v1.0.1 + with: + repo_secrets: | + APP_ID=${{ inputs.github-app-name }}:app-id + APP_INSTALLATION_ID=${{ inputs.github-app-name }}:app-installation-id + PRIVATE_KEY=${{ inputs.github-app-name }}:private-key + + - name: Generate GitHub App token + id: generate_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ env.APP_ID }} + private-key: ${{ env.PRIVATE_KEY }} + repositories: "grafana-enterprise" + owner: "grafana" + + - name: Setup Enterprise + shell: bash + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git clone https://x-access-token:${GH_TOKEN}@github.com/grafana/grafana-enterprise.git ../grafana-enterprise; + + cd ../grafana-enterprise + + if git checkout ${GITHUB_HEAD_REF}; then + echo "checked out ${GITHUB_HEAD_REF}" + elif git checkout ${GITHUB_BASE_REF}; then + echo "checked out ${GITHUB_BASE_REF}" + else + git checkout main + fi + + ./build.sh diff --git a/.github/workflows/pr-backend-coverage.yml b/.github/workflows/pr-backend-coverage.yml new file mode 100644 index 00000000000..7935860c798 --- /dev/null +++ b/.github/workflows/pr-backend-coverage.yml @@ -0,0 +1,69 @@ +name: Coverage + +on: + workflow_dispatch: + push: + branches: + - main + paths-ignore: + - 'docs/**' + - '**/*.md' + +permissions: + contents: read + id-token: write + +env: + EDITION: 'oss' + WIRE_TAGS: 'oss' + +jobs: + main: + name: Backend Unit Tests + runs-on: ubuntu-latest-8-cores + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential shared-mime-info + go install github.com/mfridman/tparse@c1754a1f484ac5cd422697b0fec635177ddc8507 # v0.17.0 + - name: Generate Go code + run: make gen-go + - name: Run unit tests + run: COVER_OPTS="-coverprofile=be-unit.cov -coverpkg=github.com/grafana/grafana/..." GO_TEST_OUTPUT="/tmp/unit.log" make test-go-unit-cov + - name: Process and upload coverage + uses: ./.github/actions/test-coverage-processor + with: + test-type: 'be-unit' + # Needs to be named 'unit.cov' based on the Makefile command `make test-go-unit` + coverage-file: 'unit.cov' + codecov-token: ${{ secrets.CODECOV_TOKEN }} + codecov-flag: 'be-unit' + codecov-name: 'be-unit' + + - name: Install Grafana Bench + # We can't allow forks here, as we need secret access. + if: ${{ github.event_name != 'pull_request' }} + uses: ./.github/actions/setup-grafana-bench + + - name: Process output for Bench + if: ${{ github.event_name != 'pull_request' }} + run: | + grafana-bench report \ + --trigger pr-backend-unit-tests-oss \ + --report-input go \ + --report-output log \ + --grafana-version "$(git rev-parse HEAD)" \ + --suite-name grafana-oss-unit-tests \ + /tmp/unit.log + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false diff --git a/.github/workflows/pr-backend-unit-tests.yml b/.github/workflows/pr-backend-unit-tests.yml index 99ec9b0ea49..f81b9c8f6ac 100644 --- a/.github/workflows/pr-backend-unit-tests.yml +++ b/.github/workflows/pr-backend-unit-tests.yml @@ -1,78 +1,104 @@ name: Backend Unit Tests on: - workflow_dispatch: - push: - branches: - - main - paths-ignore: - - 'docs/**' - - '**/*.md' pull_request: paths-ignore: - 'docs/**' - '**/*.md' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read id-token: write -env: - EDITION: 'oss' - WIRE_TAGS: 'oss' - jobs: - backend-testing-coverage: - name: Backend Testing & Coverage - runs-on: ubuntu-latest + grafana: + # Run this workflow only for PRs from forks; if it gets merged into `main` or `release-*`, + # the `pr-backend-unit-tests-enterprise` workflow will run instead + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true + name: Grafana + runs-on: ubuntu-latest-8-cores + continue-on-error: true steps: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Go uses: actions/setup-go@v5 with: go-version-file: go.mod - cache: true - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y build-essential shared-mime-info - go install github.com/mfridman/tparse@c1754a1f484ac5cd422697b0fec635177ddc8507 # v0.17.0 - + - name: Restore GOCACHE + uses: actions/cache/restore@v4 + with: + key: go-test-cache-${{ github.ref_name }} + restore-keys: | + go-test-cache-${{ github.base_ref }} + go-test-cache-main + path: /home/runner/.cache/go-build - name: Generate Go code run: make gen-go - - name: Run unit tests - run: COVER_OPTS="-coverprofile=be-unit.cov -coverpkg=github.com/grafana/grafana/..." GO_TEST_OUTPUT="/tmp/unit.log" make test-go-unit - - - name: Process and upload coverage - uses: ./.github/actions/test-coverage-processor + run: make test-go-unit + - name: "Generate token" + id: generate_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 with: - test-type: 'be-unit' - # Needs to be named 'unit.cov' based on the Makefile command `make test-go-unit` - coverage-file: 'unit.cov' - codecov-token: ${{ secrets.CODECOV_TOKEN }} - codecov-flag: 'be-unit' - codecov-name: 'be-unit' + app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + - name: Clear GOCACHE + run: gh cache delete go-test-cache-${{ github.ref_name }} + continue-on-error: true + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + - name: Save GOCACHE + uses: actions/cache/save@v4 + with: + key: go-test-cache-${{ github.ref_name }} + path: /home/runner/.cache/go-build - - name: Install Grafana Bench - # We can't allow forks here, as we need secret access. - if: ${{ github.event_name != 'pull_request' }} - uses: ./.github/actions/setup-grafana-bench - - - name: Process output for Bench - if: ${{ github.event_name != 'pull_request' }} - run: | - grafana-bench report \ - --trigger pr-backend-unit-tests-oss \ - --report-input go \ - --report-output log \ - --grafana-version "$(git rev-parse HEAD)" \ - --suite-name grafana-oss-unit-tests \ - /tmp/unit.log - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + grafana-enterprise: + # Run this workflow for non-PR events (like pushes to `main` or `release-*`) OR for internal PRs (PRs not from forks) + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false + name: Grafana Enterprise + runs-on: ubuntu-latest-8-cores + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + - name: Restore GOCACHE + uses: actions/cache/restore@v4 + with: + key: go-test-cache-${{ github.ref_name }}-enterprise + restore-keys: | + go-test-cache-${{ github.base_ref }}-enterprise + go-test-cache-main-enterprise + path: /home/runner/.cache/go-build + - name: Setup Enterprise + uses: ./.github/actions/setup-enterprise + with: + github-app-name: 'grafana-ci-bot' + - name: Generate Go code + run: make gen-go + - name: Run unit tests + run: make test-go-unit + - name: "Generate token" + id: generate_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + - name: Clear GOCACHE + run: gh cache delete go-test-cache-${{ github.ref_name }}-enterprise + continue-on-error: true + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + - name: Save GOCACHE + uses: actions/cache/save@v4 + with: + key: go-test-cache-${{ github.ref_name }}-enterprise + path: /home/runner/.cache/go-build diff --git a/Makefile b/Makefile index 699cfb0652e..a90b6df1dcb 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,9 @@ GO_BUILD_FLAGS += $(if $(GO_BUILD_DEV),-dev) GO_BUILD_FLAGS += $(if $(GO_BUILD_TAGS),-build-tags=$(GO_BUILD_TAGS)) GO_BUILD_FLAGS += $(GO_RACE_FLAG) GO_TEST_OUTPUT := $(shell [ -n "$(GO_TEST_OUTPUT)" ] && echo '-json | tee $(GO_TEST_OUTPUT) | tparse -all') +GO_UNIT_COVERAGE ?= true +GO_UNIT_COVER_PROFILE ?= unit.cov +GO_INTEGRATION_COVER_PROFILE ?= integration.cov GIT_BASE = remotes/origin/main # GNU xargs has flag -r, and BSD xargs (e.g. MacOS) has that behaviour by default @@ -246,8 +249,13 @@ test-go: test-go-unit test-go-integration .PHONY: test-go-unit test-go-unit: ## Run unit tests for backend with flags. - @echo "test backend unit tests" - $(GO) test $(GO_RACE_FLAG) -short -covermode=atomic -coverprofile=unit.cov -timeout=30m $(GO_TEST_FILES) $(GO_TEST_OUTPUT) + @echo "backend unit tests" + $(GO) test $(GO_RACE_FLAG) -v -short -timeout=30m $(GO_TEST_FILES) $(GO_TEST_OUTPUT) + +.PHONY: test-go-unit-cov +test-go-unit-cov: ## Run unit tests for backend with flags and coverage + @echo "backend unit tests with coverage" + $(GO) test $(GO_RACE_FLAG) -v -short $(if $(filter true,$(GO_UNIT_COVERAGE)),-covermode=atomic -coverprofile=$(GO_UNIT_COVER_PROFILE) $(if $(GO_UNIT_TEST_COVERPKG),-coverpkg=$(GO_UNIT_TEST_COVERPKG)),) -timeout=30m $(GO_TEST_FILES) $(GO_TEST_OUTPUT) .PHONY: test-go-unit-pretty test-go-unit-pretty: check-tparse @@ -260,7 +268,7 @@ test-go-unit-pretty: check-tparse .PHONY: test-go-integration test-go-integration: ## Run integration tests for backend with flags. @echo "test backend integration tests" - $(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegration" -covermode=atomic -coverprofile=integration.cov -timeout=5m $(GO_INTEGRATION_TESTS) $(GO_TEST_OUTPUT) + $(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegration" -covermode=atomic -coverprofile=$(GO_INTEGRATION_COVER_PROFILE) -timeout=5m $(GO_INTEGRATION_TESTS) $(GO_TEST_OUTPUT) .PHONY: test-go-integration-alertmanager test-go-integration-alertmanager: ## Run integration tests for the remote alertmanager (config taken from the mimir_backend block).