// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 //! Messenger instance setup utilities for testing. use anyhow::Result; use std::net::TcpListener; use std::sync::Arc; use tokio::time::Duration; use velo::Messenger; use velo::backend::Transport; use velo::backend::tcp::TcpTransportBuilder; /// Create a single Messenger instance with TCP transport on a random port. /// /// # Returns /// Messenger instance /// /// # Example /// ```ignore /// let messenger = create_messenger_tcp().await?; /// ``` pub async fn create_messenger_tcp() -> Result> { let listener = TcpListener::bind("127.0.0.1:0")?; let transport: Arc = Arc::new( TcpTransportBuilder::new() .from_listener(listener)? .build()?, ); let messenger = Messenger::builder() .add_transport(transport) .build() .await?; // Give transport a moment to bind tokio::time::sleep(Duration::from_millis(100)).await; Ok(messenger) } /// Container for a pair of connected Messenger instances. pub struct MessengerPair { pub messenger_a: Arc, pub messenger_b: Arc, } /// Create a pair of Messenger instances with bidirectional peer registration. /// /// Both instances: /// - Use TCP transport on random ports /// - Are registered as peers of each other /// - Ready for communication /// /// # Example /// ```ignore /// let pair = create_messenger_pair_tcp().await?; /// /// // Can now send messages between messenger_a and messenger_b /// pair.messenger_a.unary("handler")? /// .instance(pair.messenger_b.instance_id()) /// .send().await?; /// ``` pub async fn create_messenger_pair_tcp() -> Result { // Create first Messenger instance let messenger_a = create_messenger_tcp().await?; // Create second Messenger instance let messenger_b = create_messenger_tcp().await?; // Register each as peer of the other messenger_a.register_peer(messenger_b.peer_info())?; messenger_b.register_peer(messenger_a.peer_info())?; // Give time for peer registration to propagate tokio::time::sleep(Duration::from_millis(200)).await; Ok(MessengerPair { messenger_a, messenger_b, }) } #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_create_messenger_instance() { let messenger = create_messenger_tcp() .await .expect("Should create Messenger"); let peer_info = messenger.peer_info(); assert_eq!( peer_info.instance_id().worker_id(), messenger.instance_id().worker_id() ); assert!(!peer_info.worker_address().as_bytes().is_empty()); // Local handlers should include system entries let handlers = messenger.list_local_handlers(); assert!( handlers.contains(&"_list_handlers".to_string()), "Expected _list_handlers in local handler list: {:?}", handlers ); assert!( handlers.contains(&"_hello".to_string()), "Expected _hello in local handler list: {:?}", handlers ); } #[tokio::test] async fn test_create_messenger_pair() { let pair = create_messenger_pair_tcp() .await .expect("Should create pair"); // Verify both instances have different IDs assert_ne!( pair.messenger_a.instance_id(), pair.messenger_b.instance_id() ); // Verify worker addresses differ assert_ne!( pair.messenger_a.peer_info().worker_address().checksum(), pair.messenger_b.peer_info().worker_address().checksum() ); // Verify system handlers are discoverable across peers let handlers_from_a = pair .messenger_a .available_handlers(pair.messenger_b.instance_id()) .await .expect("Handlers from messenger_b should be available"); assert!( handlers_from_a.contains(&"_list_handlers".to_string()), "messenger_a should see _list_handlers on messenger_b: {:?}", handlers_from_a ); assert!( handlers_from_a.contains(&"_hello".to_string()), "messenger_a should see _hello on messenger_b: {:?}", handlers_from_a ); let handlers_from_b = pair .messenger_b .available_handlers(pair.messenger_a.instance_id()) .await .expect("Handlers from messenger_a should be available"); assert!( handlers_from_b.contains(&"_list_handlers".to_string()), "messenger_b should see _list_handlers on messenger_a: {:?}", handlers_from_b ); assert!( handlers_from_b.contains(&"_hello".to_string()), "messenger_b should see _hello on messenger_a: {:?}", handlers_from_b ); } }