• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "sync")]
3 
4 #[cfg(all(target_family = "wasm", not(target_os = "wasi")))]
5 use wasm_bindgen_test::wasm_bindgen_test as test;
6 #[cfg(all(target_family = "wasm", not(target_os = "wasi")))]
7 use wasm_bindgen_test::wasm_bindgen_test as maybe_tokio_test;
8 
9 #[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))]
10 use tokio::test as maybe_tokio_test;
11 
12 use tokio::sync::Mutex;
13 use tokio_test::task::spawn;
14 use tokio_test::{assert_pending, assert_ready};
15 
16 use std::sync::Arc;
17 
18 #[test]
straight_execution()19 fn straight_execution() {
20     let l = Arc::new(Mutex::new(100));
21 
22     {
23         let mut t = spawn(l.clone().lock_owned());
24         let mut g = assert_ready!(t.poll());
25         assert_eq!(&*g, &100);
26         *g = 99;
27     }
28     {
29         let mut t = spawn(l.clone().lock_owned());
30         let mut g = assert_ready!(t.poll());
31         assert_eq!(&*g, &99);
32         *g = 98;
33     }
34     {
35         let mut t = spawn(l.lock_owned());
36         let g = assert_ready!(t.poll());
37         assert_eq!(&*g, &98);
38     }
39 }
40 
41 #[test]
readiness()42 fn readiness() {
43     let l = Arc::new(Mutex::new(100));
44     let mut t1 = spawn(l.clone().lock_owned());
45     let mut t2 = spawn(l.lock_owned());
46 
47     let g = assert_ready!(t1.poll());
48 
49     // We can't now acquire the lease since it's already held in g
50     assert_pending!(t2.poll());
51 
52     // But once g unlocks, we can acquire it
53     drop(g);
54     assert!(t2.is_woken());
55     assert_ready!(t2.poll());
56 }
57 
58 /// Ensure a mutex is unlocked if a future holding the lock
59 /// is aborted prematurely.
60 #[tokio::test]
61 #[cfg(feature = "full")]
aborted_future_1()62 async fn aborted_future_1() {
63     use std::time::Duration;
64     use tokio::time::{interval, timeout};
65 
66     let m1: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
67     {
68         let m2 = m1.clone();
69         // Try to lock mutex in a future that is aborted prematurely
70         timeout(Duration::from_millis(1u64), async move {
71             let iv = interval(Duration::from_millis(1000));
72             tokio::pin!(iv);
73             m2.lock_owned().await;
74             iv.as_mut().tick().await;
75             iv.as_mut().tick().await;
76         })
77         .await
78         .unwrap_err();
79     }
80     // This should succeed as there is no lock left for the mutex.
81     timeout(Duration::from_millis(1u64), async move {
82         m1.lock_owned().await;
83     })
84     .await
85     .expect("Mutex is locked");
86 }
87 
88 /// This test is similar to `aborted_future_1` but this time the
89 /// aborted future is waiting for the lock.
90 #[tokio::test]
91 #[cfg(feature = "full")]
aborted_future_2()92 async fn aborted_future_2() {
93     use std::time::Duration;
94     use tokio::time::timeout;
95 
96     let m1: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
97     {
98         // Lock mutex
99         let _lock = m1.clone().lock_owned().await;
100         {
101             let m2 = m1.clone();
102             // Try to lock mutex in a future that is aborted prematurely
103             timeout(Duration::from_millis(1u64), async move {
104                 m2.lock_owned().await;
105             })
106             .await
107             .unwrap_err();
108         }
109     }
110     // This should succeed as there is no lock left for the mutex.
111     timeout(Duration::from_millis(1u64), async move {
112         m1.lock_owned().await;
113     })
114     .await
115     .expect("Mutex is locked");
116 }
117 
118 #[test]
try_lock_owned()119 fn try_lock_owned() {
120     let m: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
121     {
122         let g1 = m.clone().try_lock_owned();
123         assert!(g1.is_ok());
124         let g2 = m.clone().try_lock_owned();
125         assert!(g2.is_err());
126     }
127     let g3 = m.try_lock_owned();
128     assert!(g3.is_ok());
129 }
130 
131 #[maybe_tokio_test]
debug_format()132 async fn debug_format() {
133     let s = "debug";
134     let m = Arc::new(Mutex::new(s.to_string()));
135     assert_eq!(format!("{:?}", s), format!("{:?}", m.lock_owned().await));
136 }
137