netring 0.29.0

High-performance zero-copy packet I/O for Linux (AF_PACKET TPACKET_V3 + AF_XDP)
Documentation
//! Integration test for `Monitor::builder().on_async::<E>(handler)`.
//!
//! Builds a `Monitor` with both a sync and an async handler for
//! the same event type; verifies the build path and the
//! tokio-driven run loop honour both.

#![cfg(all(feature = "tokio", feature = "flow"))]

use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};
use std::time::Duration;

use netring::monitor::Monitor;
use netring::protocol::builtin::Tcp;
use netring::protocol::event_typed::FlowStarted;

#[tokio::test(flavor = "current_thread")]
async fn builder_accepts_async_handler_with_arc_capture() {
    let pool_calls = Arc::new(AtomicU32::new(0));
    let pool_h = Arc::clone(&pool_calls);

    let monitor = Monitor::builder()
        .interface("lo")
        .protocol::<Tcp>()
        .on::<FlowStarted<Tcp>>(|_evt: &FlowStarted<Tcp>| Ok(()))
        .on_async::<FlowStarted<Tcp>, _>(
            // (E, H) — H inferred
            move |_evt: &FlowStarted<Tcp>| {
                let pool = Arc::clone(&pool_h);
                async move {
                    tokio::task::yield_now().await;
                    pool.fetch_add(1, Ordering::Relaxed);
                    Ok(())
                }
            },
        )
        .build();

    match monitor {
        Ok(_) => {
            // The build path is the only thing this test can verify
            // deterministically — actually firing the handler
            // requires real TCP traffic on lo (or CAP_NET_RAW
            // capture access). The unit tests in
            // monitor::async_handler::tests exercise dispatch end
            // to end.
            let _ = pool_calls;
        }
        Err(e) => {
            eprintln!("Monitor::builder().build() failed: {e}");
        }
    }
}

#[tokio::test(flavor = "current_thread")]
async fn builder_accepts_async_only_handler() {
    let monitor = Monitor::builder()
        .interface("lo")
        .protocol::<Tcp>()
        .on_async::<FlowStarted<Tcp>, _>(
            // (E, H) — H inferred
            |_evt: &FlowStarted<Tcp>| async move { Ok(()) },
        )
        .build()
        .expect("build async-only");

    let run = monitor.run_for(Duration::from_millis(50));
    match tokio::time::timeout(Duration::from_secs(2), run).await {
        Ok(Ok(())) => {}
        Ok(Err(_)) => {
            // Likely no CAP_NET_RAW; not a test failure.
        }
        Err(_) => panic!("run_for didn't honour its deadline"),
    }
}