diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e3608b285..966ff508d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -28,24 +28,37 @@ jobs: name: integration-tests path: ./target/debug/sccache - backends: + integration-tests: runs-on: ubuntu-24.04 - needs: build + strategy: + matrix: + type: [backends, tools] steps: - name: Clone repository uses: actions/checkout@v5 - - uses: actions/download-artifact@v5 - with: - name: integration-tests - path: ./target/debug - - - name: Chmod for binary - run: chmod +x ./target/debug/sccache - - name: Test - run: cd tests/integration && make test-backends + run: cd tests/integration && WITH_COVERAGE=1 make test-${{ matrix.type }} + + - name: Build report + run: | + cd tests/integration + WITH_COVERAGE=1 make coverage-report + echo "Coverage files:" + ls ../../target/integration-coverage/profraw -l + echo "Coverage report:" + ls ../../target/integration-coverage/reports/lcov.info -l + + - name: Upload coverage results (to Codecov.io) + uses: codecov/codecov-action@v5 + with: + files: target/integration-coverage/reports/lcov.info + name: codecov-umbrella-integration-${{ matrix.type }} + fail_ci_if_error: true + # verbose: true + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} gha: runs-on: ubuntu-24.04 @@ -182,24 +195,6 @@ jobs: shell: bash run: cat "$SCCACHE_ERROR_LOG" - tools: - runs-on: ubuntu-24.04 - needs: build - - steps: - - uses: actions/checkout@v5 - - - uses: actions/download-artifact@v5 - with: - name: integration-tests - path: ./target/debug - - - name: Chmod for binary - run: chmod +x ./target/debug/sccache - - - name: Test - run: cd tests/integration && make test-tools - hip: # Probably wouldn't matter anyway since we run in a container, but staying # close to the version is better than not. diff --git a/tests/integration/Makefile b/tests/integration/Makefile index 51459cae7..7ab4a9382 100644 --- a/tests/integration/Makefile +++ b/tests/integration/Makefile @@ -6,6 +6,22 @@ export GID := $(shell id -g) PROJECT_ROOT := $(shell git rev-parse --show-toplevel) SCCACHE_BIN := $(PROJECT_ROOT)/target/debug/sccache + +# Coverage support via WITH_COVERAGE=1 +COVERAGE_DIR := $(PROJECT_ROOT)/target/integration-coverage + +ifdef WITH_COVERAGE +export WITH_COVERAGE +SCCACHE_BIN := $(PROJECT_ROOT)/target/coverage/debug/sccache +BUILD_TARGET_DIR := --target-dir target/coverage +# Container paths (docker-compose will receive these) +export SCCACHE_PATH := /sccache/target/coverage/debug/sccache +export LLVM_PROFILE_FILE := /coverage/profraw/%p-%m.profraw +else +# Default container path +export SCCACHE_PATH := /sccache/target/debug/sccache +endif + BACKENDS := redis redis-deprecated memcached memcached-deprecated s3 azblob webdav basedirs TOOLS := gcc clang cmake autotools coverage zstd @@ -72,23 +88,38 @@ help: @echo " make test-backends Run all backend tests" @echo " make clean Stop all services and clean up" @echo " make help Show this help" + @echo "" + @echo "Coverage Collection:" + @echo " Run any test with WITH_COVERAGE=1 to collect coverage data" + @echo " Example: WITH_COVERAGE=1 make test-redis" + @echo " Example: WITH_COVERAGE=1 make test-backends" + @echo " make coverage-report Generate lcov report from collected data" + @echo " make coverage-clean Clean coverage artifacts" -build: $(SCCACHE_BIN) $(PROJECT_ROOT)/target/integration-cargo-cache +build: $(SCCACHE_BIN) $(PROJECT_ROOT)/target/integration-cargo-cache $(COVERAGE_DIR)/profraw # Create a persistent cargo cache for integration tests, used to avoid re-downloading dependencies $(PROJECT_ROOT)/target/integration-cargo-cache: @mkdir -p $@ +$(COVERAGE_DIR)/profraw: + @mkdir -p $@ + $(SCCACHE_BIN): $(PROJECT_ROOT)/Cargo.toml $(PROJECT_ROOT)/Cargo.lock +ifdef WITH_COVERAGE + @echo "Building sccache with coverage instrumentation in Docker..." +else @echo "Building sccache in Docker..." +endif @docker run --rm \ -v $(PROJECT_ROOT):/sccache \ - -v integration-cargo-cache:/usr/local/cargo/registry \ + -v $(PROJECT_ROOT)/target/integration-cargo-cache:/usr/local/cargo/registry \ -w /sccache \ -e OPENSSL_NO_VENDOR=1 \ + $(if $(WITH_COVERAGE),-e RUSTFLAGS="-Cinstrument-coverage -Ccodegen-units=1 -Copt-level=0 -Coverflow-checks=off" -e CARGO_INCREMENTAL=0 -e "LLVM_PROFILE_FILE=/tmp/build-%p-%m.profraw") \ rust:latest \ bash -c "apt-get update -qq && apt-get install -y -qq libssl-dev pkg-config && \ - cargo build --all-features && \ + cargo build --all-features $(BUILD_TARGET_DIR) && \ chown -R $(UID):$(GID) target" @echo "Binary built: $(SCCACHE_BIN)" @ls -lh $(SCCACHE_BIN) @@ -118,6 +149,50 @@ test-tools: $(addprefix test-,$(TOOLS)) test: test-backends test-tools @echo "All tests completed" +coverage-report: + @echo "Generating coverage report from integration tests..." + @if [ ! -d "$(PROJECT_ROOT)/target/integration-coverage/profraw" ]; then \ + echo "Error: No coverage data found."; \ + echo "Run tests with: WITH_COVERAGE=1 make test-"; \ + exit 1; \ + fi + @if [ -z "$$(find $(PROJECT_ROOT)/target/integration-coverage/profraw -name '*.profraw' 2>/dev/null)" ]; then \ + echo "Error: No .profraw files found in coverage directory."; \ + echo "Run tests with: WITH_COVERAGE=1 make test-"; \ + exit 1; \ + fi + @echo "Generating coverage report..." + @docker run --rm \ + -v $(PROJECT_ROOT):/sccache \ + -v $(PROJECT_ROOT)/target/integration-cargo-cache:/usr/local/cargo/registry \ + -v sccache-coverage-tools:/usr/local/cargo/bin \ + -v sccache-rustup:/usr/local/rustup \ + -w /sccache \ + rust:latest \ + bash -c "rustup component add llvm-tools 2>/dev/null || true && \ + (which grcov >/dev/null 2>&1 || cargo install grcov --locked) && \ + mkdir -p target/integration-coverage/reports && \ + grcov target/integration-coverage/profraw \ + --binary-path target/coverage/debug \ + --source-dir . \ + --output-type lcov \ + --output-path target/integration-coverage/reports/lcov.info \ + --branch \ + --ignore-not-existing \ + --ignore '/*' \ + --ignore 'build.rs' \ + --excl-br-line '^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()' && \ + chown -R $(UID):$(GID) target/integration-coverage" + @echo "" + @echo "Coverage report generated:" + @echo " $(PROJECT_ROOT)/target/integration-coverage/reports/lcov.info" + @echo "" + @echo "View summary with: lcov --summary target/integration-coverage/reports/lcov.info" + clean: + @echo "Cleaning coverage artifacts..." + @rm -rf $(PROJECT_ROOT)/target/integration-coverage + @echo "Coverage artifacts cleaned" + @echo "Stopping and removing all test services..." @docker compose --profile '*' down -v @echo "Cleanup complete" diff --git a/tests/integration/docker-compose.yml b/tests/integration/docker-compose.yml index 12cb7e668..411d9e7ee 100644 --- a/tests/integration/docker-compose.yml +++ b/tests/integration/docker-compose.yml @@ -1,19 +1,21 @@ x-common-env: &common-env RUST_BACKTRACE: full - RUSTC_WRAPPER: /sccache/target/debug/sccache + RUSTC_WRAPPER: ${SCCACHE_PATH:-/sccache/target/debug/sccache} RUST_LOG: debug + SCCACHE_PATH: ${SCCACHE_PATH:-/sccache/target/debug/sccache} + LLVM_PROFILE_FILE: ${LLVM_PROFILE_FILE:-} x-test-runner: &test-runner user: "${UID:-1000}:${GID:-1000}" volumes: - ../../:/sccache:ro - ../../target/integration-cargo-cache:/usr/local/cargo/registry:rw + - ../../target/integration-coverage:/coverage:rw tmpfs: - /build:exec,uid=${UID:-1000},gid=${GID:-1000},mode=1777 working_dir: /build environment: <<: *common-env - SCCACHE_PATH: /sccache/target/debug/sccache x-health-check: &healthcheck interval: 2s @@ -264,6 +266,7 @@ services: image: silkeh/clang:21-trixie entrypoint: /sccache/tests/integration/scripts/test-cmake.sh environment: + <<: *common-env SCCACHE_DIR: /build/sccache profiles: - test @@ -297,7 +300,6 @@ services: entrypoint: /sccache/tests/integration/scripts/test-zstd.sh environment: <<: *common-env - SCCACHE_PATH: /sccache/target/debug/sccache CARGO_INCREMENTAL: "0" profiles: - test @@ -324,7 +326,6 @@ services: condition: service_started environment: <<: *common-env - SCCACHE_PATH: /sccache/target/debug/sccache profiles: - test - basedirs diff --git a/tests/integration/scripts/test-coverage.sh b/tests/integration/scripts/test-coverage.sh index 4302589dc..88329ef0d 100755 --- a/tests/integration/scripts/test-coverage.sh +++ b/tests/integration/scripts/test-coverage.sh @@ -3,7 +3,7 @@ set -euo pipefail SCCACHE="${SCCACHE_PATH:-/sccache/target/debug/sccache}" export RUSTFLAGS="-Cinstrument-coverage" -export LLVM_PROFILE_FILE="coverage-%p-%m.profraw" +export LLVM_PROFILE_FILE="${LLVM_PROFILE_FILE:-coverage-%p-%m.profraw}" export CARGO_INCREMENTAL=0 echo "=========================================="