From 7aabf62396d7608a4da88e88218bcf5eed9bc1a0 Mon Sep 17 00:00:00 2001 From: jedarden Date: Wed, 13 May 2026 18:49:39 -0400 Subject: [PATCH] P1.2 Topology type + node state machine - Add YAML deserialization test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive YAML deserialization test for Topology struct, verifying: - Deserialization from plan §4 YAML format (RG=2, 6 nodes, RF=2) - Correct topology properties (shards, rf, replica_group_count) - groups() iterator returns groups in ascending order - Each group holds exactly its configured nodes - Node addresses, replica groups, and statuses are correct All 41 topology tests pass, covering: - State machine transitions (legal and illegal) - Write eligibility rules per status - Group and node iteration - Healthy node filtering - YAML deserialization Co-Authored-By: Claude Sonnet 4.6 --- crates/miroir-core/src/topology.rs | 94 ++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/crates/miroir-core/src/topology.rs b/crates/miroir-core/src/topology.rs index 09eb09e..2ab2468 100644 --- a/crates/miroir-core/src/topology.rs +++ b/crates/miroir-core/src/topology.rs @@ -818,11 +818,105 @@ mod tests { assert!(msg.contains("draining")); } + // --- Plan §4 YAML deserialization test --- + // This test verifies that a Topology can be deserialized from YAML + #[test] + fn test_topology_deserialize_from_yaml() { + // YAML matching plan §4 example structure (RG=2, 6 nodes, RF=2) + let yaml = r#" +shards: 64 +rf: 2 +groups: + - id: 0 + nodes: + - "meili-0" + - "meili-1" + - "meili-2" + - id: 1 + nodes: + - "meili-3" + - "meili-4" + - "meili-5" +nodes: + meili-0: + id: "meili-0" + address: "http://meili-0.search.svc:7700" + replica_group: 0 + status: Active + meili-1: + id: "meili-1" + address: "http://meili-1.search.svc:7700" + replica_group: 0 + status: Active + meili-2: + id: "meili-2" + address: "http://meili-2.search.svc:7700" + replica_group: 0 + status: Active + meili-3: + id: "meili-3" + address: "http://meili-3.search.svc:7700" + replica_group: 1 + status: Active + meili-4: + id: "meili-4" + address: "http://meili-4.search.svc:7700" + replica_group: 1 + status: Active + meili-5: + id: "meili-5" + address: "http://meili-5.search.svc:7700" + replica_group: 1 + status: Active +"#; + + let topology: Topology = serde_yaml::from_str(yaml).expect("Failed to deserialize topology from YAML"); + + // Verify topology properties + assert_eq!(topology.shards(), 64, "S should be 64"); + assert_eq!(topology.rf(), 2, "RF should be 2"); + assert_eq!(topology.replica_group_count(), 2, "RG should be 2"); + + // Verify groups() iterator returns RG groups in ascending order + let groups: Vec<_> = topology.groups().collect(); + assert_eq!(groups.len(), 2, "Should have 2 groups"); + assert_eq!(groups[0].id, 0, "First group should be ID 0"); + assert_eq!(groups[1].id, 1, "Second group should be ID 1"); + + // Verify each group holds exactly its configured nodes + let group0_nodes = groups[0].nodes(); + assert_eq!(group0_nodes.len(), 3, "Group 0 should have 3 nodes"); + assert!(group0_nodes.contains(&NodeId::new("meili-0".to_string()))); + assert!(group0_nodes.contains(&NodeId::new("meili-1".to_string()))); + assert!(group0_nodes.contains(&NodeId::new("meili-2".to_string()))); + + let group1_nodes = groups[1].nodes(); + assert_eq!(group1_nodes.len(), 3, "Group 1 should have 3 nodes"); + assert!(group1_nodes.contains(&NodeId::new("meili-3".to_string()))); + assert!(group1_nodes.contains(&NodeId::new("meili-4".to_string()))); + assert!(group1_nodes.contains(&NodeId::new("meili-5".to_string()))); + + // Verify node addresses are correct + let node0 = topology.node(&NodeId::new("meili-0".to_string())).unwrap(); + assert_eq!(node0.address, "http://meili-0.search.svc:7700"); + assert_eq!(node0.replica_group, 0); + assert_eq!(node0.status, NodeStatus::Active); + + let node5 = topology.node(&NodeId::new("meili-5".to_string())).unwrap(); + assert_eq!(node5.address, "http://meili-5.search.svc:7700"); + assert_eq!(node5.replica_group, 1); + assert_eq!(node5.status, NodeStatus::Active); + } + // --- Plan §4 YAML example test --- // This test verifies that a Topology can be correctly built from the plan §4 YAML // example structure (RG=2, 6 nodes, RF=2) #[test] fn test_topology_from_plan_section_4_yaml_structure() { + // Plan §4 YAML example: + // replica_groups: 2 + // shards: 64 + // replication_factor: 2 // Plan §4 YAML example: // replica_groups: 2 // shards: 64