//! Tests for [`super`]. use super::*; fn now() -> DateTime { "2026-07-21T18:24:39Z".parse().unwrap() } fn checked_at() -> String { "2026-07-21T18:24:00Z".into() } fn healthy(name: &str) -> TargetView { TargetView { name: name.into(), label: name.to_uppercase(), health_configured: true, health: Some(HealthView { status: HealthStatus::Operational, checked_at: checked_at(), version: Some("1.4.0".into()), error: None, }), uptime_24h: Some(100.0), latency_avg_ms: Some(42.0), tls: None, incident: None, whois: None, backups: Vec::new(), scan_pipeline: None, systemd: None, ca_bundle: None, synckit_fleet: None, tests: None, dns: None, cors: None, } } fn node<'a>(p: &'a Payload, id: &str) -> &'a Node { p.node(id).unwrap_or_else(|| panic!("no node {id}")) } #[test] fn a_healthy_target_is_ok_and_structurally_sound() { let p = payload(&[healthy("mnw")], now()); assert_eq!(p.source, SOURCE); assert_eq!(p.schema, ops_status::SCHEMA_VERSION); assert_eq!(p.validate(), Ok(())); assert_eq!(node(&p, "target:mnw").status, Status::Ok); assert_eq!(node(&p, "target:mnw").label, "MNW"); assert_eq!(p.worst_status(), Status::Ok); } #[test] fn uptime_and_latency_are_typed_values_not_strings() { let p = payload(&[healthy("mnw")], now()); let n = node(&p, "target:mnw"); let uptime = n.fields.iter().find(|f| f.label == "uptime 24h").unwrap(); assert_eq!( uptime.value, Value::Progress { value: 100.0, max: 100.0, unit: Some("%".into()) } ); let latency = n.fields.iter().find(|f| f.label == "latency 24h").unwrap(); assert_eq!( latency.value, Value::Quantity { value: 42.0, unit: Some("ms".into()) } ); } #[test] fn an_unreachable_target_is_failed_and_says_why() { let mut t = healthy("mnw"); t.health = Some(HealthView { status: HealthStatus::Unreachable, checked_at: checked_at(), version: None, error: Some("connection timed out".into()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Failed); assert_eq!(n.conditions[0].condition_type, "health"); assert_eq!( n.conditions[0].detail.as_deref(), Some("connection timed out") ); assert_eq!(p.worst_status(), Status::Failed); } #[test] fn a_target_never_checked_is_pending_not_healthy() { let mut t = healthy("new"); t.health = None; let p = payload(&[t], now()); let n = node(&p, "target:new"); assert_eq!(n.status, Status::Pending); assert_eq!( n.conditions[0].detail.as_deref(), Some("no health check recorded yet") ); // No health snapshot means no version and no checked-at field. assert!(n.fields.iter().all(|f| f.label != "version")); assert!(n.fields.iter().all(|f| f.label != "checked")); assert_eq!(p.validate(), Ok(())); } #[test] fn an_expiring_certificate_degrades_an_otherwise_healthy_target() { // The Sando contrast: unlike a promotion gate, an expiring cert is a real // problem with the target and must color it even when health is green. let mut t = healthy("mnw"); t.tls = Some(TlsView { valid: true, days_remaining: 9, checked_at: checked_at(), error: None, webpki_trusted: Some(true), platform_trusted: Some(true), platform_error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let tls = n .conditions .iter() .find(|c| c.condition_type == "tls") .unwrap(); assert_eq!(tls.status, Status::Degraded); assert!(tls.detail.as_deref().unwrap().contains("9 days")); } #[test] fn an_expired_certificate_fails_the_target() { let mut t = healthy("mnw"); t.tls = Some(TlsView { valid: true, days_remaining: -3, checked_at: checked_at(), error: None, webpki_trusted: Some(true), platform_trusted: Some(true), platform_error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Failed); let tls = n .conditions .iter() .find(|c| c.condition_type == "tls") .unwrap(); assert!( tls.detail .as_deref() .unwrap() .contains("expired 3 days ago") ); } #[test] fn a_healthy_certificate_stays_ok_but_still_reports_its_runway() { let mut t = healthy("mnw"); t.tls = Some(TlsView { valid: true, days_remaining: 60, checked_at: checked_at(), error: None, webpki_trusted: Some(true), platform_trusted: Some(true), platform_error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); let tls = n .conditions .iter() .find(|c| c.condition_type == "tls") .unwrap(); assert_eq!(tls.status, Status::Ok); assert!(tls.detail.as_deref().unwrap().contains("60 days remaining")); } #[test] fn a_host_trust_store_that_rejects_a_publicly_valid_chain_degrades_the_target() { // multithreaded takes its outbound trust anchors from the host CA // bundle on every path it has, with no in-binary fallback. A bundle // that goes stale or thin therefore breaks OAuth, link previews and S3 // at once while the certificates themselves are perfectly good, which // is why the two stores are reported separately rather than folded. let mut t = healthy("mnw"); t.tls = Some(TlsView { valid: true, days_remaining: 60, checked_at: checked_at(), error: None, webpki_trusted: Some(true), platform_trusted: Some(false), platform_error: Some("invalid peer certificate: UnknownIssuer".into()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let tls = n .conditions .iter() .find(|c| c.condition_type == "tls") .unwrap(); assert_eq!(tls.status, Status::Degraded); let detail = tls.detail.as_deref().unwrap(); assert!(detail.contains("host trust store")); assert!(detail.contains("UnknownIssuer")); } #[test] fn a_thin_ca_bundle_fails_the_target_and_a_stale_one_only_degrades_it() { // The severity split is the point: a bundle below the certificate floor // means outbound TLS is broken now, while a package one release behind // is drift. Collapsing them would either page on drift or bury an outage. let mut thin = healthy("mnw"); thin.ca_bundle = Some(CaBundleView { status: "thin".into(), issues: vec!["bundle holds 3 certificates, below the floor of 80".into()], checked_at: checked_at(), error: None, }); assert_eq!( node(&payload(&[thin], now()), "target:mnw").status, Status::Failed ); let mut stale = healthy("mnw"); stale.ca_bundle = Some(CaBundleView { status: "stale".into(), issues: vec!["ca-certificates 20260601 installed, 20261101 available".into()], checked_at: checked_at(), error: None, }); let p = payload(&[stale], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let ca = n .conditions .iter() .find(|c| c.condition_type == "ca_bundle") .unwrap(); assert!(ca.detail.as_deref().unwrap().contains("20261101 available")); } #[test] fn a_ca_bundle_probe_that_could_not_run_says_so_rather_than_reading_green() { let mut t = healthy("mnw"); t.ca_bundle = Some(CaBundleView { status: "error".into(), issues: Vec::new(), checked_at: checked_at(), error: Some("apt-cache policy failed to run: No such file or directory".into()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let ca = n .conditions .iter() .find(|c| c.condition_type == "ca_bundle") .unwrap(); assert!(ca.detail.as_deref().unwrap().contains("probe error")); } #[test] fn a_pre_migration_tls_row_reports_expiry_and_claims_nothing_about_trust() { // Rows written before the trust columns existed carry NULL, not false. // Reading those as "untrusted" would light up every target on the first // run after an upgrade, which trains the eye to ignore the condition. let mut t = healthy("mnw"); t.tls = Some(TlsView { valid: true, days_remaining: 60, checked_at: checked_at(), error: None, webpki_trusted: None, platform_trusted: None, platform_error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); let tls = n .conditions .iter() .find(|c| c.condition_type == "tls") .unwrap(); assert_eq!(tls.status, Status::Ok); assert!(tls.detail.as_deref().unwrap().contains("60 days remaining")); } #[test] fn an_open_incident_surfaces_with_its_transition_and_start() { let mut t = healthy("mnw"); t.incident = Some(IncidentView { from_status: "operational".into(), to_status: "unreachable".into(), started_at: "2026-07-21T17:00:00Z".into(), }); // Health has recovered on paper but the incident is still open: the node // must not read green while an incident stands. let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Failed); let incident = n .conditions .iter() .find(|c| c.condition_type == "incident") .unwrap(); assert_eq!(incident.status, Status::Failed); assert_eq!( incident.detail.as_deref(), Some("operational to unreachable") ); assert_eq!( incident.since, Some("2026-07-21T17:00:00Z".parse::>().unwrap()) ); } #[test] fn a_failed_whois_lookup_is_degraded_not_failed() { // Registrar WHOIS is flaky; a lookup error is not proof the domain lapsed. let mut t = healthy("mnw"); t.whois = Some(WhoisView { days_remaining: None, checked_at: checked_at(), error: Some("connection reset".into()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); } #[test] fn an_expiring_domain_degrades_the_target() { let mut t = healthy("mnw"); t.whois = Some(WhoisView { days_remaining: Some(12), checked_at: checked_at(), error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let whois = n .conditions .iter() .find(|c| c.condition_type == "whois") .unwrap(); assert!(whois.detail.as_deref().unwrap().contains("12 days")); } #[test] fn a_whois_check_with_no_signal_emits_no_condition() { let mut t = healthy("mnw"); t.whois = Some(WhoisView { days_remaining: None, checked_at: checked_at(), error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert!(n.conditions.iter().all(|c| c.condition_type != "whois")); assert_eq!(n.status, Status::Ok); } #[test] fn the_loudest_of_several_problems_wins_the_target() { let mut t = healthy("mnw"); t.health = Some(HealthView { status: HealthStatus::Degraded, checked_at: checked_at(), version: Some("1.4.0".into()), error: Some("unexpected status 503".into()), }); t.tls = Some(TlsView { valid: true, days_remaining: -1, checked_at: checked_at(), error: None, webpki_trusted: Some(true), platform_trusted: Some(true), platform_error: None, }); let p = payload(&[t], now()); // health is degraded, tls is failed: the target is failed. assert_eq!(node(&p, "target:mnw").status, Status::Failed); } #[test] fn one_targets_failure_does_not_touch_another() { let mut down = healthy("mt"); down.health = Some(HealthView { status: HealthStatus::Error, checked_at: checked_at(), version: None, error: Some("500 Internal Server Error".into()), }); let p = payload(&[healthy("mnw"), down], now()); assert_eq!(node(&p, "target:mnw").status, Status::Ok); assert_eq!(node(&p, "target:mt").status, Status::Failed); assert_eq!(p.worst_status(), Status::Failed); assert_eq!(p.validate(), Ok(())); } #[test] fn an_unknown_incident_status_stays_legible() { let mut t = healthy("mnw"); t.incident = Some(IncidentView { from_status: "operational".into(), to_status: "sideways".into(), started_at: checked_at(), }); let p = payload(&[t], now()); let incident = node(&p, "target:mnw") .conditions .iter() .find(|c| c.condition_type == "incident") .unwrap(); assert_eq!(incident.status, Status::Unknown); } #[test] fn a_malformed_timestamp_costs_only_that_timestamp() { let mut t = healthy("mnw"); t.health = Some(HealthView { status: HealthStatus::Operational, checked_at: "not a timestamp".into(), version: Some("1.4.0".into()), error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); assert_eq!(n.conditions[0].since, None); assert!(n.fields.iter().all(|f| f.label != "checked")); } #[test] fn a_stale_backup_degrades_the_target_and_names_the_database() { // The 40-day-stale backup that stayed green by every check that existed. let mut t = healthy("mnw"); t.backups = vec![BackupView { database: "makenotwork".into(), status: "stale".into(), age_hours: Some(960), checked_at: checked_at(), error: None, }]; let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let backup = n .conditions .iter() .find(|c| c.condition_type == "backup:makenotwork") .unwrap(); assert_eq!(backup.status, Status::Degraded); assert!(backup.detail.as_deref().unwrap().contains("960h")); } #[test] fn a_missing_backup_fails_the_target() { let mut t = healthy("mnw"); t.backups = vec![BackupView { database: "makenotwork".into(), status: "missing".into(), age_hours: None, checked_at: checked_at(), error: None, }]; let p = payload(&[t], now()); assert_eq!(node(&p, "target:mnw").status, Status::Failed); } #[test] fn several_databases_read_as_distinct_conditions() { let mut t = healthy("mnw"); t.backups = vec![ BackupView { database: "makenotwork".into(), status: "ok".into(), age_hours: Some(6), checked_at: checked_at(), error: None, }, BackupView { database: "multithreaded".into(), status: "ok".into(), age_hours: Some(7), checked_at: checked_at(), error: None, }, ]; let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); assert!( n.conditions .iter() .any(|c| c.condition_type == "backup:makenotwork") ); assert!( n.conditions .iter() .any(|c| c.condition_type == "backup:multithreaded") ); } #[test] fn a_degraded_scan_pipeline_carries_its_issues() { let mut t = healthy("mnw"); t.scan_pipeline = Some(ScanView { status: "degraded".into(), issues: vec!["thumbnail error rate 22%".into(), "queue stuck: 4".into()], checked_at: checked_at(), error: None, }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let scan = n .conditions .iter() .find(|c| c.condition_type == "scan_pipeline") .unwrap(); assert!( scan.detail .as_deref() .unwrap() .contains("thumbnail error rate 22%") ); assert!(scan.detail.as_deref().unwrap().contains("queue stuck: 4")); } #[test] fn an_unreachable_scan_pipeline_fails_the_target() { let mut t = healthy("mnw"); t.scan_pipeline = Some(ScanView { status: "unreachable".into(), issues: Vec::new(), checked_at: checked_at(), error: Some("502 Bad Gateway".into()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Failed); let scan = n .conditions .iter() .find(|c| c.condition_type == "scan_pipeline") .unwrap(); assert!(scan.detail.as_deref().unwrap().contains("502 Bad Gateway")); } fn fleet_view(versions: Vec<(Option<&str>, i64)>) -> SyncKitFleetView { SyncKitFleetView { devices: versions.iter().map(|(_, d)| d).sum(), window_days: 30, versions: versions .into_iter() .map(|(v, d)| (v.map(str::to_string), d)) .collect(), checked_at: checked_at(), error: None, } } #[test] fn a_fleet_readout_reports_the_distribution_without_degrading() { let mut t = healthy("mnw"); t.synckit_fleet = Some(fleet_view(vec![(Some("0.6.0"), 12), (None, 3)])); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); let fleet = n .conditions .iter() .find(|c| c.condition_type == "synckit_fleet") .unwrap(); assert_eq!(fleet.status, Status::Ok); let detail = fleet.detail.as_deref().unwrap(); assert!(detail.contains("15 devices in 30d"), "got {detail}"); assert!(detail.contains("0.6.0 x12"), "got {detail}"); assert!(detail.contains("unknown x3"), "got {detail}"); } #[test] fn an_ancient_version_in_the_field_does_not_degrade_the_target() { // The whole design call: version age is a fact, not an incident. A fleet // entirely on a year-old SDK must still read green. let mut t = healthy("mnw"); t.synckit_fleet = Some(fleet_view(vec![(Some("0.1.0"), 200)])); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); } #[test] fn an_empty_fleet_is_ok_and_says_so() { let mut t = healthy("mnw"); t.synckit_fleet = Some(fleet_view(vec![])); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); let fleet = n .conditions .iter() .find(|c| c.condition_type == "synckit_fleet") .unwrap(); assert!( fleet .detail .as_deref() .unwrap() .contains("no devices synced in 30d") ); } #[test] fn an_unavailable_fleet_readout_degrades_but_never_fails() { let mut t = healthy("mnw"); let mut fleet = fleet_view(vec![]); fleet.error = Some("HTTP 401 (alerts ingest token rejected)".into()); t.synckit_fleet = Some(fleet); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!( n.status, Status::Degraded, "a readout PoM cannot take is yellow, not red: health owns whether MNW is up" ); let fleet = n .conditions .iter() .find(|c| c.condition_type == "synckit_fleet") .unwrap(); assert!(fleet.detail.as_deref().unwrap().contains("401")); } #[test] fn a_successful_readout_becomes_target_fields() { let mut t = healthy("mnw"); t.synckit_fleet = Some(fleet_view(vec![(Some("0.6.0"), 12)])); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert!(n.fields.iter().any(|f| f.label == "synckit fleet")); assert!(n.fields.iter().any(|f| f.label == "synckit devices")); } #[test] fn an_unavailable_readout_contributes_no_fields() { // A blank column beats a field reading "0 devices" that is really "PoM // could not ask". let mut t = healthy("mnw"); let mut fleet = fleet_view(vec![]); fleet.error = Some("request: timed out".into()); t.synckit_fleet = Some(fleet); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert!(!n.fields.iter().any(|f| f.label.starts_with("synckit"))); } fn tests_view(passed: bool, stale: bool) -> TestsView { TestsView { ran: true, passed, total_passed: Some(226), total_failed: if passed { Some(0) } else { Some(3) }, started_at: Some(checked_at()), stale, stale_reason: if stale { Some("tests are 12 days old (threshold: 7d)".into()) } else { None }, } } fn condition<'a>(n: &'a Node, ty: &str) -> &'a Condition { n.conditions .iter() .find(|c| c.condition_type == ty) .unwrap_or_else(|| panic!("no {ty} condition")) } #[test] fn a_never_run_test_target_is_pending_not_healthy() { let mut t = healthy("mnw"); t.tests = Some(TestsView { ran: false, passed: false, total_passed: None, total_failed: None, started_at: None, stale: true, stale_reason: Some("no tests have been run".into()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); // Pending is quieter than degraded: no evidence is not a failure. assert_eq!(n.status, Status::Pending); assert_eq!( condition(n, "tests").detail.as_deref(), Some("no tests have been run yet") ); } #[test] fn a_failing_test_run_degrades_but_does_not_fail_the_target() { // A red suite is a regression signal; the running service is health's job. let mut t = healthy("mnw"); t.tests = Some(tests_view(false, false)); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let c = condition(n, "tests"); assert_eq!(c.status, Status::Degraded); assert!(c.detail.as_deref().unwrap().contains("3 failed")); } #[test] fn a_stale_but_passing_test_run_degrades_the_target() { let mut t = healthy("mnw"); t.tests = Some(tests_view(true, true)); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); assert!( condition(n, "tests") .detail .as_deref() .unwrap() .contains("12 days old") ); } #[test] fn a_fresh_passing_test_run_leaves_the_target_ok() { let mut t = healthy("mnw"); t.tests = Some(tests_view(true, false)); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); assert_eq!(condition(n, "tests").status, Status::Ok); } #[test] fn a_dns_mismatch_degrades_the_target_and_names_the_record() { let mut t = healthy("mnw"); t.dns = Some(DnsView { records: vec![ DnsRecordView { name: "makenot.work".into(), record_type: "A".into(), matches: true, error: None, }, DnsRecordView { name: "makenot.work".into(), record_type: "MX".into(), matches: false, error: None, }, ], checked_at: Some(checked_at()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); let c = condition(n, "dns"); assert_eq!(c.status, Status::Degraded); assert!(c.detail.as_deref().unwrap().contains("MX does not match")); } #[test] fn a_dns_lookup_error_reads_as_a_flaky_degrade_not_a_mismatch() { let mut t = healthy("mnw"); t.dns = Some(DnsView { records: vec![DnsRecordView { name: "makenot.work".into(), record_type: "TXT".into(), matches: false, error: Some("SERVFAIL".into()), }], checked_at: Some(checked_at()), }); let p = payload(&[t], now()); let c = condition(node(&p, "target:mnw"), "dns"); assert_eq!(c.status, Status::Degraded); assert!( c.detail .as_deref() .unwrap() .contains("lookup failed: SERVFAIL") ); } #[test] fn all_dns_records_matching_stays_ok_and_counts_them() { let mut t = healthy("mnw"); t.dns = Some(DnsView { records: vec![DnsRecordView { name: "makenot.work".into(), record_type: "A".into(), matches: true, error: None, }], checked_at: Some(checked_at()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Ok); // Singular, not "1 records match". assert_eq!( condition(n, "dns").detail.as_deref(), Some("1 record match") ); } #[test] fn a_cors_misconfiguration_degrades_the_target() { let mut t = healthy("mnw"); t.cors = Some(CorsView { checks: vec![CorsCheckView { url: "https://makenot.work/api".into(), origin: "https://app.makenot.work".into(), passes: false, error: None, }], checked_at: Some(checked_at()), }); let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert_eq!(n.status, Status::Degraded); assert!( condition(n, "cors") .detail .as_deref() .unwrap() .contains("does not allow https://app.makenot.work") ); } #[test] fn passing_cors_preflights_stay_ok() { let mut t = healthy("mnw"); t.cors = Some(CorsView { checks: vec![CorsCheckView { url: "https://makenot.work/api".into(), origin: "https://app.makenot.work".into(), passes: true, error: None, }], checked_at: Some(checked_at()), }); let p = payload(&[t], now()); assert_eq!(node(&p, "target:mnw").status, Status::Ok); } #[test] fn the_new_conditions_do_not_disturb_a_target_that_has_none_of_them() { // A target without test/dns/cors config emits none of the three, exactly // as before, the additive property the shared contract exists to give. let p = payload(&[healthy("mnw")], now()); let n = node(&p, "target:mnw"); assert!(n.conditions.iter().all(|c| c.condition_type != "tests")); assert!(n.conditions.iter().all(|c| c.condition_type != "dns")); assert!(n.conditions.iter().all(|c| c.condition_type != "cors")); assert_eq!(p.validate(), Ok(())); } #[test] fn a_target_that_does_not_watch_health_says_nothing_about_health() { // The test-only targets (the desktop apps, the SDK) have no HTTP endpoint // and never will. Emitting `health: pending` for them is a row that can // never go green, which held af/bb/go/sk pending forever and the whole // source with them. let mut t = healthy("af"); t.health_configured = false; t.health = None; let p = payload(&[t], now()); let n = node(&p, "target:af"); assert!( n.conditions.iter().all(|c| c.condition_type != "health"), "unconfigured health must emit no condition, got {:?}", n.conditions ); assert_eq!(p.validate(), Ok(())); } #[test] fn a_stored_snapshot_still_reports_after_the_config_is_removed() { // Config is truth for whether to watch, but evidence already collected // should not vanish: dropping the block should not silently erase the // last thing PoM knew about that target's health. let mut t = healthy("mnw"); t.health_configured = false; let p = payload(&[t], now()); let n = node(&p, "target:mnw"); assert!(n.conditions.iter().any(|c| c.condition_type == "health")); assert_eq!(p.validate(), Ok(())); } #[test] fn a_watched_target_with_no_snapshot_yet_is_still_pending() { // The case the flag must not break: health IS configured, no check has // run, so "evidence of nothing" is the honest answer. let mut t = healthy("mnw"); t.health = None; let p = payload(&[t], now()); let n = node(&p, "target:mnw"); let h = n .conditions .iter() .find(|c| c.condition_type == "health") .expect("configured health must still emit a condition"); assert_eq!(h.status, Status::Pending); assert_eq!(p.validate(), Ok(())); } #[test] fn render_is_a_pure_function_of_state_and_clock() { let a = payload(&[healthy("mnw")], now()); let b = payload(&[healthy("mnw")], now()); assert_eq!( serde_json::to_value(&a).unwrap(), serde_json::to_value(&b).unwrap() ); } #[test] fn pom_declares_no_actions() { let p = payload(&[healthy("mnw")], now()); assert!(p.actions.is_empty()); assert!(node(&p, "target:mnw").actions.is_empty()); }