1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #![cfg(feature = "sync")]
15 use std::sync::Arc;
16 
17 use ylong_runtime::sync::{AutoRelSemaphore, Semaphore};
18 use ylong_runtime::task::JoinHandle;
19 
20 /// SDV test cases for `AutoRelSemaphore::acquire()`.
21 ///
22 /// # Brief
23 /// 1. Create a counting auto-release-semaphore with an initial capacity.
24 /// 2. Acquire an auto-release-permit.
25 /// 3. Asynchronously acquires a permit.
26 /// 4. Check the number of permits in every stage.
27 #[test]
sdv_auto_release_sem_acquire_test()28 fn sdv_auto_release_sem_acquire_test() {
29     let sem = Arc::new(AutoRelSemaphore::new(1).unwrap());
30     let sem2 = sem.clone();
31     let handle = ylong_runtime::spawn(async move {
32         let _permit2 = sem2.acquire().await.unwrap();
33         assert_eq!(sem2.current_permits(), 0);
34     });
35     ylong_runtime::block_on(handle).expect("block_on failed");
36     assert_eq!(sem.current_permits(), 1);
37 }
38 
39 /// SDV test cases for `AutoRelSemaphore::try_acquire()`.
40 ///
41 /// # Brief
42 /// 1. Create a counting auto-release-semaphore with an initial capacity.
43 /// 2. Acquire an auto-release-permit.
44 /// 3. Fail to acquire an auto-release-permit.
45 /// 4. Acquire an auto-release-permit successfully after the last one is
46 ///    recycled.
47 #[test]
sdv_auto_release_sem_try_acquire_test()48 fn sdv_auto_release_sem_try_acquire_test() {
49     let sem = AutoRelSemaphore::new(1).unwrap();
50     let permit = sem.try_acquire();
51     assert!(permit.is_ok());
52     let permit2 = sem.try_acquire();
53     assert!(permit2.is_err());
54     drop(permit);
55     let permit3 = sem.try_acquire();
56     assert!(permit3.is_ok());
57 }
58 
59 /// SDV test cases for `Semaphore::release()`.
60 ///
61 /// # Brief
62 /// 1. Create a counting semaphore with an initial capacity.
63 /// 2. Call `Semaphore::release()` to add a permit to the semaphore.
64 /// 3. Check the number of permits before and after releasing.
65 #[test]
sdv_release_test()66 fn sdv_release_test() {
67     let sem = Semaphore::new(2).unwrap();
68     assert_eq!(sem.current_permits(), 2);
69     sem.release();
70     assert_eq!(sem.current_permits(), 3);
71 }
72 
73 /// SDV test cases for `AutoRelSemaphore::close()`.
74 ///
75 /// # Brief
76 /// 1. Create a counting auto-release-semaphore with an initial capacity.
77 /// 2. Close the semaphore.
78 /// 3. Fail to acquire an auto-release-permit.
79 #[test]
sdv_auto_release_sem_close_test()80 fn sdv_auto_release_sem_close_test() {
81     let sem = Arc::new(AutoRelSemaphore::new(2).unwrap());
82     let sem2 = sem.clone();
83     assert!(!sem.is_closed());
84     sem.close();
85     assert!(sem.is_closed());
86     let permit = sem.try_acquire();
87     assert!(permit.is_err());
88     let handle = ylong_runtime::spawn(async move {
89         let permit2 = sem2.acquire().await;
90         assert!(permit2.is_err());
91     });
92     ylong_runtime::block_on(handle).expect("block_on failed");
93 }
94 
95 /// Stress test cases for `AutoRelSemaphore::acquire()`.
96 ///
97 /// # Brief
98 /// 1. Create a counting auto-release-semaphore with an initial capacity.
99 /// 2. Repeating acquiring an auto-release-permit for a huge number of times.
100 /// 3. Check the correctness of function of semaphore.
101 #[test]
sdv_auto_release_sem_stress_test()102 fn sdv_auto_release_sem_stress_test() {
103     let sem = Arc::new(AutoRelSemaphore::new(5).unwrap());
104     let mut tasks: Vec<JoinHandle<()>> = Vec::new();
105 
106     for _ in 0..1000 {
107         let sem2 = sem.clone();
108         tasks.push(ylong_runtime::spawn(async move {
109             let _permit = sem2.acquire().await;
110         }));
111     }
112     for t in tasks {
113         let _ = ylong_runtime::block_on(t);
114     }
115     let permit1 = sem.try_acquire();
116     assert!(permit1.is_ok());
117     let permit2 = sem.try_acquire();
118     assert!(permit2.is_ok());
119     let permit3 = sem.try_acquire();
120     assert!(permit3.is_ok());
121     let permit4 = sem.try_acquire();
122     assert!(permit4.is_ok());
123     let permit5 = sem.try_acquire();
124     assert!(permit5.is_ok());
125     assert!(sem.try_acquire().is_err());
126 }
127 
128 /// Stress test cases for `AutoRelSemaphore::acquire()` and
129 /// `AutoRelSemaphore::drop()`.
130 ///
131 /// # Brief
132 /// 1. Create a counting auto-release-semaphore with an initial capacity.
133 /// 2. Repeating acquiring a pair of auto-release-permit for a huge number of
134 ///    times.
135 /// 3. Check the correctness of the future of `Permit`.
136 #[test]
sdv_async_stress_test()137 fn sdv_async_stress_test() {
138     let mut tasks: Vec<JoinHandle<()>> = Vec::new();
139 
140     for _ in 0..50000 {
141         let sem = Arc::new(AutoRelSemaphore::new(1).unwrap());
142         let sem2 = sem.clone();
143         tasks.push(ylong_runtime::spawn(async move {
144             let _permit = sem.acquire().await;
145         }));
146         tasks.push(ylong_runtime::spawn(async move {
147             let _permit = sem2.acquire().await;
148         }));
149     }
150     for t in tasks {
151         let _ = ylong_runtime::block_on(t);
152     }
153 }
154 
155 /// SDV test cases for `Semaphore::try_acquire()`.
156 ///
157 /// # Brief
158 /// 1. Create a counting semaphore with an initial capacity.
159 /// 2. Acquire permits successfully.
160 /// 3. Fail to acquire a permit when all permits are consumed.
161 #[test]
sdv_try_acquire_test()162 fn sdv_try_acquire_test() {
163     let sem = Semaphore::new(2).unwrap();
164     let permit = sem.try_acquire();
165     assert!(permit.is_ok());
166     drop(permit);
167     assert_eq!(sem.current_permits(), 1);
168     let permit2 = sem.try_acquire();
169     assert!(permit2.is_ok());
170     drop(permit2);
171     assert_eq!(sem.current_permits(), 0);
172     let permit3 = sem.try_acquire();
173     assert!(permit3.is_err());
174 }
175 
176 /// SDV test cases for `Semaphore::acquire()`.
177 ///
178 /// # Brief
179 /// 1. Create a counting semaphore with an initial capacity.
180 /// 2. Acquire a permit.
181 /// 3. Asynchronously acquires a permit.
182 /// 4. Check the number of permits in every stage.
183 #[test]
sdv_acquire_test()184 fn sdv_acquire_test() {
185     let sem = Arc::new(Semaphore::new(0).unwrap());
186     let sem2 = sem.clone();
187     let handle = ylong_runtime::spawn(async move {
188         let _permit2 = sem2.acquire().await.unwrap();
189         assert_eq!(sem2.current_permits(), 0);
190     });
191     sem.release();
192     ylong_runtime::block_on(handle).expect("block_on failed");
193     assert_eq!(sem.current_permits(), 0);
194 }
195