Skip to content

test(input-matrix): make the SAM/stdin comparisons non-vacuous - #663

Merged
nh13 merged 1 commit into
mainfrom
nh/test-de-vacuum-input-matrix
Jul 26, 2026
Merged

nh13 merged 1 commit into
mainfrom
nh/test-de-vacuum-input-matrix

Conversation

@nh13

@nh13 nh13 commented Jul 26, 2026 •

Copy link
Copy Markdown
Member

Stacked on #644 — please merge that one first. The base is nh/feat-accept-sam-input, so the diff here is only this change.

The problem

#644 added test_input_source_matrix.rs, which holds every command to two contracts: uncompressed SAM must be accepted anywhere BAM is, and -i - must be accepted by anything that streams. Both are checked by running the command two ways and comparing what it wrote against a named-path oracle.

That comparison is only evidence when the output depends on the records that went in. For five commands it did not:

  • simplex, duplex and codec were handed ungrouped reads and wrote a header-only BAM from any input, including no input at all.
  • simplex-metrics and duplex-metrics emitted identical all-zero tables either way, because the fixture carried nothing for them to count.

So for those five, a reader that silently dropped the entire stream still matched the oracle and the matrices passed. This was found by fault-injecting a header-only BAM while reviewing #644 — it predates that PR's stdin work and affected the SAM axis identically.

What this does

Fixtures they actually emit records from. duplex and duplex-metrics get both strands of one molecule, tagged RX plus a strand-suffixed MI. simplex and simplex-metrics get single-strand molecules instead — simplex-metrics rejects a base UMI seen on both strands outright ("received duplex-UMI data … run duplex-metrics"), so it cannot share the duplex shape. codec reuses the CODEC command's own pair builder rather than a second copy of the MI/MC/overlap invariants, and needs the same --min-reads/--min-duplex-length its own tests pass. Record counts for the five go 0/0/0 and all-zero → 4, 2, 1, 28 and 29.

An assertion instead of a caveat. #644 documented this limitation in a comment listing the affected commands, which is exactly the kind of thing that goes stale. Every command now declares a third contract axis, output_depends_on_input, and every_command_output_depends_on_its_input drives each fixture through its command twice — once populated, once drained of records — and fails if the two agree. A future fixture that stops producing records for a command breaks there, at the cause, rather than quietly hollowing out the other two matrices. The comment is now a pointer to that test.

zipper is the one declared exemption: it emits one output template per uBAM template and the uBAM arrives on -u, so an empty -i legitimately still yields every template, unmapped. Refusing an empty input outright also counts as depending on it, which is how extract passes.

Verification

Fault-injected in both directions rather than trusting a green run:

  • Restoring the old ungrouped shapes fails the new test for exactly the five affected commands and no others.
  • Declaring zipper Required fails it for zipper alone, so the exemption is load-bearing rather than an escape hatch.

cargo ci-test 6023 passed / 0 failed; ci-fmt, ci-lint, and both --no-default-features --all-targets and --all-features --all-targets checks clean. The cross-module reference to the CODEC pair builder follows the existing precedent in test_streaming_input.rs and was checked against the no-default-features build, where the self dev-dependency keeps those modules compiled.

Summary by CodeRabbit

  • Tests
    • Expanded integration coverage for duplex and single-strand molecule workflows.
    • Added validation to ensure command results respond appropriately to their input data.
    • Added empty-input scenarios across supported commands to detect misleading or unchanged outputs.
    • Improved coverage for codec options and input formats, including FASTQ, BAM, and paired-read fixtures.

@nh13
nh13 temporarily deployed to github-actions July 26, 2026 00:05 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 41 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 50530726-0c4f-4ab5-a8ef-e235ebdf6653

📥 Commits

Reviewing files that changed from the base of the PR and between 2597997 and ed4fde7.

📒 Files selected for processing (2)
  • tests/integration/helpers/bam_generator.rs
  • tests/integration/test_input_source_matrix.rs

Walkthrough

The integration matrix now declares whether command output must depend on input, generates populated and drained fixtures across input formats, and compares their outputs. New RX/MI-tagged duplex and single-strand BAM builders support expanded command-shape coverage.

Changes

Input dependence validation

