use alt_controller_image::compare::{Change, SemanticDifference, compare}; use alt_controller_image::manifest::{ ArchiveMemberRecord, ArtifactManifest, FileRecord, InitrdRecord, PackageRecord, ServiceRecord, }; use tempfile::tempdir; fn baseline() -> ArtifactManifest { ArtifactManifest::new( vec![PackageRecord::new("kernel-image-rt", "1.0")], vec![FileRecord::file("etc/controller.conf", "aaa")], Some(InitrdRecord::new("boot/initrd-rt.img", "old-initrd")), vec![ServiceRecord::new("controller.service", true)], vec![ArchiveMemberRecord::new("etc/controller.conf", "file")], ) .expect("valid baseline manifest") } #[test] fn compares_added_removed_and_changed_semantic_records() { let left = baseline(); let right = ArtifactManifest::new( vec![ PackageRecord::new("kernel-image-rt", "2.0"), PackageRecord::new("controller-agent", "1.0"), ], 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")], ) .expect("valid comparison manifest"); let report = compare(&left, &right); 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 }, ] ); assert!(report.render().contains("changed initrd")); } #[test] fn reads_and_writes_a_toml_manifest_beside_an_artifact() { let fixture = tempdir().expect("temporary directory"); let artifact = fixture.path().join("controller.tar"); let manifest = baseline(); let manifest_path = manifest.write_beside(&artifact).expect("write manifest"); assert_eq!(manifest_path, fixture.path().join("artifact.manifest.toml")); assert_eq!(ArtifactManifest::load(&manifest_path).expect("load manifest"), manifest); } #[test] fn rejects_duplicate_semantic_keys() { let error = ArtifactManifest::new( vec![PackageRecord::new("controller", "1"), PackageRecord::new("controller", "2")], vec![], None, vec![], vec![], ) .expect_err("duplicate package names must fail"); assert!(error.to_string().contains("duplicate package record")); }