Skip to content

Commit

Permalink
infra_test_util library with TaskRunner (#1300)
Browse files Browse the repository at this point in the history
  • Loading branch information
battlmonstr authored Jul 1, 2023
1 parent c4225e6 commit 1c59386
Show file tree
Hide file tree
Showing 75 changed files with 486 additions and 436 deletions.
8 changes: 0 additions & 8 deletions cmd/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,6 @@ endif()
if(NOT SILKWORM_CORE_ONLY)
find_package(GTest REQUIRED)

# Silkworm Infra Tests
file(GLOB_RECURSE SILKWORM_INFRA_TESTS CONFIGURE_DEPENDS "${SILKWORM_MAIN_SRC_DIR}/infra/*_test.cpp")
add_executable(infra_test "unit_test.cpp;${SILKWORM_INFRA_TESTS}")
if(SILKWORM_SANITIZE)
target_compile_definitions(infra_test PRIVATE GRPC_ASAN_SUPPRESSED GRPC_TSAN_SUPPRESSED)
endif()
target_link_libraries(infra_test silkworm_infra Catch2::Catch2 GTest::gmock)

# Silkworm Node Tests
file(GLOB_RECURSE SILKWORM_NODE_TESTS CONFIGURE_DEPENDS "${SILKWORM_MAIN_SRC_DIR}/node/*_test.cpp")
add_executable(node_test unit_test.cpp ${SILKWORM_NODE_TESTS})
Expand Down
28 changes: 24 additions & 4 deletions silkworm/infra/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,29 @@
find_package(absl REQUIRED)
find_package(asio-grpc REQUIRED)
find_package(Boost REQUIRED container thread)
find_package(Catch2 REQUIRED)
find_package(gRPC REQUIRED)
find_package(GTest REQUIRED)
find_package(magic_enum REQUIRED)

add_subdirectory(test_util)

set(TARGET silkworm_infra)

file(GLOB_RECURSE SRC CONFIGURE_DEPENDS "*.cpp" "*.hpp")
list(FILTER SRC EXCLUDE REGEX "_test\\.cpp$")
list(FILTER SRC EXCLUDE REGEX "_benchmark\\.cpp$")
list(FILTER SRC EXCLUDE REGEX "test_util/")

add_library(silkworm_infra "${SRC}")
add_library(${TARGET} "${SRC}")

# Suppress ASAN/TSAN in gRPC to avoid ODR violation when building Silkworm with sanitizers See
# https://github.com/grpc/grpc/issues/19224
if(SILKWORM_SANITIZE)
target_compile_definitions(silkworm_infra PRIVATE GRPC_ASAN_SUPPRESSED GRPC_TSAN_SUPPRESSED)
target_compile_definitions(${TARGET} PRIVATE GRPC_ASAN_SUPPRESSED GRPC_TSAN_SUPPRESSED)
endif()

target_include_directories(silkworm_infra PUBLIC "${SILKWORM_MAIN_DIR}")
target_include_directories(${TARGET} PUBLIC "${SILKWORM_MAIN_DIR}")

set(LIBS_PUBLIC
silkworm_core
Expand All @@ -56,7 +63,20 @@ if(MSVC)
endif(MSVC)

target_link_libraries(
silkworm_infra
${TARGET}
PUBLIC "${LIBS_PUBLIC}"
PRIVATE "${LIBS_PRIVATE}"
)

# unit tests
set(TEST_TARGET ${TARGET}_test)
file(GLOB_RECURSE TEST_SRC CONFIGURE_DEPENDS "*_test.cpp")
add_executable(${TEST_TARGET} "${SILKWORM_MAIN_DIR}/cmd/test/unit_test.cpp" ${TEST_SRC})
if(SILKWORM_SANITIZE)
target_compile_definitions(${TEST_TARGET} PRIVATE GRPC_ASAN_SUPPRESSED GRPC_TSAN_SUPPRESSED)
endif()
target_link_libraries(
${TEST_TARGET}
PRIVATE ${TARGET} Catch2::Catch2 GTest::gmock
INTERFACE silkworm_infra_test_util
)
21 changes: 5 additions & 16 deletions silkworm/infra/common/log_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include <catch2/catch.hpp>

#include <silkworm/infra/test/log.hpp>
#include <silkworm/infra/test_util/log.hpp>

namespace silkworm::log {

Expand Down Expand Up @@ -52,17 +52,6 @@ void check_log_not_empty() {
CHECK(log_buffer.content().find("test") != std::string::npos);
}

//! Utility class using RAII to swap the underlying buffers of the provided streams
class StreamSwap {
public:
StreamSwap(std::ostream& o1, std::ostream& o2) : buffer_(o1.rdbuf()), stream_(o1) { o1.rdbuf(o2.rdbuf()); }
~StreamSwap() { stream_.rdbuf(buffer_); }

private:
std::streambuf* buffer_;
std::ostream& stream_;
};

//! Build the prettified key-value pair using color scheme
static std::string prettified_key_value(const std::string& key, const std::string& value) {
std::string kv_pair{kColorGreen};
Expand All @@ -77,8 +66,8 @@ static std::string prettified_key_value(const std::string& key, const std::strin

TEST_CASE("LogBuffer", "[silkworm][common][log]") {
// Temporarily override std::cout and std::cerr with null stream to avoid terminal output
StreamSwap cout_swap{std::cout, test::null_stream()};
StreamSwap cerr_swap{std::cerr, test::null_stream()};
test_util::StreamSwap cout_swap{std::cout, test_util::null_stream()};
test_util::StreamSwap cerr_swap{std::cerr, test_util::null_stream()};

SECTION("LogBuffer stores nothing for verbosity higher than default") {
check_log_empty<Level::kDebug>();
Expand All @@ -94,14 +83,14 @@ TEST_CASE("LogBuffer", "[silkworm][common][log]") {
}

SECTION("LogBuffer stores nothing for verbosity higher than configured one") {
test::SetLogVerbosityGuard guard{Level::kWarning};
test_util::SetLogVerbosityGuard guard{Level::kWarning};
check_log_empty<Level::kInfo>();
check_log_empty<Level::kDebug>();
check_log_empty<Level::kTrace>();
}

SECTION("LogBuffer stores content for verbosity lower than or equal to configured one") {
test::SetLogVerbosityGuard guard{Level::kWarning};
test_util::SetLogVerbosityGuard guard{Level::kWarning};
check_log_not_empty<Level::kWarning>();
check_log_not_empty<Level::kError>();
check_log_not_empty<Level::kCritical>();
Expand Down
58 changes: 22 additions & 36 deletions silkworm/infra/concurrency/awaitable_condition_variable_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,87 +19,73 @@
#include <chrono>
#include <future>

#include <boost/asio/co_spawn.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/use_future.hpp>
#include <catch2/catch.hpp>

#include <silkworm/infra/test_util/task_runner.hpp>

namespace silkworm::concurrency {

using namespace boost::asio;
using namespace std::chrono_literals;

template <typename TResult>
static void poll_context_until_future_is_ready(io_context& context, std::future<TResult>& future) {
while (future.wait_for(0s) != std::future_status::ready) {
context.poll_one();
}
}

template <typename TResult>
static TResult run(io_context& context, awaitable<TResult> awaitable1) {
auto task = co_spawn(context, std::move(awaitable1), use_future);
poll_context_until_future_is_ready(context, task);
return task.get();
}

TEST_CASE("AwaitableConditionVariable.not_blocking_when_notified_before_waiting") {
io_context context;
test_util::TaskRunner runner;
AwaitableConditionVariable cond_var;
auto waiter = cond_var.waiter();

cond_var.notify_all();
run(context, waiter());
runner.run(waiter());
}

TEST_CASE("AwaitableConditionVariable.blocks_during_waiting") {
io_context context;
using namespace std::chrono_literals;

test_util::TaskRunner runner;
AwaitableConditionVariable cond_var;
auto waiter = cond_var.waiter();

// schedule waiting
auto task = co_spawn(context, waiter(), use_future);
auto future = runner.spawn_future(waiter());
// run until it blocks
while (context.poll_one() > 0) {
while (runner.context().poll_one() > 0) {
}

CHECK(task.wait_for(0s) == std::future_status::timeout);
CHECK(future.wait_for(0s) == std::future_status::timeout);
}

TEST_CASE("AwaitableConditionVariable.notify_all_awakes_waiter") {
io_context context;
test_util::TaskRunner runner;
AwaitableConditionVariable cond_var;
auto waiter = cond_var.waiter();

// schedule waiting
auto task = co_spawn(context, waiter(), use_future);
auto future = runner.spawn_future(waiter());
// run until it blocks
while (context.poll_one() > 0) {
while (runner.context().poll_one() > 0) {
}

cond_var.notify_all();
poll_context_until_future_is_ready(context, task);
runner.poll_context_until_future_is_ready(future);
}

TEST_CASE("AwaitableConditionVariable.notify_all_awakes_multiple_waiters") {
io_context context;
test_util::TaskRunner runner;
AwaitableConditionVariable cond_var;
auto waiter1 = cond_var.waiter();
auto waiter2 = cond_var.waiter();
auto waiter3 = cond_var.waiter();

// schedule waiting
auto task1 = co_spawn(context, waiter1(), use_future);
auto task2 = co_spawn(context, waiter2(), use_future);
auto task3 = co_spawn(context, waiter3(), use_future);
auto future1 = runner.spawn_future(waiter1());
auto future2 = runner.spawn_future(waiter2());
auto future3 = runner.spawn_future(waiter3());
// run until it blocks
while (context.poll_one() > 0) {
while (runner.context().poll_one() > 0) {
}

cond_var.notify_all();
poll_context_until_future_is_ready(context, task1);
poll_context_until_future_is_ready(context, task2);
poll_context_until_future_is_ready(context, task3);
runner.poll_context_until_future_is_ready(future1);
runner.poll_context_until_future_is_ready(future2);
runner.poll_context_until_future_is_ready(future3);
}

} // namespace silkworm::concurrency
8 changes: 4 additions & 4 deletions silkworm/infra/concurrency/context_pool_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
#include <catch2/catch.hpp>

#include <silkworm/infra/common/log.hpp>
#include <silkworm/infra/test/log.hpp>
#include <silkworm/infra/test_util/log.hpp>

namespace silkworm::concurrency {

// Exclude gRPC tests from sanitizer builds due to data race warnings inside gRPC library
#ifndef SILKWORM_SANITIZE
TEST_CASE("Context", "[silkworm][concurrency][server_context]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};
Context ctx{0};

SECTION("ServerContext") {
Expand Down Expand Up @@ -65,12 +65,12 @@ TEST_CASE("Context", "[silkworm][concurrency][server_context]") {
}

SECTION("print") {
CHECK_NOTHROW(test::null_stream() << ctx);
CHECK_NOTHROW(test_util::null_stream() << ctx);
}
}

TEST_CASE("ContextPool", "[silkworm][concurrency][Context]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};

SECTION("ContextPool OK") {
ContextPool context_pool{2};
Expand Down
20 changes: 4 additions & 16 deletions silkworm/infra/concurrency/timeout_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,19 @@
#include <exception>
#include <stdexcept>

#include <silkworm/infra/concurrency/coroutine.hpp>
#include <silkworm/infra/concurrency/task.hpp>

#include <boost/asio/awaitable.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/multiple_exceptions.hpp>
#include <boost/asio/this_coro.hpp>
#include <boost/asio/use_future.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/system/system_error.hpp>
#include <catch2/catch.hpp>

#include <silkworm/infra/concurrency/awaitable_wait_for_all.hpp>
#include <silkworm/infra/concurrency/awaitable_wait_for_one.hpp>
#include <silkworm/infra/test_util/task_runner.hpp>

namespace silkworm::concurrency {

Expand Down Expand Up @@ -94,17 +91,8 @@ awaitable<void> wait_until_cancelled_bad() {

template <typename TResult>
TResult run(awaitable<TResult> awaitable1) {
io_context context;
auto task = co_spawn(
context,
std::move(awaitable1),
boost::asio::use_future);

while (task.wait_for(0s) != std::future_status::ready) {
context.poll_one();
}

return task.get();
test_util::TaskRunner runner;
return runner.run(std::move(awaitable1));
}

TEST_CASE("Timeout.value") {
Expand Down
14 changes: 7 additions & 7 deletions silkworm/infra/grpc/client/client_context_pool_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <boost/asio/post.hpp>
#include <catch2/catch.hpp>

#include <silkworm/infra/test/log.hpp>
#include <silkworm/infra/test_util/log.hpp>

namespace silkworm::rpc {

Expand Down Expand Up @@ -72,13 +72,13 @@ TEST_CASE("ClientContext", "[silkworm][infra][grpc][client][client_context]") {
}

SECTION("print") {
CHECK_NOTHROW(test::null_stream() << context);
CHECK_NOTHROW(test_util::null_stream() << context);
}
}
}

TEST_CASE("ClientContextPool: create context pool", "[silkworm][infra][grpc][client][client_context]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};

SECTION("reject size 0") {
CHECK_THROWS_MATCHES((ClientContextPool{0}), std::logic_error,
Expand Down Expand Up @@ -121,7 +121,7 @@ TEST_CASE("ClientContextPool: create context pool", "[silkworm][infra][grpc][cli
}

TEST_CASE("ClientContextPool: start context pool", "[silkworm][infra][grpc][client][client_context]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};

SECTION("running 1 thread") {
ClientContextPool cp{1};
Expand All @@ -139,7 +139,7 @@ TEST_CASE("ClientContextPool: start context pool", "[silkworm][infra][grpc][clie
}

TEST_CASE("ClientContextPool: run context pool", "[silkworm][infra][grpc][client][client_context]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};

SECTION("running 1 thread") {
ClientContextPool cp{1};
Expand Down Expand Up @@ -168,7 +168,7 @@ TEST_CASE("ClientContextPool: run context pool", "[silkworm][infra][grpc][client
}

TEST_CASE("ClientContextPool: stop context pool", "[silkworm][infra][grpc][client][client_context]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};

SECTION("not yet running") {
ClientContextPool cp{3};
Expand All @@ -194,7 +194,7 @@ TEST_CASE("ClientContextPool: stop context pool", "[silkworm][infra][grpc][clien
}

TEST_CASE("ClientContextPool: cannot restart context pool", "[silkworm][infra][grpc][client][client_context]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};

SECTION("running 1 thread") {
ClientContextPool cp{1};
Expand Down
4 changes: 2 additions & 2 deletions silkworm/infra/grpc/common/util_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <catch2/catch.hpp>

#include <silkworm/infra/common/log.hpp>
#include <silkworm/infra/test/log.hpp>
#include <silkworm/infra/test_util/log.hpp>

namespace silkworm::rpc {

Expand Down Expand Up @@ -72,7 +72,7 @@ TEST_CASE("GrpcLogGuard", "[silkworm][rpc][util]") {
}

TEST_CASE("gpr_silkworm_log", "[silkworm][rpc][util]") {
test::SetLogVerbosityGuard guard{log::Level::kNone};
test_util::SetLogVerbosityGuard guard{log::Level::kNone};
const char* FILE_NAME{"file.cpp"};
const int LINE_NUMBER{10};
Grpc2SilkwormLogGuard log_guard;
Expand Down
Loading

0 comments on commit 1c59386

Please sign in to comment.