test: isolate retained-byte and allocation-size measurements

Merged
JL
25d ago
+309-92

Addresses F15 / R14. A process-wide live-byte delta could approve a 2 KiB retained allocation under a 1 KiB limit when another thread freed preexisting memory. Concurrent maximum-block measurements could reset each other's results.

min_live and min_max_block now attribute allocations to a synchronous scope on the calling thread. A recursion-guarded registry preserves ownership across cross-thread frees and scope exit. Safe TLS ownership and a thread-bound guard handle unwind and thread teardown. An atomic empty-registry fast path avoids the registry mutex when no scoped blocks remain.

The helpers distinguish allocation count, retained requested bytes and maximum requested block. Realloc attributes its replacement to the current scope; spawned/deferred allocations are excluded. Existing process counters and min_allocs remain available. Rustdoc states these limits. No public API or migration changes.

The production source change is confined to cfg(test) in src/lib.rs; the remainder of that file is byte-identical to main. The only other change is five lines adding a focused whatsapp-rust (test_alloc) entry to the existing Miri workflow matrix, authorized by the campaign owner. No dependencies, consumer manifests, runtime code, SizingRuntime lane guards or existing CI settings change.

Validation

  • Final Rust sources: 2,479 library tests passed under parallel libtest and nextest; three existing tests remain ignored. Nextest and SDK all-target Clippy with warnings denied completed with current head 39a341b9 checked out. The preceding libtest run started on 3b44b97a, whose Rust source is identical; 39a341b9 only quotes the YAML filter.
  • All seven focused tests pass the actual cargo miri test --locked -p whatsapp-rust --lib test_alloc:: command. The exact extracted module also passes Miri with strict provenance.
  • Controls cover unrelated frees, simultaneous maxima, cross-thread ownership, preexisting/reallocated blocks, unwind/TLS teardown, alignment and zeroing. A three-attempt test checks that min_live retries until both limits hold in one actual sample.
  • The race controls reject the original process-delta/reset behavior: retained bytes become negative, and a 4096-byte maximum is overwritten by 128.
  • All shareable native features: 2,926 tests passed, three skipped. The unchanged client sizing guard reports 16,464 requested bytes and 114 allocations per client, within its 17,000/160 limits.
  • Earlier runs competing with compilation/Miri had pairing timeouts. Full repeated suites passed with unchanged timeouts.
  • Remote release binary size is unchanged: 11,562,616 stripped bytes, with zero deltas in all reported metrics. The WASM release build, E2E and all four Miri jobs pass.
  • Integration with latest main 02456d45 (including #1643, #1644 and #1645) merges without conflicts in a separate worktree; 2,492 SDK library tests pass under nextest, three skipped. No API call-site fixes or branch update were needed. This is local integration evidence, separate from CI on head 39a341b9.
  • Formatting, workflow YAML parsing and diff checks pass.

Current-head Build & Test, Build & Lint with all features (including tests), native/MSRV API consumers, Rustdoc, Clippy, generated artifacts and formatting pass. MSRV tests and all eleven per-crate feature-matrix jobs pass. All current-head checks have reached terminal status; no required test/build job is pending. The exceptions below remain visible. CodeRabbit completed its full review of 39a341b9 without actionable findings; Greptile passes and all review threads are resolved. Cubic did not review because its monthly quota is exhausted.

Informational SemVer fails identically on baseline 8f711a9 and this head: 23/3/7 major-check categories in wacore/wacore-binary/waproto against published releases. Compared diagnostic categories and affected item lines match. No gates are weakened.

CodSpeed comparison is neutral with two session-self warnings (-8.22%/-8.21%). Both have exactly unchanged instruction-execution metrics; modeled memory time changes from 1.111 to 1.222 µs while cache time changes from 0.0667 to 0.0639 µs. CodSpeed flags different environments (AMD EPYC to Intel Xeon). The affected libsignal source and benchmarks are unchanged. This supports an environment/model explanation, not a demonstrated runtime regression; the warning remains visible.

Ready for the campaign owner to remove draft, with the informational/advisory caveats above. GitHub reports mergeable=true and mergeable_state=unstable; the informational SemVer job is the only failed check. No merge is requested.