use moonpool_sim::{NetworkConfiguration, NetworkProvider, SimWorld, TcpListenerTrait};
use tokio::io::AsyncWriteExt;
#[test]
fn test_basic_simulation_bind() {
let local_runtime = tokio::runtime::Builder::new_current_thread()
.enable_io()
.enable_time()
.build_local(Default::default())
.expect("Failed to build local runtime");
local_runtime.block_on(async move {
let sim = SimWorld::new();
let provider = sim.network_provider();
let listener = provider.bind("test-addr").await.unwrap();
let addr = listener.local_addr().unwrap();
assert_eq!(addr, "test-addr");
println!("Successfully bound to {}", addr);
});
}
async fn simple_echo_server<P>(provider: P, addr: &str) -> std::io::Result<()>
where
P: NetworkProvider + Clone,
{
let listener = provider.bind(addr).await?;
let _client = provider.connect(addr).await?; let (mut stream, _peer_addr) = listener.accept().await?;
let test_data = b"Hello from simple echo server";
stream.write_all(test_data).await?;
Ok(())
}
#[test]
fn test_simple_echo_simulation() {
let local_runtime = tokio::runtime::Builder::new_current_thread()
.enable_io()
.enable_time()
.build_local(Default::default())
.expect("Failed to build local runtime");
local_runtime.block_on(async move {
let config = NetworkConfiguration::fast_local(); let mut sim = SimWorld::new_with_network_config(config);
let provider = sim.network_provider();
simple_echo_server(provider, "echo-server").await.unwrap();
sim.run_until_empty();
assert!(sim.current_time() > std::time::Duration::ZERO);
println!("Simulation completed in {:?}", sim.current_time());
});
}
#[test]
fn test_deterministic_simulation_behavior() {
let local_runtime = tokio::runtime::Builder::new_current_thread()
.enable_io()
.enable_time()
.build_local(Default::default())
.expect("Failed to build local runtime");
local_runtime.block_on(async move {
let mut execution_times = Vec::new();
for _run in 0..3 {
let config = NetworkConfiguration::fast_local();
let mut sim = SimWorld::new_with_network_config(config);
let provider = sim.network_provider();
simple_echo_server(provider, "deterministic-test")
.await
.unwrap();
sim.run_until_empty();
execution_times.push(sim.current_time());
}
let first_time = execution_times[0];
for (i, &time) in execution_times.iter().enumerate() {
assert_eq!(
time, first_time,
"Run {} produced different timing than first run. Expected: {:?}, Got: {:?}",
i, first_time, time
);
}
println!(
"All {} runs completed deterministically in {:?}",
execution_times.len(),
first_time
);
});
}
#[test]
fn test_network_provider_trait_usage() {
let local_runtime = tokio::runtime::Builder::new_current_thread()
.enable_io()
.enable_time()
.build_local(Default::default())
.expect("Failed to build local runtime");
local_runtime.block_on(async move {
let sim = SimWorld::new();
let provider = sim.network_provider();
async fn use_provider_generically<P: NetworkProvider>(
provider: P,
addr: &str,
) -> std::io::Result<String> {
let listener = provider.bind(addr).await?;
listener.local_addr()
}
let addr = use_provider_generically(provider, "dynamic-test")
.await
.unwrap();
assert_eq!(addr, "dynamic-test");
println!("Generic provider usage successful: bound to {}", addr);
});
}