use std::sync::atomic::{AtomicUsize, Ordering};
use super::*;
use crate::testing::TestRunner;
#[test]
fn ping_records_pruned() {
System::build()
.name("test")
.ping_interval(5)
.build(TestRunner)
.block_on(async {
let mut arb = Arbiter::new();
let id = arb.id();
let answered = || {
PINGS.with(|p| {
p.borrow()
.get(&id)
.is_some_and(|recs| recs.iter().any(|r| r.rtt.is_some()))
})
};
let has = || PINGS.with(|p| p.borrow().contains_key(&id));
for _ in 0..400 {
if answered() {
break;
}
Delay::new(Duration::from_millis(5)).await;
}
assert!(answered());
arb.stop();
arb.join().unwrap();
for _ in 0..400 {
if !has() {
break;
}
Delay::new(Duration::from_millis(5)).await;
}
assert!(!has());
});
}
#[test]
fn latency_sampling() {
System::build()
.name("test")
.latency_interval(5)
.build(TestRunner)
.block_on(async {
let mut arb = Arbiter::new();
let sampled = |arb: &Arbiter| arb.latency().unwrap().histogram.count() >= 2;
let sys_arb = System::current().arbiter();
for _ in 0..400 {
if sampled(&arb) && sampled(&sys_arb) {
break;
}
Delay::new(Duration::from_millis(5)).await;
}
assert!(sampled(&arb));
assert!(sampled(&sys_arb));
let m = arb.latency().unwrap();
assert_eq!(m.interval, Duration::from_millis(5));
assert!(m.last_sample.unwrap() <= Instant::now());
arb.stop();
arb.join().unwrap();
});
System::build()
.name("test")
.latency_interval(0)
.build(TestRunner)
.block_on(async {
assert_eq!(System::current().arbiter().latency(), None);
let mut arb = Arbiter::new();
assert_eq!(arb.latency(), None);
arb.stop();
arb.join().unwrap();
});
}
#[test]
#[should_panic(expected = "System is not running")]
fn current_without_system() {
assert!(System::try_current().is_none());
let _ = System::current();
}
#[test]
fn system_api() {
let config = System::new("base", TestRunner).block_on(async {
let sys = System::current();
assert_eq!(sys.name(), "base");
assert!(!sys.testing());
assert!(!sys.signals());
assert_eq!(System::try_current().unwrap().id(), sys.id());
assert_eq!(sys.arbiter(), Arbiter::current());
assert!(format!("{sys:?}").contains("base"));
assert!(format!("{:?}", sys.config()).contains("base"));
assert_eq!(sys.get_value(|| 1usize), 1);
assert_eq!(sys.get_value(|| 2usize), 1);
assert_eq!(sys.spawn_blocking(|| 10).await, Ok(10));
let cnt = Arc::new(AtomicUsize::new(0));
let cnt2 = cnt.clone();
sys.handle()
.spawn(async move {
cnt2.fetch_add(1, Ordering::Relaxed);
})
.await
.unwrap();
assert_eq!(cnt.load(Ordering::Relaxed), 1);
sys.list_arbiters(|arbs| assert_eq!(arbs, [sys.arbiter()]));
sys.config()
});
assert!(System::try_current().is_none());
System::with_config("copy", config).block_on(async {
let sys = System::current();
assert_eq!(sys.name(), "copy");
assert_eq!(Arbiter::current().name(), "copy");
});
}
#[test]
fn list_arbiter_pings() {
System::build()
.name("test")
.ping_interval(5)
.build(TestRunner)
.block_on(async {
let mut arb = Arbiter::new();
let visited = || {
let mut found = false;
System::list_arbiter_pings(|a, recs| {
if a == &arb && recs.iter().any(|r| r.rtt.is_some()) {
found = true;
}
});
found
};
for _ in 0..400 {
if visited() {
break;
}
Delay::new(Duration::from_millis(5)).await;
}
assert!(visited());
let mut visited = false;
System::list_arbiter_pings(|_, _| {
visited = true;
assert!(System::current().0.arbiters.try_lock().is_some());
});
assert!(visited);
arb.stop();
arb.join().unwrap();
});
}
#[test]
fn list_arbiters_callback_joins_worker() {
System::new("list-join", TestRunner).block_on(async {
let sys = System::current();
let worker = Arbiter::new();
sys.list_arbiters(|arbs| {
assert!(sys.0.arbiters.try_lock().is_some());
let mut arb = arbs.iter().find(|arb| **arb == worker).unwrap().clone();
arb.stop();
arb.join().unwrap();
sys.list_arbiters(|arbs| assert!(!arbs.contains(&worker)));
});
});
}