diff --git a/codex-rs/core/tests/suite/plugins.rs b/codex-rs/core/tests/suite/plugins.rs index 30aedccf0..5b83d3b13 100644 --- a/codex-rs/core/tests/suite/plugins.rs +++ b/codex-rs/core/tests/suite/plugins.rs @@ -153,6 +153,45 @@ async fn build_apps_enabled_plugin_test_codex( .codex) } +async fn wait_for_sample_mcp_ready(codex: &codex_core::CodexThread) -> Result<()> { + let startup_event = wait_for_event_with_timeout( + codex, + |ev| match ev { + EventMsg::McpStartupComplete(summary) => { + summary.ready.iter().any(|server| server == "sample") + || summary + .failed + .iter() + .any(|failure| failure.server == "sample") + || summary.cancelled.iter().any(|server| server == "sample") + } + _ => false, + }, + Duration::from_secs(70), + ) + .await; + let EventMsg::McpStartupComplete(startup) = startup_event else { + unreachable!("event guard guarantees McpStartupComplete"); + }; + if let Some(failure) = startup + .failed + .iter() + .find(|failure| failure.server == "sample") + { + let error = &failure.error; + bail!("plugin MCP server failed to start: {error}"); + } + if startup.cancelled.iter().any(|server| server == "sample") { + bail!("plugin MCP server startup was cancelled"); + } + assert!( + startup.ready.iter().any(|server| server == "sample"), + "expected plugin MCP server to be ready; startup summary: {startup:?}" + ); + + Ok(()) +} + fn tool_names(body: &serde_json::Value) -> Vec { body.get("tools") .and_then(serde_json::Value::as_array) @@ -268,6 +307,7 @@ async fn explicit_plugin_mentions_inject_plugin_guidance() -> Result<()> { let codex = build_apps_enabled_plugin_test_codex(&server, codex_home, apps_server.chatgpt_base_url) .await?; + wait_for_sample_mcp_ready(&codex).await?; codex .submit(Op::UserInput { @@ -416,41 +456,7 @@ async fn plugin_mcp_tools_are_listed() -> Result<()> { let rmcp_test_server_bin = stdio_server_bin()?; write_plugin_mcp_plugin(codex_home.as_ref(), &rmcp_test_server_bin); let codex = build_plugin_test_codex(&server, codex_home).await?; - - let startup_event = wait_for_event_with_timeout( - &codex, - |ev| match ev { - EventMsg::McpStartupComplete(summary) => { - summary.ready.iter().any(|server| server == "sample") - || summary - .failed - .iter() - .any(|failure| failure.server == "sample") - || summary.cancelled.iter().any(|server| server == "sample") - } - _ => false, - }, - Duration::from_secs(70), - ) - .await; - let EventMsg::McpStartupComplete(startup) = startup_event else { - unreachable!("event guard guarantees McpStartupComplete"); - }; - if let Some(failure) = startup - .failed - .iter() - .find(|failure| failure.server == "sample") - { - let error = &failure.error; - bail!("plugin MCP server failed to start: {error}"); - } - if startup.cancelled.iter().any(|server| server == "sample") { - bail!("plugin MCP server startup was cancelled"); - } - assert!( - startup.ready.iter().any(|server| server == "sample"), - "expected plugin MCP server to be ready; startup summary: {startup:?}" - ); + wait_for_sample_mcp_ready(&codex).await?; codex.submit(Op::ListMcpTools).await?; let list_event = wait_for_event_with_timeout(