Skip to content

test: coverage initiative — kernels, readers, with_* API#195

Open
d-laub wants to merge 51 commits into
mainfrom
worktree-test-coverage-initiative
Open

test: coverage initiative — kernels, readers, with_* API#195
d-laub wants to merge 51 commits into
mainfrom
worktree-test-coverage-initiative

Conversation

@d-laub
Copy link
Copy Markdown
Collaborator

@d-laub d-laub commented May 25, 2026

Summary

Three-wave test-coverage initiative.

Wave 1 — numba kernel behavior tests (coverage.py can't instrument numba):

  • Extended reconstruct_haplotype_from_sparse case matrix (ref-only, deletion spanning region end, overlapping variants)
  • New get_diffs_sparse tests covering both fast and slow paths
  • New filter_af tests across min/max/both/no-op + 2-D offsets layout (xfail — see Findings)
  • Filled choose_exonic_variants scenario gaps (spans start/end, entirely before/after)
  • New intervals_to_tracks tests

Wave 2 — user-facing readers + DataLoader:

  • _fasta.py: missing contig, protocol attrs, zero-length range
  • _bigwig.py: read smoke, protocol attrs, missing path raises RuntimeError
  • _torch.py: 6 smoke tests for get_dataloader / get_sampler / to_dataloader (skip cleanly via importorskip when torch missing; verified passing in py310/py311/py312/py313 envs)

Wave 3 — API surface:

  • Dataset.with_* matrix: with_settings, with_len, with_seqs, with_tracks, with_insertion_fill
  • Dataset.open error paths: missing dir, missing metadata, missing input_regions, ploidy mismatch, empty dataset
  • _indexing.py edge cases: negative indices, OOB, step slices, boolean masks, empty selections

Coverage config (pyproject.toml):

  • Omitted _dataset/_intervals.py (numba-only)
  • Added @nb.njit / @numba.njit / PyTorch ImportError to exclude_lines

Coverage impact

Overall: 63% → 74%. Key modules:

  • _genotypes.py: 5% → 100% (numba exclusion working)
  • _intervals.py: 12% → omitted
  • _bigwig.py: 47% → 61%
  • _open.py: 80% → 87%
  • _tracks.py: 41% → 79%
  • _torch.py: stays 31% in dev env (torch not installed); fully exercised in py3xx envs

Full report: docs/superpowers/specs/2026-05-25-test-coverage-after.txt.

Findings worth surfacing

  1. filter_af 2-D offsets layout is broken — kernel calls lengths_to_offsets (plain numpy) from within @nb.njit, which raises a TypingError. Test is xfail(strict=True); fix would be @nb.njit-decorating lengths_to_offsets in _utils.py.
  2. _torch.py ABI quirk — must import numpy before pytest.importorskip("torch") in py310 env to avoid a Fatal Python error during torch import. Documented in the test file with a noqa.

Test plan

  • pixi run -e dev pytest tests — 413 passed, 4 skipped, 3 xfailed
  • pixi run -e dev cargo test --release — 4 passed
  • pixi run -e py310 pytest tests/unit/test_torch.py — 6 passed
  • pixi run -e dev ruff check python/ tests/ — clean
  • pixi run -e dev typecheck — 0 errors

Spec: docs/superpowers/specs/2026-05-25-test-coverage-design.md
Plan: docs/superpowers/plans/2026-05-25-test-coverage-implementation.md

🤖 Generated with Claude Code

d-laub and others added 30 commits May 25, 2026 11:34
Three-wave plan in a single bundled PR: numba-kernel behavior tests,
user-facing readers + DataLoader, and Dataset.with_* / open/indexing
API surface. Excludes numba-only modules from the coverage gate since
coverage.py can't instrument them.
19 tests across with_settings, with_len, with_seqs, with_tracks, and
with_insertion_fill confirming each returns a new lazy view without
mutating the original, and rejects invalid input.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Omit _intervals.py (numba-only) and add exclude_lines for @nb.njit,
@numba.njit, and the PyTorch ImportError guard. Saves the new
coverage baseline (65% overall, _genotypes 5%→100%).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rch imports

Two findings from the test-coverage initiative folded in:

1. filter_af's 2-D geno_offsets path called lengths_to_offsets (plain numpy)
   from inside @nb.njit, which numba could not compile. Replaced with an
   inline cumulative-sum loop. Unxfails test_filter_af_2d_offsets_layout.

2. test_torch.py imported torch via pytest.importorskip before genvarloader,
   which caused a numpy/torch ABI abort in py310 env. Reordered to import
   genvarloader first (which loads numpy in the order torch expects), then
   importorskip torch.
…oader reproducible

Adds tests/integration/dataset/test_determinism.py covering:
- two opens with the same rng seed + jitter produce identical reads
- jitter=0 reads are byte-identical across repeated lookups
- (xfail) seeded torch.Generator should give reproducible shuffled batches.
  Currently broken: get_sampler() builds RandomSampler without forwarding
  the DataLoader's generator, so the sampler uses the global torch RNG.

Note: also surfaced that with_settings(rng=...) is broken in _impl.py
(line 271 writes "rng" into to_evolve but the dataclass field is _rng),
so the seed-equality test seeds via Dataset.open(..., rng=...) instead.
d-laub and others added 21 commits May 25, 2026 18:02
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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