use crate::model::artifacts::ArtifactChecksumRecord;
use crate::model::operation_plan::*;
use crate::model::{
attempt_journal::AttemptBudgetRecord,
inventory::{InventoryRecord, InventoryTargetRecord, InventoryTargetRequest},
};
pub(crate) const ROOT: &str = "aaaaa-aa";
pub(crate) const APP: &str = "renrk-eyaaa-aaaaa-aaada-cai";
pub(crate) fn request() -> OperationPlanRequest {
let inventory = InventoryRecord::new(
[(ROOT, None), (APP, Some(ROOT))]
.into_iter()
.map(|(id, parent)| {
InventoryTargetRecord::new(&InventoryTargetRequest {
canister_id: id.into(),
parent_canister_id: parent.map(str::to_owned),
role: None,
module_hash: None,
})
.expect("row")
})
.collect(),
)
.expect("inventory");
OperationPlanRequest {
context: PlanContextRecord::new(&PlanContextRequest {
network: "ab".repeat(32),
caller: "2vxsx-fae".into(),
release: "cd".repeat(32),
})
.expect("context"),
inventory,
selected_targets: vec![APP.into()],
operations: vec![
operation(0, APP, "ef", 1, 1),
PlannedOperationRecord::new(PlannedOperationRequest {
depends_on: vec![0],
..operation_request(&operation(7, APP, "01", 2, 1))
})
.unwrap(),
],
budget: PlanBudgetRecord::new(3, 2).expect("aggregate ceilings"),
}
}
pub(crate) fn single_operation_request(
mut original: OperationPlanRequest,
mut operation: PlannedOperationRequest,
) -> OperationPlanRequest {
operation.depends_on.clear();
original.budget = PlanBudgetRecord::new(
operation.budget.mutations(),
operation.budget.observations(),
)
.unwrap();
original.operations = vec![PlannedOperationRecord::new(operation).unwrap()];
original
}
pub(crate) fn operation(
id: u64,
target: &str,
hash: &str,
mutations: u32,
observations: u32,
) -> PlannedOperationRecord {
PlannedOperationRecord::new(PlannedOperationRequest {
depends_on: vec![],
operation_sequence: id,
target: target.into(),
request: hash.repeat(32),
budget: AttemptBudgetRecord::new(mutations, observations).expect("finite operation"),
})
.expect("operation")
}
pub(crate) fn declaration(plan: &OperationPlanRecord) -> OperationPlanRequest {
OperationPlanRequest {
context: plan.context().clone(),
inventory: plan.inventory().clone(),
selected_targets: plan.selected_targets().to_vec(),
operations: plan.operations().to_vec(),
budget: plan.budget().clone(),
}
}
pub(crate) fn operation_request(operation: &PlannedOperationRecord) -> PlannedOperationRequest {
PlannedOperationRequest {
depends_on: operation.depends_on().to_vec(),
operation_sequence: operation.operation_sequence(),
target: operation.target().into(),
request: operation.request().into(),
budget: operation.budget().clone(),
}
}
pub(crate) fn set_dependencies(
plan: &mut OperationPlanRequest,
dependencies: impl IntoIterator<Item = (u64, Vec<u64>)>,
) {
for (sequence, depends_on) in dependencies {
let row = plan
.operations
.iter_mut()
.find(|row| row.operation_sequence() == sequence)
.unwrap();
let mut request = operation_request(row);
request.depends_on = depends_on;
*row = PlannedOperationRecord::new(request).unwrap();
}
}
pub fn plan() -> OperationPlanRecord {
OperationPlanRecord::new(request()).expect("original qualified plan fixture")
}
pub(crate) fn plan_for_request(
digest: &crate::model::artifacts::ArtifactChecksumRecord,
) -> OperationPlanRecord {
let mut original = request();
original.operations[1] = PlannedOperationRecord::new(PlannedOperationRequest {
request: digest.hash().into(),
..operation_request(&original.operations[1])
})
.unwrap();
OperationPlanRecord::new(original).unwrap()
}
pub fn hash(pair: &str) -> crate::model::artifacts::ArtifactChecksumRecord {
ArtifactChecksumRecord::from_hash(&pair.repeat(32)).expect("opaque exact SHA-256")
}