chore: Update boost usages to match 1.88 (#2355)

This commit is contained in:
Alex Kremer
2025-07-23 15:49:19 +01:00
committed by GitHub
parent bcaa5f3392
commit b29e2e4c88
40 changed files with 598 additions and 362 deletions

View File

@@ -19,6 +19,8 @@
#include "app/Stopper.hpp"
#include "util/Spawn.hpp"
#include <boost/asio/spawn.hpp>
#include <functional>
@@ -36,7 +38,7 @@ Stopper::~Stopper()
void
Stopper::setOnStop(std::function<void(boost::asio::yield_context)> cb)
{
boost::asio::spawn(ctx_, std::move(cb));
util::spawn(ctx_, std::move(cb));
}
void

View File

@@ -21,6 +21,7 @@
#include "cluster/ClioNode.hpp"
#include "data/BackendInterface.hpp"
#include "util/Spawn.hpp"
#include "util/log/Logger.hpp"
#include <boost/asio/spawn.hpp>
@@ -62,7 +63,7 @@ ClusterCommunicationService::ClusterCommunicationService(
void
ClusterCommunicationService::run()
{
boost::asio::spawn(strand_, [this](boost::asio::yield_context yield) {
util::spawn(strand_, [this](boost::asio::yield_context yield) {
boost::asio::steady_timer timer(yield.get_executor());
while (true) {
timer.expires_after(readInterval_);
@@ -71,7 +72,7 @@ ClusterCommunicationService::run()
}
});
boost::asio::spawn(strand_, [this](boost::asio::yield_context yield) {
util::spawn(strand_, [this](boost::asio::yield_context yield) {
boost::asio::steady_timer timer(yield.get_executor());
while (true) {
doWrite();
@@ -108,7 +109,7 @@ ClioNode
ClusterCommunicationService::selfData() const
{
ClioNode result{};
boost::asio::spawn(strand_, [this, &result](boost::asio::yield_context) { result = selfData_; });
util::spawn(strand_, [this, &result](boost::asio::yield_context) { result = selfData_; });
return result;
}
@@ -119,7 +120,7 @@ ClusterCommunicationService::clusterData() const
return std::unexpected{"Service is not healthy"};
}
std::vector<ClioNode> result;
boost::asio::spawn(strand_, [this, &result](boost::asio::yield_context) {
util::spawn(strand_, [this, &result](boost::asio::yield_context) {
result = otherNodesData_;
result.push_back(selfData_);
});

View File

@@ -23,6 +23,7 @@
#include "data/LedgerCacheInterface.hpp"
#include "data/Types.hpp"
#include "etl/CorruptionDetector.hpp"
#include "util/Spawn.hpp"
#include "util/log/Logger.hpp"
#include <boost/asio/executor_work_guard.hpp>
@@ -108,14 +109,12 @@ synchronous(FnType&& func)
using R = typename boost::result_of<FnType(boost::asio::yield_context)>::type;
if constexpr (!std::is_same_v<R, void>) {
R res;
boost::asio::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func, &res](auto yield) {
res = func(yield);
});
util::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func, &res](auto yield) { res = func(yield); });
ctx.run();
return res;
} else {
boost::asio::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func](auto yield) { func(yield); });
util::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func](auto yield) { func(yield); });
ctx.run();
}
}

View File

@@ -30,8 +30,8 @@
#include <boost/asio.hpp>
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/json/object.hpp>
@@ -79,7 +79,7 @@ class DefaultExecutionStrategy {
std::condition_variable syncCv_;
boost::asio::io_context ioc_;
std::optional<boost::asio::io_service::work> work_;
std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work_;
std::reference_wrapper<HandleType const> handle_;
std::thread thread_;
@@ -107,7 +107,7 @@ public:
: maxWriteRequestsOutstanding_{settings.maxWriteRequestsOutstanding}
, maxReadRequestsOutstanding_{settings.maxReadRequestsOutstanding}
, writeBatchSize_{settings.writeBatchSize}
, work_{ioc_}
, work_{boost::asio::make_work_guard(ioc_)}
, handle_{std::cref(handle)}
, thread_{[this]() { ioc_.run(); }}
, counters_{std::move(counters)}
@@ -334,7 +334,7 @@ public:
};
auto res = boost::asio::async_compose<CompletionTokenType, void(ResultOrErrorType)>(
init, token, boost::asio::get_associated_executor(token)
std::move(init), token, boost::asio::get_associated_executor(token)
);
numReadRequestsOutstanding_ -= numStatements;
@@ -387,7 +387,7 @@ public:
};
auto res = boost::asio::async_compose<CompletionTokenType, void(ResultOrErrorType)>(
init, token, boost::asio::get_associated_executor(token)
std::move(init), token, boost::asio::get_associated_executor(token)
);
--numReadRequestsOutstanding_;
@@ -456,7 +456,7 @@ public:
};
boost::asio::async_compose<CompletionTokenType, void()>(
init, token, boost::asio::get_associated_executor(token)
std::move(init), token, boost::asio::get_associated_executor(token)
);
numReadRequestsOutstanding_ -= statements.size();

View File

