From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/oneshot-uniffi/tests/sync.rs | 343 ++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 third_party/rust/oneshot-uniffi/tests/sync.rs (limited to 'third_party/rust/oneshot-uniffi/tests/sync.rs') diff --git a/third_party/rust/oneshot-uniffi/tests/sync.rs b/third_party/rust/oneshot-uniffi/tests/sync.rs new file mode 100644 index 0000000000..c6ba081c66 --- /dev/null +++ b/third_party/rust/oneshot-uniffi/tests/sync.rs @@ -0,0 +1,343 @@ +use core::mem; +use oneshot::TryRecvError; + +#[cfg(feature = "std")] +use oneshot::{RecvError, RecvTimeoutError}; +#[cfg(feature = "std")] +use std::time::{Duration, Instant}; + +#[cfg(feature = "std")] +mod thread { + #[cfg(loom)] + pub use loom::thread::spawn; + #[cfg(not(loom))] + pub use std::thread::{sleep, spawn}; + + #[cfg(loom)] + pub fn sleep(_timeout: core::time::Duration) { + loom::thread::yield_now() + } +} + +mod helpers; +use helpers::{maybe_loom_model, DropCounter}; + +#[test] +fn send_before_try_recv() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + assert!(sender.send(19i128).is_ok()); + + assert_eq!(receiver.try_recv(), Ok(19i128)); + assert_eq!(receiver.try_recv(), Err(TryRecvError::Disconnected)); + #[cfg(feature = "std")] + { + assert_eq!(receiver.recv_ref(), Err(RecvError)); + assert!(receiver.recv_timeout(Duration::from_secs(1)).is_err()); + } + }) +} + +#[cfg(feature = "std")] +#[test] +fn send_before_recv() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::<()>(); + assert!(sender.send(()).is_ok()); + assert_eq!(receiver.recv(), Ok(())); + }); + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + assert!(sender.send(19).is_ok()); + assert_eq!(receiver.recv(), Ok(19)); + }); + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + assert!(sender.send(21).is_ok()); + assert_eq!(receiver.recv(), Ok(21)); + }); + // FIXME: This test does not work with loom. There is something that happens after the + // channel object becomes larger than ~500 bytes and that makes an atomic read from the state + // result in "signal: 10, SIGBUS: access to undefined memory" + #[cfg(not(loom))] + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::<[u8; 4096]>(); + assert!(sender.send([0b10101010; 4096]).is_ok()); + assert!(receiver.recv().unwrap()[..] == [0b10101010; 4096][..]); + }); +} + +#[cfg(feature = "std")] +#[test] +fn send_before_recv_ref() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + assert!(sender.send(19i128).is_ok()); + + assert_eq!(receiver.recv_ref(), Ok(19i128)); + assert_eq!(receiver.recv_ref(), Err(RecvError)); + assert_eq!(receiver.try_recv(), Err(TryRecvError::Disconnected)); + assert!(receiver.recv_timeout(Duration::from_secs(1)).is_err()); + }) +} + +#[cfg(feature = "std")] +#[test] +fn send_before_recv_timeout() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + assert!(sender.send(19i128).is_ok()); + + let start = Instant::now(); + let timeout = Duration::from_secs(1); + assert_eq!(receiver.recv_timeout(timeout), Ok(19i128)); + assert!(start.elapsed() < Duration::from_millis(100)); + + assert!(receiver.recv_timeout(timeout).is_err()); + assert!(receiver.try_recv().is_err()); + assert!(receiver.recv().is_err()); + }) +} + +#[test] +fn send_then_drop_receiver() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + assert!(sender.send(19i128).is_ok()); + mem::drop(receiver); + }) +} + +#[test] +fn send_with_dropped_receiver() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + mem::drop(receiver); + let send_error = sender.send(5u128).unwrap_err(); + assert_eq!(*send_error.as_inner(), 5); + assert_eq!(send_error.into_inner(), 5); + }) +} + +#[test] +fn try_recv_with_dropped_sender() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + mem::drop(sender); + receiver.try_recv().unwrap_err(); + }) +} + +#[cfg(feature = "std")] +#[test] +fn recv_with_dropped_sender() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + mem::drop(sender); + receiver.recv().unwrap_err(); + }) +} + +#[cfg(feature = "std")] +#[test] +fn recv_before_send() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + let t = thread::spawn(move || { + thread::sleep(Duration::from_millis(2)); + sender.send(9u128).unwrap(); + }); + assert_eq!(receiver.recv(), Ok(9)); + t.join().unwrap(); + }) +} + +#[cfg(feature = "std")] +#[test] +fn recv_timeout_before_send() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + let t = thread::spawn(move || { + thread::sleep(Duration::from_millis(2)); + sender.send(9u128).unwrap(); + }); + assert_eq!(receiver.recv_timeout(Duration::from_secs(1)), Ok(9)); + t.join().unwrap(); + }) +} + +#[cfg(feature = "std")] +#[test] +fn recv_before_send_then_drop_sender() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + let t = thread::spawn(move || { + thread::sleep(Duration::from_millis(10)); + mem::drop(sender); + }); + assert!(receiver.recv().is_err()); + t.join().unwrap(); + }) +} + +#[cfg(feature = "std")] +#[test] +fn recv_timeout_before_send_then_drop_sender() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + let t = thread::spawn(move || { + thread::sleep(Duration::from_millis(10)); + mem::drop(sender); + }); + assert!(receiver.recv_timeout(Duration::from_secs(1)).is_err()); + t.join().unwrap(); + }) +} + +#[test] +fn try_recv() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + assert_eq!(receiver.try_recv(), Err(TryRecvError::Empty)); + mem::drop(sender) + }) +} + +#[cfg(feature = "std")] +#[test] +fn try_recv_then_drop_receiver() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel::(); + let t1 = thread::spawn(move || { + let _ = sender.send(42); + }); + let t2 = thread::spawn(move || { + assert!(matches!( + receiver.try_recv(), + Ok(42) | Err(TryRecvError::Empty) + )); + mem::drop(receiver); + }); + t1.join().unwrap(); + t2.join().unwrap(); + }) +} + +#[cfg(feature = "std")] +#[test] +fn recv_deadline_and_timeout_no_time() { + maybe_loom_model(|| { + let (_sender, receiver) = oneshot::channel::(); + + let start = Instant::now(); + assert_eq!( + receiver.recv_deadline(start), + Err(RecvTimeoutError::Timeout) + ); + assert!(start.elapsed() < Duration::from_millis(200)); + + let start = Instant::now(); + assert_eq!( + receiver.recv_timeout(Duration::from_millis(0)), + Err(RecvTimeoutError::Timeout) + ); + assert!(start.elapsed() < Duration::from_millis(200)); + }) +} + +// This test doesn't give meaningful results when run with oneshot_test_delay and loom +#[cfg(all(feature = "std", not(all(oneshot_test_delay, loom))))] +#[test] +fn recv_deadline_time_should_elapse() { + maybe_loom_model(|| { + let (_sender, receiver) = oneshot::channel::(); + + let start = Instant::now(); + #[cfg(not(loom))] + let timeout = Duration::from_millis(100); + #[cfg(loom)] + let timeout = Duration::from_millis(1); + assert_eq!( + receiver.recv_deadline(start + timeout), + Err(RecvTimeoutError::Timeout) + ); + assert!(start.elapsed() > timeout); + assert!(start.elapsed() < timeout * 3); + }) +} + +#[cfg(all(feature = "std", not(all(oneshot_test_delay, loom))))] +#[test] +fn recv_timeout_time_should_elapse() { + maybe_loom_model(|| { + let (_sender, receiver) = oneshot::channel::(); + + let start = Instant::now(); + #[cfg(not(loom))] + let timeout = Duration::from_millis(100); + #[cfg(loom)] + let timeout = Duration::from_millis(1); + + assert_eq!( + receiver.recv_timeout(timeout), + Err(RecvTimeoutError::Timeout) + ); + assert!(start.elapsed() > timeout); + assert!(start.elapsed() < timeout * 3); + }) +} + +#[cfg(not(loom))] +#[test] +fn non_send_type_can_be_used_on_same_thread() { + use std::ptr; + + #[derive(Debug, Eq, PartialEq)] + struct NotSend(*mut ()); + + let (sender, receiver) = oneshot::channel(); + sender.send(NotSend(ptr::null_mut())).unwrap(); + let reply = receiver.try_recv().unwrap(); + assert_eq!(reply, NotSend(ptr::null_mut())); +} + +#[test] +fn message_in_channel_dropped_on_receiver_drop() { + maybe_loom_model(|| { + let (sender, receiver) = oneshot::channel(); + let (message, counter) = DropCounter::new(()); + assert_eq!(counter.count(), 0); + sender.send(message).unwrap(); + assert_eq!(counter.count(), 0); + mem::drop(receiver); + assert_eq!(counter.count(), 1); + }) +} + +#[test] +fn send_error_drops_message_correctly() { + maybe_loom_model(|| { + let (sender, _) = oneshot::channel(); + let (message, counter) = DropCounter::new(()); + + let send_error = sender.send(message).unwrap_err(); + assert_eq!(counter.count(), 0); + mem::drop(send_error); + assert_eq!(counter.count(), 1); + }); +} + +#[test] +fn send_error_drops_message_correctly_on_into_inner() { + maybe_loom_model(|| { + let (sender, _) = oneshot::channel(); + let (message, counter) = DropCounter::new(()); + + let send_error = sender.send(message).unwrap_err(); + assert_eq!(counter.count(), 0); + let message = send_error.into_inner(); + assert_eq!(counter.count(), 0); + mem::drop(message); + assert_eq!(counter.count(), 1); + }); +} -- cgit v1.2.3