Skip to content

test(relay): run the outage lease test on the real clock - #4244

Merged
kixelated merged 2 commits into
mainfrom
claude/relay-auth-lifetime-flake
Sep 26, 2026
Merged

kixelated merged 2 commits into
mainfrom
claude/relay-auth-lifetime-flake

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Problem

an_outage_keeps_the_session_until_expires fails ~9/10 runs on macOS with publisher connect timeout after ~0.1s. It ran under start_paused = true, which auto-advances the clock to the next timer whenever the runtime has no ready work. The relay accepts the TCP connection, then waits on the kernel for the client's bytes; macOS delivers loopback asynchronously, so the idle poll finds nothing and jumps straight past the 10s timeout. Linux loopback completes inside the sender's syscall, so Linux CI passes (checked runs 36213200307 and 36212266674, both with #4215).

#4215 exposed it by removing wait_for_listener: restoring that probe makes it pass 10/10 again, but only by luck, not by removing the race.

Approach

The test spans real sockets (auth HTTP, TCP sessions), so a virtual clock can't bound it. Run it on the real clock with a whole-second expires ~2-3s out (the wire carries whole seconds, so the relay sees that exact instant), and assert the close is observed no earlier than expires. Load only delays the close, so the assertion holds on a busy machine; the old 100ms "still open" sample is gone.

Verified on macOS (M4): 10/10 passes (~2.1s each); the whole auth_lifetime file 20/20 under --stress-count with every core pinned by yes; forcing the relay deadline to 1s fails with "an outage must not close the publisher before expires".

Impact

  • None: test-only.

Alternatives

  • Restore wait_for_listener: masks the race; any later socket wait under the paused clock can still fire a virtual timeout.
  • Pause only after setup: the close and end reports still travel over sockets while assert_closed's timeout is pending.

Follow-ups

  • fix(auth): keep accepted grants on fixed expiry deadlines #4237 adds a 5s skew allowance to the deadline, which would add 5s real time here; the lower-bound assertion and 10s timeout still hold.
  • Other start_paused tests near sockets (moq-relay cluster.rs, internal.rs, websocket.rs; moq-tokio mdns.rs, resolve.rs) weren't audited for the same race.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

A paused tokio clock auto-advances to the next timer whenever the runtime
waits on a socket. macOS delivers loopback asynchronously, so the test's
10s connect timeout fired mid-handshake: ~9 in 10 runs failed once #4215
dropped the listener probe that happened to mask it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review September 26, 2026 04:58
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 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-26T14:38:10.240361Z 56089bb New commits
ℹ️ 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.

@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 56 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: e1bd4486-b36c-441f-bfc7-628ef54fa670

📥 Commits

Reviewing files that changed from the base of the PR and between ea7db01 and 56089bb.

📒 Files selected for processing (1)
  • rs/moq-relay/tests/auth_lifetime.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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

Copy link
Copy Markdown

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 automated review suggestions for this pull request.

Reviewed commit: 1973488506

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

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

const SLACK: Duration = Duration::from_secs(30);
// Whole seconds, as the grant crosses the wire, so the relay sees this exact instant.
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
let expires = SystemTime::UNIX_EPOCH + Duration::from_secs(now.as_secs() + 3);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Start the short expiry after connection setup

This deadline is only 2–3 seconds away, but it starts before binding the auth server and relay and before completing two sequential client handshakes plus the media round-trip, even though those setup operations individually allow up to 10 seconds. On a sufficiently loaded runner the grant can therefore expire during setup, causing connection failure or exercising the clock-skew path instead of the intended live-session outage behavior; load does not merely delay the observed close as the comment claims.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not changing this. The grant's expires is fixed by the connect answer, and re-checks answer 503, so it can't start after setup. Setup is a few ms of loopback round-trips against a 2-3s budget, and if it ever overran expires the connect would be refused and the test fails loudly at "publisher/subscriber connect failed", never a false pass. Widening the margin would add real seconds to every run for a load level that would already time out other tests.

(Written by Claude Opus 5.5)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merged origin/main (#4240) and re-ran cargo test -p moq-relay --test auth_lifetime: 12/12 pass. Replied to the Codex setup-margin finding without changing the test. Enabling auto-merge.

(Written by Claude Opus 5.5)

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.

1 participant