]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/ext/test/http/curl_http_test.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / ext / test / http / curl_http_test.cc
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #include "opentelemetry/ext//http/client/curl/http_client_curl.h"
5 #include "opentelemetry/ext/http/client/http_client_factory.h"
6 #include "opentelemetry/ext/http/server/http_server.h"
7
8 #include <assert.h>
9 #include <atomic>
10 #include <chrono>
11 #include <condition_variable>
12 #include <fstream>
13 #include <memory>
14 #include <thread>
15 #include <vector>
16
17 #define HTTP_PORT 19000
18
19 #include <gtest/gtest.h>
20
21 namespace curl = opentelemetry::ext::http::client::curl;
22 namespace http_client = opentelemetry::ext::http::client;
23 namespace nostd = opentelemetry::nostd;
24
25 class CustomEventHandler : public http_client::EventHandler
26 {
27 public:
28 virtual void OnResponse(http_client::Response &response) noexcept override{};
29 virtual void OnEvent(http_client::SessionState state, nostd::string_view reason) noexcept override
30 {}
31 virtual void OnConnecting(const http_client::SSLCertificate &) noexcept {}
32 virtual ~CustomEventHandler() = default;
33 bool is_called_ = false;
34 };
35
36 class GetEventHandler : public CustomEventHandler
37 {
38 void OnResponse(http_client::Response &response) noexcept override
39 {
40 ASSERT_EQ(200, response.GetStatusCode());
41 ASSERT_EQ(response.GetBody().size(), 0);
42 is_called_ = true;
43 };
44 };
45
46 class PostEventHandler : public CustomEventHandler
47 {
48 void OnResponse(http_client::Response &response) noexcept override
49 {
50 ASSERT_EQ(200, response.GetStatusCode());
51 std::string body(response.GetBody().begin(), response.GetBody().end());
52 ASSERT_EQ(body, "{'k1':'v1', 'k2':'v2', 'k3':'v3'}");
53 is_called_ = true;
54 }
55 };
56
57 class BasicCurlHttpTests : public ::testing::Test, public HTTP_SERVER_NS::HttpRequestCallback
58 {
59 protected:
60 HTTP_SERVER_NS::HttpServer server_;
61 std::string server_address_;
62 std::atomic<bool> is_setup_;
63 std::atomic<bool> is_running_;
64 std::vector<HTTP_SERVER_NS::HttpRequest> received_requests_;
65 std::mutex mtx_requests;
66 std::condition_variable cv_got_events;
67 std::mutex cv_m;
68
69 public:
70 BasicCurlHttpTests() : is_setup_(false), is_running_(false){};
71
72 virtual void SetUp() override
73 {
74 if (is_setup_.exchange(true))
75 {
76 return;
77 }
78 int port = server_.addListeningPort(HTTP_PORT);
79 std::ostringstream os;
80 os << "localhost:" << port;
81 server_address_ = "http://" + os.str() + "/simple/";
82 server_.setServerName(os.str());
83 server_.setKeepalive(false);
84 server_.addHandler("/simple/", *this);
85 server_.addHandler("/get/", *this);
86 server_.addHandler("/post/", *this);
87 server_.start();
88 is_running_ = true;
89 }
90
91 virtual void TearDown() override
92 {
93 if (!is_setup_.exchange(false))
94 return;
95 server_.stop();
96 is_running_ = false;
97 }
98
99 virtual int onHttpRequest(HTTP_SERVER_NS::HttpRequest const &request,
100 HTTP_SERVER_NS::HttpResponse &response) override
101 {
102 int response_status = 404;
103 if (request.uri == "/get/")
104 {
105
106 std::unique_lock<std::mutex> lk(mtx_requests);
107 received_requests_.push_back(request);
108 response.headers["Content-Type"] = "text/plain";
109 response_status = 200;
110 }
111 if (request.uri == "/post/")
112 {
113 std::unique_lock<std::mutex> lk(mtx_requests);
114 received_requests_.push_back(request);
115 response.headers["Content-Type"] = "application/json";
116 response.body = "{'k1':'v1', 'k2':'v2', 'k3':'v3'}";
117 response_status = 200;
118 }
119
120 cv_got_events.notify_one();
121
122 return response_status;
123 }
124
125 bool waitForRequests(unsigned timeOutSec, unsigned expected_count = 1)
126 {
127 std::unique_lock<std::mutex> lk(mtx_requests);
128 if (cv_got_events.wait_for(lk, std::chrono::milliseconds(1000 * timeOutSec),
129 [&] { return received_requests_.size() >= expected_count; }))
130 {
131 return true;
132 }
133 return false;
134 }
135 };
136
137 TEST_F(BasicCurlHttpTests, DoNothing) {}
138
139 TEST_F(BasicCurlHttpTests, HttpRequest)
140 {
141 curl::Request req;
142 const char *b = "test-data";
143 http_client::Body body = {b, b + strlen(b)};
144 http_client::Body body1 = body;
145 req.SetBody(body);
146 ASSERT_EQ(req.body_, body1);
147 req.AddHeader("name1", "value1");
148 req.AddHeader("name2", "value2");
149 ASSERT_TRUE(req.headers_.find("name1")->second == "value1");
150 ASSERT_TRUE(req.headers_.find("name2")->second == "value2");
151
152 req.ReplaceHeader("name1", "value3");
153 ASSERT_EQ(req.headers_.find("name1")->second, "value3");
154
155 req.SetTimeoutMs(std::chrono::duration<int>(2000));
156 ASSERT_EQ(req.timeout_ms_, std::chrono::duration<int>(2000));
157 }
158
159 TEST_F(BasicCurlHttpTests, HttpResponse)
160 {
161 curl::Response res;
162 http_client::Headers m1 = {
163 {"name1", "value1_1"}, {"name1", "value1_2"}, {"name2", "value3"}, {"name3", "value3"}};
164 res.headers_ = m1;
165
166 const char *b = "test-data";
167 http_client::Body body = {b, b + strlen(b)};
168 int count = 0;
169 res.ForEachHeader("name1", [&count](nostd::string_view name, nostd::string_view value) {
170 if (name != "name1")
171 return false;
172 if (value != "value1_1" && value != "value1_2")
173 return false;
174 count++;
175 return true;
176 });
177 ASSERT_EQ(count, 2);
178 count = 0;
179 res.ForEachHeader([&count](nostd::string_view name, nostd::string_view value) {
180 if (name != "name1" && name != "name2" && name != "name3")
181 return false;
182 if (value != "value1_1" && value != "value1_2" && value != "value2" && value != "value3")
183 return false;
184 count++;
185 return true;
186 });
187 ASSERT_EQ(count, 4);
188 }
189
190 TEST_F(BasicCurlHttpTests, SendGetRequest)
191 {
192 received_requests_.clear();
193 auto session_manager = http_client::HttpClientFactory::Create();
194 EXPECT_TRUE(session_manager != nullptr);
195
196 auto session = session_manager->CreateSession("http://127.0.0.1:19000");
197 auto request = session->CreateRequest();
198 request->SetUri("get/");
199 GetEventHandler *handler = new GetEventHandler();
200 session->SendRequest(*handler);
201 ASSERT_TRUE(waitForRequests(30, 1));
202 session->FinishSession();
203 ASSERT_TRUE(handler->is_called_);
204 delete handler;
205 }
206
207 TEST_F(BasicCurlHttpTests, SendPostRequest)
208 {
209 received_requests_.clear();
210 auto session_manager = http_client::HttpClientFactory::Create();
211 EXPECT_TRUE(session_manager != nullptr);
212
213 auto session = session_manager->CreateSession("http://127.0.0.1:19000");
214 auto request = session->CreateRequest();
215 request->SetUri("post/");
216 request->SetMethod(http_client::Method::Post);
217
218 const char *b = "test-data";
219 http_client::Body body = {b, b + strlen(b)};
220 request->SetBody(body);
221 request->AddHeader("Content-Type", "text/plain");
222 PostEventHandler *handler = new PostEventHandler();
223 session->SendRequest(*handler);
224 ASSERT_TRUE(waitForRequests(30, 1));
225 session->FinishSession();
226 ASSERT_TRUE(handler->is_called_);
227
228 session_manager->CancelAllSessions();
229 session_manager->FinishAllSessions();
230
231 delete handler;
232 }
233
234 TEST_F(BasicCurlHttpTests, RequestTimeout)
235 {
236 received_requests_.clear();
237 auto session_manager = http_client::HttpClientFactory::Create();
238 EXPECT_TRUE(session_manager != nullptr);
239
240 auto session = session_manager->CreateSession("222.222.222.200:19000"); // Non Existing address
241 auto request = session->CreateRequest();
242 request->SetUri("get/");
243 GetEventHandler *handler = new GetEventHandler();
244 session->SendRequest(*handler);
245 session->FinishSession();
246 ASSERT_FALSE(handler->is_called_);
247 delete handler;
248 }
249
250 TEST_F(BasicCurlHttpTests, CurlHttpOperations)
251 {
252 GetEventHandler *handler = new GetEventHandler();
253
254 const char *b = "test-data";
255 http_client::Body body = {b, b + strlen(b)};
256
257 http_client::Headers headers = {
258 {"name1", "value1_1"}, {"name1", "value1_2"}, {"name2", "value3"}, {"name3", "value3"}};
259
260 curl::HttpOperation http_operations1(http_client::Method::Head, "/get", handler,
261 curl::RequestMode::Async, headers, body, true);
262 http_operations1.Send();
263
264 curl::HttpOperation http_operations2(http_client::Method::Get, "/get", handler,
265 curl::RequestMode::Async, headers, body, true);
266 http_operations2.Send();
267
268 curl::HttpOperation http_operations3(http_client::Method::Get, "/get", handler,
269 curl::RequestMode::Async, headers, body, false);
270 http_operations3.Send();
271 delete handler;
272 }
273
274 TEST_F(BasicCurlHttpTests, SendGetRequestSync)
275 {
276 received_requests_.clear();
277 curl::HttpClientSync http_client;
278
279 http_client::Headers m1 = {};
280 auto result = http_client.Get("http://127.0.0.1:19000/get/", m1);
281 EXPECT_EQ(result, true);
282 EXPECT_EQ(result.GetSessionState(), http_client::SessionState::Response);
283 }
284
285 TEST_F(BasicCurlHttpTests, SendGetRequestSyncTimeout)
286 {
287 received_requests_.clear();
288 curl::HttpClientSync http_client;
289
290 http_client::Headers m1 = {};
291 auto result = http_client.Get("http://222.222.222.200:19000/get/", m1);
292 EXPECT_EQ(result, false);
293
294 // When network is under proxy, it may connect success but closed by peer when send data
295 EXPECT_TRUE(result.GetSessionState() == http_client::SessionState::ConnectFailed ||
296 result.GetSessionState() == http_client::SessionState::SendFailed);
297 }
298
299 TEST_F(BasicCurlHttpTests, SendPostRequestSync)
300 {
301 received_requests_.clear();
302 curl::HttpClientSync http_client;
303
304 http_client::Headers m1 = {};
305 http_client::Body body = {};
306 auto result = http_client.Post("http://127.0.0.1:19000/post/", body, m1);
307 EXPECT_EQ(result, true);
308 EXPECT_EQ(result.GetSessionState(), http_client::SessionState::Response);
309 }
310
311 TEST_F(BasicCurlHttpTests, GetBaseUri)
312 {
313 curl::HttpClient session_manager;
314
315 auto session = session_manager.CreateSession("127.0.0.1:80");
316 ASSERT_EQ(std::static_pointer_cast<curl::Session>(session)->GetBaseUri(), "http://127.0.0.1:80/");
317
318 session = session_manager.CreateSession("https://127.0.0.1:443");
319 ASSERT_EQ(std::static_pointer_cast<curl::Session>(session)->GetBaseUri(),
320 "https://127.0.0.1:443/");
321
322 session = session_manager.CreateSession("http://127.0.0.1:31339");
323 ASSERT_EQ(std::static_pointer_cast<curl::Session>(session)->GetBaseUri(),
324 "http://127.0.0.1:31339/");
325 }