diff options
| author | Hermes Agent <hermes@localhost> | 2026-08-12 07:48:21 +0000 |
|---|---|---|
| committer | Hermes Agent <hermes@localhost> | 2026-08-12 07:48:21 +0000 |
| commit | f967d698efd44473a9285e02d0109f3bb0641622 (patch) | |
| tree | c94975571db9426cf71b15c9e6d16346e438c7c6 /tests | |
| parent | 5e6cae20331f8e7cfd551b4656f0de852a4ad44c (diff) | |
Format native builder and satisfy clippy
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/archive.rs | 47 | ||||
| -rw-r--r-- | tests/build.rs | 71 | ||||
| -rw-r--r-- | tests/cli.rs | 37 | ||||
| -rw-r--r-- | tests/compare.rs | 306 | ||||
| -rw-r--r-- | tests/initramfs.rs | 28 | ||||
| -rw-r--r-- | tests/model_validation.rs | 5 | ||||
| -rw-r--r-- | tests/package_installer.rs | 34 | ||||
| -rw-r--r-- | tests/rootfs_finalization.rs | 63 | ||||
| -rw-r--r-- | tests/stage_graph.rs | 5 |
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]); } |