//! Remote Disk Manager (chj.disks): inventory model, operation planner, jobs. pub mod inventory; pub mod js; pub mod planner; pub mod service; #[cfg(test)] mod parity { use super::js::first_difference; use serde_json::Value; pub fn calls(name: &str) -> Vec { let fixture: Value = serde_json::from_str(include_str!("../../../tests/fixtures/disks/parity-0.1.0.json")).unwrap(); let list: Vec = fixture["calls"].as_array().unwrap().iter().filter(|c| c["fn"] == name).cloned().collect(); assert!(list.len() >= 10, "too few recorded {name} calls"); list } #[test] fn inventory_matches_0_1_0() { let mut failures = Vec::new(); for (i, call) in calls("buildInventory").iter().enumerate() { let built = super::inventory::build_inventory(call["input"][0].as_str().unwrap()); if let Some(diff) = first_difference(&call["output"], &built, "$") { failures.push(format!("#{i}: {diff}")); } } assert!(failures.is_empty(), "{} mismatches:\n{}", failures.len(), failures.iter().take(8).cloned().collect::>().join("\n")); } #[test] fn planner_matches_0_1_0() { let mut failures = Vec::new(); for (i, call) in calls("planOperations").iter().enumerate() { let input = &call["input"]; let title = input.get(2).and_then(|o| o.get("title")); let result = super::planner::plan_operations(&input[0], &input[1], title); match (result, call.get("error")) { (Ok(plan), None) => { if let Some(diff) = first_difference(&call["output"], &plan, "$") { failures.push(format!("#{i}: {diff}")); } } (Err(error), Some(expected)) => { if expected["code"] != error.code.as_str() || expected["message"] != error.message.as_str() { failures.push(format!("#{i}: error {} / {} vs {} / {}", expected["code"], expected["message"], error.code, error.message)); } } (Ok(_), Some(expected)) => failures.push(format!("#{i}: expected error {}", expected["code"])), (Err(error), None) => failures.push(format!("#{i}: unexpected error {} {}", error.code, error.message)), } } for (i, call) in calls("suggestions").iter().enumerate() { let result = serde_json::Value::Array(super::planner::suggestions(&call["input"][0])); if let Some(diff) = first_difference(&call["output"], &result, "$") { failures.push(format!("suggestions #{i}: {diff}")); } } assert!(failures.is_empty(), "{} mismatches:\n{}", failures.len(), failures.iter().take(10).cloned().collect::>().join("\n")); } }