Layer / File(s) Summary
Duplex and simplex fixture builders
tests/integration/helpers/bam_generator.rs
Adds RX/MI-tagged duplex and single-strand paired-record generators with strand-specific SAM flags, coordinates, and template lengths.
Contract and fixture-shape wiring
tests/integration/test_input_source_matrix.rs
Adds the output_depends_on_input contract axis and routes duplex, simplex, and codec shapes through fixture creation and invocation.
Drained-input comparison test
tests/integration/test_input_source_matrix.rs
Generates command-specific empty inputs and compares populated versus drained runs, allowing commands that reject empty input and declared non-applicable cases.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant InputSourceMatrix
  participant FixtureBuilder
  participant Command
  participant OutputComparator
  InputSourceMatrix->>FixtureBuilder: create populated fixture
  InputSourceMatrix->>Command: run with populated input
  InputSourceMatrix->>FixtureBuilder: create drained fixture
  InputSourceMatrix->>Command: run with drained input
  Command-->>OutputComparator: populated and drained outputs
  OutputComparator-->>InputSourceMatrix: detect identical output
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: strengthening SAM/stdin matrix tests so output comparisons are no longer vacuous.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nh/test-de-vacuum-input-matrix

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.91%. Comparing base (e10785b) to head (ed4fde7).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #663      +/-   ##
==========================================
+ Coverage   93.80%   93.91%   +0.10%     
==========================================
  Files         177      177              
  Lines      107658   107726      +68     
==========================================
+ Hits       100990   101172     +182     
+ Misses       6668     6554     -114     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nh13
nh13 force-pushed the nh/feat-accept-sam-input branch 2 times, most recently from 5650d82 to 3d49b1b Compare July 26, 2026 05:27
Base automatically changed from nh/feat-accept-sam-input to main July 26, 2026 05:31
@nh13
nh13 force-pushed the nh/test-de-vacuum-input-matrix branch from 95ea088 to 2597997 Compare July 26, 2026 05:42
@nh13
nh13 temporarily deployed to github-actions July 26, 2026 05:42 — with GitHub Actions Inactive
@nh13

nh13 commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@nh13

nh13 commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/integration/test_input_source_matrix.rs`:
- Around line 996-1000: Restrict the early return in the drained-run handling to
the specific expected empty-input rejection, rather than accepting every
non-zero exit from drained. Use the command’s existing status, stderr, or error
classification to identify and exempt only that known refusal; allow unrelated
failures such as invalid flags, missing companions, rejected headers, or panics
to fail the test and reach output comparison as appropriate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 276b3f8c-fa5b-4574-b7d6-51a63184cfab

📥 Commits

Reviewing files that changed from the base of the PR and between db79ee6 and 2597997.

📒 Files selected for processing (2)
  • tests/integration/helpers/bam_generator.rs
  • tests/integration/test_input_source_matrix.rs

Comment thread tests/integration/test_input_source_matrix.rs Outdated
@nh13
nh13 force-pushed the nh/test-de-vacuum-input-matrix branch from 2597997 to 3d78ecb Compare July 26, 2026 16:54
@nh13
nh13 temporarily deployed to github-actions July 26, 2026 16:54 — with GitHub Actions Inactive
The SAM and stdin matrices compare a command's output against the same
command reading a named path. That is only evidence when the output
depends on the records that went in, and for five commands it did not:
`simplex`, `duplex` and `codec` were handed ungrouped reads and wrote a
header-only BAM from any input, and `simplex-metrics`/`duplex-metrics`
emitted the same all-zero tables either way. A reader that dropped the
entire stream still matched the oracle for all five.

Give them fixtures they emit records from. `duplex` and `duplex-metrics`
get both strands of one molecule (`RX` plus strand-suffixed `MI`), and
`simplex`/`simplex-metrics` get single-strand molecules — `simplex-metrics`
rejects a base UMI seen on both strands outright, so it cannot share the
duplex shape. `codec` reuses the CODEC command's own pair builder rather
than a second copy of the MI/MC/overlap invariants, and needs the same
`--min-reads`/`--min-duplex-length` its own tests pass.

Rather than trust that this stays true, put it under test. Every command
now declares `output_depends_on_input`, and a new matrix drives each
fixture through its command twice — once populated, once drained — and
fails if the two agree. That converts an enumerated caveat in a doc
comment into an assertion: a future fixture that stops producing records
breaks at the cause instead of quietly hollowing out the other matrices.

`zipper` declares the exemption, verified to be load-bearing: it emits one
template per uBAM template and the uBAM arrives on `-u`, so an empty `-i`
legitimately yields the same templates unmapped.

Verified by fault injection in both directions — restoring the old shapes
fails the new test for exactly those five commands and no others, and
declaring `zipper` Required fails it for `zipper` alone.
@nh13
nh13 force-pushed the nh/test-de-vacuum-input-matrix branch from 3d78ecb to ed4fde7 Compare July 26, 2026 18:23
@nh13
nh13 temporarily deployed to github-actions July 26, 2026 18:23 — with GitHub Actions Inactive
@nh13

nh13 commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@nh13

nh13 commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@nh13
nh13 merged commit 7ec7820 into main Jul 26, 2026
14 checks passed
@nh13
nh13 deleted the nh/test-de-vacuum-input-matrix branch July 26, 2026 23:49
@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

This branch was previously deployed

1 inactive deployment
github-actions — ed4fde7b Deployed Jul 26, 2026 by nh13 via coverage #3115
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant