Skip to content

Commit b3dd57d

Browse files
authored
Merge pull request #5966 from sysown/fix/codecov-path-merge-v3.0
fix(coverage): emit repo-root LCOV paths so TAP merges with unit-tests
2 parents 8bafb86 + 91f1d18 commit b3dd57d

3 files changed

Lines changed: 61 additions & 72 deletions

File tree

.github/workflows/CI-unit-tests-asan-coverage.yml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,18 +168,25 @@ jobs:
168168
path: coverage/lcov.info
169169
if-no-files-found: warn
170170

171+
- name: Require non-empty coverage/lcov.info
172+
# With disable_search + plugins:noop, a missing/empty LCOV would
173+
# make the Codecov step a silent no-op while fail_ci_if_error:false
174+
# keeps the job green. Fail here so coverage-generation regressions
175+
# are visible; Codecov SaaS outages remain non-blocking below.
176+
id: require-lcov
177+
if: always()
178+
run: test -s coverage/lcov.info
179+
171180
- name: Upload coverage to Codecov
172181
# Send the same lcov.info we already archive as a workflow artifact
173182
# to Codecov so PRs get the "this PR changes coverage of touched
174183
# files from N% to M%" comment and main accumulates a historical
175184
# graph at https://app.codecov.io/gh/sysown/proxysql.
176185
#
177-
# `if: always()` so coverage uploads regardless of whether the unit
178-
# tests themselves passed; partial coverage is still useful for
179-
# diagnosing why a PR went red. `fail_ci_if_error: false` so a
180-
# transient Codecov outage never gates a green CI run on a
181-
# third-party SaaS.
182-
if: always()
186+
# Upload when LCOV exists even if unit tests failed (partial coverage
187+
# is still useful). Skip only when require-lcov failed. Codecov SaaS
188+
# outages stay non-blocking via fail_ci_if_error: false.
189+
if: always() && steps.require-lcov.outcome == 'success'
183190
uses: codecov/codecov-action@v4
184191
with:
185192
codecov_yml_path: codecov.yml
@@ -198,6 +205,10 @@ jobs:
198205
# action silently falls back to legacy tokenless mode and the
199206
# upload fails.
200207
use_oidc: true
208+
# Only the explicit LCOV file. Default plugins include gcov which
209+
# auto-discovers leftover .gcno and pollutes the upload.
210+
disable_search: true
211+
plugins: noop
201212
fail_ci_if_error: false
202213
verbose: true
203214

codecov.yml

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,36 @@
1-
# Codecov server-side configuration for ProxySQL.
1+
# Codecov configuration for ProxySQL.
22
#
3-
# ---------------------------------------------------------------------------
4-
# Coverage path alignment (the `fixes` block below)
5-
# ---------------------------------------------------------------------------
6-
# ProxySQL uploads coverage to Codecov from two independent pipelines that
7-
# historically disagreed on the *root* of every source path, which left the
8-
# daemon's lib/ coverage filed under a phantom folder Codecov could not align
9-
# to the git tree. Symptom: lib/MySQL_Monitor.cpp (and every other daemon-only
10-
# file) showing a flat 0% on https://app.codecov.io/gh/sysown/proxysql even
11-
# though the integration suite exercises it heavily.
3+
# Path contract (both upload pipelines MUST emit the same shape):
124
#
13-
# The two pipelines:
5+
# TAP integration (flags tap-*)
6+
# test/infra/control/run-tests-isolated.bash normalizes every LCOV SF:
7+
# path to repo-root-relative form (lib/MySQL_Monitor.cpp, src/main.cpp,
8+
# test/tap/..., include/...).
149
#
15-
# 1. TAP integration groups (flags `tap-*`)
16-
# test/infra/control/run-tests-isolated.bash rewrites every LCOV `SF:`
17-
# path to a `proxysql/`-prefixed form (e.g. `proxysql/lib/MySQL_Monitor.cpp`).
18-
# The prefix matches the CI checkout layout — the repo is checked out into
19-
# a `proxysql/` subdirectory of the runner workspace, and codecov-cli's
20-
# network-file listing is rooted one level above it — but it does NOT match
21-
# the repository git tree, whose root holds lib/, src/, include/, test/.
10+
# Unit tests (flag unit-tests)
11+
# test/infra/control/run-unit-tests-asan-coverage.bash already emits
12+
# repo-root-relative paths (lcov --directory lib).
2213
#
23-
# 2. Unit tests (flag `unit-tests`)
24-
# test/infra/control/run-unit-tests-asan-coverage.bash captures with
25-
# `lcov --capture --directory lib`, producing repo-root-relative paths
26-
# (`lib/MySQL_Monitor.cpp`). A `--initial` baseline seeds every instrumented
27-
# line at 0%, so files the unit tests never execute (the monitor thread,
28-
# the admin handler, the session loop, ...) sit at 0% in this namespace.
14+
# Historically TAP prefixed paths with proxysql/ (matching the CI checkout
15+
# subdirectory). That created a phantom proxysql/ namespace on Codecov that
16+
# never merged with unit-tests lib/, so daemon-only files like
17+
# lib/MySQL_Monitor.cpp showed 0% despite thousands of real TAP hits.
18+
# The TAP sed rewrite and the GH-Actions codecov-action settings
19+
# (no network_prefix, disable_search, plugins:noop, root_dir:proxysql)
20+
# keep both pipelines on the git-tree path scheme.
2921
#
30-
# Because the TAP coverage landed under `proxysql/lib/...` and the unit-tests
31-
# baseline owned `lib/...`, the two never merged: browsing the canonical repo
32-
# path `lib/MySQL_Monitor.cpp` showed only the unit-tests 0% baseline, while the
33-
# real ~38% from the TAP daemon was orphaned (and ultimately dropped) under the
34-
# non-existent `proxysql/lib/` tree.
35-
#
36-
# `fixes` strips the `proxysql/` prefix from report paths during Codecov's
37-
# server-side processing, so the TAP namespace collapses onto the git-tree
38-
# paths (`proxysql/lib/MySQL_Monitor.cpp` -> `lib/MySQL_Monitor.cpp`) and merges
39-
# with the unit-tests sessions. Verified against a real `tap-legacy-g1` upload:
40-
# all 210 `SF:` paths resolve to an existing repo file after the strip, with
41-
# zero misses. The rule only matches paths beginning with `proxysql/`, so the
42-
# already-correct `unit-tests` paths (`lib/...`, `include/...`) are untouched.
43-
#
44-
# If the TAP pipeline is ever changed to emit repo-root-relative paths directly
45-
# (the cleaner long-term fix, which also needs the codecov-action `root_dir`
46-
# pointed at the checkout subdir in the reusable ci-*.yml workflows on the
47-
# GH-Actions branch), this rule becomes a harmless no-op and can be removed.
22+
# fixes: kept as a safety net for any leftover proxysql/-prefixed SF: lines
23+
# from older artifacts or partial rollouts. Becomes a no-op once every
24+
# producer emits repo-root paths.
25+
26+
codecov:
27+
# GitHub default branch is v3.0 (master is stale and has no codecov.yml).
28+
branch: v3.0
29+
4830
fixes:
4931
- "proxysql/::"
32+
33+
# Vendored test dependencies (Boost, googletest, etc.) drown out daemon
34+
# coverage. Keep test/tap/** included -- those are first-party TAP sources.
35+
ignore:
36+
- "test/deps/**"

