moonpool-sim 0.7.0

Simulation engine for the moonpool framework
use futures::io::{AsyncRead, AsyncWriteExt};
use moonpool_sim::{NetworkConfiguration, NetworkProvider, SimWorld, TcpListenerTrait};
use std::io::IoSlice;
use std::pin::Pin;
use std::task::{Context, Poll};

fn try_read(server: &mut (impl AsyncRead + Unpin), buf: &mut [u8]) -> Option<usize> {
    let waker = futures::task::noop_waker();
    let mut cx = Context::from_waker(&waker);
    match Pin::new(server).poll_read(&mut cx, buf) {
        Poll::Ready(Ok(n)) if n > 0 => Some(n),
        _ => None,
    }
}

#[test]
fn vectored_write_preserves_slice_boundaries_as_delivery_events() {
    let local_runtime = tokio::runtime::Builder::new_current_thread()
        .enable_io()
        .enable_time()
        .build()
        .expect("Failed to build local runtime");

    local_runtime.block_on(async move {
        let mut sim = SimWorld::new_with_network_config(NetworkConfiguration::fast_local());
        let provider = sim.network_provider();
        let addr = "vectored-write-test";

        let listener = provider.bind(addr).await.expect("bind should succeed");
        let mut client = provider
            .connect(addr)
            .await
            .expect("connect should succeed");
        let (mut server, _peer_addr) = listener.accept().await.expect("accept should succeed");

        assert!(client.is_write_vectored());

        let seg0 = b"AAAA";
        let seg1 = b"BBBBBB";
        let seg2 = b"CC";
        let bufs = [IoSlice::new(seg0), IoSlice::new(seg1), IoSlice::new(seg2)];
        let total = seg0.len() + seg1.len() + seg2.len();

        let accepted = client
            .write_vectored(&bufs)
            .await
            .expect("vectored write should succeed");
        assert_eq!(accepted, total);

        let mut chunks: Vec<Vec<u8>> = Vec::new();
        let mut buf = vec![0; 4096];
        while sim.pending_event_count() > 0 {
            sim.step();
            if let Some(n) = try_read(&mut server, &mut buf) {
                chunks.push(buf[..n].to_vec());
            }
        }

        assert_eq!(chunks, vec![seg0.to_vec(), seg1.to_vec(), seg2.to_vec()]);
    });
}