From 0533bd2e7cc65c3ae46b51baa3a9128eda230492 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Fri, 24 Oct 2025 18:31:24 -0500 Subject: [PATCH] Fixed flaky unit test (#5654) This PR fixes a test that is sporadically failing in CI. The problem is that two unit tests (the older `login_and_cancel_chatgpt` and a recently added `login_chatgpt_includes_forced_workspace_query_param`) exercise code paths that start the login server. The server binds to a hard-coded localhost port number, so attempts to start more than one server at the same time will fail. If these two tests happen to run concurrently, one of them will fail. To fix this, I've added a simple mutex. We can use this same mutex for future tests that use the same pattern. --- codex-rs/Cargo.lock | 1 + codex-rs/app-server/Cargo.toml | 1 + codex-rs/app-server/tests/suite/login.rs | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 0d8522a6..a2e49fc5 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -853,6 +853,7 @@ dependencies = [ "pretty_assertions", "serde", "serde_json", + "serial_test", "tempfile", "tokio", "toml", diff --git a/codex-rs/app-server/Cargo.toml b/codex-rs/app-server/Cargo.toml index 5efbefd6..c1efb2ef 100644 --- a/codex-rs/app-server/Cargo.toml +++ b/codex-rs/app-server/Cargo.toml @@ -47,6 +47,7 @@ base64 = { workspace = true } core_test_support = { workspace = true } os_info = { workspace = true } pretty_assertions = { workspace = true } +serial_test = { workspace = true } tempfile = { workspace = true } toml = { workspace = true } wiremock = { workspace = true } diff --git a/codex-rs/app-server/tests/suite/login.rs b/codex-rs/app-server/tests/suite/login.rs index 220769b7..d4d6374b 100644 --- a/codex-rs/app-server/tests/suite/login.rs +++ b/codex-rs/app-server/tests/suite/login.rs @@ -13,6 +13,7 @@ use codex_app_server_protocol::LoginChatGptResponse; use codex_app_server_protocol::LogoutChatGptResponse; use codex_app_server_protocol::RequestId; use codex_login::login_with_api_key; +use serial_test::serial; use tempfile::TempDir; use tokio::time::timeout; @@ -94,6 +95,8 @@ async fn logout_chatgpt_removes_auth() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] +// Serialize tests that launch the login server since it binds to a fixed port. +#[serial(login_port)] async fn login_and_cancel_chatgpt() { let codex_home = TempDir::new().unwrap_or_else(|e| panic!("create tempdir: {e}")); create_config_toml(codex_home.path()).unwrap_or_else(|err| panic!("write config.toml: {err}")); @@ -208,6 +211,8 @@ async fn login_chatgpt_rejected_when_forced_api() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] +// Serialize tests that launch the login server since it binds to a fixed port. +#[serial(login_port)] async fn login_chatgpt_includes_forced_workspace_query_param() { let codex_home = TempDir::new().unwrap_or_else(|e| panic!("create tempdir: {e}")); create_config_toml_forced_workspace(codex_home.path(), "ws-forced")