mod support;
use ic_backup::{
model::effect_graph::{EffectGraphRecord, EffectNodeRecord, EffectNodeRequest},
ops::persistence::{BackupLayoutGuard, create_effect_graph, read_effect_graph},
policy::effect_order::{EffectOrderError, EffectProgressRequest, readiness},
};
use std::fs;
#[test]
fn retained_graph_projects_causal_progress_without_rewriting_original_dependencies() {
let root = support::temp_root("ic-backup-public-effect");
let record = EffectGraphRecord::new(
[(10, vec![]), (20, vec![10]), (30, vec![20])]
.into_iter()
.map(|(id, depends_on)| {
EffectNodeRecord::new(EffectNodeRequest {
operation_sequence: id,
depends_on,
})
.expect("node")
})
.collect(),
)
.expect("graph");
let digest = record.digest();
let layout = BackupLayoutGuard::acquire(&root).expect("exclusion");
create_effect_graph(&layout, &record).expect("retain original graph");
drop(layout);
let layout = BackupLayoutGuard::acquire(&root).expect("reopen");
let graph = read_effect_graph(&layout, &digest).expect("original digest");
let retained = fs::read(root.join("effect-graph.json")).expect("original bytes");
let view = readiness(
&graph,
&EffectProgressRequest {
completed_operations: vec![10],
},
)
.expect("caller-declared causal progress");
assert_eq!(view.graph, digest);
assert_eq!(
view.ready
.iter()
.map(|node| node.operation_sequence())
.collect::<Vec<_>>(),
vec![20]
);
assert_eq!(
view.blocked
.iter()
.map(|node| node.operation_sequence())
.collect::<Vec<_>>(),
vec![30]
);
assert!(matches!(
readiness(
&graph,
&EffectProgressRequest {
completed_operations: vec![30]
}
),
Err(EffectOrderError::UnmetDependency {
operation_sequence: 30,
dependency: 20
})
));
assert_eq!(
fs::read(root.join("effect-graph.json")).expect("unchanged graph"),
retained
);
assert_eq!(graph, record);
drop(layout);
fs::remove_dir_all(root).expect("clean successful fixture");
}