ci+deps+test(persistence): run the S3+ES composite suite on every agent, fix its latent defects, and bump past the crc-fast x86_64 panic - #391
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
aacruzgon
force-pushed
the
ci/390-anti-vacuous-gated-suites
branch
from
July 24, 2026 17:06
7e9a650 to
0425f82
Compare
…n test step The s3_es_tests.rs suite self-skips unless RUN_MINIO_S3_ES_TESTS=1, and no workflow ever set it — the suite had never run in CI, and every green run passed it vacuously (#390). It is the only coverage of the composite S3-CRUD + Elasticsearch-search wiring against real backends. Set the variable on the existing 'Run tests with all features' step (per maintainer preference, no new steps in ci.yml), gated to Linux via a runner.os expression because the ES container is not viable on the virtualized Windows agent. The anti-vacuous count assertion originally proposed for this suite moves to #390 PR B, which makes availability guards fail loudly in CI at the code level instead of asserting counts in YAML. Tests: validated via this PR's own CI run, which now executes the 10 S3+ES tests inside the workspace test step.
aacruzgon
force-pushed
the
ci/390-anti-vacuous-gated-suites
branch
from
July 24, 2026 17:15
0425f82 to
9376bf6
Compare
The suite had never actually run anywhere (#390), and un-skipping it in CI revealed it was born broken — 3 of 10 tests fail deterministically: - The harness built the composite with the default sync config, which is SyncMode::Asynchronous, but never called start_sync_workers(). With an S3 primary (no durable outbox) every secondary sync fails with 'async worker was never started'; composite create/update/delete swallow that error by design (primary succeeded), so nothing ever reached ES and every positive search assertion failed. The composite now uses SyncMode::Synchronous, which is also the semantics these tests assert. - The fixed 100ms sleeps for ES refresh are replaced with a bounded search_until() poll (10s), so index-visibility lag on a loaded CI runner cannot flake the suite. The delete test now also waits for the create to be searchable first, so its absence check can't pass vacuously; the tenant-isolation test waits for tenant-a visibility before asserting tenant-b's absence, making that check meaningful. Tests: RUN_MINIO_S3_ES_TESTS=1 cargo test -p helios-persistence --test s3_es_tests --features s3,elasticsearch — 10/10 pass locally against real MinIO + ES containers (first full pass of this suite); scoped CI-style clippy clean.
smunini
requested changes
Jul 27, 2026
Reproduction experiment for #391 review feedback: make the S3+ES composite suite (s3_es_tests.rs) run on a non-Linux agent so the assumed Windows failure is observed rather than inferred. Two gates had to move together. `runs-on: [self-hosted]` picks whichever agent is free, and RUN_MINIO_S3_ES_TESTS was `${{ runner.os == 'Linux' && '1' || '' }}`, so a Windows landing skipped the suite silently - which is exactly why the previous green run on github-agent4 (Windows) proved nothing. Pin to the Windows agent and set the variable unconditionally. Both changes are marked TEMPORARY and revert once the failure signature is captured.
…S suite" This reverts commit 2717104.
Run 30303350382 removed the gate and pinned Test Rust to the Windows agent to observe the failure instead of predicting it. Two things came back. The panic is real and precisely located: 8 of 10 tests died in crc-fast-1.6.0/src/arch/mod.rs:121 with "x86 features missing (SSE4.1 && PCLMULQDQ)". crc-fast 1.6.0 gates its software fallback behind #[cfg(target_arch = "x86")], so on x86_64 the fallback never compiles and the SoftwareFallback arm falls through to a panic. Upstream fixed it in 1.7.1; aws-smithy-checksums 0.63.12 pins ~1.6.0, so reaching the fix means moving aws-sdk-s3 to >= 1.122.0. The second half of the gate was wrong: Elasticsearch works on that agent. s3_es_test_read_missing_returns_none passed, and it runs the full make_harness() path including the ES testcontainer and initialize(). Comment-only; the gate expression is unchanged.
This comment has been minimized.
This comment has been minimized.
…agent
The S3+ES suite was gated to Linux because the AWS S3 SDK panics on the
self-hosted Windows agent. Run 30303350382 pinned Test Rust to that agent
with the gate removed and captured the cause: 8 of 10 tests panicked in
crc-fast-1.6.0/src/arch/mod.rs:121, "x86 features missing (SSE4.1 &&
PCLMULQDQ)". The agent is a virtualized guest lacking those instructions,
and crc-fast 1.6.0 gates its software fallback behind
#[cfg(target_arch = "x86")] - so on x86_64 the fallback never compiles and
the SoftwareFallback arm falls through to a panic. The SDK reaches it on
every upload via aws-sdk-s3 -> aws-smithy-checksums -> crc-fast.
crc-fast fixed the fallback in 1.7.1, but aws-smithy-checksums 0.63.12
pins `crc-fast ~1.6.0`, which excludes it, and a [patch] override cannot
satisfy a tilde requirement either. The fix has to arrive through the SDK:
aws-sdk-s3 1.122.0 -> aws-smithy-checksums 0.64.4 -> crc-fast 1.9.0.
1.122.0 rather than latest: aws-sdk-s3 1.140.0 needs aws-smithy-types
1.6.1 -> serde ^1.0.228, and the workspace pins serde = "=1.0.224"
(Cargo.toml:40). 1.122.0 is the earliest release carrying the fix and it
resolves against that pin.
helios-sof's lru moves 0.12 -> 0.16 to follow the SDK's own pin, which
went ^0.12 -> ^0.16 in this bump. Its comment already prescribed exactly
this ("Bump to the latest once the AWS SDK updates its lru pin"); without
it the lockfile would carry two lru versions whenever `s3` is enabled.
Usage is new/get/put only and needed no source change.
With the panic gone, RUN_MINIO_S3_ES_TESTS becomes an unconditional "1".
Elasticsearch was never the blocker the gate also claimed: in that same
run s3_es_test_read_missing_returns_none passed, exercising the whole
make_harness() path including ES container start and initialize().
Reverts once the S3+ES suite is confirmed 10/10 on the agent that failed in run 30303350382. Not for merge.
… fix" This reverts commit b351029.
This comment has been minimized.
This comment has been minimized.
The Windows leg of the MinIO conditional-writes check set AWS_REQUEST_CHECKSUM_CALCULATION and AWS_RESPONSE_CHECKSUM_VALIDATION to WHEN_REQUIRED. That existed only to dodge the crc-fast 1.6.0 panic on this virtualized x86_64 agent - the same bug that gated the S3+ES suite to Linux. Dodging it disabled the SDK's default integrity protection, so this leg ran a different SDK configuration than the Linux leg, and the checksum path was the one thing Windows never exercised. With crc-fast 1.9.0 (via aws-sdk-s3 1.122.0) the panic is gone, so both legs now run identical defaults and the Windows leg regains checksum coverage. The steps still differ only by shell.
… removal Reverts once the MinIO settings tests are confirmed 5/5 with the SDK's default checksum path active. Not for merge.
…ated-suites # Conflicts: # .github/workflows/ci.yml
… opt-out removal" This reverts commit 7c4315b.
This comment has been minimized.
This comment has been minimized.
smunini
approved these changes
Jul 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Run the S3+ES composite suite on every agent, fix its latent defects, and remove the crc-fast panic at the root
Summary
crates/persistence/tests/s3_es_tests.rsself-skips unlessRUN_MINIO_S3_ES_TESTS=1, and no workflow ever set it. The suite had never run in CI — every green run passed it vacuously (#390).Un-skipping it uncovered two further layers:
crc-fastbug rather than a property of the runner. Rather than gate the suite to Linux, this PR fixes it at the root by bumping the SDK past the fixedcrc-fast— which also lets ci: fix Windows MinIO step crc-fast panic + add CI timeouts #345's checksum workaround be removed.Net result: the suite runs unconditionally on every agent, verified 10/10 on the Windows agent that previously failed 8/10, and the Windows MinIO leg regains the checksum coverage it has been forfeiting since #345.
Why
Three separate ways this was silently verifying nothing:
RUN_MINIO_S3_ES_TESTSwas unset everywhere, sos3_es_testsskipped in every CI run since it was written. Thefinished in 0.01ssignature was there the whole time.crc-fastpanic was treated as a Windows-runner peculiarity. It is not: any HFS deployment writing to S3 on a CPU without SSE4.1+PCLMULQDQ panicked on every upload.Changes
crates/persistence/tests/s3_es_tests.rsSyncMode::Asynchronous— but never calledstart_sync_workers(). With an S3 primary (no durable outbox), every secondary sync failed with "async worker was never started", andcomposite.create/update/deleteswallow sync errors by design (primary succeeded,warn!only). Nothing ever reached ES, so all positive search assertions failed. The harness now builds the composite withSyncMode::Synchronous, which is also the semantics the tests assert. Verified by writing to the ES backend directly (worked all along) — the bug was purely the composite wiring in the harness.search_until()helper polls (10s bound). The delete test now waits for the create to be searchable before deleting, so its absence assertion can't pass vacuously; the tenant-isolation test waits for tenant-a's visibility before asserting tenant-b sees nothing, making the isolation check meaningful rather than timing-dependent.Cargo.lock,crates/sof/Cargo.tomlaws-sdk-s31.119.0 → 1.122.0, pullingaws-smithy-checksums0.63.12 → 0.64.4 →crc-fast1.6.0 → 1.9.0, past the upstream fix.helios-sof'slru0.12 → 0.16, following the SDK's own pin (^0.12→^0.16) so the lockfile keeps a singlelru. The comment there already prescribed exactly this: "Bump to the latest once the AWS SDK updates its lru pin." Usage isnew/get/putonly; no source change needed..github/workflows/ci.ymlRUN_MINIO_S3_ES_TESTS: "1"on the existing "Run tests with all features" step — no new step, no extra build, no OS gate.AWS_REQUEST_CHECKSUM_CALCULATION/AWS_RESPONSE_CHECKSUM_VALIDATIONfrom the Windows MinIO step. See Relationship to #345. ci: fix Windows MinIO step crc-fast panic + add CI timeouts #345's job/step timeouts are untouched.Investigation
1. Reproducing the Windows failure
An earlier revision of this PR gated the suite to Linux on two assumptions: that the AWS SDK panics on the Windows agent, and that the ES container was unproven there. To replace conjecture with evidence, run 30303350382 (commit
2717104ce, reverted) removed the gate and pinnedtest-rustto[self-hosted, Windows]. The job failed as intended:Assumption 1 confirmed. The only two passing tests are precisely the two that never PUT an object to S3.
Assumption 2 disproved — ES was never a blocker.
s3_es_test_read_missing_returns_nonepassed, and it runs the wholemake_harness()path: ES testcontainer start,ElasticsearchBackendconstruction, andinitialize().await.expect("initialize ES backend"). The container works on that agent.2. Root cause
crc-fast1.6.0,src/arch/mod.rs:A table-based software fallback has existed since 1.2.0, but the call to it is gated
#[cfg(target_arch = "x86")]— 32-bit x86 only. Onx86_64that line compiles to nothing and control drops into thepanic!. (The helper it would have called is broken the same way: its inner software call is also cfg'd tox86, and it discards the return value, falling through to an identical panic.) The// This should never happencomment is the tell — the author assumed every x86 CPU advertises SSE4.1+PCLMULQDQ; the agent is a virtualized guest that does not. The SDK reaches this on every upload viaaws-sdk-s3→aws-smithy-checksums→crc-fast.Upstream fixed it in 1.7.1, under "Ensure Miri passes on x86_64" (PR #26) — not advertised as a CPU-compat fix, which is why the changelog doesn't flag it:
3. Why the fix needs an SDK bump
Not reachable by
cargo updatealone:aws-smithy-checksums 0.63.12requirescrc-fast ~1.6.0(>=1.6.0, <1.7.0), there is no 1.6.1, and a[patch.crates-io]override cannot satisfy a tilde requirement either. It has to arrive through the SDK.Why 1.122.0 and not latest:
aws-sdk-s3 1.140.0needsaws-smithy-types 1.6.1→serde ^1.0.228, and the workspace pinsserde = { version = "=1.0.224" }(Cargo.toml:40). 1.122.0 is the earliest release carrying the fix and it resolves against that pin.Relationship to #345
cc @smunini — #345 hit this exact panic in the Windows MinIO step and diagnosed it correctly down to the line number and dependency chain. Its workaround was the right call at the time: the fix genuinely wasn't reachable, for the tilde-pin reason above, and #345 said so explicitly, naming the root fix as "expose host CPU features (SSE4.1 + PCLMULQDQ) to the Windows runner's hypervisor."
What's new here is the mechanism. #345 described crc-fast 1.6.0 as having "no software fallback on x86_64" — true in effect, but the fallback exists and is merely cfg'd out, which makes this an upstream bug with an upstream fix rather than a hardware requirement. That opens a third option beyond "workaround" and "change the hypervisor": bump the SDK. With the panic gone, #345's env opt-out is unnecessary and is removed here.
This matters for coverage, not just tidiness.
WHEN_REQUIREDdoesn't merely route around a crash — it disables the SDK's default integrity protection, so the Windows leg was running a different SDK configuration than the Linux leg, and the checksum path (the thing that was broken) was the one part Windows never exercised. Both legs now run identical defaults and differ only by shell.#345's remaining caveat still stands: "any other hardware-CRC/crypto path on that runner could still hit this." This fixes
crc-fastspecifically, not the general class of hardware-accelerated paths on a guest with a restricted CPU feature set.Testing
CI, on the Windows agent that originally failed
Each run below was temporarily pinned to
[self-hosted, Windows]to guarantee it landed ongithub-agent4; every pin has been reverted, and the branch shipsruns-on: [self-hosted].s3_es_testsmainmergedFinal run (job), with the SDK's default CRC32 path active on the CPU that used to panic:
14.45s of real container work, not the
finished in 0.01sskip signature — the first genuine full pass of this suite on a non-Linux agent. Because the eight previously-panicking tests had never reached their ES assertions on Windows, passing them also proves ES indexing, search visibility, and thesearch_until()bound work there — not merely that the panic is gone. And because real uploads now compute CRC32 on a CPU lacking those instructions, thecrc-fast1.9.0 fallback is genuinely exercised rather than just present.Local
RUN_MINIO_S3_ES_TESTS=1 cargo test -p helios-persistence --test s3_es_tests --features s3,elasticsearch— 10/10 against real MinIO + ES containers.cargo clippy --all-targets --all-featureswith CI's exact-Aflags — exit 0, re-run after mergingmain.cargo test -p helios-sof --lib— 127/127 (thelrubump).cargo check -p helios-persistence --features s3,elasticsearch --testsandcargo check -p helios-sof --all-targets— clean.cargo metadataexits 0 with no lockfile rewrite after themainmerge, confirming the mergedCargo.lockis consistent.cargo fmt --allapplied.Notes
ci.ymlhas a macOS linker branch, so an agent may exist. crc-fast's aarch64 path needs NEON+AES, which Apple Silicon has, so the same failure is unlikely — but it has not been demonstrated.serde = "=1.0.224"workspace pin capsaws-sdk-s3below 1.140.0, andhelios-sof'slrumust track whatever the SDK pins or the lockfile carries two versions whenevers3is enabled.warn!s — a production misconfiguration would silently lose the entire search index. Flagged on Test suites can pass vacuously: env-gated tests silently skip in CI (sibling of #389) #390 for triage.#[ignore]for the AWS suite, MinIO containerrun_idlabel) and PR A2 (scheduled OIDC workflow fors3_tests.rs, pending IAM setup). The Redis twin-suite contract check rides with feat(cluster): make HFS cluster-capable behind a load balancer #269.