#![cfg(unix)]
use std::os::unix::fs::PermissionsExt as _;
use std::path::{Path, PathBuf};
mod common;
fn cli() -> PathBuf {
PathBuf::from(env!("CARGO_BIN_EXE_lm-provision"))
}
fn profile() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../lm-provision-driver/tests/fixtures/apply-secret.json")
}
fn unique_dir(name: &str) -> PathBuf {
let dir = std::env::temp_dir().join(format!(
"lm-provision-cli-apply-target-e2e-{name}-{}-{}",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.expect("system time")
.as_nanos()
));
std::fs::create_dir_all(&dir).expect("the temp directory is writable");
dir
}
fn executable(path: &Path, script: &str) {
std::fs::write(path, script).expect("the stub is writable");
std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o755))
.expect("the stub is made executable");
}
fn stub_platform_cli(dir: &Path, described: &str) {
executable(
&dir.join("runpod-cli"),
&format!(
"#!/bin/sh\n\
echo \"$@\" >> {argv}\n\
for arg in \"$@\"; do\n\
\x20 if [ \"$arg\" = get-pod ]; then\n\
\x20 echo '{described}'\n\
\x20 exit 0\n\
\x20 fi\n\
done\n\
echo '\"\"'\n",
argv = dir.join("platform-argv").display(),
),
);
}
fn stub_transport(dir: &Path, remote_hash: &str) {
executable(
&dir.join("ssh"),
&format!(
"#!/bin/sh\n\
echo \"$@\" >> {argv}\n\
case \"$*\" in\n\
\x20 *sha256sum*) echo 'deadbeef /root/lm-provisioner' ;;\n\
\x20 *\"'hash'\"*) echo '{remote_hash}' ;;\n\
\x20 *\"'validate'\"*) echo '{{\"ok\":true,\"name\":\"t\"}}' ;;\n\
esac\n\
exit 0\n",
argv = dir.join("ssh-argv").display(),
),
);
executable(
&dir.join("scp"),
&format!(
"#!/bin/sh\necho \"$@\" >> {argv}\nexit 0\n",
argv = dir.join("scp-argv").display(),
),
);
}
fn profile_hash() -> String {
lm_provision::cli::ast_hash(&profile()).expect("the fixture resolves and hashes")
}
fn recorded(dir: &Path, which: &str) -> String {
std::fs::read_to_string(dir.join(which)).unwrap_or_default()
}
fn key_file(dir: &Path) -> PathBuf {
let path = dir.join("id_test");
std::fs::write(&path, b"not a real key\n").expect("the temp directory is writable");
path
}
fn apply(dir: &Path, args: &[&str], key: Option<&Path>) -> std::process::Output {
let mut command = std::process::Command::new(cli());
command
.arg("apply")
.args(args)
.args(["--profile", &profile().display().to_string()])
.args([
"--validate-only",
"--skip-install",
"--no-ledger",
"--no-artifacts",
])
.env(
"PATH",
format!(
"{}:{}",
dir.display(),
std::env::var("PATH").unwrap_or_default()
),
)
.env("HOME", dir)
.env("XDG_RUNTIME_DIR", dir)
.env("RUNPOD_API_KEY", "test-key-not-a-real-one")
.current_dir(dir);
match key {
Some(path) => command.env("LM_PROVISION_SSH_KEY", path),
None => command.env_remove("LM_PROVISION_SSH_KEY"),
};
command.output().expect("the CLI binary runs")
}
#[test]
fn a_provider_and_an_id_are_resolved_into_the_ssh_the_session_dials() {
let _guard = common::stage_and_run();
let dir = unique_dir("resolved");
stub_platform_cli(
&dir,
r#"{"id":"pod-1","publicIp":"203.0.113.9","portMappings":{"22":21001},"desiredStatus":"RUNNING"}"#,
);
stub_transport(&dir, &profile_hash());
let key = key_file(&dir);
let output = apply(
&dir,
&["--provider", "runpod", "--pod-id", "pod-1"],
Some(&key),
);
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
assert_eq!(
output.status.code(),
Some(0),
"the session ran against the resolved endpoint: {stderr}"
);
let platform = recorded(&dir, "platform-argv");
assert!(
platform.contains("pods get-pod pod-1"),
"the machine was read back by its id, through the adapter's own template: {platform}"
);
let dialed = recorded(&dir, "ssh-argv");
assert!(
dialed.contains("-p 21001"),
"the port the platform mapped: {dialed}"
);
assert!(
dialed.contains("root@203.0.113.9"),
"the address the platform reported, as the user it runs workloads as: {dialed}"
);
assert!(
dialed.contains(&format!("-i {}", key.display())),
"the identity file came from the environment, not a flag: {dialed}"
);
assert!(
dialed.contains("ControlMaster=auto"),
"the steps of one session share a connection: {dialed}"
);
assert!(
recorded(&dir, "scp-argv").contains("ControlMaster=auto"),
"including the file transfers, which are most of the handshakes"
);
std::fs::remove_dir_all(&dir).ok();
}
#[test]
fn a_machine_that_reports_no_address_is_refused_before_anything_is_dialed() {
let _guard = common::stage_and_run();
let dir = unique_dir("booting");
stub_platform_cli(
&dir,
r#"{"id":"pod-1","publicIp":"","portMappings":{},"desiredStatus":"RUNNING"}"#,
);
stub_transport(&dir, &profile_hash());
let key = key_file(&dir);
let output = apply(
&dir,
&["--provider", "runpod", "--pod-id", "pod-1"],
Some(&key),
);
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
assert_eq!(output.status.code(), Some(1), "{stderr}");
assert!(
stderr.contains("no ssh endpoint"),
"the message says what the machine reported, and what to do: {stderr}"
);
assert!(
stderr.contains("read from the platform: publicIp: empty;"),
"and which field the projection found wanting: {stderr}"
);
assert!(
!dir.join("ssh-argv").exists(),
"nothing was dialed: {}",
recorded(&dir, "ssh-argv")
);
std::fs::remove_dir_all(&dir).ok();
}
#[test]
fn no_key_and_no_environment_variable_names_both_ways_to_give_one() {
let _guard = common::stage_and_run();
let dir = unique_dir("no-key");
stub_platform_cli(
&dir,
r#"{"id":"pod-1","publicIp":"203.0.113.9","portMappings":{"22":21001}}"#,
);
stub_transport(&dir, &profile_hash());
let output = apply(&dir, &["--provider", "runpod", "--pod-id", "pod-1"], None);
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
assert_eq!(output.status.code(), Some(2), "{stderr}");
assert!(
stderr.contains("LM_PROVISION_SSH_KEY") && stderr.contains("--key"),
"{stderr}"
);
assert!(
!dir.join("platform-argv").exists(),
"the platform was not even asked: the run could not have connected either way"
);
std::fs::remove_dir_all(&dir).ok();
}