use futures::channel::{mpsc, oneshot}; use futures::executor::{block_on, block_on_stream}; use futures::future::{poll_fn, FutureExt}; use futures::pin_mut; use futures::sink::{Sink, SinkExt}; use futures::stream::{Stream, StreamExt}; use futures::task::{Context, Poll}; use futures_test::task::{new_count_waker, noop_context}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::thread;
trait AssertSend: Send {} impl AssertSend for mpsc::Sender<i32> {} impl AssertSend for mpsc::Receiver<i32> {}
#[test] fn send_recv() { let (mut tx, rx) = mpsc::channel::<i32>(16);
block_on(tx.send(1)).unwrap();
drop(tx); let v: Vec<_> = block_on(rx.collect());
assert_eq!(v, vec![1]);
}
#[test] fn send_recv_no_buffer() { // Run on a task context
block_on(poll_fn(move |cx| { let (tx, rx) = mpsc::channel::<i32>(0);
pin_mut!(tx, rx);
// Send first message
assert!(tx.as_mut().start_send(1).is_ok());
assert!(tx.as_mut().poll_ready(cx).is_pending());
// poll_ready said Pending, so no room in buffer, therefore new sends // should get rejected with is_full.
assert!(tx.as_mut().start_send(0).unwrap_err().is_full());
assert!(tx.as_mut().poll_ready(cx).is_pending());
// Take the value
assert_eq!(rx.as_mut().poll_next(cx), Poll::Ready(Some(1)));
assert!(tx.as_mut().poll_ready(cx).is_ready());
// Send second message
assert!(tx.as_mut().poll_ready(cx).is_ready());
assert!(tx.as_mut().start_send(2).is_ok());
assert!(tx.as_mut().poll_ready(cx).is_pending());
// Take the value
assert_eq!(rx.as_mut().poll_next(cx), Poll::Ready(Some(2)));
assert!(tx.as_mut().poll_ready(cx).is_ready());
#[test] fn tx_close_gets_none() { let (_, mut rx) = mpsc::channel::<i32>(10);
// Run on a task context
block_on(poll_fn(move |cx| {
assert_eq!(rx.poll_next_unpin(cx), Poll::Ready(None));
Poll::Ready(())
}));
}
// #[test] // fn spawn_sends_items() { // let core = local_executor::Core::new(); // let stream = unfold(0, |i| Some(ok::<_,u8>((i, i + 1)))); // let rx = mpsc::spawn(stream, &core, 1); // assert_eq!(core.run(rx.take(4).collect()).unwrap(), // [0, 1, 2, 3]); // }
// #[test] // fn spawn_kill_dead_stream() { // use std::thread; // use std::time::Duration; // use futures::future::Either; // use futures::sync::oneshot; // // // a stream which never returns anything (maybe a remote end isn't // // responding), but dropping it leads to observable side effects // // (like closing connections, releasing limited resources, ...) // #[derive(Debug)] // struct Dead { // // when dropped you should get Err(oneshot::Canceled) on the // // receiving end // done: oneshot::Sender<()>, // } // impl Stream for Dead { // type Item = (); // type Error = (); // // fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { // Ok(Poll::Pending) // } // } // // // need to implement a timeout for the test, as it would hang // // forever right now // let (timeout_tx, timeout_rx) = oneshot::channel(); // thread::spawn(move || { // thread::sleep(Duration::from_millis(1000)); // let _ = timeout_tx.send(()); // }); // // let core = local_executor::Core::new(); // let (done_tx, done_rx) = oneshot::channel(); // let stream = Dead{done: done_tx}; // let rx = mpsc::spawn(stream, &core, 1); // let res = core.run( // Ok::<_, ()>(()) // .into_future() // .then(move |_| { // // now drop the spawned stream: maybe some timeout exceeded, // // or some connection on this end was closed by the remote // // end. // drop(rx); // // and wait for the spawned stream to release its resources // done_rx // }) // .select2(timeout_rx) // ); // match res { // Err(Either::A((oneshot::Canceled, _))) => (), // _ => { // panic!("dead stream wasn't canceled"); // }, // } // }
let t = thread::spawn(move || { let result: Vec<_> = block_on(rx.collect());
assert_eq!(result.len(), (AMT * NTHREADS) as usize); for item in result {
assert_eq!(item, 1);
}
});
let t = thread::spawn(move || { let result: Vec<_> = block_on(rx.collect());
assert_eq!(result.len(), (AMT * NTHREADS) as usize); for item in result {
assert_eq!(item, 1);
}
});
for _ in0..ITER { let v: Vec<_> = block_on(list().collect());
assert_eq!(v, vec![1, 2, 3]);
}
}
asyncfn send_one_two_three(mut tx: mpsc::Sender<i32>) { for i in1..=3 {
tx.send(i).await.unwrap();
}
}
/// Stress test that after receiver dropped, /// no messages are lost. fn stress_close_receiver_iter() { let (tx, rx) = mpsc::unbounded(); letmut rx = block_on_stream(rx); let (unwritten_tx, unwritten_rx) = std::sync::mpsc::channel(); let th = thread::spawn(move || { for i in1.. { if tx.unbounded_send(i).is_err() {
unwritten_tx.send(i).expect("unwritten_tx"); return;
}
}
});
// Read one message to make sure thread effectively started
assert_eq!(Some(1), rx.next());
rx.close();
for i in2.. { match rx.next() {
Some(r) => assert!(i == r),
None => { let unwritten = unwritten_rx.recv().expect("unwritten_rx");
assert_eq!(unwritten, i);
th.join().unwrap(); return;
}
}
}
}
for _ in0..ITER {
stress_close_receiver_iter();
}
}
asyncfn stress_poll_ready_sender(mut sender: mpsc::Sender<u32>, count: u32) { for i in (1..=count).rev() {
sender.send(i).await.unwrap();
}
}
/// Tests that after `poll_ready` indicates capacity a channel can always send without waiting. #[allow(clippy::same_item_push)] #[test] fn stress_poll_ready() { const AMT: u32 = if cfg!(miri) { 100 } else { 1000 }; const NTHREADS: u32 = 8;
/// Run a stress test using the specified channel capacity. fn stress(capacity: usize) { let (tx, rx) = mpsc::channel(capacity); letmut threads = Vec::new(); for _ in0..NTHREADS { let sender = tx.clone();
threads.push(thread::spawn(move || block_on(stress_poll_ready_sender(sender, AMT))));
}
drop(tx);
let result: Vec<_> = block_on(rx.collect());
assert_eq!(result.len() as u32, AMT * NTHREADS);
for thread in threads {
thread.join().unwrap();
}
}
#[test] fn try_send_recv() { let (mut tx, mut rx) = mpsc::channel(1);
tx.try_send("hello").unwrap();
tx.try_send("hello").unwrap();
tx.try_send("hello").unwrap_err(); // should be full
rx.try_next().unwrap();
rx.try_next().unwrap();
rx.try_next().unwrap_err(); // should be empty
tx.try_send("hello").unwrap();
rx.try_next().unwrap();
rx.try_next().unwrap_err(); // should be empty
}
#[test] fn same_receiver() { let (mut txa1, _) = mpsc::channel::<i32>(1); let txa2 = txa1.clone();
let (mut txb1, _) = mpsc::channel::<i32>(1); let txb2 = txb1.clone();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.