1 // Copyright (c) 2025 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(feature = "async", feature = "tokio_base"))]
15
16 mod common;
17
18 use std::convert::Infallible;
19 use std::time::Instant;
20
21 use ylong_http::response::status::StatusCode;
22 use ylong_http_client::async_impl::{Body, Client, Request};
23
24 use crate::common::init_test_work_runtime;
25
server_fn( _req: hyper::Request<hyper::Body>, ) -> Result<hyper::Response<hyper::Body>, Infallible>26 async fn server_fn(
27 _req: hyper::Request<hyper::Body>,
28 ) -> Result<hyper::Response<hyper::Body>, Infallible> {
29 let response = hyper::Response::builder()
30 .status(hyper::StatusCode::OK)
31 .body(hyper::Body::empty())
32 .expect("build hyper response failed");
33 Ok(response)
34 }
35
36 #[test]
37 #[cfg(all(feature = "http1_1", not(feature = "__tls")))]
sdv_client_request_time_group_http1()38 fn sdv_client_request_time_group_http1() {
39 define_service_handle!(HTTP;);
40
41 let rt = init_test_work_runtime(4);
42
43 let (tx, rx) = std::sync::mpsc::channel();
44
45 rt.block_on(async move {
46 let mut handle = start_http_server!(HTTP; server_fn);
47 handle
48 .server_start
49 .recv()
50 .await
51 .expect("recv server start msg failed !");
52 tx.send(handle)
53 .expect("send Handle out the server coroutine failed !");
54 });
55
56 let mut handle = rx.recv().expect("recv Handle failed !");
57
58 let client = Client::builder().build().expect("Build Client failed.");
59
60 let request = Request::builder()
61 .url(format!("{}:{}", "127.0.0.1", handle.port).as_str())
62 .version("HTTP/1.1")
63 .method("GET")
64 .body(Body::empty())
65 .expect("Client build Request failed.");
66
67 rt.block_on(async move {
68 let start = Instant::now();
69 let response = client.request(request).await.expect("get response failed");
70 let cost = Instant::now() - start;
71 assert_eq!(response.status(), StatusCode::OK);
72
73 let time_group = response.time_group();
74 assert!(time_group.dns_duration().unwrap() < cost);
75 assert!(time_group.connect_duration().unwrap() < cost);
76 assert!(time_group.tcp_duration().unwrap() < cost);
77 assert!(time_group.transfer_duration().unwrap() < cost);
78
79 handle
80 .client_shutdown
81 .send(())
82 .await
83 .expect("send client shutdown");
84 handle
85 .server_shutdown
86 .recv()
87 .await
88 .expect("server shutdown");
89 })
90 }
91
92 #[test]
93 #[cfg(all(feature = "http1_1", feature = "__tls"))]
sdv_client_request_time_group_https1()94 fn sdv_client_request_time_group_https1() {
95 define_service_handle!(HTTPS;);
96
97 let rt = init_test_work_runtime(4);
98
99 let mut handles_vec = vec![];
100 start_server!(
101 HTTPS;
102 ServerNum: 1,
103 Runtime: rt,
104 Handles: handles_vec,
105 ServeFnName: server_fn,
106 );
107 let handle = handles_vec.pop().expect("No more handles !");
108
109 let client = Client::builder()
110 .danger_accept_invalid_certs(true)
111 .build()
112 .expect("Build Client failed.");
113
114 let request = Request::builder()
115 .url(format!("{}:{}", "127.0.0.1", handle.port).as_str())
116 .version("HTTP/1.1")
117 .method("GET")
118 .body(Body::empty())
119 .expect("Client build Request failed.");
120
121 rt.block_on(async move {
122 let start = Instant::now();
123 let response = client.request(request).await.expect("get response failed");
124 let cost = Instant::now() - start;
125 assert_eq!(response.status(), StatusCode::OK);
126
127 let time_group = response.time_group();
128 assert!(time_group.dns_duration().unwrap() < cost);
129 assert!(time_group.connect_duration().unwrap() < cost);
130 assert!(time_group.tls_duration().unwrap() < cost);
131 assert!(time_group.tcp_duration().unwrap() < cost);
132 assert!(time_group.transfer_duration().unwrap() < cost);
133 });
134 }
135
136 #[test]
137 #[cfg(all(feature = "http2", not(feature = "__tls")))]
sdv_client_request_time_group_http2()138 fn sdv_client_request_time_group_http2() {
139 define_service_handle!(HTTP;);
140
141 let rt = init_test_work_runtime(4);
142
143 let (tx, rx) = std::sync::mpsc::channel();
144
145 rt.block_on(async move {
146 let mut handle = start_http_server!(HTTP; server_fn);
147 handle
148 .server_start
149 .recv()
150 .await
151 .expect("recv server start msg failed !");
152 tx.send(handle)
153 .expect("send Handle out the server coroutine failed !");
154 });
155
156 let mut handle = rx.recv().expect("recv Handle failed !");
157
158 let client = Client::builder()
159 .http2_prior_knowledge()
160 .build()
161 .expect("Build Client failed.");
162
163 let request = Request::builder()
164 .url(format!("{}:{}", "127.0.0.1", handle.port).as_str())
165 .version("HTTP/2.0")
166 .method("GET")
167 .body(Body::empty())
168 .expect("Client build Request failed.");
169
170 rt.block_on(async move {
171 let start = Instant::now();
172 let response = client.request(request).await.expect("get response failed");
173 let cost = Instant::now() - start;
174 assert_eq!(response.status(), StatusCode::OK);
175
176 let time_group = response.time_group();
177 assert!(time_group.dns_duration().unwrap() < cost);
178 assert!(time_group.connect_duration().unwrap() < cost);
179 assert!(time_group.tcp_duration().unwrap() < cost);
180 assert!(time_group.transfer_duration().unwrap() < cost);
181
182 handle
183 .client_shutdown
184 .send(())
185 .await
186 .expect("send client shutdown");
187 handle
188 .server_shutdown
189 .recv()
190 .await
191 .expect("server shutdown");
192 })
193 }
194
195 #[test]
196 #[cfg(all(feature = "http1_1", not(feature = "__tls")))]
sdv_client_request_time_group_proxy()197 fn sdv_client_request_time_group_proxy() {
198 define_service_handle!(HTTP;);
199
200 let rt = init_test_work_runtime(4);
201
202 let (mut handle1, mut handle2) = rt.block_on(async move {
203 let mut handle1 = start_http_server!(HTTP; server_fn);
204 let mut handle2 = start_http_server!(HTTP; server_fn);
205 handle1
206 .server_start
207 .recv()
208 .await
209 .expect("recv server start msg failed !");
210 handle2
211 .server_start
212 .recv()
213 .await
214 .expect("recv server start msg failed !");
215 (handle1, handle2)
216 });
217
218 let client = Client::builder()
219 .proxy(
220 ylong_http_client::Proxy::http(
221 format!("http://{}:{}", "127.0.0.1", handle2.port).as_str(),
222 )
223 .build()
224 .unwrap(),
225 )
226 .build()
227 .expect("Build Client failed.");
228
229 let request = Request::builder()
230 .url(format!("{}:{}", "127.0.0.1", handle1.port).as_str())
231 .version("HTTP/1.1")
232 .method("GET")
233 .body(Body::empty())
234 .expect("Client build Request failed.");
235
236 rt.block_on(async move {
237 let start = Instant::now();
238 let response = client.request(request).await.expect("get response failed");
239 let cost = Instant::now() - start;
240 assert_eq!(response.status(), StatusCode::OK);
241
242 let time_group = response.time_group();
243 assert!(time_group.dns_duration().unwrap() < cost);
244 assert!(time_group.connect_duration().unwrap() < cost);
245 assert!(time_group.tcp_duration().unwrap() < cost);
246 assert!(time_group.transfer_duration().unwrap() < cost);
247
248 handle1
249 .client_shutdown
250 .send(())
251 .await
252 .expect("send client shutdown");
253 handle1
254 .server_shutdown
255 .recv()
256 .await
257 .expect("server shutdown");
258 handle2
259 .client_shutdown
260 .send(())
261 .await
262 .expect("send client shutdown");
263 handle2
264 .server_shutdown
265 .recv()
266 .await
267 .expect("server shutdown");
268 })
269 }
270
271 #[test]
272 #[cfg(all(feature = "http1_1", not(feature = "__tls")))]
sdv_client_request_time_group_redirect()273 fn sdv_client_request_time_group_redirect() {
274 define_service_handle!(HTTP;);
275
276 let rt = init_test_work_runtime(4);
277
278 let mut handle = rt.block_on(async move {
279 let mut handle = start_http_server!(HTTP; server_fn);
280 handle
281 .server_start
282 .recv()
283 .await
284 .expect("recv server start msg failed !");
285 handle
286 });
287
288 let client = Client::builder()
289 .redirect(ylong_http_client::Redirect::default())
290 .build()
291 .expect("Build Client failed.");
292
293 let request = Request::builder()
294 .url(format!("{}:{}", "127.0.0.1", handle.port).as_str())
295 .version("HTTP/1.1")
296 .method("GET")
297 .body(Body::empty())
298 .expect("Client build Request failed.");
299
300 rt.block_on(async move {
301 let start = Instant::now();
302 let response = client.request(request).await.expect("get response failed");
303 let cost = Instant::now() - start;
304 assert_eq!(response.status(), StatusCode::OK);
305
306 let time_group = response.time_group();
307 assert!(time_group.dns_duration().unwrap() < cost);
308 assert!(time_group.connect_duration().unwrap() < cost);
309 assert!(time_group.tcp_duration().unwrap() < cost);
310 assert!(time_group.transfer_duration().unwrap() < cost);
311
312 handle
313 .client_shutdown
314 .send(())
315 .await
316 .expect("send client shutdown");
317 handle
318 .server_shutdown
319 .recv()
320 .await
321 .expect("server shutdown");
322 })
323 }
324