Initial vendor packages

Signed-off-by: Valentin Popov <valentin@popov.link>
This commit is contained in:
2024-01-08 01:21:28 +04:00
parent 5ecd8cf2cb
commit 1b6a04ca55
7309 changed files with 2160054 additions and 0 deletions

339
vendor/flume/tests/after.rs vendored Normal file
View File

@ -0,0 +1,339 @@
// //! Tests for the after channel flavor.
// #[macro_use]
// extern crate crossbeam_channel;
// extern crate crossbeam_utils;
// extern crate rand;
// use std::sync::atomic::AtomicUsize;
// use std::sync::atomic::Ordering;
// use std::thread;
// use std::time::{Duration, Instant};
// use crossbeam_channel::{after, Select, TryRecvError};
// use crossbeam_utils::thread::scope;
// fn ms(ms: u64) -> Duration {
// Duration::from_millis(ms)
// }
// #[test]
// fn fire() {
// let start = Instant::now();
// let r = after(ms(50));
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// thread::sleep(ms(100));
// let fired = r.try_recv().unwrap();
// assert!(start < fired);
// assert!(fired - start >= ms(50));
// let now = Instant::now();
// assert!(fired < now);
// assert!(now - fired >= ms(50));
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// select! {
// recv(r) -> _ => panic!(),
// default => {}
// }
// select! {
// recv(r) -> _ => panic!(),
// recv(after(ms(200))) -> _ => {}
// }
// }
// #[test]
// fn capacity() {
// const COUNT: usize = 10;
// for i in 0..COUNT {
// let r = after(ms(i as u64));
// assert_eq!(r.capacity(), Some(1));
// }
// }
// #[test]
// fn len_empty_full() {
// let r = after(ms(50));
// assert_eq!(r.len(), 0);
// assert_eq!(r.is_empty(), true);
// assert_eq!(r.is_full(), false);
// thread::sleep(ms(100));
// assert_eq!(r.len(), 1);
// assert_eq!(r.is_empty(), false);
// assert_eq!(r.is_full(), true);
// r.try_recv().unwrap();
// assert_eq!(r.len(), 0);
// assert_eq!(r.is_empty(), true);
// assert_eq!(r.is_full(), false);
// }
// #[test]
// fn try_recv() {
// let r = after(ms(200));
// assert!(r.try_recv().is_err());
// thread::sleep(ms(100));
// assert!(r.try_recv().is_err());
// thread::sleep(ms(200));
// assert!(r.try_recv().is_ok());
// assert!(r.try_recv().is_err());
// thread::sleep(ms(200));
// assert!(r.try_recv().is_err());
// }
// #[test]
// fn recv() {
// let start = Instant::now();
// let r = after(ms(50));
// let fired = r.recv().unwrap();
// assert!(start < fired);
// assert!(fired - start >= ms(50));
// let now = Instant::now();
// assert!(fired < now);
// assert!(now - fired < fired - start);
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// }
// #[test]
// fn recv_timeout() {
// let start = Instant::now();
// let r = after(ms(200));
// assert!(r.recv_timeout(ms(100)).is_err());
// let now = Instant::now();
// assert!(now - start >= ms(100));
// assert!(now - start <= ms(150));
// let fired = r.recv_timeout(ms(200)).unwrap();
// assert!(fired - start >= ms(200));
// assert!(fired - start <= ms(250));
// assert!(r.recv_timeout(ms(200)).is_err());
// let now = Instant::now();
// assert!(now - start >= ms(400));
// assert!(now - start <= ms(450));
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// }
// #[test]
// fn recv_two() {
// let r1 = after(ms(50));
// let r2 = after(ms(50));
// scope(|scope| {
// scope.spawn(|_| {
// select! {
// recv(r1) -> _ => {}
// recv(r2) -> _ => {}
// }
// });
// scope.spawn(|_| {
// select! {
// recv(r1) -> _ => {}
// recv(r2) -> _ => {}
// }
// });
// })
// .unwrap();
// }
// #[test]
// fn recv_race() {
// select! {
// recv(after(ms(50))) -> _ => {}
// recv(after(ms(100))) -> _ => panic!(),
// }
// select! {
// recv(after(ms(100))) -> _ => panic!(),
// recv(after(ms(50))) -> _ => {}
// }
// }
// #[test]
// fn stress_default() {
// const COUNT: usize = 10;
// for _ in 0..COUNT {
// select! {
// recv(after(ms(0))) -> _ => {}
// default => panic!(),
// }
// }
// for _ in 0..COUNT {
// select! {
// recv(after(ms(100))) -> _ => panic!(),
// default => {}
// }
// }
// }
// #[test]
// fn select() {
// const THREADS: usize = 4;
// const COUNT: usize = 1000;
// const TIMEOUT_MS: u64 = 100;
// let v = (0..COUNT)
// .map(|i| after(ms(i as u64 / TIMEOUT_MS / 2)))
// .collect::<Vec<_>>();
// let hits = AtomicUsize::new(0);
// scope(|scope| {
// for _ in 0..THREADS {
// scope.spawn(|_| {
// let v: Vec<&_> = v.iter().collect();
// loop {
// let timeout = after(ms(TIMEOUT_MS));
// let mut sel = Select::new();
// for r in &v {
// sel.recv(r);
// }
// let oper_timeout = sel.recv(&timeout);
// let oper = sel.select();
// match oper.index() {
// i if i == oper_timeout => {
// oper.recv(&timeout).unwrap();
// break;
// }
// i => {
// oper.recv(&v[i]).unwrap();
// hits.fetch_add(1, Ordering::SeqCst);
// }
// }
// }
// });
// }
// })
// .unwrap();
// assert_eq!(hits.load(Ordering::SeqCst), COUNT);
// }
// #[test]
// fn ready() {
// const THREADS: usize = 4;
// const COUNT: usize = 1000;
// const TIMEOUT_MS: u64 = 100;
// let v = (0..COUNT)
// .map(|i| after(ms(i as u64 / TIMEOUT_MS / 2)))
// .collect::<Vec<_>>();
// let hits = AtomicUsize::new(0);
// scope(|scope| {
// for _ in 0..THREADS {
// scope.spawn(|_| {
// let v: Vec<&_> = v.iter().collect();
// loop {
// let timeout = after(ms(TIMEOUT_MS));
// let mut sel = Select::new();
// for r in &v {
// sel.recv(r);
// }
// let oper_timeout = sel.recv(&timeout);
// loop {
// let i = sel.ready();
// if i == oper_timeout {
// timeout.try_recv().unwrap();
// return;
// } else if v[i].try_recv().is_ok() {
// hits.fetch_add(1, Ordering::SeqCst);
// break;
// }
// }
// }
// });
// }
// })
// .unwrap();
// assert_eq!(hits.load(Ordering::SeqCst), COUNT);
// }
// #[test]
// fn stress_clone() {
// const RUNS: usize = 1000;
// const THREADS: usize = 10;
// const COUNT: usize = 50;
// for i in 0..RUNS {
// let r = after(ms(i as u64));
// scope(|scope| {
// for _ in 0..THREADS {
// scope.spawn(|_| {
// let r = r.clone();
// let _ = r.try_recv();
// for _ in 0..COUNT {
// drop(r.clone());
// thread::yield_now();
// }
// });
// }
// })
// .unwrap();
// }
// }
// #[test]
// fn fairness() {
// const COUNT: usize = 1000;
// for &dur in &[0, 1] {
// let mut hits = [0usize; 2];
// for _ in 0..COUNT {
// select! {
// recv(after(ms(dur))) -> _ => hits[0] += 1,
// recv(after(ms(dur))) -> _ => hits[1] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// }
// #[test]
// fn fairness_duplicates() {
// const COUNT: usize = 1000;
// for &dur in &[0, 1] {
// let mut hits = [0usize; 5];
// for _ in 0..COUNT {
// let r = after(ms(dur));
// select! {
// recv(r) -> _ => hits[0] += 1,
// recv(r) -> _ => hits[1] += 1,
// recv(r) -> _ => hits[2] += 1,
// recv(r) -> _ => hits[3] += 1,
// recv(r) -> _ => hits[4] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// }

657
vendor/flume/tests/array.rs vendored Normal file
View File

