feat: Healthcheck endpoint (#1751)

Fixes #1759
This commit is contained in:
Alex Kremer
2024-11-26 13:56:25 +00:00
committed by GitHub
parent 541bf4395f
commit fd73b90416
6 changed files with 82 additions and 19 deletions

View File

@@ -56,6 +56,7 @@
#include <string>
#include <string_view>
#include <thread>
#include <tuple>
#include <utility>
#include <vector>
@@ -214,8 +215,9 @@ TEST_F(WebServerTest, Http)
{
auto e = std::make_shared<EchoExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
auto const res = HttpSyncClient::post("localhost", port, R"({"Hello":1})");
auto const [status, res] = HttpSyncClient::post("localhost", port, R"({"Hello":1})");
EXPECT_EQ(res, R"({"Hello":1})");
EXPECT_EQ(status, boost::beast::http::status::ok);
}
TEST_F(WebServerTest, Ws)
@@ -233,11 +235,12 @@ TEST_F(WebServerTest, HttpInternalError)
{
auto e = std::make_shared<ExceptionExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
auto const res = HttpSyncClient::post("localhost", port, R"({})");
auto const [status, res] = HttpSyncClient::post("localhost", port, R"({})");
EXPECT_EQ(
res,
R"({"error":"internal","error_code":73,"error_message":"Internal error.","status":"error","type":"response"})"
);
EXPECT_EQ(status, boost::beast::http::status::internal_server_error);
}
TEST_F(WebServerTest, WsInternalError)
@@ -316,13 +319,16 @@ TEST_F(WebServerTest, HttpRequestOverload)
{
auto e = std::make_shared<EchoExecutor>();
auto const server = makeServerSync(cfg, ctx, dosGuardOverload, e);
auto res = HttpSyncClient::post("localhost", port, R"({})");
auto [status, res] = HttpSyncClient::post("localhost", port, R"({})");
EXPECT_EQ(res, "{}");
res = HttpSyncClient::post("localhost", port, R"({})");
EXPECT_EQ(status, boost::beast::http::status::ok);
std::tie(status, res) = HttpSyncClient::post("localhost", port, R"({})");
EXPECT_EQ(
res,
R"({"error":"slowDown","error_code":10,"error_message":"You are placing too much load on the server.","status":"error","type":"response"})"
);
EXPECT_EQ(status, boost::beast::http::status::service_unavailable);
}
TEST_F(WebServerTest, WsRequestOverload)
@@ -349,11 +355,12 @@ TEST_F(WebServerTest, HttpPayloadOverload)
std::string const s100(100, 'a');
auto e = std::make_shared<EchoExecutor>();
auto server = makeServerSync(cfg, ctx, dosGuardOverload, e);
auto const res = HttpSyncClient::post("localhost", port, fmt::format(R"({{"payload":"{}"}})", s100));
auto const [status, res] = HttpSyncClient::post("localhost", port, fmt::format(R"({{"payload":"{}"}})", s100));
EXPECT_EQ(
res,
R"({"payload":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","warning":"load","warnings":[{"id":2003,"message":"You are about to be rate limited"}]})"
);
EXPECT_EQ(status, boost::beast::http::status::ok);
}
TEST_F(WebServerTest, WsPayloadOverload)
@@ -393,6 +400,26 @@ TEST_F(WebServerTest, WsTooManyConnection)
EXPECT_TRUE(exceptionThrown);
}
TEST_F(WebServerTest, HealthCheck)
{
auto e = std::make_shared<ExceptionExecutor>(); // request handled before we get to executor
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
auto const [status, res] = HttpSyncClient::get("localhost", port, "", "/health");
EXPECT_FALSE(res.empty());
EXPECT_EQ(status, boost::beast::http::status::ok);
}
TEST_F(WebServerTest, GetOtherThanHealthCheck)
{
auto e = std::make_shared<ExceptionExecutor>(); // request handled before we get to executor
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
auto const [status, res] = HttpSyncClient::get("localhost", port, "", "/");
EXPECT_FALSE(res.empty());
EXPECT_EQ(status, boost::beast::http::status::bad_request);
}
std::string
JSONServerConfigWithAdminPassword(uint32_t const port)
{
@@ -500,8 +527,11 @@ TEST_P(WebServerAdminTest, HttpAdminCheck)
auto server = makeServerSync(serverConfig, ctx, dosGuardOverload, e);
std::string const request = "Why hello";
uint32_t const webServerPort = serverConfig.value<uint32_t>("server.port");
auto const res = HttpSyncClient::post("localhost", std::to_string(webServerPort), request, GetParam().headers);
auto const [status, res] =
HttpSyncClient::post("localhost", std::to_string(webServerPort), request, GetParam().headers);
EXPECT_EQ(res, fmt::format("{} {}", request, GetParam().expectedResponse));
EXPECT_EQ(status, boost::beast::http::status::ok);
}
INSTANTIATE_TEST_CASE_P(
@@ -618,8 +648,10 @@ TEST_F(WebServerPrometheusTest, rejectedWithoutAdminPassword)
uint32_t const webServerPort = tests::util::generateFreePort();
Config const serverConfig{boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort))};
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
auto const res = HttpSyncClient::get("localhost", std::to_string(webServerPort), "", "/metrics");
auto const [status, res] = HttpSyncClient::get("localhost", std::to_string(webServerPort), "", "/metrics");
EXPECT_EQ(res, "Only admin is allowed to collect metrics");
EXPECT_EQ(status, boost::beast::http::status::unauthorized);
}
TEST_F(WebServerPrometheusTest, rejectedIfPrometheusIsDisabled)
@@ -641,7 +673,7 @@ TEST_F(WebServerPrometheusTest, rejectedIfPrometheusIsDisabled)
Config const serverConfig{boost::json::parse(JSONServerConfigWithDisabledPrometheus)};
PrometheusService::init(serverConfig);
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
auto const res = HttpSyncClient::get(
auto const [status, res] = HttpSyncClient::get(
"localhost",
std::to_string(webServerPort),
"",
@@ -652,6 +684,7 @@ TEST_F(WebServerPrometheusTest, rejectedIfPrometheusIsDisabled)
)}
);
EXPECT_EQ(res, "Prometheus is disabled in clio config");
EXPECT_EQ(status, boost::beast::http::status::forbidden);
}
TEST_F(WebServerPrometheusTest, validResponse)
@@ -662,7 +695,7 @@ TEST_F(WebServerPrometheusTest, validResponse)
auto e = std::make_shared<EchoExecutor>();
Config const serverConfig{boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort))};
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
auto const res = HttpSyncClient::get(
auto const [status, res] = HttpSyncClient::get(
"localhost",
std::to_string(webServerPort),
"",
@@ -673,4 +706,5 @@ TEST_F(WebServerPrometheusTest, validResponse)
)}
);
EXPECT_EQ(res, "# TYPE test_counter counter\ntest_counter 1\n\n");
EXPECT_EQ(status, boost::beast::http::status::ok);
}