16dbb5987Sopenharmony_ci// Copyright (c) 2023 Huawei Device Co., Ltd. 26dbb5987Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 36dbb5987Sopenharmony_ci// you may not use this file except in compliance with the License. 46dbb5987Sopenharmony_ci// You may obtain a copy of the License at 56dbb5987Sopenharmony_ci// 66dbb5987Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 76dbb5987Sopenharmony_ci// 86dbb5987Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 96dbb5987Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 106dbb5987Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 116dbb5987Sopenharmony_ci// See the License for the specific language governing permissions and 126dbb5987Sopenharmony_ci// limitations under the License. 136dbb5987Sopenharmony_ci 146dbb5987Sopenharmony_ci#[cfg(feature = "async")] 156dbb5987Sopenharmony_cimod async_utils; 166dbb5987Sopenharmony_ci 176dbb5987Sopenharmony_ci#[cfg(feature = "sync")] 186dbb5987Sopenharmony_cimod sync_utils; 196dbb5987Sopenharmony_ci 206dbb5987Sopenharmony_ciuse tokio::runtime::Runtime; 216dbb5987Sopenharmony_ci 226dbb5987Sopenharmony_cimacro_rules! define_service_handle { 236dbb5987Sopenharmony_ci ( 246dbb5987Sopenharmony_ci HTTP; 256dbb5987Sopenharmony_ci ) => { 266dbb5987Sopenharmony_ci use tokio::sync::mpsc::{Receiver, Sender}; 276dbb5987Sopenharmony_ci 286dbb5987Sopenharmony_ci pub struct HttpHandle { 296dbb5987Sopenharmony_ci pub port: u16, 306dbb5987Sopenharmony_ci 316dbb5987Sopenharmony_ci // This channel allows the server to notify the client when it is up and running. 326dbb5987Sopenharmony_ci pub server_start: Receiver<()>, 336dbb5987Sopenharmony_ci 346dbb5987Sopenharmony_ci // This channel allows the client to notify the server when it is ready to shut down. 356dbb5987Sopenharmony_ci pub client_shutdown: Sender<()>, 366dbb5987Sopenharmony_ci 376dbb5987Sopenharmony_ci // This channel allows the server to notify the client when it has shut down. 386dbb5987Sopenharmony_ci pub server_shutdown: Receiver<()>, 396dbb5987Sopenharmony_ci } 406dbb5987Sopenharmony_ci }; 416dbb5987Sopenharmony_ci ( 426dbb5987Sopenharmony_ci HTTPS; 436dbb5987Sopenharmony_ci ) => { 446dbb5987Sopenharmony_ci pub struct TlsHandle { 456dbb5987Sopenharmony_ci pub port: u16, 466dbb5987Sopenharmony_ci } 476dbb5987Sopenharmony_ci }; 486dbb5987Sopenharmony_ci} 496dbb5987Sopenharmony_ci 506dbb5987Sopenharmony_ci#[macro_export] 516dbb5987Sopenharmony_cimacro_rules! start_server { 526dbb5987Sopenharmony_ci ( 536dbb5987Sopenharmony_ci HTTPS; 546dbb5987Sopenharmony_ci ServerNum: $server_num: expr, 556dbb5987Sopenharmony_ci Runtime: $runtime: expr, 566dbb5987Sopenharmony_ci Handles: $handle_vec: expr, 576dbb5987Sopenharmony_ci ServeFnName: $service_fn: ident, 586dbb5987Sopenharmony_ci ) => {{ 596dbb5987Sopenharmony_ci for _i in 0..$server_num { 606dbb5987Sopenharmony_ci let (tx, rx) = std::sync::mpsc::channel(); 616dbb5987Sopenharmony_ci let server_handle = $runtime.spawn(async move { 626dbb5987Sopenharmony_ci let handle = start_http_server!( 636dbb5987Sopenharmony_ci HTTPS; 646dbb5987Sopenharmony_ci $service_fn 656dbb5987Sopenharmony_ci ); 666dbb5987Sopenharmony_ci tx.send(handle) 676dbb5987Sopenharmony_ci .expect("Failed to send the handle to the test thread."); 686dbb5987Sopenharmony_ci }); 696dbb5987Sopenharmony_ci $runtime 706dbb5987Sopenharmony_ci .block_on(server_handle) 716dbb5987Sopenharmony_ci .expect("Runtime start server coroutine failed"); 726dbb5987Sopenharmony_ci let handle = rx 736dbb5987Sopenharmony_ci .recv() 746dbb5987Sopenharmony_ci .expect("Handle send channel (Server-Half) be closed unexpectedly"); 756dbb5987Sopenharmony_ci $handle_vec.push(handle); 766dbb5987Sopenharmony_ci } 776dbb5987Sopenharmony_ci }}; 786dbb5987Sopenharmony_ci ( 796dbb5987Sopenharmony_ci HTTP; 806dbb5987Sopenharmony_ci ServerNum: $server_num: expr, 816dbb5987Sopenharmony_ci Runtime: $runtime: expr, 826dbb5987Sopenharmony_ci Handles: $handle_vec: expr, 836dbb5987Sopenharmony_ci ServeFnName: $service_fn: ident, 846dbb5987Sopenharmony_ci ) => {{ 856dbb5987Sopenharmony_ci for _i in 0..$server_num { 866dbb5987Sopenharmony_ci let (tx, rx) = std::sync::mpsc::channel(); 876dbb5987Sopenharmony_ci let server_handle = $runtime.spawn(async move { 886dbb5987Sopenharmony_ci let mut handle = start_http_server!( 896dbb5987Sopenharmony_ci HTTP; 906dbb5987Sopenharmony_ci $service_fn 916dbb5987Sopenharmony_ci ); 926dbb5987Sopenharmony_ci handle 936dbb5987Sopenharmony_ci .server_start 946dbb5987Sopenharmony_ci .recv() 956dbb5987Sopenharmony_ci .await 966dbb5987Sopenharmony_ci .expect("Start channel (Server-Half) be closed unexpectedly"); 976dbb5987Sopenharmony_ci tx.send(handle) 986dbb5987Sopenharmony_ci .expect("Failed to send the handle to the test thread."); 996dbb5987Sopenharmony_ci }); 1006dbb5987Sopenharmony_ci $runtime 1016dbb5987Sopenharmony_ci .block_on(server_handle) 1026dbb5987Sopenharmony_ci .expect("Runtime start server coroutine failed"); 1036dbb5987Sopenharmony_ci let handle = rx 1046dbb5987Sopenharmony_ci .recv() 1056dbb5987Sopenharmony_ci .expect("Handle send channel (Server-Half) be closed unexpectedly"); 1066dbb5987Sopenharmony_ci $handle_vec.push(handle); 1076dbb5987Sopenharmony_ci } 1086dbb5987Sopenharmony_ci }}; 1096dbb5987Sopenharmony_ci} 1106dbb5987Sopenharmony_ci 1116dbb5987Sopenharmony_ci#[macro_export] 1126dbb5987Sopenharmony_cimacro_rules! start_http_server { 1136dbb5987Sopenharmony_ci ( 1146dbb5987Sopenharmony_ci HTTP; 1156dbb5987Sopenharmony_ci $server_fn: ident 1166dbb5987Sopenharmony_ci ) => {{ 1176dbb5987Sopenharmony_ci use hyper::service::{make_service_fn, service_fn}; 1186dbb5987Sopenharmony_ci use std::convert::Infallible; 1196dbb5987Sopenharmony_ci use tokio::sync::mpsc::channel; 1206dbb5987Sopenharmony_ci 1216dbb5987Sopenharmony_ci let (start_tx, start_rx) = channel::<()>(1); 1226dbb5987Sopenharmony_ci let (client_tx, mut client_rx) = channel::<()>(1); 1236dbb5987Sopenharmony_ci let (server_tx, server_rx) = channel::<()>(1); 1246dbb5987Sopenharmony_ci 1256dbb5987Sopenharmony_ci let tcp_listener = std::net::TcpListener::bind("127.0.0.1:0").expect("server bind port failed !"); 1266dbb5987Sopenharmony_ci let addr = tcp_listener.local_addr().expect("get server local address failed!"); 1276dbb5987Sopenharmony_ci let port = addr.port(); 1286dbb5987Sopenharmony_ci let server = hyper::Server::from_tcp(tcp_listener).expect("build hyper server from tcp listener failed !"); 1296dbb5987Sopenharmony_ci 1306dbb5987Sopenharmony_ci tokio::spawn(async move { 1316dbb5987Sopenharmony_ci let make_svc = 1326dbb5987Sopenharmony_ci make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn($server_fn)) }); 1336dbb5987Sopenharmony_ci server 1346dbb5987Sopenharmony_ci .serve(make_svc) 1356dbb5987Sopenharmony_ci .with_graceful_shutdown(async { 1366dbb5987Sopenharmony_ci start_tx 1376dbb5987Sopenharmony_ci .send(()) 1386dbb5987Sopenharmony_ci .await 1396dbb5987Sopenharmony_ci .expect("Start channel (Client-Half) be closed unexpectedly"); 1406dbb5987Sopenharmony_ci client_rx 1416dbb5987Sopenharmony_ci .recv() 1426dbb5987Sopenharmony_ci .await 1436dbb5987Sopenharmony_ci .expect("Client channel (Client-Half) be closed unexpectedly"); 1446dbb5987Sopenharmony_ci }) 1456dbb5987Sopenharmony_ci .await 1466dbb5987Sopenharmony_ci .expect("Start server failed"); 1476dbb5987Sopenharmony_ci server_tx 1486dbb5987Sopenharmony_ci .send(()) 1496dbb5987Sopenharmony_ci .await 1506dbb5987Sopenharmony_ci .expect("Server channel (Client-Half) be closed unexpectedly"); 1516dbb5987Sopenharmony_ci }); 1526dbb5987Sopenharmony_ci 1536dbb5987Sopenharmony_ci HttpHandle { 1546dbb5987Sopenharmony_ci port, 1556dbb5987Sopenharmony_ci server_start: start_rx, 1566dbb5987Sopenharmony_ci client_shutdown: client_tx, 1576dbb5987Sopenharmony_ci server_shutdown: server_rx, 1586dbb5987Sopenharmony_ci } 1596dbb5987Sopenharmony_ci }}; 1606dbb5987Sopenharmony_ci ( 1616dbb5987Sopenharmony_ci HTTPS; 1626dbb5987Sopenharmony_ci $service_fn: ident 1636dbb5987Sopenharmony_ci ) => {{ 1646dbb5987Sopenharmony_ci let mut port = 10000; 1656dbb5987Sopenharmony_ci let listener = loop { 1666dbb5987Sopenharmony_ci let addr = std::net::SocketAddr::from(([127, 0, 0, 1], port)); 1676dbb5987Sopenharmony_ci match tokio::net::TcpListener::bind(addr).await { 1686dbb5987Sopenharmony_ci Ok(listener) => break listener, 1696dbb5987Sopenharmony_ci Err(_) => { 1706dbb5987Sopenharmony_ci port += 1; 1716dbb5987Sopenharmony_ci if port == u16::MAX { 1726dbb5987Sopenharmony_ci port = 10000; 1736dbb5987Sopenharmony_ci } 1746dbb5987Sopenharmony_ci continue; 1756dbb5987Sopenharmony_ci } 1766dbb5987Sopenharmony_ci } 1776dbb5987Sopenharmony_ci }; 1786dbb5987Sopenharmony_ci let port = listener.local_addr().unwrap().port(); 1796dbb5987Sopenharmony_ci 1806dbb5987Sopenharmony_ci tokio::spawn(async move { 1816dbb5987Sopenharmony_ci let mut acceptor = openssl::ssl::SslAcceptor::mozilla_intermediate(openssl::ssl::SslMethod::tls()) 1826dbb5987Sopenharmony_ci .expect("SslAcceptorBuilder error"); 1836dbb5987Sopenharmony_ci acceptor 1846dbb5987Sopenharmony_ci .set_session_id_context(b"test") 1856dbb5987Sopenharmony_ci .expect("Set session id error"); 1866dbb5987Sopenharmony_ci acceptor 1876dbb5987Sopenharmony_ci .set_private_key_file("tests/file/key.pem", openssl::ssl::SslFiletype::PEM) 1886dbb5987Sopenharmony_ci .expect("Set private key error"); 1896dbb5987Sopenharmony_ci acceptor 1906dbb5987Sopenharmony_ci .set_certificate_chain_file("tests/file/cert.pem") 1916dbb5987Sopenharmony_ci .expect("Set cert error"); 1926dbb5987Sopenharmony_ci acceptor.set_alpn_protos(b"\x08http/1.1").unwrap(); 1936dbb5987Sopenharmony_ci acceptor.set_alpn_select_callback(|_, client| { 1946dbb5987Sopenharmony_ci openssl::ssl::select_next_proto(b"\x08http/1.1", client).ok_or(openssl::ssl::AlpnError::NOACK) 1956dbb5987Sopenharmony_ci }); 1966dbb5987Sopenharmony_ci 1976dbb5987Sopenharmony_ci let acceptor = acceptor.build(); 1986dbb5987Sopenharmony_ci 1996dbb5987Sopenharmony_ci let (stream, _) = listener.accept().await.expect("TCP listener accept error"); 2006dbb5987Sopenharmony_ci let ssl = openssl::ssl::Ssl::new(acceptor.context()).expect("Ssl Error"); 2016dbb5987Sopenharmony_ci let mut stream = tokio_openssl::SslStream::new(ssl, stream).expect("SslStream Error"); 2026dbb5987Sopenharmony_ci core::pin::Pin::new(&mut stream).accept().await.unwrap(); // SSL negotiation finished successfully 2036dbb5987Sopenharmony_ci 2046dbb5987Sopenharmony_ci hyper::server::conn::Http::new() 2056dbb5987Sopenharmony_ci .http1_only(true) 2066dbb5987Sopenharmony_ci .http1_keep_alive(true) 2076dbb5987Sopenharmony_ci .serve_connection(stream, hyper::service::service_fn($service_fn)) 2086dbb5987Sopenharmony_ci .await 2096dbb5987Sopenharmony_ci }); 2106dbb5987Sopenharmony_ci 2116dbb5987Sopenharmony_ci TlsHandle { 2126dbb5987Sopenharmony_ci port, 2136dbb5987Sopenharmony_ci } 2146dbb5987Sopenharmony_ci }}; 2156dbb5987Sopenharmony_ci} 2166dbb5987Sopenharmony_ci 2176dbb5987Sopenharmony_ci/// Creates a `Request`. 2186dbb5987Sopenharmony_ci#[macro_export] 2196dbb5987Sopenharmony_ci#[cfg(feature = "sync")] 2206dbb5987Sopenharmony_cimacro_rules! ylong_request { 2216dbb5987Sopenharmony_ci ( 2226dbb5987Sopenharmony_ci Request: { 2236dbb5987Sopenharmony_ci Method: $method: expr, 2246dbb5987Sopenharmony_ci Host: $host: expr, 2256dbb5987Sopenharmony_ci Port: $port: expr, 2266dbb5987Sopenharmony_ci $( 2276dbb5987Sopenharmony_ci Header: $req_n: expr, $req_v: expr, 2286dbb5987Sopenharmony_ci )* 2296dbb5987Sopenharmony_ci Body: $req_body: expr, 2306dbb5987Sopenharmony_ci }, 2316dbb5987Sopenharmony_ci ) => { 2326dbb5987Sopenharmony_ci ylong_http::request::RequestBuilder::new() 2336dbb5987Sopenharmony_ci .method($method) 2346dbb5987Sopenharmony_ci .url(format!("{}:{}", $host, $port).as_str()) 2356dbb5987Sopenharmony_ci $(.header($req_n, $req_v))* 2366dbb5987Sopenharmony_ci .body(ylong_http::body::TextBody::from_bytes($req_body.as_bytes())) 2376dbb5987Sopenharmony_ci .expect("Request build failed") 2386dbb5987Sopenharmony_ci }; 2396dbb5987Sopenharmony_ci} 2406dbb5987Sopenharmony_ci 2416dbb5987Sopenharmony_ci/// Creates a `Request`. 2426dbb5987Sopenharmony_ci#[macro_export] 2436dbb5987Sopenharmony_ci#[cfg(feature = "async")] 2446dbb5987Sopenharmony_cimacro_rules! ylong_request { 2456dbb5987Sopenharmony_ci ( 2466dbb5987Sopenharmony_ci Request: { 2476dbb5987Sopenharmony_ci Method: $method: expr, 2486dbb5987Sopenharmony_ci Host: $host: expr, 2496dbb5987Sopenharmony_ci Port: $port: expr, 2506dbb5987Sopenharmony_ci $( 2516dbb5987Sopenharmony_ci Header: $req_n: expr, $req_v: expr, 2526dbb5987Sopenharmony_ci )* 2536dbb5987Sopenharmony_ci Body: $req_body: expr, 2546dbb5987Sopenharmony_ci }, 2556dbb5987Sopenharmony_ci ) => { 2566dbb5987Sopenharmony_ci ylong_http_client::async_impl::RequestBuilder::new() 2576dbb5987Sopenharmony_ci .method($method) 2586dbb5987Sopenharmony_ci .url(format!("{}:{}", $host, $port).as_str()) 2596dbb5987Sopenharmony_ci $(.header($req_n, $req_v))* 2606dbb5987Sopenharmony_ci .body(ylong_http_client::async_impl::Body::slice($req_body.as_bytes())) 2616dbb5987Sopenharmony_ci .expect("Request build failed") 2626dbb5987Sopenharmony_ci }; 2636dbb5987Sopenharmony_ci} 2646dbb5987Sopenharmony_ci 2656dbb5987Sopenharmony_ci/// Sets server async function. 2666dbb5987Sopenharmony_ci#[macro_export] 2676dbb5987Sopenharmony_cimacro_rules! set_server_fn { 2686dbb5987Sopenharmony_ci ( 2696dbb5987Sopenharmony_ci ASYNC; 2706dbb5987Sopenharmony_ci $server_fn_name: ident, 2716dbb5987Sopenharmony_ci $(Request: { 2726dbb5987Sopenharmony_ci Method: $method: expr, 2736dbb5987Sopenharmony_ci $( 2746dbb5987Sopenharmony_ci Header: $req_n: expr, $req_v: expr, 2756dbb5987Sopenharmony_ci )* 2766dbb5987Sopenharmony_ci Body: $req_body: expr, 2776dbb5987Sopenharmony_ci }, 2786dbb5987Sopenharmony_ci Response: { 2796dbb5987Sopenharmony_ci Status: $status: expr, 2806dbb5987Sopenharmony_ci Version: $version: expr, 2816dbb5987Sopenharmony_ci $( 2826dbb5987Sopenharmony_ci Header: $resp_n: expr, $resp_v: expr, 2836dbb5987Sopenharmony_ci )* 2846dbb5987Sopenharmony_ci Body: $resp_body: expr, 2856dbb5987Sopenharmony_ci },)* 2866dbb5987Sopenharmony_ci ) => { 2876dbb5987Sopenharmony_ci async fn $server_fn_name(request: hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, std::convert::Infallible> { 2886dbb5987Sopenharmony_ci match request.method().as_str() { 2896dbb5987Sopenharmony_ci // TODO If there are requests with the same Method, an error will be reported for creating two identical match branches. 2906dbb5987Sopenharmony_ci $( 2916dbb5987Sopenharmony_ci $method => { 2926dbb5987Sopenharmony_ci assert_eq!($method, request.method().as_str(), "Assert request method failed"); 2936dbb5987Sopenharmony_ci assert_eq!( 2946dbb5987Sopenharmony_ci "/", 2956dbb5987Sopenharmony_ci request.uri().to_string(), 2966dbb5987Sopenharmony_ci "Assert request host failed", 2976dbb5987Sopenharmony_ci ); 2986dbb5987Sopenharmony_ci assert_eq!( 2996dbb5987Sopenharmony_ci $version, 3006dbb5987Sopenharmony_ci format!("{:?}", request.version()), 3016dbb5987Sopenharmony_ci "Assert request version failed", 3026dbb5987Sopenharmony_ci ); 3036dbb5987Sopenharmony_ci $(assert_eq!( 3046dbb5987Sopenharmony_ci $req_v, 3056dbb5987Sopenharmony_ci request 3066dbb5987Sopenharmony_ci .headers() 3076dbb5987Sopenharmony_ci .get($req_n) 3086dbb5987Sopenharmony_ci .expect(format!("Get request header \"{}\" failed", $req_n).as_str()) 3096dbb5987Sopenharmony_ci .to_str() 3106dbb5987Sopenharmony_ci .expect(format!("Convert request header \"{}\" into string failed", $req_n).as_str()), 3116dbb5987Sopenharmony_ci "Assert request header {} failed", $req_n, 3126dbb5987Sopenharmony_ci );)* 3136dbb5987Sopenharmony_ci let body = hyper::body::to_bytes(request.into_body()).await 3146dbb5987Sopenharmony_ci .expect("Get request body failed"); 3156dbb5987Sopenharmony_ci assert_eq!($req_body.as_bytes(), body, "Assert request body failed"); 3166dbb5987Sopenharmony_ci Ok( 3176dbb5987Sopenharmony_ci hyper::Response::builder() 3186dbb5987Sopenharmony_ci .version(hyper::Version::HTTP_11) 3196dbb5987Sopenharmony_ci .status($status) 3206dbb5987Sopenharmony_ci $(.header($resp_n, $resp_v))* 3216dbb5987Sopenharmony_ci .body($resp_body.into()) 3226dbb5987Sopenharmony_ci .expect("Build response failed") 3236dbb5987Sopenharmony_ci ) 3246dbb5987Sopenharmony_ci }, 3256dbb5987Sopenharmony_ci )* 3266dbb5987Sopenharmony_ci _ => {panic!("Unrecognized METHOD !");}, 3276dbb5987Sopenharmony_ci } 3286dbb5987Sopenharmony_ci } 3296dbb5987Sopenharmony_ci 3306dbb5987Sopenharmony_ci }; 3316dbb5987Sopenharmony_ci ( 3326dbb5987Sopenharmony_ci SYNC; 3336dbb5987Sopenharmony_ci $server_fn_name: ident, 3346dbb5987Sopenharmony_ci $(Request: { 3356dbb5987Sopenharmony_ci Method: $method: expr, 3366dbb5987Sopenharmony_ci $( 3376dbb5987Sopenharmony_ci Header: $req_n: expr, $req_v: expr, 3386dbb5987Sopenharmony_ci )* 3396dbb5987Sopenharmony_ci Body: $req_body: expr, 3406dbb5987Sopenharmony_ci }, 3416dbb5987Sopenharmony_ci Response: { 3426dbb5987Sopenharmony_ci Status: $status: expr, 3436dbb5987Sopenharmony_ci Version: $version: expr, 3446dbb5987Sopenharmony_ci $( 3456dbb5987Sopenharmony_ci Header: $resp_n: expr, $resp_v: expr, 3466dbb5987Sopenharmony_ci )* 3476dbb5987Sopenharmony_ci Body: $resp_body: expr, 3486dbb5987Sopenharmony_ci },)* 3496dbb5987Sopenharmony_ci ) => { 3506dbb5987Sopenharmony_ci async fn $server_fn_name(request: hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, std::convert::Infallible> { 3516dbb5987Sopenharmony_ci match request.method().as_str() { 3526dbb5987Sopenharmony_ci // TODO If there are requests with the same Method, an error will be reported for creating two identical match branches. 3536dbb5987Sopenharmony_ci $( 3546dbb5987Sopenharmony_ci $method => { 3556dbb5987Sopenharmony_ci assert_eq!($method, request.method().as_str(), "Assert request method failed"); 3566dbb5987Sopenharmony_ci assert_eq!( 3576dbb5987Sopenharmony_ci "/", 3586dbb5987Sopenharmony_ci request.uri().to_string(), 3596dbb5987Sopenharmony_ci "Assert request uri failed", 3606dbb5987Sopenharmony_ci ); 3616dbb5987Sopenharmony_ci assert_eq!( 3626dbb5987Sopenharmony_ci $version, 3636dbb5987Sopenharmony_ci format!("{:?}", request.version()), 3646dbb5987Sopenharmony_ci "Assert request version failed", 3656dbb5987Sopenharmony_ci ); 3666dbb5987Sopenharmony_ci $(assert_eq!( 3676dbb5987Sopenharmony_ci $req_v, 3686dbb5987Sopenharmony_ci request 3696dbb5987Sopenharmony_ci .headers() 3706dbb5987Sopenharmony_ci .get($req_n) 3716dbb5987Sopenharmony_ci .expect(format!("Get request header \"{}\" failed", $req_n).as_str()) 3726dbb5987Sopenharmony_ci .to_str() 3736dbb5987Sopenharmony_ci .expect(format!("Convert request header \"{}\" into string failed", $req_n).as_str()), 3746dbb5987Sopenharmony_ci "Assert request header {} failed", $req_n, 3756dbb5987Sopenharmony_ci );)* 3766dbb5987Sopenharmony_ci let body = hyper::body::to_bytes(request.into_body()).await 3776dbb5987Sopenharmony_ci .expect("Get request body failed"); 3786dbb5987Sopenharmony_ci assert_eq!($req_body.as_bytes(), body, "Assert request body failed"); 3796dbb5987Sopenharmony_ci Ok( 3806dbb5987Sopenharmony_ci hyper::Response::builder() 3816dbb5987Sopenharmony_ci .version(hyper::Version::HTTP_11) 3826dbb5987Sopenharmony_ci .status($status) 3836dbb5987Sopenharmony_ci $(.header($resp_n, $resp_v))* 3846dbb5987Sopenharmony_ci .body($resp_body.into()) 3856dbb5987Sopenharmony_ci .expect("Build response failed") 3866dbb5987Sopenharmony_ci ) 3876dbb5987Sopenharmony_ci }, 3886dbb5987Sopenharmony_ci )* 3896dbb5987Sopenharmony_ci _ => {panic!("Unrecognized METHOD !");}, 3906dbb5987Sopenharmony_ci } 3916dbb5987Sopenharmony_ci } 3926dbb5987Sopenharmony_ci 3936dbb5987Sopenharmony_ci }; 3946dbb5987Sopenharmony_ci} 3956dbb5987Sopenharmony_ci 3966dbb5987Sopenharmony_ci#[macro_export] 3976dbb5987Sopenharmony_cimacro_rules! ensure_server_shutdown { 3986dbb5987Sopenharmony_ci (ServerHandle: $handle:expr) => { 3996dbb5987Sopenharmony_ci $handle 4006dbb5987Sopenharmony_ci .client_shutdown 4016dbb5987Sopenharmony_ci .send(()) 4026dbb5987Sopenharmony_ci .await 4036dbb5987Sopenharmony_ci .expect("Client channel (Server-Half) be closed unexpectedly"); 4046dbb5987Sopenharmony_ci $handle 4056dbb5987Sopenharmony_ci .server_shutdown 4066dbb5987Sopenharmony_ci .recv() 4076dbb5987Sopenharmony_ci .await 4086dbb5987Sopenharmony_ci .expect("Server channel (Server-Half) be closed unexpectedly"); 4096dbb5987Sopenharmony_ci }; 4106dbb5987Sopenharmony_ci} 4116dbb5987Sopenharmony_ci 4126dbb5987Sopenharmony_cipub fn init_test_work_runtime(thread_num: usize) -> Runtime { 4136dbb5987Sopenharmony_ci tokio::runtime::Builder::new_multi_thread() 4146dbb5987Sopenharmony_ci .worker_threads(thread_num) 4156dbb5987Sopenharmony_ci .enable_all() 4166dbb5987Sopenharmony_ci .build() 4176dbb5987Sopenharmony_ci .expect("Build runtime failed.") 4186dbb5987Sopenharmony_ci} 419