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