Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+176
View File
@@ -0,0 +1,176 @@
use dever_runtime::{
channel::{Channel, Error},
task::{Limits, Runtime},
};
use std::{
future::{Future, poll_fn},
sync::{
Arc,
atomic::{AtomicUsize, Ordering},
},
task::Poll,
};
fn runtime() -> Runtime {
Runtime::new(Limits {
threads: 2,
workers: 1,
tasks: 8,
})
.unwrap()
}
async fn pending(future: std::pin::Pin<&mut impl Future>) {
let mut future = future;
poll_fn(|context| {
assert!(future.as_mut().poll(context).is_pending());
Poll::Ready(())
})
.await;
}
#[test]
fn capacity_is_bounded() {
for capacity in [-1, 0, 65537] {
assert!(matches!(
Channel::<i64>::new(capacity),
Err(Error::Capacity)
));
}
Channel::<i64>::new(1).unwrap();
Channel::<i64>::new(65536).unwrap();
}
#[test]
fn backpressure_preserves_fifo_and_nullable_items() {
runtime()
.run(async |_| {
let channel = Channel::new(1).unwrap();
channel.send(Some(1)).await.unwrap();
let mut sent = std::pin::pin!(channel.send(None));
pending(sent.as_mut()).await;
assert_eq!(channel.receive().await, Ok(Some(Some(1))));
sent.await.unwrap();
let alias = channel.clone();
alias.close().await.unwrap();
channel.close().await.unwrap();
assert_eq!(channel.receive().await, Ok(Some(None)));
assert_eq!(alias.receive().await, Ok(None));
})
.unwrap();
}
#[test]
fn close_wakes_senders_and_all_receivers_without_discarding_queued_values() {
runtime()
.run(async |_| {
let channel = Channel::new(1).unwrap();
channel.send(1).await.unwrap();
let mut sent = std::pin::pin!(channel.send(2));
pending(sent.as_mut()).await;
channel.close().await.unwrap();
assert_eq!(sent.await, Err(Error::Closed));
assert_eq!(channel.receive().await, Ok(Some(1)));
assert_eq!(channel.receive().await, Ok(None));
let empty = Channel::<i64>::new(1).unwrap();
let mut first = std::pin::pin!(empty.receive());
let mut second = std::pin::pin!(empty.receive());
pending(first.as_mut()).await;
pending(second.as_mut()).await;
empty.close().await.unwrap();
assert_eq!(first.await, Ok(None));
assert_eq!(second.await, Ok(None));
})
.unwrap();
}
#[test]
fn cancelling_waiters_returns_reserved_capacity_and_items() {
runtime()
.run(async |_| {
let channel = Channel::new(1).unwrap();
channel.send(1).await.unwrap();
{
let mut sent = std::pin::pin!(channel.send(2));
pending(sent.as_mut()).await;
assert_eq!(channel.receive().await, Ok(Some(1)));
}
channel.send(3).await.unwrap();
assert_eq!(channel.receive().await, Ok(Some(3)));
{
let mut received = std::pin::pin!(channel.receive());
pending(received.as_mut()).await;
channel.send(4).await.unwrap();
}
assert_eq!(channel.receive().await, Ok(Some(4)));
})
.unwrap();
}
#[test]
fn producers_and_consumers_transfer_every_item_once() {
runtime()
.run(async |scope| {
let channel = Channel::new(4).unwrap();
let mut producers = Vec::new();
let mut consumers = Vec::new();
for start in [0, 64] {
let sender = channel.clone();
producers.push(
scope
.spawn_leaf(move || async move {
for value in start..start + 64 {
sender.send(value).await.unwrap();
}
})
.unwrap(),
);
let channel = channel.clone();
consumers.push(
scope
.spawn_leaf(move || async move {
let mut values = Vec::new();
while let Some(value) = channel.receive().await.unwrap() {
values.push(value);
}
values
})
.unwrap(),
);
}
for task in producers {
task.wait().await.unwrap();
}
channel.close().await.unwrap();
let mut received = Vec::new();
for task in consumers {
received.extend(task.wait().await.unwrap());
}
received.sort();
assert_eq!(received, (0..128).collect::<Vec<_>>());
})
.unwrap();
}
struct Notice(Arc<AtomicUsize>);
impl Drop for Notice {
fn drop(&mut self) {
self.0.fetch_add(1, Ordering::SeqCst);
}
}
#[test]
fn last_alias_releases_nonclone_messages_once() {
let drops = Arc::new(AtomicUsize::new(0));
runtime()
.run(async |_| {
let channel = Channel::new(1).unwrap();
channel.send(Notice(drops.clone())).await.unwrap();
let alias = channel.clone();
drop(channel);
assert_eq!(drops.load(Ordering::SeqCst), 0);
drop(alias);
assert_eq!(drops.load(Ordering::SeqCst), 1);
})
.unwrap();
}