summaryrefslogtreecommitdiffstats
path: root/vendor/tokio/tests/task_id.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/tokio/tests/task_id.rs
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/tokio/tests/task_id.rs')
-rw-r--r--vendor/tokio/tests/task_id.rs303
1 files changed, 303 insertions, 0 deletions
diff --git a/vendor/tokio/tests/task_id.rs b/vendor/tokio/tests/task_id.rs
new file mode 100644
index 000000000..d7b7c0cd8
--- /dev/null
+++ b/vendor/tokio/tests/task_id.rs
@@ -0,0 +1,303 @@
+#![warn(rust_2018_idioms)]
+#![allow(clippy::declare_interior_mutable_const)]
+#![cfg(all(feature = "full", tokio_unstable))]
+
+#[cfg(not(tokio_wasi))]
+use std::error::Error;
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+#[cfg(not(tokio_wasi))]
+use tokio::runtime::{Builder, Runtime};
+use tokio::sync::oneshot;
+use tokio::task::{self, Id, LocalSet};
+
+#[cfg(not(tokio_wasi))]
+mod support {
+ pub mod panic;
+}
+#[cfg(not(tokio_wasi))]
+use support::panic::test_panic;
+
+#[tokio::test(flavor = "current_thread")]
+async fn task_id_spawn() {
+ tokio::spawn(async { println!("task id: {}", task::id()) })
+ .await
+ .unwrap();
+}
+
+#[cfg(not(tokio_wasi))]
+#[tokio::test(flavor = "current_thread")]
+async fn task_id_spawn_blocking() {
+ task::spawn_blocking(|| println!("task id: {}", task::id()))
+ .await
+ .unwrap();
+}
+
+#[tokio::test(flavor = "current_thread")]
+async fn task_id_collision_current_thread() {
+ let handle1 = tokio::spawn(async { task::id() });
+ let handle2 = tokio::spawn(async { task::id() });
+
+ let (id1, id2) = tokio::join!(handle1, handle2);
+ assert_ne!(id1.unwrap(), id2.unwrap());
+}
+
+#[cfg(not(tokio_wasi))]
+#[tokio::test(flavor = "multi_thread")]
+async fn task_id_collision_multi_thread() {
+ let handle1 = tokio::spawn(async { task::id() });
+ let handle2 = tokio::spawn(async { task::id() });
+
+ let (id1, id2) = tokio::join!(handle1, handle2);
+ assert_ne!(id1.unwrap(), id2.unwrap());
+}
+
+#[tokio::test(flavor = "current_thread")]
+async fn task_ids_match_current_thread() {
+ let (tx, rx) = oneshot::channel();
+ let handle = tokio::spawn(async {
+ let id = rx.await.unwrap();
+ assert_eq!(id, task::id());
+ });
+ tx.send(handle.id()).unwrap();
+ handle.await.unwrap();
+}
+
+#[cfg(not(tokio_wasi))]
+#[tokio::test(flavor = "multi_thread")]
+async fn task_ids_match_multi_thread() {
+ let (tx, rx) = oneshot::channel();
+ let handle = tokio::spawn(async {
+ let id = rx.await.unwrap();
+ assert_eq!(id, task::id());
+ });
+ tx.send(handle.id()).unwrap();
+ handle.await.unwrap();
+}
+
+#[cfg(not(tokio_wasi))]
+#[tokio::test(flavor = "multi_thread")]
+async fn task_id_future_destructor_completion() {
+ struct MyFuture {
+ tx: Option<oneshot::Sender<Id>>,
+ }
+
+ impl Future for MyFuture {
+ type Output = ();
+
+ fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
+ Poll::Ready(())
+ }
+ }
+
+ impl Drop for MyFuture {
+ fn drop(&mut self) {
+ let _ = self.tx.take().unwrap().send(task::id());
+ }
+ }
+
+ let (tx, rx) = oneshot::channel();
+ let handle = tokio::spawn(MyFuture { tx: Some(tx) });
+ let id = handle.id();
+ handle.await.unwrap();
+ assert_eq!(rx.await.unwrap(), id);
+}
+
+#[cfg(not(tokio_wasi))]
+#[tokio::test(flavor = "multi_thread")]
+async fn task_id_future_destructor_abort() {
+ struct MyFuture {
+ tx: Option<oneshot::Sender<Id>>,
+ }
+
+ impl Future for MyFuture {
+ type Output = ();
+
+ fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
+ Poll::Pending
+ }
+ }
+ impl Drop for MyFuture {
+ fn drop(&mut self) {
+ let _ = self.tx.take().unwrap().send(task::id());
+ }
+ }
+
+ let (tx, rx) = oneshot::channel();
+ let handle = tokio::spawn(MyFuture { tx: Some(tx) });
+ let id = handle.id();
+ handle.abort();
+ assert!(handle.await.unwrap_err().is_cancelled());
+ assert_eq!(rx.await.unwrap(), id);
+}
+
+#[tokio::test(flavor = "current_thread")]
+async fn task_id_output_destructor_handle_dropped_before_completion() {
+ struct MyOutput {
+ tx: Option<oneshot::Sender<Id>>,
+ }
+
+ impl Drop for MyOutput {
+ fn drop(&mut self) {
+ let _ = self.tx.take().unwrap().send(task::id());
+ }
+ }
+
+ struct MyFuture {
+ tx: Option<oneshot::Sender<Id>>,
+ }
+
+ impl Future for MyFuture {
+ type Output = MyOutput;
+
+ fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+ Poll::Ready(MyOutput { tx: self.tx.take() })
+ }
+ }
+
+ let (tx, mut rx) = oneshot::channel();
+ let handle = tokio::spawn(MyFuture { tx: Some(tx) });
+ let id = handle.id();
+ drop(handle);
+ assert!(rx.try_recv().is_err());
+ assert_eq!(rx.await.unwrap(), id);
+}
+
+#[tokio::test(flavor = "current_thread")]
+async fn task_id_output_destructor_handle_dropped_after_completion() {
+ struct MyOutput {
+ tx: Option<oneshot::Sender<Id>>,
+ }
+
+ impl Drop for MyOutput {
+ fn drop(&mut self) {
+ let _ = self.tx.take().unwrap().send(task::id());
+ }
+ }
+
+ struct MyFuture {
+ tx_output: Option<oneshot::Sender<Id>>,
+ tx_future: Option<oneshot::Sender<()>>,
+ }
+
+ impl Future for MyFuture {
+ type Output = MyOutput;
+
+ fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+ let _ = self.tx_future.take().unwrap().send(());
+ Poll::Ready(MyOutput {
+ tx: self.tx_output.take(),
+ })
+ }
+ }
+
+ let (tx_output, mut rx_output) = oneshot::channel();
+ let (tx_future, rx_future) = oneshot::channel();
+ let handle = tokio::spawn(MyFuture {
+ tx_output: Some(tx_output),
+ tx_future: Some(tx_future),
+ });
+ let id = handle.id();
+ rx_future.await.unwrap();
+ assert!(rx_output.try_recv().is_err());
+ drop(handle);
+ assert_eq!(rx_output.await.unwrap(), id);
+}
+
+#[test]
+fn task_try_id_outside_task() {
+ assert_eq!(None, task::try_id());
+}
+
+#[cfg(not(tokio_wasi))]
+#[test]
+fn task_try_id_inside_block_on() {
+ let rt = Runtime::new().unwrap();
+ rt.block_on(async {
+ assert_eq!(None, task::try_id());
+ });
+}
+
+#[tokio::test(flavor = "current_thread")]
+async fn task_id_spawn_local() {
+ LocalSet::new()
+ .run_until(async {
+ task::spawn_local(async { println!("task id: {}", task::id()) })
+ .await
+ .unwrap();
+ })
+ .await
+}
+
+#[tokio::test(flavor = "current_thread")]
+async fn task_id_nested_spawn_local() {
+ LocalSet::new()
+ .run_until(async {
+ task::spawn_local(async {
+ let parent_id = task::id();
+ LocalSet::new()
+ .run_until(async {
+ task::spawn_local(async move {
+ assert_ne!(parent_id, task::id());
+ })
+ .await
+ .unwrap();
+ })
+ .await;
+ assert_eq!(parent_id, task::id());
+ })
+ .await
+ .unwrap();
+ })
+ .await;
+}
+
+#[cfg(not(tokio_wasi))]
+#[tokio::test(flavor = "multi_thread")]
+async fn task_id_block_in_place_block_on_spawn() {
+ task::spawn(async {
+ let parent_id = task::id();
+
+ task::block_in_place(move || {
+ let rt = Builder::new_current_thread().build().unwrap();
+ rt.block_on(rt.spawn(async move {
+ assert_ne!(parent_id, task::id());
+ }))
+ .unwrap();
+ });
+
+ assert_eq!(parent_id, task::id());
+ })
+ .await
+ .unwrap();
+}
+
+#[cfg(not(tokio_wasi))]
+#[test]
+fn task_id_outside_task_panic_caller() -> Result<(), Box<dyn Error>> {
+ let panic_location_file = test_panic(|| {
+ let _ = task::id();
+ });
+
+ // The panic location should be in this file
+ assert_eq!(&panic_location_file.unwrap(), file!());
+
+ Ok(())
+}
+
+#[cfg(not(tokio_wasi))]
+#[test]
+fn task_id_inside_block_on_panic_caller() -> Result<(), Box<dyn Error>> {
+ let panic_location_file = test_panic(|| {
+ let rt = Runtime::new().unwrap();
+ rt.block_on(async {
+ task::id();
+ });
+ });
+
+ // The panic location should be in this file
+ assert_eq!(&panic_location_file.unwrap(), file!());
+
+ Ok(())
+}