2020-02-06 02:59:45 +01:00
|
|
|
use std::time::{Duration, Instant};
|
|
|
|
|
2021-01-26 10:46:14 +01:00
|
|
|
use futures_util::future::try_join_all;
|
|
|
|
|
2020-02-06 02:59:45 +01:00
|
|
|
#[test]
|
|
|
|
fn await_for_timer() {
|
2021-01-26 10:46:14 +01:00
|
|
|
let time = Duration::from_secs(1);
|
2020-02-06 02:59:45 +01:00
|
|
|
let instant = Instant::now();
|
|
|
|
actix_rt::System::new("test_wait_timer").block_on(async move {
|
2020-12-28 02:40:22 +01:00
|
|
|
tokio::time::sleep(time).await;
|
2020-02-06 02:59:45 +01:00
|
|
|
});
|
|
|
|
assert!(
|
|
|
|
instant.elapsed() >= time,
|
|
|
|
"Block on should poll awaited future to completion"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn join_another_arbiter() {
|
2021-01-26 10:46:14 +01:00
|
|
|
let time = Duration::from_secs(1);
|
2020-02-06 02:59:45 +01:00
|
|
|
let instant = Instant::now();
|
|
|
|
actix_rt::System::new("test_join_another_arbiter").block_on(async move {
|
|
|
|
let mut arbiter = actix_rt::Arbiter::new();
|
|
|
|
arbiter.send(Box::pin(async move {
|
2020-12-28 02:40:22 +01:00
|
|
|
tokio::time::sleep(time).await;
|
2020-02-06 02:59:45 +01:00
|
|
|
actix_rt::Arbiter::current().stop();
|
|
|
|
}));
|
|
|
|
arbiter.join().unwrap();
|
|
|
|
});
|
|
|
|
assert!(
|
|
|
|
instant.elapsed() >= time,
|
|
|
|
"Join on another arbiter should complete only when it calls stop"
|
|
|
|
);
|
|
|
|
|
|
|
|
let instant = Instant::now();
|
|
|
|
actix_rt::System::new("test_join_another_arbiter").block_on(async move {
|
|
|
|
let mut arbiter = actix_rt::Arbiter::new();
|
|
|
|
arbiter.exec_fn(move || {
|
|
|
|
actix_rt::spawn(async move {
|
2020-12-28 02:40:22 +01:00
|
|
|
tokio::time::sleep(time).await;
|
2020-02-06 02:59:45 +01:00
|
|
|
actix_rt::Arbiter::current().stop();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
arbiter.join().unwrap();
|
|
|
|
});
|
|
|
|
assert!(
|
|
|
|
instant.elapsed() >= time,
|
|
|
|
"Join on a arbiter that has used actix_rt::spawn should wait for said future"
|
|
|
|
);
|
|
|
|
|
|
|
|
let instant = Instant::now();
|
|
|
|
actix_rt::System::new("test_join_another_arbiter").block_on(async move {
|
|
|
|
let mut arbiter = actix_rt::Arbiter::new();
|
|
|
|
arbiter.send(Box::pin(async move {
|
2020-12-28 02:40:22 +01:00
|
|
|
tokio::time::sleep(time).await;
|
2020-02-06 02:59:45 +01:00
|
|
|
actix_rt::Arbiter::current().stop();
|
|
|
|
}));
|
|
|
|
arbiter.stop();
|
|
|
|
arbiter.join().unwrap();
|
|
|
|
});
|
|
|
|
assert!(
|
|
|
|
instant.elapsed() < time,
|
|
|
|
"Premature stop of arbiter should conclude regardless of it's current state"
|
|
|
|
);
|
|
|
|
}
|
2020-02-06 04:36:00 +01:00
|
|
|
|
|
|
|
#[test]
|
2020-12-27 00:26:02 +01:00
|
|
|
fn non_static_block_on() {
|
|
|
|
let string = String::from("test_str");
|
|
|
|
let str = string.as_str();
|
2020-02-06 04:36:00 +01:00
|
|
|
|
2020-12-28 02:40:22 +01:00
|
|
|
let sys = actix_rt::System::new("borrow some");
|
2020-12-27 00:26:02 +01:00
|
|
|
|
|
|
|
sys.block_on(async {
|
2020-12-28 02:40:22 +01:00
|
|
|
actix_rt::time::sleep(Duration::from_millis(1)).await;
|
2020-12-27 00:26:02 +01:00
|
|
|
assert_eq!("test_str", str);
|
2020-02-06 04:36:00 +01:00
|
|
|
});
|
|
|
|
|
2020-12-28 02:40:22 +01:00
|
|
|
let rt = actix_rt::Runtime::new().unwrap();
|
2020-12-27 00:26:02 +01:00
|
|
|
|
|
|
|
rt.block_on(async {
|
2020-12-28 02:40:22 +01:00
|
|
|
actix_rt::time::sleep(Duration::from_millis(1)).await;
|
2020-12-27 00:26:02 +01:00
|
|
|
assert_eq!("test_str", str);
|
2020-02-06 04:36:00 +01:00
|
|
|
});
|
2020-12-27 00:26:02 +01:00
|
|
|
|
|
|
|
actix_rt::System::run(|| {
|
|
|
|
assert_eq!("test_str", str);
|
|
|
|
actix_rt::System::current().stop();
|
|
|
|
})
|
|
|
|
.unwrap();
|
2020-02-06 04:36:00 +01:00
|
|
|
}
|
2021-01-26 10:46:14 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn wait_for_spawns() {
|
|
|
|
let rt = actix_rt::Runtime::new().unwrap();
|
|
|
|
|
|
|
|
let handle = rt.spawn(async {
|
|
|
|
println!("running on the runtime");
|
|
|
|
// assertion panic is caught at task boundary
|
|
|
|
assert_eq!(1, 2);
|
|
|
|
});
|
|
|
|
|
|
|
|
assert!(rt.block_on(handle).is_err());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn run_in_existing_tokio() {
|
|
|
|
use actix_rt::System;
|
|
|
|
use futures_util::future::try_join_all;
|
|
|
|
use tokio::task::LocalSet;
|
|
|
|
|
|
|
|
async fn run_application() {
|
|
|
|
let first_task = tokio::spawn(async {
|
|
|
|
println!("One task");
|
|
|
|
Ok::<(), ()>(())
|
|
|
|
});
|
|
|
|
|
|
|
|
let second_task = tokio::spawn(async {
|
|
|
|
println!("Another task");
|
|
|
|
Ok::<(), ()>(())
|
|
|
|
});
|
|
|
|
|
|
|
|
try_join_all(vec![first_task, second_task])
|
|
|
|
.await
|
|
|
|
.expect("Some of the futures finished unexpectedly");
|
|
|
|
}
|
|
|
|
|
|
|
|
let runtime = tokio::runtime::Builder::new_multi_thread()
|
|
|
|
.worker_threads(2)
|
|
|
|
.enable_all()
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let actix_local_set = LocalSet::new();
|
|
|
|
let sys = System::run_in_tokio("actix-main-system", &actix_local_set);
|
|
|
|
actix_local_set.spawn_local(sys);
|
|
|
|
|
|
|
|
let rest_operations = run_application();
|
|
|
|
runtime.block_on(actix_local_set.run_until(rest_operations));
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn run_application() -> usize {
|
|
|
|
let first_task = tokio::spawn(async {
|
|
|
|
println!("One task");
|
|
|
|
Ok::<(), ()>(())
|
|
|
|
});
|
|
|
|
|
|
|
|
let second_task = tokio::spawn(async {
|
|
|
|
println!("Another task");
|
|
|
|
Ok::<(), ()>(())
|
|
|
|
});
|
|
|
|
|
|
|
|
let tasks = try_join_all(vec![first_task, second_task])
|
|
|
|
.await
|
|
|
|
.expect("Some of the futures finished unexpectedly");
|
|
|
|
|
|
|
|
tasks.len()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn attack_to_tokio() {
|
|
|
|
use actix_rt::System;
|
|
|
|
|
|
|
|
let runtime = tokio::runtime::Builder::new_multi_thread()
|
|
|
|
.worker_threads(2)
|
|
|
|
.enable_all()
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let rest_operations = run_application();
|
|
|
|
let res = System::attach_to_tokio("actix-main-system", runtime, rest_operations);
|
|
|
|
|
|
|
|
assert_eq!(res, 2);
|
|
|
|
}
|