• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #[macro_export]
15 macro_rules! async_client_test_case {
16     (
17         HTTPS;
18         ServeFnName: $server_fn_name: ident,
19         RootCA: $ca_file: expr,
20         RuntimeThreads: $thread_num: expr,
21         $(ClientNum: $client_num: expr,)?
22         $(Request: {
23             Method: $method: expr,
24             Host: $host: expr,
25             $(
26                 Header: $req_n: expr, $req_v: expr,
27             )*
28             Body: $req_body: expr,
29         },
30         Response: {
31             Status: $status: expr,
32             Version: $version: expr,
33             $(
34                 Header: $resp_n: expr, $resp_v: expr,
35             )*
36             Body: $resp_body: expr,
37         },)*
38     ) => {{
39         define_service_handle!(HTTPS;);
40         set_server_fn!(
41             ASYNC;
42             $server_fn_name,
43             $(Request: {
44                 Method: $method,
45                 $(
46                     Header: $req_n, $req_v,
47                 )*
48                 Body: $req_body,
49             },
50             Response: {
51                 Status: $status,
52                 Version: $version,
53                 $(
54                     Header: $resp_n, $resp_v,
55                 )*
56                 Body: $resp_body,
57             },)*
58         );
59 
60         let runtime = init_test_work_runtime($thread_num);
61         // The number of servers may be variable based on the number of servers set by the user.
62         // However, clippy checks that the variable does not need to be variable.
63         #[allow(unused_mut, unused_assignments)]
64         let mut server_num = 1;
65         $(server_num = $client_num;)?
66 
67         let mut handles_vec = vec![];
68         start_server!(
69             HTTPS;
70             ServerNum: server_num,
71             Runtime: runtime,
72             Handles: handles_vec,
73             ServeFnName: $server_fn_name,
74         );
75 
76         let mut shut_downs = vec![];
77         async_client_assert!(
78             HTTPS;
79             RootCA: $ca_file,
80             Runtime: runtime,
81             ServerNum: server_num,
82             Handles: handles_vec,
83             ShutDownHandles: shut_downs,
84             $(Request: {
85                 Method: $method,
86                 Host: $host,
87                 $(
88                     Header: $req_n, $req_v,
89                 )*
90                 Body: $req_body,
91             },
92             Response: {
93                 Status: $status,
94                 Version: $version,
95                 $(
96                     Header: $resp_n, $resp_v,
97                 )*
98                 Body: $resp_body,
99             },)*
100         );
101 
102         for shutdown_handle in shut_downs {
103             runtime.block_on(shutdown_handle).expect("Runtime wait for server shutdown failed");
104         }
105     }};
106     (
107         HTTP;
108         ServeFnName: $server_fn_name: ident,
109         RuntimeThreads: $thread_num: expr,
110         $(ClientNum: $client_num: expr,)?
111         $(Request: {
112             Method: $method: expr,
113             Host: $host: expr,
114             $(
115                 Header: $req_n: expr, $req_v: expr,
116             )*
117             Body: $req_body: expr,
118         },
119         Response: {
120             Status: $status: expr,
121             Version: $version: expr,
122             $(
123                 Header: $resp_n: expr, $resp_v: expr,
124             )*
125             Body: $resp_body: expr,
126         },)*
127     ) => {{
128         define_service_handle!(HTTP;);
129         set_server_fn!(
130             ASYNC;
131             $server_fn_name,
132             $(Request: {
133                 Method: $method,
134                 $(
135                     Header: $req_n, $req_v,
136                 )*
137                 Body: $req_body,
138             },
139             Response: {
140                 Status: $status,
141                 Version: $version,
142                 $(
143                     Header: $resp_n, $resp_v,
144                 )*
145                 Body: $resp_body,
146             },)*
147         );
148 
149         let runtime = init_test_work_runtime($thread_num);
150         // The number of servers may be variable based on the number of servers set by the user.
151         // However, clippy checks that the variable does not need to be variable.
152         #[allow(unused_mut, unused_assignments)]
153         let mut server_num = 1;
154         $(server_num = $client_num;)?
155         let mut handles_vec = vec![];
156 
157         start_server!(
158             HTTP;
159             ServerNum: server_num,
160             Runtime: runtime,
161             Handles: handles_vec,
162             ServeFnName: $server_fn_name,
163         );
164 
165         let mut shut_downs = vec![];
166         async_client_assert!(
167             HTTP;
168             Runtime: runtime,
169             ServerNum: server_num,
170             Handles: handles_vec,
171             ShutDownHandles: shut_downs,
172             $(Request: {
173                 Method: $method,
174                 Host: $host,
175                 $(
176                     Header: $req_n, $req_v,
177                 )*
178                 Body: $req_body,
179             },
180             Response: {
181                 Status: $status,
182                 Version: $version,
183                 $(
184                     Header: $resp_n, $resp_v,
185                 )*
186                 Body: $resp_body,
187             },)*
188         );
189 
190         for shutdown_handle in shut_downs {
191             runtime.block_on(shutdown_handle).expect("Runtime wait for server shutdown failed");
192         }
193     }};
194 
195 }
196 
197 #[macro_export]
198 macro_rules! async_client_assert {
199     (
200         HTTPS;
201         RootCA: $ca_file: expr,
202         Runtime: $runtime: expr,
203         ServerNum: $server_num: expr,
204         Handles: $handle_vec: expr,
205         ShutDownHandles: $shut_downs: expr,
206         $(Request: {
207             Method: $method: expr,
208             Host: $host: expr,
209             $(
210             Header: $req_n: expr, $req_v: expr,
211             )*
212             Body: $req_body: expr,
213         },
214         Response: {
215             Status: $status: expr,
216             Version: $version: expr,
217             $(
218             Header: $resp_n: expr, $resp_v: expr,
219             )*
220             Body: $resp_body: expr,
221         },)*
222     ) => {{
223         let client = ylong_http_client::async_impl::Client::builder()
224         .max_h1_conn_number(10)
225         .tls_ca_file($ca_file)
226         .danger_accept_invalid_hostnames(true)
227         .build()
228         .unwrap();
229         let client = std::sync::Arc::new(client);
230         for _i in 0..$server_num {
231             let handle = $handle_vec.pop().expect("No more handles !");
232             let client = std::sync::Arc::clone(&client);
233             let shutdown_handle = $runtime.spawn(async move {
234                 async_client_assertions!(
235                     ServerHandle: handle,
236                     ClientRef: client,
237                     $(Request: {
238                         Method: $method,
239                         Host: $host,
240                         $(
241                             Header: $req_n, $req_v,
242                         )*
243                         Body: $req_body,
244                     },
245                     Response: {
246                         Status: $status,
247                         Version: $version,
248                         $(
249                             Header: $resp_n, $resp_v,
250                         )*
251                         Body: $resp_body,
252                     },)*
253                 );
254             });
255             $shut_downs.push(shutdown_handle);
256         }
257     }};
258     (
259         HTTP;
260         Runtime: $runtime: expr,
261         ServerNum: $server_num: expr,
262         Handles: $handle_vec: expr,
263         ShutDownHandles: $shut_downs: expr,
264         $(Request: {
265             Method: $method: expr,
266             Host: $host: expr,
267             $(
268             Header: $req_n: expr, $req_v: expr,
269             )*
270             Body: $req_body: expr,
271         },
272         Response: {
273             Status: $status: expr,
274             Version: $version: expr,
275             $(
276             Header: $resp_n: expr, $resp_v: expr,
277             )*
278             Body: $resp_body: expr,
279         },)*
280     ) => {{
281         //let client = async_build_http_client();
282         let client = ylong_http_client::async_impl::Client::new();
283         let client = std::sync::Arc::new(client);
284         for _i in 0..$server_num {
285             let mut handle = $handle_vec.pop().expect("No more handles !");
286             let client = std::sync::Arc::clone(&client);
287             let shutdown_handle = $runtime.spawn(async move {
288                 async_client_assertions!(
289                     ServerHandle: handle,
290                     ClientRef: client,
291                     $(Request: {
292                         Method: $method,
293                         Host: $host,
294                         $(
295                             Header: $req_n, $req_v,
296                         )*
297                         Body: $req_body,
298                     },
299                     Response: {
300                         Status: $status,
301                         Version: $version,
302                         $(
303                             Header: $resp_n, $resp_v,
304                         )*
305                         Body: $resp_body,
306                     },)*
307                 );
308                 ensure_server_shutdown!(ServerHandle: handle);
309             });
310             $shut_downs.push(shutdown_handle);
311         }
312     }}
313 }
314 
315 #[macro_export]
316 macro_rules! async_client_assertions {
317     (
318         ServerHandle: $handle:expr,
319         ClientRef: $client:expr,
320         $(Request: {
321             Method: $method: expr,
322             Host: $host: expr,
323             $(
324             Header: $req_n: expr, $req_v: expr,
325             )*
326             Body: $req_body: expr,
327         },
328         Response: {
329             Status: $status: expr,
330             Version: $version: expr,
331             $(
332                 Header: $resp_n: expr, $resp_v: expr,
333             )*
334             Body: $resp_body: expr,
335         },)*
336     ) => {
337         $(
338             let request = ylong_http_client::async_impl::Request::builder()
339                 .method($method)
340                 .url(format!("{}:{}", $host, $handle.port).as_str())
341                 $(.header($req_n, $req_v))*
342                 .body(ylong_http_client::async_impl::Body::slice($req_body))
343                 .expect("Request build failed");
344 
345             let mut response = $client
346                 .request(request)
347                 .await
348                 .expect("Request send failed");
349 
350             assert_eq!(response.status().as_u16(), $status, "Assert response status code failed") ;
351             assert_eq!(response.version().as_str(), $version, "Assert response version failed");
352             $(assert_eq!(
353                 response
354                     .headers()
355                     .get($resp_n)
356                     .expect(format!("Get response header \"{}\" failed", $resp_n).as_str())
357                     .to_string()
358                     .expect(format!("Convert response header \"{}\"into string failed", $resp_n).as_str()),
359                 $resp_v,
360                 "Assert response header \"{}\" failed", $resp_n,
361             );)*
362             let mut buf = [0u8; 4096];
363             let mut size = 0;
364             loop {
365                 let read = response
366                     .data(&mut buf[size..]).await
367                     .expect("Response body read failed");
368                 if read == 0 {
369                     break;
370                 }
371                 size += read;
372             }
373             assert_eq!(&buf[..size], $resp_body.as_bytes(), "Assert response body failed");
374         )*
375     }
376 }
377