@ -0,0 +1,657 @@
//! Tests for the array channel flavor.
extern crate crossbeam_utils;
extern crate rand;
use std::any::Any;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::Duration;
use flume::{bounded, Receiver};
use flume::{RecvError, RecvTimeoutError, TryRecvError};
use flume::{SendError, SendTimeoutError, TrySendError};
use crossbeam_utils::thread::scope;
use rand::{thread_rng, Rng};
fn ms(ms: u64) -> Duration {
Duration::from_millis(ms)
}
#[test]
fn smoke() {
let (s, r) = bounded(1);
s.send(7).unwrap();
assert_eq!(r.try_recv(), Ok(7));
s.send(8).unwrap();
assert_eq!(r.recv(), Ok(8));
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout));
}
#[test]
fn capacity() {
for i in 1..10 {
let (s, r) = bounded::<()>(i);
assert_eq!(s.capacity(), Some(i));
assert_eq!(r.capacity(), Some(i));
}
}
#[test]
fn len_empty_full() {
let (s, r) = bounded(2);
assert_eq!(s.len(), 0);
assert_eq!(s.is_empty(), true);
assert_eq!(s.is_full(), false);
assert_eq!(r.len(), 0);
assert_eq!(r.is_empty(), true);
assert_eq!(r.is_full(), false);
s.send(()).unwrap();
assert_eq!(s.len(), 1);
assert_eq!(s.is_empty(), false);
assert_eq!(s.is_full(), false);
assert_eq!(r.len(), 1);
assert_eq!(r.is_empty(), false);
assert_eq!(r.is_full(), false);
s.send(()).unwrap();
assert_eq!(s.len(), 2);
assert_eq!(s.is_empty(), false);
assert_eq!(s.is_full(), true);
assert_eq!(r.len(), 2);
assert_eq!(r.is_empty(), false);
assert_eq!(r.is_full(), true);
r.recv().unwrap();
assert_eq!(s.len(), 1);
assert_eq!(s.is_empty(), false);
assert_eq!(s.is_full(), false);
assert_eq!(r.len(), 1);
assert_eq!(r.is_empty(), false);
assert_eq!(r.is_full(), false);
}
#[test]
fn try_recv() {
let (s, r) = bounded(100);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
thread::sleep(ms(1500));
assert_eq!(r.try_recv(), Ok(7));
thread::sleep(ms(500));
assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
s.send(7).unwrap();
});
})
.unwrap();
}
#[test]
fn recv() {
let (s, r) = bounded(100);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.recv(), Ok(7));
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(8));
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(9));
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
s.send(7).unwrap();
s.send(8).unwrap();
s.send(9).unwrap();
});
})
.unwrap();
}
#[test]
fn recv_timeout() {
let (s, r) = bounded::<i32>(100);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout));
assert_eq!(r.recv_timeout(ms(1000)), Ok(7));
assert_eq!(
r.recv_timeout(ms(1000)),
Err(RecvTimeoutError::Disconnected)
);
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
s.send(7).unwrap();
});
})
.unwrap();
}
#[test]
fn try_send() {
let (s, r) = bounded(1);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(s.try_send(1), Ok(()));
assert_eq!(s.try_send(2), Err(TrySendError::Full(2)));
thread::sleep(ms(1500));
assert_eq!(s.try_send(3), Ok(()));
thread::sleep(ms(500));
assert_eq!(s.try_send(4), Err(TrySendError::Disconnected(4)));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
assert_eq!(r.try_recv(), Ok(1));
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
assert_eq!(r.recv(), Ok(3));
});
})
.unwrap();
}
#[test]
fn send() {
let (s, r) = bounded(1);
scope(|scope| {
scope.spawn(|_| {
s.send(7).unwrap();
thread::sleep(ms(1000));
s.send(8).unwrap();
thread::sleep(ms(1000));
s.send(9).unwrap();
thread::sleep(ms(1000));
s.send(10).unwrap();
});
scope.spawn(|_| {
thread::sleep(ms(1500));
assert_eq!(r.recv(), Ok(7));
assert_eq!(r.recv(), Ok(8));
assert_eq!(r.recv(), Ok(9));
});
})
.unwrap();
}
#[test]
fn send_timeout() {
let (s, r) = bounded(2);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(s.send_timeout(1, ms(1000)), Ok(()));
assert_eq!(s.send_timeout(2, ms(1000)), Ok(()));
assert_eq!(
s.send_timeout(3, ms(500)),
Err(SendTimeoutError::Timeout(3))
);
thread::sleep(ms(1000));
assert_eq!(s.send_timeout(4, ms(1000)), Ok(()));
thread::sleep(ms(1000));
assert_eq!(s.send(5), Err(SendError(5)));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(1));
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(2));
assert_eq!(r.recv(), Ok(4));
});
})
.unwrap();
}
#[test]
fn send_after_disconnect() {
let (s, r) = bounded(100);
s.send(1).unwrap();
s.send(2).unwrap();
s.send(3).unwrap();
drop(r);
assert_eq!(s.send(4), Err(SendError(4)));
assert_eq!(s.try_send(5), Err(TrySendError::Disconnected(5)));
assert_eq!(
s.send_timeout(6, ms(500)),
Err(SendTimeoutError::Disconnected(6))
);
}
#[test]
fn recv_after_disconnect() {
let (s, r) = bounded(100);
s.send(1).unwrap();
s.send(2).unwrap();
s.send(3).unwrap();
drop(s);
assert_eq!(r.recv(), Ok(1));
assert_eq!(r.recv(), Ok(2));
assert_eq!(r.recv(), Ok(3));
assert!(r.recv().is_err());
}
#[test]
fn len() {
const COUNT: usize = 25_000;
const CAP: usize = 1000;
let (s, r) = bounded(CAP);
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
for _ in 0..CAP / 10 {
for i in 0..50 {
s.send(i).unwrap();
assert_eq!(s.len(), i + 1);
}
for i in 0..50 {
r.recv().unwrap();
assert_eq!(r.len(), 50 - i - 1);
}
}
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
for i in 0..CAP {
s.send(i).unwrap();
assert_eq!(s.len(), i + 1);
}
for _ in 0..CAP {
r.recv().unwrap();
}
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
scope(|scope| {
scope.spawn(|_| {
for i in 0..COUNT {
assert_eq!(r.recv(), Ok(i));
let len = r.len();
assert!(len <= CAP);
}
});
scope.spawn(|_| {
for i in 0..COUNT {
s.send(i).unwrap();
let len = s.len();
assert!(len <= CAP);
}
});
})
.unwrap();
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
}
#[test]
fn disconnect_wakes_sender() {
let (s, r) = bounded(1);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(s.send(()), Ok(()));
assert_eq!(s.send(()), Err(SendError(())));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
drop(r);
});
})
.unwrap();
}
#[test]
fn disconnect_wakes_receiver() {
let (s, r) = bounded::<()>(1);
scope(|scope| {
scope.spawn(move |_| {
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
drop(s);
});
})
.unwrap();
}
#[test]
fn spsc() {
const COUNT: usize = 100_000;
let (s, r) = bounded(3);
scope(|scope| {
scope.spawn(move |_| {
for i in 0..COUNT {
assert_eq!(r.recv(), Ok(i));
}
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
for i in 0..COUNT {
s.send(i).unwrap();
}
});
})
.unwrap();
}
#[test]
fn mpmc() {
const COUNT: usize = 25_000;
const THREADS: usize = 4;
let (s, r) = bounded::<usize>(3);
let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
scope(|scope| {
for _ in 0..THREADS {
scope.spawn(|_| {
for _ in 0..COUNT {
let n = r.recv().unwrap();
v[n].fetch_add(1, Ordering::SeqCst);
}
});
}
for _ in 0..THREADS {
scope.spawn(|_| {
for i in 0..COUNT {
s.send(i).unwrap();
}
});
}
})
.unwrap();
for c in v {
assert_eq!(c.load(Ordering::SeqCst), THREADS);
}
}
#[test]
fn stress_oneshot() {
const COUNT: usize = 10_000;
for _ in 0..COUNT {
let (s, r) = bounded(1);
scope(|scope| {
scope.spawn(|_| r.recv().unwrap());
scope.spawn(|_| s.send(0).unwrap());
})
.unwrap();
}
}
#[test]
fn stress_iter() {
const COUNT: usize = 100_000;
let (request_s, request_r) = bounded(1);
let (response_s, response_r) = bounded(1);
scope(|scope| {
scope.spawn(move |_| {
let mut count = 0;
loop {
for x in response_r.try_iter() {
count += x;
if count == COUNT {
return;
}
}
request_s.send(()).unwrap();
}
});
for _ in request_r.iter() {
if response_s.send(1).is_err() {
break;
}
}
})
.unwrap();
}
#[test]
fn stress_timeout_two_threads() {
const COUNT: usize = 100;
let (s, r) = bounded(2);
scope(|scope| {
scope.spawn(|_| {
for i in 0..COUNT {
if i % 2 == 0 {
thread::sleep(ms(50));
}
loop {
if let Ok(()) = s.send_timeout(i, ms(10)) {
break;
}
}
}
});
scope.spawn(|_| {
for i in 0..COUNT {
if i % 2 == 0 {
thread::sleep(ms(50));
}
loop {
if let Ok(x) = r.recv_timeout(ms(10)) {
assert_eq!(x, i);
break;
}
}
}
});
})
.unwrap();
}
#[test]
fn drops() {
const RUNS: usize = 100;
static DROPS: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, PartialEq)]
struct DropCounter;
impl Drop for DropCounter {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
}
}
let mut rng = thread_rng();
for _ in 0..RUNS {
let steps = rng.gen_range(0..10_000);
let additional = rng.gen_range(0..50);
DROPS.store(0, Ordering::SeqCst);
let (s, r) = bounded::<DropCounter>(50);
scope(|scope| {
scope.spawn(|_| {
for _ in 0..steps {
r.recv().unwrap();
}
});
scope.spawn(|_| {
for _ in 0..steps {
s.send(DropCounter).unwrap();
}
});
})
.unwrap();
for _ in 0..additional {
s.send(DropCounter).unwrap();
}
assert_eq!(DROPS.load(Ordering::SeqCst), steps);
drop(s);
drop(r);
assert_eq!(DROPS.load(Ordering::SeqCst), steps + additional);
}
}
#[test]
fn linearizable() {
const COUNT: usize = 25_000;
const THREADS: usize = 4;
let (s, r) = bounded(THREADS);
scope(|scope| {
for _ in 0..THREADS {
scope.spawn(|_| {
for _ in 0..COUNT {
s.send(0).unwrap();
r.try_recv().unwrap();
}
});
}
})
.unwrap();
}
// #[test]
// fn fairness() {
// const COUNT: usize = 10_000;
// let (s1, r1) = bounded::<()>(COUNT);
// let (s2, r2) = bounded::<()>(COUNT);
// for _ in 0..COUNT {
// s1.send(()).unwrap();
// s2.send(()).unwrap();
// }
// let mut hits = [0usize; 2];
// for _ in 0..COUNT {
// select! {
// recv(r1) -> _ => hits[0] += 1,
// recv(r2) -> _ => hits[1] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// #[test]
// fn fairness_duplicates() {
// const COUNT: usize = 10_000;
// let (s, r) = bounded::<()>(COUNT);
// for _ in 0..COUNT {
// s.send(()).unwrap();
// }
// let mut hits = [0usize; 5];
// for _ in 0..COUNT {
// select! {
// recv(r) -> _ => hits[0] += 1,
// recv(r) -> _ => hits[1] += 1,
// recv(r) -> _ => hits[2] += 1,
// recv(r) -> _ => hits[3] += 1,
// recv(r) -> _ => hits[4] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// #[test]
// fn recv_in_send() {
// let (s, _r) = bounded(1);
// s.send(()).unwrap();
// #[allow(unreachable_code)]
// {
// select! {
// send(s, panic!()) -> _ => panic!(),
// default => {}
// }
// }
// let (s, r) = bounded(2);
// s.send(()).unwrap();
// select! {
// send(s, assert_eq!(r.recv(), Ok(()))) -> _ => {}
// }
// }
#[test]
fn channel_through_channel() {
const COUNT: usize = 1000;
type T = Box<dyn Any + Send>;
let (s, r) = bounded::<T>(1);
scope(|scope| {
scope.spawn(move |_| {
let mut s = s;
for _ in 0..COUNT {
let (new_s, new_r) = bounded(1);
let new_r: T = Box::new(Some(new_r));
s.send(new_r).unwrap();
s = new_s;
}
});
scope.spawn(move |_| {
let mut r = r;
for _ in 0..COUNT {
r = r
.recv()
.unwrap()
.downcast_mut::<Option<Receiver<T>>>()
.unwrap()
.take()
.unwrap()
}
});
})
.unwrap();
}

276
vendor/flume/tests/async.rs vendored Normal file
View File

@ -0,0 +1,276 @@
#[cfg(feature = "async")]
use {
flume::*,
futures::{stream::FuturesUnordered, StreamExt, TryFutureExt, Future},
futures::task::{Context, Waker, Poll},
async_std::prelude::FutureExt,
std::{time::Duration, sync::{atomic::{AtomicUsize, Ordering}, Arc}},
};
#[cfg(feature = "async")]
#[test]
fn r#async_recv() {
let (tx, rx) = unbounded();
let t = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(250));
tx.send(42u32).unwrap();
});
async_std::task::block_on(async {
assert_eq!(rx.recv_async().await.unwrap(), 42);
});
t.join().unwrap();
}
#[cfg(feature = "async")]
#[test]
fn r#async_send() {
let (tx, rx) = bounded(1);
let t = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(250));
assert_eq!(rx.recv(), Ok(42));
});
async_std::task::block_on(async {
tx.send_async(42u32).await.unwrap();
});
t.join().unwrap();
}
#[cfg(feature = "async")]
#[test]
fn r#async_recv_disconnect() {
let (tx, rx) = bounded::<i32>(0);
let t = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(250));
drop(tx)
});
async_std::task::block_on(async {
assert_eq!(rx.recv_async().await, Err(RecvError::Disconnected));
});
t.join().unwrap();
}
#[cfg(feature = "async")]
#[test]
fn r#async_send_disconnect() {
let (tx, rx) = bounded(0);
let t = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(250));
drop(rx)
});
async_std::task::block_on(async {
assert_eq!(tx.send_async(42u32).await, Err(SendError(42)));
});
t.join().unwrap();
}
#[cfg(feature = "async")]
#[test]
fn r#async_recv_drop_recv() {
let (tx, rx) = bounded::<i32>(10);
let recv_fut = rx.recv_async();
async_std::task::block_on(async {
let res = async_std::future::timeout(std::time::Duration::from_millis(500), rx.recv_async()).await;
assert!(res.is_err());
});
let rx2 = rx.clone();
let t = std::thread::spawn(move || {
async_std::task::block_on(async {
rx2.recv_async().await
})
});
std::thread::sleep(std::time::Duration::from_millis(500));
tx.send(42).unwrap();
drop(recv_fut);
assert_eq!(t.join().unwrap(), Ok(42))
}
#[cfg(feature = "async")]
#[async_std::test]
async fn r#async_send_1_million_no_drop_or_reorder() {
#[derive(Debug)]
enum Message {
Increment {
old: u64,
},
ReturnCount,
}
let (tx, rx) = unbounded();
let t = async_std::task::spawn(async move {
let mut count = 0u64;
while let Ok(Message::Increment { old }) = rx.recv_async().await {
assert_eq!(old, count);
count += 1;
}
count
});
for next in 0..1_000_000 {
tx.send(Message::Increment { old: next }).unwrap();
}
tx.send(Message::ReturnCount).unwrap();
let count = t.await;
assert_eq!(count, 1_000_000)
}
#[cfg(feature = "async")]
#[async_std::test]
async fn parallel_async_receivers() {
let (tx, rx) = flume::unbounded();
let send_fut = async move {
let n_sends: usize = 100000;
for _ in 0..n_sends {
tx.send_async(()).await.unwrap();
}
};
async_std::task::spawn(
send_fut
.timeout(Duration::from_secs(5))
.map_err(|_| panic!("Send timed out!"))
);
let mut futures_unordered = (0..250)
.map(|_| async {
while let Ok(()) = rx.recv_async().await
/* rx.recv() is OK */
{}
})
.collect::<FuturesUnordered<_>>();
let recv_fut = async {
while futures_unordered.next().await.is_some() {}
};
recv_fut
.timeout(Duration::from_secs(5))
.map_err(|_| panic!("Receive timed out!"))
.await
.unwrap();
println!("recv end");
}
#[cfg(feature = "async")]
#[test]
fn change_waker() {
let (tx, rx) = flume::bounded(1);
tx.send(()).unwrap();
struct DebugWaker(Arc<AtomicUsize>, Waker);
impl DebugWaker {
fn new() -> Self {
let woken = Arc::new(AtomicUsize::new(0));
let woken_cloned = woken.clone();
let waker = waker_fn::waker_fn(move || {
woken.fetch_add(1, Ordering::SeqCst);
});
DebugWaker(woken_cloned, waker)
}
fn woken(&self) -> usize {
self.0.load(Ordering::SeqCst)
}
fn ctx(&self) -> Context {
Context::from_waker(&self.1)
}
}
// Check that the waker is correctly updated when sending tasks change their wakers
{
let send_fut = tx.send_async(());
futures::pin_mut!(send_fut);
let (waker1, waker2) = (DebugWaker::new(), DebugWaker::new());
// Set the waker to waker1
assert_eq!(send_fut.as_mut().poll(&mut waker1.ctx()), Poll::Pending);
// Change the waker to waker2
assert_eq!(send_fut.poll(&mut waker2.ctx()), Poll::Pending);
// Wake the future
rx.recv().unwrap();
// Check that waker2 was woken and waker1 was not
assert_eq!(waker1.woken(), 0);
assert_eq!(waker2.woken(), 1);
}
// Check that the waker is correctly updated when receiving tasks change their wakers
{
rx.recv().unwrap();
let recv_fut = rx.recv_async();
futures::pin_mut!(recv_fut);
let (waker1, waker2) = (DebugWaker::new(), DebugWaker::new());
// Set the waker to waker1
assert_eq!(recv_fut.as_mut().poll(&mut waker1.ctx()), Poll::Pending);
// Change the waker to waker2
assert_eq!(recv_fut.poll(&mut waker2.ctx()), Poll::Pending);
// Wake the future
tx.send(()).unwrap();
// Check that waker2 was woken and waker1 was not
assert_eq!(waker1.woken(), 0);
assert_eq!(waker2.woken(), 1);
}
}
#[cfg(feature = "async")]
#[test]
fn spsc_single_threaded_value_ordering() {
async fn test() {
let (tx, rx) = flume::bounded(4);
tokio::select! {
_ = producer(tx) => {},
_ = consumer(rx) => {},
}
}
async fn producer(tx: flume::Sender<usize>) {
for i in 0..100 {
tx.send_async(i).await.unwrap();
}
}
async fn consumer(rx: flume::Receiver<usize>) {
let mut expected = 0;
while let Ok(value) = rx.recv_async().await {
assert_eq!(value, expected);
expected += 1;
}
}
let rt = tokio::runtime::Builder::new_current_thread().build().unwrap();
rt.block_on(test());
}

