server/lib/tests/a_downstream_dials_only_its_upstream.rs
//! **A downstream dials only its upstream** (Holger v2.0 H3, `holger-downstream-1/2`).
//!
//! A config that asks a downstream for more than ONE upstream Holger is refused at boot,
//! every reason named; one that names its upstream pins the process's egress to that
//! origin, so every other dial (an internet registry, another port, another scheme) is
//! refused before a socket exists. Its own process: the pin is process-wide and one-way.
//!
//! That is the FETCHING downstream (`fetch` built, `boundary: Fetch`; lane HOL-CDS). The
//! default downstream is one-way: the same `mirror:` block refuses its start by line
//! (`holger-boundary-1`) and it pins nothing at all (the second test, a build without `fetch`).
use holger_server_lib::egress;
fn holger(ron: &str) -> holger_server_lib::Holger {
let dir = tempfile::tempdir().unwrap();
let cfg = dir.path().join("h.ron");
std::fs::write(&cfg, ron.replace("@D", &dir.path().display().to_string())).unwrap();
let h = holger_server_lib::read_ron_config(&cfg).unwrap();
std::mem::forget(dir);
h
}
const BASE: &str = r#"(
repositories: [
(ron_name: "inbox", ron_repo_type: "raw", ron_upstreams: [], ron_in: None, ron_out: None, ron_data_dir: Some("@D/inbox")),
@EXTRA
],
exposed_endpoints: [ (ron_name: "door", ron_url: "127.0.0.1:0", ron_http_url: None) ],
storage_endpoints: [ (ron_name: "storage", ron_storage_type: "znippy", ron_path: "@D") ],
@BOUNDARY
@MIRROR
)"#;
fn config(extra: &str, mirror: &str) -> String {
let boundary = if cfg!(feature = "fetch") {
"boundary: Fetch,"
} else {
""
};
BASE.replace("@EXTRA", extra)
.replace("@MIRROR", mirror)
.replace("@BOUNDARY", boundary)
}
fn mirror(sources: &[(&str, &str, &str)]) -> String {
let s: Vec<String> = sources
.iter()
.map(|(n, k, e)| {
format!(
r#"(ron_name: "{n}", ron_kind: {k}, ron_endpoint: "{e}", ron_credential: Anonymous,
ron_repositories: [ (ron_from: "bundles", ron_to: "inbox") ])"#
)
})
.collect();
format!(r#"mirror: Some((ron_sources: [ {} ])),"#, s.join(", "))
}
#[cfg(feature = "fetch")]
#[test]
fn a_downstream_dials_only_its_upstream_and_refuses_a_config_that_asks_for_more() {
// More than one upstream, and a registry repository: refused, both named.
let refused = holger(&config(
r#"(ron_name: "crates", ron_repo_type: "rust-remote", ron_upstreams: [], ron_in: None, ron_out: None, ron_data_dir: Some("@D/c")),"#,
&mirror(&[("a", "Holger", "http://a.example:50051"), ("b", "Holger", "http://b.example:50051")]),
))
.enter_downstream_mode()
.unwrap_err()
.to_string();
assert!(refused.contains("[holger-downstream-1]"), "{refused}");
assert!(
refused.contains("'crates'") && refused.contains("ONE upstream"),
"every reason is named: {refused}"
);
assert_eq!(egress::pinned(), None, "a refused config pins nothing");
// One upstream Holger: the process may dial it and nothing else.
let plan = holger(&config(
"",
&mirror(&[("cloud", "Holger", "http://Up.Example:50051")]),
))
.enter_downstream_mode()
.unwrap();
assert_eq!(plan.origins(), vec!["http://up.example:50051".to_string()]);
assert_eq!(
egress::pinned(),
Some(vec!["http://up.example:50051".to_string()])
);
assert!(egress::is_offline(), "everything but the upstream is off");
egress::check("remote holger", "http://up.example:50051").expect("its one line out");
for elsewhere in [
"https://index.crates.io/config.json",
"https://pypi.org/simple/",
"http://up.example:50052",
"https://up.example:50051",
] {
let e = egress::check("pull-through", elsewhere).unwrap_err();
assert!(
e.to_string().contains("[holger-downstream-2]"),
"{elsewhere}: {e}"
);
assert_eq!(e.code().code, "holger-downstream-2");
}
// HOL-EGRESS-WG: an invite whose door is not the upstream pins no WireGuard endpoint.
assert!(!egress::pin_invite_endpoint(
"http://elsewhere.example:50051",
"198.51.100.4:51830"
));
assert!(egress::check(
"sync WireGuard tunnel",
&egress::wireguard_target("198.51.100.4:51830")
)
.is_err());
// One whose door is: its endpoint, as signed, and nothing more.
assert!(egress::pin_invite_endpoint(
"http://up.example:50051",
"198.51.100.4:51830"
));
egress::check(
"sync WireGuard tunnel",
&egress::wireguard_target("198.51.100.4:51830"),
)
.expect("the invite's endpoint");
for elsewhere in [
"198.51.100.4:51830",
"http://198.51.100.4:51830",
"wireguard://198.51.100.4:51831",
"wireguard://198.51.100.5:51830",
] {
let e = egress::check("sync WireGuard tunnel", elsewhere).unwrap_err();
assert_eq!(e.code().code, "holger-downstream-2", "{elsewhere}: {e}");
}
}
/// ★ **The one-way downstream** (no `fetch` built): a `mirror:` block refuses its start by
/// line and code, and a config without one pins the process to NOTHING: every dial refused.
#[cfg(not(feature = "fetch"))]
#[test]
fn a_one_way_downstream_refuses_a_mirror_and_dials_nothing() {
let refused = holger(&config(
"",
&mirror(&[("cloud", "Holger", "http://up.example:50051")]),
))
.enter_downstream_mode()
.unwrap_err()
.to_string();
assert!(
refused.contains("[holger-boundary-1]") && refused.contains("line 9: the `mirror:` block"),
"{refused}"
);
assert_eq!(egress::pinned(), None, "a refused config pins nothing");
let plan = holger(&config("", "")).enter_downstream_mode().unwrap();
assert!(plan.origins().is_empty(), "{:?}", plan.origins());
assert_eq!(egress::pinned(), Some(vec![]));
for anywhere in ["http://up.example:50051", "https://pypi.org/simple/"] {
let e = egress::check("remote holger", anywhere).unwrap_err();
assert_eq!(e.code().code, "holger-downstream-2", "{anywhere}: {e}");
}
// HOL-EGRESS-WG: an invite's WireGuard endpoint opens no line either: no door is pinned.
assert!(!egress::pin_invite_endpoint(
"http://up.example:50051",
"198.51.100.4:51830"
));
assert_eq!(egress::pinned(), Some(vec![]));
let e = egress::check(
"sync WireGuard tunnel",
&egress::wireguard_target("198.51.100.4:51830"),
)
.unwrap_err();
assert_eq!(e.code().code, "holger-downstream-2", "{e}");
}