server/lib/tests/the_airgap_is_the_default.rs
//! **The airgap is the default** (Holger v2.0 H2 leftovers, B2; HCUT 2026-10-26).
//!
//! 1. A config that says no `network:` and names nothing that dials resolves to
//! `Offline`: the started box refuses every outbound dial ([`egress`]).
//! 2. A config that names an upstream (a pull-through source with a url, a `*-remote`
//! repository, a mirror) and says no `network:` is `Online`, and the boot says what
//! it dials; with `network: Offline` the same config is refused by name and the
//! refusal says how to let it dial.
//! 3. No upstream fallback: a `rust-remote` repository with no `ron_base_url` no longer
//! reaches for crates.io; it is refused by name and the refusal says how to name one.
use std::io::Write;
use holger_server_lib::egress::NetworkMode;
use holger_server_lib::{read_ron_config, Holger};
fn load(ron: &str) -> (tempfile::NamedTempFile, Holger) {
let mut f = tempfile::NamedTempFile::new().unwrap();
f.write_all(ron.as_bytes()).unwrap();
let h = read_ron_config(f.path()).expect("the config parses");
(f, h)
}
fn config(d: &str, network: &str, repos: &str, extra: &str) -> String {
format!(
r#"(
{network}
repositories: [ {repos} ],
exposed_endpoints: [ (ron_name: "door", ron_url: "127.0.0.1:0") ],
storage_endpoints: [],
audit: (dir: "{d}/audit", enabled: true),
{extra}
)"#
)
}
/// The default and the downstream builds: nothing named, nothing dialled.
#[cfg(not(feature = "estate"))]
#[test]
fn a_config_that_names_no_upstream_is_offline_by_default() {
let data = tempfile::tempdir().unwrap();
let d = data.path().display().to_string();
let (_f, h) = load(&config(
&d,
"",
r#"(ron_name: "files", ron_repo_type: "raw", ron_upstreams: [], ron_in: None, ron_out: None, ron_data_dir: Some("x"))"#,
"",
));
assert_eq!(
h.network,
NetworkMode::Auto,
"no `network:` is the default, not Online"
);
assert!(
h.network_needs().is_empty(),
"nothing here dials: {:?}",
h.network_needs()
);
assert_eq!(
h.resolved_network(),
NetworkMode::Offline,
"the default with no upstream is the airgap"
);
}
#[test]
fn a_config_that_names_an_upstream_is_online_and_says_what_it_dials() {
let data = tempfile::tempdir().unwrap();
let d = data.path().display().to_string();
let remote = r#"(ron_name: "crates-io", ron_repo_type: "rust-remote", ron_base_url: Some("https://index.crates.io"), ron_upstreams: [], ron_in: None, ron_out: None)"#;
let (_f, h) = load(&config(&d, "", remote, ""));
assert_eq!(h.resolved_network(), NetworkMode::Online);
let needs = h.network_needs();
assert!(
needs.iter().any(|n| n.contains("crates-io")),
"the boot names what dials: {needs:?}"
);
let (_g, mut off) = load(&config(&d, "network: Offline,", remote, ""));
let err = format!(
"{:#}",
off.instantiate_backends()
.expect_err("an explicit Offline with an upstream is refused")
);
assert!(
err.contains("[holger-offline-2]") && err.contains("crates-io"),
"{err}"
);
assert!(
err.contains("network: Online"),
"the refusal says how to let it dial: {err}"
);
}
#[test]
fn a_rust_remote_with_no_url_falls_back_to_no_upstream_and_says_how_to_name_one() {
let data = tempfile::tempdir().unwrap();
let d = data.path().display().to_string();
let (_f, mut h) = load(&config(
&d,
"network: Online,",
r#"(ron_name: "crates-io", ron_repo_type: "rust-remote", ron_upstreams: [], ron_in: None, ron_out: None)"#,
"",
));
assert!(
h.instantiate_backends().is_err(),
"a box whose one repository is refused serves nothing"
);
let err = format!(
"{:#}",
h.repositories[0]
.backend_from_config()
.expect_err("a remote with no url is refused")
);
assert!(
err.contains("[holger-offline-3]") && err.contains("crates-io"),
"{err}"
);
assert!(
err.contains("ron_base_url: Some(\"https://index.crates.io\")"),
"the refusal says how to name one: {err}"
);
}
/// ★ **An estate build is online by design, and says why** (HCON-6). `estate` (which
/// `metered`, the sold product, implies) is the box of an estate: it dials its front, its twin
/// and the ONE box. The same config that is the airgap on the default build is `Online`
/// here, the boot names the estate as the reason, and an explicit `network: Offline` is
/// refused by name rather than started half-blind.
#[cfg(feature = "estate")]
#[test]
fn an_estate_build_is_online_by_design_and_says_why() {
let data = tempfile::tempdir().unwrap();
let d = data.path().display().to_string();
let files = r#"(ron_name: "files", ron_repo_type: "raw", ron_upstreams: [], ron_in: None, ron_out: None, ron_data_dir: Some("x"))"#;
let (_f, h) = load(&config(&d, "", files, ""));
assert_eq!(h.network, NetworkMode::Auto);
let needs = h.network_needs();
assert_eq!(
needs,
vec![
"this is an estate build: the box dials its front, its twin and the ONE box"
.to_string()
],
"the estate is the one reason"
);
assert_eq!(
h.resolved_network(),
NetworkMode::Online,
"an estate box is online by design"
);
let (_g, mut off) = load(&config(&d, "network: Offline,", files, ""));
let err = format!(
"{:#}",
off.instantiate_backends()
.expect_err("an estate box told to be Offline is refused")
);
assert!(
err.contains("[holger-offline-2]") && err.contains("estate build"),
"the refusal names the estate: {err}"
);
}