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 = "signal")] 15 16 #[cfg(unix)] 17 mod linux_test { 18 use std::os::raw::c_int; 19 use std::sync::atomic::AtomicUsize; 20 use std::sync::atomic::Ordering::{Acquire, Release}; 21 use std::sync::Arc; 22 23 use ylong_runtime::futures::poll_fn; 24 use ylong_runtime::signal::{signal, SignalKind}; 25 26 /// SDV cases of `SignalKind` conversion. 27 /// 28 /// # Brief 29 /// 1. Check the trait `From<c_int>` for `SignalKind`. 30 /// 2. Check the trait `From<SignalKind>` for `c_int`. 31 /// 3. Check the method `from_raw` of `SignalKind`. 32 /// 4. Check the method `as_raw` of `SignalKind`. 33 #[test] sdv_signal_from_and_into_c_int()34 fn sdv_signal_from_and_into_c_int() { 35 assert_eq!(SignalKind::from(1), SignalKind::hangup()); 36 assert_eq!(c_int::from(SignalKind::hangup()), 1); 37 assert_eq!(SignalKind::from_raw(2), SignalKind::interrupt()); 38 assert_eq!(SignalKind::interrupt().as_raw(), 2); 39 } 40 41 /// SDV cases for signal `recv()`. 42 /// 43 /// # Brief 44 /// 1. Generate a counter to ensure that notifications are received every 45 /// time listening. 46 /// 2. Spawns a task to loop and listen to a signal. 47 /// 3. Send notification signals in a loop until all waiting is completed. 48 #[test] sdv_signal_recv_test()49 fn sdv_signal_recv_test() { 50 let handle = ylong_runtime::spawn(async move { 51 let mut stream = signal(SignalKind::alarm()).unwrap(); 52 for _ in 0..10 { 53 unsafe { libc::raise(libc::SIGALRM) }; 54 stream.recv().await; 55 } 56 }); 57 let _ = ylong_runtime::block_on(handle); 58 } 59 60 /// SDV cases for signal `recv()` in multi thread. 61 /// 62 /// # Brief 63 /// 1. Generate a counter to confirm that all signals are waiting. 64 /// 2. Spawns some tasks to listen to a signal. 65 /// 3. Send a notification signal when all signals are waiting. 66 #[test] sdv_signal_recv_multi_thread_test()67 fn sdv_signal_recv_multi_thread_test() { 68 let num = Arc::new(AtomicUsize::new(0)); 69 let mut handles = Vec::new(); 70 for _ in 0..10 { 71 let num_clone = num.clone(); 72 handles.push(ylong_runtime::spawn(async move { 73 let mut stream = signal(SignalKind::child()).unwrap(); 74 num_clone.fetch_add(1, Release); 75 stream.recv().await; 76 })); 77 } 78 while num.load(Acquire) < 10 {} 79 unsafe { libc::raise(libc::SIGCHLD) }; 80 for handle in handles { 81 let _ = ylong_runtime::block_on(handle); 82 } 83 } 84 85 /// SDV cases for signal `poll_recv()`. 86 /// 87 /// # Brief 88 /// 1. Generate a counter to ensure that notifications are received every 89 /// time listening. 90 /// 2. Spawns a task to loop and listen to a signal. 91 /// 3. Send notification signals in a loop until all waiting is completed. 92 #[test] sdv_signal_poll_recv_test()93 fn sdv_signal_poll_recv_test() { 94 let handle = ylong_runtime::spawn(async move { 95 let mut stream = signal(SignalKind::hangup()).unwrap(); 96 for _ in 0..10 { 97 unsafe { libc::raise(libc::SIGHUP) }; 98 poll_fn(|cx| stream.poll_recv(cx)).await; 99 } 100 }); 101 let _ = ylong_runtime::block_on(handle); 102 } 103 104 /// SDV cases for signal `poll_recv()` in multi thread. 105 /// 106 /// # Brief 107 /// 1. Generate a counter to confirm that all signals are waiting. 108 /// 2. Spawns some tasks to listen to a signal. 109 /// 3. Send a notification signal when all signals are waiting. 110 #[test] sdv_signal_poll_recv_multi_thread_test()111 fn sdv_signal_poll_recv_multi_thread_test() { 112 let num = Arc::new(AtomicUsize::new(0)); 113 let mut handles = Vec::new(); 114 for _ in 0..10 { 115 let num_clone = num.clone(); 116 handles.push(ylong_runtime::spawn(async move { 117 let mut stream = signal(SignalKind::io()).unwrap(); 118 num_clone.fetch_add(1, Release); 119 stream.recv().await; 120 })); 121 } 122 while num.load(Acquire) < 10 {} 123 unsafe { libc::raise(libc::SIGIO) }; 124 for handle in handles { 125 let _ = ylong_runtime::block_on(handle); 126 } 127 } 128 129 /// SDV cases for SIGALRM signal. 130 /// 131 /// # Brief 132 /// 1. Generate the SIGALRM signal. 133 /// 2. Check the function of `signal` for the SIGALRM signal. 134 #[test] sdv_signal_alarm()135 fn sdv_signal_alarm() { 136 let handle = ylong_runtime::spawn(async move { 137 let mut signal = signal(SignalKind::alarm()).unwrap(); 138 unsafe { libc::raise(libc::SIGALRM) }; 139 signal.recv().await; 140 }); 141 let _ = ylong_runtime::block_on(handle); 142 } 143 144 /// SDV cases for SIGCHLD signal. 145 /// 146 /// # Brief 147 /// 1. Generate the SIGCHLD signal. 148 /// 2. Check the function of `signal` for the SIGCHLD signal. 149 #[test] sdv_signal_child()150 fn sdv_signal_child() { 151 let handle = ylong_runtime::spawn(async move { 152 let mut signal = signal(SignalKind::child()).unwrap(); 153 unsafe { libc::raise(libc::SIGCHLD) }; 154 signal.recv().await; 155 }); 156 let _ = ylong_runtime::block_on(handle); 157 } 158 159 /// SDV cases for SIGHUP signal. 160 /// 161 /// # Brief 162 /// 1. Generate the SIGHUP signal. 163 /// 2. Check the function of `signal` for the SIGHUP signal. 164 #[test] sdv_signal_hangup()165 fn sdv_signal_hangup() { 166 let handle = ylong_runtime::spawn(async move { 167 let mut signal = signal(SignalKind::hangup()).unwrap(); 168 unsafe { libc::raise(libc::SIGHUP) }; 169 signal.recv().await; 170 }); 171 let _ = ylong_runtime::block_on(handle); 172 } 173 174 /// SDV cases for SIGINT signal. 175 /// 176 /// # Brief 177 /// 1. Generate the SIGINT signal. 178 /// 2. Check the function of `signal` for the SIGINT signal. 179 #[test] sdv_signal_interrupt()180 fn sdv_signal_interrupt() { 181 let handle = ylong_runtime::spawn(async move { 182 let mut signal = signal(SignalKind::interrupt()).unwrap(); 183 unsafe { libc::raise(libc::SIGINT) }; 184 signal.recv().await; 185 }); 186 let _ = ylong_runtime::block_on(handle); 187 } 188 189 /// SDV cases for SIGIO signal. 190 /// 191 /// # Brief 192 /// 1. Generate the SIGIO signal. 193 /// 2. Check the function of `signal` for the SIGIO signal. 194 #[test] sdv_signal_io()195 fn sdv_signal_io() { 196 let handle = ylong_runtime::spawn(async move { 197 let mut signal = signal(SignalKind::io()).unwrap(); 198 unsafe { libc::raise(libc::SIGIO) }; 199 signal.recv().await; 200 }); 201 let _ = ylong_runtime::block_on(handle); 202 } 203 204 /// SDV cases for SIGPIPE signal. 205 /// 206 /// # Brief 207 /// 1. Generate the SIGPIPE signal. 208 /// 2. Check the function of `signal` for the SIGPIPE signal. 209 #[test] sdv_signal_pipe()210 fn sdv_signal_pipe() { 211 let handle = ylong_runtime::spawn(async move { 212 let mut signal = signal(SignalKind::pipe()).unwrap(); 213 unsafe { libc::raise(libc::SIGPIPE) }; 214 signal.recv().await; 215 }); 216 let _ = ylong_runtime::block_on(handle); 217 } 218 219 /// SDV cases for SIGTERM signal. 220 /// 221 /// # Brief 222 /// 1. Generate the SIGTERM signal. 223 /// 2. Check the function of `signal` for the SIGTERM signal. 224 #[test] sdv_signal_terminate()225 fn sdv_signal_terminate() { 226 let handle = ylong_runtime::spawn(async move { 227 let mut signal = signal(SignalKind::terminate()).unwrap(); 228 unsafe { libc::raise(libc::SIGTERM) }; 229 signal.recv().await; 230 }); 231 let _ = ylong_runtime::block_on(handle); 232 } 233 234 /// SDV cases for SIGUSR1 signal. 235 /// 236 /// # Brief 237 /// 1. Generate the SIGUSR1 signal. 238 /// 2. Check the function of `signal` for the SIGUSR1 signal. 239 #[test] sdv_signal_user_defined1()240 fn sdv_signal_user_defined1() { 241 let handle = ylong_runtime::spawn(async move { 242 let mut signal = signal(SignalKind::user_defined1()).unwrap(); 243 unsafe { libc::raise(libc::SIGUSR1) }; 244 signal.recv().await; 245 }); 246 let _ = ylong_runtime::block_on(handle); 247 } 248 249 /// SDV cases for SIGUSR2 signal. 250 /// 251 /// # Brief 252 /// 1. Generate the SIGUSR2 signal. 253 /// 2. Check the function of `signal` for the SIGUSR2 signal. 254 #[test] sdv_signal_user_defined2()255 fn sdv_signal_user_defined2() { 256 let handle = ylong_runtime::spawn(async move { 257 let mut signal = signal(SignalKind::user_defined2()).unwrap(); 258 unsafe { libc::raise(libc::SIGUSR2) }; 259 signal.recv().await; 260 }); 261 let _ = ylong_runtime::block_on(handle); 262 } 263 264 /// SDV cases for SIGWINCH signal. 265 /// 266 /// # Brief 267 /// 1. Generate the SIGWINCH signal. 268 /// 2. Check the function of `signal` for the SIGWINCH signal. 269 #[test] sdv_signal_window_change()270 fn sdv_signal_window_change() { 271 let handle = ylong_runtime::spawn(async move { 272 let mut signal = signal(SignalKind::window_change()).unwrap(); 273 unsafe { libc::raise(libc::SIGWINCH) }; 274 signal.recv().await; 275 }); 276 let _ = ylong_runtime::block_on(handle); 277 } 278 } 279