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(feature = "async", feature = "http1_1", feature = "ylong_base"))]
15
16 #[macro_use]
17 pub mod tcp_server;
18
19 use ylong_http::body::async_impl::Body;
20
21 use crate::tcp_server::{format_header_str, TcpHandle};
22
23 /// SDV test cases for `async::Client`.
24 ///
25 /// # Brief
26 /// 1. Starts a hyper server acts as proxy with the tokio coroutine.
27 /// 2. Creates an async::Client.
28 /// 3. The client sends a request message.
29 /// 4. Verifies the received request on the server.
30 /// 5. The server sends a response message.
31 /// 6. Verifies the received response on the client.
32 /// 7. Shuts down the server.
33 #[test]
sdv_async_client_send_request()34 fn sdv_async_client_send_request() {
35 let mut handles_vec = vec![];
36
37 start_tcp_server!(
38 ASYNC;
39 Proxy: true,
40 ServerNum: 1,
41 Handles: handles_vec,
42 Request: {
43 Method: "GET",
44 Path: "/data",
45 Header: "Content-Length", "6",
46 Body: "Hello!",
47 },
48 Response: {
49 Status: 201,
50 Version: "HTTP/1.1",
51 Header: "Content-Length", "11",
52 Body: "METHOD GET!",
53 },
54 );
55
56 let handle = handles_vec.pop().expect("No more handles !");
57 let client = ylong_http_client::async_impl::Client::builder()
58 .proxy(
59 ylong_http_client::Proxy::http(
60 format!("http://{}{}", handle.addr.as_str(), "/data").as_str(),
61 )
62 .build()
63 .expect("Http proxy build failed"),
64 )
65 .build()
66 .expect("Client build failed!");
67
68 let shutdown_handle = ylong_runtime::spawn(async move {
69 {
70 let request = build_client_request!(
71 Request: {
72 Method: "GET",
73 Path: "/data",
74 Addr: handle.addr.as_str(),
75 Header: "Content-Length", "6",
76 Body: "Hello!",
77 },
78 );
79
80 let mut response = client.request(request).await.expect("Request send failed");
81
82 assert_eq!(
83 response.status().as_u16(),
84 201,
85 "Assert response status code failed"
86 );
87 assert_eq!(
88 response.version().as_str(),
89 "HTTP/1.1",
90 "Assert response version failed"
91 );
92 assert_eq!(
93 response
94 .headers()
95 .get("Content-Length")
96 .unwrap_or_else(|| panic!(
97 "Get response header \"{}\" failed",
98 "Content-Length"
99 ))
100 .to_str()
101 .unwrap_or_else(|_| panic!(
102 "Convert response header \"{}\"into string failed",
103 "Content-Length"
104 )),
105 "11",
106 "Assert response header \"{}\" failed",
107 "Content-Length",
108 );
109 let mut buf = [0u8; 4096];
110 let mut size = 0;
111 loop {
112 let read = response
113 .body_mut()
114 .data(&mut buf[size..])
115 .await
116 .expect("Response body read failed");
117 if read == 0 {
118 break;
119 }
120 size += read;
121 }
122 assert_eq!(
123 &buf[..size],
124 "METHOD GET!".as_bytes(),
125 "Assert response body failed"
126 );
127 }
128 handle
129 .server_shutdown
130 .recv()
131 .expect("server send order failed !");
132 });
133 ylong_runtime::block_on(shutdown_handle).expect("Runtime wait for server shutdown failed");
134 }
135