100 lines
2.4 KiB
Rust
100 lines
2.4 KiB
Rust
//! Test for larger tasks.
|
|
|
|
use async_executor::Executor;
|
|
use futures_lite::future::{self, block_on};
|
|
use futures_lite::prelude::*;
|
|
|
|
use std::sync::Arc;
|
|
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
fn do_run<Fut: Future<Output = ()>>(mut f: impl FnMut(Arc<Executor<'static>>) -> Fut) {
|
|
// This should not run for longer than two minutes.
|
|
#[cfg(not(miri))]
|
|
let _stop_timeout = {
|
|
let (stop_timeout, stopper) = async_channel::bounded::<()>(1);
|
|
thread::spawn(move || {
|
|
block_on(async move {
|
|
let timeout = async {
|
|
async_io::Timer::after(Duration::from_secs(2 * 60)).await;
|
|
eprintln!("test timed out after 2m");
|
|
std::process::exit(1)
|
|
};
|
|
|
|
let _ = stopper.recv().or(timeout).await;
|
|
})
|
|
});
|
|
stop_timeout
|
|
};
|
|
|
|
let ex = Arc::new(Executor::new());
|
|
|
|
// Test 1: Use the `run` command.
|
|
block_on(ex.run(f(ex.clone())));
|
|
|
|
// Test 2: Loop on `tick`.
|
|
block_on(async {
|
|
let ticker = async {
|
|
loop {
|
|
ex.tick().await;
|
|
}
|
|
};
|
|
|
|
f(ex.clone()).or(ticker).await
|
|
});
|
|
|
|
// Test 3: Run on many threads.
|
|
thread::scope(|scope| {
|
|
let (_signal, shutdown) = async_channel::bounded::<()>(1);
|
|
|
|
for _ in 0..16 {
|
|
let shutdown = shutdown.clone();
|
|
let ex = &ex;
|
|
scope.spawn(move || block_on(ex.run(shutdown.recv())));
|
|
}
|
|
|
|
block_on(f(ex.clone()));
|
|
});
|
|
|
|
// Test 4: Tick loop on many threads.
|
|
thread::scope(|scope| {
|
|
let (_signal, shutdown) = async_channel::bounded::<()>(1);
|
|
|
|
for _ in 0..16 {
|
|
let shutdown = shutdown.clone();
|
|
let ex = &ex;
|
|
scope.spawn(move || {
|
|
block_on(async move {
|
|
let ticker = async {
|
|
loop {
|
|
ex.tick().await;
|
|
}
|
|
};
|
|
|
|
shutdown.recv().or(ticker).await
|
|
})
|
|
});
|
|
}
|
|
|
|
block_on(f(ex.clone()));
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn smoke() {
|
|
do_run(|ex| async move { ex.spawn(async {}).await });
|
|
}
|
|
|
|
#[test]
|
|
fn yield_now() {
|
|
do_run(|ex| async move { ex.spawn(future::yield_now()).await })
|
|
}
|
|
|
|
#[test]
|
|
fn timer() {
|
|
do_run(|ex| async move {
|
|
ex.spawn(async_io::Timer::after(Duration::from_millis(5)))
|
|
.await;
|
|
})
|
|
}
|