Moving rpc_test utility functions to a separate common.hpp/common.cpp file
This commit is contained in:
parent
cdbed5eacc
commit
971fc27cd7
4 changed files with 249 additions and 158 deletions
|
@ -1,4 +1,4 @@
|
|||
add_executable(rpc_test entry.cpp rpc.cpp)
|
||||
add_executable(rpc_test common.hpp common.cpp entry.cpp rpc.cpp)
|
||||
|
||||
target_link_libraries(rpc_test node secure rpc test_common gtest)
|
||||
|
||||
|
|
172
nano/rpc_test/common.cpp
Normal file
172
nano/rpc_test/common.cpp
Normal file
|
@ -0,0 +1,172 @@
|
|||
#include <nano/rpc_test/common.hpp>
|
||||
#include <nano/lib/threading.hpp>
|
||||
#include <nano/node/ipc/ipc_server.hpp>
|
||||
#include <nano/node/transport/tcp.hpp>
|
||||
#include <nano/rpc/rpc_request_processor.hpp>
|
||||
#include <nano/test_common/system.hpp>
|
||||
#include <nano/test_common/testutil.hpp>
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class rpc;
|
||||
|
||||
nano::test::test_response::test_response (boost::property_tree::ptree const & request_a, boost::asio::io_context & io_ctx_a) :
|
||||
request (request_a),
|
||||
sock (io_ctx_a)
|
||||
{
|
||||
}
|
||||
|
||||
nano::test::test_response::test_response (boost::property_tree::ptree const & request_a, uint16_t port_a, boost::asio::io_context & io_ctx_a) :
|
||||
request (request_a),
|
||||
sock (io_ctx_a)
|
||||
{
|
||||
run (port_a);
|
||||
}
|
||||
|
||||
void nano::test::test_response::run (uint16_t port_a)
|
||||
{
|
||||
sock.async_connect (nano::tcp_endpoint (boost::asio::ip::address_v6::loopback (), port_a), [this] (boost::system::error_code const & ec) {
|
||||
if (!ec)
|
||||
{
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, request);
|
||||
req.method (boost::beast::http::verb::post);
|
||||
req.target ("/");
|
||||
req.version (11);
|
||||
ostream.flush ();
|
||||
req.body () = ostream.str ();
|
||||
req.prepare_payload ();
|
||||
boost::beast::http::async_write (sock, req, [this] (boost::system::error_code const & ec, size_t bytes_transferred) {
|
||||
if (!ec)
|
||||
{
|
||||
boost::beast::http::async_read (sock, sb, resp, [this] (boost::system::error_code const & ec, size_t bytes_transferred) {
|
||||
if (!ec)
|
||||
{
|
||||
std::stringstream body (resp.body ());
|
||||
try
|
||||
{
|
||||
boost::property_tree::read_json (body, json);
|
||||
status = 200;
|
||||
}
|
||||
catch (std::exception &)
|
||||
{
|
||||
status = 500;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 400;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 600;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 400;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
nano::test::scoped_io_thread_name_change::scoped_io_thread_name_change ()
|
||||
{
|
||||
renew ();
|
||||
}
|
||||
|
||||
nano::test::scoped_io_thread_name_change::~scoped_io_thread_name_change ()
|
||||
{
|
||||
reset ();
|
||||
}
|
||||
|
||||
void nano::test::scoped_io_thread_name_change::reset ()
|
||||
{
|
||||
nano::thread_role::set (nano::thread_role::name::unknown);
|
||||
}
|
||||
|
||||
void nano::test::scoped_io_thread_name_change::renew ()
|
||||
{
|
||||
nano::thread_role::set (nano::thread_role::name::io);
|
||||
}
|
||||
|
||||
nano::test::rpc_context::rpc_context (std::shared_ptr<nano::rpc> & rpc_a, std::unique_ptr<nano::ipc::ipc_server> & ipc_server_a, std::unique_ptr<nano::ipc_rpc_processor> & ipc_rpc_processor_a, std::unique_ptr<nano::node_rpc_config> & node_rpc_config_a, std::unique_ptr<scoped_io_thread_name_change> & io_scope_a)
|
||||
{
|
||||
rpc = std::move (rpc_a);
|
||||
ipc_server = std::move (ipc_server_a);
|
||||
ipc_rpc_processor = std::move (ipc_rpc_processor_a);
|
||||
node_rpc_config = std::move (node_rpc_config_a);
|
||||
io_scope = std::move (io_scope_a);
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::node> nano::test::add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config, nano::node_flags const & node_flags)
|
||||
{
|
||||
node_config.ipc_config.transport_tcp.enabled = true;
|
||||
node_config.ipc_config.transport_tcp.port = nano::test::get_available_port ();
|
||||
return system.add_node (node_config, node_flags);
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::node> nano::test::add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config)
|
||||
{
|
||||
return add_ipc_enabled_node (system, node_config, nano::node_flags ());
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::node> nano::test::add_ipc_enabled_node (nano::test::system & system)
|
||||
{
|
||||
nano::node_config node_config (nano::test::get_available_port (), system.logging);
|
||||
return add_ipc_enabled_node (system, node_config);
|
||||
}
|
||||
|
||||
void nano::test::reset_confirmation_height (nano::store & store, nano::account const & account)
|
||||
{
|
||||
auto transaction = store.tx_begin_write ();
|
||||
nano::confirmation_height_info confirmation_height_info;
|
||||
if (!store.confirmation_height.get (transaction, account, confirmation_height_info))
|
||||
{
|
||||
store.confirmation_height.clear (transaction, account);
|
||||
}
|
||||
}
|
||||
|
||||
void nano::test::wait_response_impl (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time, boost::property_tree::ptree & response_json)
|
||||
{
|
||||
test_response response (request, rpc_ctx.rpc->listening_port (), system.io_ctx);
|
||||
ASSERT_TIMELY (time, response.status != 0);
|
||||
ASSERT_EQ (200, response.status);
|
||||
response_json = response.json;
|
||||
}
|
||||
|
||||
boost::property_tree::ptree nano::test::wait_response (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time)
|
||||
{
|
||||
boost::property_tree::ptree response_json;
|
||||
wait_response_impl (system, rpc_ctx, request, time, response_json);
|
||||
return response_json;
|
||||
}
|
||||
|
||||
bool nano::test::check_block_response_count (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, uint64_t size_count)
|
||||
{
|
||||
auto response (wait_response (system, rpc_ctx, request));
|
||||
auto & blocks = response.get_child ("blocks");
|
||||
return size_count == blocks.size ();
|
||||
}
|
||||
|
||||
nano::test::rpc_context nano::test::add_rpc (nano::test::system & system, std::shared_ptr<nano::node> const & node_a)
|
||||
{
|
||||
auto scoped_thread_name_io (std::make_unique<scoped_io_thread_name_change> ());
|
||||
auto node_rpc_config (std::make_unique<nano::node_rpc_config> ());
|
||||
auto ipc_server (std::make_unique<nano::ipc::ipc_server> (*node_a, *node_rpc_config));
|
||||
nano::rpc_config rpc_config (node_a->network_params.network, nano::test::get_available_port (), true);
|
||||
const auto ipc_tcp_port = ipc_server->listening_tcp_port ();
|
||||
debug_assert (ipc_tcp_port.has_value ());
|
||||
auto ipc_rpc_processor (std::make_unique<nano::ipc_rpc_processor> (system.io_ctx, rpc_config, ipc_tcp_port.value ()));
|
||||
auto rpc (std::make_shared<nano::rpc> (system.io_ctx, rpc_config, *ipc_rpc_processor));
|
||||
rpc->start ();
|
||||
|
||||
return rpc_context{ rpc, ipc_server, ipc_rpc_processor, node_rpc_config, scoped_thread_name_io };
|
||||
}
|
||||
}
|
74
nano/rpc_test/common.hpp
Normal file
74
nano/rpc_test/common.hpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/beast/core/flat_buffer.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class ipc_rpc_processor;
|
||||
class node;
|
||||
class node_config;
|
||||
class node_flags;
|
||||
class node_rpc_config;
|
||||
class public_key;
|
||||
class rpc;
|
||||
class store;
|
||||
|
||||
using account = public_key;
|
||||
namespace ipc
|
||||
{
|
||||
class ipc_server;
|
||||
}
|
||||
namespace test
|
||||
{
|
||||
class system;
|
||||
class scoped_io_thread_name_change
|
||||
{
|
||||
public:
|
||||
scoped_io_thread_name_change ();
|
||||
~scoped_io_thread_name_change ();
|
||||
void reset ();
|
||||
void renew ();
|
||||
};
|
||||
class test_response
|
||||
{
|
||||
public:
|
||||
test_response (boost::property_tree::ptree const & request_a, boost::asio::io_context & io_ctx_a);
|
||||
test_response (boost::property_tree::ptree const & request_a, uint16_t port_a, boost::asio::io_context & io_ctx_a);
|
||||
void run (uint16_t port_a);
|
||||
boost::property_tree::ptree const & request;
|
||||
boost::asio::ip::tcp::socket sock;
|
||||
boost::property_tree::ptree json;
|
||||
boost::beast::flat_buffer sb;
|
||||
boost::beast::http::request<boost::beast::http::string_body> req;
|
||||
boost::beast::http::response<boost::beast::http::string_body> resp;
|
||||
std::atomic<int> status{ 0 };
|
||||
};
|
||||
class rpc_context
|
||||
{
|
||||
public:
|
||||
rpc_context (std::shared_ptr<nano::rpc> & rpc_a, std::unique_ptr<nano::ipc::ipc_server> & ipc_server_a, std::unique_ptr<nano::ipc_rpc_processor> & ipc_rpc_processor_a, std::unique_ptr<nano::node_rpc_config> & node_rpc_config_a, std::unique_ptr<scoped_io_thread_name_change> & io_scope_a);
|
||||
|
||||
std::shared_ptr<nano::rpc> rpc;
|
||||
std::unique_ptr<nano::ipc::ipc_server> ipc_server;
|
||||
std::unique_ptr<nano::ipc_rpc_processor> ipc_rpc_processor;
|
||||
std::unique_ptr<nano::node_rpc_config> node_rpc_config;
|
||||
std::unique_ptr<scoped_io_thread_name_change> io_scope;
|
||||
};
|
||||
|
||||
std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config, nano::node_flags const & node_flags);
|
||||
std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config);
|
||||
std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system);
|
||||
void reset_confirmation_height (nano::store & store, nano::account const & account);
|
||||
void wait_response_impl (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time, boost::property_tree::ptree & response_json);
|
||||
boost::property_tree::ptree wait_response (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time = 5s);
|
||||
bool check_block_response_count (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, uint64_t size_count);
|
||||
rpc_context add_rpc (nano::test::system & system, std::shared_ptr<nano::node> const & node_a);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
#include <nano/node/node_rpc_config.hpp>
|
||||
#include <nano/rpc/rpc.hpp>
|
||||
#include <nano/rpc/rpc_request_processor.hpp>
|
||||
#include <nano/rpc_test/common.hpp>
|
||||
#include <nano/test_common/network.hpp>
|
||||
#include <nano/test_common/system.hpp>
|
||||
#include <nano/test_common/telemetry.hpp>
|
||||
|
@ -22,163 +23,7 @@
|
|||
#include <utility>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
class test_response
|
||||
{
|
||||
public:
|
||||
test_response (boost::property_tree::ptree const & request_a, boost::asio::io_context & io_ctx_a) :
|
||||
request (request_a),
|
||||
sock (io_ctx_a)
|
||||
{
|
||||
}
|
||||
|
||||
test_response (boost::property_tree::ptree const & request_a, uint16_t port_a, boost::asio::io_context & io_ctx_a) :
|
||||
request (request_a),
|
||||
sock (io_ctx_a)
|
||||
{
|
||||
run (port_a);
|
||||
}
|
||||
|
||||
void run (uint16_t port_a)
|
||||
{
|
||||
sock.async_connect (nano::tcp_endpoint (boost::asio::ip::address_v6::loopback (), port_a), [this] (boost::system::error_code const & ec) {
|
||||
if (!ec)
|
||||
{
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, request);
|
||||
req.method (boost::beast::http::verb::post);
|
||||
req.target ("/");
|
||||
req.version (11);
|
||||
ostream.flush ();
|
||||
req.body () = ostream.str ();
|
||||
req.prepare_payload ();
|
||||
boost::beast::http::async_write (sock, req, [this] (boost::system::error_code const & ec, size_t bytes_transferred) {
|
||||
if (!ec)
|
||||
{
|
||||
boost::beast::http::async_read (sock, sb, resp, [this] (boost::system::error_code const & ec, size_t bytes_transferred) {
|
||||
if (!ec)
|
||||
{
|
||||
std::stringstream body (resp.body ());
|
||||
try
|
||||
{
|
||||
boost::property_tree::read_json (body, json);
|
||||
status = 200;
|
||||
}
|
||||
catch (std::exception &)
|
||||
{
|
||||
status = 500;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 400;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 600;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 400;
|
||||
}
|
||||
});
|
||||
}
|
||||
boost::property_tree::ptree const & request;
|
||||
boost::asio::ip::tcp::socket sock;
|
||||
boost::property_tree::ptree json;
|
||||
boost::beast::flat_buffer sb;
|
||||
boost::beast::http::request<boost::beast::http::string_body> req;
|
||||
boost::beast::http::response<boost::beast::http::string_body> resp;
|
||||
std::atomic<int> status{ 0 };
|
||||
};
|
||||
|
||||
class rpc_context
|
||||
{
|
||||
public:
|
||||
rpc_context (std::shared_ptr<nano::rpc> & rpc_a, std::unique_ptr<nano::ipc::ipc_server> & ipc_server_a, std::unique_ptr<nano::ipc_rpc_processor> & ipc_rpc_processor_a, std::unique_ptr<nano::node_rpc_config> & node_rpc_config_a)
|
||||
{
|
||||
rpc = std::move (rpc_a);
|
||||
ipc_server = std::move (ipc_server_a);
|
||||
ipc_rpc_processor = std::move (ipc_rpc_processor_a);
|
||||
node_rpc_config = std::move (node_rpc_config_a);
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::rpc> rpc;
|
||||
std::unique_ptr<nano::ipc::ipc_server> ipc_server;
|
||||
std::unique_ptr<nano::ipc_rpc_processor> ipc_rpc_processor;
|
||||
std::unique_ptr<nano::node_rpc_config> node_rpc_config;
|
||||
};
|
||||
|
||||
std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config, nano::node_flags const & node_flags)
|
||||
{
|
||||
node_config.ipc_config.transport_tcp.enabled = true;
|
||||
node_config.ipc_config.transport_tcp.port = nano::test::get_available_port ();
|
||||
return system.add_node (node_config, node_flags);
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system, nano::node_config & node_config)
|
||||
{
|
||||
return add_ipc_enabled_node (system, node_config, nano::node_flags ());
|
||||
}
|
||||
|
||||
std::shared_ptr<nano::node> add_ipc_enabled_node (nano::test::system & system)
|
||||
{
|
||||
nano::node_config node_config (nano::test::get_available_port (), system.logging);
|
||||
return add_ipc_enabled_node (system, node_config);
|
||||
}
|
||||
|
||||
void reset_confirmation_height (nano::store & store, nano::account const & account)
|
||||
{
|
||||
auto transaction = store.tx_begin_write ();
|
||||
nano::confirmation_height_info confirmation_height_info;
|
||||
if (!store.confirmation_height.get (transaction, account, confirmation_height_info))
|
||||
{
|
||||
store.confirmation_height.clear (transaction, account);
|
||||
}
|
||||
}
|
||||
|
||||
void wait_response_impl (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time, boost::property_tree::ptree & response_json)
|
||||
{
|
||||
test_response response (request, rpc_ctx.rpc->listening_port (), system.io_ctx);
|
||||
ASSERT_TIMELY (time, response.status != 0);
|
||||
ASSERT_EQ (200, response.status);
|
||||
response_json = response.json;
|
||||
}
|
||||
|
||||
boost::property_tree::ptree wait_response (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, std::chrono::duration<double, std::nano> const & time = 5s)
|
||||
{
|
||||
boost::property_tree::ptree response_json;
|
||||
wait_response_impl (system, rpc_ctx, request, time, response_json);
|
||||
return response_json;
|
||||
}
|
||||
|
||||
bool check_block_response_count (nano::test::system & system, rpc_context const & rpc_ctx, boost::property_tree::ptree & request, uint64_t size_count)
|
||||
{
|
||||
auto response (wait_response (system, rpc_ctx, request));
|
||||
auto & blocks = response.get_child ("blocks");
|
||||
return size_count == blocks.size ();
|
||||
}
|
||||
|
||||
rpc_context add_rpc (nano::test::system & system, std::shared_ptr<nano::node> const & node_a)
|
||||
{
|
||||
auto node_rpc_config (std::make_unique<nano::node_rpc_config> ());
|
||||
auto ipc_server (std::make_unique<nano::ipc::ipc_server> (*node_a, *node_rpc_config));
|
||||
nano::rpc_config rpc_config (node_a->network_params.network, nano::test::get_available_port (), true);
|
||||
const auto ipc_tcp_port = ipc_server->listening_tcp_port ();
|
||||
debug_assert (ipc_tcp_port.has_value ());
|
||||
auto ipc_rpc_processor (std::make_unique<nano::ipc_rpc_processor> (system.io_ctx, rpc_config, ipc_tcp_port.value ()));
|
||||
auto rpc (std::make_shared<nano::rpc> (system.io_ctx, rpc_config, *ipc_rpc_processor));
|
||||
rpc->start ();
|
||||
|
||||
return rpc_context{ rpc, ipc_server, ipc_rpc_processor, node_rpc_config };
|
||||
}
|
||||
}
|
||||
using namespace nano::test;
|
||||
|
||||
TEST (rpc, wrapped_task)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue