Skip to content

Commit adc984a

Browse files
authored
rpcdaemon: refactoring ContextTestBase as infra test utility (#2127)
1 parent 7c1720b commit adc984a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+217
-141
lines changed

cmd/benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_executable(benchmark_test benchmark_test.cpp ${SILKWORM_BENCHMARK_TESTS})
2121
target_link_libraries(
2222
benchmark_test
2323
silkworm_infra
24+
silkworm_infra_test_util
2425
silkworm_node
2526
silkworm_rpcdaemon
2627
silkworm_rpcdaemon_test_util

silkworm/core/common/base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ using BlockNum = uint64_t;
5050
using BlockNumRange = std::pair<BlockNum, BlockNum>;
5151
using BlockTime = uint64_t;
5252

53+
inline constexpr BlockNum kEarliestBlockNumber{0ul};
54+
5355
inline constexpr size_t kAddressLength{20};
5456

5557
inline constexpr size_t kHashLength{32};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
Copyright 2023 The Silkworm Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "context_test_base.hpp"
18+
19+
namespace silkworm::test_util {
20+
21+
ContextTestBase::ContextTestBase()
22+
: log_guard_{log::Level::kNone},
23+
context_{0},
24+
io_context_{*context_.io_context()},
25+
grpc_context_{*context_.grpc_context()},
26+
context_thread_{[&]() { context_.execute_loop(); }} {}
27+
28+
ContextTestBase::~ContextTestBase() {
29+
context_.stop();
30+
if (context_thread_.joinable()) {
31+
context_thread_.join();
32+
}
33+
}
34+
35+
} // namespace silkworm::test_util

silkworm/rpc/test_util/context_test_base.hpp renamed to silkworm/infra/test_util/context_test_base.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include <silkworm/infra/grpc/client/client_context_pool.hpp>
2828
#include <silkworm/infra/test_util/log.hpp>
2929

30-
namespace silkworm::rpc::test {
30+
namespace silkworm::test_util {
3131

3232
class ContextTestBase {
3333
public:
@@ -50,10 +50,10 @@ class ContextTestBase {
5050
~ContextTestBase();
5151

5252
silkworm::test_util::SetLogVerbosityGuard log_guard_;
53-
ClientContext context_;
53+
rpc::ClientContext context_;
5454
boost::asio::io_context& io_context_;
5555
agrpc::GrpcContext& grpc_context_;
5656
std::thread context_thread_;
5757
};
5858

59-
} // namespace silkworm::rpc::test
59+
} // namespace silkworm::test_util

silkworm/rpc/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,6 @@ silkworm_library(
5959
PRIVATE ${SILKWORM_RPCDAEMON_PRIVATE_LIBRARIES}
6060
)
6161

62-
target_link_libraries(silkworm_rpcdaemon_test PRIVATE silkworm_rpcdaemon_test_util GTest::gmock)
62+
target_link_libraries(
63+
silkworm_rpcdaemon_test PRIVATE silkworm_infra_test_util silkworm_rpcdaemon_test_util GTest::gmock
64+
)

silkworm/rpc/commands/engine_api_test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ class EngineRpcApi_ForTest : public EngineRpcApi {
106106
using testing::_;
107107
using testing::InvokeWithoutArgs;
108108

109-
struct EngineRpcApiTest : public test::JsonApiTestBase<EngineRpcApi_ForTest> {
110-
EngineRpcApiTest() : test::JsonApiTestBase<EngineRpcApi_ForTest>() {
109+
struct EngineRpcApiTest : public test_util::JsonApiTestBase<EngineRpcApi_ForTest> {
110+
EngineRpcApiTest() : test_util::JsonApiTestBase<EngineRpcApi_ForTest>() {
111111
add_private_service<ethdb::Database>(io_context_, std::make_unique<DummyDatabase>(mock_cursor));
112112
add_shared_service<engine::ExecutionEngine>(io_context_, mock_engine);
113113
add_private_service<ethbackend::BackEnd>(io_context_, std::make_unique<test::BackEndMock>());
114114
}
115115

116-
std::shared_ptr<test::ExecutionEngineMock> mock_engine{std::make_shared<test::ExecutionEngineMock>()};
116+
std::shared_ptr<test_util::ExecutionEngineMock> mock_engine{std::make_shared<test_util::ExecutionEngineMock>()};
117117
std::shared_ptr<test::MockCursor> mock_cursor{std::make_shared<test::MockCursor>()};
118118
};
119119

silkworm/rpc/commands/erigon_api.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <intx/intx.hpp>
2424

25+
#include <silkworm/core/common/base.hpp>
2526
#include <silkworm/core/common/util.hpp>
2627
#include <silkworm/core/protocol/ethash_rule_set.hpp>
2728
#include <silkworm/core/types/evmc_bytes32.hpp>
@@ -127,7 +128,7 @@ Task<void> ErigonRpcApi::handle_erigon_get_block_by_timestamp(const nlohmann::js
127128
const auto chain_storage = tx->create_storage();
128129

129130
// Lookup the first and last block headers
130-
const auto first_header = co_await chain_storage->read_canonical_header(core::kEarliestBlockNumber);
131+
const auto first_header = co_await chain_storage->read_canonical_header(kEarliestBlockNumber);
131132
const auto head_header_hash = co_await core::rawdb::read_head_header_hash(*tx);
132133
const auto header_header_block_number = co_await chain_storage->read_block_number(head_header_hash);
133134
const auto current_header = co_await chain_storage->read_header(*header_header_block_number, head_header_hash);
@@ -138,7 +139,7 @@ Task<void> ErigonRpcApi::handle_erigon_get_block_by_timestamp(const nlohmann::js
138139
if (current_header->timestamp <= timestamp) {
139140
block_number = current_block_number;
140141
} else if (first_header->timestamp >= timestamp) {
141-
block_number = core::kEarliestBlockNumber;
142+
block_number = kEarliestBlockNumber;
142143
} else {
143144
// Good-old binary search to find the lowest block header matching timestamp
144145
auto matching_block_number = co_await binary_search(current_block_number, [&](uint64_t bn) -> Task<bool> {

silkworm/rpc/commands/erigon_api_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class ErigonRpcApi_ForTest : public ErigonRpcApi {
5252
}
5353
};
5454

55-
using ErigonRpcApiTest = test::JsonApiTestBase<ErigonRpcApi_ForTest>;
55+
using ErigonRpcApiTest = test_util::JsonApiTestBase<ErigonRpcApi_ForTest>;
5656

5757
#ifndef SILKWORM_SANITIZE
5858
TEST_CASE_METHOD(ErigonRpcApiTest, "ErigonRpcApi::handle_erigon_get_block_by_timestamp", "[rpc][erigon_api]") {

silkworm/rpc/commands/eth_api_test.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,97 +24,97 @@
2424
namespace silkworm::rpc::commands {
2525

2626
#ifndef SILKWORM_SANITIZE
27-
TEST_CASE_METHOD(test::RpcApiE2ETest, "unit: eth_blockNumber succeeds if request well-formed", "[rpc][api]") {
27+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "unit: eth_blockNumber succeeds if request well-formed", "[rpc][api]") {
2828
const auto request = R"({"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]})"_json;
2929
std::string reply;
30-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
30+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
3131
CHECK(nlohmann::json::parse(reply) == R"({
3232
"jsonrpc":"2.0",
3333
"id":1,
3434
"result":"0x9"
3535
})"_json);
3636
}
3737

38-
TEST_CASE_METHOD(test::RpcApiE2ETest, "unit: eth_blockNumber fails if request empty", "[rpc][api]") {
38+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "unit: eth_blockNumber fails if request empty", "[rpc][api]") {
3939
const auto request = R"({})"_json;
4040
std::string reply;
41-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
41+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
4242
CHECK(nlohmann::json::parse(reply) == R"({
4343
"jsonrpc":"2.0",
4444
"id":null,
4545
"error":{"code":-32600,"message":"invalid request"}
4646
})"_json);
4747
}
4848

49-
TEST_CASE_METHOD(test::RpcApiE2ETest, "unit: eth_sendRawTransaction fails rlp parsing", "[rpc][api]") {
49+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "unit: eth_sendRawTransaction fails rlp parsing", "[rpc][api]") {
5050
const auto request = R"({
5151
"jsonrpc": "2.0",
5252
"id": 1,
5353
"method": "eth_sendRawTransaction",
5454
"params": ["0xd46ed67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f0724456"]
5555
})"_json;
5656
std::string reply;
57-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
57+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
5858
CHECK(nlohmann::json::parse(reply) == R"({
5959
"jsonrpc":"2.0",
6060
"id":1,
6161
"error":{"code":-32000,"message":"rlp: input exceeds encoded length"}
6262
})"_json);
6363
}
6464

65-
TEST_CASE_METHOD(test::RpcApiE2ETest, "unit: eth_sendRawTransaction fails wrong number digit", "[rpc][api]") {
65+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "unit: eth_sendRawTransaction fails wrong number digit", "[rpc][api]") {
6666
const auto request = R"({
6767
"jsonrpc": "2.0",
6868
"id": 1,
6969
"method": "eth_sendRawTransaction",
7070
"params": ["0xd46ed67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445"]
7171
})"_json;
7272
std::string reply;
73-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
73+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
7474
CHECK(nlohmann::json::parse(reply) == R"({
7575
"jsonrpc":"2.0",
7676
"id":1,
7777
"error":{"code":-32000,"message":"rlp: unexpected EIP-2178 serialization"}
7878
})"_json);
7979
}
8080

81-
TEST_CASE_METHOD(test::RpcApiE2ETest, "unit: eth_feeHistory succeeds if request well-formed", "[rpc][api]") {
81+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "unit: eth_feeHistory succeeds if request well-formed", "[rpc][api]") {
8282
const auto request = R"({"jsonrpc":"2.0","id":1,"method":"eth_feeHistory","params":["0x1","0x867A80",[25,75]]})"_json;
8383
std::string reply;
84-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
84+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
8585
CHECK(nlohmann::json::parse(reply) == R"({
8686
"jsonrpc":"2.0",
8787
"id":1,
8888
"result":{"gasUsedRatio":null,"oldestBlock":"0x0"}
8989
})"_json);
9090
}
9191