test/infra/control/run-tests-isolated.bash

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -389,34 +389,25 @@ docker run \
389389
if [ -f \"\${coverage_file}\" ]; then
390390
echo \">>> Coverage report generated: \${coverage_file}\"
391391
392-
# Normalize SF: source-file paths in the LCOV report
393-
# so Codecov can resolve them against the runner workspace.
392+
# Normalize SF: paths to repo-root-relative form so TAP
393+
# coverage merges with unit-tests on Codecov.
394394
# fastcov emits a mix of:
395-
# SF:/opt/proxysql/include/X.h (absolute container path
396-
# embedded in .gcno files)
397-
# SF:lib/Y.cpp (relative to fastcov cwd
398-
# = /opt/proxysql)
399-
# SF:proxysql/src/Z.cpp (already correct)
400-
# codecov-cli's network_root_folder is the runner's
401-
# /home/runner/work/proxysql/proxysql and the repo content
402-
# lives at <network_root>/proxysql/, so only paths shaped
403-
# as 'SF:proxysql/...' get resolved -- the other two forms
395+
# SF:/opt/proxysql/include/X.h (absolute container path)
396+
# SF:/gcov/proxysql/lib/Y.cpp (GCOV_PREFIX layout)
397+
# SF:lib/Y.cpp (relative to /opt/proxysql)
398+
# SF:proxysql/src/Z.cpp (legacy prefixed form)
399+
# Unit-tests upload SF:lib/... (repo-root). Emitting the
400+
# same shape here is required: the old proxysql/ prefix
401+
# created a phantom namespace that never merged, leaving
402+
# lib/MySQL_Monitor.cpp at 0% despite real TAP hits.
404403
# NB to future editors: this whole script body is the
405404
# argument to an outer bash -c that is wrapped in
406-
# DOUBLE QUOTES. Inside those outer double quotes,
407-
# backticks still trigger command substitution and bare
408-
# double-quote characters terminate the argument early.
409-
# That means comments here must avoid backticks (use
410-
# apostrophes for inline code) and avoid any literal
411-
# double-quote character (use apostrophes, or escape
412-
# as backslash-double-quote like the script body does
413-
# for genuine strings).
414-
# are silently dropped server-side. On the previous green
415-
# run that meant Codecov stored 27 files / 5694 lines out
416-
# of the 84621 lines fastcov actually measured.
405+
# DOUBLE QUOTES. Comments must avoid backticks and bare
406+
# double-quote characters.
417407
sed -i \
418-
-e 's|^SF:/opt/proxysql/|SF:proxysql/|' \
419-
-e '/^SF:proxysql\\//!s|^SF:|SF:proxysql/|' \
408+
-e 's|^SF:/opt/proxysql/|SF:|' \
409+
-e 's|^SF:/gcov/proxysql/|SF:|' \
410+
-e 's|^SF:proxysql/|SF:|' \
420411
\"\${coverage_file}\"
421412
422413
if command -v genhtml >/dev/null 2>&1; then

0 commit comments

Comments
 (0)