428
vendor/flume/tests/basic.rs vendored Normal file
View File

@ -0,0 +1,428 @@
use std::time::{Instant, Duration};
use flume::*;
#[test]
fn send_recv() {
let (tx, rx) = unbounded();
for i in 0..1000 { tx.send(i).unwrap(); }
for i in 0..1000 { assert_eq!(rx.try_recv().unwrap(), i); }
assert!(rx.try_recv().is_err());
}
#[test]
fn iter() {
let (tx, rx) = unbounded();
for i in 0..1000 { tx.send(i).unwrap(); }
drop(tx);
assert_eq!(rx.iter().sum::<u32>(), (0..1000).sum());
}
#[test]
fn try_iter() {
let (tx, rx) = unbounded();
for i in 0..1000 { tx.send(i).unwrap(); }
assert_eq!(rx.try_iter().sum::<u32>(), (0..1000).sum());
}
#[test]
fn iter_threaded() {
let (tx, rx) = unbounded();
for i in 0..1000 {
let tx = tx.clone();
std::thread::spawn(move || tx.send(i).unwrap());
}
drop(tx);
assert_eq!(rx.iter().sum::<u32>(), (0..1000).sum());
}
#[cfg_attr(any(target_os = "macos", windows), ignore)] // FIXME #41
#[test]
fn send_timeout() {
let dur = Duration::from_millis(350);
let max_error = Duration::from_millis(5);
let dur_min = dur.checked_sub(max_error).unwrap();
let dur_max = dur.checked_add(max_error).unwrap();
let (tx, rx) = bounded(1);
assert!(tx.send_timeout(42, dur).is_ok());
let then = Instant::now();
assert!(tx.send_timeout(43, dur).is_err());
let now = Instant::now();
let this = now.duration_since(then);
if !(dur_min < this && this < dur_max) {
panic!("timeout exceeded: {:?}", this);
}
assert_eq!(rx.drain().count(), 1);
drop(rx);
assert!(tx.send_timeout(42, Duration::from_millis(350)).is_err());
}
#[cfg_attr(any(target_os = "macos", windows), ignore)] // FIXME #41
#[test]
fn recv_timeout() {
let dur = Duration::from_millis(350);
let max_error = Duration::from_millis(5);
let dur_min = dur.checked_sub(max_error).unwrap();
let dur_max = dur.checked_add(max_error).unwrap();
let (tx, rx) = unbounded();
let then = Instant::now();
assert!(rx.recv_timeout(dur).is_err());
let now = Instant::now();
let this = now.duration_since(then);
if !(dur_min < this && this < dur_max) {
panic!("timeout exceeded: {:?}", this);
}
tx.send(42).unwrap();
assert_eq!(rx.recv_timeout(dur), Ok(42));
assert!(Instant::now().duration_since(now) < max_error);
}
#[cfg_attr(any(target_os = "macos", windows), ignore)] // FIXME #41
#[test]
fn recv_deadline() {
let dur = Duration::from_millis(350);
let max_error = Duration::from_millis(5);
let dur_min = dur.checked_sub(max_error).unwrap();
let dur_max = dur.checked_add(max_error).unwrap();
let (tx, rx) = unbounded();
let then = Instant::now();
assert!(rx.recv_deadline(then.checked_add(dur).unwrap()).is_err());
let now = Instant::now();
let this = now.duration_since(then);
if !(dur_min < this && this < dur_max) {
panic!("timeout exceeded: {:?}", this);
}
tx.send(42).unwrap();
assert_eq!(rx.recv_deadline(now.checked_add(dur).unwrap()), Ok(42));
assert!(Instant::now().duration_since(now) < max_error);
}
#[test]
fn recv_timeout_missed_send() {
let (tx, rx) = bounded(10);
assert!(rx.recv_timeout(Duration::from_millis(100)).is_err());
tx.send(42).unwrap();
assert_eq!(rx.recv(), Ok(42));
}
#[test]
fn disconnect_tx() {
let (tx, rx) = unbounded::<()>();
drop(tx);
assert!(rx.recv().is_err());
}
#[test]
fn disconnect_rx() {
let (tx, rx) = unbounded();
drop(rx);
assert!(tx.send(0).is_err());
}
#[test]
fn drain() {
let (tx, rx) = unbounded();
for i in 0..100 {
tx.send(i).unwrap();
}
assert_eq!(rx.drain().sum::<u32>(), (0..100).sum());
for i in 0..100 {
tx.send(i).unwrap();
}
for i in 0..100 {
tx.send(i).unwrap();
}
rx.recv().unwrap();
(1u32..100).chain(0..100).zip(rx).for_each(|(l, r)| assert_eq!(l, r));
}
#[test]
fn try_send() {
let (tx, rx) = bounded(5);
for i in 0..5 {
tx.try_send(i).unwrap();
}
assert!(tx.try_send(42).is_err());
assert_eq!(rx.recv(), Ok(0));
assert_eq!(tx.try_send(42), Ok(()));
assert_eq!(rx.recv(), Ok(1));
drop(rx);
assert!(tx.try_send(42).is_err());
}
#[test]
fn send_bounded() {
let (tx, rx) = bounded(5);
for _ in 0..5 {
tx.send(42).unwrap();
}
let _ = rx.recv().unwrap();
tx.send(42).unwrap();
assert!(tx.try_send(42).is_err());
rx.drain();
let mut ts = Vec::new();
for _ in 0..100 {
let tx = tx.clone();
ts.push(std::thread::spawn(move || {
for i in 0..10000 {
tx.send(i).unwrap();
}
}));
}
drop(tx);
assert_eq!(rx.iter().sum::<u64>(), (0..10000).sum::<u64>() * 100);
for t in ts {
t.join().unwrap();
}
assert!(rx.recv().is_err());
}
#[test]
fn rendezvous() {
let (tx, rx) = bounded(0);
for i in 0..5 {
let tx = tx.clone();
let t = std::thread::spawn(move || {
assert!(tx.try_send(()).is_err());
let then = Instant::now();
tx.send(()).unwrap();
let now = Instant::now();
assert!(now.duration_since(then) > Duration::from_millis(100), "iter = {}", i);
});
std::thread::sleep(Duration::from_millis(1000));
rx.recv().unwrap();
t.join().unwrap();
}
}
#[test]
fn hydra() {
let thread_num = 32;
let msg_num = 1000;
let (main_tx, main_rx) = unbounded::<()>();
let mut txs = Vec::new();
for _ in 0..thread_num {
let main_tx = main_tx.clone();
let (tx, rx) = unbounded();
txs.push(tx);
std::thread::spawn(move || {
for msg in rx.iter() {
main_tx.send(msg).unwrap();
}
});
}
drop(main_tx);
for _ in 0..10 {
for tx in &txs {
for _ in 0..msg_num {
tx.send(Default::default()).unwrap();
}
}
for _ in 0..thread_num {
for _ in 0..msg_num {
main_rx.recv().unwrap();
}
}
}
drop(txs);
assert!(main_rx.recv().is_err());
}
#[test]
fn robin() {
let thread_num = 32;
let msg_num = 10;
let (mut main_tx, main_rx) = bounded::<()>(1);
for _ in 0..thread_num {
let (mut tx, rx) = bounded(100);
std::mem::swap(&mut tx, &mut main_tx);
std::thread::spawn(move || {
for msg in rx.iter() {
tx.send(msg).unwrap();
}
});
}
for _ in 0..10 {
let main_tx = main_tx.clone();
std::thread::spawn(move || {
for _ in 0..msg_num {
main_tx.send(Default::default()).unwrap();
}
});
for _ in 0..msg_num {
main_rx.recv().unwrap();
}
}
}
#[cfg(feature = "select")]
#[test]
fn select_general() {
#[derive(Debug, PartialEq)]
struct Foo(usize);
let (tx0, rx0) = bounded(1);
let (tx1, rx1) = unbounded();
for (i, t) in vec![tx0.clone(), tx1].into_iter().enumerate() {
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(250));
let _ = t.send(Foo(i));
});
}
let x = Selector::new()
.recv(&rx0, |x| x)
.recv(&rx1, |x| x)
.wait()
.unwrap();
if x == Foo(0) {
assert!(rx1.recv().unwrap() == Foo(1));
} else {
assert!(rx0.recv().unwrap() == Foo(0));
}
tx0.send(Foo(42)).unwrap();
let t = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(100));
assert_eq!(rx0.recv().unwrap(), Foo(42));
assert_eq!(rx0.recv().unwrap(), Foo(43));
});
Selector::new()
.send(&tx0, Foo(43), |x| x)
.wait()
.unwrap();
t.join().unwrap();
}
struct MessageWithoutDebug(u32);
#[test]
// This is a 'does it build' test, to make sure that the error types can turn
// into a std::error::Error without requiring the payload (which is not used
// there) to impl Debug.
fn std_error_without_debug() {
let (tx, rx) = unbounded::<MessageWithoutDebug>();
match tx.send(MessageWithoutDebug(1)) {
Ok(_) => {}
Err(e) => {
let _std_err: &dyn std::error::Error = &e;
}
}
match rx.recv() {
Ok(_) => {}
Err(e) => {
let _std_err: &dyn std::error::Error = &e;
}
}
match tx.try_send(MessageWithoutDebug(2)) {
Ok(_) => {}
Err(e) => {
let _std_err: &dyn std::error::Error = &e;
}
}
match rx.try_recv() {
Ok(_) => {}
Err(e) => {
let _std_err: &dyn std::error::Error = &e;
}
}
match tx.send_timeout(MessageWithoutDebug(3), Duration::from_secs(1000000)) {
Ok(_) => {}
Err(e) => {
let _std_err: &dyn std::error::Error = &e;
}
}
match rx.recv_timeout(Duration::from_secs(10000000)) {
Ok(_) => {}
Err(e) => {
let _std_err: &dyn std::error::Error = &e;
}
}
}
#[test]
fn weak_close() {
let (tx, rx) = unbounded::<()>();
let weak = tx.downgrade();
drop(tx);
assert!(weak.upgrade().is_none());
assert!(rx.is_disconnected());
assert!(rx.try_recv().is_err());
}
#[test]
fn weak_upgrade() {
let (tx, rx) = unbounded();
let weak = tx.downgrade();
let tx2 = weak.upgrade().unwrap();
drop(tx);
assert!(!rx.is_disconnected());
tx2.send(()).unwrap();
assert!(rx.try_recv().is_ok());
}

View File

@ -0,0 +1,57 @@
#[test]
fn same_sender() {
let (tx1, _rx) = flume::unbounded::<()>();
let tx2 = tx1.clone();
assert!(tx1.same_channel(&tx2));
let (tx3, _rx) = flume::unbounded::<()>();
assert!(!tx1.same_channel(&tx3));
assert!(!tx2.same_channel(&tx3));
}
#[test]
fn same_receiver() {
let (_tx, rx1) = flume::unbounded::<()>();
let rx2 = rx1.clone();
assert!(rx1.same_channel(&rx2));
let (_tx, rx3) = flume::unbounded::<()>();
assert!(!rx1.same_channel(&rx3));
assert!(!rx2.same_channel(&rx3));
}
#[cfg(feature = "async")]
#[test]
fn same_send_sink() {
let (tx1, _rx) = flume::unbounded::<()>();
let tx1 = tx1.into_sink();
let tx2 = tx1.clone();
assert!(tx1.same_channel(&tx2));
let (tx3, _rx) = flume::unbounded::<()>();
let tx3 = tx3.into_sink();
assert!(!tx1.same_channel(&tx3));
assert!(!tx2.same_channel(&tx3));
}
#[cfg(feature = "async")]
#[test]
fn same_recv_stream() {
let (_tx, rx1) = flume::unbounded::<()>();
let rx1 = rx1.into_stream();
let rx2 = rx1.clone();
assert!(rx1.same_channel(&rx2));
let (_tx, rx3) = flume::unbounded::<()>();
let rx3 = rx3.into_stream();
assert!(!rx1.same_channel(&rx3));
assert!(!rx2.same_channel(&rx3));
}

