Files
codex/codex-rs/exec-server/src/websocket_pong_watchdog_tests.rs
richardopenai 042e61726d [codex] bound Rendezvous WebSocket liveness (#30643)
## Summary

- require a Pong within 60 seconds for established Noise Rendezvous
WebSockets on both the harness and executor
- bound steady-state WebSocket writes and harness event delivery so
backpressure cannot mask the deadline
- classify executor disconnects with bounded reasons and feed them into
the existing reconnect metric and structured log
- cover silent peers, responsive peers, continuous non-Pong traffic, and
local application backpressure

## Why

The existing periodic Pings did not track Pongs, so a half-open or
blackholed connection could remain stuck until the operating system's
TCP timeout. This adds the smallest explicit liveness contract without
new spans, RTT histograms, feature flags, or TCP diagnostics.

## Testing

- `just test -p codex-exec-server` on devbox `richard-6` — 300 passed, 2
skipped
- `just fix -p codex-exec-server`
- `just fmt`
- independent correctness, performance/security, and YAGNI reviews — no
findings
2026-07-01 14:15:34 -07:00

35 lines
1019 B
Rust

use std::time::Duration;
use pretty_assertions::assert_eq;
use tokio::time::Instant;
use super::WebSocketPongWatchdog;
#[test]
fn repeated_ping_does_not_extend_deadline() {
let started_at = Instant::now();
let timeout = Duration::from_secs(2);
let mut watchdog = WebSocketPongWatchdog::new(timeout);
watchdog.ping_sent(started_at);
watchdog.ping_sent(started_at + Duration::from_secs(1));
assert_eq!(
watchdog.write_deadline(started_at + Duration::from_secs(1)),
started_at + timeout
);
assert_eq!(watchdog.deadline(), Some(started_at + timeout));
}
#[test]
fn pong_starts_a_fresh_deadline() {
let started_at = Instant::now();
let timeout = Duration::from_secs(2);
let mut watchdog = WebSocketPongWatchdog::new(timeout);
watchdog.ping_sent(started_at);
watchdog.received_pong();
assert_eq!(watchdog.deadline(), None);
watchdog.ping_sent(started_at + timeout);
assert_eq!(watchdog.deadline(), Some(started_at + timeout + timeout));
}