Repository navigation
test: make coverage fast: optimize crypto deps in test builds, run capacity tests at test-scale caps - #69
Conversation
The 960-row scope cap was duplicated in the tool, flow-trust and import-trust grant modules. It now lives in one place, with a smaller value under test so filling a scope to its limit takes a handful of grants, and a test pins the production value. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace the hard-coded 960 row limit in the engine gap tests with a CAP constant sourced from engine::MAX_SCOPE_ROWS, so the tests track the real cap instead of silently drifting if it changes. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a test asserting that the production scope row limit stays at 960 and remains below the 1024 rows the scope load contract accepts, since unit tests only exercise the smaller test cap and would not catch a drift in the production value. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The upper bound on the production scope row cap and its relationship to the test cap are now checked by const assertions next to the constants instead of at runtime in a unit test, so a violation fails the build rather than a single test. The test keeps pinning the production value at 960. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Debug and test builds now compile the crypto crates at opt-level 3 so Argon2id key derivation no longer takes seconds per call under coverage instrumentation. Only third-party crypto crates are optimized, leaving the workspace's own debug assertions and coverage counters intact. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Raise the optimization level for the zeroize crate in dev builds so its zeroing routines run at full speed during development, matching the existing per-package overrides for other crypto dependencies. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Unit tests now fill the approval store client to its limit using a small test-only cap instead of the production 65,536, so the bound check runs in a handful of admits rather than tens of thousands. A new test pins the bus constant's contract value, and a compile-time assertion keeps the test cap from ever exceeding it. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The hard-coded 1024-entry cap on the creation retry memo is now a named constant that shrinks to 16 under cfg(test), mirroring the existing scope-row cap so tests can fill the memo without thousands of iterations. A compile-time assertion keeps the test cap at or below the production value, and a new test pins the production cap at 1024. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reformatted the approval engine and its gap tests to satisfy rustfmt, wrapping long conditionals and method chains and dropping stray blank lines. No behaviour changes. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Tiny Sweeper reviewReviewed head: Verdict: Ready for maintainer review · Priority: none Diagnostics and supporting detailsFull summaryPull request purpose (title): test: make coverage fast: optimize crypto deps in test builds, run capacity tests at test-scale caps. Tiny Sweeper completed its review; deterministic results follow. Review snapshot
Completeness: Complete Features
Tests
FindingsNo active actionable findings. Before mergeNone. Agent review detailscritique
security
tests
commits
description
Evidence and run details
|
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Why
The v0.21.0 release spent 30 minutes in "Require 90% line coverage in every source file" (run 43181492534, 08:21→08:52), against 3.5 minutes for the plain
cargo teststep. Timing every test withcargo nextestfound two kinds of cost, both multiplied by coverage instrumentation on a 4-core runner:PasswordKey::deriveruns the production parameters (64 MiB, 3 passes). Unoptimized, each derivation takes seconds. About 25 password and cipher tests paid that cost, up to 7.5 s each.admits in the store-client test (15 s), and 1,024/1,026 begin/consume/record cycles in the creation-memo tests (4 s).What
devprofile.testandcargo llvm-covinherit it. This coversargon2,blake2,aes,aes-gcm,ghash,polyval,chacha20,chacha20poly1305,poly1305,sha2,hmac,hkdf,curve25519-dalek,x25519-dalekandzeroize. Only these third-party crates are optimized: workspace code keeps debug assertions and coverage counters, and what each test checks is unchanged.cfg(test)and unchanged otherwise. The refusal at the boundary is the same comparison either way.engine::MAX_SCOPE_ROWSreplaces the 3 duplicate960constants (tool, flow-trust and import-trust paths). It is 8 under test. The pin test isthe_production_scope_row_cap_is_960, plus compile-time asserts that it stays below the 1024-row load contract.engine::MAX_PENDING_CREATIONSreplaces a bare1024inmemo_begin. It is 16 under test, pinned bythe_production_creation_memo_cap_is_1024.approval_callbacks::MAX_RUNTIME_SCOPESisMAX_APPROVAL_SCOPES2outside tests and 16 under test, pinned bythe_bus_approval_scope_cap_is_65536.Results (local, nextest,
--all-features)tinysecurity-approvalsuiteThe rest is spread across 1,350 sub-second tests, plus a few production-strength Argon2id derivations. The frozen host fixtures need those exact parameters, so they stay.
Verification
cargo fmt --check,cargo clippy --all-targets --all-features -D warnings, andcargo doc --no-deps --all-featureswith-D warningsare clean.cargo llvm-cov --workspace --all-targets --all-featurespasses. In a cold instrumented build, the test phase took 19 s on a 95-core box.run-native-master-cipher-coverage.sh) can't run on my box: its ancestor directories are group-writable, and the module loader refuses that. It's unchanged by this PR (examples don't build withcfg(test)); CI runs it. Without it, four files that the native fixtures exist to cover are under 90%. None of them is touched here.adapter::device::tests::unpublished_worker_plaintext_is_wiped_on_clock_read_failure_and_join_abortfailed once in one full run. It relies onJoinHandle::abortlanding at an await point. It then passed 20/20 alone, and 0 failures in 8 module-suite plus 6 full-workspace runs each on this branch and on upstream740dafc. So it's a rare pre-existing race, not caused here.Not changed, worth a follow-up
ApprovalStoreClient::admitscans aVecwithcontainson every call, so filling it toward 65,536 subjects is quadratic in production too. AHashSet(or keeping theVecfor order and adding an index) would fix it.Summary by CodeRabbit