From 413df10d5c3c2dd3d3c4d5c2b8a7f7b539b9d947 Mon Sep 17 00:00:00 2001 From: jedarden Date: Sat, 9 May 2026 08:06:51 -0400 Subject: [PATCH] Phase 1 (miroir-cdo): Fix scatter tests to use correct UnavailableShardPolicy variant Changed UnavailableShardPolicy::Skip to UnavailableShardPolicy::Partial in scatter.rs tests to match the actual enum definition. All Phase 1 Core Routing tests now pass: - 18 router tests (rendezvous hashing, covering sets, write targets) - All topology tests (groups, nodes, health state) - All merger tests (global sort, facets, offset/limit) - All scatter tests (fan-out primitives) Co-Authored-By: Claude Opus 4.7 --- crates/miroir-core/src/scatter.rs | 150 ++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/crates/miroir-core/src/scatter.rs b/crates/miroir-core/src/scatter.rs index 54f97b2..a1bdc91 100644 --- a/crates/miroir-core/src/scatter.rs +++ b/crates/miroir-core/src/scatter.rs @@ -79,3 +79,153 @@ impl Scatter for StubScatter { }) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::config::UnavailableShardPolicy; + + #[test] + fn test_scatter_request_creation() { + let request = ScatterRequest { + body: b"test body".to_vec(), + headers: vec![("Content-Type".to_string(), "application/json".to_string())], + method: "POST".to_string(), + path: "/search".to_string(), + }; + + assert_eq!(request.body, b"test body"); + assert_eq!(request.headers.len(), 1); + assert_eq!(request.method, "POST"); + assert_eq!(request.path, "/search"); + } + + #[test] + fn test_stub_scatter_returns_empty_response() { + let scatter = StubScatter; + let topology = Topology::new(1); + let nodes = vec![NodeId::new("node1".to_string())]; + let request = ScatterRequest { + body: Vec::new(), + headers: Vec::new(), + method: "GET".to_string(), + path: "/".to_string(), + }; + + let result = scatter + .scatter(&topology, nodes, request, UnavailableShardPolicy::Partial) + .unwrap(); + + assert!(result.responses.is_empty()); + assert!(result.failed.is_empty()); + } + + #[test] + fn test_scatter_response_empty() { + let response = ScatterResponse { + responses: Vec::new(), + failed: Vec::new(), + }; + + assert!(response.responses.is_empty()); + assert!(response.failed.is_empty()); + } + + #[test] + fn test_scatter_response_with_data() { + let node_response = NodeResponse { + node_id: NodeId::new("node1".to_string()), + body: b"response".to_vec(), + status: 200, + headers: vec![("Content-Type".to_string(), "application/json".to_string())], + }; + + let response = ScatterResponse { + responses: vec![node_response], + failed: vec![NodeId::new("node2".to_string())], + }; + + assert_eq!(response.responses.len(), 1); + assert_eq!(response.failed.len(), 1); + assert_eq!(response.responses[0].node_id.as_str(), "node1"); + assert_eq!(response.responses[0].status, 200); + assert_eq!(response.failed[0].as_str(), "node2"); + } + + #[test] + fn test_node_response_creation() { + let response = NodeResponse { + node_id: NodeId::new("test-node".to_string()), + body: b"test body".to_vec(), + status: 200, + headers: vec![("X-Custom".to_string(), "value".to_string())], + }; + + assert_eq!(response.node_id.as_str(), "test-node"); + assert_eq!(response.body, b"test body"); + assert_eq!(response.status, 200); + assert_eq!(response.headers.len(), 1); + assert_eq!(response.headers[0].0, "X-Custom"); + } + + #[test] + fn test_stub_scatter_with_empty_nodes() { + let scatter = StubScatter; + let topology = Topology::new(1); + let nodes: Vec = Vec::new(); + let request = ScatterRequest { + body: Vec::new(), + headers: Vec::new(), + method: "GET".to_string(), + path: "/".to_string(), + }; + + let result = scatter + .scatter(&topology, nodes, request, UnavailableShardPolicy::Partial) + .unwrap(); + + assert!(result.responses.is_empty()); + assert!(result.failed.is_empty()); + } + + #[test] + fn test_stub_scatter_with_multiple_nodes() { + let scatter = StubScatter; + let mut topology = Topology::new(1); + + let node1 = NodeId::new("node1".to_string()); + let node2 = NodeId::new("node2".to_string()); + let node3 = NodeId::new("node3".to_string()); + + topology.add_node(crate::topology::Node::new( + node1.clone(), + "http://node1".to_string(), + 0, + )); + topology.add_node(crate::topology::Node::new( + node2.clone(), + "http://node2".to_string(), + 0, + )); + topology.add_node(crate::topology::Node::new( + node3.clone(), + "http://node3".to_string(), + 0, + )); + + let nodes = vec![node1, node2, node3]; + let request = ScatterRequest { + body: Vec::new(), + headers: Vec::new(), + method: "POST".to_string(), + path: "/search".to_string(), + }; + + let result = scatter + .scatter(&topology, nodes, request, UnavailableShardPolicy::Partial) + .unwrap(); + + assert!(result.responses.is_empty()); + assert!(result.failed.is_empty()); + } +}