Skip to content

feat(coverage): hybrid xtrace/DEBUG-trap coverage engine (ADR-009)Β #860

Description

@Chemaclass

🎯 Goal

Implement the hybrid coverage engine recommended by ADR-009 (spike #859): use set -x β†’ a dedicated BASH_XTRACEFD, parsed offline, on Bash 4.1+; keep the current DEBUG-trap engine as the fallback on the Bash 3.0–4.0 floor. Selected via BASHUNIT_COVERAGE_ENGINE=auto|xtrace|trap (auto = xtrace iff BASH_XTRACEFD exists).

Measured payoff (ADR-009): ~6× lower per-line cost (bash 3.2 +0.855s→+0.127s; bash 5 +0.730s→+0.131s) — enough to make --coverage a candidate for a gating CI job instead of nightly-only.

πŸ“ Context

  • Current engine: DEBUG trap β†’ bashunit::coverage::record_line per line (src/coverage.sh:126). The trap dispatch dominates cost (proven by perf(coverage): dedup line hits at source in the DEBUG trapΒ #853: dedup was break-even).
  • ADR: adrs/adr-009-coverage-tracing-engine.md. Reproducible benchmark: adrs/assets/adr-009-cov-engine-bench.sh.

πŸ”§ Scope

  1. Engine selector + BASHUNIT_COVERAGE_ENGINE (default auto); auto probes BASH_XTRACEFD availability once.
  2. xtrace engine: per-run (and per-worker) trace file on a dedicated fd; PS4='@@${BASH_SOURCE}:${LINENO} '; offline parser producing the same covered-line set + branch inputs the trap path feeds today.
  3. Per-test attribution: emit a sentinel line into the trace at each test boundary (replaces _BASHUNIT_COVERAGE_CURRENT_TEST_*); partition the parse by sentinel.
  4. Sandbox self-instrumentation: save/restore PS4/BASH_XTRACEFD/set -x around test bodies so a test using set -x doesn't corrupt (or get corrupted by) the engine.
  5. --parallel: one trace file per worker, merged like the per-$$ data files.
  6. Framework-line filtering via the existing should_track path rules.

βœ… Acceptance criteria

  • Byte-for-byte identical coverage output (covered-line set, branch arms, per-test attribution, LCOV) between xtrace and trap engines across the coverage fixture suite β€” pin this as the RED test (engine equivalence oracle).
  • auto selects trap on Bash <4.1 and xtrace on β‰₯4.1; all three modes forced-selectable.
  • --parallel coverage correct under both engines.
  • No regression to the Bash 3.0 floor (trap path unchanged there).
  • Only after equivalence is proven: consider promoting --coverage to a gating workflow.

⛓️ Constraints

  • Bash 3.0+ core; xtrace path is strictly a 4.1+ fast path with the trap fallback intact.
  • Do not flip the default engine until equivalence is green on all platforms (Linux/macOS/Windows-bash, Bash 3.2β†’5).

Follow-up to the #854 spike / ADR-009.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions