Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

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}");
}