mirror of
https://github.com/hanzoai/codex.git
synced 2026-10-30 14:59:26 +00:00
## What changed - Add experimental `account/read.workspaceRouting` metadata containing the selected ChatGPT workspace ID, resolved HTTPS backend origin, and routing override (`us`, `us_cr`, or `NO_CONSTRAINT`). - Discover and cache routing through `accounts/check` for saved logins, new logins, and workspace switches. Return `null` for signed-out accounts, API-only accounts, and saved credentials without a selected workspace. - Validate discovered origins against required `chatgpt_base_url` origins. Return errors for failed or malformed discovery and retry on later reads. - Wait for requirements and routing before publishing account updates, including to newly initialized connections. Clear routing on logout, discard stale discovery results, and guard queued notifications against account changes. ## Testing Add unit and integration coverage for origin resolution and validation, discovery failures and retries, startup discovery, workspace switching, logout, configuration changes during discovery, and authentication changes while notifications wait for queue capacity. GitOrigin-RevId: 2c5367bb01dd7543b08d374f44444323e40f1981
100 lines
3.5 KiB
Rust
100 lines
3.5 KiB
Rust
//! Exercises auth changes while notification delivery waits for queue capacity.
|
|
|
|
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
use test_case::test_case;
|
|
|
|
#[test_case(0; "same_owner_refresh")]
|
|
#[test_case(1; "owner_change")]
|
|
#[test_case(2; "coalesced_owner_changes")]
|
|
#[tokio::test]
|
|
async fn queued_notifications_follow_auth_owner_changes(owner_generation: u64) {
|
|
for login in [false, true] {
|
|
let (tx, mut rx) = mpsc::channel(/*buffer*/ 1);
|
|
let outgoing = OutgoingMessageSender::new(
|
|
tx.clone(),
|
|
codex_analytics::AnalyticsEventsClient::disabled(),
|
|
);
|
|
let (changes, auth_changes) = watch::channel(AuthChangeState::default());
|
|
let updated = AccountUpdatedNotification {
|
|
auth_mode: None,
|
|
plan_type: None,
|
|
};
|
|
tx.send(OutgoingEnvelope::Broadcast {
|
|
message: timestamped_server_notification(ServerNotification::AccountUpdated(
|
|
updated.clone(),
|
|
)),
|
|
})
|
|
.await
|
|
.unwrap();
|
|
let payload = AccountLoginCompletedNotification {
|
|
login_id: Some("queued-login".into()),
|
|
success: true,
|
|
error: None,
|
|
onboarding_entrypoint: None,
|
|
};
|
|
let notification = if login {
|
|
AccountNotification::LoginCompleted(payload.clone())
|
|
} else {
|
|
AccountNotification::Updated(updated.clone())
|
|
};
|
|
let send = outgoing.send_account_notification(
|
|
Some(ConnectionId(7)),
|
|
&auth_changes,
|
|
/*owner_generation*/ 0,
|
|
notification,
|
|
);
|
|
tokio::pin!(send);
|
|
// Poll delivery with a full queue before changing authentication.
|
|
assert!(futures::poll!(&mut send).is_pending());
|
|
changes.send_replace(AuthChangeState {
|
|
generation: 2,
|
|
owner_generation,
|
|
});
|
|
rx.recv().await.unwrap();
|
|
send.await;
|
|
if login {
|
|
let OutgoingEnvelope::ToConnection {
|
|
connection_id,
|
|
message: OutgoingMessage::AppServerNotification(envelope),
|
|
..
|
|
} = rx.try_recv().unwrap()
|
|
else {
|
|
panic!("expected targeted login completion");
|
|
};
|
|
assert_eq!(connection_id, ConnectionId(7));
|
|
let ServerNotification::AccountLoginCompleted(actual) = envelope.notification else {
|
|
panic!("expected login completion");
|
|
};
|
|
assert_eq!(
|
|
actual,
|
|
if owner_generation == 0 {
|
|
payload
|
|
} else {
|
|
AccountLoginCompletedNotification {
|
|
success: false,
|
|
error: Some("account changed before sign-in completed".into()),
|
|
..payload
|
|
}
|
|
}
|
|
);
|
|
} else if owner_generation == 0 {
|
|
let OutgoingEnvelope::ToConnection {
|
|
connection_id,
|
|
message: OutgoingMessage::AppServerNotification(envelope),
|
|
..
|
|
} = rx.try_recv().unwrap()
|
|
else {
|
|
panic!("expected targeted account update");
|
|
};
|
|
assert_eq!(connection_id, ConnectionId(7));
|
|
let ServerNotification::AccountUpdated(actual) = envelope.notification else {
|
|
panic!("expected account update");
|
|
};
|
|
assert_eq!(actual, updated);
|
|
} else {
|
|
assert!(rx.try_recv().is_err());
|
|
}
|
|
}
|
|
}
|