use crate::fixtures::Fixtures;
use futures::io::{AsyncReadExt, AsyncWriteExt};
use moonpool_core::{NetworkProvider, Providers, TcpListenerTrait};
pub(crate) async fn network_contract<P: Providers, F: Fixtures>(p: &P, fixtures: &F) {
let net = p.network();
let listener = net.bind(&fixtures.bind_addr()).await.expect("bind failed");
let local = listener.local_addr().expect("local_addr failed");
assert!(!local.is_empty(), "local_addr() must be non-empty");
let mut client = net
.connect(&fixtures.connect_addr(&local))
.await
.expect("connect failed");
let (mut server, _peer) = listener.accept().await.expect("accept failed");
client
.write_all(b"ping")
.await
.expect("client write failed");
let mut received = [0u8; 4];
server
.read_exact(&mut received)
.await
.expect("server read failed");
assert_eq!(&received, b"ping", "server must receive exact bytes");
server
.write_all(&received)
.await
.expect("server write failed");
let mut echoed = [0u8; 4];
client
.read_exact(&mut echoed)
.await
.expect("client read failed");
assert_eq!(&echoed, b"ping", "client must receive its bytes back");
client.close().await.expect("client close failed");
let mut tail = [0u8; 8];
let n = server
.read(&mut tail)
.await
.expect("server read after FIN failed");
assert_eq!(n, 0, "server must observe EOF after peer half-closes");
if let Some(unbound) = fixtures.unbound_addr() {
assert!(
net.connect(&unbound).await.is_err(),
"connect to an unbound address must fail"
);
}
}