Files
xy/crates/xy/tests/uptime.rs
T
logaritmiskandClaude Opus 5 0c8ae3b617 fix(supervisor): compute uptime at read time, not publish time
set_state computed uptime_secs from started_at.elapsed() and pushed the
result into the watch channel. do_start sets started_at immediately before
calling set_state(Running), so the published value was always ~0, and the
list/status handlers copied that frozen snapshot straight out. A server
that stayed healthy reported 0s forever, because the value was only
recomputed on the next state transition.

Status now carries started_at (an Instant, in-process only) and the
handlers derive uptime_secs when they build ServerSummary. The wire type
is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGntTHCW3sEPy1VBRopNNp
2026-08-07 13:11:01 +02:00

41 lines
1.1 KiB
Rust

mod common;
use common::*;
#[tokio::test]
async fn uptime_grows_while_a_server_stays_running() {
let xy = xy_bin();
let sleeper = sleep_server_bin();
let mut h = Harness::new();
h.write_server("alpha", sleeper.to_str().unwrap(), 19_101, "always");
h.start_daemon(&xy).await;
for _ in 0..40 {
let (_c, out, _e) = h.run_cli(&xy, &["list"]).await;
if out.contains("alpha") && out.contains("running") {
break;
}
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
}
tokio::time::sleep(std::time::Duration::from_millis(1_200)).await;
let (code, out, _e) = h.run_cli(&xy, &["list"]).await;
assert_eq!(code, 0);
let row = out
.lines()
.find(|l| l.starts_with("alpha"))
.unwrap_or_else(|| panic!("no alpha row in:\n{out}"));
let uptime = row
.split_whitespace()
.nth(4)
.unwrap_or_else(|| panic!("no uptime column in row: {row:?}"));
assert_ne!(
uptime, "0s",
"a server running for over a second must not report 0s uptime; row: {row:?}"
);
}