/* Eagle - A simple library for RPC in Rust Copyright (c) 2024 KodiCraft This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use eagle::Protocol; use env_logger::{Builder, Env}; use std::sync::Once; static INIT: Once = Once::new(); pub fn init_logger() { INIT.call_once(|| { let env = Env::default() .filter_or("RUST_LOG", "info") .write_style_or("LOG_STYLE", "always"); Builder::from_env(env).format_timestamp_nanos().init(); }); } #[derive(Protocol)] enum TestProtocol { Addition((i32, i32), i32), SomeKindOfQuestion(String, i32), ThisRespondsWithAString(i32, String), Void((), ()), } #[derive(Clone)] struct TrivialServer; impl TestProtocolServerHandler for TrivialServer { async fn addition(&mut self, a: i32, b: i32) -> i32 { a + b } async fn some_kind_of_question(&mut self, s: String) -> i32 { s.len() as i32 } async fn this_responds_with_a_string(&mut self, i: i32) -> String { format!("The number is {}", i) } async fn void(&mut self) {} } struct Cleanup { address: String, } impl Drop for Cleanup { fn drop(&mut self) { std::fs::remove_file(&self.address).unwrap(); } } #[tokio::test] async fn e2e() { init_logger(); #[cfg(feature = "unix")] let address = format!("/tmp/eagle-test-{}.sock", rand::random::()); #[cfg(feature = "unix")] let _cleanup = Cleanup { address: address.clone(), }; #[cfg(feature = "tcp")] let address = format!("127.0.0.1:{}", 10000 + rand::random::() % 1000); let server_task = tokio::spawn(TestProtocolServer::bind(TrivialServer, address.clone())); // Wait for the server to start, the developer is responsible for this in production tokio::time::sleep(std::time::Duration::from_millis(10)).await; let client = TestProtocolClient::connect(address).await.unwrap(); assert_eq!(client.addition(2, 5).await.unwrap(), 7); assert_eq!( client .some_kind_of_question("Hello, world!".to_string()) .await .unwrap(), "Hello, world!".len() as i32 ); assert_eq!( client.this_responds_with_a_string(42).await.unwrap(), "The number is 42" ); client.void().await.unwrap(); server_task.abort(); }