mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-04 11:55:51 +00:00
refactor: Replace all old instances of Config with New Config (#1627)
Fixes #1184 Previous PR's found [here](https://github.com/XRPLF/clio/pull/1593) and [here](https://github.com/XRPLF/clio/pull/1544)
This commit is contained in:
@@ -23,7 +23,12 @@
|
||||
#include "util/TestHttpClient.hpp"
|
||||
#include "util/TestWebSocketClient.hpp"
|
||||
#include "util/TmpFile.hpp"
|
||||
#include "util/config/Config.hpp"
|
||||
#include "util/newconfig/Array.hpp"
|
||||
#include "util/newconfig/ConfigDefinition.hpp"
|
||||
#include "util/newconfig/ConfigFileJson.hpp"
|
||||
#include "util/newconfig/ConfigValue.hpp"
|
||||
#include "util/newconfig/Types.hpp"
|
||||
#include "util/prometheus/Gauge.hpp"
|
||||
#include "util/prometheus/Label.hpp"
|
||||
#include "util/prometheus/Prometheus.hpp"
|
||||
#include "web/AdminVerificationStrategy.hpp"
|
||||
@@ -61,6 +66,7 @@
|
||||
#include <vector>
|
||||
|
||||
using namespace util;
|
||||
using namespace util::config;
|
||||
using namespace web::impl;
|
||||
using namespace web;
|
||||
|
||||
@@ -105,6 +111,30 @@ generateJSONDataOverload(std::string_view port)
|
||||
));
|
||||
}
|
||||
|
||||
inline ClioConfigDefinition
|
||||
getParseServerConfig(boost::json::value val)
|
||||
{
|
||||
ConfigFileJson const jsonVal{val.as_object()};
|
||||
auto config = ClioConfigDefinition{
|
||||
{"server.ip", ConfigValue{ConfigType::String}},
|
||||
{"server.port", ConfigValue{ConfigType::Integer}},
|
||||
{"server.admin_password", ConfigValue{ConfigType::String}.optional()},
|
||||
{"server.local_admin", ConfigValue{ConfigType::Boolean}.optional()},
|
||||
{"server.ws_max_sending_queue_size", ConfigValue{ConfigType::Integer}.defaultValue(1500)},
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")},
|
||||
{"dos_guard.max_fetches", ConfigValue{ConfigType::Integer}},
|
||||
{"dos_guard.sweep_interval", ConfigValue{ConfigType::Integer}},
|
||||
{"dos_guard.max_connections", ConfigValue{ConfigType::Integer}},
|
||||
{"dos_guard.max_requests", ConfigValue{ConfigType::Integer}},
|
||||
{"dos_guard.whitelist.[]", Array{ConfigValue{ConfigType::String}.optional()}},
|
||||
{"ssl_key_file", ConfigValue{ConfigType::String}.optional()},
|
||||
{"ssl_cert_file", ConfigValue{ConfigType::String}.optional()},
|
||||
};
|
||||
auto const errors = config.parse(jsonVal);
|
||||
[&]() { ASSERT_FALSE(errors.has_value()); }();
|
||||
return config;
|
||||
};
|
||||
|
||||
struct WebServerTest : NoLoggerFixture {
|
||||
~WebServerTest() override
|
||||
{
|
||||
@@ -131,12 +161,12 @@ struct WebServerTest : NoLoggerFixture {
|
||||
// this ctx is for dos timer
|
||||
boost::asio::io_context ctxSync;
|
||||
std::string const port = std::to_string(tests::util::generateFreePort());
|
||||
Config cfg{generateJSONWithDynamicPort(port)};
|
||||
ClioConfigDefinition cfg{getParseServerConfig(generateJSONWithDynamicPort(port))};
|
||||
dosguard::WhitelistHandler whitelistHandler{cfg};
|
||||
dosguard::DOSGuard dosGuard{cfg, whitelistHandler};
|
||||
dosguard::IntervalSweepHandler sweepHandler{cfg, ctxSync, dosGuard};
|
||||
|
||||
Config cfgOverload{generateJSONDataOverload(port)};
|
||||
ClioConfigDefinition cfgOverload{getParseServerConfig(generateJSONDataOverload(port))};
|
||||
dosguard::WhitelistHandler whitelistHandlerOverload{cfgOverload};
|
||||
dosguard::DOSGuard dosGuardOverload{cfgOverload, whitelistHandlerOverload};
|
||||
dosguard::IntervalSweepHandler sweepHandlerOverload{cfgOverload, ctxSync, dosGuardOverload};
|
||||
@@ -184,7 +214,7 @@ namespace {
|
||||
template <class Executor>
|
||||
std::shared_ptr<web::HttpServer<Executor>>
|
||||
makeServerSync(
|
||||
util::Config const& config,
|
||||
util::config::ClioConfigDefinition const& config,
|
||||
boost::asio::io_context& ioc,
|
||||
web::dosguard::DOSGuardInterface& dosGuard,
|
||||
std::shared_ptr<Executor> const& handler
|
||||
@@ -213,7 +243,7 @@ makeServerSync(
|
||||
|
||||
TEST_F(WebServerTest, Http)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
|
||||
auto const [status, res] = HttpSyncClient::post("localhost", port, R"({"Hello":1})");
|
||||
EXPECT_EQ(res, R"({"Hello":1})");
|
||||
@@ -233,7 +263,7 @@ TEST_F(WebServerTest, Ws)
|
||||
|
||||
TEST_F(WebServerTest, HttpInternalError)
|
||||
{
|
||||
auto e = std::make_shared<ExceptionExecutor>();
|
||||
auto const e = std::make_shared<ExceptionExecutor>();
|
||||
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
|
||||
auto const [status, res] = HttpSyncClient::post("localhost", port, R"({})");
|
||||
EXPECT_EQ(
|
||||
@@ -273,31 +303,31 @@ TEST_F(WebServerTest, WsInternalErrorNotJson)
|
||||
|
||||
TEST_F(WebServerTest, IncompleteSslConfig)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
|
||||
auto jsonConfig = generateJSONWithDynamicPort(port);
|
||||
jsonConfig.as_object()["ssl_key_file"] = sslKeyFile.path;
|
||||
|
||||
auto const server = makeServerSync(Config{jsonConfig}, ctx, dosGuard, e);
|
||||
auto const server = makeServerSync(getParseServerConfig(jsonConfig), ctx, dosGuard, e);
|
||||
EXPECT_EQ(server, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, WrongSslConfig)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
|
||||
auto jsonConfig = generateJSONWithDynamicPort(port);
|
||||
jsonConfig.as_object()["ssl_key_file"] = sslKeyFile.path;
|
||||
jsonConfig.as_object()["ssl_cert_file"] = "wrong_path";
|
||||
|
||||
auto const server = makeServerSync(Config{jsonConfig}, ctx, dosGuard, e);
|
||||
auto const server = makeServerSync(getParseServerConfig(jsonConfig), ctx, dosGuard, e);
|
||||
EXPECT_EQ(server, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, Https)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
cfg = Config{addSslConfig(generateJSONWithDynamicPort(port))};
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
cfg = getParseServerConfig(addSslConfig(generateJSONWithDynamicPort(port)));
|
||||
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
|
||||
auto const res = HttpsSyncClient::syncPost("localhost", port, R"({"Hello":1})");
|
||||
EXPECT_EQ(res, R"({"Hello":1})");
|
||||
@@ -306,7 +336,7 @@ TEST_F(WebServerTest, Https)
|
||||
TEST_F(WebServerTest, Wss)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
cfg = Config{addSslConfig(generateJSONWithDynamicPort(port))};
|
||||
cfg = getParseServerConfig(addSslConfig(generateJSONWithDynamicPort(port)));
|
||||
auto server = makeServerSync(cfg, ctx, dosGuard, e);
|
||||
WebServerSslSyncClient wsClient;
|
||||
wsClient.connect("localhost", port);
|
||||
@@ -317,7 +347,7 @@ TEST_F(WebServerTest, Wss)
|
||||
|
||||
TEST_F(WebServerTest, HttpRequestOverload)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
auto const server = makeServerSync(cfg, ctx, dosGuardOverload, e);
|
||||
auto [status, res] = HttpSyncClient::post("localhost", port, R"({})");
|
||||
EXPECT_EQ(res, "{}");
|
||||
@@ -353,7 +383,7 @@ TEST_F(WebServerTest, WsRequestOverload)
|
||||
TEST_F(WebServerTest, HttpPayloadOverload)
|
||||
{
|
||||
std::string const s100(100, 'a');
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
auto server = makeServerSync(cfg, ctx, dosGuardOverload, e);
|
||||
auto const [status, res] = HttpSyncClient::post("localhost", port, fmt::format(R"({{"payload":"{}"}})", s100));
|
||||
EXPECT_EQ(
|
||||
@@ -366,7 +396,7 @@ TEST_F(WebServerTest, HttpPayloadOverload)
|
||||
TEST_F(WebServerTest, WsPayloadOverload)
|
||||
{
|
||||
std::string const s100(100, 'a');
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
auto server = makeServerSync(cfg, ctx, dosGuardOverload, e);
|
||||
WebSocketSyncClient wsClient;
|
||||
wsClient.connect("localhost", port);
|
||||
@@ -380,7 +410,7 @@ TEST_F(WebServerTest, WsPayloadOverload)
|
||||
|
||||
TEST_F(WebServerTest, WsTooManyConnection)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
auto server = makeServerSync(cfg, ctx, dosGuardOverload, e);
|
||||
// max connection is 2, exception should happen when the third connection is made
|
||||
WebSocketSyncClient wsClient1;
|
||||
@@ -504,15 +534,38 @@ struct WebServerAdminTestParams {
|
||||
std::string expectedResponse;
|
||||
};
|
||||
|
||||
inline ClioConfigDefinition
|
||||
getParseAdminServerConfig(boost::json::value val)
|
||||
{
|
||||
ConfigFileJson const jsonVal{val.as_object()};
|
||||
auto config = ClioConfigDefinition{
|
||||
{"server.ip", ConfigValue{ConfigType::String}},
|
||||
{"server.port", ConfigValue{ConfigType::Integer}},
|
||||
{"server.admin_password", ConfigValue{ConfigType::String}.optional()},
|
||||
{"server.local_admin", ConfigValue{ConfigType::Boolean}.optional()},
|
||||
{"server.processing_policy", ConfigValue{ConfigType::String}.defaultValue("parallel")},
|
||||
{"server.parallel_requests_limit", ConfigValue{ConfigType::Integer}.optional()},
|
||||
{"server.ws_max_sending_queue_size", ConfigValue{ConfigType::Integer}.defaultValue(1500)},
|
||||
{"ssl_cert_file", ConfigValue{ConfigType::String}.optional()},
|
||||
{"ssl_key_file", ConfigValue{ConfigType::String}.optional()},
|
||||
{"prometheus.enabled", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
{"prometheus.compress_reply", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}
|
||||
};
|
||||
auto const errors = config.parse(jsonVal);
|
||||
[&]() { ASSERT_FALSE(errors.has_value()); }();
|
||||
return config;
|
||||
};
|
||||
|
||||
class WebServerAdminTest : public WebServerTest, public ::testing::WithParamInterface<WebServerAdminTestParams> {};
|
||||
|
||||
TEST_P(WebServerAdminTest, WsAdminCheck)
|
||||
{
|
||||
auto e = std::make_shared<AdminCheckExecutor>();
|
||||
Config const serverConfig{boost::json::parse(GetParam().config)};
|
||||
ClioConfigDefinition const serverConfig{getParseAdminServerConfig(boost::json::parse(GetParam().config))};
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuardOverload, e);
|
||||
WebSocketSyncClient wsClient;
|
||||
uint32_t const webServerPort = serverConfig.value<uint32_t>("server.port");
|
||||
uint32_t const webServerPort = serverConfig.get<uint32_t>("server.port");
|
||||
wsClient.connect("localhost", std::to_string(webServerPort), GetParam().headers);
|
||||
std::string const request = "Why hello";
|
||||
auto const res = wsClient.syncPost(request);
|
||||
@@ -522,11 +575,11 @@ TEST_P(WebServerAdminTest, WsAdminCheck)
|
||||
|
||||
TEST_P(WebServerAdminTest, HttpAdminCheck)
|
||||
{
|
||||
auto e = std::make_shared<AdminCheckExecutor>();
|
||||
Config const serverConfig{boost::json::parse(GetParam().config)};
|
||||
auto const e = std::make_shared<AdminCheckExecutor>();
|
||||
ClioConfigDefinition const serverConfig{getParseAdminServerConfig(boost::json::parse(GetParam().config))};
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuardOverload, e);
|
||||
std::string const request = "Why hello";
|
||||
uint32_t const webServerPort = serverConfig.value<uint32_t>("server.port");
|
||||
uint32_t const webServerPort = serverConfig.get<uint32_t>("server.port");
|
||||
auto const [status, res] =
|
||||
HttpSyncClient::post("localhost", std::to_string(webServerPort), request, GetParam().headers);
|
||||
|
||||
@@ -616,8 +669,10 @@ TEST_F(WebServerTest, AdminErrorCfgTestBothAdminPasswordAndLocalAdminSet)
|
||||
webServerPort
|
||||
);
|
||||
|
||||
auto e = std::make_shared<AdminCheckExecutor>();
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithBothAdminPasswordAndLocalAdmin)};
|
||||
auto const e = std::make_shared<AdminCheckExecutor>();
|
||||
ClioConfigDefinition const serverConfig{
|
||||
getParseAdminServerConfig(boost::json::parse(JSONServerConfigWithBothAdminPasswordAndLocalAdmin))
|
||||
};
|
||||
EXPECT_THROW(web::make_HttpServer(serverConfig, ctx, dosGuardOverload, e), std::logic_error);
|
||||
}
|
||||
|
||||
@@ -635,8 +690,10 @@ TEST_F(WebServerTest, AdminErrorCfgTestBothAdminPasswordAndLocalAdminFalse)
|
||||
webServerPort
|
||||
);
|
||||
|
||||
auto e = std::make_shared<AdminCheckExecutor>();
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithNoAdminPasswordAndLocalAdminFalse)};
|
||||
auto const e = std::make_shared<AdminCheckExecutor>();
|
||||
ClioConfigDefinition const serverConfig{
|
||||
getParseAdminServerConfig(boost::json::parse(JSONServerConfigWithNoAdminPasswordAndLocalAdminFalse))
|
||||
};
|
||||
EXPECT_THROW(web::make_HttpServer(serverConfig, ctx, dosGuardOverload, e), std::logic_error);
|
||||
}
|
||||
|
||||
@@ -644,9 +701,11 @@ struct WebServerPrometheusTest : util::prometheus::WithPrometheus, WebServerTest
|
||||
|
||||
TEST_F(WebServerPrometheusTest, rejectedWithoutAdminPassword)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
uint32_t const webServerPort = tests::util::generateFreePort();
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort))};
|
||||
ClioConfigDefinition const serverConfig{
|
||||
getParseAdminServerConfig(boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort)))
|
||||
};
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
|
||||
auto const [status, res] = HttpSyncClient::get("localhost", std::to_string(webServerPort), "", "/metrics");
|
||||
|
||||
@@ -662,15 +721,18 @@ TEST_F(WebServerPrometheusTest, rejectedIfPrometheusIsDisabled)
|
||||
"server":{{
|
||||
"ip": "0.0.0.0",
|
||||
"port": {},
|
||||
"admin_password": "secret"
|
||||
"admin_password": "secret",
|
||||
"ws_max_sending_queue_size": 1500
|
||||
}},
|
||||
"prometheus": {{ "enabled": false }}
|
||||
}})JSON",
|
||||
webServerPort
|
||||
);
|
||||
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithDisabledPrometheus)};
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
ClioConfigDefinition const serverConfig{
|
||||
getParseAdminServerConfig(boost::json::parse(JSONServerConfigWithDisabledPrometheus))
|
||||
};
|
||||
PrometheusService::init(serverConfig);
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
|
||||
auto const [status, res] = HttpSyncClient::get(
|
||||
@@ -692,8 +754,10 @@ TEST_F(WebServerPrometheusTest, validResponse)
|
||||
uint32_t const webServerPort = tests::util::generateFreePort();
|
||||
auto& testCounter = PrometheusService::counterInt("test_counter", util::prometheus::Labels());
|
||||
++testCounter;
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort))};
|
||||
auto const e = std::make_shared<EchoExecutor>();
|
||||
ClioConfigDefinition const serverConfig{
|
||||
getParseAdminServerConfig(boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort)))
|
||||
};
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
|
||||
auto const [status, res] = HttpSyncClient::get(
|
||||
"localhost",
|
||||
|
||||
Reference in New Issue
Block a user