use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use std::time::{Duration, Instant};
use tokio_compat::runtime::current_thread;
use futures_01::future::Future as Future01;
use futures_util::compat::Future01CompatExt;
#[test]
fn can_run_01_futures() {
let future_ran = Arc::new(AtomicBool::new(false));
let ran = future_ran.clone();
current_thread::run(futures_01::future::lazy(move || {
future_ran.store(true, Ordering::SeqCst);
Ok::<(), ()>(())
}));
assert!(ran.load(Ordering::SeqCst));
}
#[test]
fn can_spawn_01_futures() {
let future_ran = Arc::new(AtomicBool::new(false));
let ran = future_ran.clone();
current_thread::run(futures_01::future::lazy(move || {
tokio_01::spawn(futures_01::future::lazy(move || {
future_ran.store(true, Ordering::SeqCst);
Ok(())
}));
Ok(())
}));
assert!(ran.load(Ordering::SeqCst));
}
#[test]
fn can_spawn_std_futures() {
let future_ran = Arc::new(AtomicBool::new(false));
let ran = future_ran.clone();
current_thread::run(futures_01::future::lazy(move || {
tokio_02::spawn(async move {
future_ran.store(true, Ordering::SeqCst);
});
Ok(())
}));
assert!(ran.load(Ordering::SeqCst));
}
#[test]
fn tokio_01_timers_work() {
let future1_ran = Arc::new(AtomicBool::new(false));
let ran = future1_ran.clone();
let future1 = futures_01::future::lazy(|| {
let when = Instant::now() + Duration::from_millis(15);
tokio_01::timer::Delay::new(when).map(move |_| when)
})
.map(move |when| {
ran.store(true, Ordering::SeqCst);
assert!(Instant::now() >= when);
})
.map_err(|_| panic!("timer should work"));
let future2_ran = Arc::new(AtomicBool::new(false));
let ran = future2_ran.clone();
let future2 = async move {
let when = Instant::now() + Duration::from_millis(10);
tokio_01::timer::Delay::new(when).compat().await.unwrap();
ran.store(true, Ordering::SeqCst);
assert!(Instant::now() >= when);
};
current_thread::run(futures_01::future::lazy(move || {
tokio_02::spawn(future2);
tokio_01::spawn(future1);
Ok(())
}));
assert!(future1_ran.load(Ordering::SeqCst));
assert!(future2_ran.load(Ordering::SeqCst));
}
#[test]
fn block_on_01_timer() {
let mut rt = current_thread::Runtime::new().unwrap();
let when = Instant::now() + Duration::from_millis(10);
rt.block_on(tokio_01::timer::Delay::new(when)).unwrap();
assert!(Instant::now() >= when);
}
#[test]
fn block_on_std_01_timer() {
let mut rt = current_thread::Runtime::new().unwrap();
let when = Instant::now() + Duration::from_millis(10);
rt.block_on_std(async move {
tokio_01::timer::Delay::new(when).compat().await.unwrap();
});
assert!(Instant::now() >= when);
}
#[test]
fn block_on_01_spawn() {
let mut rt = current_thread::Runtime::new().unwrap();
rt.block_on(futures_01::future::lazy(|| {
tokio_01::spawn(futures_01::future::lazy(|| Ok(())))
}))
.unwrap();
}
#[test]
fn block_on_std_01_spawn() {
let mut rt = current_thread::Runtime::new().unwrap();
rt.block_on_std(async { tokio_01::spawn(futures_01::future::lazy(|| Ok(()))) });
}
#[test]
fn tokio_02_spawn_blocking_works() {
let ran = Arc::new(AtomicBool::new(false));
let ran2 = ran.clone();
current_thread::run_std(async move {
println!("in future, before blocking");
tokio_02::task::spawn_blocking(move || {
println!("in blocking");
ran.store(true, Ordering::SeqCst);
})
.await
.expect("blocking task panicked!");
println!("blocking done");
});
assert!(ran2.load(Ordering::SeqCst));
}
#[test]
fn block_on_twice() {
let mut rt = current_thread::Runtime::new().unwrap();
rt.block_on_std(async {
tokio_02::spawn(async {}).await.unwrap();
println!("spawn 1 done")
});
println!("block_on 1 done");
rt.block_on_std(async {
tokio_02::spawn(async {}).await.unwrap();
println!("spawn 2 done");
});
println!("done");
}
#[test]
fn idle_after_block_on() {
let mut rt = current_thread::Runtime::new().unwrap();
let ran = Arc::new(AtomicBool::new(false));
rt.block_on_std(async {
tokio_02::spawn(async {}).await;
});
let ran2 = ran.clone();
rt.spawn_std(async move {
tokio_02::task::yield_now().await;
ran2.store(true, Ordering::SeqCst);
});
rt.run().unwrap();
assert!(ran.load(Ordering::SeqCst));
}
#[test]
fn enter_exposed() {
let rt = current_thread::Runtime::new().unwrap();
rt.enter(|| {
let _handle = tokio_02::runtime::Handle::current();
});
}
#[test]
fn enter_can_spawn_01_futures() {
let future_ran = Arc::new(AtomicBool::new(false));
let ran = future_ran.clone();
let mut rt = current_thread::Runtime::new().unwrap();
rt.enter(|| {
tokio_01::spawn(futures_01::future::lazy(move || {
future_ran.store(true, Ordering::SeqCst);
Ok(())
}));
});
rt.run();
assert!(ran.load(Ordering::SeqCst));
}