mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
## What changed - Add `accountSession/list` and `accountSession/switch` for the active managed ChatGPT login, with optional workspace membership refresh. - Validate membership and workspace policy, pause new turns, and unload running threads before switching credentials. Notify clients with `thread/closed` and `account/updated`; selecting the current workspace leaves threads running. - Support browser sign-in for SSO through `allowBrowserLogin`, binding the callback to the requesting login and workspace. Require a separate sign-in for government workspaces. - Preserve the selected workspace across token refresh and conditionally restore the previous workspace if routing validation fails. Guard credential writes against concurrent login or logout changes. ## Testing Add app-server and auth tests covering workspace switching, credential preservation, policy and identity rejection, conditional rollback, stale sessions, and SSO callback validation. GitOrigin-RevId: 1234abc33b71e69b66318da3e201fccc08867906
52 lines
1.7 KiB
Rust
52 lines
1.7 KiB
Rust
use super::TurnAdmission;
|
|
use crate::error_code::INVALID_REQUEST_ERROR_CODE;
|
|
use codex_extension_api::TurnStartAdmission;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn drain_rejects_new_work_without_waiting_for_admitted_work() {
|
|
let admission = TurnAdmission::default();
|
|
let active = admission.subscribe_active();
|
|
let in_flight = admission.admit().expect("initial request admitted");
|
|
let automatic = admission
|
|
.admit_turn_start()
|
|
.expect("automatic start admitted");
|
|
admission.begin_drain();
|
|
assert_eq!(*active.borrow(), 2);
|
|
assert!(admission.admit_turn_start().is_none());
|
|
|
|
let error = admission.admit().err().expect("new request rejected");
|
|
assert_eq!(error.code, INVALID_REQUEST_ERROR_CODE);
|
|
assert_eq!(
|
|
error.data,
|
|
Some(serde_json::json!({ "reason": "serverShuttingDown" }))
|
|
);
|
|
drop(in_flight);
|
|
assert_eq!(*active.borrow(), 1);
|
|
drop(automatic);
|
|
assert_eq!(*active.borrow(), 0);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn workspace_pause_waits_for_admitted_work_and_preserves_shutdown_drain() {
|
|
let admission = TurnAdmission::default();
|
|
let in_flight = admission.admit().unwrap();
|
|
let pending_pause = admission.pause();
|
|
tokio::pin!(pending_pause);
|
|
tokio::select! {
|
|
biased;
|
|
_ = &mut pending_pause => panic!("pause completed before the existing request"),
|
|
() = async {} => {}
|
|
}
|
|
assert!(admission.admit().is_err());
|
|
assert!(admission.admit_turn_start().is_none());
|
|
drop(in_flight);
|
|
let pause = pending_pause.await.unwrap();
|
|
drop(pause);
|
|
drop(admission.admit().unwrap());
|
|
let pause = admission.pause().await.unwrap();
|
|
admission.begin_drain();
|
|
drop(pause);
|
|
assert!(admission.admit().is_err());
|
|
}
|