#![cfg(all(feature = "async", not(loom)))] use core::mem; use core::time::Duration; mod helpers; use helpers::DropCounter; #[tokio::test] async fn send_before_await_tokio() { let (sender, receiver) = oneshot::channel(); assert!(sender.send(19i128).is_ok()); assert_eq!(receiver.await, Ok(19i128)); } #[async_std::test] async fn send_before_await_async_std() { let (sender, receiver) = oneshot::channel(); assert!(sender.send(19i128).is_ok()); assert_eq!(receiver.await, Ok(19i128)); } #[tokio::test] async fn await_with_dropped_sender_tokio() { let (sender, receiver) = oneshot::channel::(); mem::drop(sender); receiver.await.unwrap_err(); } #[async_std::test] async fn await_with_dropped_sender_async_std() { let (sender, receiver) = oneshot::channel::(); mem::drop(sender); receiver.await.unwrap_err(); } #[tokio::test] async fn await_before_send_tokio() { let (sender, receiver) = oneshot::channel(); let (message, counter) = DropCounter::new(79u128); let t = tokio::spawn(async move { tokio::time::sleep(Duration::from_millis(10)).await; sender.send(message) }); let returned_message = receiver.await.unwrap(); assert_eq!(counter.count(), 0); assert_eq!(*returned_message.value(), 79u128); mem::drop(returned_message); assert_eq!(counter.count(), 1); t.await.unwrap().unwrap(); } #[async_std::test] async fn await_before_send_async_std() { let (sender, receiver) = oneshot::channel(); let (message, counter) = DropCounter::new(79u128); let t = async_std::task::spawn(async move { async_std::task::sleep(Duration::from_millis(10)).await; sender.send(message) }); let returned_message = receiver.await.unwrap(); assert_eq!(counter.count(), 0); assert_eq!(*returned_message.value(), 79u128); mem::drop(returned_message); assert_eq!(counter.count(), 1); t.await.unwrap(); } #[tokio::test] async fn await_before_send_then_drop_sender_tokio() { let (sender, receiver) = oneshot::channel::(); let t = tokio::spawn(async { tokio::time::sleep(Duration::from_millis(10)).await; mem::drop(sender); }); assert!(receiver.await.is_err()); t.await.unwrap(); } #[async_std::test] async fn await_before_send_then_drop_sender_async_std() { let (sender, receiver) = oneshot::channel::(); let t = async_std::task::spawn(async { async_std::task::sleep(Duration::from_millis(10)).await; mem::drop(sender); }); assert!(receiver.await.is_err()); t.await; } // Tests that the Receiver handles being used synchronously even after being polled #[tokio::test] async fn poll_future_and_then_try_recv() { use core::future::Future; use core::pin::Pin; use core::task::{self, Poll}; struct StupidReceiverFuture(oneshot::Receiver<()>); impl Future for StupidReceiverFuture { type Output = Result<(), oneshot::RecvError>; fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { let poll_result = Future::poll(Pin::new(&mut self.0), cx); self.0.try_recv().expect_err("Should never be a message"); poll_result } } let (sender, receiver) = oneshot::channel(); let t = tokio::spawn(async { tokio::time::sleep(Duration::from_millis(20)).await; mem::drop(sender); }); StupidReceiverFuture(receiver).await.unwrap_err(); t.await.unwrap(); } #[tokio::test] async fn poll_receiver_then_drop_it() { let (sender, receiver) = oneshot::channel::<()>(); // This will poll the receiver and then give up after 100 ms. tokio::time::timeout(Duration::from_millis(100), receiver) .await .unwrap_err(); // Make sure the receiver has been dropped by the runtime. assert!(sender.send(()).is_err()); }