diff --git a/.github/workflows/ci-rust.yml b/.github/workflows/ci-rust.yml index 70490c8..3c664bb 100644 --- a/.github/workflows/ci-rust.yml +++ b/.github/workflows/ci-rust.yml @@ -66,3 +66,10 @@ jobs: run: ./pleasew --plain_output test //... env: VERITAS_NO_HOOK: "1" + + - name: Coverage smoke test (lib_test) + run: | + ./pleasew --plain_output cover //test/rust/lib:lib_test 2>&1 | tee cover.log + grep -Eq '^\s+lib\.rs [1-9][0-9]*/' cover.log + env: + VERITAS_NO_HOOK: "1" diff --git a/CHANGELOG.md b/CHANGELOG.md index dfa8901..76c6ab7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +- `rust_test` ignored `LlvmProfdataTool`, `LlvmCovTool` and `Coverage` (plugin + config was read with `CONFIG.get`, which does not see it), so `llvm-profdata` + was taken from the host. With an older host LLVM the merge failed + (`unsupported instrumentation profile format version`) and `plz cover` + reported 0%. The configured tools are now passed to the test. +- The coverage error now names the `llvm-profdata` that failed. + +### Documentation + +- Documented the Rust coverage report location, format and contents, and the + silent `No data` result when `[cover] fileextension = .rs` is missing. +- Added a CI coverage smoke test. + ## [0.5.0] - 2026-09-19 ### Added diff --git a/build_defs/rust/rust.build_defs b/build_defs/rust/rust.build_defs index fe0a648..2792b1e 100644 --- a/build_defs/rust/rust.build_defs +++ b/build_defs/rust/rust.build_defs @@ -61,13 +61,13 @@ def _is_coverage_enabled(rule_coverage=None): """Determines whether coverage instrumentation is enabled for a target.""" if rule_coverage is not None: return rule_coverage - return CONFIG.get("RUST.COVERAGE", "true").lower() in ("true", "1", "yes", "on") + return (CONFIG.RUST.COVERAGE or "true").lower() in ("true", "1", "yes", "on") def _test_tools(profdata_override=None, cov_override=None): """Returns test_tools dictionary for rust_test.""" tools = {"TOOL": [_rust_tool()]} - profdata = profdata_override or CONFIG.get("RUST.LLVM_PROFDATA_TOOL", "") - cov = cov_override or CONFIG.get("RUST.LLVM_COV_TOOL", "") + profdata = profdata_override or CONFIG.RUST.LLVM_PROFDATA_TOOL + cov = cov_override or CONFIG.RUST.LLVM_COV_TOOL if profdata and (profdata.startswith("//") or profdata.startswith("///") or profdata.startswith(":")): tools["LLVM_PROFDATA"] = [profdata] if cov and (cov.startswith("//") or cov.startswith("///") or cov.startswith(":")): diff --git a/docs/rust/usage.md b/docs/rust/usage.md index 23c4116..e8cd5ab 100644 --- a/docs/rust/usage.md +++ b/docs/rust/usage.md @@ -308,7 +308,18 @@ Display detailed, line-by-line covered source listings: ./pleasew cover -l //test/lib:lib_test ``` -### 4. Per-Rule Coverage Control +### 4. Report Output + +- **Location**: Please merges the per-test results into + `plz-out/log/coverage.xml` (Cobertura XML) and `plz-out/log/coverage.json` + (per-file line markers plus per-file and per-directory percentages). +- **Contents**: line coverage only. Branch coverage and per-function data are + not emitted, so consumers cannot join coverage with per-function complexity + from this report. +- **Missing `[cover]` setting**: without `fileextension = .rs` the report is + silently `Total coverage: No data`. + +### 5. Per-Rule Coverage Control You can enable or disable coverage instrumentation on individual rules: diff --git a/tools/please_rust/testrunner/runner.go b/tools/please_rust/testrunner/runner.go index f104b6f..28cfcf9 100644 --- a/tools/please_rust/testrunner/runner.go +++ b/tools/please_rust/testrunner/runner.go @@ -133,7 +133,8 @@ func mergeProfdata(profdataPath, tmpDir string, profrawFiles []string) (string, cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - return "", fmt.Errorf("llvm-profdata merge failed: %w", err) + version, _ := exec.Command(resolved, "--version").CombinedOutput() + return "", fmt.Errorf("llvm-profdata merge failed using %s (%s): %w", resolved, strings.Join(strings.Fields(string(version)), " "), err) } return mergedPath, nil }