1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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"));
}
|