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
41 lines
1.1 KiB
Rust
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:?}"
|
|
);
|
|
}
|