use std::{ sync::{ atomic::{AtomicBool, Ordering}, Arc, }, thread, time::{Duration, Instant}, }; use actix_rt::{time, Arbiter, System}; use tokio::sync::oneshot; #[test] #[should_panic] fn no_system_current_panic() { System::current(); } #[test] fn try_current_no_system() { assert!(System::try_current().is_none()) } #[test] fn try_current_with_system() { System::new().block_on(async { assert!(System::try_current().is_some()) }); } #[test] fn non_static_block_on() { let string = String::from("test_str"); let string = string.as_str(); let sys = System::new(); sys.block_on(async { actix_rt::time::sleep(Duration::from_millis(1)).await; assert_eq!("test_str", string); }); let rt = actix_rt::Runtime::new().unwrap(); rt.block_on(async { actix_rt::time::sleep(Duration::from_millis(1)).await; assert_eq!("test_str", string); }); System::current().stop(); sys.run().unwrap(); } #[test] fn await_for_timer() { let time = Duration::from_secs(1); let instant = Instant::now(); System::new().block_on(async move { time::sleep(time).await; }); assert!( instant.elapsed() >= time, "Calling `block_on` should poll awaited future to completion." ); } #[test] fn system_arbiter_spawn() { let runner = System::new(); let (tx, rx) = oneshot::channel(); let sys = System::current(); thread::spawn(|| { // this thread will have no arbiter in it's thread local so call will panic Arbiter::current(); }) .join() .unwrap_err(); let thread = thread::spawn(|| { // this thread will have no arbiter in it's thread local so use the system handle instead System::set_current(sys); let sys = System::current(); let arb = sys.arbiter(); arb.spawn(async move { tx.send(42u32).unwrap(); System::current().stop(); }); }); assert_eq!(runner.block_on(rx).unwrap(), 42); thread.join().unwrap(); } struct Atom(Arc); impl Drop for Atom { fn drop(&mut self) { self.0.store(true, Ordering::SeqCst); } } #[test] fn system_stop_arbiter_join_barrier() { let sys = System::new(); let arb = Arbiter::new(); let atom = Atom(Arc::new(AtomicBool::new(false))); // arbiter should be alive to receive spawn msg assert!(Arbiter::current().spawn_fn(|| {})); assert!(arb.spawn_fn(move || { // thread should get dropped during sleep thread::sleep(Duration::from_secs(2)); // pointless load to move atom into scope atom.0.load(Ordering::SeqCst); panic!("spawned fn (thread) should be dropped during sleep"); })); System::current().stop(); sys.run().unwrap(); // arbiter should be dead and return false assert!(!Arbiter::current().spawn_fn(|| {})); assert!(!arb.spawn_fn(|| {})); }