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