use super::*;
fn tempdir() -> PathBuf {
let d = std::env::temp_dir().join(format!(
"fdl-join-config-{}-{}",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.subsec_nanos())
.unwrap_or(0),
));
fs::create_dir_all(&d).unwrap();
d
}
#[test]
fn door_defaults_to_b_and_refuses_c_by_name() {
assert_eq!(Door::parse(None).unwrap(), Door::B);
assert_eq!(Door::parse(Some("a")).unwrap(), Door::A);
assert_eq!(Door::parse(Some("nologin")).unwrap(), Door::Nologin);
let err = Door::parse(Some("c")).unwrap_err();
assert!(err.contains("second, source-only key"), "got: {err}");
let err = Door::parse(Some("z")).unwrap_err();
assert!(err.contains("unknown door"), "got: {err}");
}
#[test]
fn endpoint_parses_the_compact_spec() {
let e = Endpoint::parse(Some("flodl-join@ctrl.example.com:2222")).unwrap();
assert_eq!(e.user, "flodl-join");
assert_eq!(e.host, "ctrl.example.com");
assert_eq!(e.port, 2222);
let e = Endpoint::parse(Some("ctrl")).unwrap();
assert_eq!(e.host, "ctrl");
assert_eq!(e.port, 22);
assert!(Endpoint::parse(Some("user@:22")).is_err());
assert!(Endpoint::parse(Some("host:notaport")).is_err());
}
#[test]
fn labels_are_filename_safe() {
assert!(validate_label("b300").is_ok());
assert!(validate_label("farm_a-2").is_ok());
assert!(validate_label("").is_err());
assert!(validate_label("a/b").is_err());
assert!(validate_label("a b").is_err());
}
#[test]
fn token_surgery_preserves_every_other_byte() {
let yml = "\
# a farm, mostly comments
cluster:
controller:
join:
# the credential
token: aaaabbbbccccddddaaaabbbbccccdddd
start: manual
";
assert_eq!(
find_token_line(yml).as_deref(),
Some("aaaabbbbccccddddaaaabbbbccccdddd"),
);
let new = replace_token_line(yml, "ffff0000ffff0000ffff0000ffff0000").unwrap();
assert!(new.contains("token: ffff0000ffff0000ffff0000ffff0000"));
assert!(new.contains("# a farm, mostly comments"));
assert!(new.contains(" # the credential"));
assert!(new.contains(" start: manual"));
assert_eq!(find_token_line("# token: dead\n"), None);
}
#[test]
fn manifest_scan_reads_name_path_dep_and_features() {
let m = "\
[package]
name = \"my-train\"
version = \"0.1.0\"
[dependencies]
flodl = { path = \"../rdl/flodl\", features = [\"x\"] }
serde = \"1\"
[features]
cuda = [\"flodl/cuda\"]
rocm = [\"flodl/rocm\"]
";
assert_eq!(package_name(m).as_deref(), Some("my-train"));
assert_eq!(flodl_path_dep(m).as_deref(), Some("../rdl/flodl"));
assert!(declares_gpu_features(m));
let table_form = "\
[package]
name = \"t\"
[dependencies.flodl]
path = \"../flodl\"
";
assert_eq!(flodl_path_dep(table_form).as_deref(), Some("../flodl"));
let registry = "[package]\nname = \"t\"\n\n[dependencies]\nflodl = \"=0.7.0\"\n";
assert_eq!(flodl_path_dep(registry), None);
assert!(!declares_gpu_features(registry));
}
#[test]
fn path_dep_walks_up_to_the_dep_root() {
let tmp = tempdir();
let train = tmp.join("proj/train");
fs::create_dir_all(&train).unwrap();
fs::create_dir_all(tmp.join("proj/rdl/flodl")).unwrap();
fs::write(
train.join("Cargo.toml"),
"[package]\nname = \"train\"\n\n[dependencies]\nflodl = { path = \"../rdl/flodl\" }\n",
)
.unwrap();
let d = derive_publish(&train).unwrap().expect("a crate");
assert_eq!(d.from_root, tmp.join("proj").canonicalize().unwrap());
assert_eq!(d.cwd_rel.as_deref(), Some("train"));
assert_eq!(d.bin, "target/release/train");
assert!(!d.build.contains("FDL_GPU_FEATURE"), "no features declared");
let _ = fs::remove_dir_all(&tmp);
}
#[test]
fn registry_dep_ships_the_crate_dir_alone() {
let tmp = tempdir();
let train = tmp.join("train");
fs::create_dir_all(&train).unwrap();
fs::write(
train.join("Cargo.toml"),
"[package]\nname = \"train\"\n\n[dependencies]\nflodl = \"=0.7.0\"\n\n\
[features]\ncuda = [\"flodl/cuda\"]\nrocm = [\"flodl/rocm\"]\n",
)
.unwrap();
let d = derive_publish(&train).unwrap().expect("a crate");
assert_eq!(d.from_root, train.canonicalize().unwrap());
assert_eq!(d.cwd_rel, None);
assert!(
d.build.contains("--features \"$FDL_GPU_FEATURE\""),
"declared vendor features must ride the recipe: {}",
d.build,
);
assert!(d.bin_caveat.is_none());
assert!(derive_publish(&tmp.join("nowhere")).unwrap().is_none());
let _ = fs::remove_dir_all(&tmp);
}
#[test]
fn a_workspace_above_the_crate_earns_the_bin_caveat() {
let tmp = tempdir();
let member = tmp.join("ws/member");
fs::create_dir_all(&member).unwrap();
fs::create_dir_all(tmp.join("ws/flodl")).unwrap();
fs::write(
tmp.join("ws/Cargo.toml"),
"[workspace]\nmembers = [\"member\"]\n",
)
.unwrap();
fs::write(
member.join("Cargo.toml"),
"[package]\nname = \"member\"\n\n[dependencies]\nflodl = { path = \"../flodl\" }\n",
)
.unwrap();
let d = derive_publish(&member).unwrap().expect("a crate");
let caveat = d.bin_caveat.expect("the workspace must be flagged");
assert!(caveat.contains("WORKSPACE target/"), "got: {caveat}");
let _ = fs::remove_dir_all(&tmp);
}
#[test]
fn normalize_and_common_ancestor_do_pure_path_math() {
assert_eq!(
normalize(Path::new("/a/b/c/../../d")),
PathBuf::from("/a/d"),
);
assert_eq!(
common_ancestor(Path::new("/a/b/c"), Path::new("/a/b/d/e")),
PathBuf::from("/a/b"),
);
}
#[test]
fn freshness_flags_a_stale_lockfile() {
let tmp = tempdir();
fs::write(tmp.join("Cargo.lock"), "x").unwrap();
let empty = tempdir();
assert!(freshness_report(&empty).contains("no Cargo.lock"));
let old = std::time::SystemTime::now() - std::time::Duration::from_secs(600);
let lock = fs::File::options()
.write(true)
.open(tmp.join("Cargo.lock"))
.unwrap();
lock.set_modified(old).unwrap();
fs::write(tmp.join("main.rs"), "fn main() {}").unwrap();
let report = freshness_report(&tmp);
assert!(report.contains("predates"), "got: {report}");
let _ = fs::remove_dir_all(&tmp);
let _ = fs::remove_dir_all(&empty);
}
fn no_flags() -> JoinConfigArgs {
JoinConfigArgs {
label: None,
controller: None,
door: None,
crate_dir: None,
data_path: None,
gpu_ram_share: None,
regen: false,
install_key: false,
no_install_key: false,
authorized_keys: None,
cloud_init: false,
cloud_init_user: None,
yes: false,
json: false,
}
}
#[test]
fn cloud_init_embeds_the_artifacts_and_the_failure_taxonomy() {
let yml = "join:\n token: t\n persist: true\n";
let key = "-----BEGIN OPENSSH PRIVATE KEY-----\nAAAA\n-----END OPENSSH PRIVATE KEY-----\n";
let ci = render_cloud_init("b300", "ubuntu", Door::B, yml, key);
assert!(ci.starts_with("#cloud-config\n"));
assert!(ci.contains("SECRET ARTIFACT"));
assert!(
ci.contains(" -----BEGIN OPENSSH PRIVATE KEY-----"),
"got:\n{ci}"
);
assert!(ci.contains(" join:"), "got:\n{ci}");
assert!(ci.contains("path: /home/ubuntu/.ssh/flodl-join"));
assert!(ci.contains("permissions: \"0600\""));
assert!(ci.contains("Restart=always"));
assert!(ci.contains("RestartPreventExitStatus=2"));
assert!(ci.contains("FailureAction=poweroff"));
assert!(ci.contains("User=ubuntu"));
assert!(ci.contains("systemctl enable --now flodl-join.service"));
assert!(ci.contains("NOT the meter"), "got:\n{ci}");
}
#[test]
fn cloud_init_installs_what_the_instance_does_not_have() {
let yml = "join:\n token: t\n";
let key = "-----BEGIN OPENSSH PRIVATE KEY-----\nAAAA\n-----END OPENSSH PRIVATE KEY-----\n";
let ci = render_cloud_init("b300", "ubuntu", Door::B, yml, key);
assert!(ci.contains("command -v fdl >/dev/null ||"), "got:\n{ci}");
assert!(ci.contains("https://flodl.dev/fdl"));
let fdl_at = ci.find("command -v fdl").unwrap();
let enable_at = ci.find("systemctl enable --now").unwrap();
assert!(
fdl_at < enable_at,
"fdl must be installed before the unit starts"
);
}
#[test]
fn cloud_init_provisions_only_what_the_door_reaches_for() {
let yml = "join:\n token: t\n";
let key = "k\n";
let b = render_cloud_init("b300", "ubuntu", Door::B, yml, key);
assert!(b.contains("command -v cargo >/dev/null ||"), "got:\n{b}");
assert!(b.contains(" - build-essential\n"), "got:\n{b}");
assert!(b.contains(" - rsync\n"));
assert!(b.contains("su -l ubuntu -c"), "got:\n{b}");
assert!(
b.contains("Environment=PATH=/home/ubuntu/.cargo/bin:"),
"got:\n{b}"
);
let a = render_cloud_init("b300", "ubuntu", Door::A, yml, key);
assert!(a.contains(" - sshfs\n"), "got:\n{a}");
assert!(!a.contains("cargo"), "door `a` builds nothing");
let n = render_cloud_init("b300", "ubuntu", Door::Nologin, yml, key);
assert!(!n.contains("cargo"));
assert!(!n.contains("sshfs"));
assert!(n.contains(" - curl\n"), "every door still fetches fdl");
}
#[test]
fn a_root_instance_gets_root_s_actual_home() {
let yml = "join:\n token: t\n";
let key = "k\n";
let ci = render_cloud_init("b300", "root", Door::B, yml, key);
assert!(ci.contains("path: /root/.ssh/flodl-join"), "got:\n{ci}");
assert!(ci.contains("path: /root/training/fdl.yml"));
assert!(ci.contains("WorkingDirectory=/root/training"));
assert!(ci.contains("Environment=PATH=/root/.cargo/bin:"));
assert!(!ci.contains("/home/root"), "got:\n{ci}");
}
#[test]
fn the_worker_yml_speaks_each_doors_dialect() {
let ep = Endpoint {
user: "flodl-join".into(),
host: "ctrl".into(),
port: 2222,
};
let cli = no_flags();
let b = render_worker_yml("b300", &ep, "aa".repeat(16).as_str(), Door::B, &cli);
assert!(
b.contains("from: rsync://flodl-join@ctrl:/tree"),
"got:\n{b}"
);
assert!(b.contains(&format!("token: {}", "aa".repeat(16))));
assert!(b.contains("port: 2222"));
assert!(b.contains("identity_file: ~/.ssh/flodl-join"));
assert!(b.contains("libtorch: auto"));
assert!(b.contains("persist: true"));
let a = render_worker_yml("b300", &ep, "tok", Door::A, &cli);
assert!(
a.contains("data_source: sshfs://flodl-join@ctrl:/flodl/data"),
"got:\n{a}"
);
assert!(!a.contains("from: rsync"), "door `a` cannot pull a source");
let n = render_worker_yml("b300", &ep, "tok", Door::Nologin, &cli);
assert!(!n.contains("data_source:"));
assert!(!n.contains("from: rsync"));
let mut cli = no_flags();
cli.gpu_ram_share = Some(0.5);
let apu = render_worker_yml("b300", &ep, "tok", Door::B, &cli);
assert!(apu.contains("gpu_ram_share: 0.5"), "got:\n{apu}");
}
#[test]
fn the_authorized_line_composes_restrictions_and_the_doors_command() {
let pub_line = "ssh-ed25519 AAAAtest flodl-join-b300";
let served = PathBuf::from("/home/op/.flodl/run");
let cli = no_flags();
let b = authorized_keys_line(Door::B, &served, &cli, pub_line);
assert!(b.starts_with("restrict,port-forwarding,permitopen=\"127.0.0.1:1337\","));
assert!(
b.contains("command=\"rrsync -ro /home/op/.flodl/run\""),
"got: {b}"
);
assert!(b.ends_with(pub_line));
let a = authorized_keys_line(Door::A, &served, &cli, pub_line);
assert!(
a.contains("command=\"internal-sftp -R -d /flodl/data\""),
"got: {a}"
);
let n = authorized_keys_line(Door::Nologin, &served, &cli, pub_line);
assert!(n.contains("command=\"/usr/sbin/nologin\""), "got: {n}");
}
#[test]
fn the_scaffolded_overlay_loads_through_the_real_config_path() {
let tmp = tempdir();
let base = tmp.join("fdl.yml");
fs::write(&base, "# base\n").unwrap();
let token = fresh_token().unwrap();
fs::write(
tmp.join("fdl.b300.yml"),
render_overlay_scaffold("b300", &token, &tmp, Some("trainer")),
)
.unwrap();
let project = crate::config::load_project_with_env(&base, Some("b300")).unwrap();
let cluster = project
.cluster
.expect("the overlay carries a cluster block");
let join = cluster.controller.join.expect("a join block");
assert_eq!(join.token.as_deref(), Some(token.as_str()));
assert_eq!(join.discovery, Some(true));
assert_eq!(join.start.as_deref(), Some("manual"));
let cmd = project
.commands
.get("trainer")
.expect("the scaffold wires the named command");
assert_eq!(cmd.cluster, Some(true));
assert!(cluster.workers.is_empty(), "walk-ins fill the roster");
let _ = fs::remove_dir_all(&tmp);
}
const OUR_LINE: &str = "restrict,port-forwarding,permitopen=\"127.0.0.1:1337\",\
command=\"rrsync -ro /srv/run\" ssh-ed25519 AAAAour flodl-join-b300";
#[test]
fn key_material_skips_quote_aware_options() {
assert_eq!(key_material(OUR_LINE), Some(("ssh-ed25519", "AAAAour")),);
assert_eq!(
key_material("ssh-rsa AAAAbare user@host"),
Some(("ssh-rsa", "AAAAbare")),
);
assert_eq!(
key_material("sk-ecdsa-sha2-nistp256@openssh.com AAAAsk c"),
Some(("sk-ecdsa-sha2-nistp256@openssh.com", "AAAAsk")),
);
assert_eq!(key_material("# a comment"), None);
assert_eq!(key_material(""), None);
assert_eq!(key_material("options-only-no-key"), None);
}
#[test]
fn upsert_appends_replaces_or_leaves_identical() {
let (out, o) = upsert_authorized_line("", OUR_LINE).unwrap();
assert_eq!(o, UpsertOutcome::Appended);
assert_eq!(out, format!("{OUR_LINE}\n"));
let foreign = "ssh-ed25519 AAAAforeign someone@laptop\n# a comment\n";
let (out, o) = upsert_authorized_line(foreign, OUR_LINE).unwrap();
assert_eq!(o, UpsertOutcome::Appended);
assert!(
out.starts_with(foreign),
"foreign content must be untouched"
);
assert!(out.ends_with(&format!("{OUR_LINE}\n")));
let mixed = "ssh-ed25519 AAAAforeign a@b\nssh-ed25519 AAAAour old-comment\n# tail\n";
let (out, o) = upsert_authorized_line(mixed, OUR_LINE).unwrap();
assert_eq!(o, UpsertOutcome::Replaced);
assert!(out.contains("ssh-ed25519 AAAAforeign a@b\n"));
assert!(out.contains(&format!("{OUR_LINE}\n")));
assert!(!out.contains("old-comment"));
assert!(out.ends_with("# tail\n"));
let installed = format!("{OUR_LINE}\n");
let (out, o) = upsert_authorized_line(&installed, OUR_LINE).unwrap();
assert_eq!(o, UpsertOutcome::Identical);
assert_eq!(out, installed);
}
#[test]
fn install_needs_explicit_consent() {
let mut cli = no_flags();
cli.yes = true; let line = OUR_LINE;
match install_authorized_line(&cli, line, 1).unwrap() {
InstallAction::Skipped(why) => {
assert!(why.contains("--install-key"), "got: {why}")
}
other => panic!("--yes alone must not install, got {other:?}"),
}
let mut cli = no_flags();
cli.no_install_key = true;
assert!(matches!(
install_authorized_line(&cli, line, 1).unwrap(),
InstallAction::Skipped(_),
));
let mut cli = no_flags();
cli.install_key = true;
cli.no_install_key = true;
assert!(install_authorized_line(&cli, line, 1).is_err());
}
#[test]
fn fresh_tokens_are_32_hex_and_unique() {
let a = fresh_token().unwrap();
let b = fresh_token().unwrap();
assert_eq!(a.len(), 32);
assert!(a.chars().all(|c| c.is_ascii_hexdigit()));
assert_ne!(a, b);
}
#[test]
fn a_farms_door_and_controller_survive_a_flagless_rerun() {
for door in [Door::B, Door::A, Door::Nologin] {
let farm = tempdir();
fs::create_dir_all(&farm).unwrap();
let ctrl = Endpoint::parse(Some("op@ctrl.example:2222")).unwrap();
let yml = render_worker_yml("f", &ctrl, "tok", door, &no_flags());
fs::write(farm.join("worker.yml"), yml).unwrap();
let (got_door, got_ctrl) = recover_shape(&farm).expect("the farm reads back");
assert_eq!(got_door, door, "door for {door:?}");
let round = Endpoint::parse(Some(&got_ctrl)).unwrap();
assert_eq!(round.host, "ctrl.example");
assert_eq!(round.port, 2222);
assert_eq!(round.user, "op");
let _ = fs::remove_dir_all(&farm);
}
}
#[test]
fn a_farm_dir_without_a_worker_yml_recovers_nothing() {
let farm = tempdir();
fs::create_dir_all(&farm).unwrap();
assert!(recover_shape(&farm).is_none());
let _ = fs::remove_dir_all(&farm);
}
#[test]
fn an_authorized_keys_path_under_etc_ssh_is_refused() {
let mut cli = no_flags();
cli.install_key = true;
cli.authorized_keys = Some("/etc/ssh/authorized_keys.d/op".to_string());
let err = install_authorized_line(&cli, "ssh-ed25519 AAAA test", 22).unwrap_err();
assert!(err.contains("system sshd configuration"), "got: {err}");
assert!(err.contains("by hand"), "names the way out: {err}");
}
#[test]
fn the_drop_in_forces_a_command_only_for_the_tunnel_only_door() {
let deb = crate::util::platform::Platform::Debian;
let nologin = render_sshd_conf("f", Door::Nologin, 2022, deb);
assert!(
nologin.contains("ForceCommand /usr/sbin/nologin"),
"{nologin}"
);
for door in [Door::A, Door::B] {
let conf = render_sshd_conf("f", door, 2022, deb);
assert!(
!conf.contains("ForceCommand"),
"{door:?} must not force one:\n{conf}"
);
}
}
#[test]
fn the_drop_in_scopes_the_guardrail_to_the_port() {
let conf = render_sshd_conf(
"f",
Door::Nologin,
2022,
crate::util::platform::Platform::Debian,
);
assert!(conf.contains("Match LocalPort 2022"), "{conf}");
assert!(conf.contains("PermitOpen 127.0.0.1:1337"), "{conf}");
assert!(conf.contains("\nPort 22\n"), "{conf}");
assert!(
!conf.contains("Match User"),
"user-scoped defeats the purpose: {conf}"
);
}
#[test]
fn the_drop_in_names_the_per_platform_trap() {
use crate::util::platform::Platform;
let deb = render_sshd_conf("f", Door::Nologin, 2022, Platform::Debian);
assert!(
deb.contains("ssh.socket"),
"Debian must warn about socket activation: {deb}"
);
let rhel = render_sshd_conf("f", Door::Nologin, 2022, Platform::Rhel);
assert!(
rhel.contains("SELinux"),
"RHEL must warn about the port label: {rhel}"
);
let plain = render_sshd_conf("f", Door::Nologin, 22, Platform::Debian);
assert!(!plain.contains("ssh.socket"), "{plain}");
}
#[test]
fn a_scaffolded_overlay_never_deletes_the_projects_commands() {
for hint in [None, Some("trainer")] {
let tmp = tempdir();
let base = tmp.join("fdl.yml");
fs::write(&base, "commands:\n build:\n run: echo hi\n").unwrap();
let token = fresh_token().unwrap();
fs::write(
tmp.join("fdl.f.yml"),
render_overlay_scaffold("f", &token, &tmp, hint),
)
.unwrap();
let merged = crate::config::load_project_with_env(&base, Some("f")).unwrap();
assert!(
merged.commands.contains_key("build"),
"hint={hint:?}: the base command vanished under the overlay",
);
match hint {
Some(name) => assert_eq!(
merged.commands.get(name).and_then(|c| c.cluster),
Some(true),
"a named command must be wired for launcher mode",
),
None => assert_eq!(merged.commands.len(), 1),
}
let _ = fs::remove_dir_all(&tmp);
}
}