mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
@@ -60,7 +60,7 @@ using namespace etl;
|
||||
using namespace util::config;
|
||||
using testing::Return;
|
||||
|
||||
constexpr static auto const TwoSourcesLedgerResponse = R"({
|
||||
constexpr static auto const kTWO_SOURCES_LEDGER_RESPONSE = R"({
|
||||
"etl_sources": [
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
@@ -75,7 +75,7 @@ constexpr static auto const TwoSourcesLedgerResponse = R"({
|
||||
]
|
||||
})";
|
||||
|
||||
constexpr static auto const ThreeSourcesLedgerResponse = R"({
|
||||
constexpr static auto const kTHREE_SOURCES_LEDGER_RESPONSE = R"({
|
||||
"etl_sources": [
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
@@ -100,14 +100,14 @@ getParseLoadBalancerConfig(boost::json::value val)
|
||||
{
|
||||
ClioConfigDefinition config{
|
||||
{{"forwarding.cache_timeout",
|
||||
ConfigValue{ConfigType::Double}.defaultValue(0.0).withConstraint(validatePositiveDouble)},
|
||||
ConfigValue{ConfigType::Double}.defaultValue(0.0).withConstraint(gValidatePositiveDouble)},
|
||||
{"forwarding.request_timeout",
|
||||
ConfigValue{ConfigType::Double}.defaultValue(10.0).withConstraint(validatePositiveDouble)},
|
||||
ConfigValue{ConfigType::Double}.defaultValue(10.0).withConstraint(gValidatePositiveDouble)},
|
||||
{"allow_no_etl", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
{"etl_sources.[].ip", Array{ConfigValue{ConfigType::String}.optional().withConstraint(validateIP)}},
|
||||
{"etl_sources.[].ws_port", Array{ConfigValue{ConfigType::String}.optional().withConstraint(validatePort)}},
|
||||
{"etl_sources.[].ip", Array{ConfigValue{ConfigType::String}.optional().withConstraint(gValidateIp)}},
|
||||
{"etl_sources.[].ws_port", Array{ConfigValue{ConfigType::String}.optional().withConstraint(gValidatePort)}},
|
||||
{"etl_sources.[].grpc_port", Array{ConfigValue{ConfigType::String}.optional()}},
|
||||
{"num_markers", ConfigValue{ConfigType::Integer}.optional().withConstraint(validateNumMarkers)}}
|
||||
{"num_markers", ConfigValue{ConfigType::Integer}.optional().withConstraint(gValidateNumMarkers)}}
|
||||
};
|
||||
|
||||
auto const errors = config.parse(ConfigFileJson{val.as_object()});
|
||||
@@ -117,12 +117,6 @@ getParseLoadBalancerConfig(boost::json::value val)
|
||||
}
|
||||
|
||||
struct LoadBalancerConstructorTests : util::prometheus::WithPrometheus, MockBackendTestStrict {
|
||||
StrictMockSubscriptionManagerSharedPtr subscriptionManager_;
|
||||
StrictMockNetworkValidatedLedgersPtr networkManager_;
|
||||
StrictMockSourceFactory sourceFactory_{2};
|
||||
boost::asio::io_context ioContext_;
|
||||
boost::json::value configJson_ = boost::json::parse(TwoSourcesLedgerResponse);
|
||||
|
||||
std::unique_ptr<LoadBalancer>
|
||||
makeLoadBalancer()
|
||||
{
|
||||
@@ -130,12 +124,19 @@ struct LoadBalancerConstructorTests : util::prometheus::WithPrometheus, MockBack
|
||||
return std::make_unique<LoadBalancer>(
|
||||
cfg,
|
||||
ioContext_,
|
||||
backend,
|
||||
backend_,
|
||||
subscriptionManager_,
|
||||
networkManager_,
|
||||
[this](auto&&... args) -> SourcePtr { return sourceFactory_(std::forward<decltype(args)>(args)...); }
|
||||
);
|
||||
}
|
||||
|
||||
protected:
|
||||
StrictMockSubscriptionManagerSharedPtr subscriptionManager_;
|
||||
StrictMockNetworkValidatedLedgersPtr networkManager_;
|
||||
StrictMockSourceFactory sourceFactory_{2};
|
||||
boost::asio::io_context ioContext_;
|
||||
boost::json::value configJson_ = boost::json::parse(kTWO_SOURCES_LEDGER_RESPONSE);
|
||||
};
|
||||
|
||||
TEST_F(LoadBalancerConstructorTests, construct)
|
||||
@@ -178,9 +179,9 @@ TEST_F(LoadBalancerConstructorTests, fetchETLState_AllSourcesFail)
|
||||
{
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(2);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::EtlConnectionError}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::EtlConnectionError}));
|
||||
EXPECT_THROW({ makeLoadBalancer(); }, std::logic_error);
|
||||
}
|
||||
|
||||
@@ -199,7 +200,7 @@ TEST_F(LoadBalancerConstructorTests, fetchETLState_Source1Fails0OK)
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(2);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled).WillOnce(Return(boost::json::object{}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::EtlConnectionError}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), run);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
makeLoadBalancer();
|
||||
@@ -209,7 +210,7 @@ TEST_F(LoadBalancerConstructorTests, fetchETLState_Source0Fails1OK)
|
||||
{
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(2);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::EtlConnectionError}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled).WillOnce(Return(boost::json::object{}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), run);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
@@ -233,7 +234,7 @@ TEST_F(LoadBalancerConstructorTests, fetchETLState_AllSourcesFailButAllowNoEtlIs
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled).WillOnce(Return(boost::json::object{}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), run);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::EtlConnectionError}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
|
||||
configJson_.as_object()["allow_no_etl"] = true;
|
||||
@@ -264,6 +265,8 @@ struct LoadBalancerOnConnectHookTests : LoadBalancerConstructorTests {
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
loadBalancer_ = makeLoadBalancer();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<LoadBalancer> loadBalancer_;
|
||||
};
|
||||
|
||||
@@ -380,7 +383,7 @@ struct LoadBalancer3SourcesTests : LoadBalancerConstructorTests {
|
||||
LoadBalancer3SourcesTests()
|
||||
{
|
||||
sourceFactory_.setSourcesNumber(3);
|
||||
configJson_ = boost::json::parse(ThreeSourcesLedgerResponse);
|
||||
configJson_ = boost::json::parse(kTHREE_SOURCES_LEDGER_RESPONSE);
|
||||
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(3);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled).WillOnce(Return(boost::json::object{}));
|
||||
@@ -391,6 +394,8 @@ struct LoadBalancer3SourcesTests : LoadBalancerConstructorTests {
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(2), run);
|
||||
loadBalancer_ = makeLoadBalancer();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<LoadBalancer> loadBalancer_;
|
||||
};
|
||||
|
||||
@@ -419,6 +424,7 @@ struct LoadBalancerLoadInitialLedgerTests : LoadBalancerOnConnectHookTests {
|
||||
util::Random::setSeed(0);
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t const sequence_ = 123;
|
||||
uint32_t const numMarkers_ = 16;
|
||||
bool const cacheOnly_ = true;
|
||||
@@ -467,6 +473,7 @@ TEST_F(LoadBalancerLoadInitialLedgerTests, load_source0ReturnsStatusFalse)
|
||||
}
|
||||
|
||||
struct LoadBalancerLoadInitialLedgerCustomNumMarkersTests : LoadBalancerConstructorTests {
|
||||
protected:
|
||||
uint32_t const numMarkers_ = 16;
|
||||
uint32_t const sequence_ = 123;
|
||||
bool const cacheOnly_ = true;
|
||||
@@ -498,6 +505,8 @@ struct LoadBalancerFetchLegerTests : LoadBalancerOnConnectHookTests {
|
||||
util::Random::setSeed(0);
|
||||
response_.second.set_validated(true);
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t const sequence_ = 123;
|
||||
bool const getObjects_ = true;
|
||||
bool const getObjectNeighbors_ = false;
|
||||
@@ -574,6 +583,7 @@ struct LoadBalancerForwardToRippledTests : LoadBalancerConstructorTests, SyncAsi
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
}
|
||||
|
||||
protected:
|
||||
boost::json::object const request_{{"command", "value"}};
|
||||
std::optional<std::string> const clientIP_ = "some_ip";
|
||||
boost::json::object const response_{{"response", "other_value"}};
|
||||
@@ -585,7 +595,7 @@ TEST_F(LoadBalancerForwardToRippledTests, forward)
|
||||
auto loadBalancer = makeLoadBalancer();
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::ADMIN_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::kADMIN_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(response_));
|
||||
|
||||
@@ -600,7 +610,7 @@ TEST_F(LoadBalancerForwardToRippledTests, forwardWithXUserHeader)
|
||||
auto loadBalancer = makeLoadBalancer();
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(response_));
|
||||
|
||||
@@ -615,12 +625,12 @@ TEST_F(LoadBalancerForwardToRippledTests, source0Fails)
|
||||
auto loadBalancer = makeLoadBalancer();
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::EtlConnectionError}));
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(1),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(response_));
|
||||
|
||||
@@ -646,36 +656,36 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
testing::Values(
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"ConnectionError_RequestError",
|
||||
rpc::ClioError::etlCONNECTION_ERROR,
|
||||
rpc::ClioError::etlREQUEST_ERROR,
|
||||
rpc::ClioError::etlREQUEST_ERROR
|
||||
rpc::ClioError::EtlConnectionError,
|
||||
rpc::ClioError::EtlRequestError,
|
||||
rpc::ClioError::EtlRequestError
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"RequestError_RequestTimeout",
|
||||
rpc::ClioError::etlREQUEST_ERROR,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT
|
||||
rpc::ClioError::EtlRequestError,
|
||||
rpc::ClioError::EtlRequestTimeout,
|
||||
rpc::ClioError::EtlRequestTimeout
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"RequestTimeout_InvalidResponse",
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlINVALID_RESPONSE,
|
||||
rpc::ClioError::etlINVALID_RESPONSE
|
||||
rpc::ClioError::EtlRequestTimeout,
|
||||
rpc::ClioError::EtlInvalidResponse,
|
||||
rpc::ClioError::EtlInvalidResponse
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"BothRequestTimeout",
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT
|
||||
rpc::ClioError::EtlRequestTimeout,
|
||||
rpc::ClioError::EtlRequestTimeout,
|
||||
rpc::ClioError::EtlRequestTimeout
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"InvalidResponse_RequestError",
|
||||
rpc::ClioError::etlINVALID_RESPONSE,
|
||||
rpc::ClioError::etlREQUEST_ERROR,
|
||||
rpc::ClioError::etlINVALID_RESPONSE
|
||||
rpc::ClioError::EtlInvalidResponse,
|
||||
rpc::ClioError::EtlRequestError,
|
||||
rpc::ClioError::EtlInvalidResponse
|
||||
}
|
||||
),
|
||||
tests::util::NameGenerator
|
||||
tests::util::kNAME_GENERATOR
|
||||
);
|
||||
|
||||
TEST_P(LoadBalancerForwardToRippledErrorTests, bothSourcesFail)
|
||||
@@ -684,12 +694,12 @@ TEST_P(LoadBalancerForwardToRippledErrorTests, bothSourcesFail)
|
||||
auto loadBalancer = makeLoadBalancer();
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(std::unexpected{GetParam().firstSourceError}));
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(1),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(std::unexpected{GetParam().secondSourceError}));
|
||||
|
||||
@@ -710,7 +720,7 @@ TEST_F(LoadBalancerForwardToRippledTests, forwardingCacheEnabled)
|
||||
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(response_));
|
||||
|
||||
@@ -737,12 +747,12 @@ TEST_F(LoadBalancerForwardToRippledTests, onLedgerClosedHookInvalidatesCache)
|
||||
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(response_));
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(1),
|
||||
forwardToRippled(request, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
forwardToRippled(request, clientIP_, LoadBalancer::kUSER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(boost::json::object{}));
|
||||
|
||||
@@ -764,7 +774,7 @@ TEST_F(LoadBalancerForwardToRippledTests, commandLineMissing)
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
EXPECT_EQ(
|
||||
loadBalancer->forwardToRippled(request, clientIP_, false, yield).error(),
|
||||
rpc::ClioError::rpcCOMMAND_IS_MISSING
|
||||
rpc::ClioError::RpcCommandIsMissing
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user