Skip to content

test(ecstore): assert the error conversions, and stop the census over-reporting - #6241

Merged
overtrue merged 2 commits into
mainfrom
overtrue/1836-batch4-ecstore
Aug 19, 2026
Merged

test(ecstore): assert the error conversions, and stop the census over-reporting#6241
overtrue merged 2 commits into
mainfrom
overtrue/1836-batch4-ecstore

Conversation

@overtrue

Copy link
Copy Markdown
Collaborator

What

Fourth batch of backlog#1836, taking on the largest remaining cluster: 17 candidates in ecstore. One was a real assertion-less test. The other sixteen were the census mis-reading three legitimate patterns, so this fixes the script rather than the tests — the same call batch two made when its delegation heuristic mis-fired.

The sixteen false positives

#[should_panic(expected = "...")] — 5 tests. should_panic was already listed in VERIFY_SIGNALS, but the check only ran against the function body. The attribute block was collected into attrs and then never used, so the expected panic message — which is the assertion — was invisible to the scan.

A body that is a single call — 9 tests. run(DurabilityMode::Strict).await, aborting_encode_drops_blocked_producer(EncodePipeline::Vec).await. The delegation rule keyed off the callee's name (assert_, verify_, run_, _harness, …), which these do not match. But a body whose entire content is one call delegates by construction, whatever the callee happens to be called — that is now its own rule.

Compile-time contracts — 2 tests. assert_replication_config_ext::<ReplicationConfiguration>() does match the assert_ prefix, but the turbofish sits between the name and the parens and broke \s*\(. And tier.rs's signature guard declares a nested fn and then discards it with let _ = call_legacy_refresh; — the same "the type system is the assertion" shape as the already-recognised fn _name() form.

Tree-wide candidates drop from 53 to 33; ecstore from 17 to 1.

The one that was real

test_error_conversions ran two conversions and threw both results away:

let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "test");
let _disk_error: DiskError = io_error.into();

It now pins what each conversion owes its caller:

  • a plain io::Error becomes DiskError::Io and keeps its kind — it must not be promoted to FileNotFound on the strength of ErrorKind::NotFound, since reduce_errs counts those as different errors during quorum aggregation;
  • a typed DiskError boxed through io::Error round-trips back to itself rather than degrading to Io, which is the behaviour the From impl's own comment calls out;
  • a serde_json::Error folds into other with its message intact.

Verification

cargo nextest run -p rustfs-ecstore --lib -E 'test(test_error_conversions)' passes, cargo clippy -p rustfs-ecstore --all-targets -- -D warnings is clean, cargo fmt --all applied. The script change was checked against the excluded tests individually — each of the sixteen is confirmed to carry verification the scan could not see.

…-reporting

The census listed 17 candidates in ecstore. Sixteen were false positives of three shapes, and reading them showed the heuristics rather than the tests were wrong:

- `#[should_panic(expected = "...")]` (5). `should_panic` was already in the verification signals, but the check only ever ran against the function body — the attribute block was collected and then ignored, so the expected panic message, which *is* the assertion, was invisible.
- Bodies that are a single call into a shared harness (9), like `run(DurabilityMode::Strict).await` and `aborting_encode_drops_blocked_producer(EncodePipeline::Vec).await`. The delegation rule keyed off callee names (`assert_`/`verify_`/`run_`/`_harness`), which these do not match, though a body that is nothing but one call delegates by construction whatever the callee is called.
- Compile-time contracts (2): a turbofish between the callee and its parens (`assert_replication_config_ext::<T>()`) broke the delegation regex, and a nested `fn` that is only bound and discarded is the same signature guard as the already-recognised `fn _name()` form.

The script now folds the attribute block into the verification text, allows a turbofish in the delegation patterns, and recognises both a single-call body and a discarded nested-fn binding. Tree-wide candidates drop from 53 to 33, ecstore from 17 to 1.

The one that survives was real: `test_error_conversions` performed two conversions and discarded both results. It now pins what each conversion must produce — a plain `io::Error` stays `DiskError::Io` rather than being guessed at from its `NotFound` kind, a typed error boxed through `io::Error` round-trips back to itself instead of degrading to `Io`, and a serde_json error folds into `other` with its message intact.

Refs backlog#1836
@github-actions

Copy link
Copy Markdown
Contributor

CLA requirements are satisfied for this pull request.

@overtrue
overtrue enabled auto-merge (squash) August 19, 2026 03:01
@overtrue
overtrue merged commit 728efce into main Aug 19, 2026
5 of 7 checks passed
@overtrue
overtrue deleted the overtrue/1836-batch4-ecstore branch August 19, 2026 03:01
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.

2 participants