Skip to content

Make integration test assertions fallible - #708

Merged
leynos merged 6 commits into
mainfrom
test-quality-fallible-assertions
Sep 27, 2026
Merged

leynos merged 6 commits into
mainfrom
test-quality-fallible-assertions

Conversation

@leynos

@leynos leynos commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

This branch replaces panicking assertions in Result-returning integration tests with fallible checks, so test failures retain useful diagnostics without suppressing clippy::panic_in_result_fn. It removes all 45 measured expectations for that lint across the assigned integration surface, retains Result for real I/O and subprocess work, makes three numeric fixture conversions fallible, and deletes one unused connection-harness helper.

This is the second test-quality layer, stacked directly above #706 (test-quality-sweep). Spelling, structural module moves, production lint fixes, and final lint enforcement remain in later layers. No generated spelling configuration or byte-exact golden data changed.

Review feedback

Two findings from the previous round are addressed on the current head.

  • CodeRabbit "Developer Documentation" warning. The branch added a shared test abstraction without documenting it. The developers' guide now has a Fallible assertions in integration tests subsection covering the clippy::panic_in_result_fn motivation, how to choose between check, check_eq, and check_equal, the Result<(), String> failure contract, and the #[path]/pub(super) placement rule. The abstraction is test-only scaffolding, so no ADR or design-document change was needed.
  • chatgpt-codex-connector P1, tests/prepared_app.rs over the 400-line limit. The branch's original tests/prepared_app.rs (575 lines) and tests/connection.rs (549 lines) both exceeded the AGENTS.md limit, so both are split into feature-focused modules behind thin driver files. The rebase re-expressed that split against main's newer layout; see Rebase below.
  • CodeScene "Large Method" on tests/workspace_manifest.rs. The extracted check_workspace_members helper and its caller were shortened so both fall below the method-size threshold. CodeScene re-reviewed at 613ed21 and approved.

Review walkthrough

Rebase

