- Created T026-practical-test task.yaml for MVP smoke testing - Added k8shost-server to flake.nix (packages, apps, overlays) - Staged all workspace directories for nix flake build - Updated flake.nix shellHook to include k8shost Resolves: T026.S1 blocker (R8 - nix submodule visibility)
113 lines
3.6 KiB
Rust
113 lines
3.6 KiB
Rust
//! Integration tests for FireCracker backend
|
|
//!
|
|
//! These tests require:
|
|
//! - FireCracker binary at /usr/bin/firecracker (or PLASMAVMC_FIRECRACKER_PATH)
|
|
//! - Kernel image (PLASMAVMC_FIRECRACKER_KERNEL_PATH)
|
|
//! - Rootfs image (PLASMAVMC_FIRECRACKER_ROOTFS_PATH)
|
|
//!
|
|
//! Set PLASMAVMC_FIRECRACKER_TEST=1 to enable these tests.
|
|
|
|
use plasmavmc_firecracker::FireCrackerBackend;
|
|
use plasmavmc_hypervisor::HypervisorBackend;
|
|
use plasmavmc_types::{VmSpec, VirtualMachine, VmState};
|
|
use std::path::Path;
|
|
use std::time::Duration;
|
|
use tokio::time::sleep;
|
|
|
|
#[tokio::test]
|
|
#[ignore]
|
|
async fn integration_firecracker_lifecycle() {
|
|
// Check if test is enabled
|
|
if std::env::var("PLASMAVMC_FIRECRACKER_TEST").is_err() {
|
|
eprintln!("Skipping integration test: PLASMAVMC_FIRECRACKER_TEST not set");
|
|
return;
|
|
}
|
|
|
|
// Check for required environment variables
|
|
let kernel_path = match std::env::var("PLASMAVMC_FIRECRACKER_KERNEL_PATH") {
|
|
Ok(path) => path,
|
|
Err(_) => {
|
|
eprintln!("Skipping integration test: PLASMAVMC_FIRECRACKER_KERNEL_PATH not set");
|
|
return;
|
|
}
|
|
};
|
|
|
|
let rootfs_path = match std::env::var("PLASMAVMC_FIRECRACKER_ROOTFS_PATH") {
|
|
Ok(path) => path,
|
|
Err(_) => {
|
|
eprintln!("Skipping integration test: PLASMAVMC_FIRECRACKER_ROOTFS_PATH not set");
|
|
return;
|
|
}
|
|
};
|
|
|
|
// Verify paths exist
|
|
if !Path::new(&kernel_path).exists() {
|
|
eprintln!("Skipping integration test: kernel path does not exist: {}", kernel_path);
|
|
return;
|
|
}
|
|
|
|
if !Path::new(&rootfs_path).exists() {
|
|
eprintln!("Skipping integration test: rootfs path does not exist: {}", rootfs_path);
|
|
return;
|
|
}
|
|
|
|
// Check for FireCracker binary
|
|
let firecracker_path = std::env::var("PLASMAVMC_FIRECRACKER_PATH")
|
|
.unwrap_or_else(|_| "/usr/bin/firecracker".to_string());
|
|
if !Path::new(&firecracker_path).exists() {
|
|
eprintln!("Skipping integration test: FireCracker binary not found: {}", firecracker_path);
|
|
return;
|
|
}
|
|
|
|
// Create backend
|
|
let backend = match FireCrackerBackend::from_env() {
|
|
Ok(backend) => backend,
|
|
Err(e) => {
|
|
eprintln!("Skipping integration test: Failed to create backend: {}", e);
|
|
return;
|
|
}
|
|
};
|
|
|
|
// Create VM spec
|
|
let mut spec = VmSpec::default();
|
|
spec.cpu.vcpus = 1;
|
|
spec.memory.size_mib = 128;
|
|
|
|
// Create VM
|
|
let vm = VirtualMachine::new("test-vm", "org1", "proj1", spec);
|
|
let handle = backend.create(&vm).await.expect("create VM");
|
|
|
|
// Start VM
|
|
backend.start(&handle).await.expect("start VM");
|
|
|
|
// Wait a bit for VM to boot (FireCracker boots very fast, < 125ms)
|
|
sleep(Duration::from_millis(500)).await;
|
|
|
|
// Check status - FireCracker should be running after start
|
|
let status = backend.status(&handle).await.expect("get status");
|
|
assert!(
|
|
matches!(status.actual_state, VmState::Running | VmState::Starting),
|
|
"VM should be running or starting, got: {:?}",
|
|
status.actual_state
|
|
);
|
|
|
|
eprintln!("VM started successfully, state: {:?}", status.actual_state);
|
|
|
|
// Stop VM
|
|
backend.stop(&handle, Duration::from_secs(5))
|
|
.await
|
|
.expect("stop VM");
|
|
|
|
// Verify stopped
|
|
let status = backend.status(&handle).await.expect("get status after stop");
|
|
assert!(
|
|
matches!(status.actual_state, VmState::Stopped | VmState::Failed),
|
|
"VM should be stopped, got: {:?}",
|
|
status.actual_state
|
|
);
|
|
|
|
// Delete VM
|
|
backend.delete(&handle).await.expect("delete VM");
|
|
|
|
eprintln!("Integration test completed successfully");
|
|
}
|