#![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>, _>(
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(_) => {
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>, _>(
|_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(_)) => {
}
Err(_) => panic!("run_for didn't honour its deadline"),
}
}