#![cfg(all(unix, feature = "exe"))]
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use std::process::Command;
fn on_disk_bytes(path: &Path) -> u64 {
use std::os::unix::fs::MetadataExt;
std::fs::metadata(path)
.expect("stat")
.blocks()
.saturating_mul(512)
}
#[test]
fn packed_stub_materializes_then_execs_payload_and_compresses_when_supported() {
let stub = env!("CARGO_BIN_EXE_decmpfs-stub");
let dir = std::env::temp_dir().join(format!("decmpfs-e2e-{}", std::process::id()));
std::fs::create_dir_all(&dir).expect("scratch dir");
let payload = dir.join("payload.sh");
let filler = "# ".to_string() + &"decmpfs ".repeat(200_000);
std::fs::write(
&payload,
format!("#!/bin/sh\n{filler}\necho \"MATERIALIZED $*\"\n"),
)
.expect("write payload");
std::fs::set_permissions(&payload, std::fs::Permissions::from_mode(0o755))
.expect("chmod payload");
let packed = dir.join("packed");
let outcome = decmpfs::exe::pack_executable_with_stub(
Path::new(stub),
&payload,
&packed,
&decmpfs::Gate::any(),
)
.expect("pack succeeds");
assert!(
matches!(outcome, decmpfs::exe::PackOutcome::Packed { .. }),
"Gate::any() must pack, got {outcome:?}",
);
let compression_supported = matches!(
decmpfs::probe(&packed),
Ok(decmpfs::Support::Supported | decmpfs::Support::AlreadyCompressed)
);
let first = Command::new(&packed)
.arg("hello")
.output()
.expect("run packed stub");
assert!(
first.status.success(),
"first run failed: {}",
String::from_utf8_lossy(&first.stderr),
);
assert_eq!(
String::from_utf8_lossy(&first.stdout).trim(),
"MATERIALIZED hello",
"first run must exec the materialized payload",
);
let logical = std::fs::metadata(&packed).expect("stat").len();
let physical = on_disk_bytes(&packed);
if compression_supported {
assert!(
physical < logical,
"materialized file should be FS-compressed: {physical} on disk vs {logical} logical",
);
}
let second = Command::new(&packed)
.arg("again")
.output()
.expect("run materialized file");
assert!(second.status.success());
assert_eq!(
String::from_utf8_lossy(&second.stdout).trim(),
"MATERIALIZED again",
);
assert!(
!decmpfs::exe::contains_payload(&packed),
"after materialize the file carries no packed payload",
);
std::fs::remove_dir_all(&dir).ok();
}