mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-26 22:55:53 +00:00
refactor: Use expected<void, error> instead of optional<error> (#2565)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
This commit is contained in:
@@ -143,9 +143,9 @@ public:
|
||||
*
|
||||
* @param response The response to send.
|
||||
* @param yield The yield context.
|
||||
* @return An error if the operation failed or nullopt if it succeeded.
|
||||
* @return An error if the operation fails, otherwise nothing.
|
||||
*/
|
||||
virtual std::optional<Error>
|
||||
virtual std::expected<void, Error>
|
||||
send(Response response, boost::asio::yield_context yield) = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -147,9 +147,9 @@ makeConnection(
|
||||
tagDecoratorFactory
|
||||
);
|
||||
sslConnection->setTimeout(std::chrono::seconds{10});
|
||||
auto const maybeError = sslConnection->sslHandshake(yield);
|
||||
if (maybeError.has_value())
|
||||
return std::unexpected{fmt::format("SSL handshake error: {}", maybeError->message())};
|
||||
auto const expectedSuccess = sslConnection->sslHandshake(yield);
|
||||
if (not expectedSuccess.has_value())
|
||||
return std::unexpected{fmt::format("SSL handshake error: {}", expectedSuccess.error().message())};
|
||||
|
||||
connection = std::move(sslConnection);
|
||||
} else {
|
||||
|
||||
@@ -70,8 +70,8 @@ SubscriptionContext::send(std::shared_ptr<std::string> message)
|
||||
}
|
||||
|
||||
tasksGroup_.spawn(yield_, [this, message = std::move(message)](boost::asio::yield_context innerYield) mutable {
|
||||
auto const maybeError = connection_.get().sendShared(std::move(message), innerYield);
|
||||
if (maybeError.has_value() and errorHandler_(*maybeError, connection_)) {
|
||||
auto const expectedSuccess = connection_.get().sendShared(std::move(message), innerYield);
|
||||
if (not expectedSuccess.has_value() and errorHandler_(expectedSuccess.error(), connection_)) {
|
||||
connection_.get().close(innerYield);
|
||||
gotError_ = true;
|
||||
}
|
||||
|
||||
@@ -365,9 +365,9 @@ ConnectionHandler::processRequest(
|
||||
auto response = handleRequest(connection, subscriptionContext, request, yield);
|
||||
|
||||
LOG(log_.trace()) << connection.tag() << "Sending response: " << response.message();
|
||||
auto const maybeError = connection.send(std::move(response), yield);
|
||||
if (maybeError.has_value()) {
|
||||
return handleError(maybeError.value(), connection);
|
||||
auto const expectedSuccess = connection.send(std::move(response), yield);
|
||||
if (not expectedSuccess.has_value()) {
|
||||
return handleError(expectedSuccess.error(), connection);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
virtual std::expected<ConnectionPtr, Error>
|
||||
upgrade(util::TagDecoratorFactory const& tagDecoratorFactory, boost::asio::yield_context yield) = 0;
|
||||
|
||||
virtual std::optional<Error>
|
||||
virtual std::expected<void, Error>
|
||||
sendRaw(
|
||||
boost::beast::http::response<boost::beast::http::string_body> response,
|
||||
boost::asio::yield_context yield
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
HttpConnection&
|
||||
operator=(HttpConnection const& other) = delete;
|
||||
|
||||
std::optional<Error>
|
||||
std::expected<void, Error>
|
||||
sslHandshake(boost::asio::yield_context yield)
|
||||
requires IsSslTcpStream<StreamType>
|
||||
{
|
||||
@@ -132,11 +132,11 @@ public:
|
||||
auto const bytesUsed =
|
||||
stream_.async_handshake(boost::asio::ssl::stream_base::server, buffer_.cdata(), yield[error]);
|
||||
if (error)
|
||||
return error;
|
||||
return std::unexpected{error};
|
||||
|
||||
buffer_.consume(bytesUsed);
|
||||
|
||||
return std::nullopt;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<Error>
|
||||
std::expected<void, Error>
|
||||
sendRaw(
|
||||
boost::beast::http::response<boost::beast::http::string_body> response,
|
||||
boost::asio::yield_context yield
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
timeout_ = newTimeout;
|
||||
}
|
||||
|
||||
std::optional<Error>
|
||||
std::expected<void, Error>
|
||||
send(Response response, boost::asio::yield_context yield) override
|
||||
{
|
||||
auto httpResponse = std::move(response).intoHttpResponse();
|
||||
|
||||
@@ -47,15 +47,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<Error>
|
||||
std::expected<void, Error>
|
||||
send(T message, boost::asio::yield_context yield)
|
||||
{
|
||||
if (error_)
|
||||
return error_;
|
||||
return std::unexpected{error_};
|
||||
|
||||
queue_.push(std::move(message));
|
||||
if (isSending_)
|
||||
return std::nullopt;
|
||||
return {};
|
||||
|
||||
isSending_ = true;
|
||||
while (not queue_.empty() and not error_) {
|
||||
@@ -65,8 +65,8 @@ public:
|
||||
}
|
||||
isSending_ = false;
|
||||
if (error_)
|
||||
return error_;
|
||||
return std::nullopt;
|
||||
return std::unexpected{error_};
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class WsConnectionBase : public Connection {
|
||||
public:
|
||||
using Connection::Connection;
|
||||
|
||||
virtual std::optional<Error>
|
||||
virtual std::expected<void, Error>
|
||||
sendShared(std::shared_ptr<std::string> message, boost::asio::yield_context yield) = 0;
|
||||
};
|
||||
|
||||
@@ -108,14 +108,14 @@ public:
|
||||
WsConnection&
|
||||
operator=(WsConnection const&) = delete;
|
||||
|
||||
std::optional<Error>
|
||||
std::expected<void, Error>
|
||||
performHandshake(boost::asio::yield_context yield)
|
||||
{
|
||||
Error error;
|
||||
stream_.async_accept(initialRequest_, yield[error]);
|
||||
if (error)
|
||||
return error;
|
||||
return std::nullopt;
|
||||
return std::unexpected{error};
|
||||
return {};
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<Error>
|
||||
std::expected<void, Error>
|
||||
sendShared(std::shared_ptr<std::string> message, boost::asio::yield_context yield) override
|
||||
{
|
||||
return sendingQueue_.send(std::move(message), yield);
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
stream_.set_option(wsTimeout);
|
||||
}
|
||||
|
||||
std::optional<Error>
|
||||
std::expected<void, Error>
|
||||
send(Response response, boost::asio::yield_context yield) override
|
||||
{
|
||||
return sendingQueue_.send(std::move(response), yield);
|
||||
@@ -206,9 +206,9 @@ makeWsConnection(
|
||||
auto connection = std::make_unique<WsConnection<StreamType>>(
|
||||
std::forward<StreamType>(stream), std::move(ip), std::move(buffer), std::move(request), tagDecoratorFactory
|
||||
);
|
||||
auto maybeError = connection->performHandshake(yield);
|
||||
if (maybeError.has_value())
|
||||
return std::unexpected{maybeError.value()};
|
||||
auto const expectedSuccess = connection->performHandshake(yield);
|
||||
if (not expectedSuccess.has_value())
|
||||
return std::unexpected{expectedSuccess.error()};
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ HttpAsyncClient::HttpAsyncClient(boost::asio::io_context& ioContext) : stream_{i
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
HttpAsyncClient::connect(
|
||||
std::string_view host,
|
||||
std::string_view port,
|
||||
@@ -198,18 +198,18 @@ HttpAsyncClient::connect(
|
||||
boost::asio::ip::tcp::resolver resolver{stream_.get_executor()};
|
||||
auto const resolverResults = resolver.resolve(host, port, error);
|
||||
if (error)
|
||||
return error;
|
||||
return std::unexpected{error};
|
||||
|
||||
ASSERT(!resolverResults.empty(), "No results from resolver");
|
||||
|
||||
boost::beast::get_lowest_layer(stream_).expires_after(timeout);
|
||||
stream_.async_connect(resolverResults.begin()->endpoint(), yield[error]);
|
||||
if (error)
|
||||
return error;
|
||||
return std::nullopt;
|
||||
return std::unexpected{error};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
HttpAsyncClient::send(
|
||||
boost::beast::http::request<boost::beast::http::string_body> request,
|
||||
boost::asio::yield_context yield,
|
||||
@@ -221,8 +221,8 @@ HttpAsyncClient::send(
|
||||
boost::beast::get_lowest_layer(stream_).expires_after(timeout);
|
||||
http::async_write(stream_, request, yield[error]);
|
||||
if (error)
|
||||
return error;
|
||||
return std::nullopt;
|
||||
return std::unexpected{error};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<boost::beast::http::response<boost::beast::http::string_body>, boost::system::error_code>
|
||||
|
||||
@@ -78,7 +78,7 @@ class HttpAsyncClient {
|
||||
public:
|
||||
HttpAsyncClient(boost::asio::io_context& ioContext);
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
connect(
|
||||
std::string_view host,
|
||||
std::string_view port,
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
std::chrono::steady_clock::duration timeout
|
||||
);
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
send(
|
||||
boost::beast::http::request<boost::beast::http::string_body> request,
|
||||
boost::asio::yield_context yield,
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
|
||||
void
|
||||
gracefulShutdown();
|
||||
|
||||
void
|
||||
disconnect();
|
||||
};
|
||||
|
||||
@@ -137,7 +137,7 @@ WebSocketAsyncClient::WebSocketAsyncClient(boost::asio::io_context& ioContext) :
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
WebSocketAsyncClient::connect(
|
||||
std::string const& host,
|
||||
std::string const& port,
|
||||
@@ -153,7 +153,7 @@ WebSocketAsyncClient::connect(
|
||||
boost::beast::get_lowest_layer(stream_).expires_after(timeout);
|
||||
stream_.next_layer().async_connect(results, yield[error]);
|
||||
if (error)
|
||||
return error;
|
||||
return std::unexpected{error};
|
||||
|
||||
boost::beast::websocket::stream_base::timeout wsTimeout =
|
||||
boost::beast::websocket::stream_base::timeout::suggested(boost::beast::role_type::client);
|
||||
@@ -173,12 +173,12 @@ WebSocketAsyncClient::connect(
|
||||
stream_.async_handshake(fmt::format("{}:{}", host, port), "/", yield[error]);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
return std::unexpected{error};
|
||||
|
||||
return std::nullopt;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
WebSocketAsyncClient::send(
|
||||
boost::asio::yield_context yield,
|
||||
std::string_view message,
|
||||
@@ -190,8 +190,8 @@ WebSocketAsyncClient::send(
|
||||
);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
return std::nullopt;
|
||||
return std::unexpected{error};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<std::string, boost::system::error_code>
|
||||
|
||||
@@ -56,7 +56,7 @@ class WebSocketAsyncClient {
|
||||
public:
|
||||
WebSocketAsyncClient(boost::asio::io_context& ioContext);
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
connect(
|
||||
std::string const& host,
|
||||
std::string const& port,
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
std::vector<WebHeader> additionalHeaders = {}
|
||||
);
|
||||
|
||||
std::optional<boost::system::error_code>
|
||||
std::expected<void, boost::system::error_code>
|
||||
send(boost::asio::yield_context yield, std::string_view message, std::chrono::steady_clock::duration timeout);
|
||||
|
||||
std::expected<std::string, boost::system::error_code>
|
||||
|
||||
@@ -48,7 +48,7 @@ struct MockConnectionImpl : web::ng::Connection {
|
||||
|
||||
MOCK_METHOD(void, setTimeout, (std::chrono::steady_clock::duration), (override));
|
||||
|
||||
using SendReturnType = std::optional<web::ng::Error>;
|
||||
using SendReturnType = std::expected<void, web::ng::Error>;
|
||||
MOCK_METHOD(SendReturnType, send, (web::ng::Response, boost::asio::yield_context), (override));
|
||||
|
||||
using ReceiveReturnType = std::expected<web::ng::Request, web::ng::Error>;
|
||||
|
||||
@@ -44,7 +44,7 @@ struct MockHttpConnectionImpl : web::ng::impl::UpgradableConnection {
|
||||
|
||||
MOCK_METHOD(void, setTimeout, (std::chrono::steady_clock::duration), (override));
|
||||
|
||||
using SendReturnType = std::optional<web::ng::Error>;
|
||||
using SendReturnType = std::expected<void, web::ng::Error>;
|
||||
MOCK_METHOD(SendReturnType, send, (web::ng::Response, boost::asio::yield_context), (override));
|
||||
|
||||
MOCK_METHOD(
|
||||
|
||||
@@ -42,7 +42,7 @@ struct MockWsConnectionImpl : web::ng::impl::WsConnectionBase {
|
||||
|
||||
MOCK_METHOD(void, setTimeout, (std::chrono::steady_clock::duration), (override));
|
||||
|
||||
using SendReturnType = std::optional<web::ng::Error>;
|
||||
using SendReturnType = std::expected<void, web::ng::Error>;
|
||||
MOCK_METHOD(SendReturnType, send, (web::ng::Response, boost::asio::yield_context), (override));
|
||||
|
||||
using ReceiveReturnType = std::expected<web::ng::Request, web::ng::Error>;
|
||||
@@ -50,13 +50,7 @@ struct MockWsConnectionImpl : web::ng::impl::WsConnectionBase {
|
||||
|
||||
MOCK_METHOD(void, close, (boost::asio::yield_context), (override));
|
||||
|
||||
using SendBufferReturnType = std::optional<web::ng::Error>;
|
||||
MOCK_METHOD(
|
||||
SendBufferReturnType,
|
||||
sendShared,
|
||||
(std::shared_ptr<std::string>, boost::asio::yield_context),
|
||||
(override)
|
||||
);
|
||||
MOCK_METHOD(SendReturnType, sendShared, (std::shared_ptr<std::string>, boost::asio::yield_context), (override));
|
||||
};
|
||||
|
||||
using MockWsConnection = testing::NiceMock<MockWsConnectionImpl>;
|
||||
|
||||
@@ -261,9 +261,9 @@ TEST_F(ServerHttpTest, ClientDisconnects)
|
||||
{
|
||||
HttpAsyncClient client{ctx_};
|
||||
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
client.disconnect();
|
||||
server_->stop(yield);
|
||||
@@ -312,16 +312,17 @@ TEST_F(ServerHttpTest, OnConnectCheck)
|
||||
return {};
|
||||
});
|
||||
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
// Have to send a request here because the server does async_detect_ssl() which waits for some data to appear
|
||||
client.send(
|
||||
expectedSuccess = client.send(
|
||||
http::request<http::string_body>{http::verb::get, "/", 11, requestMessage_},
|
||||
yield,
|
||||
std::chrono::milliseconds{100}
|
||||
);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
// Wait for the onConnectCheck to be called
|
||||
timer.expires_after(std::chrono::milliseconds{100});
|
||||
@@ -374,16 +375,17 @@ TEST_F(ServerHttpTest, OnConnectCheckFailed)
|
||||
});
|
||||
|
||||
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
// Have to send a request here because the server does async_detect_ssl() which waits for some data to appear
|
||||
client.send(
|
||||
expectedSuccess = client.send(
|
||||
http::request<http::string_body>{http::verb::get, "/", 11, requestMessage_},
|
||||
yield,
|
||||
std::chrono::milliseconds{100}
|
||||
);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
auto const response = client.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(response.has_value()) << response.error().message(); }();
|
||||
@@ -434,15 +436,17 @@ TEST_F(ServerHttpTest, OnDisconnectHook)
|
||||
|
||||
EXPECT_CALL(onDisconnectHookMock, Call).WillOnce([&timer](auto&&) { timer.cancel(); });
|
||||
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
client.send(
|
||||
// Have to send a request here because the server does async_detect_ssl() which waits for some data to appear
|
||||
expectedSuccess = client.send(
|
||||
http::request<http::string_body>{http::verb::get, "/", 11, requestMessage_},
|
||||
yield,
|
||||
std::chrono::milliseconds{100}
|
||||
);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
client.gracefulShutdown();
|
||||
|
||||
@@ -463,17 +467,17 @@ TEST_F(ServerHttpTest, ClientIsDisconnectedIfServerStopped)
|
||||
{
|
||||
HttpAsyncClient client{ctx_};
|
||||
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
// Have to send a request here because the server does async_detect_ssl() which waits for some data to appear
|
||||
maybeError = client.send(
|
||||
expectedSuccess = client.send(
|
||||
http::request<http::string_body>{http::verb::get, "/", 11, requestMessage_},
|
||||
yield,
|
||||
std::chrono::milliseconds{100}
|
||||
);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
auto message = client.receive(yield, std::chrono::milliseconds{100});
|
||||
EXPECT_TRUE(message.has_value()) << message.error().message();
|
||||
@@ -498,13 +502,13 @@ TEST_P(ServerHttpTest, RequestResponse)
|
||||
Response const response{http::status::ok, "some response", Request{request}};
|
||||
|
||||
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
maybeError = client.send(request, yield, std::chrono::milliseconds{100});
|
||||
EXPECT_FALSE(maybeError.has_value()) << maybeError->message();
|
||||
expectedSuccess = client.send(request, yield, std::chrono::milliseconds{100});
|
||||
EXPECT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message();
|
||||
|
||||
auto const expectedResponse = client.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedResponse.has_value()) << expectedResponse.error().message(); }();
|
||||
@@ -548,9 +552,9 @@ TEST_F(ServerTest, WsClientDisconnects)
|
||||
WebSocketAsyncClient client{ctx_};
|
||||
|
||||
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
client.close();
|
||||
server_->stop(yield);
|
||||
@@ -570,13 +574,13 @@ TEST_F(ServerTest, WsRequestResponse)
|
||||
Response const response{http::status::ok, "some response", Request{requestMessage_, headers}};
|
||||
|
||||
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
maybeError = client.send(yield, requestMessage_, std::chrono::milliseconds{100});
|
||||
EXPECT_FALSE(maybeError.has_value()) << maybeError->message();
|
||||
expectedSuccess = client.send(yield, requestMessage_, std::chrono::milliseconds{100});
|
||||
EXPECT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message();
|
||||
|
||||
auto const expectedResponse = client.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedResponse.has_value()) << expectedResponse.error().message(); }();
|
||||
@@ -608,10 +612,10 @@ TEST_F(ServerTest, WsClientIsDisconnectedIfServerStopped)
|
||||
{
|
||||
WebSocketAsyncClient client{ctx_};
|
||||
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
|
||||
auto maybeError =
|
||||
auto expectedSuccess =
|
||||
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
|
||||
EXPECT_TRUE(maybeError.has_value());
|
||||
EXPECT_EQ(maybeError.value().value(), static_cast<int>(boost::beast::websocket::error::upgrade_declined));
|
||||
EXPECT_FALSE(expectedSuccess.has_value());
|
||||
EXPECT_EQ(expectedSuccess.error().value(), static_cast<int>(boost::beast::websocket::error::upgrade_declined));
|
||||
|
||||
ctx_.stop();
|
||||
});
|
||||
|
||||
@@ -65,10 +65,13 @@ TEST_F(NgSubscriptionContextTests, Send)
|
||||
auto subscriptionContext = makeSubscriptionContext(yield);
|
||||
auto const message = std::make_shared<std::string>("some message");
|
||||
|
||||
EXPECT_CALL(connection_, sendShared).WillOnce([&message](std::shared_ptr<std::string> sendingMessage, auto&&) {
|
||||
EXPECT_CALL(connection_, sendShared)
|
||||
.WillOnce(
|
||||
[&message](std::shared_ptr<std::string> sendingMessage, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(sendingMessage, message);
|
||||
return std::nullopt;
|
||||
});
|
||||
return {};
|
||||
}
|
||||
);
|
||||
subscriptionContext.send(message);
|
||||
subscriptionContext.disconnect(yield);
|
||||
});
|
||||
@@ -84,16 +87,24 @@ TEST_F(NgSubscriptionContextTests, SendOrder)
|
||||
testing::Sequence const sequence;
|
||||
EXPECT_CALL(connection_, sendShared)
|
||||
.InSequence(sequence)
|
||||
.WillOnce([&message1](std::shared_ptr<std::string> sendingMessage, auto&&) {
|
||||
.WillOnce(
|
||||
[&message1](
|
||||
std::shared_ptr<std::string> sendingMessage, auto&&
|
||||
) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(sendingMessage, message1);
|
||||
return std::nullopt;
|
||||
});
|
||||
return {};
|
||||
}
|
||||
);
|
||||
EXPECT_CALL(connection_, sendShared)
|
||||
.InSequence(sequence)
|
||||
.WillOnce([&message2](std::shared_ptr<std::string> sendingMessage, auto&&) {
|
||||
.WillOnce(
|
||||
[&message2](
|
||||
std::shared_ptr<std::string> sendingMessage, auto&&
|
||||
) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(sendingMessage, message2);
|
||||
return std::nullopt;
|
||||
});
|
||||
return {};
|
||||
}
|
||||
);
|
||||
|
||||
subscriptionContext.send(message1);
|
||||
subscriptionContext.send(message2);
|
||||
@@ -109,7 +120,7 @@ TEST_F(NgSubscriptionContextTests, SendFailed)
|
||||
|
||||
EXPECT_CALL(connection_, sendShared).WillOnce([&message](std::shared_ptr<std::string> sendingMessage, auto&&) {
|
||||
EXPECT_EQ(sendingMessage, message);
|
||||
return boost::system::errc::make_error_code(boost::system::errc::not_supported);
|
||||
return std::unexpected{boost::system::errc::make_error_code(boost::system::errc::not_supported)};
|
||||
});
|
||||
EXPECT_CALL(errorHandler_, Call).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(connection_, close);
|
||||
@@ -125,11 +136,15 @@ TEST_F(NgSubscriptionContextTests, SendTooManySubscriptions)
|
||||
auto const message = std::make_shared<std::string>("message1");
|
||||
|
||||
EXPECT_CALL(connection_, sendShared)
|
||||
.WillOnce([&message](std::shared_ptr<std::string> sendingMessage, boost::asio::yield_context innerYield) {
|
||||
.WillOnce(
|
||||
[&message](
|
||||
std::shared_ptr<std::string> sendingMessage, boost::asio::yield_context innerYield
|
||||
) -> std::expected<void, web::ng::Error> {
|
||||
boost::asio::post(innerYield); // simulate send is slow by switching to another coroutine
|
||||
EXPECT_EQ(sendingMessage, message);
|
||||
return std::nullopt;
|
||||
});
|
||||
return {};
|
||||
}
|
||||
);
|
||||
EXPECT_CALL(connection_, close);
|
||||
|
||||
subscriptionContext.send(message);
|
||||
|
||||
@@ -173,9 +173,10 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_NoHandler_Send)
|
||||
.WillOnce(Return(makeRequest("some_request", headers)))
|
||||
.WillOnce(Return(makeError(websocket::error::closed)));
|
||||
|
||||
EXPECT_CALL(*mockHttpConnection, send).WillOnce([](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockHttpConnection, send)
|
||||
.WillOnce([](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), "WebSocket is not supported by this server");
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockHttpConnection.get()](Connection const& c) {
|
||||
@@ -197,12 +198,13 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_BadTarget_Send)
|
||||
.WillOnce(Return(makeRequest(http::request<http::string_body>{http::verb::get, target, 11, requestMessage})))
|
||||
.WillOnce(Return(makeError(http::error::end_of_stream)));
|
||||
|
||||
EXPECT_CALL(*mockHttpConnection, send).WillOnce([](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockHttpConnection, send)
|
||||
.WillOnce([](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), "Bad target");
|
||||
auto const httpResponse = std::move(response).intoHttpResponse();
|
||||
EXPECT_EQ(httpResponse.result(), http::status::bad_request);
|
||||
EXPECT_EQ(httpResponse.version(), 11);
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockHttpConnection.get()](Connection const& c) {
|
||||
@@ -221,9 +223,10 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_BadMethod_Send)
|
||||
.WillOnce(Return(makeRequest(http::request<http::string_body>{http::verb::acl, "/", 11})))
|
||||
.WillOnce(Return(makeError(http::error::end_of_stream)));
|
||||
|
||||
EXPECT_CALL(*mockHttpConnection, send).WillOnce([](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockHttpConnection, send)
|
||||
.WillOnce([](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), "Unsupported http method");
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockHttpConnection.get()](Connection const& c) {
|
||||
@@ -255,9 +258,10 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_Send)
|
||||
return Response(http::status::ok, responseMessage, request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockWsConnection, send).WillOnce([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockWsConnection, send)
|
||||
.WillOnce([&responseMessage](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockWsConnection.get()](Connection const& c) {
|
||||
@@ -290,13 +294,17 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, SendSubscriptionMessage)
|
||||
return Response(http::status::ok, "", request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockWsConnection, send).WillOnce(Return(std::nullopt));
|
||||
EXPECT_CALL(*mockWsConnection, send).WillOnce(Return(std::expected<void, web::ng::Error>{}));
|
||||
|
||||
EXPECT_CALL(*mockWsConnection, sendShared)
|
||||
.WillOnce([&subscriptionMessage](std::shared_ptr<std::string> sendingMessage, auto&&) {
|
||||
.WillOnce(
|
||||
[&subscriptionMessage](
|
||||
std::shared_ptr<std::string> sendingMessage, auto&&
|
||||
) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(*sendingMessage, subscriptionMessage);
|
||||
return std::nullopt;
|
||||
});
|
||||
return {};
|
||||
}
|
||||
);
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockWsConnection.get()](Connection const& c) {
|
||||
EXPECT_EQ(&c, connectionPtr);
|
||||
@@ -328,7 +336,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, SubscriptionContextIsDisconnec
|
||||
return Response(http::status::ok, "", request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockWsConnection, send).WillOnce(Return(std::nullopt));
|
||||
EXPECT_CALL(*mockWsConnection, send).WillOnce(Return(std::expected<void, web::ng::Error>{}));
|
||||
|
||||
EXPECT_CALL(onDisconnectHook, Call).After(expectationReceiveCalled);
|
||||
|
||||
@@ -367,9 +375,10 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, SubscriptionContextIsNullForHt
|
||||
return Response(http::status::ok, responseMessage, request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockHttpConnection, send).WillOnce([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockHttpConnection, send)
|
||||
.WillOnce([&responseMessage](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(
|
||||
@@ -413,9 +422,11 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_Send_Loop)
|
||||
return Response(http::status::ok, responseMessage, request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockHttpConnection, send).Times(3).WillRepeatedly([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockHttpConnection, send)
|
||||
.Times(3)
|
||||
.WillRepeatedly([&responseMessage](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(
|
||||
@@ -456,7 +467,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_SendError)
|
||||
|
||||
EXPECT_CALL(*mockHttpConnection, send).WillOnce([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return makeError(http::error::end_of_stream).error();
|
||||
return makeError(http::error::end_of_stream);
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockHttpConnection.get()](Connection const& c) {
|
||||
@@ -498,7 +509,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, OnIpChangeHookCalledWhenSentFr
|
||||
|
||||
EXPECT_CALL(*mockHttpConnectionFromProxy, send).WillOnce([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return makeError(http::error::end_of_stream).error();
|
||||
return makeError(http::error::end_of_stream);
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call)
|
||||
@@ -542,12 +553,12 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Stop)
|
||||
send(testing::ResultOf([](Response const& r) { return r.message(); }, responseMessage), testing::_)
|
||||
)
|
||||
.Times(3)
|
||||
.WillRepeatedly([&](auto&&, auto&&) {
|
||||
.WillRepeatedly([&](auto&&, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
++numCalls;
|
||||
if (numCalls == 3)
|
||||
util::spawn(ctx_, [this](auto yield) { connectionHandler.stop(yield); });
|
||||
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(
|
||||
@@ -659,9 +670,10 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send)
|
||||
return Response(http::status::ok, responseMessage, request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockWsConnection, send).WillOnce([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockWsConnection, send)
|
||||
.WillOnce([&responseMessage](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockWsConnection.get()](Connection const& c) {
|
||||
@@ -699,9 +711,10 @@ TEST_F(ConnectionHandlerParallelProcessingTest, OnIpChangeHookCalledWhenSentFrom
|
||||
return Response(http::status::ok, responseMessage, request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockWsConnectionFromProxy, send).WillOnce([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockWsConnectionFromProxy, send)
|
||||
.WillOnce([&responseMessage](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call)
|
||||
@@ -738,9 +751,11 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop)
|
||||
return Response(http::status::ok, responseMessage, request);
|
||||
});
|
||||
|
||||
EXPECT_CALL(*mockWsConnection, send).Times(2).WillRepeatedly([&responseMessage](Response response, auto&&) {
|
||||
EXPECT_CALL(*mockWsConnection, send)
|
||||
.Times(2)
|
||||
.WillRepeatedly([&responseMessage](Response response, auto&&) -> std::expected<void, web::ng::Error> {
|
||||
EXPECT_EQ(response.message(), responseMessage);
|
||||
return std::nullopt;
|
||||
return {};
|
||||
});
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockWsConnection.get()](Connection const& c) {
|
||||
@@ -787,7 +802,7 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop_TooMany
|
||||
send(testing::ResultOf([](Response response) { return response.message(); }, responseMessage), testing::_)
|
||||
)
|
||||
.Times(3)
|
||||
.WillRepeatedly(Return(std::nullopt));
|
||||
.WillRepeatedly(Return(std::expected<void, web::ng::Error>{}));
|
||||
|
||||
EXPECT_CALL(
|
||||
*mockWsConnection,
|
||||
@@ -799,7 +814,7 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop_TooMany
|
||||
)
|
||||
)
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(std::nullopt));
|
||||
.WillRepeatedly(Return(std::expected<void, web::ng::Error>{}));
|
||||
|
||||
EXPECT_CALL(onDisconnectMock, Call).WillOnce([connectionPtr = mockWsConnection.get()](Connection const& c) {
|
||||
EXPECT_EQ(&c, connectionPtr);
|
||||
|
||||
@@ -80,8 +80,9 @@ protected:
|
||||
TEST_F(HttpConnectionTests, wasUpgraded)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -95,11 +96,12 @@ TEST_F(HttpConnectionTests, Receive)
|
||||
request_.set(boost::beast::http::field::user_agent, "test_client");
|
||||
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
maybeError = httpClient_.send(request_, yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
expectedSuccess = httpClient_.send(request_, yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -123,8 +125,9 @@ TEST_F(HttpConnectionTests, Receive)
|
||||
TEST_F(HttpConnectionTests, ReceiveTimeout)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -138,8 +141,9 @@ TEST_F(HttpConnectionTests, ReceiveTimeout)
|
||||
TEST_F(HttpConnectionTests, ReceiveClientDisconnected)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
httpClient_.disconnect();
|
||||
});
|
||||
|
||||
@@ -157,11 +161,12 @@ TEST_F(HttpConnectionTests, Send)
|
||||
Response const response{http::status::ok, "some response data", request};
|
||||
|
||||
util::spawn(ctx_, [this, response = response](boost::asio::yield_context yield) mutable {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
auto const expectedResponse = httpClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedResponse.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedResponse.has_value()) << expectedResponse.error().message(); }();
|
||||
|
||||
auto const receivedResponse = expectedResponse.value();
|
||||
auto const sentResponse = std::move(response).intoHttpResponse();
|
||||
@@ -173,8 +178,8 @@ TEST_F(HttpConnectionTests, Send)
|
||||
|
||||
runSpawn([this, &response](boost::asio::yield_context yield) {
|
||||
auto connection = acceptConnection(yield);
|
||||
auto maybeError = connection->send(response, yield);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess = connection->send(response, yield);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -184,8 +189,9 @@ TEST_F(HttpConnectionTests, SendMultipleTimes)
|
||||
Response const response{http::status::ok, "some response data", request};
|
||||
|
||||
util::spawn(ctx_, [this, response = response](boost::asio::yield_context yield) mutable {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
auto const expectedResponse = httpClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
@@ -204,8 +210,8 @@ TEST_F(HttpConnectionTests, SendMultipleTimes)
|
||||
auto connection = acceptConnection(yield);
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
auto maybeError = connection->send(response, yield);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess = connection->send(response, yield);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -216,9 +222,9 @@ TEST_F(HttpConnectionTests, SendMultipleTimesFromMultipleCoroutines)
|
||||
Response const response{http::status::ok, "some response data", request};
|
||||
|
||||
util::spawn(ctx_, [this, response = response](boost::asio::yield_context yield) mutable {
|
||||
auto const maybeError =
|
||||
auto const expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
auto const expectedResponse = httpClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
@@ -239,8 +245,8 @@ TEST_F(HttpConnectionTests, SendMultipleTimesFromMultipleCoroutines)
|
||||
util::CoroutineGroup group{yield};
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
group.spawn(yield, [&response, &connection](boost::asio::yield_context innerYield) {
|
||||
auto const maybeError = connection->send(response, innerYield);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto const expectedSuccess = connection->send(response, innerYield);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
}
|
||||
group.asyncWait(yield);
|
||||
@@ -251,9 +257,9 @@ TEST_F(HttpConnectionTests, SendMultipleTimesClientDisconnected)
|
||||
{
|
||||
Response const response{http::status::ok, "some response data", Request{request_}};
|
||||
util::spawn(ctx_, [this, response = response](boost::asio::yield_context yield) mutable {
|
||||
auto const maybeError =
|
||||
auto const expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
auto const expectedResponse = httpClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedResponse.has_value()) << expectedResponse.error().message(); }();
|
||||
httpClient_.disconnect();
|
||||
@@ -262,15 +268,15 @@ TEST_F(HttpConnectionTests, SendMultipleTimesClientDisconnected)
|
||||
runSpawn([this, &response](boost::asio::yield_context yield) {
|
||||
auto connection = acceptConnection(yield);
|
||||
connection->setTimeout(std::chrono::milliseconds{1});
|
||||
auto maybeError = connection->send(response, yield);
|
||||
auto expectedSuccess = connection->send(response, yield);
|
||||
size_t counter{1};
|
||||
while (not maybeError.has_value() and counter < 100) {
|
||||
while (expectedSuccess.has_value() and counter < 100) {
|
||||
++counter;
|
||||
maybeError = connection->send(response, yield);
|
||||
expectedSuccess = connection->send(response, yield);
|
||||
}
|
||||
// Sending after getting an error should be safe
|
||||
maybeError = connection->send(response, yield);
|
||||
EXPECT_TRUE(maybeError.has_value());
|
||||
expectedSuccess = connection->send(response, yield);
|
||||
EXPECT_FALSE(expectedSuccess.has_value());
|
||||
EXPECT_LT(counter, 100);
|
||||
});
|
||||
}
|
||||
@@ -279,20 +285,21 @@ TEST_F(HttpConnectionTests, SendClientDisconnected)
|
||||
{
|
||||
Response const response{http::status::ok, "some response data", Request{request_}};
|
||||
util::spawn(ctx_, [this, response = response](boost::asio::yield_context yield) mutable {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
httpClient_.disconnect();
|
||||
});
|
||||
runSpawn([this, &response](boost::asio::yield_context yield) {
|
||||
auto connection = acceptConnection(yield);
|
||||
connection->setTimeout(std::chrono::milliseconds{1});
|
||||
auto maybeError = connection->send(response, yield);
|
||||
auto expectedSuccess = connection->send(response, yield);
|
||||
size_t counter{1};
|
||||
while (not maybeError.has_value() and counter < 100) {
|
||||
while (expectedSuccess.has_value() and counter < 100) {
|
||||
++counter;
|
||||
maybeError = connection->send(response, yield);
|
||||
expectedSuccess = connection->send(response, yield);
|
||||
}
|
||||
EXPECT_TRUE(maybeError.has_value());
|
||||
EXPECT_FALSE(expectedSuccess.has_value());
|
||||
EXPECT_LT(counter, 100);
|
||||
});
|
||||
}
|
||||
@@ -300,15 +307,16 @@ TEST_F(HttpConnectionTests, SendClientDisconnected)
|
||||
TEST_F(HttpConnectionTests, Close)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
size_t counter{0};
|
||||
while (not maybeError.has_value() and counter < 100) {
|
||||
while (expectedSuccess.has_value() and counter < 100) {
|
||||
++counter;
|
||||
maybeError = httpClient_.send(request_, yield, std::chrono::milliseconds{1});
|
||||
expectedSuccess = httpClient_.send(request_, yield, std::chrono::milliseconds{1});
|
||||
}
|
||||
EXPECT_TRUE(maybeError.has_value());
|
||||
EXPECT_FALSE(expectedSuccess.has_value());
|
||||
EXPECT_LT(counter, 100);
|
||||
});
|
||||
|
||||
@@ -322,11 +330,12 @@ TEST_F(HttpConnectionTests, Close)
|
||||
TEST_F(HttpConnectionTests, IsUpgradeRequested_GotHttpRequest)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
maybeError = httpClient_.send(request_, yield, std::chrono::milliseconds{1});
|
||||
EXPECT_FALSE(maybeError.has_value()) << maybeError->message();
|
||||
expectedSuccess = httpClient_.send(request_, yield, std::chrono::milliseconds{1});
|
||||
EXPECT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -340,8 +349,9 @@ TEST_F(HttpConnectionTests, IsUpgradeRequested_GotHttpRequest)
|
||||
TEST_F(HttpConnectionTests, IsUpgradeRequested_FailedToFetch)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -357,8 +367,8 @@ TEST_F(HttpConnectionTests, Upgrade)
|
||||
WebSocketAsyncClient wsClient{ctx_};
|
||||
|
||||
util::spawn(ctx_, [this, &wsClient](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess = wsClient.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -375,8 +385,9 @@ TEST_F(HttpConnectionTests, Upgrade)
|
||||
TEST_F(HttpConnectionTests, Ip)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) mutable {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -391,8 +402,9 @@ TEST_F(HttpConnectionTests, isAdminSetAdmin)
|
||||
EXPECT_CALL(adminSetter, Call).WillOnce(testing::Return(true));
|
||||
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) mutable {
|
||||
auto maybeError = httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
|
||||
auto expectedSuccess =
|
||||
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
|
||||
@@ -99,8 +99,9 @@ protected:
|
||||
TEST_F(WebWsConnectionTests, WasUpgraded)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
auto wsConnection = acceptConnection(yield);
|
||||
@@ -115,8 +116,9 @@ TEST_F(WebWsConnectionTests, DisconnectClientOnInactivity)
|
||||
std::thread clientThread{[&clientCtx]() { clientCtx.run(); }};
|
||||
|
||||
util::spawn(clientCtx, [&work, this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
boost::asio::steady_timer timer{yield.get_executor(), std::chrono::milliseconds{5}};
|
||||
timer.async_wait(yield);
|
||||
work.reset();
|
||||
@@ -143,8 +145,9 @@ TEST_F(WebWsConnectionTests, Send)
|
||||
Response const response{boost::beast::http::status::ok, "some response", request_};
|
||||
|
||||
util::spawn(ctx_, [this, &response](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
auto const expectedMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedMessage.has_value()) << expectedMessage.error().message(); }();
|
||||
EXPECT_EQ(expectedMessage.value(), response.message());
|
||||
@@ -152,8 +155,8 @@ TEST_F(WebWsConnectionTests, Send)
|
||||
|
||||
runSpawn([this, &response](boost::asio::yield_context yield) {
|
||||
auto wsConnection = acceptConnection(yield);
|
||||
auto maybeError = wsConnection->send(response, yield);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess = wsConnection->send(response, yield);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -162,8 +165,9 @@ TEST_F(WebWsConnectionTests, SendShared)
|
||||
auto const response = std::make_shared<std::string>("some response");
|
||||
|
||||
util::spawn(ctx_, [this, &response](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
auto const expectedMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedMessage.has_value()) << expectedMessage.error().message(); }();
|
||||
EXPECT_EQ(expectedMessage.value(), *response);
|
||||
@@ -171,8 +175,8 @@ TEST_F(WebWsConnectionTests, SendShared)
|
||||
|
||||
runSpawn([this, &response](boost::asio::yield_context yield) {
|
||||
auto wsConnection = acceptConnection(yield);
|
||||
auto maybeError = wsConnection->sendShared(response, yield);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess = wsConnection->sendShared(response, yield);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -181,8 +185,9 @@ TEST_F(WebWsConnectionTests, MultipleSend)
|
||||
Response const response{boost::beast::http::status::ok, "some response", request_};
|
||||
|
||||
util::spawn(ctx_, [this, &response](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
auto const expectedMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
@@ -195,8 +200,8 @@ TEST_F(WebWsConnectionTests, MultipleSend)
|
||||
auto wsConnection = acceptConnection(yield);
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
auto maybeError = wsConnection->send(response, yield);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess = wsConnection->send(response, yield);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -206,8 +211,9 @@ TEST_F(WebWsConnectionTests, MultipleSendFromMultipleCoroutines)
|
||||
Response const response{boost::beast::http::status::ok, "some response", request_};
|
||||
|
||||
util::spawn(ctx_, [this, &response](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
auto const expectedMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
@@ -222,8 +228,8 @@ TEST_F(WebWsConnectionTests, MultipleSendFromMultipleCoroutines)
|
||||
util::CoroutineGroup group{yield};
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
group.spawn(yield, [&wsConnection, &response](boost::asio::yield_context innerYield) {
|
||||
auto maybeError = wsConnection->send(response, innerYield);
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess = wsConnection->send(response, innerYield);
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
}
|
||||
group.asyncWait(yield);
|
||||
@@ -235,21 +241,22 @@ TEST_F(WebWsConnectionTests, SendFailed)
|
||||
Response const response{boost::beast::http::status::ok, "some response", request_};
|
||||
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
wsClient_.close();
|
||||
});
|
||||
|
||||
runSpawn([this, &response](boost::asio::yield_context yield) {
|
||||
auto wsConnection = acceptConnection(yield);
|
||||
wsConnection->setTimeout(std::chrono::milliseconds{1});
|
||||
std::optional<Error> maybeError;
|
||||
std::expected<void, Error> expectedSuccess;
|
||||
size_t counter = 0;
|
||||
while (not maybeError.has_value() and counter < 100) {
|
||||
maybeError = wsConnection->send(response, yield);
|
||||
while (expectedSuccess.has_value() and counter < 100) {
|
||||
expectedSuccess = wsConnection->send(response, yield);
|
||||
++counter;
|
||||
}
|
||||
EXPECT_TRUE(maybeError.has_value());
|
||||
EXPECT_FALSE(expectedSuccess.has_value());
|
||||
EXPECT_LT(counter, 100);
|
||||
});
|
||||
}
|
||||
@@ -259,8 +266,9 @@ TEST_F(WebWsConnectionTests, SendFailedSendingFromMultipleCoroutines)
|
||||
Response const response{boost::beast::http::status::ok, "some response", request_};
|
||||
|
||||
util::spawn(ctx_, [this, &response](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
auto const expectedMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedMessage.has_value()) << expectedMessage.error().message(); }();
|
||||
@@ -271,15 +279,15 @@ TEST_F(WebWsConnectionTests, SendFailedSendingFromMultipleCoroutines)
|
||||
runSpawn([this, &response](boost::asio::yield_context yield) {
|
||||
auto wsConnection = acceptConnection(yield);
|
||||
wsConnection->setTimeout(std::chrono::milliseconds{1});
|
||||
std::optional<Error> maybeError;
|
||||
std::expected<void, Error> expectedSuccess;
|
||||
size_t counter = 0;
|
||||
while (not maybeError.has_value() and counter < 100) {
|
||||
maybeError = wsConnection->send(response, yield);
|
||||
while (expectedSuccess.has_value() and counter < 100) {
|
||||
expectedSuccess = wsConnection->send(response, yield);
|
||||
++counter;
|
||||
}
|
||||
// Sending after getting an error should be safe
|
||||
maybeError = wsConnection->send(response, yield);
|
||||
EXPECT_TRUE(maybeError.has_value());
|
||||
expectedSuccess = wsConnection->send(response, yield);
|
||||
EXPECT_FALSE(expectedSuccess.has_value());
|
||||
EXPECT_LT(counter, 100);
|
||||
});
|
||||
}
|
||||
@@ -287,11 +295,12 @@ TEST_F(WebWsConnectionTests, SendFailedSendingFromMultipleCoroutines)
|
||||
TEST_F(WebWsConnectionTests, Receive)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
maybeError = wsClient_.send(yield, request_.message(), std::chrono::milliseconds{100});
|
||||
EXPECT_FALSE(maybeError.has_value()) << maybeError->message();
|
||||
expectedSuccess = wsClient_.send(yield, request_.message(), std::chrono::milliseconds{100});
|
||||
EXPECT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -306,12 +315,13 @@ TEST_F(WebWsConnectionTests, Receive)
|
||||
TEST_F(WebWsConnectionTests, MultipleReceive)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
|
||||
for ([[maybe_unused]] auto i : std::ranges::iota_view{0, 3}) {
|
||||
maybeError = wsClient_.send(yield, request_.message(), std::chrono::milliseconds{100});
|
||||
EXPECT_FALSE(maybeError.has_value()) << maybeError->message();
|
||||
expectedSuccess = wsClient_.send(yield, request_.message(), std::chrono::milliseconds{100});
|
||||
EXPECT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -329,8 +339,9 @@ TEST_F(WebWsConnectionTests, MultipleReceive)
|
||||
TEST_F(WebWsConnectionTests, ReceiveTimeout)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
runSpawn([this](boost::asio::yield_context yield) {
|
||||
@@ -345,8 +356,9 @@ TEST_F(WebWsConnectionTests, ReceiveTimeout)
|
||||
TEST_F(WebWsConnectionTests, ReceiveFailed)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
wsClient_.close();
|
||||
});
|
||||
|
||||
@@ -361,8 +373,9 @@ TEST_F(WebWsConnectionTests, ReceiveFailed)
|
||||
TEST_F(WebWsConnectionTests, Close)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
auto const maybeMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
|
||||
EXPECT_FALSE(maybeMessage.has_value());
|
||||
EXPECT_THAT(maybeMessage.error().message(), testing::HasSubstr("was gracefully closed"));
|
||||
@@ -377,8 +390,9 @@ TEST_F(WebWsConnectionTests, Close)
|
||||
TEST_F(WebWsConnectionTests, CloseWhenConnectionIsAlreadyClosed)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
wsClient_.close();
|
||||
});
|
||||
|
||||
@@ -393,8 +407,9 @@ TEST_F(WebWsConnectionTests, CloseWhenConnectionIsAlreadyClosed)
|
||||
TEST_F(WebWsConnectionTests, CloseCalledFromMultipleSubCoroutines)
|
||||
{
|
||||
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
|
||||
auto maybeError = wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
|
||||
auto expectedSuccess =
|
||||
wsClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
|
||||
[&]() { ASSERT_TRUE(expectedSuccess.has_value()) << expectedSuccess.error().message(); }();
|
||||
});
|
||||
|
||||
testing::StrictMock<testing::MockFunction<void()>> closeCalled;
|
||||
|
||||
Reference in New Issue
Block a user