Skip to content

Fix incorrect Notified await and remove stray lint expectation#101

Merged
leynos merged 5 commits intomainfrom
codex/fix-lint-errors-in-tests
Sep 15, 2025
Merged

Fix incorrect Notified await and remove stray lint expectation#101
leynos merged 5 commits intomainfrom
codex/fix-lint-errors-in-tests

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Sep 14, 2025

Summary

  • remove unused lint expectation from TestComplexity
  • await Notified instances without borrowing to satisfy Unpin

Testing

  • make fmt
  • make lint
  • make test

https://chatgpt.com/codex/tasks/task_e_68c6ae2b6a308322a72309ae796d7507

Summary by Sourcery

Remove unused dead_code lint expectation and streamline Notify::notified() usage in tests by awaiting the returned futures directly rather than through mutable references

Bug Fixes:

  • Remove incorrect mutable borrows when awaiting Notify::notified() futures to satisfy Unpin requirements
  • Eliminate stray unused lint expectation on the TestComplexity enum

Enhancements:

  • Simplify test code by awaiting Notify::notified() directly without &mut

Tests:

  • Update daemon and worker integration tests to capture and await Notify::notified() futures directly

This reverts commit 8dd43a5732e21f18db751915ee7ca78fcdd202a9.
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Sep 14, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

The PR updates async tests to await Notify.notified() futures directly (removing mutable borrows to satisfy Unpin) and removes a redundant lint expectation on the TestComplexity enum.

File-Level Changes

Change Details Files
Fix awaiting of Notify.notified() futures to remove unnecessary mutable borrows
  • Dropped mutable binding for Notify::notified()
  • Replaced (&mut future).await with future.await in tests
crates/comenqd/tests/daemon.rs
Remove stray lint expectation from TestComplexity enum
  • Deleted #[expect(dead_code, …)] from Simple variant
crates/comenqd/tests/util.rs

Possibly linked issues


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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 14, 2025

Warning

Rate limit exceeded

@leynos has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 2a432d7 and 717de17.

📒 Files selected for processing (2)
  • crates/comenqd/src/daemon.rs (1 hunks)
  • crates/comenqd/tests/util.rs (3 hunks)

Summary by CodeRabbit

  • New Features

    • Listener read-timeout and request-size limits are now publicly accessible for easier reuse and consistency.
  • Tests

    • Improved worker tests for clearer async behaviour without changing outcomes.
    • Added coverage to exercise all test complexity levels.
  • Refactor

    • Simplified test waiting patterns to reduce mutable bindings and improve clarity; no functional changes.

Walkthrough

Refactor test awaiting of Notify to avoid mutable Notified bindings by cloning Arc<Notify> and awaiting inside closures; remove a dead_code lint suppression on TestComplexity::Simple; add CLIENT_READ_TIMEOUT_SECS and MAX_REQUEST_BYTES to the daemon listener public re-exports.

Changes

Cohort / File(s) Summary
Await syntax refactor in tests
crates/comenqd/tests/daemon.rs
Replace mutable Notified future bindings with closures that clone the Arc<Notify> and call await on notified() on-demand (remove &mut ... .await usage).
Lint attribute adjustment
crates/comenqd/tests/util.rs
Remove #[expect(dead_code, reason = "...")] attribute from the TestComplexity::Simple enum variant and add a test uses_all_test_complexity_variants to exercise variants.
Daemon listener public re-exports
crates/comenqd/src/daemon.rs
Expand pub use crate::listener::{...} to include CLIENT_READ_TIMEOUT_SECS and MAX_REQUEST_BYTES alongside handle_client, prepare_listener, and run_listener.

Sequence Diagram(s)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

Clone the Notify, await on cue,
Drop the mut, keep tests true.
A lint erased, two constants shown,
API stretched, no logic blown.
Small tidy steps, then push and brew.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed Mark the title as an accurate, concise summary of the primary changes. Reference both the Notified await fix and the removal of the stray lint expectation, which align with the test updates and the TestComplexity change described in the raw_summary and PR objectives. Note the small public re-export change in daemon.rs is present but not the main intent, so keep the title focused on the test and lint fixes.
Description Check ✅ Passed Mark the PR description as related to the changeset and sufficient for this lenient check. State the description documents removal of the dead_code lint expectation and the switch to awaiting Notify::notified() directly, which matches the file diffs and PR objectives. Approve the description as adequately connected to the changes for reviewers to understand the intent.

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

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

Codex Review: Here are some suggestions.

Reply with @codex fix comments to fix any unresolved comments.

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, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback".

Comment thread crates/comenqd/tests/daemon.rs Outdated
Comment thread crates/comenqd/tests/daemon.rs Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 273f1b6 and bcffa25.

📒 Files selected for processing (2)
  • crates/comenqd/src/daemon.rs (1 hunks)
  • crates/comenqd/tests/daemon.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Use rstest fixtures for shared setup.