92-
TEST_CASE_METHOD(test::RpcApiE2ETest, "fuzzy: eth_call invalid params", "[rpc][api]") {
92+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "fuzzy: eth_call invalid params", "[rpc][api]") {
9393
const auto request = R"({"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{}, "latest"]})"_json;
9494
std::string reply;
95-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
95+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
9696
CHECK(nlohmann::json::parse(reply) == R"({
9797
"jsonrpc":"2.0",
9898
"id":1,
9999
"error":{"code":-32000,"message":"insufficient funds for gas * price + value: address 0x0000000000000000000000000000000000000000 have 0 want 15240199550000000"}
100100
})"_json);
101101
}
102102

103-
TEST_CASE_METHOD(test::RpcApiE2ETest, "fuzzy: eth_feeHistory sigsegv invalid input", "[rpc][api]") {
103+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "fuzzy: eth_feeHistory sigsegv invalid input", "[rpc][api]") {
104104
const auto request = R"({"jsonrpc":"2.0","id":1,"method":"eth_feeHistory","params":["5x1","0x2",[95,99]]})"_json;
105105
std::string reply;
106-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
106+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
107107
CHECK(nlohmann::json::parse(reply) == R"({
108108
"jsonrpc":"2.0",
109109
"id":1,
110110
"error":{"code":100,"message":"invalid block_count: 5x1"}
111111
})"_json);
112112
}
113113

