provisioning-platform/crates/ontoref-compute/tests/integration_script_provider.rs

123 lines
4 KiB
Rust
Raw Normal View History

//! Integration test for `ScriptProvider` using a temp Nu script.
//!
//! Requires `nu` on PATH. The test is marked `#[ignore]` by default so CI
//! without Nushell installed doesn't fail; run explicitly with:
//! `cargo test -p ontoref-compute --test integration_script_provider -- --ignored`
#[cfg(feature = "script")]
mod script_tests {
use std::io::Write;
use ontoref_compute::providers::script::ScriptProvider;
use ontoref_compute::{ComputeProvider, InstanceSpec};
/// Write a minimal Nu script that responds to `spawn` with a valid Instance JSON.
fn write_reference_script(path: &std::path::Path) {
let script = r#"#!/usr/bin/env nu
# Reference script provider responds to spawn/destroy/status/list/health.
let req = $in | from json
match $req.op {
"spawn" => {
{
result: "spawn",
handle: "script-test-0000000000000001",
ip: null,
ssh_host: null,
ssh_port: null,
expires_at: null,
provider: "script-nu",
metadata: {}
} | to json
},
"destroy" => {
{ result: "ack" } | to json
},
"status" => {
{ result: "status", value: "running" } | to json
},
"list" => {
{ result: "list", value: [] } | to json
},
"health" => {
{ result: "health", value: true } | to json
},
_ => {
exit 1
}
}
"#;
let mut f = std::fs::File::create(path).expect("create script file");
f.write_all(script.as_bytes()).expect("write script");
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = f.metadata().expect("metadata").permissions();
perms.set_mode(0o755);
std::fs::set_permissions(path, perms).expect("chmod");
}
}
#[tokio::test]
#[ignore = "requires nu on PATH"]
async fn script_provider_spawn_parses_valid_instance() {
let tmp = tempfile::tempdir().expect("tempdir");
let script_path = tmp.path().join("provider.nu");
write_reference_script(&script_path);
// Verify nu is available before running.
let nu_check = std::process::Command::new("nu").arg("--version").output();
if nu_check.is_err() || !nu_check.unwrap().status.success() {
eprintln!("nu not found on PATH — skipping");
return;
}
let provider =
ScriptProvider::new(std::path::PathBuf::from("nu"), script_path);
let spec = InstanceSpec::new("test-image:latest", 2, 1024);
let inst = provider.spawn(spec).await.expect("spawn should succeed");
assert_eq!(inst.handle.as_str(), "script-test-0000000000000001");
assert_eq!(inst.provider, "script-nu");
}
#[tokio::test]
#[ignore = "requires nu on PATH"]
async fn script_provider_destroy_is_idempotent() {
let tmp = tempfile::tempdir().expect("tempdir");
let script_path = tmp.path().join("provider.nu");
write_reference_script(&script_path);
if std::process::Command::new("nu").arg("--version").output().is_err() {
return;
}
let provider =
ScriptProvider::new(std::path::PathBuf::from("nu"), script_path);
let handle = ontoref_compute::InstanceHandle::new("script-test-0000000000000001");
provider.destroy(&handle).await.expect("first destroy");
provider.destroy(&handle).await.expect("second destroy (idempotent)");
}
#[tokio::test]
#[ignore = "requires nu on PATH"]
async fn script_provider_health_returns_ok() {
let tmp = tempfile::tempdir().expect("tempdir");
let script_path = tmp.path().join("provider.nu");
write_reference_script(&script_path);
if std::process::Command::new("nu").arg("--version").output().is_err() {
return;
}
let provider =
ScriptProvider::new(std::path::PathBuf::from("nu"), script_path);
let health = provider.health().await.expect("health");
assert!(health.ok);
}
}