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 Version: "HTTP/1.1",
45 Path: "/data",
46 Header: "Content-Length", "6",
47 Header: "Accept", "*/*",
48 Body: "Hello!",
49 },
50 Response: {
51 Status: 201,
52 Version: "HTTP/1.1",
53 Header: "Content-Length", "11",
54 Body: "METHOD GET!",
55 },
56 );
57
58 let handle = handles_vec.pop().expect("No more handles !");
59 let client = ylong_http_client::async_impl::Client::builder()
60 .proxy(
61 ylong_http_client::Proxy::http(
62 format!("http://{}{}", handle.addr.as_str(), "/data").as_str(),
63 )
64 .build()
65 .expect("Http proxy build failed"),
66 )
67 .build()
68 .expect("Client build failed!");
69
70 let shutdown_handle = ylong_runtime::spawn(async move {
71 {
72 let request = build_client_request!(
73 Request: {
74 Method: "GET",
75 Path: "/data",
76 Addr: handle.addr.as_str(),
77 Header: "Content-Length", "6",
78 Body: "Hello!",
79 },
80 );
81
82 let mut response = client.request(request).await.expect("Request send failed");
83
84 assert_eq!(
85 response.status().as_u16(),
86 201,
87 "Assert response status code failed"
88 );
89 assert_eq!(
90 response.version().as_str(),
91 "HTTP/1.1",
92 "Assert response version failed"
93 );
94 assert_eq!(
95 response
96 .headers()
97 .get("Content-Length")
98 .unwrap_or_else(|| panic!(
99 "Get response header \"{}\" failed",
100 "Content-Length"
101 ))
102 .to_string()
103 .unwrap_or_else(|_| panic!(
104 "Convert response header \"{}\"into string failed",
105 "Content-Length"
106 )),
107 "11",
108 "Assert response header \"{}\" failed",
109 "Content-Length",
110 );
111 let mut buf = [0u8; 4096];
112 let mut size = 0;
113 loop {
114 let read = response
115 .body_mut()
116 .data(&mut buf[size..])
117 .await
118 .expect("Response body read failed");
119 if read == 0 {
120 break;
121 }
122 size += read;
123 }
124 assert_eq!(
125 &buf[..size],
126 "METHOD GET!".as_bytes(),
127 "Assert response body failed"
128 );
129 }
130 handle
131 .server_shutdown
132 .recv()
133 .expect("server send order failed !");
134 });
135 ylong_runtime::block_on(shutdown_handle).expect("Runtime wait for server shutdown failed");
136 }
137