use microsandbox::{Sandbox, sandbox::FlatClone};
use test_utils::msb_test;
async fn cleanup(name: &str) {
if let Ok(handle) = Sandbox::get(name).await {
let _ = handle.kill().await;
let _ = handle.remove().await;
}
}
async fn create_flat(name: &str) -> Sandbox {
Sandbox::builder(name)
.image("alpine:3.20")
.root_disk_with(|disk| disk.flat().size(512u32).clone_strategy(FlatClone::Copy))
.cpus(1)
.memory(512)
.replace()
.create()
.await
.expect("create flat-rootfs sandbox through the public SDK")
}
#[msb_test]
async fn public_sdk_boots_independent_flat_rootfs_sandboxes() {
let suffix = std::process::id();
let first_name = format!("flat-sdk-a-{suffix}");
let second_name = format!("flat-sdk-b-{suffix}");
cleanup(&first_name).await;
cleanup(&second_name).await;
let first = create_flat(&first_name).await;
let first_result = first
.shell(
"set -eu; test \"$(grep ' / ' /proc/mounts | cut -d ' ' -f 3 | head -n 1)\" = ext4; printf first > /sdk-private-marker; test \"$(cat /sdk-private-marker)\" = first",
)
.await
.expect("exercise first flat rootfs");
assert!(
first_result.status().success,
"first guest check failed: stdout=`{}` stderr=`{}`",
first_result.stdout().unwrap_or_default(),
first_result.stderr().unwrap_or_default()
);
first.stop().await.expect("stop first sandbox");
let second = create_flat(&second_name).await;
let second_result = second
.shell(
"set -eu; test \"$(grep ' / ' /proc/mounts | cut -d ' ' -f 3 | head -n 1)\" = ext4; test ! -e /sdk-private-marker; printf second > /sdk-private-marker; test \"$(cat /sdk-private-marker)\" = second",
)
.await
.expect("exercise second flat rootfs");
let second_stdout = second_result.stdout().unwrap_or_default();
let second_stderr = second_result.stderr().unwrap_or_default();
let second_success = second_result.status().success;
let _ = second.stop().await;
cleanup(&first_name).await;
cleanup(&second_name).await;
assert!(
second_success,
"second guest check failed: stdout=`{second_stdout}` stderr=`{second_stderr}`"
);
}