mod common;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use net_kit::{Net, NetworkStatus};
#[test]
fn fresh_net_is_not_started() {
let net = Net::new();
assert_eq!(
net.local_network_reachability().unwrap(),
NetworkStatus::Unavailable
);
assert!(net.register(Box::new(|_| {})).unwrap().is_none());
assert!(net.clear_all_listener().is_err());
}
#[test]
fn default_matches_new() {
let net = Net::default();
assert_eq!(
net.local_network_reachability().unwrap(),
NetworkStatus::Unavailable
);
assert!(net.register(Box::new(|_| {})).unwrap().is_none());
}
#[test]
fn start_then_basic_operations() {
let rt = common::build_runtime();
let net = Net::new();
rt.block_on(async {
net.start().await.expect("start should succeed");
});
let handle = net
.register(Box::new(|_status| {}))
.unwrap()
.expect("register after start returns a handle");
let status = net.local_network_reachability().unwrap();
assert!(matches!(
status,
NetworkStatus::Available | NetworkStatus::Unavailable
));
assert!(net.unregister(handle).unwrap(), "first unregister succeeds");
assert!(
!net.unregister(handle).unwrap(),
"second unregister is a no-op"
);
net.shutdown().expect("shutdown should succeed");
}
#[test]
fn register_multiple_then_clear() {
let rt = common::build_runtime();
let net = Net::new();
rt.block_on(async { net.start().await.unwrap() });
let h1 = net.register(Box::new(|_| {})).unwrap().unwrap();
let h2 = net.register(Box::new(|_| {})).unwrap().unwrap();
let h3 = net.register(Box::new(|_| {})).unwrap().unwrap();
assert_ne!(h1, h2);
assert_ne!(h2, h3);
assert_ne!(h1, h3);
net.clear_all_listener().expect("clear after start is Ok");
assert!(!net.unregister(h1).unwrap());
assert!(!net.unregister(h2).unwrap());
assert!(!net.unregister(h3).unwrap());
net.shutdown().unwrap();
}
#[test]
fn lifecycle_start_shutdown_restart() {
let rt = common::build_runtime();
let net = Net::new();
rt.block_on(async { net.start().await.unwrap() });
let h = net.register(Box::new(|_| {})).unwrap().unwrap();
assert!(net.unregister(h).unwrap());
net.shutdown().unwrap();
assert!(net.register(Box::new(|_| {})).unwrap().is_none());
assert!(net.clear_all_listener().is_err());
rt.block_on(async { net.start().await.unwrap() });
assert!(net.register(Box::new(|_| {})).unwrap().is_some());
net.shutdown().unwrap();
}
#[test]
fn registering_does_not_immediately_invoke() {
let rt = common::build_runtime();
let net = Net::new();
rt.block_on(async { net.start().await.unwrap() });
let counter = Arc::new(AtomicUsize::new(0));
let _h = net
.register(common::counting_listener(Arc::clone(&counter)))
.unwrap()
.unwrap();
std::thread::sleep(common::CALLBACK_SETTLE);
assert_eq!(
counter.load(Ordering::SeqCst),
0,
"listener must not fire purely on registration"
);
net.shutdown().unwrap();
}