#![cfg(target_os = "linux")]
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use smolvm_pack::assets::AssetCollector;
use smolvm_pack::extract::{extract_sidecar, extract_sidecar_shared, shared_extract_enabled};
use smolvm_pack::format::PackManifest;
use smolvm_pack::{read_footer_from_sidecar, sidecar_path_for, Packer};
fn layer_tar(filename: &str, content: &[u8]) -> Vec<u8> {
let mut builder = tar::Builder::new(Vec::new());
let mut header = tar::Header::new_gnu();
header.set_entry_type(tar::EntryType::Regular);
header.set_size(content.len() as u64);
header.set_mode(0o644);
header.set_cksum();
builder.append_data(&mut header, filename, content).unwrap();
builder.into_inner().unwrap()
}
fn build_real_sidecar(dir: &Path) -> std::path::PathBuf {
let stub_path = dir.join("stub");
fs::write(&stub_path, b"#!/bin/sh\necho stub").unwrap();
let mut collector = AssetCollector::new(dir.join("staging")).unwrap();
collector
.add_layer(
"sha256:aaa111aaa111bbb222",
&layer_tar("etc/base.conf", b"base layer file"),
)
.unwrap();
collector
.add_layer(
"sha256:ccc333ccc333ddd444",
&layer_tar("etc/top.conf", b"top layer file"),
)
.unwrap();
let manifest = PackManifest::new(
"test:latest".to_string(),
"sha256:test".to_string(),
"linux/x86_64".to_string(),
"linux/x86_64".to_string(),
);
let output = dir.join("packed");
Packer::new(manifest)
.with_stub(&stub_path)
.with_assets(collector)
.pack(&output)
.unwrap();
sidecar_path_for(&output)
}
fn file_map(root: &Path) -> std::collections::BTreeMap<String, Vec<u8>> {
let mut out = std::collections::BTreeMap::new();
let mut stack = vec![root.to_path_buf()];
while let Some(d) = stack.pop() {
for entry in fs::read_dir(&d).unwrap() {
let entry = entry.unwrap();
let ft = entry.file_type().unwrap();
let p = entry.path();
if ft.is_dir() {
stack.push(p);
} else if ft.is_file() {
let rel = p.strip_prefix(root).unwrap().to_string_lossy().to_string();
out.insert(rel, fs::read(&p).unwrap());
}
}
}
out
}
#[test]
fn shared_extraction_is_content_addressed_idempotent_and_locked_down() {
let tmp = tempfile::tempdir().unwrap();
let sidecar = build_real_sidecar(tmp.path());
let footer = read_footer_from_sidecar(&sidecar).unwrap();
let shared_root = tmp.path().join("_shared");
let pack_plain = tmp.path().join("vm-plain/pack");
let shared_dir = extract_sidecar_shared(&sidecar, &shared_root, &footer, false).unwrap();
extract_sidecar(&sidecar, &pack_plain, &footer, false, false).unwrap();
assert_eq!(
shared_dir,
shared_root.join(format!("{:08x}", footer.checksum)),
"shared dir must be keyed by the footer checksum"
);
assert!(shared_dir.is_dir(), "shared extraction dir must exist");
let reference = file_map(&pack_plain);
assert!(!reference.is_empty(), "extraction produced no files");
assert_eq!(
file_map(&shared_dir),
reference,
"shared content must match a plain extraction byte-for-byte"
);
let shared_dir2 = extract_sidecar_shared(&sidecar, &shared_root, &footer, false).unwrap();
assert_eq!(
shared_dir2, shared_dir,
"second machine must reuse the copy"
);
let store_dirs: Vec<_> = fs::read_dir(&shared_root)
.unwrap()
.filter_map(|e| e.ok())
.filter(|e| e.path().is_dir())
.collect();
assert_eq!(
store_dirs.len(),
1,
"only one content-addressed extraction may exist for one checksum"
);
for dir in [&shared_root, &shared_dir] {
let mode = fs::metadata(dir).unwrap().permissions().mode() & 0o777;
assert_eq!(
mode,
0o700,
"{} must be 0700, got {:o}",
dir.display(),
mode
);
}
}
#[test]
fn kill_switch_disables_the_shared_store() {
assert!(
shared_extract_enabled(),
"shared store should be enabled by default on Linux"
);
std::env::set_var("SMOLVM_DISABLE_SHARED_EXTRACT", "1");
assert!(
!shared_extract_enabled(),
"kill-switch must disable the shared store"
);
std::env::remove_var("SMOLVM_DISABLE_SHARED_EXTRACT");
}
fn build_real_sidecar_marked(dir: &Path, marker: &[u8]) -> std::path::PathBuf {
fs::create_dir_all(dir).unwrap();
let stub_path = dir.join("stub");
fs::write(&stub_path, b"#!/bin/sh\necho stub").unwrap();
let mut collector = AssetCollector::new(dir.join("staging")).unwrap();
collector
.add_layer(
"sha256:aaa111aaa111bbb222",
&layer_tar("etc/base.conf", marker),
)
.unwrap();
let manifest = PackManifest::new(
"test:latest".to_string(),
"sha256:test".to_string(),
"linux/x86_64".to_string(),
"linux/x86_64".to_string(),
);
let output = dir.join("packed");
Packer::new(manifest)
.with_stub(&stub_path)
.with_assets(collector)
.pack(&output)
.unwrap();
sidecar_path_for(&output)
}
#[test]
fn shared_store_is_not_lru_evicted_by_a_later_pack() {
let tmp = tempfile::tempdir().unwrap();
let shared_root = tmp.path().join("_shared");
std::env::set_var("SMOLVM_PACK_CACHE_MAX_BYTES", "1");
let sa = build_real_sidecar_marked(&tmp.path().join("a"), b"alpha-layer");
let fa = read_footer_from_sidecar(&sa).unwrap();
let da = extract_sidecar_shared(&sa, &shared_root, &fa, false).unwrap();
let sb = build_real_sidecar_marked(&tmp.path().join("b"), b"beta-layer-longer-bytes");
let fb = read_footer_from_sidecar(&sb).unwrap();
let db = extract_sidecar_shared(&sb, &shared_root, &fb, false).unwrap();
std::env::remove_var("SMOLVM_PACK_CACHE_MAX_BYTES");
assert_ne!(
fa.checksum, fb.checksum,
"test needs two distinct-checksum packs"
);
assert!(
da.is_dir(),
"first shared entry must SURVIVE a later extraction (not be LRU-evicted)"
);
assert!(db.is_dir(), "second shared entry must exist");
for d in [&da, &db] {
let n = fs::read_dir(d.join("layers"))
.unwrap()
.filter_map(|e| e.ok())
.filter(|e| e.path().is_dir())
.count();
assert!(n > 0, "{} must keep its layer dirs", d.display());
}
}