mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-19 18:09:47 +01:00
test: add ipc test to test multiprocess type conversion code
Add unit test to test IPC method calls and type conversion between bitcoin c++ types and capnproto messages. Right now there are custom type hooks in bitcoin IPC code, so the test is simple, but in upcoming commits, code will be added to convert bitcoin types to capnproto messages, and the test will be expanded.
This commit is contained in:
parent
fe4e83f50d
commit
4aaee23921
@ -10,7 +10,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\test\*_properties.cpp" />
|
||||
<ClCompile Include="..\..\src\test\*_tests.cpp" />
|
||||
<ClCompile Include="..\..\src\test\*_tests.cpp" Exclude="..\..\src\test\ipc_tests.cpp" />
|
||||
<ClCompile Include="..\..\src\test\gen\*_gen.cpp" />
|
||||
<ClCompile Include="..\..\src\test\main.cpp" />
|
||||
<ClCompile Include="..\..\src\test\util\*.cpp" />
|
||||
|
@ -216,6 +216,39 @@ BITCOIN_TEST_SUITE += \
|
||||
wallet/test/init_test_fixture.h
|
||||
endif # ENABLE_WALLET
|
||||
|
||||
if BUILD_MULTIPROCESS
|
||||
# Add boost ipc_tests definition to BITCOIN_TESTS
|
||||
BITCOIN_TESTS += test/ipc_tests.cpp
|
||||
|
||||
# Build ipc_test code in a separate library so it can be compiled with custom
|
||||
# LIBMULTIPROCESS_CFLAGS without those flags affecting other tests
|
||||
LIBBITCOIN_IPC_TEST=libbitcoin_ipc_test.a
|
||||
EXTRA_LIBRARIES += $(LIBBITCOIN_IPC_TEST)
|
||||
libbitcoin_ipc_test_a_SOURCES = \
|
||||
test/ipc_test.cpp \
|
||||
test/ipc_test.h
|
||||
libbitcoin_ipc_test_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_ipc_test_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) $(LIBMULTIPROCESS_CFLAGS)
|
||||
|
||||
# Generate various .c++/.h files from the ipc_test.capnp file
|
||||
include $(MPGEN_PREFIX)/include/mpgen.mk
|
||||
EXTRA_DIST += test/ipc_test.capnp
|
||||
libbitcoin_ipc_test_mpgen_output = \
|
||||
test/ipc_test.capnp.c++ \
|
||||
test/ipc_test.capnp.h \
|
||||
test/ipc_test.capnp.proxy-client.c++ \
|
||||
test/ipc_test.capnp.proxy-server.c++ \
|
||||
test/ipc_test.capnp.proxy-types.c++ \
|
||||
test/ipc_test.capnp.proxy-types.h \
|
||||
test/ipc_test.capnp.proxy.h
|
||||
nodist_libbitcoin_ipc_test_a_SOURCES = $(libbitcoin_ipc_test_mpgen_output)
|
||||
CLEANFILES += $(libbitcoin_ipc_test_mpgen_output)
|
||||
endif
|
||||
|
||||
# Explicitly list dependencies on generated headers as described in
|
||||
# https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html#Recording-Dependencies-manually
|
||||
test/libbitcoin_ipc_test_a-ipc_test.$(OBJEXT): test/ipc_test.capnp.h
|
||||
|
||||
test_test_bitcoin_SOURCES = $(BITCOIN_TEST_SUITE) $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||
test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(TESTDEFS) $(BOOST_CPPFLAGS) $(EVENT_CFLAGS)
|
||||
test_test_bitcoin_LDADD = $(LIBTEST_UTIL)
|
||||
@ -223,6 +256,9 @@ if ENABLE_WALLET
|
||||
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
||||
test_test_bitcoin_CPPFLAGS += $(BDB_CPPFLAGS)
|
||||
endif
|
||||
if BUILD_MULTIPROCESS
|
||||
test_test_bitcoin_LDADD += $(LIBBITCOIN_IPC_TEST) $(LIBMULTIPROCESS_LIBS)
|
||||
endif
|
||||
|
||||
test_test_bitcoin_LDADD += $(LIBBITCOIN_NODE) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
||||
$(LIBLEVELDB) $(LIBMEMENV) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) $(MINISKETCH_LIBS)
|
||||
|
2
src/test/.gitignore
vendored
Normal file
2
src/test/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# capnp generated files
|
||||
*.capnp.*
|
15
src/test/ipc_test.capnp
Normal file
15
src/test/ipc_test.capnp
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2023 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@0xd71b0fc8727fdf83;
|
||||
|
||||
using Cxx = import "/capnp/c++.capnp";
|
||||
$Cxx.namespace("gen");
|
||||
|
||||
using Proxy = import "/mp/proxy.capnp";
|
||||
$Proxy.include("test/ipc_test.h");
|
||||
|
||||
interface FooInterface $Proxy.wrap("FooImplementation") {
|
||||
add @0 (a :Int32, b :Int32) -> (result :Int32);
|
||||
}
|
57
src/test/ipc_test.cpp
Normal file
57
src/test/ipc_test.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2023 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <mp/proxy-types.h>
|
||||
#include <logging.h>
|
||||
#include <test/ipc_test.capnp.h>
|
||||
#include <test/ipc_test.capnp.proxy.h>
|
||||
#include <test/ipc_test.h>
|
||||
|
||||
#include <future>
|
||||
#include <kj/common.h>
|
||||
#include <kj/memory.h>
|
||||
#include <kj/test.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
//! Unit test that tests execution of IPC calls without actually creating a
|
||||
//! separate process. This test is primarily intended to verify behavior of type
|
||||
//! conversion code that converts C++ objects to Cap'n Proto messages and vice
|
||||
//! versa.
|
||||
//!
|
||||
//! The test creates a thread which creates a FooImplementation object (defined
|
||||
//! in ipc_test.h) and a two-way pipe accepting IPC requests which call methods
|
||||
//! on the object through FooInterface (defined in ipc_test.capnp).
|
||||
void IpcTest()
|
||||
{
|
||||
// Setup: create FooImplemention object and listen for FooInterface requests
|
||||
std::promise<std::unique_ptr<mp::ProxyClient<gen::FooInterface>>> foo_promise;
|
||||
std::function<void()> disconnect_client;
|
||||
std::thread thread([&]() {
|
||||
mp::EventLoop loop("IpcTest", [](bool raise, const std::string& log) { LogPrintf("LOG%i: %s\n", raise, log); });
|
||||
auto pipe = loop.m_io_context.provider->newTwoWayPipe();
|
||||
|
||||
auto connection_client = std::make_unique<mp::Connection>(loop, kj::mv(pipe.ends[0]));
|
||||
auto foo_client = std::make_unique<mp::ProxyClient<gen::FooInterface>>(
|
||||
connection_client->m_rpc_system.bootstrap(mp::ServerVatId().vat_id).castAs<gen::FooInterface>(),
|
||||
connection_client.get(), /* destroy_connection= */ false);
|
||||
foo_promise.set_value(std::move(foo_client));
|
||||
disconnect_client = [&] { loop.sync([&] { connection_client.reset(); }); };
|
||||
|
||||
auto connection_server = std::make_unique<mp::Connection>(loop, kj::mv(pipe.ends[1]), [&](mp::Connection& connection) {
|
||||
auto foo_server = kj::heap<mp::ProxyServer<gen::FooInterface>>(std::make_shared<FooImplementation>(), connection);
|
||||
return capnp::Capability::Client(kj::mv(foo_server));
|
||||
});
|
||||
connection_server->onDisconnect([&] { connection_server.reset(); });
|
||||
loop.loop();
|
||||
});
|
||||
std::unique_ptr<mp::ProxyClient<gen::FooInterface>> foo{foo_promise.get_future().get()};
|
||||
|
||||
// Test: make sure arguments were sent and return value is received
|
||||
BOOST_CHECK_EQUAL(foo->add(1, 2), 3);
|
||||
|
||||
// Test cleanup: disconnect pipe and join thread
|
||||
disconnect_client();
|
||||
thread.join();
|
||||
}
|
18
src/test/ipc_test.h
Normal file
18
src/test/ipc_test.h
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2023 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_TEST_IPC_TEST_H
|
||||
#define BITCOIN_TEST_IPC_TEST_H
|
||||
|
||||
#include <primitives/transaction.h>
|
||||
|
||||
class FooImplementation
|
||||
{
|
||||
public:
|
||||
int add(int a, int b) { return a + b; }
|
||||
};
|
||||
|
||||
void IpcTest();
|
||||
|
||||
#endif // BITCOIN_TEST_IPC_TEST_H
|
13
src/test/ipc_tests.cpp
Normal file
13
src/test/ipc_tests.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2023 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <test/ipc_test.h>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ipc_tests)
|
||||
BOOST_AUTO_TEST_CASE(ipc_tests)
|
||||
{
|
||||
IpcTest();
|
||||
}
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue
Block a user