Replace duplicated tests with #[rstest(...)] parameterised cases.
Prefer mockall for mocks/stubs.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary. Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library. Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.

Files:

  • crates/comenqd/src/daemon.rs
  • crates/comenqd/tests/daemon.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in tests ...

Files:

  • crates/comenqd/src/daemon.rs
  • crates/comenqd/tests/daemon.rs
🧬 Code graph analysis (2)
crates/comenqd/src/daemon.rs (1)
crates/comenqd/src/listener.rs (3)
  • handle_client (117-136)
  • prepare_listener (34-44)
  • run_listener (57-103)
crates/comenqd/tests/daemon.rs (2)
crates/comenqd/src/worker.rs (1)
  • run_worker (161-223)
crates/comenqd/tests/util.rs (1)
  • timeout_with_retries (66-92)
🔍 Remote MCP Ref

Summary of relevant facts for reviewing this PR

  • tokio::sync::futures::Notified is not Unpin (Notified<'_> implements !Unpin). Awaiting a Notified by reference (&mut notified).await therefore requires Unpin; awaiting the future by value (notified().await) does not. This explains why the tests were changed to clone the Notify handle and await notified().await instead of awaiting a previously bound &mut Notified.

  • tokio::sync::Notify docs show the common pattern for one‑off waits is notify.notified().await; when reusing the same Notified future across iterations you must pin it (e.g., tokio::pin!) and use as_mut().await. Thus the PR’s approach (clone the Arc and call notified().await inside the closure) is the recommended simple fix when the future is not intended to be reused.

Files/changes this validates in the PR

  • Tests switching from awaiting &mut Notified to awaiting notified().await by-value — fixes the Unpin requirement and matches tokio docs.
  • Removing the stray #[expect(dead_code,...)] attribute on TestComplexity::Simple is a non-functional lint change (no runtime effect).

Sources/tools used

  • docs.rs — tokio::sync::futures::Notified struct docs (Notified !Unpin)
  • docs.rs — tokio::sync::Notify struct docs (notified().await pattern, pinning when reusing)
  • Documentation search (query for Notified Unpin)
🔇 Additional comments (4)
crates/comenqd/tests/daemon.rs (4)

292-293: Pass Arc<Notify> into hooks (not Notified)

Bind the hook to the Notify handle and await per‑attempt futures elsewhere. This keeps hooks simple and avoids pinning concerns.


297-305: Await Notify::notified() by value inside the retry closure (fixes !Unpin and FnMut)

Create a fresh Notified on each retry and await it by value. This removes the Unpin requirement and satisfies the FnMut bound of timeout_with_retries.

Ensure CI runs these tests on a slower runner to smoke out timing flakiness.


359-360: Hook enqueued notification via Arc<Notify> clone

Feed the handle, not a pre‑created waiter. This mirrors the drained path and avoids lifetime/pinning pitfalls.


366-371: Generate a new waiter per attempt for enqueued path

Call enqueued.notified().await inside the closure so retries remain valid and independent.

Comment thread crates/comenqd/src/daemon.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bcffa25 and 2a432d7.

📒 Files selected for processing (1)
  • crates/comenqd/tests/util.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Use rstest fixtures for shared setup.
Replace duplicated tests with #[rstest(...)] parameterised cases.
Prefer mockall for mocks/stubs.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary. Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library. Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.

Files:

  • crates/comenqd/tests/util.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in tests ...

Files:

  • crates/comenqd/tests/util.rs
🔍 Remote MCP Ref

Summary of additional relevant facts for the review

  • tokio::sync::futures::Notified is not Unpin (Notified implements !Unpin). Awaiting a Notified via a mutable reference (&mut notified).await requires the future to be Unpin; this is why the original tests failed lint/compile when holding a Notified and awaiting it by reference.

  • The documented, idiomatic usage for one‑off waits is to call notify.notified().await (await the future by value). If you must reuse the same Notified future across awaits, you must pin it (e.g., tokio::pin!) and use as_mut().await. The PR’s change—clone the Arc and call notified().await inside the closure—matches the recommended pattern and avoids Unpin issues.

  • Removing the stray #[expect(dead_code, ...)] attribute on TestComplexity::Simple is purely a lint/test-usage cleanup with no behavioral/runtime impact. (No external citation required; change is local to tests in the PR.)

Sources/tools used

  • docs.rs — tokio::sync::futures::Notified documentation
  • docs.rs — tokio::sync::Notify documentation (notified/pinning guidance)
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test

Comment thread crates/comenqd/tests/util.rs Outdated
@leynos leynos merged commit 5668949 into main Sep 15, 2025
2 of 3 checks passed
@leynos leynos deleted the codex/fix-lint-errors-in-tests branch September 15, 2025 20:56
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