From: Oguzhan Ozmen Date: Sun, 8 Feb 2026 00:30:13 +0000 (+0000) Subject: rgw: add operator<< for RGWEndpoint and simplify logging X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=71af1fc945e78c8f7fa460e3835733ad93a9754a;p=ceph.git rgw: add operator<< for RGWEndpoint and simplify logging Add ostream operator<< to RGWEndpoint struct for convenient logging of endpoint details (url, original_url when different, and connect_to). Update log statements across rgw_http_client.cc, rgw_rest_client.cc, and rgw_rest_conn.cc to use the new operator for cleaner, more consistent output. Add unittest_rgw_http_client to test RGWEndpoint functionality. Signed-off-by: Oguzhan Ozmen --- diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 94ed211c8c4..1b1d5bae8b7 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -586,8 +586,7 @@ int RGWHTTPClient::init_request(rgw_http_req_data *_req_data) CURL *easy_handle = req_data->get_easy_handle(); - dout(20) << "sending request to url=" << endpoint.get_url() - << " connect_to=" << endpoint.get_connect_to() << dendl; + dout(20) << "sending request to " << endpoint << dendl; curl_slist *h = headers_to_slist(headers); @@ -605,9 +604,9 @@ int RGWHTTPClient::init_request(rgw_http_req_data *_req_data) req_data->connect_to_slist = curl_slist_append(req_data->connect_to_slist, endpoint.get_connect_to().c_str()); if (! req_data->connect_to_slist) { - dout(0) << "ERROR: RGWHTTPClient::init_request failed to allocate connect_to_slist" << dendl; + dout(0) << "ERROR: RGWHTTPClient::init_request failed to allocate connect_to_slist: " << endpoint << dendl; } else { - dout(20) << "applying CURLOPT_CONNECT_TO=" << endpoint.get_connect_to() << " for url=" << endpoint.get_url() << dendl; + dout(20) << "applying CURLOPT_CONNECT_TO " << endpoint << dendl; curl_easy_setopt(easy_handle, CURLOPT_CONNECT_TO, req_data->connect_to_slist); } } diff --git a/src/rgw/rgw_http_client.h b/src/rgw/rgw_http_client.h index 942824aa9d6..5aec7c40684 100644 --- a/src/rgw/rgw_http_client.h +++ b/src/rgw/rgw_http_client.h @@ -75,6 +75,17 @@ public: void append_to_url(const std::string& suffix) { url.append(suffix); } + + friend std::ostream& operator<<(std::ostream& os, const RGWEndpoint& ep) { + os << "RGWEndpoint: url=" << ep.url; + if (!ep.original_url.empty() && ep.original_url != ep.url) { + os << " original_url=" << ep.original_url; + } + if (!ep.connect_to.empty()) { + os << " connect_to=" << ep.connect_to; + } + return os; + } }; class RGWHTTPClient : public RGWIOProvider, diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index 9317587ac78..e82680e7b0e 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -702,7 +702,8 @@ void RGWRESTStreamS3PutObj::send_init(const rgw_obj& obj) //do not encode slash in object key name url_encode(resource_str, resource, false); - ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource << " , new_host = " << new_host << " , new_url = " << new_endpoint.get_url() << dendl; + ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource + << " , new_host = " << new_host << " , new_endpoint = " << new_endpoint << dendl; method = "PUT"; headers_gen.init(method, new_host, resource_prefix, new_endpoint, resource, params, api_name); @@ -858,7 +859,9 @@ int RGWRESTStreamRWRequest::do_send_prepare(const DoutPrefixProvider *dpp, RGWAc headers_gen.emplace(cct, &new_env, &new_info); - ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource << " , new_host = " << new_host << " , new_url = " << new_endpoint.get_url() << " , new_resource = " << new_resource << dendl; + ldpp_dout(this, 20) << __func__ << "(): host = " << host << " , resource = " << resource + << " , new_host = " << new_host << " , new_endpoint = " << new_endpoint + << " , new_resource = " << new_resource << dendl; headers_gen->init(method, new_host, resource_prefix, new_endpoint, new_resource, params, api_name); diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc index 6c86d4e29fd..cdc8a2f6cea 100644 --- a/src/rgw/rgw_rest_conn.cc +++ b/src/rgw/rgw_rest_conn.cc @@ -204,7 +204,7 @@ int RGWRESTConn::get_endpoint(RGWEndpoint& endpoint) static constexpr uint32_t CONN_STATUS_EXPIRE_SECS = 2; if (diff >= CONN_STATUS_EXPIRE_SECS) { resolved_endpoints[ep_url].status.store(ceph::real_clock::zero()); - ldout(cct, 10) << "endpoint " << endpoint.get_url() << " unconnectable status expired. mark it connectable" << dendl; + ldout(cct, 10) << endpoint << " unconnectable status expired. mark it connectable" << dendl; break; } num++; @@ -216,8 +216,7 @@ int RGWRESTConn::get_endpoint(RGWEndpoint& endpoint) } get_connect_to_mapping_for_url(endpoint); - ldout(cct, 20) << "get_endpoint picked endpoint url=" << endpoint.get_url() - << " connect_to=" << endpoint.get_connect_to() << dendl; + ldout(cct, 20) << "get_endpoint picked " << endpoint << dendl; return 0; } @@ -234,8 +233,8 @@ void RGWRESTConn::set_endpoint_unconnectable(const RGWEndpoint& endpoint) const string& orig_url = endpoint.get_original_url(); if (orig_url.empty() || resolved_endpoints.find(orig_url) == resolved_endpoints.end()) { - ldout(cct, 0) << "ERROR: endpoint is not a valid or doesn't have status. " - << " original_url=" << orig_url << " current_url=" << endpoint.get_url() << dendl; + ldout(cct, 0) << "ERROR: endpoint is not a valid or doesn't have status: " + << endpoint << dendl; return; } diff --git a/src/test/rgw/CMakeLists.txt b/src/test/rgw/CMakeLists.txt index c587b5834dc..b3ebfb1a309 100644 --- a/src/test/rgw/CMakeLists.txt +++ b/src/test/rgw/CMakeLists.txt @@ -469,3 +469,9 @@ target_link_libraries(unittest_rgw_async_utils ${rgw_libs} ${UNITTEST_LIBS}) add_executable(unittest_rgw_tag test_rgw_tag.cc) add_ceph_unittest(unittest_rgw_tag) target_link_libraries(unittest_rgw_tag ${rgw_libs} ${UNITTEST_LIBS}) + +# unittest_rgw_http_client +add_executable(unittest_rgw_http_client test_rgw_http_client.cc) +add_ceph_unittest(unittest_rgw_http_client) +target_link_libraries(unittest_rgw_http_client + rgw_common ${rgw_libs} ${UNITTEST_LIBS}) diff --git a/src/test/rgw/test_rgw_http_client.cc b/src/test/rgw/test_rgw_http_client.cc new file mode 100644 index 00000000000..79f80c67edb --- /dev/null +++ b/src/test/rgw/test_rgw_http_client.cc @@ -0,0 +1,132 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*- +// vim: ts=8 sw=2 sts=2 expandtab ft=cpp + +#include +#include + +#include "rgw_http_client.h" + +using namespace std; + +// Tests for RGWEndpoint + +TEST(RGWEndpointTest, default_constructor) { + RGWEndpoint ep; + EXPECT_TRUE(ep.get_url().empty()); + EXPECT_TRUE(ep.get_original_url().empty()); + EXPECT_TRUE(ep.get_connect_to().empty()); +} + +TEST(RGWEndpointTest, constructor_sets_url_and_original_url) { + RGWEndpoint ep("http://example.com:8080"); + EXPECT_EQ(ep.get_url(), "http://example.com:8080"); + EXPECT_EQ(ep.get_original_url(), "http://example.com:8080"); +} + +TEST(RGWEndpointTest, constructor_with_connect_to) { + RGWEndpoint ep("http://example.com:8080", "example.com:8080:192.168.1.1:8080"); + EXPECT_EQ(ep.get_url(), "http://example.com:8080"); + EXPECT_EQ(ep.get_original_url(), "http://example.com:8080"); + EXPECT_EQ(ep.get_connect_to(), "example.com:8080:192.168.1.1:8080"); +} + +TEST(RGWEndpointTest, set_url_on_default_constructed_sets_original) { + RGWEndpoint ep; + EXPECT_TRUE(ep.get_original_url().empty()); + + ep.set_url("http://first.example.com"); + EXPECT_EQ(ep.get_url(), "http://first.example.com"); + EXPECT_EQ(ep.get_original_url(), "http://first.example.com"); + + // Second set_url should NOT change original_url + ep.set_url("http://second.example.com"); + EXPECT_EQ(ep.get_url(), "http://second.example.com"); + EXPECT_EQ(ep.get_original_url(), "http://first.example.com"); +} + +TEST(RGWEndpointTest, set_url_does_not_change_original_after_constructor) { + RGWEndpoint ep("http://original.example.com"); + + ep.set_url("http://modified.example.com"); + EXPECT_EQ(ep.get_url(), "http://modified.example.com"); + EXPECT_EQ(ep.get_original_url(), "http://original.example.com"); +} + +TEST(RGWEndpointTest, with_url_returns_copy_with_new_url) { + RGWEndpoint ep("http://original.example.com"); + ep.set_connect_to("original.example.com:80:192.168.1.1:80"); + + RGWEndpoint ep2 = ep.with_url("http://modified.example.com"); + + // Original unchanged + EXPECT_EQ(ep.get_url(), "http://original.example.com"); + EXPECT_EQ(ep.get_original_url(), "http://original.example.com"); + + // Copy has new url but preserves original_url and connect_to + EXPECT_EQ(ep2.get_url(), "http://modified.example.com"); + EXPECT_EQ(ep2.get_original_url(), "http://original.example.com"); + EXPECT_EQ(ep2.get_connect_to(), "original.example.com:80:192.168.1.1:80"); +} + +TEST(RGWEndpointTest, set_connect_to) { + RGWEndpoint ep("http://example.com:8080"); + EXPECT_TRUE(ep.get_connect_to().empty()); + + ep.set_connect_to("example.com:8080:192.168.1.1:8080"); + EXPECT_EQ(ep.get_connect_to(), "example.com:8080:192.168.1.1:8080"); +} + +TEST(RGWEndpointTest, add_trailing_slash) { + RGWEndpoint ep("http://example.com:8080"); + ep.add_trailing_slash(); + EXPECT_EQ(ep.get_url(), "http://example.com:8080/"); + + // Should not add another slash + ep.add_trailing_slash(); + EXPECT_EQ(ep.get_url(), "http://example.com:8080/"); +} + +TEST(RGWEndpointTest, append_to_url) { + RGWEndpoint ep("http://example.com:8080"); + ep.append_to_url("/path/to/resource"); + EXPECT_EQ(ep.get_url(), "http://example.com:8080/path/to/resource"); +} + +// Tests for operator<< + +TEST(RGWEndpointTest, ostream_operator_url_only) { + RGWEndpoint ep("http://example.com:8080"); + std::ostringstream oss; + oss << ep; + EXPECT_EQ(oss.str(), "RGWEndpoint: url=http://example.com:8080"); +} + +TEST(RGWEndpointTest, ostream_operator_with_different_original_url) { + RGWEndpoint ep; + ep.set_url("http://original.example.com:8080"); + ep.set_url("http://modified.example.com:8080"); // original_url stays the same + + std::ostringstream oss; + oss << ep; + EXPECT_EQ(oss.str(), "RGWEndpoint: url=http://modified.example.com:8080 original_url=http://original.example.com:8080"); +} + +TEST(RGWEndpointTest, ostream_operator_with_connect_to) { + RGWEndpoint ep("http://example.com:8080"); + ep.set_connect_to("example.com:8080:192.168.1.1:8080"); + + std::ostringstream oss; + oss << ep; + EXPECT_EQ(oss.str(), "RGWEndpoint: url=http://example.com:8080 connect_to=example.com:8080:192.168.1.1:8080"); +} + +TEST(RGWEndpointTest, ostream_operator_full) { + RGWEndpoint ep; + ep.set_url("http://original.example.com:8080"); + ep.set_url("http://192.168.1.1:8080"); + ep.set_connect_to("original.example.com:8080:192.168.1.1:8080"); + + std::ostringstream oss; + oss << ep; + EXPECT_EQ(oss.str(), "RGWEndpoint: url=http://192.168.1.1:8080 original_url=http://original.example.com:8080 connect_to=original.example.com:8080:192.168.1.1:8080"); +}