crates/gunnar-server/tests/dashboard_seam.rs
//! The device seam of the console dashboard — `GUNNAR_DASHBOARD=<path>` draws
//! on any writable file, no PID 1 needed — proven by reading the frames back.
//!
//! **Its own binary, on purpose.** The log tap's receiver is a process-global
//! one-shot (`gunnar_common::logtap::take_receiver`), and `dashboard::spawn`
//! takes it. Until 2026-09-04 this test lived in `dashboard_render.rs` beside
//! the frame test, which takes the same receiver by hand — so whichever ran
//! first in that process won, and the other took a degenerate arm. MEASURED
//! twice under the parallel workspace run: `spawn refused although the
//! receiver was free` (the frame test installed the tap a moment AFTER `spawn`
//! had looked for it), and `the tap's receiver, once`. The seam test's positive
//! path never ran at all under `--test-threads=1` (alphabetical order handed
//! the receiver to the frame test first). One integration-test file is one
//! process, so each test now owns the global it needs, and there is no
//! degenerate arm left to hide in: `spawn` MUST start here.
use std::path::PathBuf;
use gunnar_common::logtap::{self, LogLine, TapLayer};
use gunnar_server::dashboard::Facts;
#[test]
fn the_device_seam_draws_frames_into_a_file() {
// Installing the layer is what creates the tap and its receiver; in the
// server that happens when the tracing subscriber is built. Here nobody
// else does it, so this test does — without it `spawn` would refuse for
// "never installed", which is a different fact from the one under test.
let _tap = TapLayer::new();
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("screen");
std::fs::write(&path, b"").unwrap();
std::env::set_var("GUNNAR_DASHBOARD", &path);
let started = gunnar_server::dashboard::spawn(Facts {
ssh_bind: "127.0.0.1:2222".parse().unwrap(),
grpc_bind: Some("127.0.0.1:50051".parse().unwrap()),
data_root: PathBuf::from("/"),
build: "seam-build".into(),
engine: None,
replication: gunnar_server::replication_view::ReplicationView::new(),
tenants: gunnar_server::dashboard::TenantView::new(),
flow: gunnar_server::dashboard::FlowView::new(),
});
std::env::remove_var("GUNNAR_DASHBOARD");
assert!(
started,
"spawn must draw in its own process: the device is a writable file and the tap's \
receiver has not been taken by anyone else"
);
logtap::push(LogLine {
level: tracing::Level::INFO,
target: "gunnar::ssh",
message: "publickey accepted".into(),
fields: vec![
("event", "ssh.auth.accepted".into()),
("fingerprint", "SHA256:seam".into()),
],
span_fields: vec![("peer", "1.2.3.4:5".into()), ("principal", "seam".into())],
});
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
let mut got = String::new();
while std::time::Instant::now() < deadline {
got = String::from_utf8_lossy(&std::fs::read(&path).unwrap()).into_owned();
if got.contains("seam-build") && got.contains("login seam") {
break;
}
std::thread::sleep(std::time::Duration::from_millis(50));
}
assert!(
got.starts_with("\x1b[?25l\x1b[2J\x1b[H"),
"cursor hidden, cleared once, then homed"
);
assert!(
got.contains("seam-build") && got.contains("login seam seam\u{2026} 1.2.3.4:5"),
"{got}"
);
}