1445
vendor/flume/tests/golang.rs vendored Normal file

File diff suppressed because it is too large Load Diff

112
vendor/flume/tests/iter.rs vendored Normal file
View File

@ -0,0 +1,112 @@
//! Tests for iteration over receivers.
extern crate crossbeam_utils;
use flume::unbounded;
use crossbeam_utils::thread::scope;
#[test]
fn nested_recv_iter() {
let (s, r) = unbounded::<i32>();
let (total_s, total_r) = unbounded::<i32>();
scope(|scope| {
scope.spawn(move |_| {
let mut acc = 0;
for x in r.iter() {
acc += x;
}
total_s.send(acc).unwrap();
});
s.send(3).unwrap();
s.send(1).unwrap();
s.send(2).unwrap();
drop(s);
assert_eq!(total_r.recv().unwrap(), 6);
})
.unwrap();
}
#[test]
fn recv_iter_break() {
let (s, r) = unbounded::<i32>();
let (count_s, count_r) = unbounded();
scope(|scope| {
scope.spawn(move |_| {
let mut count = 0;
for x in r.iter() {
if count >= 3 {
break;
} else {
count += x;
}
}
count_s.send(count).unwrap();
});
s.send(2).unwrap();
s.send(2).unwrap();
s.send(2).unwrap();
let _ = s.send(2);
drop(s);
assert_eq!(count_r.recv().unwrap(), 4);
})
.unwrap();
}
#[test]
fn recv_try_iter() {
let (request_s, request_r) = unbounded();
let (response_s, response_r) = unbounded();
scope(|scope| {
scope.spawn(move |_| {
let mut count = 0;
loop {
for x in response_r.try_iter() {
count += x;
if count == 6 {
return;
}
}
request_s.send(()).unwrap();
}
});
for _ in request_r.iter() {
if response_s.send(2).is_err() {
break;
}
}
})
.unwrap();
}
#[test]
fn recv_into_iter_owned() {
let mut iter = {
let (s, r) = unbounded::<i32>();
s.send(1).unwrap();
s.send(2).unwrap();
r.into_iter()
};
assert_eq!(iter.next().unwrap(), 1);
assert_eq!(iter.next().unwrap(), 2);
assert_eq!(iter.next().is_none(), true);
}
#[test]
fn recv_into_iter_borrowed() {
let (s, r) = unbounded::<i32>();
s.send(1).unwrap();
s.send(2).unwrap();
drop(s);
let mut iter = (&r).into_iter();
assert_eq!(iter.next().unwrap(), 1);
assert_eq!(iter.next().unwrap(), 2);
assert_eq!(iter.next().is_none(), true);
}

536
vendor/flume/tests/list.rs vendored Normal file
View File

@ -0,0 +1,536 @@
//! Tests for the list channel flavor.
extern crate crossbeam_utils;
extern crate rand;
use std::any::Any;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::Duration;
use flume::{unbounded, Receiver};
use flume::{RecvError, RecvTimeoutError, TryRecvError};
use flume::{SendError, SendTimeoutError, TrySendError};
use crossbeam_utils::thread::scope;
use rand::{thread_rng, Rng};
fn ms(ms: u64) -> Duration {
Duration::from_millis(ms)
}
#[test]
fn smoke() {
let (s, r) = unbounded();
s.try_send(7).unwrap();
assert_eq!(r.try_recv(), Ok(7));
s.send(8).unwrap();
assert_eq!(r.recv(), Ok(8));
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout));
}
#[test]
fn capacity() {
let (s, r) = unbounded::<()>();
assert_eq!(s.capacity(), None);
assert_eq!(r.capacity(), None);
}
#[test]
fn len_empty_full() {
let (s, r) = unbounded();
assert_eq!(s.len(), 0);
assert_eq!(s.is_empty(), true);
assert_eq!(s.is_full(), false);
assert_eq!(r.len(), 0);
assert_eq!(r.is_empty(), true);
assert_eq!(r.is_full(), false);
s.send(()).unwrap();
assert_eq!(s.len(), 1);
assert_eq!(s.is_empty(), false);
assert_eq!(s.is_full(), false);
assert_eq!(r.len(), 1);
assert_eq!(r.is_empty(), false);
assert_eq!(r.is_full(), false);
r.recv().unwrap();
assert_eq!(s.len(), 0);
assert_eq!(s.is_empty(), true);
assert_eq!(s.is_full(), false);
assert_eq!(r.len(), 0);
assert_eq!(r.is_empty(), true);
assert_eq!(r.is_full(), false);
}
#[test]
fn try_recv() {
let (s, r) = unbounded();
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
thread::sleep(ms(1500));
assert_eq!(r.try_recv(), Ok(7));
thread::sleep(ms(500));
assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
s.send(7).unwrap();
});
})
.unwrap();
}
#[test]
fn recv() {
let (s, r) = unbounded();
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.recv(), Ok(7));
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(8));
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(9));
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
s.send(7).unwrap();
s.send(8).unwrap();
s.send(9).unwrap();
});
})
.unwrap();
}
#[test]
fn recv_timeout() {
let (s, r) = unbounded::<i32>();
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout));
assert_eq!(r.recv_timeout(ms(1000)), Ok(7));
assert_eq!(
r.recv_timeout(ms(1000)),
Err(RecvTimeoutError::Disconnected)
);
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
s.send(7).unwrap();
});
})
.unwrap();
}
#[test]
fn try_send() {
let (s, r) = unbounded();
for i in 0..1000 {
assert_eq!(s.try_send(i), Ok(()));
}
drop(r);
assert_eq!(s.try_send(777), Err(TrySendError::Disconnected(777)));
}
#[test]
fn send() {
let (s, r) = unbounded();
for i in 0..1000 {
assert_eq!(s.send(i), Ok(()));
}
drop(r);
assert_eq!(s.send(777), Err(SendError(777)));
}
#[test]
fn send_timeout() {
let (s, r) = unbounded();
for i in 0..1000 {
assert_eq!(s.send_timeout(i, ms(i as u64)), Ok(()));
}
drop(r);
assert_eq!(
s.send_timeout(777, ms(0)),
Err(SendTimeoutError::Disconnected(777))
);
}
#[test]
fn send_after_disconnect() {
let (s, r) = unbounded();
s.send(1).unwrap();
s.send(2).unwrap();
s.send(3).unwrap();
drop(r);
assert_eq!(s.send(4), Err(SendError(4)));
assert_eq!(s.try_send(5), Err(TrySendError::Disconnected(5)));
assert_eq!(
s.send_timeout(6, ms(0)),
Err(SendTimeoutError::Disconnected(6))
);
}
#[test]
fn recv_after_disconnect() {
let (s, r) = unbounded();
s.send(1).unwrap();
s.send(2).unwrap();
s.send(3).unwrap();
drop(s);
assert_eq!(r.recv(), Ok(1));
assert_eq!(r.recv(), Ok(2));
assert_eq!(r.recv(), Ok(3));
assert!(r.recv().is_err());
}
#[test]
fn len() {
let (s, r) = unbounded();
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
for i in 0..50 {
s.send(i).unwrap();
assert_eq!(s.len(), i + 1);
}
for i in 0..50 {
r.recv().unwrap();
assert_eq!(r.len(), 50 - i - 1);
}
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
}
#[test]
fn disconnect_wakes_receiver() {
let (s, r) = unbounded::<()>();
scope(|scope| {
scope.spawn(move |_| {
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
drop(s);
});
})
.unwrap();
}
#[test]
fn spsc() {
const COUNT: usize = 100_000;
let (s, r) = unbounded();
scope(|scope| {
scope.spawn(move |_| {
for i in 0..COUNT {
assert_eq!(r.recv(), Ok(i));
}
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
for i in 0..COUNT {
s.send(i).unwrap();
}
});
})
.unwrap();
}
#[test]
fn mpmc() {
const COUNT: usize = 25_000;
const THREADS: usize = 4;
let (s, r) = unbounded::<usize>();
let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
scope(|scope| {
for _ in 0..THREADS {
scope.spawn(|_| {
for _ in 0..COUNT {
let n = r.recv().unwrap();
v[n].fetch_add(1, Ordering::SeqCst);
}
});
}
for _ in 0..THREADS {
scope.spawn(|_| {
for i in 0..COUNT {
s.send(i).unwrap();
}
});
}
})
.unwrap();
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
for c in v {
assert_eq!(c.load(Ordering::SeqCst), THREADS);
}
}
#[test]
fn stress_oneshot() {
const COUNT: usize = 10_000;
for _ in 0..COUNT {
let (s, r) = unbounded();
scope(|scope| {
scope.spawn(|_| r.recv().unwrap());
scope.spawn(|_| s.send(0).unwrap());
})
.unwrap();
}
}
#[test]
fn stress_iter() {
const COUNT: usize = 100_000;
let (request_s, request_r) = unbounded();
let (response_s, response_r) = unbounded();
scope(|scope| {
scope.spawn(move |_| {
let mut count = 0;
loop {
for x in response_r.try_iter() {
count += x;
if count == COUNT {
return;
}
}
request_s.send(()).unwrap();
}
});
for _ in request_r.iter() {
if response_s.send(1).is_err() {
break;
}
}
})
.unwrap();
}
#[test]
fn stress_timeout_two_threads() {
const COUNT: usize = 100;
let (s, r) = unbounded();
scope(|scope| {
scope.spawn(|_| {
for i in 0..COUNT {
if i % 2 == 0 {
thread::sleep(ms(50));
}
s.send(i).unwrap();
}
});
scope.spawn(|_| {
for i in 0..COUNT {
if i % 2 == 0 {
thread::sleep(ms(50));
}
loop {
if let Ok(x) = r.recv_timeout(ms(10)) {
assert_eq!(x, i);
break;
}
}
}
});
})
.unwrap();
}
#[test]
fn drops() {
static DROPS: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, PartialEq)]
struct DropCounter;
impl Drop for DropCounter {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
}
}
let mut rng = thread_rng();
for _ in 0..100 {
let steps = rng.gen_range(0..10_000);
let additional = rng.gen_range(0..1000);
DROPS.store(0, Ordering::SeqCst);
let (s, r) = unbounded::<DropCounter>();
scope(|scope| {
scope.spawn(|_| {
for _ in 0..steps {
r.recv().unwrap();
}
});
scope.spawn(|_| {
for _ in 0..steps {
s.send(DropCounter).unwrap();
}
});
})
.unwrap();
for _ in 0..additional {
s.try_send(DropCounter).unwrap();
}
assert_eq!(DROPS.load(Ordering::SeqCst), steps);
drop(s);
drop(r);
assert_eq!(DROPS.load(Ordering::SeqCst), steps + additional);
}
}
#[test]
fn linearizable() {
const COUNT: usize = 25_000;
const THREADS: usize = 4;
let (s, r) = unbounded();
scope(|scope| {
for _ in 0..THREADS {
scope.spawn(|_| {
for _ in 0..COUNT {
s.send(0).unwrap();
r.try_recv().unwrap();
}
});
}
})
.unwrap();
}
// #[test]
// fn fairness() {
// const COUNT: usize = 10_000;
// let (s1, r1) = unbounded::<()>();
// let (s2, r2) = unbounded::<()>();
// for _ in 0..COUNT {
// s1.send(()).unwrap();
// s2.send(()).unwrap();
// }
// let mut hits = [0usize; 2];
// for _ in 0..COUNT {
// select! {
// recv(r1) -> _ => hits[0] += 1,
// recv(r2) -> _ => hits[1] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// #[test]
// fn fairness_duplicates() {
// const COUNT: usize = 10_000;
// let (s, r) = unbounded();
// for _ in 0..COUNT {
// s.send(()).unwrap();
// }
// let mut hits = [0usize; 5];
// for _ in 0..COUNT {
// select! {
// recv(r) -> _ => hits[0] += 1,
// recv(r) -> _ => hits[1] += 1,
// recv(r) -> _ => hits[2] += 1,
// recv(r) -> _ => hits[3] += 1,
// recv(r) -> _ => hits[4] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// #[test]
// fn recv_in_send() {
// let (s, r) = unbounded();
// s.send(()).unwrap();
// select! {
// send(s, assert_eq!(r.recv(), Ok(()))) -> _ => {}
// }
// }
#[test]
fn channel_through_channel() {
const COUNT: usize = 1000;
type T = Box<dyn Any + Send>;
let (s, r) = unbounded::<T>();
scope(|scope| {
scope.spawn(move |_| {
let mut s = s;
for _ in 0..COUNT {
let (new_s, new_r) = unbounded();
let new_r: T = Box::new(Some(new_r));
s.send(new_r).unwrap();
s = new_s;
}
});
scope.spawn(move |_| {
let mut r = r;
for _ in 0..COUNT {
r = r
.recv()
.unwrap()
.downcast_mut::<Option<Receiver<T>>>()
.unwrap()
.take()
.unwrap()
}
});
})
.unwrap();
}