@@ -23,6 +23,7 @@
#include "feed/SubscriptionManagerInterface.hpp"
#include "rpc/JS.hpp"
#include "util/Retry.hpp"
#include "util/Spawn.hpp"
#include "util/log/Logger.hpp"
#include "util/prometheus/Label.hpp"
#include "util/prometheus/Prometheus.hpp"
@@ -157,7 +158,7 @@ SubscriptionSource::stop(boost::asio::yield_context yield)
void
SubscriptionSource::subscribe()
{
boost::asio::spawn(strand_, [this, _ = boost::asio::make_work_guard(strand_)](boost::asio::yield_context yield) {
util::spawn(strand_, [this, _ = boost::asio::make_work_guard(strand_)](boost::asio::yield_context yield) {
if (auto connection = wsConnectionBuilder_.connect(yield); connection) {
wsConnection_ = std::move(connection).value();
} else {

View File

@@ -19,7 +19,9 @@
#pragma once
#include "util/Assert.hpp"
#include "util/Mutex.hpp"
#include "util/Spawn.hpp"
#include "util/config/ConfigDefinition.hpp"
#include "util/log/Logger.hpp"
#include "util/prometheus/Counter.hpp"
@@ -127,7 +129,7 @@ public:
// Each time we enqueue a job, we want to post a symmetrical job that will dequeue and run the job at the front
// of the job queue.
boost::asio::spawn(
util::spawn(
ioc_,
[this, func = std::forward<FnType>(func), start = std::chrono::system_clock::now()](auto yield) mutable {
auto const run = std::chrono::system_clock::now();

View File

@@ -21,6 +21,7 @@
#include "util/Assert.hpp"
#include "util/Mutex.hpp"
#include "util/Spawn.hpp"
#include <boost/asio/error.hpp>
#include <boost/asio/spawn.hpp>
@@ -212,7 +213,7 @@ private:
boost::signals2::scoped_connection const slot =
updateFinished_.connect([yield, sharedContext](std::expected<ValueType, ErrorType> value) {
boost::asio::spawn(yield, [sharedContext = std::move(sharedContext), value = std::move(value)](auto&&) {
util::spawn(yield, [sharedContext = std::move(sharedContext), value = std::move(value)](auto&&) {
sharedContext->result = std::move(value);
sharedContext->timer.cancel();
});

View File

@@ -19,6 +19,8 @@
#pragma once
#include "util/Spawn.hpp"
#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/bind_cancellation_slot.hpp>
#include <boost/asio/cancellation_signal.hpp>
@@ -114,7 +116,7 @@ public:
static void
spawnNew(ExecutionContext& ioContext, Fn fn)
{
boost::asio::spawn(ioContext, [fn = std::move(fn)](boost::asio::yield_context yield) {
util::spawn(ioContext, [fn = std::move(fn)](boost::asio::yield_context yield) {
Coroutine thisCoroutine{std::move(yield)};
fn(thisCoroutine);
});
@@ -133,12 +135,10 @@ public:
if (isCancelled_)
return;
boost::asio::spawn(
yield_, [signal = familySignal_, fn = std::move(fn)](boost::asio::yield_context yield) mutable {
Coroutine coroutine(std::move(yield), std::move(signal));
fn(coroutine);
}
);
util::spawn(yield_, [signal = familySignal_, fn = std::move(fn)](boost::asio::yield_context yield) mutable {
Coroutine coroutine(std::move(yield), std::move(signal));
fn(coroutine);
});
}
/**

View File

@@ -20,6 +20,7 @@
#include "util/CoroutineGroup.hpp"
#include "util/Assert.hpp"
#include "util/Spawn.hpp"
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>
@@ -48,7 +49,7 @@ CoroutineGroup::spawn(boost::asio::yield_context yield, std::function<void(boost
return false;
++childrenCounter_;
boost::asio::spawn(yield, [this, fn = std::move(fn)](boost::asio::yield_context yield) {
util::spawn(yield, [this, fn = std::move(fn)](boost::asio::yield_context yield) {
fn(yield);
onCoroutineCompleted();
});
@@ -64,7 +65,7 @@ CoroutineGroup::registerForeign(boost::asio::yield_context yield)
++childrenCounter_;
// It is important to spawn onCoroutineCompleted() to the same coroutine as will be calling asyncWait().
// timer_ here is not thread safe, so without spawn there could be a data race.
return [this, yield]() { boost::asio::spawn(yield, [this](auto&&) { onCoroutineCompleted(); }); };
return [this, yield]() { util::spawn(yield, [this](auto&&) { onCoroutineCompleted(); }); };
}
void

82
src/util/Spawn.hpp Normal file
View File

@@ -0,0 +1,82 @@
//------------------------------------------------------------------------------
/*
This file is part of clio: https://github.com/XRPLF/clio
Copyright (c) 2025, the clio developers.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#pragma once
#include <boost/asio/spawn.hpp>
#include <boost/asio/strand.hpp>
#include <exception>
#include <type_traits>
namespace util {
namespace impl {
template <typename T>
concept IsStrand = std::same_as<std::decay_t<T>, boost::asio::strand<typename std::decay_t<T>::inner_executor_type>>;
/**
* @brief A completion handler that restores `boost::asio::spawn`'s behaviour from Boost 1.83
*
* This is intended to be passed as the third argument to `boost::asio::spawn` so that exceptions are not ignored but
* propagated to `io_context.run()` call site.
*/
inline constexpr struct PropagatingCompletionHandler {
/**
* @brief The completion handler
* @param ePtr The exception that was caught on the coroutine
*/
void
operator()(std::exception_ptr ePtr)
{
if (ePtr)
std::rethrow_exception(ePtr);
}
} kPROPAGATE_EXCEPTIONS;
} // namespace impl
/**
* @brief Spawns a coroutine using `boost::asio::spawn`
*
* @note This uses kPROPAGATE_EXCEPTIONS to force asio to propagate exceptions through `io_context`
* @note Since implicit strand was removed from boost::asio::spawn this helper function adds the strand back
*
* @tparam Ctx The type of the context/strand
* @tparam F The type of the function to execute
* @param ctx The execution context
* @param func The function to execute. Must return `void`
*/
template <typename Ctx, typename F>
requires std::is_invocable_r_v<void, F, boost::asio::yield_context>
void
spawn(Ctx&& ctx, F&& func)
{
if constexpr (impl::IsStrand<Ctx>) {
boost::asio::spawn(std::forward<Ctx>(ctx), std::forward<F>(func), impl::kPROPAGATE_EXCEPTIONS);
} else {
boost::asio::spawn(
boost::asio::make_strand(std::forward<Ctx>(ctx).get_executor()),
std::forward<F>(func),
impl::kPROPAGATE_EXCEPTIONS
);
}
}
} // namespace util

View File

@@ -19,6 +19,7 @@
#pragma once
#include "util/Spawn.hpp"
#include "util/async/Concepts.hpp"
#include "util/async/context/impl/Timer.hpp"
@@ -35,7 +36,7 @@ struct SpawnDispatchStrategy {
{
auto op = outcome.getOperation();
boost::asio::spawn(
util::spawn(
ctx.getExecutor(),
[outcome = std::forward<decltype(outcome)>(outcome),
fn = std::forward<decltype(fn)>(fn)](auto yield) mutable {

View File

@@ -20,6 +20,7 @@
#include "web/ng/Server.hpp"
#include "util/Assert.hpp"
#include "util/Spawn.hpp"
#include "util/Taggable.hpp"
#include "util/config/ConfigDefinition.hpp"
#include "util/config/ObjectView.hpp"
@@ -247,28 +248,28 @@ Server::run()
return std::move(acceptor).error();
running_ = true;
boost::asio::spawn(
ctx_.get(), [this, acceptor = std::move(acceptor).value()](boost::asio::yield_context yield) mutable {
while (true) {
boost::beast::error_code errorCode;
boost::asio::ip::tcp::socket socket{ctx_.get().get_executor()};
util::spawn(ctx_.get(), [this, acceptor = std::move(acceptor).value()](boost::asio::yield_context yield) mutable {
while (true) {
boost::beast::error_code errorCode;
boost::asio::ip::tcp::socket socket{ctx_.get().get_executor()};
acceptor.async_accept(socket, yield[errorCode]);
LOG(log_.trace()) << "Accepted a new connection";
if (errorCode) {
LOG(log_.debug()) << "Error accepting a connection: " << errorCode.what();
continue;
}
boost::asio::spawn(
ctx_.get(),
[this, socket = std::move(socket)](boost::asio::yield_context yield) mutable {
handleConnection(std::move(socket), yield);
},
boost::asio::detached
);
acceptor.async_accept(socket, yield[errorCode]);
LOG(log_.trace()) << "Accepted a new connection";
if (errorCode) {
LOG(log_.debug()) << "Error accepting a connection: " << errorCode.what();
continue;
}
// Note: This was desigen to use `boost::asio::detached`
boost::asio::spawn(
ctx_.get(),
[this, socket = std::move(socket)](boost::asio::yield_context yield) mutable {
handleConnection(std::move(socket), yield);
},
boost::asio::detached
);
}
);
});
return std::nullopt;
}
@@ -313,11 +314,9 @@ Server::handleConnection(boost::asio::ip::tcp::socket socket, boost::asio::yield
LOG(log_.trace()) << connectionExpected.value()->tag() << "Connection created";
if (connectionHandler_.isStopping()) {
boost::asio::spawn(
ctx_.get(), [connection = std::move(connectionExpected).value()](boost::asio::yield_context yield) {
web::ng::impl::ConnectionHandler::stopConnection(*connection, yield);
}
);
util::spawn(ctx_.get(), [connection = std::move(connectionExpected).value()](boost::asio::yield_context yield) {
web::ng::impl::ConnectionHandler::stopConnection(*connection, yield);
});
return;
}
@@ -327,7 +326,7 @@ Server::handleConnection(boost::asio::ip::tcp::socket socket, boost::asio::yield
return;
}
boost::asio::spawn(
util::spawn(
ctx_.get(), [this, connection = std::move(connection).value()](boost::asio::yield_context yield) mutable {
connectionHandler_.processConnection(std::move(connection), yield);
}

View File

@@ -19,6 +19,7 @@
#pragma once
#include "util/AsioContextTestFixture.hpp"
#include "util/MockAmendmentCenter.hpp"
#include "util/MockBackendTestFixture.hpp"
#include "util/MockPrometheus.hpp"

View File

@@ -21,10 +21,10 @@
#include "util/Coroutine.hpp"
#include "util/LoggerFixtures.hpp"
#include "util/Spawn.hpp"
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>
@@ -43,7 +43,7 @@
struct AsyncAsioContextTest : virtual public NoLoggerFixture {
AsyncAsioContextTest()
{
work_.emplace(ctx_); // make sure ctx does not stop on its own
work_.emplace(boost::asio::make_work_guard(ctx_)); // make sure ctx does not stop on its own
runner_.emplace([&] { ctx_.run(); });
}
@@ -68,7 +68,7 @@ protected:
boost::asio::io_context ctx_;
private:
std::optional<boost::asio::io_service::work> work_;
std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work_;
std::optional<std::thread> runner_;
};
@@ -100,13 +100,11 @@ struct SyncAsioContextTest : virtual public NoLoggerFixture {
void
runSpawn(F&& f, bool allowMockLeak = false)
{
using namespace boost::asio;
testing::MockFunction<void()> call;
if (allowMockLeak)
testing::Mock::AllowLeak(&call);
spawn(ctx_, [&, _ = make_work_guard(ctx_)](yield_context yield) {
util::spawn(ctx_, [&, _ = make_work_guard(ctx_)](boost::asio::yield_context yield) {
f(yield);
call.Call();
});
@@ -119,11 +117,9 @@ struct SyncAsioContextTest : virtual public NoLoggerFixture {
void
runSpawnWithTimeout(std::chrono::steady_clock::duration timeout, F&& f, bool allowMockLeak = false)
{
using namespace boost::asio;
boost::asio::io_context timerCtx;
steady_timer timer{timerCtx, timeout};
spawn(timerCtx, [this, &timer](yield_context yield) {
boost::asio::steady_timer timer{timerCtx, timeout};
util::spawn(timerCtx, [this, &timer](boost::asio::yield_context yield) {
boost::system::error_code errorCode;
timer.async_wait(yield[errorCode]);
ctx_.stop();
@@ -135,7 +131,7 @@ struct SyncAsioContextTest : virtual public NoLoggerFixture {
if (allowMockLeak)
testing::Mock::AllowLeak(&call);
spawn(ctx_, [&](yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
f(yield);
call.Call();
});
@@ -151,22 +147,22 @@ struct SyncAsioContextTest : virtual public NoLoggerFixture {
runContext()
{
ctx_.run();
ctx_.reset();
ctx_.restart();
}
void
runContextFor(std::chrono::milliseconds duration)
{
ctx_.run_for(duration);
ctx_.reset();
ctx_.restart();
}
template <typename F>
static void
runSyncOperation(F&& f)
{
boost::asio::io_service ioc;
boost::asio::spawn(ioc, f);
boost::asio::io_context ioc;
util::spawn(ioc, f);
ioc.run();
}

View File

@@ -19,6 +19,7 @@
#pragma once
#include "rpc/common/Types.hpp"
#include "util/Spawn.hpp"
#include "web/Context.hpp"
#include <boost/asio.hpp>
@@ -35,12 +36,10 @@ struct MockAsyncRPCEngine {
bool
post(Fn&& func, [[maybe_unused]] std::string const& ip = "")
{
using namespace boost::asio;
io_context ioc;
boost::asio::io_context ioc;
spawn(ioc, [handler = std::forward<Fn>(func), _ = make_work_guard(ioc)](auto yield) mutable {
util::spawn(ioc, [handler = std::forward<Fn>(func), _ = make_work_guard(ioc)](auto yield) mutable {
handler(yield);
;
});
ioc.run();

View File

@@ -133,6 +133,7 @@ TestHttpServer::accept(boost::asio::yield_context yield)
void
TestHttpServer::handleRequest(TestHttpServer::RequestHandler handler, bool const allowToFail)
{
// Note: This was designed to use `boost::asio::detached`
boost::asio::spawn(
acceptor_.get_executor(),
[this, allowToFail, handler = std::move(handler)](asio::yield_context yield) mutable {

View File

@@ -33,13 +33,14 @@
#include "util/MockLedgerHeaderCache.hpp"
#include "util/MockPrometheus.hpp"
#include "util/Random.hpp"
#include "util/Spawn.hpp"
#include "util/StringUtils.hpp"
#include "util/config/ConfigValue.hpp"
#include "util/config/ObjectView.hpp"
#include "util/config/Types.hpp"
#include <TestGlobals.hpp>
#include <boost/asio/impl/spawn.hpp>
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/uuid/random_generator.hpp>
@@ -143,10 +144,9 @@ protected:
TEST_F(BackendCassandraTest, Basic)
{
std::atomic_bool done = false;
std::optional<boost::asio::io_context::work> work;
work.emplace(ctx_);
auto work = std::make_optional(boost::asio::make_work_guard(ctx_));
boost::asio::spawn(ctx_, [this, &done, &work](boost::asio::yield_context yield) {
util::spawn(ctx_, [this, &done, &work](boost::asio::yield_context yield) {
std::string const rawHeader =
"03C3141A01633CD656F91B4EBB5EB89B791BD34DBC8A04BB6F407C5335BC54351E"
"DD733898497E809E04074D14D271E4832D7888754F9230800761563A292FA2315A"
@@ -908,10 +908,9 @@ TEST_F(BackendCassandraTest, Basic)
TEST_F(BackendCassandraTest, CacheIntegration)
{
std::atomic_bool done = false;
std::optional<boost::asio::io_context::work> work;
work.emplace(ctx_);
auto work = std::make_optional(boost::asio::make_work_guard(ctx_));
boost::asio::spawn(ctx_, [this, &done, &work](boost::asio::yield_context yield) {
util::spawn(ctx_, [this, &done, &work](boost::asio::yield_context yield) {
backend_->cache().setFull();
// this account is not related to the above transaction and

View File

@@ -170,10 +170,11 @@ target_sources(
util/CoroutineTest.cpp
util/MoveTrackerTests.cpp
util/RandomTests.cpp
util/RetryTests.cpp
util/RepeatTests.cpp
util/ResponseExpirationCacheTests.cpp
util/RetryTests.cpp
util/SignalsHandlerTests.cpp
util/SpawnTests.cpp
util/StopHelperTests.cpp
util/TimeUtilsTests.cpp
util/TxUtilTests.cpp

View File

@@ -22,6 +22,7 @@
#include "data/cassandra/impl/AsyncExecutor.hpp"
#include "util/AsioContextTestFixture.hpp"
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <cassandra.h>
#include <gmock/gmock.h>
@@ -53,13 +54,13 @@ TEST_F(BackendCassandraAsyncExecutorTest, CompletionCalledOnSuccess)
ON_CALL(handle, asyncExecute(An<FakeStatement const&>(), An<std::function<void(FakeResultOrError)>&&>()))
.WillByDefault([this](auto const&, auto&& cb) {
ctx_.post([cb = std::forward<decltype(cb)>(cb)]() { cb({}); });
boost::asio::post(ctx_, [cb = std::forward<decltype(cb)>(cb)]() { cb({}); });
return FakeFutureWithCallback{};
});
EXPECT_CALL(handle, asyncExecute(An<FakeStatement const&>(), An<std::function<void(FakeResultOrError)>&&>()))
.Times(AtLeast(1));
auto work = std::optional<boost::asio::io_context::work>{ctx_};
auto work = std::make_optional(boost::asio::make_work_guard(ctx_));
EXPECT_CALL(callbackMock_, onComplete);
AsyncExecutor<FakeStatement, MockHandle>::run(
@@ -96,7 +97,7 @@ TEST_F(BackendCassandraAsyncExecutorTest, ExecutedMultipleTimesByRetryPolicyOnMa
EXPECT_CALL(handle, asyncExecute(An<FakeStatement const&>(), An<std::function<void(FakeResultOrError)>&&>()))
.Times(3);
auto work = std::optional<boost::asio::io_context::work>{ctx_};
auto work = std::make_optional(boost::asio::make_work_guard(ctx_));
EXPECT_CALL(callbackMock_, onComplete);
EXPECT_CALL(callbackMock_, onRetry).Times(2);
@@ -121,7 +122,7 @@ TEST_F(BackendCassandraAsyncExecutorTest, ExecutedMultipleTimesByRetryPolicyOnOt
auto handle = MockHandle{};
auto threadedCtx = boost::asio::io_context{};
auto work = std::optional<boost::asio::io_context::work>{threadedCtx};
auto work = std::make_optional(boost::asio::make_work_guard(threadedCtx));
auto thread = std::thread{[&threadedCtx] { threadedCtx.run(); }};
// emulate successful execution after some attempts
@@ -139,7 +140,7 @@ TEST_F(BackendCassandraAsyncExecutorTest, ExecutedMultipleTimesByRetryPolicyOnOt
EXPECT_CALL(handle, asyncExecute(An<FakeStatement const&>(), An<std::function<void(FakeResultOrError)>&&>()))
.Times(3);
auto work2 = std::optional<boost::asio::io_context::work>{ctx_};
auto work2 = std::make_optional(boost::asio::make_work_guard(ctx_));
EXPECT_CALL(callbackMock_, onComplete);
EXPECT_CALL(callbackMock_, onRetry).Times(2);
@@ -175,7 +176,7 @@ TEST_F(BackendCassandraAsyncExecutorTest, CompletionCalledOnFailureAfterRetryCou
EXPECT_CALL(handle, asyncExecute(An<FakeStatement const&>(), An<std::function<void(FakeResultOrError)>&&>()))
.Times(1);
auto work = std::optional<boost::asio::io_context::work>{ctx_};
auto work = std::make_optional(boost::asio::make_work_guard(ctx_));
EXPECT_CALL(callbackMock_, onComplete);
AsyncExecutor<FakeStatement, MockHandle, FakeRetryPolicy>::run(

View File

@@ -23,6 +23,7 @@
#include "data/cassandra/impl/ExecutionStrategy.hpp"
#include "util/AsioContextTestFixture.hpp"
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/json/object.hpp>
@@ -379,7 +380,7 @@ TEST_F(BackendCassandraExecutionStrategyTest, WriteMultipleAndCallSyncSucceeds)
auto const totalRequests = 1024u;
auto callCount = std::atomic_uint{0u};
auto work = std::optional<boost::asio::io_context::work>{ctx_};
auto work = std::make_optional(boost::asio::make_work_guard(ctx_));
auto thread = std::thread{[this]() { ctx_.run(); }};
ON_CALL(
@@ -429,7 +430,7 @@ TEST_F(BackendCassandraExecutionStrategyTest, WriteEachAndCallSyncSucceeds)
auto const numStatements = 16u;
auto callCount = std::atomic_uint{0u};
auto work = std::optional<boost::asio::io_context::work>{ctx_};
auto work = std::make_optional(boost::asio::make_work_guard(ctx_));
auto thread = std::thread{[this]() { ctx_.run(); }};
EXPECT_CALL(handle_, asyncExecute(A<FakeStatement const&>(), A<std::function<void(FakeResultOrError)>&&>()))

View File

@@ -20,6 +20,7 @@
#include "etl/impl/ForwardingSource.hpp"
#include "rpc/Errors.hpp"
#include "util/AsioContextTestFixture.hpp"
#include "util/Spawn.hpp"
#include "util/TestWsServer.hpp"
#include <boost/asio/spawn.hpp>
@@ -78,7 +79,7 @@ protected:
TEST_F(ForwardingSourceOperationsTests, XUserHeader)
{
std::string const xUserValue = "some_user";
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto headers = connection.headers();
ASSERT_FALSE(headers.empty());
@@ -101,7 +102,7 @@ TEST_F(ForwardingSourceOperationsTests, XUserHeader)
TEST_F(ForwardingSourceOperationsTests, ReadFailed)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
connection.close(yield);
});
@@ -116,7 +117,7 @@ TEST_F(ForwardingSourceOperationsTests, ReadFailed)
TEST_F(ForwardingSourceOperationsTests, ReadTimeout)
{
TestWsConnectionPtr connection;
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
connection = std::make_unique<TestWsConnection>(serverConnection(yield));
});
@@ -129,7 +130,7 @@ TEST_F(ForwardingSourceOperationsTests, ReadTimeout)
TEST_F(ForwardingSourceOperationsTests, ParseFailed)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto receivedMessage = connection.receive(yield);
@@ -151,7 +152,7 @@ TEST_F(ForwardingSourceOperationsTests, ParseFailed)
TEST_F(ForwardingSourceOperationsTests, GotNotAnObject)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto receivedMessage = connection.receive(yield);
@@ -174,7 +175,7 @@ TEST_F(ForwardingSourceOperationsTests, GotNotAnObject)
TEST_F(ForwardingSourceOperationsTests, Success)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto receivedMessage = connection.receive(yield);

View File

@@ -19,6 +19,7 @@
#include "etl/impl/SourceImpl.hpp"
#include "rpc/Errors.hpp"
#include "util/Spawn.hpp"
#include <boost/asio/io_context.hpp>
#include <boost/asio/spawn.hpp>
@@ -107,7 +108,7 @@ TEST_F(SourceImplTest, stop)
{
EXPECT_CALL(*subscriptionSourceMock_, stop);
boost::asio::io_context ctx;
boost::asio::spawn(ctx, [&](boost::asio::yield_context yield) { source_.stop(yield); });
util::spawn(ctx, [&](boost::asio::yield_context yield) { source_.stop(yield); });
ctx.run();
}
@@ -192,7 +193,7 @@ TEST_F(SourceImplTest, forwardToRippled)
.WillOnce(Return(request));
boost::asio::io_context ioContext;
boost::asio::spawn(ioContext, [&](boost::asio::yield_context yield) {
util::spawn(ioContext, [&](boost::asio::yield_context yield) {
auto const response = source_.forwardToRippled(request, clientIp, xUserValue, yield);
EXPECT_EQ(response, request);
});

View File

@@ -22,6 +22,7 @@
#include "util/MockNetworkValidatedLedgers.hpp"
#include "util/MockPrometheus.hpp"
#include "util/MockSubscriptionManager.hpp"
#include "util/Spawn.hpp"
#include "util/TestWsServer.hpp"
#include "util/prometheus/Gauge.hpp"
@@ -53,7 +54,7 @@ struct SubscriptionSourceConnectionTestsBase : SyncAsioContextTest {
void
stopSubscriptionSource()
{
boost::asio::spawn(ctx_, [this](auto&& yield) { subscriptionSource_.stop(yield); });
util::spawn(ctx_, [this](auto&& yield) { subscriptionSource_.stop(yield); });
}
[[maybe_unused]] TestWsConnection
@@ -117,7 +118,7 @@ TEST_F(SubscriptionSourceConnectionTests, ConnectionFailed_Retry_ConnectionFaile
TEST_F(SubscriptionSourceConnectionTests, ReadError)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
connection.close(yield);
});
@@ -129,7 +130,7 @@ TEST_F(SubscriptionSourceConnectionTests, ReadError)
TEST_F(SubscriptionSourceConnectionTests, ReadTimeout)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
std::this_thread::sleep_for(std::chrono::milliseconds{10});
});
@@ -141,7 +142,7 @@ TEST_F(SubscriptionSourceConnectionTests, ReadTimeout)
TEST_F(SubscriptionSourceConnectionTests, ReadError_Reconnect)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
for (int i = 0; i < 2; ++i) {
auto connection = serverConnection(yield);
connection.close(yield);
@@ -156,7 +157,7 @@ TEST_F(SubscriptionSourceConnectionTests, ReadError_Reconnect)
TEST_F(SubscriptionSourceConnectionTests, IsConnected)
{
EXPECT_FALSE(subscriptionSource_.isConnected());
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
connection.close(yield);
});
@@ -184,7 +185,7 @@ struct SubscriptionSourceReadTests : util::prometheus::WithPrometheus, Subscript
TEST_F(SubscriptionSourceReadTests, GotWrongMessage_Reconnect)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage("something", yield);
// We have to schedule receiving to receive close frame and boost will handle it automatically
connection.receive(yield);
@@ -198,7 +199,7 @@ TEST_F(SubscriptionSourceReadTests, GotWrongMessage_Reconnect)
TEST_F(SubscriptionSourceReadTests, GotResult)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"result":{})JSON", yield);
connection.close(yield);
});
@@ -210,7 +211,7 @@ TEST_F(SubscriptionSourceReadTests, GotResult)
TEST_F(SubscriptionSourceReadTests, GotResultWithLedgerIndex)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"result":{"ledger_index":123}})JSON", yield);
connection.close(yield);
});
@@ -223,7 +224,7 @@ TEST_F(SubscriptionSourceReadTests, GotResultWithLedgerIndex)
TEST_F(SubscriptionSourceReadTests, GotResultWithLedgerIndexAsString_Reconnect)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"result":{"ledger_index":"123"}})JSON", yield);
// We have to schedule receiving to receive close frame and boost will handle it automatically
connection.receive(yield);
@@ -237,7 +238,7 @@ TEST_F(SubscriptionSourceReadTests, GotResultWithLedgerIndexAsString_Reconnect)
TEST_F(SubscriptionSourceReadTests, GotResultWithValidatedLedgersAsNumber_Reconnect)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"result":{"validated_ledgers":123}})JSON", yield);
// We have to schedule receiving to receive close frame and boost will handle it automatically
connection.receive(yield);
@@ -261,7 +262,7 @@ TEST_F(SubscriptionSourceReadTests, GotResultWithValidatedLedgers)
EXPECT_FALSE(subscriptionSource_.hasLedger(789));
EXPECT_FALSE(subscriptionSource_.hasLedger(790));
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"result":{"validated_ledgers":"123-456,789,32"}})JSON", yield);
connection.close(yield);
});
@@ -285,7 +286,7 @@ TEST_F(SubscriptionSourceReadTests, GotResultWithValidatedLedgers)
TEST_F(SubscriptionSourceReadTests, GotResultWithValidatedLedgersWrongValue_Reconnect)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"result":{"validated_ledgers":"123-456-789,32"}})JSON", yield);
// We have to schedule receiving to receive close frame and boost will handle it automatically
connection.receive(yield);
@@ -305,7 +306,7 @@ TEST_F(SubscriptionSourceReadTests, GotResultWithLedgerIndexAndValidatedLedgers)
EXPECT_FALSE(subscriptionSource_.hasLedger(3));
EXPECT_FALSE(subscriptionSource_.hasLedger(4));
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection =
connectAndSendMessage(R"JSON({"result":{"ledger_index":123,"validated_ledgers":"1-3"}})JSON", yield);
connection.close(yield);
@@ -326,7 +327,7 @@ TEST_F(SubscriptionSourceReadTests, GotResultWithLedgerIndexAndValidatedLedgers)
TEST_F(SubscriptionSourceReadTests, GotLedgerClosed)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type":"ledgerClosed"})JSON", yield);
connection.close(yield);
});
@@ -340,7 +341,7 @@ TEST_F(SubscriptionSourceReadTests, GotLedgerClosedForwardingIsSet)
{
subscriptionSource_.setForwarding(true);
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type": "ledgerClosed"})JSON", yield);
connection.close(yield);
});
@@ -356,7 +357,7 @@ TEST_F(SubscriptionSourceReadTests, GotLedgerClosedForwardingIsSet)
TEST_F(SubscriptionSourceReadTests, GotLedgerClosedWithLedgerIndex)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type": "ledgerClosed","ledger_index": 123})JSON", yield);
connection.close(yield);
});
@@ -369,7 +370,7 @@ TEST_F(SubscriptionSourceReadTests, GotLedgerClosedWithLedgerIndex)
TEST_F(SubscriptionSourceReadTests, GotLedgerClosedWithLedgerIndexAsString_Reconnect)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type":"ledgerClosed","ledger_index":"123"}})JSON", yield);
// We have to schedule receiving to receive close frame and boost will handle it automatically
connection.receive(yield);
@@ -383,7 +384,7 @@ TEST_F(SubscriptionSourceReadTests, GotLedgerClosedWithLedgerIndexAsString_Recon
TEST_F(SubscriptionSourceReadTests, GorLedgerClosedWithValidatedLedgersAsNumber_Reconnect)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type":"ledgerClosed","validated_ledgers":123})JSON", yield);
// We have to schedule receiving to receive close frame and boost will handle it automatically
connection.receive(yield);
@@ -402,7 +403,7 @@ TEST_F(SubscriptionSourceReadTests, GotLedgerClosedWithValidatedLedgers)
EXPECT_FALSE(subscriptionSource_.hasLedger(2));
EXPECT_FALSE(subscriptionSource_.hasLedger(3));
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type":"ledgerClosed","validated_ledgers":"1-2"})JSON", yield);
connection.close(yield);
});
@@ -425,7 +426,7 @@ TEST_F(SubscriptionSourceReadTests, GotLedgerClosedWithLedgerIndexAndValidatedLe
EXPECT_FALSE(subscriptionSource_.hasLedger(2));
EXPECT_FALSE(subscriptionSource_.hasLedger(3));
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(
R"JSON({"type":"ledgerClosed","ledger_index":123,"validated_ledgers":"1-2"})JSON", yield
);
@@ -446,7 +447,7 @@ TEST_F(SubscriptionSourceReadTests, GotLedgerClosedWithLedgerIndexAndValidatedLe
TEST_F(SubscriptionSourceReadTests, GotTransactionIsForwardingFalse)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"transaction":"some_transaction_data"})JSON", yield);
connection.close(yield);
});
@@ -461,7 +462,7 @@ TEST_F(SubscriptionSourceReadTests, GotTransactionIsForwardingTrue)
subscriptionSource_.setForwarding(true);
boost::json::object const message = {{"transaction", "some_transaction_data"}};
boost::asio::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(boost::json::serialize(message), yield);
connection.close(yield);
});
@@ -477,7 +478,7 @@ TEST_F(SubscriptionSourceReadTests, GotTransactionWithMetaIsForwardingFalse)
subscriptionSource_.setForwarding(true);
boost::json::object const message = {{"transaction", "some_transaction_data"}, {"meta", "some_meta_data"}};
boost::asio::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(boost::json::serialize(message), yield);
connection.close(yield);
});
@@ -490,7 +491,7 @@ TEST_F(SubscriptionSourceReadTests, GotTransactionWithMetaIsForwardingFalse)
TEST_F(SubscriptionSourceReadTests, GotValidationReceivedIsForwardingFalse)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type":"validationReceived"})JSON", yield);
connection.close(yield);
});
@@ -505,7 +506,7 @@ TEST_F(SubscriptionSourceReadTests, GotValidationReceivedIsForwardingTrue)
subscriptionSource_.setForwarding(true);
boost::json::object const message = {{"type", "validationReceived"}};
boost::asio::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(boost::json::serialize(message), yield);
connection.close(yield);
});
@@ -518,7 +519,7 @@ TEST_F(SubscriptionSourceReadTests, GotValidationReceivedIsForwardingTrue)
TEST_F(SubscriptionSourceReadTests, GotManiefstReceivedIsForwardingFalse)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(R"JSON({"type":"manifestReceived"})JSON", yield);
connection.close(yield);
});
@@ -533,7 +534,7 @@ TEST_F(SubscriptionSourceReadTests, GotManifestReceivedIsForwardingTrue)
subscriptionSource_.setForwarding(true);
boost::json::object const message = {{"type", "manifestReceived"}};
boost::asio::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&message, this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage(boost::json::serialize(message), yield);
connection.close(yield);
});
@@ -546,7 +547,7 @@ TEST_F(SubscriptionSourceReadTests, GotManifestReceivedIsForwardingTrue)
TEST_F(SubscriptionSourceReadTests, LastMessageTime)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage("some_message", yield);
connection.close(yield);
});
@@ -569,7 +570,7 @@ TEST_F(SubscriptionSourcePrometheusCounterTests, LastMessageTime)
auto& lastMessageTimeMock = makeMock<util::prometheus::GaugeInt>(
"subscription_source_last_message_time", fmt::format("{{source=\"127.0.0.1:{}\"}}", wsServer_.port())
);
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto connection = connectAndSendMessage("some_message", yield);
connection.close(yield);
});

View File

@@ -20,6 +20,7 @@
#include "etlng/impl/ForwardingSource.hpp"
#include "rpc/Errors.hpp"
#include "util/AsioContextTestFixture.hpp"
#include "util/Spawn.hpp"
#include "util/TestWsServer.hpp"
#include <boost/asio/spawn.hpp>
@@ -78,7 +79,7 @@ protected:
TEST_F(ForwardingSourceOperationsNgTests, XUserHeader)
{
std::string const xUserValue = "some_user";
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto headers = connection.headers();
ASSERT_FALSE(headers.empty());
@@ -101,7 +102,7 @@ TEST_F(ForwardingSourceOperationsNgTests, XUserHeader)
TEST_F(ForwardingSourceOperationsNgTests, ReadFailed)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
connection.close(yield);
});
@@ -116,7 +117,7 @@ TEST_F(ForwardingSourceOperationsNgTests, ReadFailed)
TEST_F(ForwardingSourceOperationsNgTests, ReadTimeout)
{
TestWsConnectionPtr connection;
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
connection = std::make_unique<TestWsConnection>(serverConnection(yield));
});
@@ -129,7 +130,7 @@ TEST_F(ForwardingSourceOperationsNgTests, ReadTimeout)
TEST_F(ForwardingSourceOperationsNgTests, ParseFailed)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto receivedMessage = connection.receive(yield);
@@ -151,7 +152,7 @@ TEST_F(ForwardingSourceOperationsNgTests, ParseFailed)
TEST_F(ForwardingSourceOperationsNgTests, GotNotAnObject)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto receivedMessage = connection.receive(yield);
@@ -174,7 +175,7 @@ TEST_F(ForwardingSourceOperationsNgTests, GotNotAnObject)
TEST_F(ForwardingSourceOperationsNgTests, Success)
{
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto connection = serverConnection(yield);
auto receivedMessage = connection.receive(yield);

View File

@@ -22,6 +22,7 @@
#include "etlng/Models.hpp"
#include "etlng/impl/SourceImpl.hpp"
#include "rpc/Errors.hpp"
#include "util/Spawn.hpp"
#include <boost/asio/io_context.hpp>
#include <boost/asio/spawn.hpp>
@@ -133,7 +134,7 @@ TEST_F(SourceImplNgTest, stop)
EXPECT_CALL(*subscriptionSourceMock_, stop);
EXPECT_CALL(grpcSourceMock_, stop);
boost::asio::io_context ctx;
boost::asio::spawn(ctx, [&](boost::asio::yield_context yield) { source_.stop(yield); });
util::spawn(ctx, [&](boost::asio::yield_context yield) { source_.stop(yield); });
ctx.run();
}
@@ -234,7 +235,7 @@ TEST_F(SourceImplNgTest, forwardToRippled)
.WillOnce(Return(request));
boost::asio::io_context ioContext;
boost::asio::spawn(ioContext, [&](boost::asio::yield_context yield) {
util::spawn(ioContext, [&](boost::asio::yield_context yield) {
auto const response = source_.forwardToRippled(request, clientIp, xUserValue, yield);
EXPECT_EQ(response, request);
});

View File

@@ -19,6 +19,7 @@
#include "feed/FeedTestUtil.hpp"
#include "feed/impl/LedgerFeed.hpp"
#include "util/Spawn.hpp"
#include "util/TestObject.hpp"
#include "web/SubscriptionContextInterface.hpp"
@@ -62,7 +63,7 @@ TEST_F(FeedLedgerTest, SubPub)
"reserve_inc": 2
})JSON";
boost::asio::io_context ioContext;
boost::asio::spawn(ioContext, [this](boost::asio::yield_context yield) {
util::spawn(ioContext, [this](boost::asio::yield_context yield) {
EXPECT_CALL(*mockSessionPtr, onDisconnect);
auto res = testFeedPtr->sub(yield, backend_, sessionPtr);
// check the response
@@ -120,11 +121,14 @@ TEST_F(FeedLedgerTest, AutoDisconnect)
web::SubscriptionContextInterface::OnDisconnectSlot slot;
EXPECT_CALL(*mockSessionPtr, onDisconnect).WillOnce(testing::SaveArg<0>(&slot));
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
boost::asio::io_context ioContext;
util::spawn(ioContext, [this](boost::asio::yield_context yield) {
auto res = testFeedPtr->sub(yield, backend_, sessionPtr);
// check the response
EXPECT_EQ(res, json::parse(kLEDGER_RESPONSE));
});
ioContext.run();
EXPECT_EQ(testFeedPtr->count(), 1);
EXPECT_CALL(*mockSessionPtr, send(_)).Times(0);

View File

@@ -25,6 +25,7 @@
#include "util/MockBackendTestFixture.hpp"
#include "util/MockPrometheus.hpp"
#include "util/MockWsBase.hpp"
#include "util/Spawn.hpp"
#include "util/TestObject.hpp"
#include "util/async/context/BasicExecutionContext.hpp"
#include "util/async/context/SyncExecutionContext.hpp"
@@ -291,7 +292,7 @@ TEST_F(SubscriptionManagerTest, LedgerTest)
"reserve_inc": 2
})JSON";
boost::asio::io_context ctx;
boost::asio::spawn(ctx, [this](boost::asio::yield_context yield) {
util::spawn(ctx, [this](boost::asio::yield_context yield) {
EXPECT_CALL(*sessionPtr_, onDisconnect);
auto const res = subscriptionManagerPtr_->subLedger(yield, session_);
// check the response

View File

@@ -29,6 +29,7 @@
#include "util/MockBackendTestFixture.hpp"
#include "util/MockPrometheus.hpp"
#include "util/NameGenerator.hpp"
#include "util/Spawn.hpp"
#include "util/Taggable.hpp"
#include "util/TestObject.hpp"
#include "util/config/ConfigDefinition.hpp"
@@ -98,7 +99,7 @@ protected:
TEST_F(RPCHelpersTest, TraverseOwnedNodesMarkerInvalidIndexNotHex)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto account = getAccountIdWithString(kACCOUNT);
auto ret = traverseOwnedNodes(*backend_, account, 9, 10, "nothex,10", yield, [](auto) {
@@ -112,7 +113,7 @@ TEST_F(RPCHelpersTest, TraverseOwnedNodesMarkerInvalidIndexNotHex)
TEST_F(RPCHelpersTest, TraverseOwnedNodesMarkerInvalidPageNotInt)
{
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
auto account = getAccountIdWithString(kACCOUNT);
auto ret = traverseOwnedNodes(*backend_, account, 9, 10, "nothex,abc", yield, [](auto) {
@@ -145,7 +146,7 @@ TEST_F(RPCHelpersTest, TraverseOwnedNodesNoInputMarker)
ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs));
EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(1);
boost::asio::spawn(ctx_, [this, &account](boost::asio::yield_context yield) {
util::spawn(ctx_, [this, &account](boost::asio::yield_context yield) {
auto ret = traverseOwnedNodes(*backend_, account, 9, 10, {}, yield, [](auto) {});
EXPECT_TRUE(ret.has_value());
EXPECT_EQ(
@@ -184,7 +185,7 @@ TEST_F(RPCHelpersTest, TraverseOwnedNodesNoInputMarkerReturnSamePageMarker)
ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs));
EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(1);
boost::asio::spawn(ctx_, [this, &account](boost::asio::yield_context yield) {
util::spawn(ctx_, [this, &account](boost::asio::yield_context yield) {
auto count = 0;
auto ret = traverseOwnedNodes(*backend_, account, 9, 10, {}, yield, [&](auto) { count++; });
EXPECT_TRUE(ret.has_value());
@@ -235,7 +236,7 @@ TEST_F(RPCHelpersTest, TraverseOwnedNodesNoInputMarkerReturnOtherPageMarker)
ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs));
EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(1);
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto count = 0;
auto ret = traverseOwnedNodes(*backend_, account, 9, kLIMIT, {}, yield, [&](auto) { count++; });
EXPECT_TRUE(ret.has_value());
@@ -279,7 +280,7 @@ TEST_F(RPCHelpersTest, TraverseOwnedNodesWithMarkerReturnSamePageMarker)
ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs));
EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(1);
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto count = 0;
auto ret = traverseOwnedNodes(
*backend_, account, 9, kLIMIT, fmt::format("{},{}", kINDEX1, kPAGE_NUM), yield, [&](auto) { count++; }
@@ -315,7 +316,7 @@ TEST_F(RPCHelpersTest, TraverseOwnedNodesWithUnexistingIndexMarker)
ON_CALL(*backend_, doFetchLedgerObject(ownerDir2Kk, testing::_, testing::_))
.WillByDefault(Return(ownerDir.getSerializer().peekData()));
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto count = 0;
auto ret = traverseOwnedNodes(
*backend_, account, 9, kLIMIT, fmt::format("{},{}", kINDEX2, kPAGE_NUM), yield, [&](auto) { count++; }
@@ -418,15 +419,13 @@ TEST_F(RPCHelpersTest, DeliverMaxAliasV1)
TEST_F(RPCHelpersTest, DeliverMaxAliasV2)
{
auto req = boost::json::parse(
R"JSON({
"TransactionType": "Payment",
"Amount": {
"test": "test"
}
})JSON"
)
.as_object();
auto constexpr kJSON = R"JSON({
"TransactionType": "Payment",
"Amount": {
"test": "test"
}
})JSON";
auto req = boost::json::parse(kJSON).as_object();
insertDeliverMaxAlias(req, 2);
EXPECT_EQ(
@@ -523,15 +522,11 @@ TEST_F(RPCHelpersTest, TransactionAndMetadataBinaryJsonV2)
TEST_F(RPCHelpersTest, ParseIssue)
{
auto issue = parseIssue(
boost::json::parse(
R"JSON({
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"currency": "JPY"
})JSON"
)
.as_object()
);
auto constexpr kJSON = R"JSON({
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
"currency": "JPY"
})JSON";
auto issue = parseIssue(boost::json::parse(kJSON).as_object());
EXPECT_TRUE(issue.account == getAccountIdWithString(kACCOUNT2));
issue = parseIssue(boost::json::parse(R"JSON({"currency": "XRP"})JSON").as_object());
@@ -541,18 +536,11 @@ TEST_F(RPCHelpersTest, ParseIssue)
EXPECT_THROW(parseIssue(boost::json::parse(R"JSON({"currency": "XRP2"})JSON").as_object()), std::runtime_error);
EXPECT_THROW(
parseIssue(
boost::json::parse(
R"JSON({
"issuer": "abcd",
"currency": "JPY"
})JSON"
)
.as_object()
),
std::runtime_error
);
auto constexpr kJSON2 = R"JSON({
"issuer": "abcd",
"currency": "JPY"
})JSON";
EXPECT_THROW(parseIssue(boost::json::parse(kJSON2).as_object()), std::runtime_error);
EXPECT_THROW(
parseIssue(boost::json::parse(R"JSON({"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun"})JSON").as_object()),
@@ -857,7 +845,7 @@ TEST_F(RPCHelpersTest, AccountHoldsFixLPTAmendmentDisabled)
EXPECT_CALL(*mockAmendmentCenterPtr_, isEnabled(testing::_, Amendments::fixFrozenLPTokenTransfer, testing::_))
.WillOnce(Return(false));
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto ret = accountHolds(
*backend_,
*mockAmendmentCenterPtr_,
@@ -897,7 +885,7 @@ TEST_F(RPCHelpersTest, AccountHoldsLPTokenNotAMMAccount)
.Times(2)
.WillRepeatedly(Return(account2Root.getSerializer().peekData()));
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto ret = accountHolds(
*backend_, *mockAmendmentCenterPtr_, 0, account, ripple::to_currency("USD"), account2, true, yield
);
@@ -944,7 +932,7 @@ TEST_F(RPCHelpersTest, AccountHoldsLPTokenAsset1Frozen)
EXPECT_CALL(*backend_, doFetchLedgerObject(issuerKk, testing::_, testing::_))
.WillOnce(Return(issuerAccountRoot.getSerializer().peekData()));
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto ret = accountHolds(
*backend_,
*mockAmendmentCenterPtr_,
@@ -997,7 +985,7 @@ TEST_F(RPCHelpersTest, AccountHoldsLPTokenAsset2Frozen)
EXPECT_CALL(*backend_, doFetchLedgerObject(issuerKk, testing::_, testing::_))
.WillOnce(Return(issuerAccountRoot.getSerializer().peekData()));
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto ret = accountHolds(
*backend_,
*mockAmendmentCenterPtr_,
@@ -1057,7 +1045,7 @@ TEST_F(RPCHelpersTest, AccountHoldsLPTokenUnfrozen)
EXPECT_CALL(*backend_, doFetchLedgerObject(usdRippleStateKk, testing::_, testing::_))
.WillOnce(Return(usdRippleState.getSerializer().peekData()));
boost::asio::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
util::spawn(ctx_, [&, this](boost::asio::yield_context yield) {
auto ret = accountHolds(
*backend_,
*mockAmendmentCenterPtr_,
@@ -1086,122 +1074,199 @@ static auto
generateTestValuesForParametersTest()
{
return std::vector<IsAdminCmdParamTestCaseBundle>{
{.testName = "ledgerEntry",
.method = "ledger_entry",
.testJson = R"JSON({"type": false})JSON",
.expected = false},
{
.testName = "ledgerEntry",
.method = "ledger_entry",
.testJson = R"JSON({"type": false})JSON",
.expected = false,
},
{
.testName = "featureVetoedTrue",
.method = "feature",
.testJson = R"JSON({"vetoed": true, "feature": "foo"})JSON",
.expected = true,
},
{
.testName = "featureVetoedFalse",
.method = "feature",
.testJson = R"JSON({"vetoed": false, "feature": "foo"})JSON",
.expected = true,
},
{
.testName = "featureVetoedIsStr",
.method = "feature",
.testJson = R"JSON({"vetoed": "String"})JSON",
.expected = true,
},
{
.testName = "ledger",
.method = "ledger",
.testJson = R"JSON({})JSON",
.expected = false,
},
{
.testName = "ledgerWithType",
.method = "ledger",
.testJson = R"JSON({"type": "fee"})JSON",
.expected = false,
},
{
.testName = "ledgerFullTrue",
.method = "ledger",
.testJson = R"JSON({"full": true})JSON",
.expected = true,
},
{
.testName = "ledgerFullFalse",
.method = "ledger",
.testJson = R"JSON({"full": false})JSON",
.expected = false,
},
{
.testName = "ledgerFullIsStr",
.method = "ledger",
.testJson = R"JSON({"full": "String"})JSON",
.expected = true,
},
{
.testName = "ledgerFullIsEmptyStr",
.method = "ledger",
.testJson = R"JSON({"full": ""})JSON",
.expected = false,
},
{
.testName = "ledgerFullIsNumber1",
.method = "ledger",
.testJson = R"JSON({"full": 1})JSON",
.expected = true,
},
{
.testName = "ledgerFullIsNumber0",
.method = "ledger",
.testJson = R"JSON({"full": 0})JSON",
.expected = false,
},
{
.testName = "ledgerFullIsNull",
.method = "ledger",
.testJson = R"JSON({"full": null})JSON",
.expected = false,
},
{
.testName = "ledgerFullIsFloat0",
.method = "ledger",
.testJson = R"JSON({"full": 0.0})JSON",
.expected = false,
},
{
.testName = "ledgerFullIsFloat1",
.method = "ledger",
.testJson = R"JSON({"full": 0.1})JSON",
.expected = true,
},
{
.testName = "ledgerFullIsArray",
.method = "ledger",
.testJson = R"JSON({"full": [1]})JSON",
.expected = true,
},
{
.testName = "ledgerFullIsEmptyArray",
.method = "ledger",
.testJson = R"JSON({"full": []})JSON",
.expected = false,
},
{
.testName = "ledgerFullIsObject",
.method = "ledger",
.testJson = R"JSON({"full": {"key": 1}})JSON",
.expected = true,
},
{
.testName = "ledgerFullIsEmptyObject",
.method = "ledger",
.testJson = R"JSON({"full": {}})JSON",
.expected = false,
},
{.testName = "featureVetoedTrue",
.method = "feature",
.testJson = R"JSON({"vetoed": true, "feature": "foo"})JSON",
.expected = true},
{.testName = "featureVetoedFalse",
.method = "feature",
.testJson = R"JSON({"vetoed": false, "feature": "foo"})JSON",
.expected = true},
{.testName = "featureVetoedIsStr",
.method = "feature",
.testJson = R"JSON({"vetoed": "String"})JSON",
.expected = true},
{.testName = "ledger", .method = "ledger", .testJson = R"JSON({})JSON", .expected = false},
{.testName = "ledgerWithType", .method = "ledger", .testJson = R"JSON({"type": "fee"})JSON", .expected = false},
{.testName = "ledgerFullTrue", .method = "ledger", .testJson = R"JSON({"full": true})JSON", .expected = true},
{.testName = "ledgerFullFalse",
.method = "ledger",
.testJson = R"JSON({"full": false})JSON",
.expected = false},
{.testName = "ledgerFullIsStr",
.method = "ledger",
.testJson = R"JSON({"full": "String"})JSON",
.expected = true},
{.testName = "ledgerFullIsEmptyStr",
.method = "ledger",
.testJson = R"JSON({"full": ""})JSON",
.expected = false},
{.testName = "ledgerFullIsNumber1", .method = "ledger", .testJson = R"JSON({"full": 1})JSON", .expected = true},
{.testName = "ledgerFullIsNumber0",
.method = "ledger",
.testJson = R"JSON({"full": 0})JSON",
.expected = false},
{.testName = "ledgerFullIsNull",
.method = "ledger",
.testJson = R"JSON({"full": null})JSON",
.expected = false},
{.testName = "ledgerFullIsFloat0",
.method = "ledger",
.testJson = R"JSON({"full": 0.0})JSON",
.expected = false},
{.testName = "ledgerFullIsFloat1",
.method = "ledger",
.testJson = R"JSON({"full": 0.1})JSON",
.expected = true},
{.testName = "ledgerFullIsArray", .method = "ledger", .testJson = R"JSON({"full": [1]})JSON", .expected = true},
{.testName = "ledgerFullIsEmptyArray",
.method = "ledger",
.testJson = R"JSON({"full": []})JSON",
.expected = false},
{.testName = "ledgerFullIsObject",
.method = "ledger",
.testJson = R"JSON({"full": {"key": 1}})JSON",
.expected = true},
{.testName = "ledgerFullIsEmptyObject",
.method = "ledger",
.testJson = R"JSON({"full": {}})JSON",
.expected = false},
{.testName = "ledgerAccountsTrue",
.method = "ledger",
.testJson = R"JSON({"accounts": true})JSON",
.expected = true},
{.testName = "ledgerAccountsFalse",
.method = "ledger",
.testJson = R"JSON({"accounts": false})JSON",
.expected = false},
{.testName = "ledgerAccountsIsStr",
.method = "ledger",
.testJson = R"JSON({"accounts": "String"})JSON",
.expected = true},
{.testName = "ledgerAccountsIsEmptyStr",
.method = "ledger",
.testJson = R"JSON({"accounts": ""})JSON",
.expected = false},
{.testName = "ledgerAccountsIsNumber1",
.method = "ledger",
.testJson = R"JSON({"accounts": 1})JSON",
.expected = true},
{.testName = "ledgerAccountsIsNumber0",
.method = "ledger",
.testJson = R"JSON({"accounts": 0})JSON",
.expected = false},
{.testName = "ledgerAccountsIsNull",
.method = "ledger",
.testJson = R"JSON({"accounts": null})JSON",
.expected = false},
{.testName = "ledgerAccountsIsFloat0",
.method = "ledger",
.testJson = R"JSON({"accounts": 0.0})JSON",
.expected = false},
{.testName = "ledgerAccountsIsFloat1",
.method = "ledger",
.testJson = R"JSON({"accounts": 0.1})JSON",
.expected = true},
{.testName = "ledgerAccountsIsArray",
.method = "ledger",
.testJson = R"JSON({"accounts": [1]})JSON",
.expected = true},
{.testName = "ledgerAccountsIsEmptyArray",
.method = "ledger",
.testJson = R"JSON({"accounts": []})JSON",
.expected = false},
{.testName = "ledgerAccountsIsObject",
.method = "ledger",
.testJson = R"JSON({"accounts": {"key": 1}})JSON",
.expected = true},
{.testName = "ledgerAccountsIsEmptyObject",
.method = "ledger",
.testJson = R"JSON({"accounts": {}})JSON",
.expected = false},
{
.testName = "ledgerAccountsTrue",
.method = "ledger",
.testJson = R"JSON({"accounts": true})JSON",
.expected = true,
},
{
.testName = "ledgerAccountsFalse",
.method = "ledger",
.testJson = R"JSON({"accounts": false})JSON",
.expected = false,
},
{
.testName = "ledgerAccountsIsStr",
.method = "ledger",
.testJson = R"JSON({"accounts": "String"})JSON",
.expected = true,
},
{
.testName = "ledgerAccountsIsEmptyStr",
.method = "ledger",
.testJson = R"JSON({"accounts": ""})JSON",
.expected = false,
},
{
.testName = "ledgerAccountsIsNumber1",
.method = "ledger",
.testJson = R"JSON({"accounts": 1})JSON",
.expected = true,
},
{
.testName = "ledgerAccountsIsNumber0",
.method = "ledger",
.testJson = R"JSON({"accounts": 0})JSON",
.expected = false,
},
{
.testName = "ledgerAccountsIsNull",
.method = "ledger",
.testJson = R"JSON({"accounts": null})JSON",
.expected = false,
},
{
.testName = "ledgerAccountsIsFloat0",
.method = "ledger",
.testJson = R"JSON({"accounts": 0.0})JSON",
.expected = false,
},
{
.testName = "ledgerAccountsIsFloat1",
.method = "ledger",
.testJson = R"JSON({"accounts": 0.1})JSON",
.expected = true,
},
{
.testName = "ledgerAccountsIsArray",
.method = "ledger",
.testJson = R"JSON({"accounts": [1]})JSON",
.expected = true,
},
{
.testName = "ledgerAccountsIsEmptyArray",
.method = "ledger",
.testJson = R"JSON({"accounts": []})JSON",
.expected = false,
},
{
.testName = "ledgerAccountsIsObject",
.method = "ledger",
.testJson = R"JSON({"accounts": {"key": 1}})JSON",
.expected = true,
},
{
.testName = "ledgerAccountsIsEmptyObject",
.method = "ledger",
.testJson = R"JSON({"accounts": {}})JSON",
.expected = false,
},
};
}

View File

@@ -23,6 +23,7 @@
#include "util/AsioContextTestFixture.hpp"
#include "util/MockBackendTestFixture.hpp"
#include "util/MockPrometheus.hpp"
#include "util/Spawn.hpp"
#include "util/TestObject.hpp"
#include <boost/asio/spawn.hpp>
@@ -117,7 +118,7 @@ TEST_F(CredentialHelperTest, GetInvalidCredentialArray)
boost::json::array credentialsArray = {kCREDENTIAL_ID};
auto const info = createLedgerHeader(kINDEX1, 30);
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto const ret = credentials::fetchCredentialArray(
credentialsArray, getAccountIdWithString(kACCOUNT), *backend_, info, yield
);
@@ -149,7 +150,7 @@ TEST_F(CredentialHelperTest, GetValidCredentialArray)
);
expectedAuthCreds.push_back(std::move(credential));
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto const result = credentials::fetchCredentialArray(
credentialsArray, getAccountIdWithString(kACCOUNT), *backend_, ledgerHeader, yield
);

View File

@@ -20,6 +20,7 @@
#include "util/AsioContextTestFixture.hpp"
#include "util/BlockingCache.hpp"
#include "util/NameGenerator.hpp"
#include "util/Spawn.hpp"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -146,7 +147,7 @@ TEST_P(BlockingCacheWaitTest, WaitForUpdate)
EXPECT_CALL(mockUpdater, Call)
.WillOnce([this, &waitingCoroutine](boost::asio::yield_context yield) -> std::expected<ValueType, ErrorType> {
boost::asio::spawn(yield, waitingCoroutine);
util::spawn(yield, waitingCoroutine);
if (GetParam().updateSuccessful) {
return value;
}
@@ -232,7 +233,7 @@ TEST_F(BlockingCacheTest, UpdateFromTwoCoroutinesHappensOnlyOnce)
EXPECT_CALL(mockUpdater, Call)
.WillOnce([this, &waitingCoroutine](boost::asio::yield_context yield) -> std::expected<ValueType, ErrorType> {
boost::asio::spawn(yield, waitingCoroutine);
util::spawn(yield, waitingCoroutine);
return value;
});
EXPECT_CALL(mockVerifier, Call(value)).WillOnce(Return(true));
@@ -244,6 +245,6 @@ TEST_F(BlockingCacheTest, UpdateFromTwoCoroutinesHappensOnlyOnce)
};
runSpawnWithTimeout(std::chrono::seconds{1}, [&](boost::asio::yield_context yield) {
boost::asio::spawn(yield, updatingCoroutine);
util::spawn(yield, updatingCoroutine);
});
}

View File

@@ -19,6 +19,7 @@
#include "util/AsioContextTestFixture.hpp"
#include "util/CoroutineGroup.hpp"
#include "util/Spawn.hpp"
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>
@@ -183,7 +184,7 @@ TEST_F(CoroutineGroupTests, SpawnForeign)
[&]() { ASSERT_FALSE(group.registerForeign(yield).has_value()); }();
boost::asio::spawn(ctx_, [this, &onForeignComplete](boost::asio::yield_context innerYield) {
util::spawn(ctx_, [this, &onForeignComplete](boost::asio::yield_context innerYield) {
boost::asio::steady_timer timer{innerYield.get_executor(), std::chrono::milliseconds{2}};
timer.async_wait(innerYield);
callback1_.Call();

View File

@@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
/*
This file is part of clio: https://github.com/XRPLF/clio
Copyright (c) 2025, the clio developers.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "util/Spawn.hpp"
#include <boost/asio/io_context.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/strand.hpp>
#include <gtest/gtest.h>
#include <stdexcept>
TEST(SpawnTest, SpawnOnIoContext)
{
EXPECT_ANY_THROW([] {
boost::asio::io_context io;
util::spawn(io, [](boost::asio::yield_context) { throw std::runtime_error("Test exception in coroutine"); });
io.run();
}());
}
TEST(SpawnTest, SpawnOnStrand)
{
EXPECT_ANY_THROW([] {
boost::asio::io_context io;
auto str = boost::asio::make_strand(io);
util::spawn(str, [](boost::asio::yield_context) { throw std::runtime_error("Test exception in coroutine"); });
io.run();
}());
}
TEST(SpawnTest, SpawnOnCoroutine)
{
EXPECT_ANY_THROW([] {
boost::asio::io_context io;
util::spawn(io, [](boost::asio::yield_context yield) {
util::spawn(yield, [](boost::asio::yield_context) {
throw std::runtime_error("Test exception in coroutine");
});
});
io.run();
}());
}

View File

@@ -18,6 +18,7 @@
//==============================================================================
#include "util/AsioContextTestFixture.hpp"
#include "util/Spawn.hpp"
#include "util/StopHelper.hpp"
#include <boost/asio/spawn.hpp>
@@ -39,7 +40,7 @@ TEST_F(StopHelperTests, asyncWaitForStopWaitsForReadyToStop)
EXPECT_CALL(readyToStopCalled_, Call).InSequence(sequence);
EXPECT_CALL(asyncWaitForStopFinished_, Call).InSequence(sequence);
boost::asio::spawn(ctx_, [this](boost::asio::yield_context yield) {
util::spawn(ctx_, [this](boost::asio::yield_context yield) {
stopHelper_.asyncWaitForStop(yield);
asyncWaitForStopFinished_.Call();
});

View File

@@ -18,6 +18,7 @@
//==============================================================================
#include "util/AsioContextTestFixture.hpp"
#include "util/Spawn.hpp"
#include "util/TestWsServer.hpp"
#include "util/requests/Types.hpp"
#include "util/requests/WsConnection.hpp"
@@ -96,7 +97,7 @@ TEST_P(WsConnectionTests, SendAndReceive)
}
builder.addHeaders(GetParam().headers);
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = unwrap(server.acceptConnection(yield));
for (size_t i = 0; i < clientMessages.size(); ++i) {
@@ -127,7 +128,7 @@ TEST_P(WsConnectionTests, SendAndReceive)
TEST_F(WsConnectionTests, ReadTimeout)
{
TestWsConnectionPtr serverConnection;
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
serverConnection = std::make_unique<TestWsConnection>(unwrap(server.acceptConnection(yield)));
});
@@ -142,7 +143,7 @@ TEST_F(WsConnectionTests, ReadTimeout)
TEST_F(WsConnectionTests, ReadWithTimeoutWorksFine)
{
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = unwrap(server.acceptConnection(yield));
auto maybeError = serverConnection.send("hello", yield);
EXPECT_FALSE(maybeError.has_value()) << *maybeError;
@@ -159,7 +160,7 @@ TEST_F(WsConnectionTests, ReadWithTimeoutWorksFine)
TEST_F(WsConnectionTests, WriteTimeout)
{
TestWsConnectionPtr serverConnection;
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
serverConnection = std::make_unique<TestWsConnection>(unwrap(server.acceptConnection(yield)));
});
@@ -179,7 +180,7 @@ TEST_F(WsConnectionTests, WriteTimeout)
TEST_F(WsConnectionTests, WriteWithTimeoutWorksFine)
{
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = unwrap(server.acceptConnection(yield));
auto message = serverConnection.receive(yield);
ASSERT_TRUE(message.has_value());
@@ -195,7 +196,7 @@ TEST_F(WsConnectionTests, WriteWithTimeoutWorksFine)
TEST_F(WsConnectionTests, TrySslUsePlain)
{
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
// Client attempts to establish SSL connection first which will fail
auto failedConnection = server.acceptConnection(yield);
EXPECT_FALSE(failedConnection.has_value());
@@ -246,7 +247,7 @@ TEST_F(WsConnectionTests, ResolveError)
TEST_F(WsConnectionTests, WsHandshakeError)
{
builder.setConnectionTimeout(std::chrono::milliseconds{1});
asio::spawn(ctx_, [&](asio::yield_context yield) { server.acceptConnectionAndDropIt(yield); });
util::spawn(ctx_, [&](asio::yield_context yield) { server.acceptConnectionAndDropIt(yield); });
runSpawn([&](asio::yield_context yield) {
auto connection = builder.plainConnect(yield);
ASSERT_FALSE(connection.has_value());
@@ -257,7 +258,7 @@ TEST_F(WsConnectionTests, WsHandshakeError)
TEST_F(WsConnectionTests, WsHandshakeTimeout)
{
builder.setWsHandshakeTimeout(std::chrono::milliseconds{1});
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto socket = server.acceptConnectionWithoutHandshake(yield);
std::this_thread::sleep_for(std::chrono::milliseconds{10});
});
@@ -270,7 +271,7 @@ TEST_F(WsConnectionTests, WsHandshakeTimeout)
TEST_F(WsConnectionTests, CloseConnection)
{
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = unwrap(server.acceptConnection(yield));
auto message = serverConnection.receive(yield);
@@ -288,7 +289,7 @@ TEST_F(WsConnectionTests, CloseConnection)
TEST_F(WsConnectionTests, CloseConnectionTimeout)
{
TestWsConnectionPtr const serverConnection;
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = std::make_unique<TestWsConnection>(unwrap(server.acceptConnection(yield)));
});
@@ -303,7 +304,7 @@ TEST_F(WsConnectionTests, CloseConnectionTimeout)
TEST_F(WsConnectionTests, MultipleConnections)
{
for (size_t i = 0; i < 2; ++i) {
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = unwrap(server.acceptConnection(yield));
auto message = serverConnection.receive(yield);
@@ -323,7 +324,7 @@ TEST_F(WsConnectionTests, MultipleConnections)
TEST_F(WsConnectionTests, RespondsToPing)
{
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = unwrap(server.acceptConnection(yield));
testing::StrictMock<testing::MockFunction<void(boost::beast::websocket::frame_type, std::string_view)>>
@@ -331,7 +332,7 @@ TEST_F(WsConnectionTests, RespondsToPing)
serverConnection.setControlFrameCallback(controlFrameCallback.AsStdFunction());
EXPECT_CALL(controlFrameCallback, Call(boost::beast::websocket::frame_type::pong, testing::_)).WillOnce([&]() {
serverConnection.resetControlFrameCallback();
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto maybeError = serverConnection.send("got pong", yield);
ASSERT_FALSE(maybeError.has_value()) << *maybeError;
});
@@ -376,7 +377,7 @@ INSTANTIATE_TEST_SUITE_P(
TEST_P(WsConnectionErrorTests, ReadWriteError)
{
asio::spawn(ctx_, [&](asio::yield_context yield) {
util::spawn(ctx_, [&](asio::yield_context yield) {
auto serverConnection = unwrap(server.acceptConnection(yield));
auto error = serverConnection.close(yield);

View File

@@ -39,8 +39,8 @@
#include "web/dosguard/WhitelistHandler.hpp"
#include "web/interface/ConnectionBase.hpp"
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/beast/core/error.hpp>
#include <boost/beast/http/field.hpp>
#include <boost/beast/http/status.hpp>
@@ -150,7 +150,7 @@ struct WebServerTest : NoLoggerFixture {
WebServerTest()
{
work_.emplace(ctx); // make sure ctx does not stop on its own
work_.emplace(boost::asio::make_work_guard(ctx)); // make sure ctx does not stop on its own
runner_.emplace([this] { ctx.run(); });
}
@@ -182,7 +182,7 @@ struct WebServerTest : NoLoggerFixture {
TmpFile sslKeyFile{tests::sslKeyFile()};
private:
std::optional<boost::asio::io_service::work> work_;
std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work_;
std::optional<std::thread> runner_;
};

View File

@@ -24,6 +24,7 @@
#include "util/MockETLService.hpp"
#include "util/MockPrometheus.hpp"
#include "util/MockRPCEngine.hpp"
#include "util/Spawn.hpp"
#include "util/Taggable.hpp"
#include "util/config/ConfigDefinition.hpp"
#include "util/config/ConfigValue.hpp"
@@ -173,7 +174,7 @@ TEST_F(NgRpcServerHandlerTest, CoroutineSleepsUntilRpcEngineFinishes)
EXPECT_CALL(dosguard_, isOk(ip_)).WillOnce(Return(true));
EXPECT_CALL(dosguard_, add(ip_, testing::_)).WillOnce(Return(true));
EXPECT_CALL(*rpcEngine_, post).WillOnce([&](auto&& fn, auto&&) {
boost::asio::spawn(
util::spawn(
ctx_, [this, &rpcEngineDone, fn = std::forward<decltype(fn)>(fn)](boost::asio::yield_context yield) {
EXPECT_CALL(*rpcEngine_, notifyBadSyntax);
fn(yield);

View File

@@ -22,6 +22,7 @@
#include "util/LoggerFixtures.hpp"
#include "util/MockPrometheus.hpp"
#include "util/NameGenerator.hpp"
#include "util/Spawn.hpp"
#include "util/Taggable.hpp"
#include "util/TestHttpClient.hpp"
#include "util/TestWebSocketClient.hpp"
@@ -38,6 +39,7 @@
#include "web/ng/Server.hpp"
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/address_v4.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/spawn.hpp>
@@ -198,7 +200,7 @@ protected:
TEST_F(ServerTest, BadEndpoint)
{
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::address_v4::from_string("1.2.3.4"), 0};
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("1.2.3.4"), 0};
util::TagDecoratorFactory const tagDecoratorFactory{
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
};
@@ -242,7 +244,7 @@ struct ServerHttpTest : ServerTest, testing::WithParamInterface<ServerHttpTestBu
TEST_F(ServerHttpTest, ClientDisconnects)
{
HttpAsyncClient client{ctx_};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto maybeError =
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -259,7 +261,7 @@ TEST_F(ServerHttpTest, ClientDisconnects)
TEST_F(ServerHttpTest, OnConnectCheck)
{
auto const serverPort = tests::util::generateFreePort();
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::address_v4::from_string("0.0.0.0"), serverPort};
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("0.0.0.0"), serverPort};
util::TagDecoratorFactory const tagDecoratorFactory{
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
};
@@ -280,7 +282,7 @@ TEST_F(ServerHttpTest, OnConnectCheck)
HttpAsyncClient client{ctx_};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
boost::asio::steady_timer timer{yield.get_executor()};
EXPECT_CALL(onConnectCheck, Call)
@@ -319,7 +321,7 @@ TEST_F(ServerHttpTest, OnConnectCheck)
TEST_F(ServerHttpTest, OnConnectCheckFailed)
{
auto const serverPort = tests::util::generateFreePort();
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::address_v4::from_string("0.0.0.0"), serverPort};
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("0.0.0.0"), serverPort};
util::TagDecoratorFactory const tagDecoratorFactory{
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
};
@@ -347,7 +349,7 @@ TEST_F(ServerHttpTest, OnConnectCheckFailed)
};
});
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto maybeError =
client.connect("127.0.0.1", std::to_string(serverPort), yield, std::chrono::milliseconds{100});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -378,7 +380,7 @@ TEST_F(ServerHttpTest, OnConnectCheckFailed)
TEST_F(ServerHttpTest, OnDisconnectHook)
{
auto const serverPort = tests::util::generateFreePort();
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::address_v4::from_string("0.0.0.0"), serverPort};
boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address("0.0.0.0"), serverPort};
util::TagDecoratorFactory const tagDecoratorFactory{
ClioConfigDefinition{{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("uint")}}
};
@@ -399,7 +401,7 @@ TEST_F(ServerHttpTest, OnDisconnectHook)
HttpAsyncClient client{ctx_};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
boost::asio::steady_timer timer{ctx_.get_executor(), std::chrono::milliseconds{100}};
EXPECT_CALL(onDisconnectHookMock, Call).WillOnce([&timer](auto&&) { timer.cancel(); });
@@ -432,7 +434,7 @@ TEST_F(ServerHttpTest, OnDisconnectHook)
TEST_F(ServerHttpTest, ClientIsDisconnectedIfServerStopped)
{
HttpAsyncClient client{ctx_};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto maybeError =
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -467,7 +469,7 @@ TEST_P(ServerHttpTest, RequestResponse)
Response const response{http::status::ok, "some response", Request{request}};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto maybeError =
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -517,7 +519,7 @@ TEST_F(ServerTest, WsClientDisconnects)
{
WebSocketAsyncClient client{ctx_};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto maybeError =
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -539,7 +541,7 @@ TEST_F(ServerTest, WsRequestResponse)
Request::HttpHeaders const headers{};
Response const response{http::status::ok, "some response", Request{requestMessage_, headers}};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto maybeError =
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -577,7 +579,7 @@ TEST_F(ServerTest, WsRequestResponse)
TEST_F(ServerTest, WsClientIsDisconnectedIfServerStopped)
{
WebSocketAsyncClient client{ctx_};
boost::asio::spawn(ctx_, [&](boost::asio::yield_context yield) {
util::spawn(ctx_, [&](boost::asio::yield_context yield) {
auto maybeError =
client.connect("127.0.0.1", std::to_string(serverPort_), yield, std::chrono::milliseconds{100});
EXPECT_TRUE(maybeError.has_value());

View File

@@ -19,6 +19,7 @@
#include "util/AsioContextTestFixture.hpp"
#include "util/MockPrometheus.hpp"
#include "util/Spawn.hpp"
#include "util/Taggable.hpp"
#include "util/UnsupportedType.hpp"
#include "util/config/ConfigDefinition.hpp"
@@ -484,7 +485,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Stop)
.WillRepeatedly([&](auto&&, auto&&) {
++numCalls;
if (numCalls == 3)
boost::asio::spawn(ctx_, [this](auto yield) { connectionHandler.stop(yield); });
util::spawn(ctx_, [this](auto yield) { connectionHandler.stop(yield); });
return std::nullopt;
});

View File

@@ -19,6 +19,7 @@
#include "util/AsioContextTestFixture.hpp"
#include "util/CoroutineGroup.hpp"
#include "util/Spawn.hpp"
#include "util/Taggable.hpp"
#include "util/TestHttpClient.hpp"
#include "util/TestHttpServer.hpp"
@@ -78,7 +79,7 @@ protected:
TEST_F(HttpConnectionTests, wasUpgraded)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
});
@@ -93,7 +94,7 @@ TEST_F(HttpConnectionTests, Receive)
{
request_.set(boost::beast::http::field::user_agent, "test_client");
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -121,7 +122,7 @@ TEST_F(HttpConnectionTests, Receive)
TEST_F(HttpConnectionTests, ReceiveTimeout)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
});
@@ -136,7 +137,7 @@ TEST_F(HttpConnectionTests, ReceiveTimeout)
TEST_F(HttpConnectionTests, ReceiveClientDisconnected)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
httpClient_.disconnect();
@@ -155,7 +156,7 @@ TEST_F(HttpConnectionTests, Send)
Request const request{request_};
Response const response{http::status::ok, "some response data", request};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -182,7 +183,7 @@ TEST_F(HttpConnectionTests, SendMultipleTimes)
Request const request{request_};
Response const response{http::status::ok, "some response data", request};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -214,7 +215,7 @@ TEST_F(HttpConnectionTests, SendMultipleTimesFromMultipleCoroutines)
Request const request{request_};
Response const response{http::status::ok, "some response data", request};
boost::asio::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 =
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{100});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -249,7 +250,7 @@ TEST_F(HttpConnectionTests, SendMultipleTimesFromMultipleCoroutines)
TEST_F(HttpConnectionTests, SendMultipleTimesClientDisconnected)
{
Response const response{http::status::ok, "some response data", Request{request_}};
boost::asio::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 =
httpClient_.connect("localhost", httpServer_.port(), yield, std::chrono::milliseconds{1});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -277,7 +278,7 @@ TEST_F(HttpConnectionTests, SendMultipleTimesClientDisconnected)
TEST_F(HttpConnectionTests, SendClientDisconnected)
{
Response const response{http::status::ok, "some response data", Request{request_}};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
httpClient_.disconnect();
@@ -298,7 +299,7 @@ TEST_F(HttpConnectionTests, SendClientDisconnected)
TEST_F(HttpConnectionTests, Close)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -320,7 +321,7 @@ TEST_F(HttpConnectionTests, Close)
TEST_F(HttpConnectionTests, IsUpgradeRequested_GotHttpRequest)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
@@ -338,7 +339,7 @@ TEST_F(HttpConnectionTests, IsUpgradeRequested_GotHttpRequest)
TEST_F(HttpConnectionTests, IsUpgradeRequested_FailedToFetch)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
});
@@ -355,7 +356,7 @@ TEST_F(HttpConnectionTests, Upgrade)
{
WebSocketAsyncClient wsClient{ctx_};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
});
@@ -373,7 +374,7 @@ TEST_F(HttpConnectionTests, Upgrade)
TEST_F(HttpConnectionTests, Ip)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
});
@@ -389,7 +390,7 @@ TEST_F(HttpConnectionTests, isAdminSetAdmin)
testing::StrictMock<testing::MockFunction<bool()>> adminSetter;
EXPECT_CALL(adminSetter, Call).WillOnce(testing::Return(true));
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError->message(); }();
});

View File

@@ -19,6 +19,7 @@
#include "util/AsioContextTestFixture.hpp"
#include "util/CoroutineGroup.hpp"
#include "util/Spawn.hpp"
#include "util/Taggable.hpp"
#include "util/TestHttpServer.hpp"
#include "util/TestWebSocketClient.hpp"
@@ -94,7 +95,7 @@ protected:
TEST_F(WebWsConnectionTests, WasUpgraded)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
});
@@ -110,7 +111,7 @@ TEST_F(WebWsConnectionTests, DisconnectClientOnInactivity)
auto work = boost::asio::make_work_guard(clientCtx);
std::thread clientThread{[&clientCtx]() { clientCtx.run(); }};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
boost::asio::steady_timer timer{yield.get_executor(), std::chrono::milliseconds{5}};
@@ -138,7 +139,7 @@ TEST_F(WebWsConnectionTests, Send)
{
Response const response{boost::beast::http::status::ok, "some response", request_};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
auto const expectedMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
@@ -157,7 +158,7 @@ TEST_F(WebWsConnectionTests, SendShared)
{
auto const response = std::make_shared<std::string>("some response");
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
auto const expectedMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
@@ -176,7 +177,7 @@ TEST_F(WebWsConnectionTests, MultipleSend)
{
Response const response{boost::beast::http::status::ok, "some response", request_};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
@@ -201,7 +202,7 @@ TEST_F(WebWsConnectionTests, MultipleSendFromMultipleCoroutines)
{
Response const response{boost::beast::http::status::ok, "some response", request_};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
@@ -230,7 +231,7 @@ TEST_F(WebWsConnectionTests, SendFailed)
{
Response const response{boost::beast::http::status::ok, "some response", request_};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
wsClient_.close();
@@ -254,7 +255,7 @@ TEST_F(WebWsConnectionTests, SendFailedSendingFromMultipleCoroutines)
{
Response const response{boost::beast::http::status::ok, "some response", request_};
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
@@ -282,7 +283,7 @@ TEST_F(WebWsConnectionTests, SendFailedSendingFromMultipleCoroutines)
TEST_F(WebWsConnectionTests, Receive)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
@@ -301,7 +302,7 @@ TEST_F(WebWsConnectionTests, Receive)
TEST_F(WebWsConnectionTests, MultipleReceive)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
@@ -324,7 +325,7 @@ TEST_F(WebWsConnectionTests, MultipleReceive)
TEST_F(WebWsConnectionTests, ReceiveTimeout)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
});
@@ -340,7 +341,7 @@ TEST_F(WebWsConnectionTests, ReceiveTimeout)
TEST_F(WebWsConnectionTests, ReceiveFailed)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
wsClient_.close();
@@ -356,7 +357,7 @@ TEST_F(WebWsConnectionTests, ReceiveFailed)
TEST_F(WebWsConnectionTests, Close)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
auto const maybeMessage = wsClient_.receive(yield, std::chrono::milliseconds{100});
@@ -372,7 +373,7 @@ TEST_F(WebWsConnectionTests, Close)
TEST_F(WebWsConnectionTests, CloseWhenConnectionIsAlreadyClosed)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
wsClient_.close();
@@ -388,7 +389,7 @@ TEST_F(WebWsConnectionTests, CloseWhenConnectionIsAlreadyClosed)
TEST_F(WebWsConnectionTests, CloseCalledFromMultipleSubCoroutines)
{
boost::asio::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});
[&]() { ASSERT_FALSE(maybeError.has_value()) << maybeError.value().message(); }();
});