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 = "macros")]
15
16 /// SDV test cases for select! basic usage case
17 ///
18 /// # Brief
19 /// 1. Uses select! to run three async task.
20 /// 2. Uses if to disabled do_async1() and do_async3().
21 /// 3. Only the do_async2() task will be completely first.
22 #[test]
sdv_new_select_basicnull23 fn sdv_new_select_basic() {
24 async fn do_async1() -> i32 {
25 1
26 }
27
28 async fn do_async2() -> i32 {
29 2
30 }
31
32 async fn do_async3() -> bool {
33 false
34 }
35
36 let handle = ylong_runtime::spawn(async {
37 let mut count = 0;
38 ylong_runtime::select! {
39 a = do_async1(), if false => {
40 count += a;
41 },
42 b = do_async2() => {
43 count += b;
44 },
45 c = do_async3(), if false => {
46 if c {
47 count = 3;
48 }
49 else {
50 count = 4;
51 }
52 }
53 }
54 assert_eq!(count, 2);
55 });
56 ylong_runtime::block_on(handle).expect("select! fail");
57 }
58
59 /// SDV test cases for select! oneshot::channel usage
60 ///
61 /// # Brief
62 /// 1. Creates two oneshot::channel and send message.
63 /// 2. Repeated uses select! until both channel return.
64 /// 3. Checks whether the returned information of the two channels is correct.
65 #[test]
66 #[cfg(feature = "sync")]
sdv_new_select_channelnull67 fn sdv_new_select_channel() {
68 let handle = ylong_runtime::spawn(async {
69 let (tx1, mut rx1) = ylong_runtime::sync::oneshot::channel();
70 let (tx2, mut rx2) = ylong_runtime::sync::oneshot::channel();
71
72 ylong_runtime::spawn(async move {
73 tx1.send("first").unwrap();
74 });
75
76 ylong_runtime::spawn(async move {
77 tx2.send("second").unwrap();
78 });
79
80 let mut a = None;
81 let mut b = None;
82
83 while a.is_none() || b.is_none() {
84 ylong_runtime::select! {
85 v1 = (&mut rx1), if a.is_none() => a = Some(v1.unwrap()),
86 v2 = (&mut rx2), if b.is_none() => b = Some(v2.unwrap()),
87 }
88 }
89
90 let res = (a.unwrap(), b.unwrap());
91
92 assert_eq!(res.0, "first");
93 assert_eq!(res.1, "second");
94 });
95 ylong_runtime::block_on(handle).expect("select! fail");
96 }
97
98 /// SDV test cases for select! 'biased' usage
99 ///
100 /// # Brief
101 /// 1. Uses 'biased' to execute four task in the specified sequence.
102 /// 2. Checks whether the 'count' is correct.
103 #[test]
sdv_new_select_biasednull104 fn sdv_new_select_biased() {
105 let handle = ylong_runtime::spawn(async {
106 let mut count = 0u8;
107
108 loop {
109 ylong_runtime::select! {
110 biased;
111 _ = async {}, if count < 1 => {
112 count += 1;
113 assert_eq!(count, 1);
114 }
115 _ = async {}, if count < 2 => {
116 count += 1;
117 assert_eq!(count, 2);
118 }
119 _ = async {}, if count < 3 => {
120 count += 1;
121 assert_eq!(count, 3);
122 }
123 _ = async {}, if count < 4 => {
124 count += 1;
125 assert_eq!(count, 4);
126 }
127 else => {
128 break;
129 }
130 }
131 }
132
133 assert_eq!(count, 4);
134 });
135 ylong_runtime::block_on(handle).expect("select! fail");
136 }
137
138 /// SDV test cases for select! match usage
139 ///
140 /// # Brief
141 /// 1. Uses select! to run three async task.
142 /// 2. do_async2() and do_async3() will never match success.
143 /// 3. Only the do_async1() task will be completely.
144 #[test]
sdv_new_select_matchnull145 fn sdv_new_select_match() {
146 async fn do_async1() -> i32 {
147 1
148 }
149
150 async fn do_async2() -> Option<i32> {
151 Some(2)
152 }
153
154 async fn do_async3() -> Option<bool> {
155 None
156 }
157
158 let handle = ylong_runtime::spawn(async {
159 let mut count = 0;
160 ylong_runtime::select! {
161 a = do_async1() => {
162 count += a;
163 },
164 None = do_async2() => {
165 count += 2;
166 },
167 Some(c) = do_async3() => {
168 if c {
169 count = 3;
170 }
171 else {
172 count = 4;
173 }
174 }
175 }
176 assert_eq!(count, 1);
177 });
178 ylong_runtime::block_on(handle).expect("select! fail");
179 }
180
181 /// SDV test cases for select! precondition usage
182 ///
183 /// # Brief
184 /// 1. Creates a struct and implement a call to the `&mut self` async fn.
185 /// 2. Uses select! to run the async fn, and sets the precondition to the struct
186 /// member variable.
187 /// 3. The select! will be successfully executed.
188 #[test]
sdv_new_select_preconditionnull189 fn sdv_new_select_precondition() {
190 struct TestStruct {
191 bool: bool,
192 }
193 impl TestStruct {
194 async fn do_async(&mut self) {}
195 }
196
197 let handle = ylong_runtime::spawn(async {
198 let mut count = 0;
199 let mut test_struct = TestStruct { bool: true };
200 ylong_runtime::select! {
201 _ = test_struct.do_async(), if test_struct.bool => {
202 count += 1;
203 },
204 }
205 assert_eq!(count, 1);
206 });
207 ylong_runtime::block_on(handle).expect("select! fail");
208 }
209
210 /// SDV test cases for select! panic! usage
211 ///
212 /// # Brief
213 /// 1. Uses select! to run two async task with `if false`.
214 /// 2. All branches will be disabled and select! will be panic!
215 #[test]
216 #[should_panic]
sdv_new_select_panicnull217 fn sdv_new_select_panic() {
218 async fn do_async1() {}
219
220 async fn do_async2() {}
221
222 let handle = ylong_runtime::spawn(async {
223 ylong_runtime::select! {
224 _ = do_async1(), if false => {},
225 _ = do_async2(), if false => {}
226 }
227 });
228 ylong_runtime::block_on(handle).expect("select! fail");
229 }
230