39
vendor/flume/tests/method_sharing.rs vendored Normal file
View File

@ -0,0 +1,39 @@
#[cfg(feature = "async")]
use flume::*;
#[cfg(feature = "async")]
#[async_std::test]
async fn sender() {
let (sender, receiver) = bounded(1);
let sender_fut = sender.send_async(());
assert_eq!(sender.is_disconnected(), sender_fut.is_disconnected());
assert_eq!(sender.is_empty(), sender_fut.is_empty());
assert_eq!(sender.is_full(), sender_fut.is_full());
assert_eq!(sender.len(), sender_fut.len());
assert_eq!(sender.capacity(), sender_fut.capacity());
let sender_sink = sender.sink();
assert_eq!(sender.is_disconnected(), sender_sink.is_disconnected());
assert_eq!(sender.is_empty(), sender_sink.is_empty());
assert_eq!(sender.is_full(), sender_sink.is_full());
assert_eq!(sender.len(), sender_sink.len());
assert_eq!(sender.capacity(), sender_sink.capacity());
let receiver_fut = receiver.recv_async();
assert_eq!(receiver.is_disconnected(), receiver_fut.is_disconnected());
assert_eq!(receiver.is_empty(), receiver_fut.is_empty());
assert_eq!(receiver.is_full(), receiver_fut.is_full());
assert_eq!(receiver.len(), receiver_fut.len());
assert_eq!(receiver.capacity(), receiver_fut.capacity());
let receiver_stream = receiver.stream();
assert_eq!(
receiver.is_disconnected(),
receiver_stream.is_disconnected()
);
assert_eq!(receiver.is_empty(), receiver_stream.is_empty());
assert_eq!(receiver.is_full(), receiver_stream.is_full());
assert_eq!(receiver.len(), receiver_stream.len());
assert_eq!(receiver.capacity(), receiver_stream.capacity());
}

2095
vendor/flume/tests/mpsc.rs vendored Normal file

File diff suppressed because it is too large Load Diff

99
vendor/flume/tests/never.rs vendored Normal file
View File

@ -0,0 +1,99 @@
// //! Tests for the never channel flavor.
// #[macro_use]
// extern crate crossbeam_channel;
// extern crate rand;
// use std::thread;
// use std::time::{Duration, Instant};
// use crossbeam_channel::{never, tick, unbounded};
// fn ms(ms: u64) -> Duration {
// Duration::from_millis(ms)
// }
// #[test]
// fn smoke() {
// select! {
// recv(never::<i32>()) -> _ => panic!(),
// default => {}
// }
// }
// #[test]
// fn optional() {
// let (s, r) = unbounded::<i32>();
// s.send(1).unwrap();
// s.send(2).unwrap();
// let mut r = Some(&r);
// select! {
// recv(r.unwrap_or(&never())) -> _ => {}
// default => panic!(),
// }
// r = None;
// select! {
// recv(r.unwrap_or(&never())) -> _ => panic!(),
// default => {}
// }
// }
// #[test]
// fn tick_n() {
// let mut r = tick(ms(100));
// let mut step = 0;
// loop {
// select! {
// recv(r) -> _ => step += 1,
// default(ms(500)) => break,
// }
// if step == 10 {
// r = never();
// }
// }
// assert_eq!(step, 10);
// }
// #[test]
// fn capacity() {
// let r = never::<i32>();
// assert_eq!(r.capacity(), Some(0));
// }
// #[test]
// fn len_empty_full() {
// let r = never::<i32>();
// assert_eq!(r.len(), 0);
// assert_eq!(r.is_empty(), true);
// assert_eq!(r.is_full(), true);
// }
// #[test]
// fn try_recv() {
// let r = never::<i32>();
// assert!(r.try_recv().is_err());
// thread::sleep(ms(100));
// assert!(r.try_recv().is_err());
// }
// #[test]
// fn recv_timeout() {
// let start = Instant::now();
// let r = never::<i32>();
// assert!(r.recv_timeout(ms(100)).is_err());
// let now = Instant::now();
// assert!(now - start >= ms(100));
// assert!(now - start <= ms(150));
// assert!(r.recv_timeout(ms(100)).is_err());
// let now = Instant::now();
// assert!(now - start >= ms(200));
// assert!(now - start <= ms(250));
// }

837
vendor/flume/tests/ready.rs vendored Normal file
View File

