// Copyright (c) 2023 Huawei Device Co., Ltd. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #[macro_export] macro_rules! sync_client_test_on_tcp { ( HTTP; $(ClientNum: $client_num: expr,)? $(Request: { Method: $method: expr, Path: $path: expr, $( Header: $req_n: expr, $req_v: expr, )* Body: $req_body: expr, }, Response: { Status: $status: expr, Version: $version: expr, $( Header: $resp_n: expr, $resp_v: expr, )* Body: $resp_body: expr, },)* ) => {{ // The number of servers may be variable based on the number of servers set by the user. // However, cliipy checks that the variable does not need to be variable. #[allow(unused_mut, unused_assignments)] let mut server_num = 1; $(server_num = $client_num;)? let mut handles_vec = vec![]; start_tcp_server!( SYNC; ServerNum: server_num, Handles: handles_vec, $(Request: { Method: $method, Path: $path, $( Header: $req_n, $req_v, )* Body: $req_body, }, Response: { Status: $status, Version: $version, $( Header: $resp_n, $resp_v, )* Body: $resp_body, },)* ); let mut shut_downs = vec![]; sync_client_assert_on_tcp!( HTTP; ServerNum: server_num, Handles: handles_vec, ShutDownHandles: shut_downs, $(Request: { Method: $method, Path: $path, $( Header: $req_n, $req_v, )* Body: $req_body, }, Response: { Status: $status, Version: $version, $( Header: $resp_n, $resp_v, )* Body: $resp_body, },)* ); for shutdown_handle in shut_downs { shutdown_handle.join().expect("join to wait client thread finish failed !"); } }}; } #[macro_export] macro_rules! sync_client_assert_on_tcp { ( HTTP; ServerNum: $server_num: expr, Handles: $handle_vec: expr, ShutDownHandles: $shut_downs: expr, $(Request: { Method: $method: expr, Path: $path: expr, $( Header: $req_n: expr, $req_v: expr, )* Body: $req_body: expr, }, Response: { Status: $status: expr, Version: $version: expr, $( Header: $resp_n: expr, $resp_v: expr, )* Body: $resp_body: expr, },)* ) => {{ let client = ylong_http_client::sync_impl::Client::new(); let client = std::sync::Arc::new(client); for _i in 0..$server_num { let handle = $handle_vec.pop().expect("No more handles !"); let client = std::sync::Arc::clone(&client); let shutdown_handle = std::thread::spawn(move || { sync_client_assertions_on_tcp!( ServerHandle: handle, ClientRef: client, $(Request: { Method: $method, Path: $path, $( Header: $req_n, $req_v, )* Body: $req_body, }, Response: { Status: $status, Version: $version, $( Header: $resp_n, $resp_v, )* Body: $resp_body, },)* ); handle.server_shutdown.recv().expect("server send order failed !"); }); $shut_downs.push(shutdown_handle); }; }} } #[macro_export] macro_rules! sync_client_assertions_on_tcp { ( ServerHandle: $handle:expr, ClientRef: $client:expr, $(Request: { Method: $method: expr, Path: $path: expr, $( Header: $req_n: expr, $req_v: expr, )* Body: $req_body: expr, }, Response: { Status: $status: expr, Version: $version: expr, $( Header: $resp_n: expr, $resp_v: expr, )* Body: $resp_body: expr, },)* ) => { $( { let request = build_client_request!( Request: { Method: $method, Path: $path, Addr: $handle.addr.as_str(), $( Header: $req_n, $req_v, )* Body: $req_body, }, ); let mut response = $client .request(request) .expect("Request send failed"); assert_eq!(response.status().as_u16(), $status, "Assert response status code failed") ; assert_eq!(response.version().as_str(), $version, "Assert response version failed"); $(assert_eq!( response .headers() .get($resp_n) .expect(format!("Get response header \"{}\" failed", $resp_n).as_str()) .to_string() .expect(format!("Convert response header \"{}\"into string failed", $resp_n).as_str()), $resp_v, "Assert response header \"{}\" failed", $resp_n, );)* let mut buf = [0u8; 4096]; let mut size = 0; loop { let read = response .body_mut() .data(&mut buf[size..]) .expect("Response body read failed"); if read == 0 { break; } size += read; } assert_eq!(&buf[..size], $resp_body.as_bytes(), "Assert response body failed"); } )* } }