114-
TEST_CASE_METHOD(test::RpcApiE2ETest, "fuzzy: eth_feeHistory sigsegv valid input", "[rpc][api]") {
114+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "fuzzy: eth_feeHistory sigsegv valid input", "[rpc][api]") {
115115
const auto request = R"({"jsonrpc":"2.0","id":1,"method":"eth_feeHistory","params":["0x5","0x2",[95,99]]})"_json;
116116
std::string reply;
117-
run<&test::RequestHandler_ForTest::request_and_create_reply>(request, reply);
117+
run<&test_util::RequestHandler_ForTest::request_and_create_reply>(request, reply);
118118
CHECK(nlohmann::json::parse(reply) == R"({
119119
"jsonrpc":"2.0",
120120
"id":1,

silkworm/rpc/commands/parity_api_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
namespace silkworm::rpc::commands {
2323

2424
#ifndef SILKWORM_SANITIZE
25-
TEST_CASE_METHOD(test::RpcApiE2ETest, "parity_getBlockReceipts: misnamed 'params' field", "[rpc][api]") {
25+
TEST_CASE_METHOD(test_util::RpcApiE2ETest, "parity_getBlockReceipts: misnamed 'params' field", "[rpc][api]") {
2626
const auto request = R"({"jsonrpc":"2.0","id":1,"method":"parity_getBlockReceipts","pirams":["0x0"]})";
2727
std::string reply;
28-
run<&test::RequestHandler_ForTest::handle_request>(request, reply);
28+
run<&test_util::RequestHandler_ForTest::handle_request>(request, reply);
2929
CHECK(nlohmann::json::parse(reply) == R"({
3030
"jsonrpc":"2.0",
3131
"id":1,

silkworm/rpc/commands/rpc_api_test.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929

3030
namespace silkworm::rpc::commands {
3131

32+
using silkworm::test_util::SetLogVerbosityGuard;
33+
using test_util::RequestHandler_ForTest;
34+
using test_util::RpcApiTestBase;
35+
3236
// Function to recursively sort JSON arrays
3337
void sort_array(nlohmann::json& jsonObj) { // NOLINT(*-no-recursion)
3438
if (jsonObj.is_array()) {
@@ -81,7 +85,7 @@ static const std::vector<std::string> subtests_to_ignore = {
8185
// Exclude tests from sanitizer builds due to ASAN/TSAN warnings inside gRPC library
8286
#ifndef SILKWORM_SANITIZE
8387
TEST_CASE("rpc_api io (all files)", "[rpc][rpc_api]") {
84-
test_util::SetLogVerbosityGuard log_guard{log::Level::kNone};
88+
SetLogVerbosityGuard log_guard{log::Level::kNone};
8589
auto tests_dir = db::test_util::get_tests_dir();
8690
for (const auto& test_file : std::filesystem::recursive_directory_iterator(tests_dir)) {
8791
if (!test_file.is_directory() && test_file.path().extension() == ".io") {
@@ -104,7 +108,7 @@ TEST_CASE("rpc_api io (all files)", "[rpc][rpc_api]") {
104108

105109
SECTION("RPC IO test " + group_name + " | " + test_name) { // NOLINT(*-inefficient-string-concatenation)
106110
auto context = db::test_util::TestDatabaseContext();
107-
test::RpcApiTestBase<test::RequestHandler_ForTest> test_base{context.get_mdbx_env()};
111+
RpcApiTestBase<RequestHandler_ForTest> test_base{context.get_mdbx_env()};
108112

109113
std::string line_out;
110114
std::string line_in;
@@ -118,7 +122,7 @@ TEST_CASE("rpc_api io (all files)", "[rpc][rpc_api]") {
118122
auto expected = nlohmann::json::parse(line_in.substr(3));
119123

120124
std::string response;
121-
test_base.run<&test::RequestHandler_ForTest::request_and_create_reply>(request, response);
125+
test_base.run<&RequestHandler_ForTest::request_and_create_reply>(request, response);
122126
INFO("Request: " << request.dump());
123127
INFO("Actual response: " << response);
124128
INFO("Expected response: " << expected.dump());
@@ -135,15 +139,15 @@ TEST_CASE("rpc_api io (all files)", "[rpc][rpc_api]") {
135139
}
136140

137141
TEST_CASE("rpc_api io (individual)", "[rpc][rpc_api][ignore]") {
138-
test_util::SetLogVerbosityGuard log_guard{log::Level::kNone};
142+
SetLogVerbosityGuard log_guard{log::Level::kNone};
139143
auto context = db::test_util::TestDatabaseContext();
140-
test::RpcApiTestBase<test::RequestHandler_ForTest> test_base{context.get_mdbx_env()};
144+
RpcApiTestBase<RequestHandler_ForTest> test_base{context.get_mdbx_env()};
141145

142146
SECTION("sample test") {
143147
auto request = R"({"jsonrpc":"2.0","id":1,"method":"debug_getRawTransaction","params":["0x74e41d593675913d6d5521f46523f1bd396dff1891bdb35f59be47c7e5e0b34b"]})"_json;
144148
std::string response;
145149

146-
test_base.run<&test::RequestHandler_ForTest::request_and_create_reply>(request, response);
150+
test_base.run<&RequestHandler_ForTest::request_and_create_reply>(request, response);
147151
CHECK(nlohmann::json::parse(response) == R"({"jsonrpc":"2.0","id":1,"result":"0xf8678084342770c182520894658bdf435d810c91414ec09147daa6db624063798203e880820a95a0af5fc351b9e457a31f37c84e5cd99dd3c5de60af3de33c6f4160177a2c786a60a0201da7a21046af55837330a2c52fc1543cd4d9ead00ddf178dd96935b607ff9b"})"_json);
148152
}
149153
}

silkworm/rpc/common/async_task_benchmark.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <benchmark/benchmark.h>
1818

1919
#include <silkworm/rpc/common/worker_pool.hpp>
20-
#include <silkworm/rpc/test_util/context_test_base.hpp>
20+
#include <silkworm/rpc/test_util/service_context_test_base.hpp>
2121

2222
#include "async_task.hpp"
2323

@@ -27,7 +27,7 @@ std::size_t recursive_factorial(std::size_t n) {
2727
return n == 0 ? 1 : n * recursive_factorial(n - 1);
2828
}
2929

30-
struct AsyncTaskBenchTest : test::ContextTestBase {
30+
struct AsyncTaskBenchTest : test_util::ServiceContextTestBase {
3131
};
3232

3333
template <typename Executor>

silkworm/rpc/common/async_task_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
#include <catch2/catch_test_macros.hpp>
2323

2424
#include <silkworm/rpc/common/worker_pool.hpp>
25-
#include <silkworm/rpc/test_util/context_test_base.hpp>
25+
#include <silkworm/rpc/test_util/service_context_test_base.hpp>
2626

2727
namespace silkworm::rpc {
2828

29-
struct AsyncTaskTest : test::ContextTestBase {
29+
struct AsyncTaskTest : test_util::ServiceContextTestBase {
3030
};
3131

3232
const static std::vector<std::pair<std::size_t, std::size_t>> kTestData = {

silkworm/rpc/common/binary_search_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121

2222
#include <catch2/catch_test_macros.hpp>
2323

24-
#include <silkworm/rpc/test_util/context_test_base.hpp>
24+
#include <silkworm/rpc/test_util/service_context_test_base.hpp>
2525

2626
namespace silkworm::rpc {
2727

28-
struct BinarySearchTest : test::ContextTestBase {
28+
struct BinarySearchTest : test_util::ServiceContextTestBase {
2929
};
3030

3131
struct BinaryTestData {

silkworm/rpc/core/blocks.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ constexpr const char* kFinalizedBlockId{"finalized"};
3333
constexpr const char* kSafeBlockId{"safe"};
3434
constexpr const char* kLatestExecutedBlockId{"latestExecuted"};
3535

36-
constexpr BlockNum kEarliestBlockNumber{0ul};
37-
3836
// TODO(canepat) migrate to ChainStorage?
3937

4038
Task<bool> is_latest_block_number(BlockNum block_number, ethdb::Transaction& tx);

silkworm/rpc/core/estimate_gas_oracle_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
namespace silkworm::rpc {
4141

42-
struct RemoteDatabaseTest : test::KVTestBase {
42+
struct RemoteDatabaseTest : test_util::KVTestBase {
4343
public:
4444
// RemoteDatabase holds the KV stub by std::unique_ptr, so we cannot rely on mock stub from base class
4545
StrictMockKVStub* kv_stub_ = new StrictMockKVStub;

0 commit comments

Comments
 (0)