origin/main advanced to 2892081 (PR #642, "Prepare applications before server readiness") after the previous review round, which put this branch in conflict. The branch is rebased onto 2892081; the replay boundary (OLD_BASE) is 43b90a3, the last inherited commit, which was both the merge base and the prior rebase boundary because the target fast-forwarded from it.

Six commits were replayed. Three conflicts arose across two files:

  • tests/prepared_app.rs — main's structure and main's semantics won, plus this branch's fallible conversion. main had independently solved the same 400-line problem with sibling crates (prepared_app.rs + prepared_app_properties.rs + prepared_app_tcp.rs + common/prepared_app.rs fixtures), which is a strict superset of this branch's subdirectory split, so main's layout was taken and the branch's five superseded split modules dropped. The fallible-assertion purpose was then applied to main's content, which also removed a newly-added #[expect(clippy::panic_in_result_fn)] in prepared_app_tcp.rs. Because main's PR changed production startup semantics — prepare once and share one immutable PreparedApp root across workers — the expected counts changed with it (factory_calls: 1 for server startup rather than one per connection), so the old numbers were not re-asserted.
  • tests/prepared_app.rs, size limit. With main's structure adopted, the merged file still exceeded 400 lines, so the real-socket scenarios were extracted to tests/prepared_app/tcp.rs behind a #[path] module declaration, following the existing tests/connection.rs + tests/connection/ idiom.
  • tests/prepared_app_tcp.rs, import region. Resolved to main's fixture imports plus this branch's fallible-assertion module.

typos.toml is unchanged by this branch: the pre-rebase "Refresh the generated spelling dictionary" commit is byte-identical to 43b90a3 and origin/main already carries that refresh, so the rebase correctly dropped it as an empty change.

Validation

An independent Scrutineer ran all seven gates sequentially at f693b29 and every gate exited 0: make check-fmt (2s), make lint (31s), make typecheck (11s), make test (134s), make markdownlint (8s), make spelling (4s), and make nixie (4s). make test ran 81 test binaries with 1222 passed, 0 failed, 0 ignored under RUSTFLAGS="-D warnings". Per-gate logs are under /tmp/<action>-test-quality-fallible-assertions-4.out.

Because the conflict resolution was manual, the two resolved files were checked to be genuinely exercised and not merely compiling. tests/prepared_app/tcp.rs contributes the prepared_app_tcp binary (2 tests), and the prepared_app binary runs 4 tests including tcp::prepared_app_serves_real_tcp_connection_without_retransforming, confirming the #[path] module is reachable from the parent rather than orphaned by the split. The sibling tests/prepared_app_tcp.rs also ran and passed, so the extracted module and the pre-existing top-level file coexist.

Behaviour preservation for the connection split is verified three ways: assertion-message literals are byte-identical, the normalized set of source lines is unchanged apart from moved imports, and the crate still builds to the same test count with module-qualified names confirming the submodules actually run.

All five split files are under the 400-line limit: prepared_app.rs 331, prepared_app/tcp.rs 104, common/prepared_app.rs 91, prepared_app_properties.rs 124, prepared_app_tcp.rs 143, and connection.rs 17 with its modules at 82/201/70/221.

The change surface is 30 paths: 29 under tests/ plus docs/developers-guide.md.

Notes

This is the second test-quality layer, above #706 and below the spelling layer #709. The source inventory said 46 panic_in_result_fn expectations, but direct inspection of the 18 assigned integration files found 45; all 45 are removed here. origin/main still carries 45 across those 18 files — none survive on this head. Tests with real I/O or subprocess setup still return Result. Lower layers remain under their own lint configuration; full baseline enforcement comes later.

The blocking CI build-test lane, which had stalled before the previous round when the pull request's merge ref went stale, dispatched normally for 613ed21 (36331777486, success, 10m33s). The stall was cleared by the earlier rebase onto a fresh base, confirming it was stale merge-ref metadata rather than anything in the diff.

References

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: 55cb5658-454d-4886-8647-9b67f5ed89ad

📥 Commits

Reviewing files that changed from the base of the PR and between 6ac653b and b83fe9b.

📒 Files selected for processing (24)
  • tests/client_lifecycle.rs
  • tests/common/fallible_assertions/check.rs
  • tests/common/fallible_assertions/check_eq.rs
  • tests/common/fallible_assertions/check_equal.rs
  • tests/connection.rs
  • tests/connection_fragmentation.rs
  • tests/correlation_id.rs
  • tests/fixtures/client_messaging.rs
  • tests/fixtures/client_send_streaming.rs
  • tests/fragment_transport/eviction.rs
  • tests/fragment_transport/rejection.rs
  • tests/lifecycle.rs
  • tests/metadata.rs
  • tests/middleware_order.rs
  • tests/multi_packet.rs
  • tests/multi_packet_streaming.rs
  • tests/preamble/basic.rs
  • tests/preamble/responses.rs
  • tests/preamble/timeouts.rs
  • tests/prepared_app.rs
  • tests/prepared_app_tcp.rs
  • tests/push.rs
  • tests/routes.rs
  • tests/workspace_manifest.rs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/monotony (auto-detected)
  • leynos/rust-prover-tools (auto-detected)
  • leynos/mapsplice (auto-detected)
  • leynos/whitaker (auto-detected)
  • leynos/mdtablefix (auto-detected)
  • leynos/typos-config-builder (auto-detected)
  • leynos/nixie (auto-detected)
  • leynos/shared-actions (auto-detected)
  • leynos/mxd (auto-detected)
💤 Files with no reviewable changes (1)
  • tests/connection.rs

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


Summary

  • Replace panic-based checks across the assigned Result-returning integration tests with fallible checks and descriptive errors.
  • Add shared predicate and equality helpers for copyable and borrowed values.
  • Keep I/O, subprocess and callback failures on the existing Result paths. Extract preamble-server and workspace-member checks into helpers.
  • Make numeric fixture conversions fallible and remove the unused connection-harness helper.

The author reports removing all 45 measured panic_in_result_fn expectations across the assigned test surface. The author also reports that workspace tests, documentation tests, linting and type checking passed on the replayed commit. Fresh hosted checks and current-head review remain outstanding.

The PR targets #706. No new execplan document is reported.

Walkthrough

The test suite replaces panic-based assertions with fallible checks that return descriptive errors. Lifecycle server tasks propagate failures, fixture payload generation uses checked or cycling conversions, and an unused test harness method is removed.

Changes

Test error propagation

Layer / File(s) Summary
Shared fallible assertion helpers
tests/common/fallible_assertions/*
Add check, check_eq, and check_equal helpers that return errors when checks fail.
Lifecycle and application integration tests
tests/client_lifecycle.rs, tests/lifecycle.rs, tests/metadata.rs, tests/preamble/*, tests/middleware_order.rs, tests/prepared_app*.rs
Replace panic-based checks with propagated errors. Lifecycle tests also propagate server-task failures and verify the teardown state.
Framing and transport tests
tests/connection.rs, tests/connection_fragmentation.rs, tests/correlation_id.rs, tests/fixtures/*, tests/fragment_transport/*, tests/multi_packet*.rs
Return errors for failed frame, payload, correlation, and timeout checks. Fixture payload generation cycles through byte values, and message IDs use checked conversion.
Routing, push, and manifest tests
tests/routes.rs, tests/push.rs, tests/workspace_manifest.rs
Replace panic-based checks with fallible checks while retaining the expected test scenarios and manifest requirements.

Suggested labels: Issue

Priority: ⬇️ Low

Change: Other

Merge Risk: ⚪ Minimal · up to b83fe

No actionable merge-blocking issue is established; the change is ready for normal merge checks.

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Developer Documentation ⚠️ Warning The pull request adds a shared test abstraction without updating docs/developers-guide.md. The diff adds tests/common/fallible_assertions/{check,check_eq,check_equal}.rs and imports these `pub(sup… Add a section to docs/developers-guide.md that documents the fallible assertion abstraction: its test-only location, why integration tests use it, the selection of check, check_eq, and check_equal, their Result<(), String> failure…
✅ Passed checks (14 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 86.30% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 73 functions across 23 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Testing (Overall) ✅ Passed Pass this check. The authoritative diff changes only tests/ files and adds no production behaviour. The converted tests retain substantive oracles for real TCP lifecycle callbacks, routing, framing,…
User-Facing Documentation ✅ Passed The pull request changes only integration tests and test-only helpers. The authoritative diff contains no changes to docs/users-guide.md, README files, or product/library user-facing code. It introd…
Module-Level Documentation ✅ Passed Accept the change. Every changed Rust module has module-level //! documentation in the reviewed head. The three new fallible assertion modules document their purpose and relationship to the integrat…
Testing (Unit And Behavioural) ✅ Passed Mark this check as PASS. The diff changes test code only and retains meaningful behavioural checks. The tests still exercise real TCP and duplex connections, WireframeClient, ConnectionActor, `Pus…
Testing (Property / Proof) ✅ Passed Pass this check. The authoritative diff changes only integration tests and test helpers; it adds no production algorithm, lemma, or proof assumption. The new check, check_eq, and check_equal hel…
Testing (Compile-Time / Ui) ✅ Passed Pass the compile-time/UI check. The authoritative diff changes only tests/ files and does not alter production compile-time behaviour, the trybuild harness, or tests/ui cases. The new helpers an…
Unit Architecture ✅ Passed PASS: Keep this change. The pull request changes only integration-test code. The new check, check_eq, and check_equal helpers are narrow, pure comparisons with explicit Result errors and no I/…
Domain Architecture ✅ Passed Keep the change. The authoritative diff changes only files under tests/; it adds test assertion helpers, updates integration tests, adjusts test fixtures, and removes an unused test harness helper. …
Observability ✅ Passed Pass the observability check. The authoritative PR diff changes only tests/** files and test-only fallible assertion helpers. It does not alter production operational behaviour or add a new runtime …
Title check ✅ Passed The title clearly describes the main change: replacing panicking integration-test assertions with fallible assertions. No issue or roadmap identifier is required by the provided context.
Description check ✅ Passed The description directly explains the fallible assertion changes, affected tests, validation results, review feedback, and scope.
Full details: Developer Documentation

Explanation

The pull request adds a shared test abstraction without updating docs/developers-guide.md. The diff adds tests/common/fallible_assertions/{check,check_eq,check_equal}.rs and imports these pub(super) helpers from multiple integration-test crates. The developer's guide documents other shared test-support boundaries, but it contains no reference to fallible_assertions, check, check_eq, or check_equal. No documentation file changes are present in the reviewed range. Rustdoc comments in the new source files do not satisfy the requirement for developer-guide documentation.

Resolution

Add a section to docs/developers-guide.md that documents the fallible assertion abstraction: its test-only location, why integration tests use it, the selection of check, check_eq, and check_equal, their Result&lt;(), String&gt; failure behaviour, and the rule to propagate failures with ? instead of using panic-based assertions in Result-returning tests. Confirm that no ADR or design-document update is needed because this remains test-only scaffolding. No roadmap or new execplan update is required unless this work is explicitly tracked as a roadmap item.


Check each frame and pass errors along.
Count each callback; report what is wrong.
Let bytes cycle, and IDs convert with care.
Keep each test's expected result clear.
Return the failure; let no panic declare.

Comment @coderabbitai help to get the list of available commands.

@leynos
leynos added this pull request to stack #707 September 23, 2026 21:28
@sourcery-ai

sourcery-ai Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

The PR replaces panicking assertions and related lint suppressions across 18 integration-test files with fallible checks that preserve detailed expected/actual diagnostics, propagates failures through async and I/O paths, makes fixture conversions safe, and removes one unused harness helper; the stated validation suite passes.

File-Level Changes

Change Details Files
Introduced shared fallible assertion helpers and migrated integration-test expectations to return diagnostic errors.
  • Added predicate, copyable equality, and borrowed equality helpers with expected/actual context.
  • Replaced panicking assertions, expect calls, and selected manual panics across lifecycle, transport, routing, preamble, queue, prepared-app, metadata, streaming, and manifest tests.
  • Preserved Result propagation through asynchronous callbacks, spawned tasks, I/O, and subprocess-related paths.
tests/common/fallible_assertions/check.rs
tests/common/fallible_assertions/check_eq.rs
tests/common/fallible_assertions/check_equal.rs
tests/client_lifecycle.rs
tests/connection_fragmentation.rs
tests/correlation_id.rs
tests/lifecycle.rs
tests/metadata.rs
tests/middleware_order.rs
tests/multi_packet.rs
tests/multi_packet_streaming.rs
tests/preamble/basic.rs
tests/preamble/responses.rs
tests/preamble/timeouts.rs
tests/prepared_app.rs
tests/prepared_app_tcp.rs
tests/push.rs
tests/routes.rs
tests/workspace_manifest.rs
Removed lint suppressions and eliminated remaining test-only panic paths while retaining assertion coverage and improving failure diagnostics.
  • Deleted 45 clippy::panic_in_result_fn expectations in the assigned integration surface.
  • Converted callback and timeout validation failures into typed or boxed errors instead of panics.
  • Updated spawned server tasks to propagate accept and preamble I/O failures with double-? joins.
tests/client_lifecycle.rs
tests/connection_fragmentation.rs
tests/connection_fragmentation.rs
tests/fragment_transport/eviction.rs
tests/fragment_transport/rejection.rs
tests/lifecycle.rs
tests/metadata.rs
tests/multi_packet_streaming.rs
tests/preamble/timeouts.rs
tests/prepared_app.rs
tests/push.rs
tests/routes.rs
Made numeric fixture generation and conversions fallible or inherently range-safe.
  • Replaced unchecked usize to u32 message-ID conversion with u32::try_from propagation.
  • Replaced modulo-and-cast byte patterns with cycling u8 ranges.
  • Removed obsolete numeric lint suppressions.
tests/fixtures/client_messaging.rs
tests/fixtures/client_send_streaming.rs
Removed an unused connection harness builder method.
  • Deleted the dead response-tracking toggle and its dead_code suppression.
tests/connection.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-access[bot]

This comment was marked as outdated.

Comment thread tests/client_lifecycle.rs Outdated
Comment thread tests/workspace_manifest.rs
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review September 24, 2026 03:47

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 11 hours and 2 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T00:31:53.039734Z 5d61488 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@leynos
leynos marked this pull request as draft September 24, 2026 04:23
@leynos
leynos force-pushed the test-quality-fallible-assertions branch from ae3b655 to cf65478 Compare September 24, 2026 04:24
codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos force-pushed the test-quality-fallible-assertions branch from cf65478 to b83fe9b Compare September 24, 2026 04:41
codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review September 24, 2026 04:59

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 9 hours and 51 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@coderabbitai coderabbitai Bot added the Issue label Sep 24, 2026
@leynos
leynos removed this pull request from stack #707 September 24, 2026 05:19
@leynos
leynos added this pull request to stack #715 September 24, 2026 05:20
@leynos
leynos marked this pull request as draft September 24, 2026 07:15
@leynos
leynos force-pushed the test-quality-fallible-assertions branch from b83fe9b to 5e85f6a Compare September 24, 2026 07:25
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as draft September 27, 2026 00:29
@leynos
leynos marked this pull request as ready for review September 27, 2026 00:29

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, your pull request is larger than the review limit of 150,000 diff characters

@leynos leynos closed this Sep 27, 2026
@leynos leynos reopened this Sep 27, 2026
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

Base automatically changed from test-quality-sweep to main September 27, 2026 03:19
@leynos

leynos commented Sep 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat o11y, code safety, documentation and validation coverage as in scope).

❌ Failed check (1 warning)

Check name Status Explanation Resolution
Developer Documentation ⚠️ Warning The pull request adds a shared test abstraction without updating docs/developers-guide.md. The diff adds tests/common/fallible_assertions/{check,check_eq,check_equal}.rs and imports these `pub(sup… Add a section to docs/developers-guide.md that documents the fallible assertion abstraction: its test-only location, why integration tests use it, the selection of check, check_eq, and check_equal, their Result<(), String> failure…

@coderabbitai

coderabbitai Bot commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -uo pipefail
printf '%s\n' '--- branch and PR ---'
git status --short
git rev-parse --short HEAD
gh pr view 708 --repo leynos/wireframe --json headRefOid,updatedAt,files,statusCheckRollup --jq '{headRefOid,updatedAt,files:[.files[].path],checks:[.statusCheckRollup[]?|{name,conclusion,status,workflowName}]}'
printf '%s\n' '--- documentation and helper file locations ---'
fd -p 'developers-guide.md|fallible_assertions' docs tests 2>/dev/null || true
printf '%s\n' '--- documentation headings and references ---'
rg -n -C2 'fallible.assert|panic_in_result_fn|integration test|^#{1,4} ' docs/developers-guide.md | head -220
printf '%s\n' '--- helper outlines ---'
for f in tests/common/fallible_assertions/check.rs tests/common/fallible_assertions/check_eq.rs tests/common/fallible_assertions/check_equal.rs; do
  echo "$f"
  ast-grep outline "$f" --items all 2>/dev/null || true
done
printf '%s\n' '--- helper contents ---'
for f in tests/common/fallible_assertions/check.rs tests/common/fallible_assertions/check_eq.rs tests/common/fallible_assertions/check_equal.rs; do
  echo "$f"
  sed -n '1,100p' "$f"
done
printf '%s\n' '--- documentation changes in PR ---'
gh pr diff 708 --repo leynos/wireframe --name-only | rg 'docs/|fallible_assertions' || true

Length of output: 15080


🏁 Script executed:

#!/bin/bash
set -uo pipefail
printf '%s\n' '--- current guide change in PR ---'
gh pr diff 708 --repo leynos/wireframe -- docs/developers-guide.md 2>/dev/null || git diff "$(git merge-base HEAD origin/main)" HEAD -- docs/developers-guide.md
printf '%s\n' '--- test support section ---'
sed -n '775,930p' docs/developers-guide.md
printf '%s\n' '--- helper module imports ---'
rg -n -C2 'fallible_assertions/(check|check_eq|check_equal)\.rs|check_equal\(|check_eq\(|check\(' tests/workspace_manifest.rs tests/middleware_order.rs tests/client_lifecycle.rs | head -125

Length of output: 23505


🏁 Script executed:

#!/bin/bash
set -uo pipefail
printf '%s\n' '--- current guide change in PR ---'
git diff "$(git merge-base HEAD origin/main)" HEAD -- docs/developers-guide.md | head -220
printf '%s\n' '--- test support section ---'
sed -n '775,930p' docs/developers-guide.md
printf '%s\n' '--- helper module imports ---'
rg -n -C2 'fallible_assertions/(check|check_eq|check_equal)\.rs|check_equal\(|check_eq\(|check\(' tests/workspace_manifest.rs tests/middleware_order.rs tests/client_lifecycle.rs | head -125

Length of output: 23435


@leynos Yes. The returned diff shows that PR #708 adds a “Fallible assertions in integration tests” section to docs/developers-guide.md. It covers the test-only location, the reason for fallible checks, when to use each helper, their Result<(), String> behaviour, and failure propagation with ?.

My earlier answer was wrong. The search output I relied on stopped before the new section. Withdraw the Developer Documentation finding; no AI agent prompt or follow-up issue is needed for this warning. The documentation finding is resolved by the diff, although that does not establish that every hosted check has rerun.

You are interacting with an AI system.

@leynos
leynos force-pushed the test-quality-fallible-assertions branch from 9f0ca75 to 9989de1 Compare September 27, 2026 16:02
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

leynos and others added 6 commits September 27, 2026 18:38
Replace panic-prone assertions in Result-returning integration tests
with fallible checks that preserve their predicates and diagnostics.
Keep genuine I/O and subprocess failures on the existing Result paths,
and share small fallible assertion helpers across related test crates.

Remove the unused connection harness builder and make fixture byte
construction fallible without changing its generated payloads.
Move the fallible preamble server exchange and workspace-member
checks into small helpers. Preserve the existing predicates,
diagnostics, and callback order while satisfying the CodeScene
method-size gate on the integration-test layer.
tests/prepared_app.rs (575 lines) and tests/connection.rs (549 lines)
both exceeded the repository's 400-line file limit, and the fallible
assertion work pushed prepared_app.rs further over it.

Split both files into feature-focused modules, following the existing
`tests/preamble/` and `tests/fragment_transport/` layout:

- prepared_app/: support, startup, teardown, reuse, tcp, property
- connection/: support, multi_packet, logs, state

The root files are now thin drivers that declare the submodules. Shared
fixtures, harness configuration, and assertions move into a `support`
module in each crate.

No assertion predicate, message, callback ordering, or test name changed;
the crates still build to the same 5 and 17 tests respectively. The
`#[path]` declaration for the fallible assertion helpers stays in the
driver file because those helpers are `pub(super)`, which resolves to
crate visibility only at the crate root.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The fallible assertion abstraction added in this branch had no entry in
the developers' guide, which documents the other shared test-support
boundaries.

Add a "Fallible assertions in integration tests" subsection covering why
`Result`-returning tests need it, how to choose between `check`,
`check_eq`, and `check_equal`, and the `Result<(), String>` failure
contract. Record the `#[path]` placement rule, since the helpers are
`pub(super)` and therefore must be declared in the crate root rather than
in a submodule.

Remains test-only scaffolding, so no ADR or design document change is
needed.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The rebase conflict resolution merged `main`'s wireframe-loom
assertions into this branch's extracted `check_workspace_members`
helper by adding `loom_package_id` as a fifth parameter. This repo pins
`too-many-arguments-threshold = 4` in `clippy.toml` (the default is 7),
so the helper breached `clippy::too_many_arguments` under `-D warnings`.

The helper now takes the expected members as a slice of
`(package_id, description)` pairs, and each call site names its own
pairs. That keeps `main`'s description-carrying loop and the
verification of all four workspace members, including the
wireframe-loom crate, while restoring the two-parameter signature.

The branch exists to remove `#[expect]`s of this shape, so suppressing
the lint here would have worked against its purpose. Gate result for
this head: `make check-fmt`, `make typecheck`, `make test`,
`make markdownlint`, and `make spelling` all exited 0; `make lint`
failed only on this one diagnostic, which is now fixed.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Merging `main`'s wireframe-loom assertion into
`cargo_metadata_reports_explicit_members_without_widening_default_members`
grew that function to 71 lines against CodeScene's threshold of 70, so
CodeScene raised a "Large Method" finding on the rebased head. It was 65
lines on `main`, so the growth came from the conflict resolution rather
than from either side's intent.

Extract the two identical `cargo metadata` array lookups into a
`metadata_array` helper. The function is now 55 lines, below both the
CodeScene threshold and its pre-rebase length, and the duplicated
`ok_or_else` formatting lives in one place. The diagnostic text is
unchanged: it still names the requested field and reports the actual
value.

`cargo check --workspace --all-targets --all-features` and
`cargo fmt --all -- --check` both exit 0 for this change.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@leynos
leynos force-pushed the test-quality-fallible-assertions branch from 613ed21 to f693b29 Compare September 27, 2026 17:02
@leynos

leynos commented Sep 27, 2026

Copy link
Copy Markdown
Owner Author

Rebase update — citations refreshed for the new head

origin/main advanced to 2892081 (PR #642, "Prepare applications before server readiness") after the previous round, so the branch was rebased a second time. Current head: f693b29. The replay boundary is 43b90a3.

SHAs cited in the earlier confirmations no longer exist on this branch. Commit-message-preserving equivalents in the new series:

Previous Now Subject
5579d7d 2088a94 Make integration assertions fallible
7ec847e 85ef6ba Extract long integration test checks
f2f30b8 ec4e36d Split oversized integration test modules
db61dd3 a216070 Document the fallible assertion helpers
9989de1 5c93061 Fit the extracted manifest helper within the argument policy
613ed21 f693b29 Keep the manifest metadata test within the method-size threshold

All three previously-confirmed concerns re-verified at f693b29:

  • tests/client_lifecycle.rs — serve_preamble_ack(listener: TcpListener) -> TestResult<()> is defined at :147 and spawned at :170. The test retains its callback order, server join, and all three count checks and messages.
  • tests/workspace_manifest.rs — check_workspace_members(members, expected) -> TestResult is at :57. All four workspace members are still checked in the original order with the missing-array diagnostic preserved; the file is 196 lines.
  • tests/prepared_app.rs — 331 lines, under the 400-line AGENTS.md limit. The rebase took main's newer sibling-crate layout (a strict superset of this branch's earlier subdirectory split) and then applied this branch's fallible conversion to it, which also removed a newly-added #[expect(clippy::panic_in_result_fn)] in tests/prepared_app_tcp.rs. The real-socket scenarios moved to tests/prepared_app/tcp.rs (104 lines) behind a #[path] declaration.

Because main's PR changed production startup semantics — prepare once and share one immutable PreparedApp root across workers — the startup test's expected counts changed with it (factory_calls: 1 rather than one per connection). The old numbers were deliberately not re-asserted.

typos.toml is unchanged by this branch: the pre-rebase "Refresh the generated spelling dictionary" commit is byte-identical to 43b90a3, and origin/main already carries that refresh, so the rebase dropped it as an empty change.

Gates on f693b29: make check-fmt, make lint, make typecheck, make test (1222 passed, 0 failed, 0 ignored across 81 binaries), make markdownlint, make spelling, and make nixie all exit 0. Hosted build-test dispatched this time and passed (36335471809); CodeScene re-reviewed and approved at this head.

@coderabbitai

@coderabbitai

coderabbitai Bot commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -uo pipefail
printf '%s\n' '--- head and PR status ---'
git rev-parse --short HEAD
gh pr view 708 --repo leynos/wireframe --json headRefOid,statusCheckRollup --jq '{headRefOid,checks:[.statusCheckRollup[]?|{name,status,conclusion}]}'
printf '%s\n' '--- named files ---'
fd -p 'tests/client_lifecycle.rs|tests/workspace_manifest.rs|tests/prepared_app.rs|tests/prepared_app/tcp.rs|tests/prepared_app_tcp.rs|docs/developers-guide.md' . || true
printf '%s\n' '--- outlines ---'
for f in tests/client_lifecycle.rs tests/workspace_manifest.rs tests/prepared_app.rs tests/prepared_app/tcp.rs tests/prepared_app_tcp.rs; do
  if test -f "$f"; then echo "--- $f"; ast-grep outline "$f" --items all 2>/dev/null | head -85; fi
done
printf '%s\n' '--- lifecycle server and checks ---'
sed -n '130,220p' tests/client_lifecycle.rs
printf '%s\n' '--- workspace checks ---'
sed -n '1,205p' tests/workspace_manifest.rs
printf '%s\n' '--- prepared app references ---'
rg -n -C3 'factory_calls|#\[path|check_equal|panic_in_result_fn|PreparedApp' tests/prepared_app.rs tests/prepared_app/tcp.rs tests/prepared_app_tcp.rs 2>/dev/null | head -160
wc -l tests/prepared_app.rs tests/prepared_app/tcp.rs tests/workspace_manifest.rs
printf '%s\n' '--- guide section ---'
rg -n -C7 'Fallible assertions in integration tests|fallible_assertions|check_equal' docs/developers-guide.md | head -110
printf '%s\n' '--- doc diff from replay boundary ---'
git diff --stat 43b90a3 HEAD -- docs/developers-guide.md

Length of output: 27557


@leynos, my previous reply said I could not verify the rebase update. The shell results now confirm that PR #708 is at f693b29.

The inspected files support your report about the three earlier concerns. docs/developers-guide.md also contains the fallible assertion section, so the Developer Documentation warning remains resolved. GitHub reports build-test and CodeScene Code Health Review as successful at this head.

I did not rerun the local gates. Your reported local gate results remain author-reported.


✏️ Learnings added
Learnt from: leynos
URL: https://github.com/leynos/wireframe/pull/708

Timestamp: 2026-09-27T17:21:33.180Z
Learning: In leynos/wireframe, server startup prepares an application once and shares one immutable `PreparedApp` root across workers. The startup expectations in `tests/prepared_app.rs` therefore use `factory_calls: 1` for server preparation, not one factory call per connection.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@leynos

leynos commented Sep 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai approve

@coderabbitai

coderabbitai Bot commented Sep 27, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Comments resolved and changes approved.

@leynos
leynos merged commit 3f6a608 into main Sep 27, 2026
11 checks passed
@leynos
leynos deleted the test-quality-fallible-assertions branch September 27, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant