summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorHermes Agent <hermes@localhost>2026-08-12 07:48:21 +0000
committerHermes Agent <hermes@localhost>2026-08-12 07:48:21 +0000
commitf967d698efd44473a9285e02d0109f3bb0641622 (patch)
treec94975571db9426cf71b15c9e6d16346e438c7c6 /tests
parent5e6cae20331f8e7cfd551b4656f0de852a4ad44c (diff)
Format native builder and satisfy clippy
Diffstat (limited to 'tests')
-rw-r--r--tests/archive.rs47
-rw-r--r--tests/build.rs71
-rw-r--r--tests/cli.rs37
-rw-r--r--tests/compare.rs306
-rw-r--r--tests/initramfs.rs28
-rw-r--r--tests/model_validation.rs5
-rw-r--r--tests/package_installer.rs34
-rw-r--r--tests/rootfs_finalization.rs63
-rw-r--r--tests/stage_graph.rs5
9 files changed, 433 insertions, 163 deletions
diff --git a/tests/archive.rs b/tests/archive.rs
index 6e59837..83f6722 100644
--- a/tests/archive.rs
+++ b/tests/archive.rs
@@ -20,10 +20,17 @@ fn writes_deterministic_tar_with_files_directories_and_symlinks() {
let first = fixture.path().join("first.tar");
let second = fixture.path().join("second.tar");
- NativeTarWriter::new().write(&rootfs, &first).expect("write first archive");
- NativeTarWriter::new().write(&rootfs, &second).expect("write second archive");
+ NativeTarWriter::new()
+ .write(&rootfs, &first)
+ .expect("write first archive");
+ NativeTarWriter::new()
+ .write(&rootfs, &second)
+ .expect("write second archive");
- assert_eq!(fs::read(&first).expect("read first"), fs::read(&second).expect("read second"));
+ assert_eq!(
+ fs::read(&first).expect("read first"),
+ fs::read(&second).expect("read second")
+ );
let mut archive = Archive::new(fs::File::open(first).expect("open archive"));
let entries = archive
@@ -32,7 +39,13 @@ fn writes_deterministic_tar_with_files_directories_and_symlinks() {
.map(|entry| {
let entry = entry.expect("read entry");
let path = entry.path().expect("entry path").into_owned();
- (path, entry.header().entry_type(), entry.header().mtime().expect("mtime"), entry.header().uid().expect("uid"), entry.header().gid().expect("gid"))
+ (
+ path,
+ entry.header().entry_type(),
+ entry.header().mtime().expect("mtime"),
+ entry.header().uid().expect("uid"),
+ entry.header().gid().expect("gid"),
+ )
})
.collect::<Vec<_>>();
@@ -78,7 +91,10 @@ fn preserves_hardlinks_in_the_archive() {
(
entry.path().expect("entry path").into_owned(),
entry.header().entry_type(),
- entry.link_name().expect("entry link name").map(|path| path.into_owned()),
+ entry
+ .link_name()
+ .expect("entry link name")
+ .map(|path| path.into_owned()),
)
})
.collect::<Vec<_>>();
@@ -102,7 +118,10 @@ fn preserves_hardlinks_in_the_archive() {
fn rejects_a_missing_rootfs() {
let fixture = tempdir().expect("fixture directory");
let error = NativeTarWriter::new()
- .write(fixture.path().join("missing"), fixture.path().join("image.tar"))
+ .write(
+ fixture.path().join("missing"),
+ fixture.path().join("image.tar"),
+ )
.expect_err("missing rootfs must fail");
assert!(error.to_string().contains("rootfs is not a directory"));
}
@@ -119,7 +138,11 @@ fn rejects_an_archive_output_inside_the_rootfs() {
.write(&rootfs, &artifact)
.expect_err("archive output inside rootfs must be rejected");
- assert!(error.to_string().contains("archive output must not be inside rootfs"));
+ assert!(
+ error
+ .to_string()
+ .contains("archive output must not be inside rootfs")
+ );
assert!(!artifact.exists());
assert!(!rootfs.join("controller.tar.partial").exists());
}
@@ -138,7 +161,10 @@ fn refuses_to_replace_an_existing_archive() {
.expect_err("an existing archive must not be replaced");
assert!(error.to_string().contains("archive output already exists"));
- assert_eq!(fs::read_to_string(&artifact).expect("read existing artifact"), "existing artifact");
+ assert_eq!(
+ fs::read_to_string(&artifact).expect("read existing artifact"),
+ "existing artifact"
+ );
assert!(!fixture.path().join("controller.tar.partial").exists());
}
@@ -155,5 +181,8 @@ fn removes_partial_output_when_an_unsupported_entry_stops_packaging() {
.expect_err("socket entries must be rejected");
assert!(error.to_string().contains("unsupported rootfs entry type"));
- assert!(!artifact.exists(), "failed packaging must not publish a partial archive");
+ assert!(
+ !artifact.exists(),
+ "failed packaging must not publish a partial archive"
+ );
}
diff --git a/tests/build.rs b/tests/build.rs
index a0a75b8..7d67b29 100644
--- a/tests/build.rs
+++ b/tests/build.rs
@@ -119,7 +119,12 @@ fn refuses_to_reuse_an_existing_workspace() {
fs::create_dir(&workspace).expect("create existing workspace");
let error = executor
- .execute(&plan, &workspace, "profiles/apt.conf", fixture.path().join("image.tar"))
+ .execute(
+ &plan,
+ &workspace,
+ "profiles/apt.conf",
+ fixture.path().join("image.tar"),
+ )
.expect_err("existing workspace must be rejected");
assert!(error.to_string().contains("workspace already exists"));
@@ -143,7 +148,10 @@ fn rejects_an_existing_artifact_before_creating_the_workspace_or_installing() {
.expect_err("pre-existing artifact must be rejected");
assert!(error.to_string().contains("output artifact already exists"));
- assert_eq!(fs::read_to_string(&artifact).expect("read artifact"), "do not replace");
+ assert_eq!(
+ fs::read_to_string(&artifact).expect("read artifact"),
+ "do not replace"
+ );
assert!(!workspace.exists());
assert!(installer.requests.borrow().is_empty());
}
@@ -166,7 +174,10 @@ fn rejects_an_existing_companion_manifest_before_creating_the_workspace_or_insta
.expect_err("pre-existing companion manifest must be rejected");
assert!(error.to_string().contains("output manifest already exists"));
- assert_eq!(fs::read_to_string(&companion).expect("read companion manifest"), "do not replace");
+ assert_eq!(
+ fs::read_to_string(&companion).expect("read companion manifest"),
+ "do not replace"
+ );
assert!(!workspace.exists());
assert!(installer.requests.borrow().is_empty());
}
@@ -183,10 +194,19 @@ fn rejects_a_missing_apt_configuration_before_creating_the_workspace() {
let missing_apt_config = fixture.path().join("missing-apt.conf");
let error = executor
- .execute(&plan, &workspace, &missing_apt_config, fixture.path().join("image.tar"))
+ .execute(
+ &plan,
+ &workspace,
+ &missing_apt_config,
+ fixture.path().join("image.tar"),
+ )
.expect_err("missing APT configuration must be rejected");
- assert!(error.to_string().contains("APT configuration does not exist"));
+ assert!(
+ error
+ .to_string()
+ .contains("APT configuration does not exist")
+ );
assert!(!workspace.exists());
assert!(installer.requests.borrow().is_empty());
}
@@ -205,8 +225,15 @@ fn removes_the_new_workspace_when_package_installation_fails() {
.execute(&plan, &workspace, "profiles/apt.conf", &artifact)
.expect_err("failed installation must fail the build");
- assert!(error.to_string().contains("simulated package installation failure"));
- assert!(!workspace.exists(), "failed build must not leave a workspace");
+ assert!(
+ error
+ .to_string()
+ .contains("simulated package installation failure")
+ );
+ assert!(
+ !workspace.exists(),
+ "failed build must not leave a workspace"
+ );
assert!(!artifact.exists());
}
@@ -224,8 +251,15 @@ fn removes_the_new_workspace_when_the_installer_does_not_create_a_rootfs() {
.execute(&plan, &workspace, "profiles/apt.conf", &artifact)
.expect_err("missing rootfs must fail the build");
- assert!(error.to_string().contains("package installer did not create rootfs"));
- assert!(!workspace.exists(), "failed build must not leave a workspace");
+ assert!(
+ error
+ .to_string()
+ .contains("package installer did not create rootfs")
+ );
+ assert!(
+ !workspace.exists(),
+ "failed build must not leave a workspace"
+ );
assert!(!artifact.exists());
}
@@ -235,7 +269,8 @@ fn removes_the_new_workspace_when_rootfs_finalization_fails() {
let spec = ImageSpec::load(std::path::Path::new("profiles/alt-controller.toml"))
.expect("load controller spec");
let plan = BuildPlan::compile(spec).expect("compile build plan");
- let mut executor = BuildExecutor::new(RootfsFinalizationFailingInstaller, FixtureInitramfsBuilder);
+ let mut executor =
+ BuildExecutor::new(RootfsFinalizationFailingInstaller, FixtureInitramfsBuilder);
let workspace = fixture.path().join("work");
let artifact = fixture.path().join("image.tar");
@@ -243,7 +278,10 @@ fn removes_the_new_workspace_when_rootfs_finalization_fails() {
.execute(&plan, &workspace, "profiles/apt.conf", &artifact)
.expect_err("failed rootfs finalization must fail the build");
- assert!(!workspace.exists(), "failed build must not leave a workspace");
+ assert!(
+ !workspace.exists(),
+ "failed build must not leave a workspace"
+ );
assert!(!artifact.exists());
}
@@ -261,7 +299,14 @@ fn removes_the_new_workspace_when_initramfs_build_fails() {
.execute(&plan, &workspace, "profiles/apt.conf", &artifact)
.expect_err("failed initramfs build must fail the build");
- assert!(error.to_string().contains("simulated initramfs build failure"));
- assert!(!workspace.exists(), "failed build must not leave a workspace");
+ assert!(
+ error
+ .to_string()
+ .contains("simulated initramfs build failure")
+ );
+ assert!(
+ !workspace.exists(),
+ "failed build must not leave a workspace"
+ );
assert!(!artifact.exists());
}
diff --git a/tests/cli.rs b/tests/cli.rs
index 648962b..dfaf140 100644
--- a/tests/cli.rs
+++ b/tests/cli.rs
@@ -2,7 +2,7 @@ use std::fs;
use std::path::PathBuf;
use alt_controller_image::archive::NativeTarWriter;
-use alt_controller_image::cli::{run, Cli, Command};
+use alt_controller_image::cli::{Cli, Command, run};
use alt_controller_image::manifest::{ArtifactManifest, PackageRecord};
use clap::Parser;
use tempfile::tempdir;
@@ -46,8 +46,13 @@ fn parses_build_with_explicit_workspace_and_output_paths() {
#[test]
fn parses_inspect_with_an_explicit_artifact_path() {
- let cli = Cli::try_parse_from(["alt-controller-image", "inspect", "--artifact", "out/image.tar"])
- .expect("inspect command parses");
+ let cli = Cli::try_parse_from([
+ "alt-controller-image",
+ "inspect",
+ "--artifact",
+ "out/image.tar",
+ ])
+ .expect("inspect command parses");
assert!(matches!(
cli.command,
@@ -81,23 +86,37 @@ fn compare_uses_companion_manifests_for_tar_artifacts() {
fs::create_dir_all(&rootfs).expect("create rootfs");
let left = fixture.path().join("left.tar");
let right = fixture.path().join("right.tar");
- NativeTarWriter::new().write(&rootfs, &left).expect("write left archive");
- NativeTarWriter::new().write(&rootfs, &right).expect("write right archive");
+ NativeTarWriter::new()
+ .write(&rootfs, &left)
+ .expect("write left archive");
+ NativeTarWriter::new()
+ .write(&rootfs, &right)
+ .expect("write right archive");
ArtifactManifest::new(
- vec![PackageRecord::new("controller", "1.0")], vec![], None, vec![], vec![],
+ vec![PackageRecord::new("controller", "1.0")],
+ vec![],
+ None,
+ vec![],
+ vec![],
)
.expect("left manifest")
.write_beside(&left)
.expect("write left companion manifest");
ArtifactManifest::new(
- vec![PackageRecord::new("controller", "2.0")], vec![], None, vec![], vec![],
+ vec![PackageRecord::new("controller", "2.0")],
+ vec![],
+ None,
+ vec![],
+ vec![],
)
.expect("right manifest")
.write_beside(&right)
.expect("write right companion manifest");
- let error = run(Cli { command: Command::Compare { left, right } })
- .expect_err("companion package difference must be reported");
+ let error = run(Cli {
+ command: Command::Compare { left, right },
+ })
+ .expect_err("companion package difference must be reported");
assert!(error.to_string().contains("artifacts differ semantically"));
}
diff --git a/tests/compare.rs b/tests/compare.rs
index ab63f9a..8ea9fdb 100644
--- a/tests/compare.rs
+++ b/tests/compare.rs
@@ -1,5 +1,5 @@
-use alt_controller_image::compare::{Change, SemanticDifference, compare};
use alt_controller_image::archive::NativeTarWriter;
+use alt_controller_image::compare::{Change, SemanticDifference, compare};
use alt_controller_image::manifest::{
ArchiveMemberRecord, ArtifactManifest, FileRecord, InitrdRecord, PackageRecord, ServiceRecord,
};
@@ -27,7 +27,10 @@ fn compares_added_removed_and_changed_semantic_records() {
PackageRecord::new("kernel-image-rt", "2.0"),
PackageRecord::new("controller-agent", "1.0"),
],
- vec![FileRecord::symlink("etc/controller.conf", "controller.conf.real")],
+ vec![FileRecord::symlink(
+ "etc/controller.conf",
+ "controller.conf.real",
+ )],
Some(InitrdRecord::new("boot/initrd-rt.img", "new-initrd")),
vec![ServiceRecord::new("controller.service", false)],
vec![ArchiveMemberRecord::new("usr/bin/controller", "file")],
@@ -39,13 +42,33 @@ fn compares_added_removed_and_changed_semantic_records() {
assert_eq!(
report.differences(),
&[
- SemanticDifference::Package { name: "controller-agent".into(), change: Change::Added },
- SemanticDifference::Package { name: "kernel-image-rt".into(), change: Change::Changed },
- SemanticDifference::File { path: "etc/controller.conf".into(), change: Change::Changed },
- SemanticDifference::Initrd { change: Change::Changed },
- SemanticDifference::Service { name: "controller.service".into(), change: Change::Changed },
- SemanticDifference::ArchiveMember { path: "etc/controller.conf".into(), change: Change::Removed },
- SemanticDifference::ArchiveMember { path: "usr/bin/controller".into(), change: Change::Added },
+ SemanticDifference::Package {
+ name: "controller-agent".into(),
+ change: Change::Added
+ },
+ SemanticDifference::Package {
+ name: "kernel-image-rt".into(),
+ change: Change::Changed
+ },
+ SemanticDifference::File {
+ path: "etc/controller.conf".into(),
+ change: Change::Changed
+ },
+ SemanticDifference::Initrd {
+ change: Change::Changed
+ },
+ SemanticDifference::Service {
+ name: "controller.service".into(),
+ change: Change::Changed
+ },
+ SemanticDifference::ArchiveMember {
+ path: "etc/controller.conf".into(),
+ change: Change::Removed
+ },
+ SemanticDifference::ArchiveMember {
+ path: "usr/bin/controller".into(),
+ change: Change::Added
+ },
]
);
assert!(report.render().contains("changed initrd"));
@@ -98,10 +121,12 @@ fn archive_collection_records_an_initrd_once_as_a_dedicated_boot_fact() {
"8f7ed204b9dfaa20aa484445f54233c4b407cb80ec0f8c07f1f0a59675fb44cf",
))
);
- assert!(manifest
- .files
- .iter()
- .all(|record| record.path != "boot/initrd-6.12-rt1.img"));
+ assert!(
+ manifest
+ .files
+ .iter()
+ .all(|record| record.path != "boot/initrd-6.12-rt1.img")
+ );
}
#[test]
@@ -123,10 +148,12 @@ fn rootfs_collection_records_a_supplied_initrd_once_as_a_dedicated_boot_fact() {
.expect("collect rootfs facts");
assert_eq!(manifest.initrd, Some(initrd));
- assert!(manifest
- .files
- .iter()
- .all(|record| record.path != "boot/initrd-6.12-rt1.img"));
+ assert!(
+ manifest
+ .files
+ .iter()
+ .all(|record| record.path != "boot/initrd-6.12-rt1.img")
+ );
}
#[test]
@@ -136,8 +163,14 @@ fn reads_and_writes_a_toml_manifest_beside_an_artifact() {
let manifest = baseline();
let manifest_path = manifest.write_beside(&artifact).expect("write manifest");
- assert_eq!(manifest_path, fixture.path().join("controller.tar.manifest.toml"));
- assert_eq!(ArtifactManifest::load(&manifest_path).expect("load manifest"), manifest);
+ assert_eq!(
+ manifest_path,
+ fixture.path().join("controller.tar.manifest.toml")
+ );
+ assert_eq!(
+ ArtifactManifest::load(&manifest_path).expect("load manifest"),
+ manifest
+ );
}
#[test]
@@ -146,16 +179,26 @@ fn writes_distinct_manifests_for_artifacts_in_the_same_directory() {
let legacy = fixture.path().join("legacy.tar");
let native = fixture.path().join("native.tar");
let legacy_manifest = baseline();
- let native_manifest = ArtifactManifest::new(vec![], vec![], None, vec![], vec![])
- .expect("valid native manifest");
+ let native_manifest =
+ ArtifactManifest::new(vec![], vec![], None, vec![], vec![]).expect("valid native manifest");
- let legacy_path = legacy_manifest.write_beside(&legacy).expect("write legacy manifest");
- let native_path = native_manifest.write_beside(&native).expect("write native manifest");
+ let legacy_path = legacy_manifest
+ .write_beside(&legacy)
+ .expect("write legacy manifest");
+ let native_path = native_manifest
+ .write_beside(&native)
+ .expect("write native manifest");
assert_eq!(legacy_path, fixture.path().join("legacy.tar.manifest.toml"));
assert_eq!(native_path, fixture.path().join("native.tar.manifest.toml"));
- assert_eq!(ArtifactManifest::load(&legacy_path).expect("load legacy manifest"), legacy_manifest);
- assert_eq!(ArtifactManifest::load(&native_path).expect("load native manifest"), native_manifest);
+ assert_eq!(
+ ArtifactManifest::load(&legacy_path).expect("load legacy manifest"),
+ legacy_manifest
+ );
+ assert_eq!(
+ ArtifactManifest::load(&native_path).expect("load native manifest"),
+ native_manifest
+ );
}
#[test]
@@ -170,13 +213,19 @@ fn refuses_to_overwrite_an_existing_companion_manifest() {
.expect_err("existing companion manifests must not be overwritten");
assert!(error.to_string().contains("create artifact manifest"));
- assert_eq!(fs::read_to_string(&manifest_path).expect("read existing manifest"), "preserve this manifest");
+ assert_eq!(
+ fs::read_to_string(&manifest_path).expect("read existing manifest"),
+ "preserve this manifest"
+ );
}
#[test]
fn rejects_duplicate_semantic_keys() {
let error = ArtifactManifest::new(
- vec![PackageRecord::new("controller", "1"), PackageRecord::new("controller", "2")],
+ vec![
+ PackageRecord::new("controller", "1"),
+ PackageRecord::new("controller", "2"),
+ ],
vec![],
None,
vec![],
@@ -202,7 +251,11 @@ fn rejects_malformed_file_records_before_comparison() {
vec![],
)
.expect_err("regular files require a digest");
- assert!(error.to_string().contains("regular file record requires a digest"));
+ assert!(
+ error
+ .to_string()
+ .contains("regular file record requires a digest")
+ );
let error = ArtifactManifest::new(
vec![],
@@ -217,7 +270,11 @@ fn rejects_malformed_file_records_before_comparison() {
vec![],
)
.expect_err("symlinks cannot carry a digest");
- assert!(error.to_string().contains("symlink record cannot carry a digest"));
+ assert!(
+ error
+ .to_string()
+ .contains("symlink record cannot carry a digest")
+ );
}
#[test]
@@ -231,7 +288,11 @@ fn rejects_malformed_initrd_records_before_comparison() {
)
.expect_err("initrd records require a digest");
- assert!(error.to_string().contains("initrd record requires a sha256 digest"));
+ assert!(
+ error
+ .to_string()
+ .contains("initrd record requires a sha256 digest")
+ );
}
#[test]
@@ -283,24 +344,37 @@ fn collects_semantic_facts_from_native_rootfs_and_tar_artifact() {
)
.expect("collect semantic facts");
- assert_eq!(manifest.packages, vec![PackageRecord::new("controller", "1.0")]);
- assert!(manifest.files.iter().any(|record| record == &FileRecord::file(
- "etc/controller.conf",
- "2d5c759b2b539229e09d362e8dbe0ae410ff8c9ece6038624458724520683f5b",
- )));
- assert!(manifest
- .files
- .iter()
- .any(|record| record == &FileRecord::symlink("etc/controller-link", "controller.conf")));
- assert_eq!(manifest.services, vec![ServiceRecord::new("controller.service", true)]);
- assert!(manifest
- .archive_members
- .iter()
- .any(|record| record == &ArchiveMemberRecord::new("etc/controller.conf", "file")));
- assert!(manifest
- .archive_members
- .iter()
- .any(|record| record == &ArchiveMemberRecord::new("etc/controller-link", "symlink")));
+ assert_eq!(
+ manifest.packages,
+ vec![PackageRecord::new("controller", "1.0")]
+ );
+ assert!(manifest.files.iter().any(|record| record
+ == &FileRecord::file(
+ "etc/controller.conf",
+ "2d5c759b2b539229e09d362e8dbe0ae410ff8c9ece6038624458724520683f5b",
+ )));
+ assert!(
+ manifest
+ .files
+ .iter()
+ .any(|record| record == &FileRecord::symlink("etc/controller-link", "controller.conf"))
+ );
+ assert_eq!(
+ manifest.services,
+ vec![ServiceRecord::new("controller.service", true)]
+ );
+ assert!(
+ manifest
+ .archive_members
+ .iter()
+ .any(|record| record == &ArchiveMemberRecord::new("etc/controller.conf", "file"))
+ );
+ assert!(
+ manifest
+ .archive_members
+ .iter()
+ .any(|record| record == &ArchiveMemberRecord::new("etc/controller-link", "symlink"))
+ );
}
#[test]
@@ -325,10 +399,11 @@ fn collects_comparable_semantic_facts_directly_from_a_tar_artifact() {
let manifest = ArtifactManifest::collect_archive(&artifact).expect("collect archive facts");
assert_eq!(manifest.packages, Vec::<PackageRecord>::new());
- assert!(manifest.files.iter().any(|record| record == &FileRecord::file(
- "etc/controller.conf",
- "2d5c759b2b539229e09d362e8dbe0ae410ff8c9ece6038624458724520683f5b",
- )));
+ assert!(manifest.files.iter().any(|record| record
+ == &FileRecord::file(
+ "etc/controller.conf",
+ "2d5c759b2b539229e09d362e8dbe0ae410ff8c9ece6038624458724520683f5b",
+ )));
assert_eq!(
manifest.initrd,
Some(InitrdRecord::new(
@@ -336,7 +411,10 @@ fn collects_comparable_semantic_facts_directly_from_a_tar_artifact() {
"8f7ed204b9dfaa20aa484445f54233c4b407cb80ec0f8c07f1f0a59675fb44cf",
))
);
- assert_eq!(manifest.services, vec![ServiceRecord::new("controller.service", true)]);
+ assert_eq!(
+ manifest.services,
+ vec![ServiceRecord::new("controller.service", true)]
+ );
}
#[test]
@@ -350,11 +428,16 @@ fn normalizes_legacy_dot_prefixed_archive_paths_before_comparison() {
header.set_mode(0o644);
header.set_cksum();
archive
- .append_data(&mut header, "./etc/controller.conf", Cursor::new(b"controller\n"))
+ .append_data(
+ &mut header,
+ "./etc/controller.conf",
+ Cursor::new(b"controller\n"),
+ )
.expect("append legacy-style member");
archive.finish().expect("finish legacy archive");
- let manifest = ArtifactManifest::collect_archive(&artifact).expect("collect legacy archive facts");
+ let manifest =
+ ArtifactManifest::collect_archive(&artifact).expect("collect legacy archive facts");
let expected = ArtifactManifest::new(
vec![],
vec![FileRecord::file(
@@ -391,7 +474,11 @@ fn rejects_duplicate_archive_member_paths_before_semantic_comparison() {
let error = ArtifactManifest::collect_archive(&artifact)
.expect_err("ambiguous archive paths cannot be compared semantically");
- assert!(error.to_string().contains("duplicate archive member record: etc/controller.conf"));
+ assert!(
+ error
+ .to_string()
+ .contains("duplicate archive member record: etc/controller.conf")
+ );
}
#[test]
@@ -405,7 +492,11 @@ fn collects_hardlink_targets_from_an_archive_for_semantic_comparison() {
header.set_mode(0o644);
header.set_cksum();
archive
- .append_data(&mut header, "./usr/bin/controller", Cursor::new(b"controller\n"))
+ .append_data(
+ &mut header,
+ "./usr/bin/controller",
+ Cursor::new(b"controller\n"),
+ )
.expect("append regular member");
let mut link_header = tar::Header::new_gnu();
link_header.set_entry_type(tar::EntryType::Link);
@@ -447,9 +538,10 @@ fn rootfs_collection_preserves_hardlink_facts_like_archive_collection() {
.write(&rootfs, &artifact)
.expect("write native archive");
- let rootfs_manifest = ArtifactManifest::collect(&rootfs, vec![], None, &artifact)
- .expect("collect rootfs facts");
- let archive_manifest = ArtifactManifest::collect_archive(&artifact).expect("collect archive facts");
+ let rootfs_manifest =
+ ArtifactManifest::collect(&rootfs, vec![], None, &artifact).expect("collect rootfs facts");
+ let archive_manifest =
+ ArtifactManifest::collect_archive(&artifact).expect("collect archive facts");
assert_eq!(rootfs_manifest.files, archive_manifest.files);
assert!(rootfs_manifest.files.iter().any(|record| {
@@ -464,17 +556,28 @@ fn normalizes_dot_prefixed_paths_from_a_legacy_tree_archive() {
fs::create_dir_all(rootfs.join("etc")).expect("create rootfs directory");
fs::write(rootfs.join("etc/controller.conf"), "controller\n").expect("write rootfs file");
let artifact = fixture.path().join("legacy.tar");
- let mut archive = tar::Builder::new(fs::File::create(&artifact).expect("create legacy archive"));
- archive.append_dir_all(".", &rootfs).expect("write legacy tree archive");
+ let mut archive =
+ tar::Builder::new(fs::File::create(&artifact).expect("create legacy archive"));
+ archive
+ .append_dir_all(".", &rootfs)
+ .expect("write legacy tree archive");
archive.finish().expect("finish legacy archive");
- let manifest = ArtifactManifest::collect_archive(&artifact).expect("collect legacy archive facts");
+ let manifest =
+ ArtifactManifest::collect_archive(&artifact).expect("collect legacy archive facts");
- assert!(manifest.files.iter().all(|record| !record.path.starts_with("./")));
- assert!(manifest
- .archive_members
- .iter()
- .all(|record| !record.path.starts_with("./")));
+ assert!(
+ manifest
+ .files
+ .iter()
+ .all(|record| !record.path.starts_with("./"))
+ );
+ assert!(
+ manifest
+ .archive_members
+ .iter()
+ .all(|record| !record.path.starts_with("./"))
+ );
}
#[test]
@@ -489,20 +592,26 @@ fn excludes_legacy_internal_host_and_fakedata_archive_members() {
fs::write(rootfs.join("etc/controller.conf"), "controller\n").expect("write visible file");
let legacy = fixture.path().join("legacy.tar");
let native = fixture.path().join("native.tar");
- let mut legacy_writer = tar::Builder::new(fs::File::create(&legacy).expect("create legacy archive"));
+ let mut legacy_writer =
+ tar::Builder::new(fs::File::create(&legacy).expect("create legacy archive"));
legacy_writer
.append_dir_all(".", &rootfs)
.expect("write legacy archive with internal metadata");
legacy_writer.finish().expect("finish legacy archive");
- NativeTarWriter::new().write(&rootfs, &native).expect("write native archive");
+ NativeTarWriter::new()
+ .write(&rootfs, &native)
+ .expect("write native archive");
let legacy_manifest = ArtifactManifest::collect_archive(&legacy).expect("collect legacy facts");
let native_manifest = ArtifactManifest::collect_archive(&native).expect("collect native facts");
- assert!(legacy_manifest
- .archive_members
- .iter()
- .all(|record| !record.path.starts_with(".host/") && !record.path.starts_with(".fakedata/")));
+ assert!(
+ legacy_manifest
+ .archive_members
+ .iter()
+ .all(|record| !record.path.starts_with(".host/")
+ && !record.path.starts_with(".fakedata/"))
+ );
let report = compare(&legacy_manifest, &native_manifest);
assert!(report.is_equivalent(), "{}", report.render());
}
@@ -519,16 +628,21 @@ fn native_manifest_collection_excludes_internal_members_from_its_archive_facts()
fs::write(rootfs.join("etc/controller.conf"), "controller\n").expect("write visible file");
let artifact = fixture.path().join("legacy.tar");
let mut writer = tar::Builder::new(fs::File::create(&artifact).expect("create legacy archive"));
- writer.append_dir_all(".", &rootfs).expect("write legacy archive");
+ writer
+ .append_dir_all(".", &rootfs)
+ .expect("write legacy archive");
writer.finish().expect("finish legacy archive");
let manifest = ArtifactManifest::collect(&rootfs, vec![], None, &artifact)
.expect("collect native filesystem and archive facts");
- assert!(manifest
- .archive_members
- .iter()
- .all(|record| !record.path.starts_with(".host/") && !record.path.starts_with(".fakedata/")));
+ assert!(
+ manifest
+ .archive_members
+ .iter()
+ .all(|record| !record.path.starts_with(".host/")
+ && !record.path.starts_with(".fakedata/"))
+ );
}
#[test]
@@ -541,19 +655,25 @@ fn archive_collection_excludes_nested_internal_metadata_members() {
fs::write(rootfs.join("etc/controller.conf"), "controller\n").expect("write visible file");
let artifact = fixture.path().join("legacy.tar");
let mut writer = tar::Builder::new(fs::File::create(&artifact).expect("create legacy archive"));
- writer.append_dir_all(".", &rootfs).expect("write legacy archive");
+ writer
+ .append_dir_all(".", &rootfs)
+ .expect("write legacy archive");
writer.finish().expect("finish legacy archive");
let manifest = ArtifactManifest::collect_archive(&artifact).expect("collect archive facts");
- assert!(manifest
- .archive_members
- .iter()
- .all(|record| !record.path.split('/').any(|component| component == ".fakedata")));
- assert!(manifest
- .files
- .iter()
- .all(|record| !record.path.split('/').any(|component| component == ".fakedata")));
+ assert!(manifest.archive_members.iter().all(|record| {
+ !record
+ .path
+ .split('/')
+ .any(|component| component == ".fakedata")
+ }));
+ assert!(manifest.files.iter().all(|record| {
+ !record
+ .path
+ .split('/')
+ .any(|component| component == ".fakedata")
+ }));
}
#[test]
@@ -575,7 +695,10 @@ fn rootfs_collection_recognizes_services_enabled_by_non_default_targets() {
let manifest = ArtifactManifest::collect(&rootfs, vec![], None, &artifact)
.expect("collect native filesystem and archive facts");
- assert_eq!(manifest.services, vec![ServiceRecord::new("controller.service", true)]);
+ assert_eq!(
+ manifest.services,
+ vec![ServiceRecord::new("controller.service", true)]
+ );
}
#[test]
@@ -598,7 +721,10 @@ fn archive_collection_coalesces_a_service_enabled_by_multiple_targets() {
let manifest = ArtifactManifest::collect_archive(&artifact).expect("collect archive facts");
- assert_eq!(manifest.services, vec![ServiceRecord::new("controller.service", true)]);
+ assert_eq!(
+ manifest.services,
+ vec![ServiceRecord::new("controller.service", true)]
+ );
}
#[test]
diff --git a/tests/initramfs.rs b/tests/initramfs.rs
index 429411a..5ad0b99 100644
--- a/tests/initramfs.rs
+++ b/tests/initramfs.rs
@@ -12,10 +12,8 @@ use tempfile::tempdir;
fn discovers_the_single_rt_kernel_and_renders_a_sorted_oem_recipe() {
let rootfs = tempdir().expect("rootfs directory");
fs::create_dir(rootfs.path().join("boot")).expect("boot directory");
- fs::write(rootfs.path().join("boot/vmlinuz-6.12.8-alt1.rt1"), "kernel")
- .expect("RT kernel");
- fs::write(rootfs.path().join("boot/vmlinuz-6.12.8-alt1.std"), "kernel")
- .expect("non-RT kernel");
+ fs::write(rootfs.path().join("boot/vmlinuz-6.12.8-alt1.rt1"), "kernel").expect("RT kernel");
+ fs::write(rootfs.path().join("boot/vmlinuz-6.12.8-alt1.std"), "kernel").expect("non-RT kernel");
let kernel = KernelVersion::discover_rt(rootfs.path()).expect("discover RT kernel");
assert_eq!(kernel.as_str(), "6.12.8-alt1.rt1");
@@ -59,8 +57,11 @@ fn make_initrd_adapter_uses_typed_chroot_arguments_and_records_output_digest() {
let rootfs = tempdir().expect("rootfs directory");
fs::create_dir(rootfs.path().join("boot")).expect("boot directory");
fs::write(rootfs.path().join("boot/vmlinuz-6.12-rt1"), "kernel").expect("RT kernel");
- fs::write(rootfs.path().join("boot/initrd-6.12-rt1.img"), b"generated initrd")
- .expect("generated initrd");
+ fs::write(
+ rootfs.path().join("boot/initrd-6.12-rt1.img"),
+ b"generated initrd",
+ )
+ .expect("generated initrd");
let request = InitramfsRequest::discover(rootfs.path()).expect("initramfs request");
let mut builder = MakeInitrdBuilder::new(RecordingRunner::default());
@@ -104,10 +105,19 @@ fn initramfs_adapter_refuses_to_replace_a_non_symlink_boot_alias() {
let request = InitramfsRequest::discover(rootfs.path()).expect("initramfs request");
let mut builder = MakeInitrdBuilder::new(RecordingRunner::default());
- let error = builder.build(&request).expect_err("regular boot alias must be protected");
+ let error = builder
+ .build(&request)
+ .expect_err("regular boot alias must be protected");
- assert!(error.to_string().contains("refusing to replace non-symlink boot alias"));
- assert_eq!(fs::read_to_string(boot.join("initrd.img")).expect("protected alias"), "do not replace");
+ assert!(
+ error
+ .to_string()
+ .contains("refusing to replace non-symlink boot alias")
+ );
+ assert_eq!(
+ fs::read_to_string(boot.join("initrd.img")).expect("protected alias"),
+ "do not replace"
+ );
}
#[derive(Debug, Default)]
diff --git a/tests/model_validation.rs b/tests/model_validation.rs
index f94a656..92a6640 100644
--- a/tests/model_validation.rs
+++ b/tests/model_validation.rs
@@ -56,7 +56,10 @@ fn controller_spec_preserves_the_vendored_controller_package_set() {
"rsyslog",
] {
assert!(
- spec.packages.base.iter().any(|candidate| candidate == package),
+ spec.packages
+ .base
+ .iter()
+ .any(|candidate| candidate == package),
"controller package set must contain {package}"
);
}
diff --git a/tests/package_installer.rs b/tests/package_installer.rs
index e527f14..76d8683 100644
--- a/tests/package_installer.rs
+++ b/tests/package_installer.rs
@@ -1,8 +1,8 @@
use std::path::PathBuf;
use alt_controller_image::hasher::{CommandRunner, HasherInstaller, Invocation};
-use alt_controller_image::{BuildPlan, ImageSpec};
use alt_controller_image::package_installer::{AptConfig, PackageInstaller, PackageRequest};
+use alt_controller_image::{BuildPlan, ImageSpec};
#[derive(Default)]
struct RecordingRunner {
@@ -63,13 +63,15 @@ fn hasher_installer_passes_typed_request_to_initroot_and_install_commands() {
#[test]
fn package_request_rejects_empty_packages_and_unsafe_apt_config_paths() {
assert!(AptConfig::new("").is_err());
- assert!(PackageRequest::new(
- PathBuf::from("work"),
- AptConfig::new("profiles/apt.conf").expect("valid apt config"),
- ["basesystem", ""],
- std::iter::empty::<&str>(),
- )
- .is_err());
+ assert!(
+ PackageRequest::new(
+ PathBuf::from("work"),
+ AptConfig::new("profiles/apt.conf").expect("valid apt config"),
+ ["basesystem", ""],
+ std::iter::empty::<&str>(),
+ )
+ .is_err()
+ );
}
#[test]
@@ -82,11 +84,21 @@ fn build_plan_compiles_its_typed_package_request() {
.package_request("work/alt-controller", "profiles/apt.conf")
.expect("compile package request");
- assert_eq!(request.workdir(), std::path::Path::new("work/alt-controller"));
- assert_eq!(request.apt_config().as_path(), std::path::Path::new("profiles/apt.conf"));
+ assert_eq!(
+ request.workdir(),
+ std::path::Path::new("work/alt-controller")
+ );
+ assert_eq!(
+ request.apt_config().as_path(),
+ std::path::Path::new("profiles/apt.conf")
+ );
assert_eq!(request.packages()[0], "anacron");
assert!(request.packages().contains(&"apt".to_owned()));
assert!(request.packages().contains(&"libiec61850".to_owned()));
- assert!(request.packages().contains(&"make-initrd-multipath".to_owned()));
+ assert!(
+ request
+ .packages()
+ .contains(&"make-initrd-multipath".to_owned())
+ );
assert_eq!(request.selectors(), ["^kernel-(image|modules-())-(rt)$"]);
}
diff --git a/tests/rootfs_finalization.rs b/tests/rootfs_finalization.rs
index a450b7e..9e07436 100644
--- a/tests/rootfs_finalization.rs
+++ b/tests/rootfs_finalization.rs
@@ -10,7 +10,8 @@ fn finalization_copies_trees_generates_oem_recipe_and_enables_services() {
let fixture = tempdir().expect("fixture directory");
let source = fixture.path().join("overlay");
fs::create_dir_all(source.join("nested")).expect("create source tree");
- fs::write(source.join("nested/controller.conf"), "mode = controller\n").expect("write source file");
+ fs::write(source.join("nested/controller.conf"), "mode = controller\n")
+ .expect("write source file");
symlink("nested/controller.conf", source.join("controller.conf"))
.expect("create relative source symlink");
@@ -29,7 +30,8 @@ fn finalization_copies_trees_generates_oem_recipe_and_enables_services() {
"mode = controller\n"
);
assert_eq!(
- fs::read_link(rootfs.path().join("etc/controller/controller.conf")).expect("copied symlink"),
+ fs::read_link(rootfs.path().join("etc/controller/controller.conf"))
+ .expect("copied symlink"),
Path::new("nested/controller.conf")
);
assert_eq!(
@@ -94,11 +96,16 @@ fn finalization_is_idempotent_for_matching_symlinks() {
vec![ServiceName::new("chronyd.service").expect("valid service")],
);
- finalization.apply(rootfs.path()).expect("first finalization succeeds");
- let second = finalization.apply(rootfs.path()).expect("repeat finalization succeeds");
+ finalization
+ .apply(rootfs.path())
+ .expect("first finalization succeeds");
+ let second = finalization
+ .apply(rootfs.path())
+ .expect("repeat finalization succeeds");
assert_eq!(
- fs::read_link(rootfs.path().join("etc/controller/controller-link")).expect("copied symlink"),
+ fs::read_link(rootfs.path().join("etc/controller/controller-link"))
+ .expect("copied symlink"),
Path::new("controller.conf")
);
assert_eq!(
@@ -110,10 +117,12 @@ fn finalization_is_idempotent_for_matching_symlinks() {
.expect("enabled service"),
Path::new("/usr/lib/systemd/system/chronyd.service")
);
- assert!(second
- .created_paths()
- .iter()
- .any(|path| path == "etc/controller/controller-link"));
+ assert!(
+ second
+ .created_paths()
+ .iter()
+ .any(|path| path == "etc/controller/controller-link")
+ );
}
#[test]
@@ -121,29 +130,43 @@ fn finalization_replaces_a_destination_symlink_instead_of_following_it() {
let fixture = tempdir().expect("fixture directory");
let source = fixture.path().join("overlay");
fs::create_dir_all(&source).expect("create source tree");
- fs::write(source.join("controller.conf"), "new controller configuration\n")
- .expect("write source file");
+ fs::write(
+ source.join("controller.conf"),
+ "new controller configuration\n",
+ )
+ .expect("write source file");
let rootfs = tempdir().expect("rootfs directory");
let outside = fixture.path().join("outside.conf");
fs::write(&outside, "must not change\n").expect("write outside file");
fs::create_dir_all(rootfs.path().join("etc/controller")).expect("create destination directory");
- symlink(&outside, rootfs.path().join("etc/controller/controller.conf"))
- .expect("create destination symlink");
+ symlink(
+ &outside,
+ rootfs.path().join("etc/controller/controller.conf"),
+ )
+ .expect("create destination symlink");
let finalization = RootfsFinalization::new(
vec![CopyTree::new(&source, "etc/controller").expect("valid copy destination")],
InitrdOem::new(std::iter::empty::<&str>(), std::iter::empty::<&str>()),
vec![],
);
- finalization.apply(rootfs.path()).expect("finalization replaces symlink safely");
+ finalization
+ .apply(rootfs.path())
+ .expect("finalization replaces symlink safely");
- assert_eq!(fs::read_to_string(&outside).expect("read outside file"), "must not change\n");
- assert!(fs::symlink_metadata(rootfs.path().join("etc/controller/controller.conf"))
- .expect("inspect copied file")
- .file_type()
- .is_file());
assert_eq!(
- fs::read_to_string(rootfs.path().join("etc/controller/controller.conf")).expect("read copied file"),
+ fs::read_to_string(&outside).expect("read outside file"),
+ "must not change\n"
+ );
+ assert!(
+ fs::symlink_metadata(rootfs.path().join("etc/controller/controller.conf"))
+ .expect("inspect copied file")
+ .file_type()
+ .is_file()
+ );
+ assert_eq!(
+ fs::read_to_string(rootfs.path().join("etc/controller/controller.conf"))
+ .expect("read copied file"),
"new controller configuration\n"
);
}
diff --git a/tests/stage_graph.rs b/tests/stage_graph.rs
index cd6fc93..13a297d 100644
--- a/tests/stage_graph.rs
+++ b/tests/stage_graph.rs
@@ -34,7 +34,10 @@ fn stage_graph_orders_artifact_producers_before_consumers() {
Stage::Manifest,
]
);
- assert_eq!(plan.dependencies(Stage::Package), &[Stage::FinalizeRootfs, Stage::BuildInitramfs]);
+ assert_eq!(
+ plan.dependencies(Stage::Package),
+ &[Stage::FinalizeRootfs, Stage::BuildInitramfs]
+ );
assert_eq!(plan.dependencies(Stage::BuildInitramfs), &[Stage::Install]);
assert_eq!(plan.dependencies(Stage::Manifest), &[Stage::Package]);
}