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(all(target_os = "linux", feature = "process"))]
15
16 use std::ffi::OsStr;
17 use std::path::Path;
18
19 use ylong_runtime::io::{AsyncReadExt, AsyncWriteExt};
20 use ylong_runtime::process::pty_process::{Pty, PtyCommand};
21
22 /// SDV test cases for pty_process basic.
23 ///
24 /// # Brief
25 /// 1. Create a `Pty` and a `Command`.
26 /// 2. Set configs.
27 /// 3. `spawn()` the child with pts of `Pty`.
28 #[test]
sdv_pty_process_test()29 fn sdv_pty_process_test() {
30 let handle = ylong_runtime::spawn(async {
31 let mut command = PtyCommand::new("echo");
32 assert_eq!(command.get_program(), "echo");
33
34 command.arg("first").args(["second"]);
35
36 let args: Vec<&OsStr> = command.get_args().collect();
37 assert_eq!(args, &["first", "second"]);
38
39 command.env("PATH", "/bin");
40 let envs: Vec<(&OsStr, Option<&OsStr>)> = command.get_envs().collect();
41 assert_eq!(envs, &[(OsStr::new("PATH"), Some(OsStr::new("/bin")))]);
42
43 command.env_remove("PATH");
44 let envs: Vec<(&OsStr, Option<&OsStr>)> = command.get_envs().collect();
45 assert_eq!(envs, &[(OsStr::new("PATH"), None)]);
46
47 command.env_clear();
48 let envs: Vec<(&OsStr, Option<&OsStr>)> = command.get_envs().collect();
49 assert!(envs.is_empty());
50
51 let envs = [(OsStr::new("TZ"), OsStr::new("test"))];
52 command.envs(envs);
53 let envs: Vec<(&OsStr, Option<&OsStr>)> = command.get_envs().collect();
54 assert_eq!(envs, &[(OsStr::new("TZ"), Some(OsStr::new("test")))]);
55
56 command.env_clear();
57 let envs: Vec<(&OsStr, Option<&OsStr>)> = command.get_envs().collect();
58 assert!(envs.is_empty());
59
60 command.current_dir("/bin");
61 assert_eq!(command.get_current_dir(), Some(Path::new("/bin")));
62 });
63 ylong_runtime::block_on(handle).unwrap();
64 }
65
66 /// SDV test cases for pty_process read and write.
67 ///
68 /// # Brief
69 /// 1. Create a `Pty` and a `Command`.
70 /// 2. `spawn()` the child with pts of `Pty`.
71 /// 3. Write `Pty` with arg.
72 /// 4. Read `Pty` with correct result.
73 #[test]
sdv_pty_process_read_and_write_test()74 fn sdv_pty_process_read_and_write_test() {
75 let arg = "hello world!";
76 ylong_runtime::block_on(async {
77 let mut pty = Pty::new().unwrap();
78 let pts = pty.pts().unwrap();
79
80 let mut command = PtyCommand::new("echo");
81 let mut child = command.spawn(&pts).unwrap();
82
83 pty.write_all(arg.as_bytes()).await.unwrap();
84
85 let status = child.wait().await.unwrap();
86 assert!(status.success());
87
88 let mut buf = [0; 14];
89 pty.read_exact(&mut buf).await.unwrap();
90 pty.flush().await.unwrap();
91 pty.shutdown().await.unwrap();
92 assert_eq!(String::from_utf8_lossy(&buf).replace(['\n', '\r'], ""), arg);
93 });
94 }
95
96 /// SDV test cases for pty split.
97 ///
98 /// # Brief
99 /// 1. Create a `Pty` and a `Command` with arg.
100 /// 2. `spawn()` the child with pts of `Pty`.
101 /// 3. Write read_pty with arg.
102 /// 4. Read write_pty with correct result.
103 #[test]
sdv_pty_split_test()104 fn sdv_pty_split_test() {
105 let arg = "hello world!";
106 ylong_runtime::block_on(async {
107 let mut pty = Pty::new().unwrap();
108 let pts = pty.pts().unwrap();
109 let (mut read_pty, mut write_pty) = pty.split();
110
111 let mut command = PtyCommand::new("echo");
112 let mut child = command.spawn(&pts).unwrap();
113
114 write_pty.resize(24, 80, 0, 0).expect("resize set fail!");
115 write_pty.write_all(arg.as_bytes()).await.unwrap();
116 write_pty.flush().await.unwrap();
117 write_pty.shutdown().await.unwrap();
118
119 let status = child.wait().await.unwrap();
120 assert!(status.success());
121
122 let mut buf = [0; 14];
123 read_pty.read_exact(&mut buf).await.unwrap();
124 assert_eq!(String::from_utf8_lossy(&buf).replace(['\n', '\r'], ""), arg);
125 });
126 }
127
128 /// SDV test cases for pty into_split.
129 ///
130 /// # Brief
131 /// 1. Create a `Pty` and a `Command` with arg.
132 /// 2. `spawn()` the child with pts of `Pty`.
133 /// 3. Write read_pty with arg.
134 /// 4. Read write_pty with correct result.
135 #[test]
sdv_pty_into_split_test()136 fn sdv_pty_into_split_test() {
137 let arg = "hello world!";
138 ylong_runtime::block_on(async {
139 let pty = Pty::new().unwrap();
140 let pts = pty.pts().unwrap();
141 let (mut read_pty, mut write_pty) = pty.into_split();
142
143 let mut command = PtyCommand::new("echo");
144 let mut child = command.spawn(&pts).unwrap();
145
146 write_pty.resize(24, 80, 0, 0).expect("resize set fail!");
147 write_pty.write_all(arg.as_bytes()).await.unwrap();
148 write_pty.flush().await.unwrap();
149 write_pty.shutdown().await.unwrap();
150
151 let status = child.wait().await.unwrap();
152 assert!(status.success());
153
154 let mut buf = [0; 14];
155 read_pty.read_exact(&mut buf).await.unwrap();
156 assert_eq!(String::from_utf8_lossy(&buf).replace(['\n', '\r'], ""), arg);
157 });
158 }
159
160 /// SDV test cases for pty unsplit.
161 ///
162 /// # Brief
163 /// 1. Create a `Pty` and a `Command` with arg.
164 /// 2. `unsplit()` read and write.
165 /// 3. `spawn()` the child with pts of `Pty`.
166 /// 4. Write pty with arg.
167 /// 5. Read pty with correct result.
168 #[test]
sdv_pty_unsplit_test()169 fn sdv_pty_unsplit_test() {
170 let arg = "hello world!";
171 ylong_runtime::block_on(async {
172 let pty = Pty::new().unwrap();
173 let pts = pty.pts().unwrap();
174 let (read_pty, write_pty) = pty.into_split();
175 let mut pty = Pty::unsplit(read_pty, write_pty).expect("unsplit fail!");
176
177 let mut command = PtyCommand::new("echo");
178 let mut child = command.spawn(&pts).unwrap();
179
180 pty.write_all(arg.as_bytes()).await.unwrap();
181
182 let status = child.wait().await.unwrap();
183 assert!(status.success());
184
185 let mut buf = [0; 14];
186 pty.read_exact(&mut buf).await.unwrap();
187 assert_eq!(String::from_utf8_lossy(&buf).replace(['\n', '\r'], ""), arg);
188 });
189 }
190
191 /// SDV test cases for pty debug.
192 ///
193 /// # Brief
194 /// 1. Debug pty and splitPty.
195 /// 2. Check format is correct.
196 #[test]
sdv_pty_debug_test()197 fn sdv_pty_debug_test() {
198 ylong_runtime::block_on(async {
199 let pty = Pty::new().unwrap();
200 let pts = pty.pts().unwrap();
201 assert!(format!("{pts:?}").contains("Pts(PtsInner(OwnedFd { fd:"));
202 let (read_pty, write_pty) = pty.into_split();
203 assert!(format!("{read_pty:?}")
204 .contains("SplitReadPty(Pty(AsyncSource { io: Some(PtyInner(OwnedFd { fd:"));
205 assert!(format!("{write_pty:?}")
206 .contains("SplitWritePty(Pty(AsyncSource { io: Some(PtyInner(OwnedFd { fd:"));
207 let mut pty = Pty::unsplit(read_pty, write_pty).expect("unsplit fail!");
208 let (read_pty, write_pty) = pty.split();
209 assert!(format!("{read_pty:?}")
210 .contains("BorrowReadPty(Pty(AsyncSource { io: Some(PtyInner(OwnedFd { fd:"));
211 assert!(format!("{write_pty:?}")
212 .contains("BorrowWritePty(Pty(AsyncSource { io: Some(PtyInner(OwnedFd { fd:"));
213 });
214 }
215