11#include < addresstype.h>
22#include < boost/test/unit_test.hpp>
3+ #include < interfaces/init.h>
4+ #include < interfaces/ipc.h>
35#include < interfaces/mining.h>
6+ #include < ipc/capnp/init.capnp.h>
7+ #include < ipc/capnp/init.capnp.proxy.h>
48#include < node/miner.h>
59#include < node/transaction.h>
10+ #include < mp/proxy-io.h>
611#include < sv2/messages.h>
712#include < sv2/template_provider.h>
813#include < test/util/net.h>
1116#include < util/sock.h>
1217#include < util/strencodings.h>
1318
19+ #include < future>
1420#include < memory>
21+ #include < thread>
1522
1623// For verbose debugging use:
1724// build/src/test/test_sv2 --run_test=sv2_template_provider_tests --log_level=all -- -debug=sv2 -loglevel=sv2:trace -printtoconsole=1 | grep -v disabled
@@ -20,6 +27,82 @@ BOOST_FIXTURE_TEST_SUITE(sv2_template_provider_tests, TestChain100Setup)
2027
2128static constexpr size_t SV2_NEW_TEMPLATE_MESSAGE_SIZE{91 };
2229
30+ /* *
31+ * A test implementation of the Init interface that provides a Mining
32+ * interface via the node context passed to its constructor.
33+ */
34+ class TestInitImpl : public interfaces ::Init {
35+ public:
36+ TestInitImpl (node::NodeContext& node) : m_node(node) {}
37+ std::unique_ptr<interfaces::Mining> makeMining () override { return interfaces::MakeMining (m_node); }
38+ private:
39+ node::NodeContext& m_node;
40+ };
41+
42+ /* *
43+ * A class to set up an IPC server and client for testing.
44+ * The EventLoop runs in a separate thread.
45+ */
46+ class IPCTestSetup {
47+ private:
48+ std::unique_ptr<mp::Connection> m_server_connection;
49+ std::unique_ptr<mp::Connection> m_client_connection;
50+ std::promise<std::unique_ptr<ipc::capnp::messages::Init::Client>> m_client;
51+ std::thread m_thread;
52+
53+ public:
54+ std::unique_ptr<interfaces::Init> m_init;
55+
56+ IPCTestSetup (node::NodeContext& node)
57+ : m_thread([&] {
58+ mp::EventLoop loop (" test" , [](bool raise, const std::string& log) {
59+ std::cout << " LOG" << raise << " : " << log << " \n " ;
60+ if (raise) throw std::runtime_error (log);
61+ });
62+ auto pipe{loop.m_io_context .provider ->newTwoWayPipe ()};
63+
64+ m_server_connection =
65+ std::make_unique<mp::Connection>(loop, kj::mv (pipe.ends [0 ]), [&](mp::Connection& connection) {
66+ auto server_proxy = kj::heap<mp::ProxyServer<ipc::capnp::messages::Init>>(
67+ std::make_shared<TestInitImpl>(node), connection
68+ );
69+ return capnp::Capability::Client (kj::mv (server_proxy));
70+ });
71+ m_server_connection->onDisconnect ([&] {
72+ m_server_connection.reset ();
73+ });
74+ m_client_connection = std::make_unique<mp::Connection>(loop, kj::mv (pipe.ends [1 ]));
75+ m_client_connection->onDisconnect ([&] {
76+ m_client_connection.reset ();
77+ });
78+ m_client.set_value (std::make_unique<ipc::capnp::messages::Init::Client>(
79+ m_client_connection->m_rpc_system ->bootstrap (mp::ServerVatId ().vat_id ).castAs <ipc::capnp::messages::Init>()));
80+
81+ loop.loop ();
82+ })
83+ {
84+ auto client = m_client.get_future ().get ();
85+ // Create ProxyClient after EventLoop starts to ensure the initialization
86+ // "construct" request can be properly processed by the server.
87+ m_init = std::make_unique<mp::ProxyClient<ipc::capnp::messages::Init>>(
88+ std::move (*client), m_client_connection.get (), /* destroy_connection= */ true
89+ );
90+ // Release ownership of connection. ProxyClient manage its lifetime
91+ // because destroy_connection is set to true.
92+ m_client_connection.release ();
93+ }
94+
95+
96+ ~IPCTestSetup ()
97+ {
98+ // Destroy the Init client.
99+ // The EventLoop will only stop after all
100+ // clients are destroyed.
101+ m_init.reset ();
102+ m_thread.join ();
103+ }
104+ };
105+
23106/* *
24107 * A class for testing the Template Provider. Each TPTester encapsulates a
25108 * Sv2TemplateProvider (the one being tested) as well as a Sv2Cipher
@@ -142,7 +225,8 @@ class TPTester {
142225
143226BOOST_AUTO_TEST_CASE (client_tests)
144227{
145- auto mining{interfaces::MakeMining (m_node)};
228+ IPCTestSetup ipc_test_setup{m_node};
229+ auto mining{ipc_test_setup.m_init ->makeMining ()};
146230 TPTester tester{*mining};
147231
148232 tester.handshake ();
0 commit comments