@ -0,0 +1,837 @@
// //! Tests for channel readiness using the `Select` struct.
// extern crate crossbeam_channel;
// extern crate crossbeam_utils;
// use std::any::Any;
// use std::cell::Cell;
// use std::thread;
// use std::time::{Duration, Instant};
// use crossbeam_channel::{after, bounded, tick, unbounded};
// use crossbeam_channel::{Receiver, Select, TryRecvError, TrySendError};
// use crossbeam_utils::thread::scope;
// fn ms(ms: u64) -> Duration {
// Duration::from_millis(ms)
// }
// #[test]
// fn smoke1() {
// let (s1, r1) = unbounded::<usize>();
// let (s2, r2) = unbounded::<usize>();
// s1.send(1).unwrap();
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// assert_eq!(sel.ready(), 0);
// assert_eq!(r1.try_recv(), Ok(1));
// s2.send(2).unwrap();
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// assert_eq!(sel.ready(), 1);
// assert_eq!(r2.try_recv(), Ok(2));
// }
// #[test]
// fn smoke2() {
// let (_s1, r1) = unbounded::<i32>();
// let (_s2, r2) = unbounded::<i32>();
// let (_s3, r3) = unbounded::<i32>();
// let (_s4, r4) = unbounded::<i32>();
// let (s5, r5) = unbounded::<i32>();
// s5.send(5).unwrap();
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// sel.recv(&r3);
// sel.recv(&r4);
// sel.recv(&r5);
// assert_eq!(sel.ready(), 4);
// assert_eq!(r5.try_recv(), Ok(5));
// }
// #[test]
// fn disconnected() {
// let (s1, r1) = unbounded::<i32>();
// let (s2, r2) = unbounded::<i32>();
// scope(|scope| {
// scope.spawn(|_| {
// drop(s1);
// thread::sleep(ms(500));
// s2.send(5).unwrap();
// });
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.ready_timeout(ms(1000)) {
// Ok(0) => assert_eq!(r1.try_recv(), Err(TryRecvError::Disconnected)),
// _ => panic!(),
// }
// r2.recv().unwrap();
// })
// .unwrap();
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.ready_timeout(ms(1000)) {
// Ok(0) => assert_eq!(r1.try_recv(), Err(TryRecvError::Disconnected)),
// _ => panic!(),
// }
// scope(|scope| {
// scope.spawn(|_| {
// thread::sleep(ms(500));
// drop(s2);
// });
// let mut sel = Select::new();
// sel.recv(&r2);
// match sel.ready_timeout(ms(1000)) {
// Ok(0) => assert_eq!(r2.try_recv(), Err(TryRecvError::Disconnected)),
// _ => panic!(),
// }
// })
// .unwrap();
// }
// #[test]
// fn default() {
// let (s1, r1) = unbounded::<i32>();
// let (s2, r2) = unbounded::<i32>();
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// assert!(sel.try_ready().is_err());
// drop(s1);
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.try_ready() {
// Ok(0) => assert!(r1.try_recv().is_err()),
// _ => panic!(),
// }
// s2.send(2).unwrap();
// let mut sel = Select::new();
// sel.recv(&r2);
// match sel.try_ready() {
// Ok(0) => assert_eq!(r2.try_recv(), Ok(2)),
// _ => panic!(),
// }
// let mut sel = Select::new();
// sel.recv(&r2);
// assert!(sel.try_ready().is_err());
// let mut sel = Select::new();
// assert!(sel.try_ready().is_err());
// }
// #[test]
// fn timeout() {
// let (_s1, r1) = unbounded::<i32>();
// let (s2, r2) = unbounded::<i32>();
// scope(|scope| {
// scope.spawn(|_| {
// thread::sleep(ms(1500));
// s2.send(2).unwrap();
// });
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// assert!(sel.ready_timeout(ms(1000)).is_err());
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.ready_timeout(ms(1000)) {
// Ok(1) => assert_eq!(r2.try_recv(), Ok(2)),
// _ => panic!(),
// }
// })
// .unwrap();
// scope(|scope| {
// let (s, r) = unbounded::<i32>();
// scope.spawn(move |_| {
// thread::sleep(ms(500));
// drop(s);
// });
// let mut sel = Select::new();
// assert!(sel.ready_timeout(ms(1000)).is_err());
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.try_ready() {
// Ok(0) => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)),
// _ => panic!(),
// }
// })
// .unwrap();
// }
// #[test]
// fn default_when_disconnected() {
// let (_, r) = unbounded::<i32>();
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.try_ready() {
// Ok(0) => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)),
// _ => panic!(),
// }
// let (_, r) = unbounded::<i32>();
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready_timeout(ms(1000)) {
// Ok(0) => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)),
// _ => panic!(),
// }
// let (s, _) = bounded::<i32>(0);
// let mut sel = Select::new();
// sel.send(&s);
// match sel.try_ready() {
// Ok(0) => assert_eq!(s.try_send(0), Err(TrySendError::Disconnected(0))),
// _ => panic!(),
// }
// let (s, _) = bounded::<i32>(0);
// let mut sel = Select::new();
// sel.send(&s);
// match sel.ready_timeout(ms(1000)) {
// Ok(0) => assert_eq!(s.try_send(0), Err(TrySendError::Disconnected(0))),
// _ => panic!(),
// }
// }
// #[test]
// fn default_only() {
// let start = Instant::now();
// let mut sel = Select::new();
// assert!(sel.try_ready().is_err());
// let now = Instant::now();
// assert!(now - start <= ms(50));
// let start = Instant::now();
// let mut sel = Select::new();
// assert!(sel.ready_timeout(ms(500)).is_err());
// let now = Instant::now();
// assert!(now - start >= ms(450));
// assert!(now - start <= ms(550));
// }
// #[test]
// fn unblocks() {
// let (s1, r1) = bounded::<i32>(0);
// let (s2, r2) = bounded::<i32>(0);
// scope(|scope| {
// scope.spawn(|_| {
// thread::sleep(ms(500));
// s2.send(2).unwrap();
// });
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.ready_timeout(ms(1000)) {
// Ok(1) => assert_eq!(r2.try_recv(), Ok(2)),
// _ => panic!(),
// }
// })
// .unwrap();
// scope(|scope| {
// scope.spawn(|_| {
// thread::sleep(ms(500));
// assert_eq!(r1.recv().unwrap(), 1);
// });
// let mut sel = Select::new();
// let oper1 = sel.send(&s1);
// let oper2 = sel.send(&s2);
// let oper = sel.select_timeout(ms(1000));
// match oper {
// Err(_) => panic!(),
// Ok(oper) => match oper.index() {
// i if i == oper1 => oper.send(&s1, 1).unwrap(),
// i if i == oper2 => panic!(),
// _ => unreachable!(),
// },
// }
// })
// .unwrap();
// }
// #[test]
// fn both_ready() {
// let (s1, r1) = bounded(0);
// let (s2, r2) = bounded(0);
// scope(|scope| {
// scope.spawn(|_| {
// thread::sleep(ms(500));
// s1.send(1).unwrap();
// assert_eq!(r2.recv().unwrap(), 2);
// });
// for _ in 0..2 {
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.send(&s2);
// match sel.ready() {
// 0 => assert_eq!(r1.try_recv(), Ok(1)),
// 1 => s2.try_send(2).unwrap(),
// _ => panic!(),
// }
// }
// })
// .unwrap();
// }
// #[test]
// fn cloning1() {
// scope(|scope| {
// let (s1, r1) = unbounded::<i32>();
// let (_s2, r2) = unbounded::<i32>();
// let (s3, r3) = unbounded::<()>();
// scope.spawn(move |_| {
// r3.recv().unwrap();
// drop(s1.clone());
// assert!(r3.try_recv().is_err());
// s1.send(1).unwrap();
// r3.recv().unwrap();
// });
// s3.send(()).unwrap();
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.ready() {
// 0 => drop(r1.try_recv()),
// 1 => drop(r2.try_recv()),
// _ => panic!(),
// }
// s3.send(()).unwrap();
// })
// .unwrap();
// }
// #[test]
// fn cloning2() {
// let (s1, r1) = unbounded::<()>();
// let (s2, r2) = unbounded::<()>();
// let (_s3, _r3) = unbounded::<()>();
// scope(|scope| {
// scope.spawn(move |_| {
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.ready() {
// 0 => panic!(),
// 1 => drop(r2.try_recv()),
// _ => panic!(),
// }
// });
// thread::sleep(ms(500));
// drop(s1.clone());
// s2.send(()).unwrap();
// })
// .unwrap();
// }
// #[test]
// fn preflight1() {
// let (s, r) = unbounded();
// s.send(()).unwrap();
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready() {
// 0 => drop(r.try_recv()),
// _ => panic!(),
// }
// }
// #[test]
// fn preflight2() {
// let (s, r) = unbounded();
// drop(s.clone());
// s.send(()).unwrap();
// drop(s);
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready() {
// 0 => assert_eq!(r.try_recv(), Ok(())),
// _ => panic!(),
// }
// assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected));
// }
// #[test]
// fn preflight3() {
// let (s, r) = unbounded();
// drop(s.clone());
// s.send(()).unwrap();
// drop(s);
// r.recv().unwrap();
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready() {
// 0 => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)),
// _ => panic!(),
// }
// }
// #[test]
// fn duplicate_operations() {
// let (s, r) = unbounded::<i32>();
// let hit = vec![Cell::new(false); 4];
// while hit.iter().map(|h| h.get()).any(|hit| !hit) {
// let mut sel = Select::new();
// sel.recv(&r);
// sel.recv(&r);
// sel.send(&s);
// sel.send(&s);
// match sel.ready() {
// 0 => {
// assert!(r.try_recv().is_ok());
// hit[0].set(true);
// }
// 1 => {
// assert!(r.try_recv().is_ok());
// hit[1].set(true);
// }
// 2 => {
// assert!(s.try_send(0).is_ok());
// hit[2].set(true);
// }
// 3 => {
// assert!(s.try_send(0).is_ok());
// hit[3].set(true);
// }
// _ => panic!(),
// }
// }
// }
// #[test]
// fn nesting() {
// let (s, r) = unbounded::<i32>();
// let mut sel = Select::new();
// sel.send(&s);
// match sel.ready() {
// 0 => {
// assert!(s.try_send(0).is_ok());
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready() {
// 0 => {
// assert_eq!(r.try_recv(), Ok(0));
// let mut sel = Select::new();
// sel.send(&s);
// match sel.ready() {
// 0 => {
// assert!(s.try_send(1).is_ok());
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready() {
// 0 => {
// assert_eq!(r.try_recv(), Ok(1));
// }
// _ => panic!(),
// }
// }
// _ => panic!(),
// }
// }
// _ => panic!(),
// }
// }
// _ => panic!(),
// }
// }
// #[test]
// fn stress_recv() {
// const COUNT: usize = 10_000;
// let (s1, r1) = unbounded();
// let (s2, r2) = bounded(5);
// let (s3, r3) = bounded(0);
// scope(|scope| {
// scope.spawn(|_| {
// for i in 0..COUNT {
// s1.send(i).unwrap();
// r3.recv().unwrap();
// s2.send(i).unwrap();
// r3.recv().unwrap();
// }
// });
// for i in 0..COUNT {
// for _ in 0..2 {
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// match sel.ready() {
// 0 => assert_eq!(r1.try_recv(), Ok(i)),
// 1 => assert_eq!(r2.try_recv(), Ok(i)),
// _ => panic!(),
// }
// s3.send(()).unwrap();
// }
// }
// })
// .unwrap();
// }
// #[test]
// fn stress_send() {
// const COUNT: usize = 10_000;
// let (s1, r1) = bounded(0);
// let (s2, r2) = bounded(0);
// let (s3, r3) = bounded(100);
// scope(|scope| {
// scope.spawn(|_| {
// for i in 0..COUNT {
// assert_eq!(r1.recv().unwrap(), i);
// assert_eq!(r2.recv().unwrap(), i);
// r3.recv().unwrap();
// }
// });
// for i in 0..COUNT {
// for _ in 0..2 {
// let mut sel = Select::new();
// sel.send(&s1);
// sel.send(&s2);
// match sel.ready() {
// 0 => assert!(s1.try_send(i).is_ok()),
// 1 => assert!(s2.try_send(i).is_ok()),
// _ => panic!(),
// }
// }
// s3.send(()).unwrap();
// }
// })
// .unwrap();
// }
// #[test]
// fn stress_mixed() {
// const COUNT: usize = 10_000;
// let (s1, r1) = bounded(0);
// let (s2, r2) = bounded(0);
// let (s3, r3) = bounded(100);
// scope(|scope| {
// scope.spawn(|_| {
// for i in 0..COUNT {
// s1.send(i).unwrap();
// assert_eq!(r2.recv().unwrap(), i);
// r3.recv().unwrap();
// }
// });
// for i in 0..COUNT {
// for _ in 0..2 {
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.send(&s2);
// match sel.ready() {
// 0 => assert_eq!(r1.try_recv(), Ok(i)),
// 1 => assert!(s2.try_send(i).is_ok()),
// _ => panic!(),
// }
// }
// s3.send(()).unwrap();
// }
// })
// .unwrap();
// }
// #[test]
// fn stress_timeout_two_threads() {
// const COUNT: usize = 20;
// let (s, r) = bounded(2);
// scope(|scope| {
// scope.spawn(|_| {
// for i in 0..COUNT {
// if i % 2 == 0 {
// thread::sleep(ms(500));
// }
// let done = false;
// while !done {
// let mut sel = Select::new();
// sel.send(&s);
// match sel.ready_timeout(ms(100)) {
// Err(_) => {}
// Ok(0) => {
// assert!(s.try_send(i).is_ok());
// break;
// }
// Ok(_) => panic!(),
// }
// }
// }
// });
// scope.spawn(|_| {
// for i in 0..COUNT {
// if i % 2 == 0 {
// thread::sleep(ms(500));
// }
// let mut done = false;
// while !done {
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready_timeout(ms(100)) {
// Err(_) => {}
// Ok(0) => {
// assert_eq!(r.try_recv(), Ok(i));
// done = true;
// }
// Ok(_) => panic!(),
// }
// }
// }
// });
// })
// .unwrap();
// }
// #[test]
// fn send_recv_same_channel() {
// let (s, r) = bounded::<i32>(0);
// let mut sel = Select::new();
// sel.send(&s);
// sel.recv(&r);
// assert!(sel.ready_timeout(ms(100)).is_err());
// let (s, r) = unbounded::<i32>();
// let mut sel = Select::new();
// sel.send(&s);
// sel.recv(&r);
// match sel.ready_timeout(ms(100)) {
// Err(_) => panic!(),
// Ok(0) => assert!(s.try_send(0).is_ok()),
// Ok(_) => panic!(),
// }
// }
// #[test]
// fn channel_through_channel() {
// const COUNT: usize = 1000;
// type T = Box<dyn Any + Send>;
// for cap in 1..4 {
// let (s, r) = bounded::<T>(cap);
// scope(|scope| {
// scope.spawn(move |_| {
// let mut s = s;
// for _ in 0..COUNT {
// let (new_s, new_r) = bounded(cap);
// let new_r: T = Box::new(Some(new_r));
// {
// let mut sel = Select::new();
// sel.send(&s);
// match sel.ready() {
// 0 => assert!(s.try_send(new_r).is_ok()),
// _ => panic!(),
// }
// }
// s = new_s;
// }
// });
// scope.spawn(move |_| {
// let mut r = r;
// for _ in 0..COUNT {
// let new = {
// let mut sel = Select::new();
// sel.recv(&r);
// match sel.ready() {
// 0 => r
// .try_recv()
// .unwrap()
// .downcast_mut::<Option<Receiver<T>>>()
// .unwrap()
// .take()
// .unwrap(),
// _ => panic!(),
// }
// };
// r = new;
// }
// });
// })
// .unwrap();
// }
// }
// #[test]
// fn fairness1() {
// const COUNT: usize = 10_000;
// let (s1, r1) = bounded::<()>(COUNT);
// let (s2, r2) = unbounded::<()>();
// for _ in 0..COUNT {
// s1.send(()).unwrap();
// s2.send(()).unwrap();
// }
// let hits = vec![Cell::new(0usize); 4];
// for _ in 0..COUNT {
// let after = after(ms(0));
// let tick = tick(ms(0));
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// sel.recv(&after);
// sel.recv(&tick);
// match sel.ready() {
// 0 => {
// r1.try_recv().unwrap();
// hits[0].set(hits[0].get() + 1);
// }
// 1 => {
// r2.try_recv().unwrap();
// hits[1].set(hits[1].get() + 1);
// }
// 2 => {
// after.try_recv().unwrap();
// hits[2].set(hits[2].get() + 1);
// }
// 3 => {
// tick.try_recv().unwrap();
// hits[3].set(hits[3].get() + 1);
// }
// _ => panic!(),
// }
// }
// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 2));
// }
// #[test]
// fn fairness2() {
// const COUNT: usize = 10_000;
// let (s1, r1) = unbounded::<()>();
// let (s2, r2) = bounded::<()>(1);
// let (s3, r3) = bounded::<()>(0);
// scope(|scope| {
// scope.spawn(|_| {
// for _ in 0..COUNT {
// let mut sel = Select::new();
// let mut oper1 = None;
// let mut oper2 = None;
// if s1.is_empty() {
// oper1 = Some(sel.send(&s1));
// }
// if s2.is_empty() {
// oper2 = Some(sel.send(&s2));
// }
// let oper3 = sel.send(&s3);
// let oper = sel.select();
// match oper.index() {
// i if Some(i) == oper1 => assert!(oper.send(&s1, ()).is_ok()),
// i if Some(i) == oper2 => assert!(oper.send(&s2, ()).is_ok()),
// i if i == oper3 => assert!(oper.send(&s3, ()).is_ok()),
// _ => unreachable!(),
// }
// }
// });
// let hits = vec![Cell::new(0usize); 3];
// for _ in 0..COUNT {
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// sel.recv(&r3);
// loop {
// match sel.ready() {
// 0 => {
// if r1.try_recv().is_ok() {
// hits[0].set(hits[0].get() + 1);
// break;
// }
// }
// 1 => {
// if r2.try_recv().is_ok() {
// hits[1].set(hits[1].get() + 1);
// break;
// }
// }
// 2 => {
// if r3.try_recv().is_ok() {
// hits[2].set(hits[2].get() + 1);
// break;
// }
// }
// _ => unreachable!(),
// }
// }
// }
// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 10));
// })
// .unwrap();
// }

114
vendor/flume/tests/same_channel.rs vendored Normal file
View File

@ -0,0 +1,114 @@
// extern crate crossbeam_channel;
// use std::time::Duration;
// use crossbeam_channel::{after, bounded, never, tick, unbounded};
// fn ms(ms: u64) -> Duration {
// Duration::from_millis(ms)
// }
// #[test]
// fn after_same_channel() {
// let r = after(ms(50));
// let r2 = r.clone();
// assert!(r.same_channel(&r2));
// let r3 = after(ms(50));
// assert!(!r.same_channel(&r3));
// assert!(!r2.same_channel(&r3));
// let r4 = after(ms(100));
// assert!(!r.same_channel(&r4));
// assert!(!r2.same_channel(&r4));
// }
// #[test]
// fn array_same_channel() {
// let (s, r) = bounded::<usize>(1);
// let s2 = s.clone();
// assert!(s.same_channel(&s2));
// let r2 = r.clone();
// assert!(r.same_channel(&r2));
// let (s3, r3) = bounded::<usize>(1);
// assert!(!s.same_channel(&s3));
// assert!(!s2.same_channel(&s3));
// assert!(!r.same_channel(&r3));
// assert!(!r2.same_channel(&r3));
// }
// #[test]
// fn list_same_channel() {
// let (s, r) = unbounded::<usize>();
// let s2 = s.clone();
// assert!(s.same_channel(&s2));
// let r2 = r.clone();
// assert!(r.same_channel(&r2));
// let (s3, r3) = unbounded::<usize>();
// assert!(!s.same_channel(&s3));
// assert!(!s2.same_channel(&s3));
// assert!(!r.same_channel(&r3));
// assert!(!r2.same_channel(&r3));
// }
// #[test]
// fn never_same_channel() {
// let r = never::<usize>();
// let r2 = r.clone();
// assert!(r.same_channel(&r2));
// // Never channel are always equal to one another.
// let r3 = never::<usize>();
// assert!(r.same_channel(&r3));
// assert!(r2.same_channel(&r3));
// }
// #[test]
// fn tick_same_channel() {
// let r = tick(ms(50));
// let r2 = r.clone();
// assert!(r.same_channel(&r2));
// let r3 = tick(ms(50));
// assert!(!r.same_channel(&r3));
// assert!(!r2.same_channel(&r3));
// let r4 = tick(ms(100));
// assert!(!r.same_channel(&r4));
// assert!(!r2.same_channel(&r4));
// }
// #[test]
// fn zero_same_channel() {
// let (s, r) = bounded::<usize>(0);
// let s2 = s.clone();
// assert!(s.same_channel(&s2));
// let r2 = r.clone();
// assert!(r.same_channel(&r2));
// let (s3, r3) = bounded::<usize>(0);
// assert!(!s.same_channel(&s3));
// assert!(!s2.same_channel(&s3));
// assert!(!r.same_channel(&r3));
// assert!(!r2.same_channel(&r3));
// }
// #[test]
// fn different_flavors_same_channel() {
// let (s1, r1) = bounded::<usize>(0);
// let (s2, r2) = unbounded::<usize>();
// assert!(!s1.same_channel(&s2));
// assert!(!r1.same_channel(&r2));
// }

1304
vendor/flume/tests/select.rs vendored Normal file

File diff suppressed because it is too large Load Diff

1440
vendor/flume/tests/select_macro.rs vendored Normal file

File diff suppressed because it is too large Load Diff

255
vendor/flume/tests/stream.rs vendored Normal file
View File

@ -0,0 +1,255 @@
#[cfg(feature = "async")]
use {
flume::*,
futures::{stream::FuturesUnordered, StreamExt, TryFutureExt},
async_std::prelude::FutureExt,
std::time::Duration,
};
use futures::{stream, Stream};
#[cfg(feature = "async")]
#[test]
fn stream_recv() {
let (tx, rx) = unbounded();
let t = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(250));
tx.send(42u32).unwrap();
println!("sent");
});
async_std::task::block_on(async {
println!("receiving...");
let x = rx.stream().next().await;
println!("received");
assert_eq!(x, Some(42));
});
t.join().unwrap();
}
#[cfg(feature = "async")]
#[test]
fn stream_recv_disconnect() {
let (tx, rx) = bounded::<i32>(0);
let t = std::thread::spawn(move || {
tx.send(42);
std::thread::sleep(std::time::Duration::from_millis(250));
drop(tx)
});
async_std::task::block_on(async {
let mut stream = rx.into_stream();
assert_eq!(stream.next().await, Some(42));
assert_eq!(stream.next().await, None);
});
t.join().unwrap();
}
#[cfg(feature = "async")]
#[test]
fn stream_recv_drop_recv() {
let (tx, rx) = bounded::<i32>(10);
let rx2 = rx.clone();
let mut stream = rx.into_stream();
async_std::task::block_on(async {
let res = async_std::future::timeout(
std::time::Duration::from_millis(500),
stream.next()
).await;
assert!(res.is_err());
});
let t = std::thread::spawn(move || {
async_std::task::block_on(async {
rx2.stream().next().await
})
});
std::thread::sleep(std::time::Duration::from_millis(500));
tx.send(42).unwrap();
drop(stream);
assert_eq!(t.join().unwrap(), Some(42))
}
#[cfg(feature = "async")]
#[test]
fn r#stream_drop_send_disconnect() {
let (tx, rx) = bounded::<i32>(1);
let t = std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(250));
drop(tx);
});
async_std::task::block_on(async {
let mut stream = rx.into_stream();
assert_eq!(stream.next().await, None);
});
t.join().unwrap();
}
#[cfg(feature = "async")]
#[async_std::test]
async fn stream_send_1_million_no_drop_or_reorder() {
#[derive(Debug)]
enum Message {
Increment {
old: u64,
},
ReturnCount,
}
let (tx, rx) = unbounded();
let t = async_std::task::spawn(async move {
let mut count = 0u64;
let mut stream = rx.into_stream();
while let Some(Message::Increment { old }) = stream.next().await {
assert_eq!(old, count);
count += 1;
}
count
});
for next in 0..1_000_000 {
tx.send(Message::Increment { old: next }).unwrap();
}
tx.send(Message::ReturnCount).unwrap();
let count = t.await;
assert_eq!(count, 1_000_000)
}
#[cfg(feature = "async")]
#[async_std::test]
async fn parallel_streams_and_async_recv() {
let (tx, rx) = flume::unbounded();
let rx = &rx;
let send_fut = async move {
let n_sends: usize = 100000;
for _ in 0..n_sends {
tx.send_async(()).await.unwrap();
}
};
async_std::task::spawn(
send_fut
.timeout(Duration::from_secs(5))
.map_err(|_| panic!("Send timed out!"))
);
let mut futures_unordered = (0..250)
.map(|n| async move {
if n % 2 == 0 {
let mut stream = rx.stream();
while let Some(()) = stream.next().await {}
} else {
while let Ok(()) = rx.recv_async().await {}
}
})
.collect::<FuturesUnordered<_>>();
let recv_fut = async {
while futures_unordered.next().await.is_some() {}
};
recv_fut
.timeout(Duration::from_secs(5))
.map_err(|_| panic!("Receive timed out!"))
.await
.unwrap();
}
#[cfg(feature = "async")]
#[test]
fn stream_no_double_wake() {
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::pin::Pin;
use std::task::Context;
use futures::task::{waker, ArcWake};
use futures::Stream;
let count = Arc::new(AtomicUsize::new(0));
// all this waker does is count how many times it is called
struct CounterWaker {
count: Arc<AtomicUsize>,
}
impl ArcWake for CounterWaker {
fn wake_by_ref(arc_self: &Arc<Self>) {
arc_self.count.fetch_add(1, Ordering::SeqCst);
}
}
// create waker and context
let w = CounterWaker {
count: count.clone(),
};
let w = waker(Arc::new(w));
let cx = &mut Context::from_waker(&w);
// create unbounded channel
let (tx, rx) = unbounded::<()>();
let mut stream = rx.stream();
// register waker with stream
let _ = Pin::new(&mut stream).poll_next(cx);
// send multiple items
tx.send(()).unwrap();
tx.send(()).unwrap();
tx.send(()).unwrap();
// verify that stream is only woken up once.
assert_eq!(count.load(Ordering::SeqCst), 1);
}
#[cfg(feature = "async")]
#[async_std::test]
async fn stream_forward_issue_55() { // https://github.com/zesterer/flume/issues/55
fn dummy_stream() -> impl Stream<Item = usize> {
stream::unfold(0, |count| async move {
if count < 1000 {
Some((count, count + 1))
} else {
None
}
})
}
let (send_task, recv_task) = {
use futures::SinkExt;
let (tx, rx) = flume::bounded(100);
let send_task = dummy_stream()
.map(|i| Ok(i))
.forward(tx.into_sink().sink_map_err(|e| {
panic!("send error:{:#?}", e)
}));
let recv_task = rx
.into_stream()
.for_each(|item| async move {});
(send_task, recv_task)
};
let jh = async_std::task::spawn(send_task);
async_std::task::block_on(recv_task);
jh.await.unwrap();
}

53
vendor/flume/tests/thread_locals.rs vendored Normal file
View File

@ -0,0 +1,53 @@
// //! Tests that make sure accessing thread-locals while exiting the thread doesn't cause panics.
// extern crate crossbeam_utils;
// use std::thread;
// use std::time::Duration;
// use flume::unbounded;
// use crossbeam_utils::thread::scope;
// fn ms(ms: u64) -> Duration {
// Duration::from_millis(ms)
// }
// #[test]
// #[cfg_attr(target_os = "macos", ignore = "TLS is destroyed too early on macOS")]
// fn use_while_exiting() {
// struct Foo;
// impl Drop for Foo {
// fn drop(&mut self) {
// // A blocking operation after the thread-locals have been dropped. This will attempt to
// // use the thread-locals and must not panic.
// let (_s, r) = unbounded::<()>();
// select! {
// recv(r) -> _ => {}
// default(ms(100)) => {}
// }
// }
// }
// thread_local! {
// static FOO: Foo = Foo;
// }
// let (s, r) = unbounded::<()>();
// scope(|scope| {
// scope.spawn(|_| {
// // First initialize `FOO`, then the thread-locals related to crossbeam-channel.
// FOO.with(|_| ());
// r.recv().unwrap();
// // At thread exit, thread-locals related to crossbeam-channel get dropped first and
// // `FOO` is dropped last.
// });
// scope.spawn(|_| {
// thread::sleep(ms(100));
// s.send(()).unwrap();
// });
// })
// .unwrap();
// }

353
vendor/flume/tests/tick.rs vendored Normal file
View File

@ -0,0 +1,353 @@
// //! Tests for the tick channel flavor.
// #[macro_use]
// extern crate crossbeam_channel;
// extern crate crossbeam_utils;
// extern crate rand;
// use std::sync::atomic::AtomicUsize;
// use std::sync::atomic::Ordering;
// use std::thread;
// use std::time::{Duration, Instant};
// use crossbeam_channel::{after, tick, Select, TryRecvError};
// use crossbeam_utils::thread::scope;
// fn ms(ms: u64) -> Duration {
// Duration::from_millis(ms)
// }
// #[test]
// fn fire() {
// let start = Instant::now();
// let r = tick(ms(50));
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// thread::sleep(ms(100));
// let fired = r.try_recv().unwrap();
// assert!(start < fired);
// assert!(fired - start >= ms(50));
// let now = Instant::now();
// assert!(fired < now);
// assert!(now - fired >= ms(50));
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// select! {
// recv(r) -> _ => panic!(),
// default => {}
// }
// select! {
// recv(r) -> _ => {}
// recv(tick(ms(200))) -> _ => panic!(),
// }
// }
// #[test]
// fn intervals() {
// let start = Instant::now();
// let r = tick(ms(50));
// let t1 = r.recv().unwrap();
// assert!(start + ms(50) <= t1);
// assert!(start + ms(100) > t1);
// thread::sleep(ms(300));
// let t2 = r.try_recv().unwrap();
// assert!(start + ms(100) <= t2);
// assert!(start + ms(150) > t2);
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// let t3 = r.recv().unwrap();
// assert!(start + ms(400) <= t3);
// assert!(start + ms(450) > t3);
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// }
// #[test]
// fn capacity() {
// const COUNT: usize = 10;
// for i in 0..COUNT {
// let r = tick(ms(i as u64));
// assert_eq!(r.capacity(), Some(1));
// }
// }
// #[test]
// fn len_empty_full() {
// let r = tick(ms(50));
// assert_eq!(r.len(), 0);
// assert_eq!(r.is_empty(), true);
// assert_eq!(r.is_full(), false);
// thread::sleep(ms(100));
// assert_eq!(r.len(), 1);
// assert_eq!(r.is_empty(), false);
// assert_eq!(r.is_full(), true);
// r.try_recv().unwrap();
// assert_eq!(r.len(), 0);
// assert_eq!(r.is_empty(), true);
// assert_eq!(r.is_full(), false);
// }
// #[test]
// fn try_recv() {
// let r = tick(ms(200));
// assert!(r.try_recv().is_err());
// thread::sleep(ms(100));
// assert!(r.try_recv().is_err());
// thread::sleep(ms(200));
// assert!(r.try_recv().is_ok());
// assert!(r.try_recv().is_err());
// thread::sleep(ms(200));
// assert!(r.try_recv().is_ok());
// assert!(r.try_recv().is_err());
// }
// #[test]
// fn recv() {
// let start = Instant::now();
// let r = tick(ms(50));
// let fired = r.recv().unwrap();
// assert!(start < fired);
// assert!(fired - start >= ms(50));
// let now = Instant::now();
// assert!(fired < now);
// assert!(now - fired < fired - start);
// assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
// }
// #[test]
// fn recv_timeout() {
// let start = Instant::now();
// let r = tick(ms(200));
// assert!(r.recv_timeout(ms(100)).is_err());
// let now = Instant::now();
// assert!(now - start >= ms(100));
// assert!(now - start <= ms(150));
// let fired = r.recv_timeout(ms(200)).unwrap();
// assert!(fired - start >= ms(200));
// assert!(fired - start <= ms(250));
// assert!(r.recv_timeout(ms(100)).is_err());
// let now = Instant::now();
// assert!(now - start >= ms(300));
// assert!(now - start <= ms(350));
// let fired = r.recv_timeout(ms(200)).unwrap();
// assert!(fired - start >= ms(400));
// assert!(fired - start <= ms(450));
// }
// #[test]
// fn recv_two() {
// let r1 = tick(ms(50));
// let r2 = tick(ms(50));
// scope(|scope| {
// scope.spawn(|_| {
// for _ in 0..10 {
// select! {
// recv(r1) -> _ => {}
// recv(r2) -> _ => {}
// }
// }
// });
// scope.spawn(|_| {
// for _ in 0..10 {
// select! {
// recv(r1) -> _ => {}
// recv(r2) -> _ => {}
// }
// }
// });
// })
// .unwrap();
// }
// #[test]
// fn recv_race() {
// select! {
// recv(tick(ms(50))) -> _ => {}
// recv(tick(ms(100))) -> _ => panic!(),
// }
// select! {
// recv(tick(ms(100))) -> _ => panic!(),
// recv(tick(ms(50))) -> _ => {}
// }
// }
// #[test]
// fn stress_default() {
// const COUNT: usize = 10;
// for _ in 0..COUNT {
// select! {
// recv(tick(ms(0))) -> _ => {}
// default => panic!(),
// }
// }
// for _ in 0..COUNT {
// select! {
// recv(tick(ms(100))) -> _ => panic!(),
// default => {}
// }
// }
// }
// #[test]
// fn select() {
// const THREADS: usize = 4;
// let hits = AtomicUsize::new(0);
// let r1 = tick(ms(200));
// let r2 = tick(ms(300));
// scope(|scope| {
// for _ in 0..THREADS {
// scope.spawn(|_| {
// let timeout = after(ms(1100));
// loop {
// let mut sel = Select::new();
// let oper1 = sel.recv(&r1);
// let oper2 = sel.recv(&r2);
// let oper3 = sel.recv(&timeout);
// let oper = sel.select();
// match oper.index() {
// i if i == oper1 => {
// oper.recv(&r1).unwrap();
// hits.fetch_add(1, Ordering::SeqCst);
// }
// i if i == oper2 => {
// oper.recv(&r2).unwrap();
// hits.fetch_add(1, Ordering::SeqCst);
// }
// i if i == oper3 => {
// oper.recv(&timeout).unwrap();
// break;
// }
// _ => unreachable!(),
// }
// }
// });
// }
// })
// .unwrap();
// assert_eq!(hits.load(Ordering::SeqCst), 8);
// }
// #[test]
// fn ready() {
// const THREADS: usize = 4;
// let hits = AtomicUsize::new(0);
// let r1 = tick(ms(200));
// let r2 = tick(ms(300));
// scope(|scope| {
// for _ in 0..THREADS {
// scope.spawn(|_| {
// let timeout = after(ms(1100));
// 'outer: loop {
// let mut sel = Select::new();
// sel.recv(&r1);
// sel.recv(&r2);
// sel.recv(&timeout);
// loop {
// match sel.ready() {
// 0 => {
// if r1.try_recv().is_ok() {
// hits.fetch_add(1, Ordering::SeqCst);
// break;
// }
// }
// 1 => {
// if r2.try_recv().is_ok() {
// hits.fetch_add(1, Ordering::SeqCst);
// break;
// }
// }
// 2 => {
// if timeout.try_recv().is_ok() {
// break 'outer;
// }
// }
// _ => unreachable!(),
// }
// }
// }
// });
// }
// })
// .unwrap();
// assert_eq!(hits.load(Ordering::SeqCst), 8);
// }
// #[test]
// fn fairness() {
// const COUNT: usize = 30;
// for &dur in &[0, 1] {
// let mut hits = [0usize; 2];
// for _ in 0..COUNT {
// let r1 = tick(ms(dur));
// let r2 = tick(ms(dur));
// for _ in 0..COUNT {
// select! {
// recv(r1) -> _ => hits[0] += 1,
// recv(r2) -> _ => hits[1] += 1,
// }
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// }
// #[test]
// fn fairness_duplicates() {
// const COUNT: usize = 30;
// for &dur in &[0, 1] {
// let mut hits = [0usize; 5];
// for _ in 0..COUNT {
// let r = tick(ms(dur));
// for _ in 0..COUNT {
// select! {
// recv(r) -> _ => hits[0] += 1,
// recv(r) -> _ => hits[1] += 1,
// recv(r) -> _ => hits[2] += 1,
// recv(r) -> _ => hits[3] += 1,
// recv(r) -> _ => hits[4] += 1,
// }
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// }
// }

557
vendor/flume/tests/zero.rs vendored Normal file
View File

@ -0,0 +1,557 @@
//! Tests for the zero channel flavor.
extern crate crossbeam_utils;
extern crate rand;
use std::any::Any;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::Duration;
use flume::{bounded, Receiver};
use flume::{RecvError, RecvTimeoutError, TryRecvError};
use flume::{SendError, SendTimeoutError, TrySendError};
use crossbeam_utils::thread::scope;
use rand::{thread_rng, Rng};
fn ms(ms: u64) -> Duration {
Duration::from_millis(ms)
}
#[test]
fn smoke() {
let (s, r) = bounded(0);
assert_eq!(s.try_send(7), Err(TrySendError::Full(7)));
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
}
#[test]
fn capacity() {
let (s, r) = bounded::<()>(0);
assert_eq!(s.capacity(), Some(0));
assert_eq!(r.capacity(), Some(0));
}
#[test]
fn len_empty_full() {
let (s, r) = bounded(0);
assert_eq!(s.len(), 0);
assert_eq!(s.is_empty(), true);
assert_eq!(s.is_full(), true);
assert_eq!(r.len(), 0);
assert_eq!(r.is_empty(), true);
assert_eq!(r.is_full(), true);
scope(|scope| {
scope.spawn(|_| s.send(0).unwrap());
scope.spawn(|_| r.recv().unwrap());
})
.unwrap();
assert_eq!(s.len(), 0);
assert_eq!(s.is_empty(), true);
assert_eq!(s.is_full(), true);
assert_eq!(r.len(), 0);
assert_eq!(r.is_empty(), true);
assert_eq!(r.is_full(), true);
}
#[test]
fn try_recv() {
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
thread::sleep(ms(1500));
assert_eq!(r.try_recv(), Ok(7));
thread::sleep(ms(500));
assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
s.send(7).unwrap();
});
})
.unwrap();
}
#[test]
fn recv() {
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.recv(), Ok(7));
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(8));
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(9));
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
s.send(7).unwrap();
s.send(8).unwrap();
s.send(9).unwrap();
});
})
.unwrap();
}
#[test]
fn recv_timeout() {
let (s, r) = bounded::<i32>(0);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout));
assert_eq!(r.recv_timeout(ms(1000)), Ok(7));
assert_eq!(
r.recv_timeout(ms(1000)),
Err(RecvTimeoutError::Disconnected)
);
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
s.send(7).unwrap();
});
})
.unwrap();
}
#[test]
fn try_send() {
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(s.try_send(7), Err(TrySendError::Full(7)));
thread::sleep(ms(1500));
assert_eq!(s.try_send(8), Ok(()));
thread::sleep(ms(500));
assert_eq!(s.try_send(9), Err(TrySendError::Disconnected(9)));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
assert_eq!(r.recv(), Ok(8));
});
})
.unwrap();
}
#[test]
fn send() {
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
s.send(7).unwrap();
thread::sleep(ms(1000));
s.send(8).unwrap();
thread::sleep(ms(1000));
s.send(9).unwrap();
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
assert_eq!(r.recv(), Ok(7));
assert_eq!(r.recv(), Ok(8));
assert_eq!(r.recv(), Ok(9));
});
})
.unwrap();
}
#[test]
fn send_timeout() {
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(
s.send_timeout(7, ms(1000)),
Err(SendTimeoutError::Timeout(7))
);
assert_eq!(s.send_timeout(8, ms(1000)), Ok(()));
assert_eq!(
s.send_timeout(9, ms(1000)),
Err(SendTimeoutError::Disconnected(9))
);
});
scope.spawn(move |_| {
thread::sleep(ms(1500));
assert_eq!(r.recv(), Ok(8));
});
})
.unwrap();
}
#[test]
fn len() {
const COUNT: usize = 25_000;
let (s, r) = bounded(0);
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
scope(|scope| {
scope.spawn(|_| {
for i in 0..COUNT {
assert_eq!(r.recv(), Ok(i));
assert_eq!(r.len(), 0);
}
});
scope.spawn(|_| {
for i in 0..COUNT {
s.send(i).unwrap();
assert_eq!(s.len(), 0);
}
});
})
.unwrap();
assert_eq!(s.len(), 0);
assert_eq!(r.len(), 0);
}
#[test]
fn disconnect_wakes_sender() {
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
assert_eq!(s.send(()), Err(SendError(())));
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
drop(r);
});
})
.unwrap();
}
#[test]
fn disconnect_wakes_receiver() {
let (s, r) = bounded::<()>(0);
scope(|scope| {
scope.spawn(move |_| {
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
thread::sleep(ms(1000));
drop(s);
});
})
.unwrap();
}
#[test]
fn spsc() {
const COUNT: usize = 100_000;
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
for i in 0..COUNT {
assert_eq!(r.recv(), Ok(i));
}
assert!(r.recv().is_err());
});
scope.spawn(move |_| {
for i in 0..COUNT {
s.send(i).unwrap();
}
});
})
.unwrap();
}
#[test]
fn mpmc() {
const COUNT: usize = 25_000;
const THREADS: usize = 4;
let (s, r) = bounded::<usize>(0);
let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
scope(|scope| {
for _ in 0..THREADS {
scope.spawn(|_| {
for _ in 0..COUNT {
let n = r.recv().unwrap();
v[n].fetch_add(1, Ordering::SeqCst);
}
});
}
for _ in 0..THREADS {
scope.spawn(|_| {
for i in 0..COUNT {
s.send(i).unwrap();
}
});
}
})
.unwrap();
for c in v {
assert_eq!(c.load(Ordering::SeqCst), THREADS);
}
}
#[test]
fn stress_oneshot() {
const COUNT: usize = 10_000;
for _ in 0..COUNT {
let (s, r) = bounded(1);
scope(|scope| {
scope.spawn(|_| r.recv().unwrap());
scope.spawn(|_| s.send(0).unwrap());
})
.unwrap();
}
}
#[test]
fn stress_iter() {
const COUNT: usize = 1000;
let (request_s, request_r) = bounded(0);
let (response_s, response_r) = bounded(0);
scope(|scope| {
scope.spawn(move |_| {
let mut count = 0;
loop {
for x in response_r.try_iter() {
count += x;
if count == COUNT {
return;
}
}
let _ = request_s.try_send(());
}
});
for _ in request_r.iter() {
if response_s.send(1).is_err() {
break;
}
}
})
.unwrap();
}
#[test]
fn stress_timeout_two_threads() {
const COUNT: usize = 100;
let (s, r) = bounded(0);
scope(|scope| {
scope.spawn(|_| {
for i in 0..COUNT {
if i % 2 == 0 {
thread::sleep(ms(50));
}
loop {
if let Ok(()) = s.send_timeout(i, ms(10)) {
break;
}
}
}
});
scope.spawn(|_| {
for i in 0..COUNT {
if i % 2 == 0 {
thread::sleep(ms(50));
}
loop {
if let Ok(x) = r.recv_timeout(ms(10)) {
assert_eq!(x, i);
break;
}
}
}
});
})
.unwrap();
}
#[test]
fn drops() {
static DROPS: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, PartialEq)]
struct DropCounter;
impl Drop for DropCounter {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::SeqCst);
}
}
let mut rng = thread_rng();
for _ in 0..100 {
let steps = rng.gen_range(0..3_000);
DROPS.store(0, Ordering::SeqCst);
let (s, r) = bounded::<DropCounter>(0);
scope(|scope| {
scope.spawn(|_| {
for _ in 0..steps {
r.recv().unwrap();
}
});
scope.spawn(|_| {
for _ in 0..steps {
s.send(DropCounter).unwrap();
}
});
})
.unwrap();
assert_eq!(DROPS.load(Ordering::SeqCst), steps);
drop(s);
drop(r);
assert_eq!(DROPS.load(Ordering::SeqCst), steps);
}
}
// #[test]
// fn fairness() {
// const COUNT: usize = 10_000;
// let (s1, r1) = bounded::<()>(0);
// let (s2, r2) = bounded::<()>(0);
// scope(|scope| {
// scope.spawn(|_| {
// let mut hits = [0usize; 2];
// for _ in 0..COUNT {
// select! {
// recv(r1) -> _ => hits[0] += 1,
// recv(r2) -> _ => hits[1] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// });
// let mut hits = [0usize; 2];
// for _ in 0..COUNT {
// select! {
// send(s1, ()) -> _ => hits[0] += 1,
// send(s2, ()) -> _ => hits[1] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// })
// .unwrap();
// }
// #[test]
// fn fairness_duplicates() {
// const COUNT: usize = 10_000;
// let (s, r) = bounded::<()>(0);
// scope(|scope| {
// scope.spawn(|_| {
// let mut hits = [0usize; 5];
// for _ in 0..COUNT {
// select! {
// recv(r) -> _ => hits[0] += 1,
// recv(r) -> _ => hits[1] += 1,
// recv(r) -> _ => hits[2] += 1,
// recv(r) -> _ => hits[3] += 1,
// recv(r) -> _ => hits[4] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// });
// let mut hits = [0usize; 5];
// for _ in 0..COUNT {
// select! {
// send(s, ()) -> _ => hits[0] += 1,
// send(s, ()) -> _ => hits[1] += 1,
// send(s, ()) -> _ => hits[2] += 1,
// send(s, ()) -> _ => hits[3] += 1,
// send(s, ()) -> _ => hits[4] += 1,
// }
// }
// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
// })
// .unwrap();
// }
// #[test]
// fn recv_in_send() {
// let (s, r) = bounded(0);
// scope(|scope| {
// scope.spawn(|_| {
// thread::sleep(ms(100));
// r.recv()
// });
// scope.spawn(|_| {
// thread::sleep(ms(500));
// s.send(()).unwrap();
// });
// select! {
// send(s, r.recv().unwrap()) -> _ => {}
// }
// })
// .unwrap();
// }
#[test]
fn channel_through_channel() {
const COUNT: usize = 1000;
type T = Box<dyn Any + Send>;
let (s, r) = bounded::<T>(0);
scope(|scope| {
scope.spawn(move |_| {
let mut s = s;
for _ in 0..COUNT {
let (new_s, new_r) = bounded(0);
let new_r: T = Box::new(Some(new_r));
s.send(new_r).unwrap();
s = new_s;
}
});
scope.spawn(move |_| {
let mut r = r;
for _ in 0..COUNT {
r = r
.recv()
.unwrap()
.downcast_mut::<Option<Receiver<T>>>()
.unwrap()
.take()
.unwrap()
}
});
})
.unwrap();
}