mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "etl/ETLState.hpp"
|
||||
#include "rpc/Errors.hpp"
|
||||
#include "util/LoggerFixtures.hpp"
|
||||
#include "util/MockSource.hpp"
|
||||
|
||||
@@ -37,7 +38,7 @@ struct ETLStateTest : public NoLoggerFixture {
|
||||
|
||||
TEST_F(ETLStateTest, Error)
|
||||
{
|
||||
EXPECT_CALL(source, forwardToRippled).WillOnce(Return(std::nullopt));
|
||||
EXPECT_CALL(source, forwardToRippled).WillOnce(Return(std::unexpected{rpc::ClioError::etlINVALID_RESPONSE}));
|
||||
auto const state = etl::ETLState::fetchETLStateFromSource(source);
|
||||
EXPECT_FALSE(state);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "etl/impl/ForwardingSource.hpp"
|
||||
#include "rpc/Errors.hpp"
|
||||
#include "util/AsioContextTestFixture.hpp"
|
||||
#include "util/TestWsServer.hpp"
|
||||
|
||||
@@ -50,7 +51,8 @@ TEST_F(ForwardingSourceTests, ConnectionFailed)
|
||||
{
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto result = forwardingSource.forwardToRippled({}, {}, {}, yield);
|
||||
EXPECT_FALSE(result);
|
||||
ASSERT_FALSE(result);
|
||||
EXPECT_EQ(result.error(), rpc::ClioError::etlCONNECTION_ERROR);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -90,7 +92,8 @@ TEST_F(ForwardingSourceOperationsTests, XUserHeader)
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto result =
|
||||
forwardingSource.forwardToRippled(boost::json::parse(message_).as_object(), {}, xUserValue, yield);
|
||||
EXPECT_FALSE(result);
|
||||
ASSERT_FALSE(result);
|
||||
EXPECT_EQ(result.error(), rpc::ClioError::etlREQUEST_ERROR);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -103,7 +106,8 @@ TEST_F(ForwardingSourceOperationsTests, ReadFailed)
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto result = forwardingSource.forwardToRippled(boost::json::parse(message_).as_object(), {}, {}, yield);
|
||||
EXPECT_FALSE(result);
|
||||
ASSERT_FALSE(result);
|
||||
EXPECT_EQ(result.error(), rpc::ClioError::etlREQUEST_ERROR);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -116,7 +120,8 @@ TEST_F(ForwardingSourceOperationsTests, ReadTimeout)
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto result = forwardingSource.forwardToRippled(boost::json::parse(message_).as_object(), {}, {}, yield);
|
||||
EXPECT_FALSE(result);
|
||||
ASSERT_FALSE(result);
|
||||
EXPECT_EQ(result.error(), rpc::ClioError::etlREQUEST_TIMEOUT);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -137,7 +142,8 @@ TEST_F(ForwardingSourceOperationsTests, ParseFailed)
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto result = forwardingSource.forwardToRippled(boost::json::parse(message_).as_object(), {}, {}, yield);
|
||||
EXPECT_FALSE(result);
|
||||
ASSERT_FALSE(result);
|
||||
EXPECT_EQ(result.error(), rpc::ClioError::etlINVALID_RESPONSE);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -159,7 +165,8 @@ TEST_F(ForwardingSourceOperationsTests, GotNotAnObject)
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto result = forwardingSource.forwardToRippled(boost::json::parse(message_).as_object(), {}, {}, yield);
|
||||
EXPECT_FALSE(result);
|
||||
ASSERT_FALSE(result);
|
||||
EXPECT_EQ(result.error(), rpc::ClioError::etlINVALID_RESPONSE);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
|
||||
#include "etl/LoadBalancer.hpp"
|
||||
#include "etl/Source.hpp"
|
||||
#include "rpc/Errors.hpp"
|
||||
#include "util/AsioContextTestFixture.hpp"
|
||||
#include "util/MockBackendTestFixture.hpp"
|
||||
#include "util/MockNetworkValidatedLedgers.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockSource.hpp"
|
||||
#include "util/MockSubscriptionManager.hpp"
|
||||
#include "util/NameGenerator.hpp"
|
||||
#include "util/Random.hpp"
|
||||
#include "util/config/Config.hpp"
|
||||
|
||||
@@ -41,10 +43,12 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -111,8 +115,10 @@ TEST_F(LoadBalancerConstructorTests, forwardingTimeoutPassedToSourceFactory)
|
||||
TEST_F(LoadBalancerConstructorTests, fetchETLState_AllSourcesFail)
|
||||
{
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(2);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled).WillOnce(Return(std::nullopt));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled).WillOnce(Return(std::nullopt));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
EXPECT_THROW({ makeLoadBalancer(); }, std::logic_error);
|
||||
}
|
||||
|
||||
@@ -130,7 +136,8 @@ 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::nullopt));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), run);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
makeLoadBalancer();
|
||||
@@ -139,7 +146,8 @@ TEST_F(LoadBalancerConstructorTests, fetchETLState_Source1Fails0OK)
|
||||
TEST_F(LoadBalancerConstructorTests, fetchETLState_Source0Fails1OK)
|
||||
{
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(2);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled).WillOnce(Return(std::nullopt));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled).WillOnce(Return(boost::json::object{}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(0), run);
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
@@ -162,7 +170,8 @@ TEST_F(LoadBalancerConstructorTests, fetchETLState_AllSourcesFailButAllowNoEtlIs
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(2);
|
||||
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::nullopt));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), forwardToRippled)
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
EXPECT_CALL(sourceFactory_.sourceAt(1), run);
|
||||
|
||||
configJson_.as_object()["allow_no_etl"] = true;
|
||||
@@ -566,7 +575,7 @@ TEST_F(LoadBalancerForwardToRippledTests, source0Fails)
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(std::nullopt));
|
||||
.WillOnce(Return(std::unexpected{rpc::ClioError::etlCONNECTION_ERROR}));
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(1),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
@@ -578,7 +587,56 @@ TEST_F(LoadBalancerForwardToRippledTests, source0Fails)
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(LoadBalancerForwardToRippledTests, bothSourcesFail)
|
||||
struct LoadBalancerForwardToRippledErrorTestBundle {
|
||||
std::string testName;
|
||||
rpc::ClioError firstSourceError;
|
||||
rpc::ClioError secondSourceError;
|
||||
rpc::ClioError responseExpectedError;
|
||||
};
|
||||
|
||||
struct LoadBalancerForwardToRippledErrorTests
|
||||
: LoadBalancerForwardToRippledTests,
|
||||
testing::WithParamInterface<LoadBalancerForwardToRippledErrorTestBundle> {};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
LoadBalancerForwardToRippledErrorTests,
|
||||
LoadBalancerForwardToRippledErrorTests,
|
||||
testing::Values(
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"ConnectionError_RequestError",
|
||||
rpc::ClioError::etlCONNECTION_ERROR,
|
||||
rpc::ClioError::etlREQUEST_ERROR,
|
||||
rpc::ClioError::etlREQUEST_ERROR
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"RequestError_RequestTimeout",
|
||||
rpc::ClioError::etlREQUEST_ERROR,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"RequestTimeout_InvalidResponse",
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlINVALID_RESPONSE,
|
||||
rpc::ClioError::etlINVALID_RESPONSE
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"BothRequestTimeout",
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT,
|
||||
rpc::ClioError::etlREQUEST_TIMEOUT
|
||||
},
|
||||
LoadBalancerForwardToRippledErrorTestBundle{
|
||||
"InvalidResponse_RequestError",
|
||||
rpc::ClioError::etlINVALID_RESPONSE,
|
||||
rpc::ClioError::etlREQUEST_ERROR,
|
||||
rpc::ClioError::etlINVALID_RESPONSE
|
||||
}
|
||||
),
|
||||
tests::util::NameGenerator
|
||||
);
|
||||
|
||||
TEST_P(LoadBalancerForwardToRippledErrorTests, bothSourcesFail)
|
||||
{
|
||||
EXPECT_CALL(sourceFactory_, makeSource).Times(2);
|
||||
auto loadBalancer = makeLoadBalancer();
|
||||
@@ -586,15 +644,17 @@ TEST_F(LoadBalancerForwardToRippledTests, bothSourcesFail)
|
||||
sourceFactory_.sourceAt(0),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(std::nullopt));
|
||||
.WillOnce(Return(std::unexpected{GetParam().firstSourceError}));
|
||||
EXPECT_CALL(
|
||||
sourceFactory_.sourceAt(1),
|
||||
forwardToRippled(request_, clientIP_, LoadBalancer::USER_FORWARDING_X_USER_VALUE, testing::_)
|
||||
)
|
||||
.WillOnce(Return(std::nullopt));
|
||||
.WillOnce(Return(std::unexpected{GetParam().secondSourceError}));
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
EXPECT_EQ(loadBalancer->forwardToRippled(request_, clientIP_, false, yield), std::nullopt);
|
||||
auto const response = loadBalancer->forwardToRippled(request_, clientIP_, false, yield);
|
||||
ASSERT_FALSE(response);
|
||||
EXPECT_EQ(response.error(), GetParam().responseExpectedError);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "etl/impl/SourceImpl.hpp"
|
||||
#include "rpc/Errors.hpp"
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
@@ -63,7 +64,7 @@ struct SubscriptionSourceMock {
|
||||
struct ForwardingSourceMock {
|
||||
MOCK_METHOD(void, constructor, (std::string const&, std::string const&, std::chrono::steady_clock::duration));
|
||||
|
||||
using ForwardToRippledReturnType = std::optional<boost::json::object>;
|
||||
using ForwardToRippledReturnType = std::expected<boost::json::object, rpc::ClioError>;
|
||||
using ClientIpOpt = std::optional<std::string>;
|
||||
MOCK_METHOD(
|
||||
ForwardToRippledReturnType,
|
||||
|
||||
Reference in New Issue
Block a user