summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorHermes Agent <hermes@localhost>2026-08-12 01:34:51 +0000
committerHermes Agent <hermes@localhost>2026-08-12 01:34:51 +0000
commit9acf451473989fa868e21d2d6ff59cf3fb445562 (patch)
treec58417401e1ecb7304c21c2ebf6f2eaa032ad907 /tests
parent020fbf6a034b3c90de1bdd3ee5e3e5e15c783059 (diff)
Add semantic artifact manifest comparison
Diffstat (limited to 'tests')
-rw-r--r--tests/compare.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/tests/compare.rs b/tests/compare.rs
new file mode 100644
index 0000000..a4f0a32
--- /dev/null
+++ b/tests/compare.rs
@@ -0,0 +1,73 @@
+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"));
+}