mirror of
https://github.com/openai/codex.git
synced 2026-09-11 20:36:49 +00:00
## What changed - Add lifecycle-backed gauges for in-flight and queued app requests, pending server requests and mailbox messages, active turns, and live MCP connections. - Register each gauge on first use and decrement it when the tracked work or resource is dropped. - Document the new `server/diagnostics` gauge names and account for the diagnostics request itself in the response example and test. GitOrigin-RevId: 4bb82a3918af0b502d149b5d761ad669b2083f39
112 lines
3.6 KiB
Rust
112 lines
3.6 KiB
Rust
use std::time::Duration;
|
|
|
|
use anyhow::Result;
|
|
use app_test_support::DEFAULT_CLIENT_NAME;
|
|
use app_test_support::MockResponsesConfig;
|
|
use app_test_support::TestAppServer;
|
|
use app_test_support::create_mock_responses_server_repeating_assistant;
|
|
use codex_app_server_protocol::ClientInfo;
|
|
use codex_app_server_protocol::ClientRequest;
|
|
use codex_app_server_protocol::InitializeCapabilities;
|
|
use codex_app_server_protocol::JSONRPCMessage;
|
|
use codex_app_server_protocol::RequestId;
|
|
use codex_app_server_protocol::ServerDiagnosticsGauge;
|
|
use codex_app_server_protocol::ServerDiagnosticsParams;
|
|
use codex_app_server_protocol::ServerDiagnosticsResponse;
|
|
use codex_app_server_protocol::ThreadStartParams;
|
|
use pretty_assertions::assert_eq;
|
|
use serde_json::json;
|
|
use tempfile::TempDir;
|
|
use tokio::time::timeout;
|
|
|
|
const READ_TIMEOUT: Duration = Duration::from_secs(20);
|
|
|
|
#[tokio::test]
|
|
async fn server_diagnostics_exposes_process_and_registered_thread_gauge() -> Result<()> {
|
|
let server = create_mock_responses_server_repeating_assistant("Done").await;
|
|
let codex_home = TempDir::new()?;
|
|
MockResponsesConfig::new(&server.uri()).write(codex_home.path())?;
|
|
let mut app_server = TestAppServer::builder()
|
|
.with_codex_home(codex_home.path())
|
|
.build_initialized()
|
|
.await?;
|
|
app_server
|
|
.start_thread(ThreadStartParams::default())
|
|
.await?;
|
|
|
|
let diagnostics: ServerDiagnosticsResponse = app_server
|
|
.request(|request_id| ClientRequest::ServerDiagnostics {
|
|
request_id,
|
|
params: ServerDiagnosticsParams::default(),
|
|
})
|
|
.await?;
|
|
|
|
assert!(diagnostics.process.id > 0);
|
|
assert!(diagnostics.process.resident_memory_bytes.is_some());
|
|
#[cfg(target_os = "macos")]
|
|
assert!(diagnostics.process.physical_footprint_bytes.is_some());
|
|
#[cfg(not(target_os = "macos"))]
|
|
assert_eq!(diagnostics.process.physical_footprint_bytes, None);
|
|
for expected_gauge in [
|
|
ServerDiagnosticsGauge {
|
|
name: "app.requests.in_flight".to_string(),
|
|
value: 1,
|
|
},
|
|
ServerDiagnosticsGauge {
|
|
name: "core.threads.live".to_string(),
|
|
value: 1,
|
|
},
|
|
] {
|
|
assert_eq!(
|
|
diagnostics
|
|
.gauges
|
|
.iter()
|
|
.find(|gauge| gauge.name == expected_gauge.name),
|
|
Some(&expected_gauge)
|
|
);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn server_diagnostics_requires_experimental_capability() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let mut app_server = TestAppServer::builder()
|
|
.with_codex_home(codex_home.path())
|
|
.build()
|
|
.await?;
|
|
let initialization = app_server
|
|
.initialize_with_capabilities(
|
|
ClientInfo {
|
|
name: DEFAULT_CLIENT_NAME.to_string(),
|
|
title: None,
|
|
version: "0.1.0".to_string(),
|
|
},
|
|
Some(InitializeCapabilities {
|
|
experimental_api: false,
|
|
..Default::default()
|
|
}),
|
|
)
|
|
.await?;
|
|
assert!(matches!(initialization, JSONRPCMessage::Response(_)));
|
|
|
|
let request_id = app_server
|
|
.send_raw_request("server/diagnostics", Some(json!({})))
|
|
.await?;
|
|
let error = timeout(
|
|
READ_TIMEOUT,
|
|
app_server.read_stream_until_error_message(RequestId::Integer(request_id)),
|
|
)
|
|
.await??;
|
|
|
|
assert_eq!(error.error.code, -32600);
|
|
assert_eq!(
|
|
error.error.message,
|
|
"server/diagnostics requires experimentalApi capability"
|
|
);
|
|
assert_eq!(error.error.data, None);
|
|
|
|
Ok(())
|
|
}
|