Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,159 @@
|
||||
use super::{DropNotice, runtime};
|
||||
use dever_runtime::task::{Error, Timed};
|
||||
use std::{
|
||||
future::{Future, poll_fn},
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
},
|
||||
task::Poll,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn dropped_stop_wait_keeps_started_work_tracked() {
|
||||
let finished = Arc::new(AtomicBool::new(false));
|
||||
let observed = finished.clone();
|
||||
let runtime = runtime();
|
||||
runtime
|
||||
.run(async |scope| {
|
||||
let (started, ready) = tokio::sync::oneshot::channel();
|
||||
let (release, blocked) = std::sync::mpsc::channel();
|
||||
let task = scope
|
||||
.spawn_sync(move || {
|
||||
started.send(()).unwrap();
|
||||
blocked.recv_timeout(Duration::from_secs(2)).unwrap();
|
||||
finished.store(true, Ordering::SeqCst);
|
||||
})
|
||||
.unwrap();
|
||||
ready.await.unwrap();
|
||||
{
|
||||
let mut stopped = std::pin::pin!(task.stop());
|
||||
poll_fn(|context| {
|
||||
assert!(stopped.as_mut().poll(context).is_pending());
|
||||
Poll::Ready(())
|
||||
})
|
||||
.await;
|
||||
}
|
||||
assert!(!observed.load(Ordering::SeqCst));
|
||||
release.send(()).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
assert!(observed.load(Ordering::SeqCst));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nullable_and_unit_results_are_completions_not_expirations() {
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let nullable = scope.spawn_leaf(|| async { None::<i64> }).unwrap();
|
||||
assert!(matches!(
|
||||
nullable.timeout(10000).await.unwrap(),
|
||||
Timed::Ready(None)
|
||||
));
|
||||
let unit = scope.spawn_leaf(|| async {}).unwrap();
|
||||
assert!(matches!(
|
||||
unit.timeout(10000).await.unwrap(),
|
||||
Timed::Ready(())
|
||||
));
|
||||
let failed = scope
|
||||
.spawn_leaf(|| async { Err::<i64, _>("original") })
|
||||
.unwrap();
|
||||
assert!(matches!(
|
||||
failed.timeout(10000).await.unwrap(),
|
||||
Timed::Ready(Err("original"))
|
||||
));
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expiration_and_invalid_duration_wait_for_captured_resources() {
|
||||
for duration in [-1, 0, 1] {
|
||||
let dropped = Arc::new(AtomicBool::new(false));
|
||||
let observed = dropped.clone();
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let (started, ready) = tokio::sync::oneshot::channel();
|
||||
let owner = DropNotice(dropped);
|
||||
let pending = scope
|
||||
.spawn_leaf(move || async move {
|
||||
let _owner = owner;
|
||||
started.send(()).unwrap();
|
||||
std::future::pending::<()>().await;
|
||||
})
|
||||
.unwrap();
|
||||
ready.await.unwrap();
|
||||
let result = pending.timeout(duration).await;
|
||||
if duration > 0 {
|
||||
assert!(matches!(result, Ok(Timed::Expired(None))));
|
||||
} else {
|
||||
assert!(matches!(result, Err(Error::InvalidTimeout)));
|
||||
}
|
||||
assert!(observed.load(Ordering::SeqCst));
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expiration_preserves_a_late_failure_from_started_blocking_work() {
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let (started, ready) = tokio::sync::oneshot::channel();
|
||||
let (release, blocked) = std::sync::mpsc::channel();
|
||||
let pending = scope
|
||||
.spawn_sync(move || {
|
||||
started.send(()).unwrap();
|
||||
blocked.recv_timeout(Duration::from_secs(2)).unwrap();
|
||||
Err::<i64, _>("late failure")
|
||||
})
|
||||
.unwrap();
|
||||
ready.await.unwrap();
|
||||
let mut timed = std::pin::pin!(pending.timeout(1));
|
||||
poll_fn(|context| {
|
||||
assert!(timed.as_mut().poll(context).is_pending());
|
||||
Poll::Ready(())
|
||||
})
|
||||
.await;
|
||||
tokio::time::sleep(Duration::from_millis(10)).await;
|
||||
poll_fn(|context| {
|
||||
assert!(timed.as_mut().poll(context).is_pending());
|
||||
Poll::Ready(())
|
||||
})
|
||||
.await;
|
||||
release.send(()).unwrap();
|
||||
assert!(matches!(
|
||||
timed.await.unwrap(),
|
||||
Timed::Expired(Some(Err("late failure")))
|
||||
));
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cancelling_a_timeout_wait_drains_the_nested_task() {
|
||||
let dropped = Arc::new(AtomicBool::new(false));
|
||||
let observed = dropped.clone();
|
||||
let (started, ready) = tokio::sync::oneshot::channel();
|
||||
runtime()
|
||||
.run(async |scope| {
|
||||
let parent = scope
|
||||
.spawn(move |child| async move {
|
||||
let owner = DropNotice(dropped);
|
||||
let pending = child
|
||||
.spawn_leaf(move || async move {
|
||||
let _owner = owner;
|
||||
started.send(()).unwrap();
|
||||
std::future::pending::<()>().await;
|
||||
})
|
||||
.unwrap();
|
||||
pending.timeout(60000).await.unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
ready.await.unwrap();
|
||||
assert!(parent.stop().await.unwrap().is_none());
|
||||
assert!(observed.load(Ordering::SeqCst));
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
Reference in new issue
Block a user