server/lib/src/topology/tests.rs
//! The estate board's words (lane E3). The board is data (Holger v2.0 H2): its drawing
//! and the drawing's golden files are holger-ui's (`src/board.rs`).
use super::*;
const NOW: i64 = 1_790_000_000_000;
fn paired(name: &str, role: &str, overlay: [u8; 4], utility: Option<[u8; 4]>) -> PairedBox {
PairedBox {
name: name.into(),
role: role.into(),
overlay: Some(overlay.into()),
utility: utility.map(Ipv4Addr::from),
}
}
fn estate() -> Pairing {
Pairing {
estate: "test3".into(),
me: "main".into(),
boxes: vec![
paired("front", ROLE_FRONT, [10, 77, 0, 1], None),
paired("main", ROLE_PRIMARY, [10, 77, 0, 2], Some([10, 13, 8, 121])),
paired("twin", ROLE_TWIN, [10, 77, 0, 3], Some([10, 13, 8, 122])),
],
not_after_unix: 0,
}
}
fn twin_row(state: &str, lag: u64, seen_ago_ms: u64) -> gpb::TwinRow {
gpb::TwinRow {
principal: "holger-twin".into(),
address: "10.77.0.3:50051".into(),
state: state.into(),
last_seen_unix_ms: NOW - seen_ago_ms as i64,
lag_entries: lag,
disk_total_bytes: 40 << 30,
disk_used_bytes: 9 << 30,
applied_seq: 1000 - lag,
head_seq: 1000,
seen_ago_ms,
..Default::default()
}
}
fn downstream(state: &str, lag: u64) -> gpb::DownstreamRow {
gpb::DownstreamRow {
name: "lab-holger".into(),
state: state.into(),
lag_entries: lag,
last_seen_unix_ms: NOW - 20_000,
seen_ago_ms: 20_000,
..Default::default()
}
}
/// The main's view of a whole estate: the twin follows level, a downstream keeps up.
fn healthy_main() -> Facts {
Facts {
now_ms: NOW,
host: "holger-main".into(),
is_twin: false,
own_disk: Some((40 << 30, 12 << 30)),
own_overlay: Some([10, 77, 0, 2].into()),
cert_not_after_unix: NOW / 1000 + 170 * 86_400,
twins: vec![twin_row("ok", 0, 30_000)],
downstreams: vec![downstream("ok", 0)],
pairing: Some(estate()),
..Default::default()
}
}
fn row<'a>(r: &'a pb::TopologyReply, name: &str) -> &'a pb::TopologyBox {
r.boxes
.iter()
.find(|b| b.name == name)
.unwrap_or_else(|| panic!("no box `{name}`: {:#?}", r.boxes))
}
#[test]
fn a_healthy_estate_is_three_lit_boxes_and_a_downstream_drawn_as_committed() {
let r = board(&healthy_main());
let names: Vec<&str> = r.boxes.iter().map(|b| b.name.as_str()).collect();
assert_eq!(
names,
vec!["main", "front", "twin", "lab-holger"],
"this box first, then front, primary, twins, downstreams"
);
assert_eq!(r.estate, "test3");
assert_eq!(r.silent_after_ms, SILENT_AFTER_MS);
let main = row(&r, "main");
assert!(
main.this_box && main.state == STATE_UP && !main.held,
"{main:?}"
);
assert_eq!(
(main.overlay_address.as_str(), main.utility_address.as_str()),
("10.77.0.2", "10.13.8.121")
);
assert!(main.disk_measured && main.disk_total_bytes == 40 << 30);
let twin = row(&r, "twin");
assert_eq!(
(
twin.state.as_str(),
twin.headline.as_str(),
twin.twin_state.as_str(),
twin.lag_entries
),
(STATE_UP, "following", "ok", 0)
);
assert_eq!(
twin.overlay_address, "10.77.0.3",
"the WireGuard overlay address rides the row"
);
assert!(
twin.sources.contains(&SOURCE_PAIRING.to_string())
&& twin.sources.contains(&SOURCE_REPORT.to_string()),
"{:?}",
twin.sources
);
let front = row(&r, "front");
assert_eq!(
(front.state.as_str(), front.headline.as_str()),
(STATE_UNKNOWN, "not asked"),
"nothing here asks the front: unknown, never silent"
);
assert_eq!(row(&r, "lab-holger").role, ROLE_DOWNSTREAM);
let links: Vec<(&str, &str, &str, &str)> = r
.links
.iter()
.map(|l| {
(
l.from.as_str(),
l.to.as_str(),
l.kind.as_str(),
l.state.as_str(),
)
})
.collect();
assert_eq!(
links,
vec![
("front", "main", LINK_SERVES, STATE_UP),
("main", "twin", LINK_FOLLOWS, STATE_UP),
("main", "lab-holger", LINK_PULLS, STATE_UP)
]
);
for (name, state) in [
("main", "up"),
("twin", "up"),
("front", "unknown"),
("lab-holger", "up"),
] {
assert_eq!(row(&r, name).state, state, "{name} not {state}");
}
}
/// ★ **The board is data** (Holger v2.0 H2 #1): the server decides every word and
/// draws nothing. holger-ui draws the rows; no server build links a renderer.
#[test]
fn the_server_serves_the_board_and_draws_nothing() {
let r = board(&whole_estate());
assert!(
r.svg.is_empty(),
"the server drew the board: {}",
&r.svg[..r.svg.len().min(200)]
);
}
#[test]
fn a_lagging_twin_is_drawn_lagging() {
let mut f = healthy_main();
f.twins = vec![twin_row("behind", 120, 30_000)];
let r = board(&f);
let twin = row(&r, "twin");
assert_eq!(
(
twin.state.as_str(),
twin.headline.as_str(),
twin.twin_state.as_str(),
twin.lag_entries
),
(STATE_BEHIND, "behind 120 entries", "behind", 120)
);
assert_eq!(
r.links
.iter()
.find(|l| l.to == "twin")
.map(|l| l.state.as_str()),
Some(STATE_BEHIND),
"the link into the twin carries its state"
);
// A twin whose position stopped while the head moved is lagging too, and says so.
f.twins = vec![twin_row("stalled", 40, 30_000)];
let r = board(&f);
assert_eq!(
(
row(&r, "twin").state.as_str(),
row(&r, "twin").headline.as_str()
),
(STATE_BEHIND, "stalled, behind 40 entries")
);
}
#[test]
fn a_silent_twin_and_one_never_heard_are_dark_and_say_which() {
let mut f = healthy_main();
f.twins = vec![twin_row("silent", 3, 240_000)];
let r = board(&f);
assert_eq!(
(
row(&r, "twin").state.as_str(),
row(&r, "twin").headline.as_str()
),
(STATE_SILENT, "silent for 4 min")
);
f.twins.clear();
let r = board(&f);
assert_eq!(
(
row(&r, "twin").state.as_str(),
row(&r, "twin").headline.as_str()
),
(STATE_SILENT, "never heard"),
"a paired twin that never reported is still drawn"
);
}
#[test]
fn a_dead_main_is_drawn_held() {
// The main's own view: back up after its death, held for its recharge (M3's boot hold).
let mut f = healthy_main();
f.held_from = Some("twin".into());
let r = board(&f);
let main = row(&r, "main");
assert!(main.held && main.state == STATE_SILENT, "{main:?}");
assert_eq!(main.headline, "held for its recharge from twin");
assert_eq!(
r.links
.iter()
.find(|l| l.kind == LINK_SERVES)
.map(|l| l.state.as_str()),
Some(STATE_SILENT),
"the front's link into a held main is dark"
);
// A fenced primary is held too.
let mut f = healthy_main();
f.fenced = Some(7);
let main = board(&f).boxes.remove(0);
assert!(
main.held && main.headline == "held: fenced at epoch 7",
"{main:?}"
);
// The twin's view: its primary stopped answering. Nothing is promoted; the main is held.
let twin_view = Facts {
now_ms: NOW,
host: "holger-twin".into(),
is_twin: true,
primary_at: "10.77.0.2:50051".into(),
look: Some(Judged {
state: "silent",
lag: 5,
applied: 995,
seen_ago_ms: 240_000,
silent: true,
stalled: false,
}),
own_overlay: Some([10, 77, 0, 3].into()),
pairing: Some(Pairing {
me: "twin".into(),
..estate()
}),
..Default::default()
};
let r = board(&twin_view);
assert_eq!(r.boxes[0].name, "twin");
assert_eq!(
(r.boxes[0].state.as_str(), r.boxes[0].headline.as_str()),
(STATE_UP, "keeping the estate")
);
let main = row(&r, "main");
assert!(
main.held && main.state == STATE_SILENT && main.headline == "held: silent for 4 min",
"{main:?}"
);
}
#[test]
fn a_twin_with_a_live_primary_reports_its_own_lag() {
let f = Facts {
now_ms: NOW,
is_twin: true,
primary_at: "10.77.0.2:50051".into(),
look: Some(Judged {
state: "behind",
lag: 12,
applied: 988,
seen_ago_ms: 5_000,
silent: false,
stalled: false,
}),
pairing: Some(Pairing {
me: "twin".into(),
..estate()
}),
..Default::default()
};
let r = board(&f);
let me = &r.boxes[0];
assert_eq!(
(
me.state.as_str(),
me.headline.as_str(),
me.twin_state.as_str(),
me.lag_entries
),
(STATE_BEHIND, "behind 12 entries", "behind", 12)
);
assert_eq!(
(
row(&r, "main").state.as_str(),
row(&r, "main").headline.as_str()
),
(STATE_UP, "answering")
);
}
#[test]
fn an_unpaired_holger_is_one_box() {
let r = board(&Facts {
now_ms: NOW,
host: "solo".into(),
..Default::default()
});
assert_eq!(r.boxes.len(), 1);
assert_eq!(
(r.boxes[0].name.as_str(), r.boxes[0].state.as_str()),
("solo", STATE_UP)
);
assert!(r.links.is_empty() && r.estate.is_empty());
}
#[test]
fn the_coarse_words_change_only_when_the_state_does() {
assert_eq!(ago(59_999), "under a minute");
assert_eq!(ago(60_000), "1 min");
assert_eq!(ago(7_199_000), "119 min");
assert_eq!(ago(7_200_000), "2 h");
}
fn upstream(
name: &str,
kind: &str,
f: impl FnOnce(&mut crate::upstreams::UpstreamFact),
) -> crate::upstreams::UpstreamFact {
let mut u = crate::upstreams::UpstreamFact {
name: name.into(),
kind: kind.into(),
speaks: if kind == crate::upstreams::KIND_MIRROR {
"Holger".into()
} else {
"rust-remote".into()
},
address: format!("https://{name}.example"),
feeds: vec!["crates".into()],
registered_ms: NOW - 3_600_000,
..Default::default()
};
f(&mut u);
u
}
/// The main of the MVP estate as the owner asked for it (lane A13): its upstreams
/// above it with their state, two downstreams below with how far behind each is
/// and how many packages each fetched, and every consumer counted.
fn whole_estate() -> Facts {
let mut f = healthy_main();
f.upstreams = vec![
upstream("crates-io", crate::upstreams::KIND_PROXY, |u| {
(u.answered, u.fetched, u.last_ok_ms) = (40, 31, NOW - 20_000);
}),
upstream("pypi", crate::upstreams::KIND_PROXY, |u| {
(
u.answered,
u.failed,
u.last_ok_ms,
u.last_err_ms,
u.last_error,
) = (
3,
2,
NOW - 900_000,
NOW - 240_000,
"connection refused".into(),
);
u.speaks = "nexus-remote".into();
u.feeds = vec!["pip".into()];
}),
upstream("npmjs", crate::upstreams::KIND_PROXY, |u| {
u.feeds = vec!["npm".into()]
}),
upstream("cloud", crate::upstreams::KIND_MIRROR, |u| {
(
u.answered,
u.fetched,
u.last_ok_ms,
u.every_secs,
u.paired_as,
u.link,
) = (
12,
120,
NOW - 30_000,
60,
"cloud-holger".into(),
"paired".into(),
);
u.feeds = vec!["B".into()];
}),
];
f.downstreams = vec![
gpb::DownstreamRow {
fetched_total: 1_204,
fetched_today: 17,
..downstream("ok", 0)
},
gpb::DownstreamRow {
name: "plant-holger".into(),
fetched_total: 88,
fetched_today: 0,
..downstream("behind", 5)
},
];
f.consumers = Some(ConsumerCount {
counted: true,
principals: 3,
peers: 2,
anonymous_today: 14,
window_days: 30,
});
f
}
/// ★ **The board shows where the bytes come from, how far behind each
/// downstream is and how much it fetched, and every consumer** (lane A13).
#[test]
fn the_board_draws_upstreams_downstream_fetches_and_every_consumer() {
let r = board(&whole_estate());
let names: Vec<&str> = r.boxes.iter().map(|b| b.name.as_str()).collect();
assert_eq!(
names,
vec![
"main",
"front",
"twin",
"cloud",
"crates-io",
"npmjs",
"pypi",
"lab-holger",
"plant-holger"
],
"upstreams after the twins, before the downstreams"
);
let words = |n: &str| {
let b = row(&r, n);
(
b.role.as_str(),
b.state.as_str(),
b.headline.as_str(),
b.upstream_kind.as_str(),
b.fetched_total,
)
};
assert_eq!(
words("crates-io"),
(ROLE_UPSTREAM, STATE_UP, "answering", "proxy", 31)
);
assert_eq!(
words("pypi"),
(ROLE_UPSTREAM, STATE_SILENT, "failing for 4 min", "proxy", 0)
);
assert!(
row(&r, "pypi").why.contains("connection refused")
&& row(&r, "pypi").why.contains("15 min ago"),
"{}",
row(&r, "pypi").why
);
assert_eq!(
words("npmjs"),
(
ROLE_UPSTREAM,
STATE_UNKNOWN,
"not asked since boot",
"proxy",
0
),
"declared and never asked is unknown, never silent"
);
assert_eq!(
words("cloud"),
(ROLE_UPSTREAM, STATE_UP, "syncing", "mirror", 120)
);
assert_eq!(
row(&r, "cloud").sources,
vec![SOURCE_CONFIG, SOURCE_MIRROR, SOURCE_PAIRING]
);
assert_eq!(
row(&r, "crates-io").sources,
vec![SOURCE_CONFIG, SOURCE_PROXY]
);
assert_eq!(row(&r, "crates-io").address, "https://crates-io.example");
assert_eq!(row(&r, "pypi").feeds, vec!["pip"]);
let lab = row(&r, "lab-holger");
assert_eq!(
(
lab.state.as_str(),
lab.lag_entries,
lab.fetched_total,
lab.fetched_today
),
(STATE_UP, 0, 1_204, 17)
);
let plant = row(&r, "plant-holger");
assert_eq!(
(
plant.state.as_str(),
plant.headline.as_str(),
plant.lag_entries,
plant.fetched_total
),
(STATE_BEHIND, "behind 5 entries", 5, 88)
);
let c = r
.consumers
.as_ref()
.expect("the consumers are on the reply");
assert_eq!(
(
c.counted,
c.principals,
c.peers,
c.anonymous_today,
c.window_days
),
(true, 3, 2, 14, 30)
);
let feeds: Vec<(&str, &str, &str)> = r
.links
.iter()
.filter(|l| l.kind == LINK_FEEDS)
.map(|l| (l.from.as_str(), l.to.as_str(), l.state.as_str()))
.collect();
assert_eq!(
feeds,
vec![
("cloud", "main", STATE_UP),
("crates-io", "main", STATE_UP),
("npmjs", "main", STATE_UNKNOWN),
("pypi", "main", STATE_SILENT)
],
"each upstream feeds the main, with its own state"
);
// The same board as JSON (`GET /-/estate.json`): the rows in order, with their words.
let v = json(&r);
let names_json: Vec<&str> = v["boxes"]
.as_array()
.unwrap()
.iter()
.filter_map(|b| b["name"].as_str())
.collect();
assert_eq!(
names_json, names,
"the JSON door serves the same rows in the same order"
);
assert_eq!(v["boxes"][6]["headline"], "failing for 4 min");
assert_eq!(v["boxes"][6]["state"], STATE_SILENT);
assert_eq!(v["links"].as_array().unwrap().len(), r.links.len());
assert_eq!(v["consumers"]["anonymous_today"], 14);
assert_eq!(v["summary"], r.summary.as_str());
assert!(
r.summary
.starts_with("3 boxes: front, main, twin · 4 upstreams"),
"{}",
r.summary
);
}
/// ★ A build with no book says so, and never shows a 0 it did not count.
#[test]
fn a_build_without_a_book_says_its_consumers_are_not_counted() {
let r = board(&healthy_main());
assert!(r.consumers.is_none());
assert!(
r.summary.contains("consumers not counted in this build")
&& !r.summary.contains("consumers: 0"),
"{}",
r.summary
);
assert!(json(&r)["consumers"].is_null());
}
/// ★ A mirror's words: a key mismatch, a quiet one, one that keeps failing.
#[test]
fn a_mirrored_holger_says_key_mismatch_silent_or_failing() {
let m = |f: fn(&mut crate::upstreams::UpstreamFact)| {
upstream_words(
&upstream("cloud", crate::upstreams::KIND_MIRROR, |u| {
(u.every_secs, u.last_ok_ms, u.paired_as) =
(60, NOW - 30_000, "cloud-holger".into());
f(u)
}),
NOW,
)
};
assert_eq!(m(|u| u.link = "key-mismatch".into()).0, STATE_SILENT);
assert_eq!(m(|u| u.link = "key-mismatch".into()).1, "key mismatch");
assert_eq!(
(
m(|u| u.last_ok_ms = NOW - 600_000).0,
m(|u| u.last_ok_ms = NOW - 600_000).1
),
(STATE_SILENT, "silent for 10 min".to_string())
);
assert_eq!(
(
m(|u| u.consecutive_failures = 2).0,
m(|u| u.consecutive_failures = 2).1
),
(STATE_BEHIND, "2 failed cycles".to_string())
);
assert_eq!(m(|u| u.last_ok_ms = 0).0, STATE_UNKNOWN);
assert_eq!(
(
m(|u| (u.last_ok_ms, u.failed) = (0, 3)).0,
m(|u| (u.last_ok_ms, u.failed) = (0, 3)).1
),
(STATE_SILENT, "never synced".to_string())
);
}
// ── the RON's own graph (HBOARD-1, owner 2026-10-23: sources, downstreams, counts, lag) ──
/// A declaration's text, read the way `holger-server start --config` reads it.
fn holger_of(ron: &str) -> crate::Holger {
let mut f = tempfile::NamedTempFile::new().unwrap();
std::io::Write::write_all(&mut f, ron.as_bytes()).unwrap();
match crate::read_ron_config(f.path()) {
Ok(h) => h,
Err(e) => panic!("the fixture declaration must parse: {e:#}"),
}
}
/// Two upstream sources and an upload door, the way tier 1's `sources:` spells them.
const RON_SOURCES: &str = r#"(
repositories: [
(ron_name: "cargo", ron_repo_type: "rust", ron_upstreams: [], ron_in: None, ron_out: None),
(ron_name: "incoming", ron_repo_type: "raw", ron_upstreams: [], ron_in: None, ron_out: None),
],
exposed_endpoints: [],
storage_endpoints: [],
sources: [
(name: "crates-io", kind: crates, serves: ["cargo"]),
(name: "cloud", kind: holger, url: "http://10.77.0.9:50051", repositories: [(ron_from: "cargo", ron_to: "cargo")]),
(name: "team", kind: upload),
],
)"#;
/// ★ **The board is the RON's graph**: every source the declaration names is a row, with
/// its address and the repositories it feeds, before anything has walked to it; what a
/// walk learnt (the fetched count) lands on the declared row.
#[test]
fn every_declared_source_is_on_the_board_with_its_count() {
let h = holger_of(RON_SOURCES);
let d = declared(&h);
let names: Vec<&str> = d.upstreams.iter().map(|u| u.name.as_str()).collect();
assert_eq!(
names,
vec!["cloud", "crates-io", "team"],
"each declared source, by name"
);
let fetched = crate::upstreams::UpstreamFact {
name: "crates-io".into(),
kind: crate::upstreams::KIND_PROXY.into(),
feeds: vec!["cargo".into()],
fetched: 7,
answered: 9,
last_ok_ms: NOW - 60_000,
..Default::default()
};
let r = board(&Facts {
now_ms: NOW,
host: "main".into(),
declared: d,
upstreams: vec![fetched],
..Default::default()
});
let row = |n: &str| {
r.boxes.iter().find(|b| b.name == n).unwrap_or_else(|| {
panic!(
"{n} is not on the board: {:?}",
r.boxes.iter().map(|b| &b.name).collect::<Vec<_>>()
)
})
};
for n in ["cloud", "crates-io", "team"] {
assert_eq!(row(n).role, ROLE_UPSTREAM, "{n} is an upstream row");
}
assert_eq!(
r.boxes.iter().filter(|b| b.name == "crates-io").count(),
1,
"the declared row and its evidence are ONE row"
);
assert_eq!(
row("crates-io").fetched_total,
7,
"the walk's count lands on the declared row"
);
assert_eq!(row("crates-io").feeds, vec!["cargo".to_string()]);
assert_eq!(row("cloud").upstream_kind, crate::upstreams::KIND_MIRROR);
assert_eq!(row("cloud").address, "http://10.77.0.9:50051");
assert_eq!(
row("cloud").state,
STATE_UNKNOWN,
"declared, no cycle yet: never a made-up 'up'"
);
assert_eq!(row("team").upstream_kind, crate::upstreams::KIND_UPLOAD);
assert_eq!(row("team").feeds, vec!["incoming".to_string()]);
assert!(
r.summary
.contains("2 upstreams: cloud, crates-io, and uploads"),
"{}",
r.summary
);
let feeds = r.links.iter().filter(|l| l.kind == LINK_FEEDS).count();
assert_eq!(feeds, 3, "each source feeds the main");
}
/// ★ A laid estate's own declaration (holger-recipe's medium: the intake chain, no
/// `sources:`) still says where its packages come in: the uploads into `incoming`.
#[test]
fn an_estate_with_no_sources_shows_its_upload_door() {
let h = holger_of(
r#"(
repositories: [(ron_name: "incoming", ron_repo_type: "raw", ron_upstreams: [], ron_in: None, ron_out: None)],
exposed_endpoints: [],
storage_endpoints: [],
)"#,
);
let d = declared(&h);
assert_eq!(d.upstreams.len(), 1);
assert_eq!(
(d.upstreams[0].name.as_str(), d.upstreams[0].kind.as_str()),
("uploads", crate::upstreams::KIND_UPLOAD)
);
let r = board(&Facts {
now_ms: NOW,
host: "main".into(),
declared: d,
..Default::default()
});
assert!(r
.boxes
.iter()
.any(|b| b.name == "uploads" && b.role == ROLE_UPSTREAM && b.state == STATE_UP));
}
/// ★ **The downstream connector the RON declares** (`sync.downstreams`) is a downstream row,
/// with the lag its sync board measures, in the board's own words.
#[cfg(feature = "sync")]
#[test]
fn a_declared_sync_downstream_is_on_the_board_with_its_lag() {
let h = holger_of(&RON_SOURCES.replace(
" sources: [",
&format!(" sync: Some((name: \"main\", downstreams: [(name: \"lab-holger\", key: \"{}\")])),\n sources: [", "ab".repeat(32)),
));
let d = declared(&h);
assert_eq!(d.downstreams, vec!["lab-holger".to_string()]);
let lag = SyncDownstream {
name: "lab-holger".into(),
via: "wireguard".into(),
state: "behind".into(),
headline: "2 generations behind".into(),
lag_generations: 2,
lag_secs: 600,
last_generation_applied: 3,
..Default::default()
};
let consumers = ConsumerCount {
counted: true,
principals: 3,
peers: 1,
anonymous_today: 5,
window_days: 30,
};
let r = board(&Facts {
now_ms: NOW,
host: "main".into(),
declared: d,
sync: vec![lag],
consumers: Some(consumers),
..Default::default()
});
let down = r
.boxes
.iter()
.find(|b| b.name == "lab-holger")
.expect("the declared downstream is on the board");
assert_eq!(down.role, ROLE_DOWNSTREAM);
assert_eq!(down.state, STATE_BEHIND);
assert_eq!(
down.lag_entries, 2,
"its lag, as the sync board measured it"
);
assert_eq!(down.headline, "2 generations behind");
assert!(r
.links
.iter()
.any(|l| l.kind == LINK_PULLS && l.to == "lab-holger"));
assert!(
r.summary
.contains("1 downstream: lab-holger via wireguard 10 min behind")
&& r.summary
.contains("3 people and 1 machine used it in 30 days, 5 anonymous today"),
"{}",
r.summary
);
// ★ Lane HOL-WGDS: the board and the summary line say how it reaches this holger, and its lag.
assert_eq!(down.via, "wireguard");
// A downstream the console enrolled (not in the RON) is on the board too, from the sync board's rows.
let console = SyncDownstream {
name: "lab-1".into(),
via: "front".into(),
state: "current".into(),
headline: "at generation 3".into(),
last_generation_applied: 3,
..Default::default()
};
let r = board(&Facts {
now_ms: NOW,
host: "main".into(),
declared: declared(&h),
sync: vec![console],
..Default::default()
});
let lab1 = r
.boxes
.iter()
.find(|b| b.name == "lab-1")
.expect("a console-enrolled downstream is drawn");
assert_eq!(
(lab1.role.as_str(), lab1.via.as_str()),
(ROLE_DOWNSTREAM, "front")
);
assert!(r.summary.contains("lab-1 via front"), "{}", r.summary);
// Never heard: still on the board, in its own word.
let r = board(&Facts {
now_ms: NOW,
host: "main".into(),
declared: declared(&h),
..Default::default()
});
let down = r
.boxes
.iter()
.find(|b| b.name == "lab-holger")
.expect("declared, not measured: still drawn");
assert_eq!(down.state, STATE_UNKNOWN);
}
/// holger.rs as it is (the owner's board, 2026-10-27): front, main and twin, the uploads into
/// `incoming` and no `sources:`, no downstream, one person in the window.
fn holger_rs() -> Facts {
let mut f = healthy_main();
f.downstreams = Vec::new();
f.declared = Declared {
upstreams: vec![DeclaredUpstream {
name: UPLOADS.into(),
kind: crate::upstreams::KIND_UPLOAD.into(),
speaks: "upload".into(),
address: String::new(),
feeds: vec![UPLOAD_DOOR.into()],
}],
downstreams: Vec::new(),
fetch: Vec::new(),
};
f.consumers = Some(ConsumerCount {
counted: true,
principals: 1,
peers: 0,
anonymous_today: 0,
window_days: 30,
});
f
}
/// ★ **The line under the title is plain and true** (OX-HOLF, the owner on holger.rs's
/// board): it counts the estate's boxes and names them (an upstream or a downstream is no
/// box of this estate), says there is no upstream when the only way in is the uploads, names
/// every downstream with its last sync or its lag (or says there is none), and says who used
/// it in the window.
#[test]
fn the_line_names_the_boxes_the_upstreams_the_downstreams_and_who_used_it() {
assert_eq!(
board(&holger_rs()).summary,
"3 boxes: front, main, twin · no upstream (uploads only) · no downstream · 1 person used it in 30 days"
);
assert_eq!(
board(&whole_estate()).summary,
"3 boxes: front, main, twin · 4 upstreams: cloud, crates-io, npmjs, pypi · 2 downstreams: lab-holger via front synced under a minute ago, plant-holger via front 5 entries behind · 3 people and 2 machines used it in 30 days, 14 anonymous today"
);
}
/// ★ The downstreams the RON declares (`sync.downstreams`), each with its last sync or its
/// lag, as the sync board measures them.
#[cfg(feature = "sync")]
#[test]
fn the_line_names_each_declared_downstream_with_its_last_sync_or_its_lag() {
let mut f = holger_rs();
f.declared.downstreams = vec!["lab-1".into(), "lab-2".into(), "lab-3".into()];
let now = NOW / 1000;
f.sync = vec![
SyncDownstream {
name: "lab-1".into(),
state: "current".into(),
last_generation_applied: 9,
last_ack_at: now - 7_200,
..Default::default()
},
SyncDownstream {
name: "lab-2".into(),
state: "behind".into(),
lag_generations: 2,
lag_secs: 3 * 86_400,
last_ack_at: now - 3 * 86_400 - 60,
..Default::default()
},
];
let r = board(&f);
assert_eq!(
r.summary,
"3 boxes: front, main, twin · no upstream (uploads only) · 3 downstreams: lab-1 via front synced 2 h ago, lab-2 via front 3 days behind, lab-3 via front never synced · 1 person used it in 30 days"
);
assert_eq!(
row(&r, "lab-1").last_seen_unix_ms,
NOW - 7_200_000,
"the row carries the last sync the line names"
);
}
/// ★ Lane OX-WGDS2: a sync downstream whose acknowledgements never come by the net (a
/// `downstream` build acks by stick) is measured by its mirror's signed report: the row and
/// the line say when it last synced and how many writes it is behind, never "never".
#[cfg(feature = "sync")]
#[test]
fn a_sync_downstream_heard_by_its_mirrors_report_says_its_last_sync_and_its_lag() {
let mut f = holger_rs();
f.declared.downstreams = vec!["lab-1".into(), "lab-2".into()];
let now = NOW / 1000;
f.sync = vec![
SyncDownstream {
name: "lab-1".into(),
via: "front".into(),
state: "current".into(),
last_report_at: now - 120,
..Default::default()
},
SyncDownstream {
name: "lab-2".into(),
via: "wireguard".into(),
state: "behind".into(),
last_report_at: now - 30,
entries_behind: 4,
..Default::default()
},
];
let r = board(&f);
assert!(
r.summary.contains(
"2 downstreams: lab-1 via front synced 2 min ago, lab-2 via wireguard 4 entries behind"
),
"{}",
r.summary
);
let (l1, l2) = (row(&r, "lab-1"), row(&r, "lab-2"));
assert_eq!(
(l1.state.as_str(), l1.last_seen_unix_ms),
(STATE_UP, NOW - 120_000),
"its last report is when it was last seen"
);
assert_eq!(
(l2.state.as_str(), l2.lag_entries, l2.last_seen_unix_ms),
(STATE_BEHIND, 4, NOW - 30_000)
);
}
/// ★ **The line and the drawing never disagree**: both are the same rows. Every count and
/// every name the line says is the rows holger-ui draws.
#[test]
fn the_line_counts_the_rows_the_board_draws() {
let mut fixtures = vec![holger_rs(), whole_estate(), healthy_main()];
let mut two_twins = whole_estate();
two_twins.twins.push(gpb::TwinRow {
principal: "twin-2".into(),
address: "10.77.0.4:50051".into(),
..twin_row("ok", 0, 1_000)
});
fixtures.push(two_twins);
for f in fixtures {
let r = board(&f);
let rows = |role: &str| {
r.boxes
.iter()
.filter(|b| b.role == role)
.collect::<Vec<_>>()
};
let boxes = rows(ROLE_FRONT).len() + rows(ROLE_PRIMARY).len() + rows(ROLE_TWIN).len();
assert!(
r.summary.starts_with(&format!("{boxes} box")),
"{boxes} estate rows drawn: {}",
r.summary
);
let ups: Vec<_> = rows(ROLE_UPSTREAM)
.into_iter()
.filter(|b| b.upstream_kind != crate::upstreams::KIND_UPLOAD)
.collect();
match ups.len() {
0 => assert!(r.summary.contains(" · no upstream"), "{}", r.summary),
n => assert!(
r.summary.contains(&format!(" · {n} upstream"))
&& ups.iter().all(|u| r.summary.contains(&u.name)),
"{}",
r.summary
),
}
let downs = rows(ROLE_DOWNSTREAM);
match downs.len() {
0 => assert!(r.summary.contains(" · no downstream"), "{}", r.summary),
n => assert!(
r.summary.contains(&format!(" · {n} downstream"))
&& downs.iter().all(|d| r.summary.contains(&d.name)),
"{}",
r.summary
),
}
}
}