Bitcoin Core 29.99.0
P2P Digital Currency
test.cpp
Go to the documentation of this file.
1// Copyright (c) 2019 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <mp/proxy-io.h>
6#include <mp/test/foo.capnp.h>
7#include <mp/test/foo.capnp.proxy.h>
8#include <mp/test/foo.h>
9
10#include <capnp/capability.h>
11#include <cstdio>
12#include <future>
13#include <functional>
14#include <iostream>
15#include <memory>
16#include <kj/common.h>
17#include <kj/memory.h>
18#include <kj/test.h>
19#include <string>
20#include <thread>
21#include <utility>
22
23namespace mp {
24namespace test {
25
26KJ_TEST("Call FooInterface methods")
27{
28 std::promise<std::unique_ptr<ProxyClient<messages::FooInterface>>> foo_promise;
29 std::function<void()> disconnect_client;
30 std::thread thread([&]() {
31 EventLoop loop("mptest", [](bool raise, const std::string& log) {
32 std::cout << "LOG" << raise << ": " << log << "\n";
33 });
34 auto pipe = loop.m_io_context.provider->newTwoWayPipe();
35
36 auto connection_client = std::make_unique<Connection>(loop, kj::mv(pipe.ends[0]));
37 auto foo_client = std::make_unique<ProxyClient<messages::FooInterface>>(
38 connection_client->m_rpc_system->bootstrap(ServerVatId().vat_id).castAs<messages::FooInterface>(),
39 connection_client.get(), /* destroy_connection= */ false);
40 foo_promise.set_value(std::move(foo_client));
41 disconnect_client = [&] { loop.sync([&] { connection_client.reset(); }); };
42
43 auto connection_server = std::make_unique<Connection>(loop, kj::mv(pipe.ends[1]), [&](Connection& connection) {
44 auto foo_server = kj::heap<ProxyServer<messages::FooInterface>>(std::make_shared<FooImplementation>(), connection);
45 return capnp::Capability::Client(kj::mv(foo_server));
46 });
47 connection_server->onDisconnect([&] { connection_server.reset(); });
48 loop.loop();
49 });
50
51 auto foo = foo_promise.get_future().get();
52 KJ_EXPECT(foo->add(1, 2) == 3);
53
54 FooStruct in;
55 in.name = "name";
56 in.setint.insert(2);
57 in.setint.insert(1);
58 in.vbool.push_back(false);
59 in.vbool.push_back(true);
60 in.vbool.push_back(false);
61 FooStruct out = foo->pass(in);
62 KJ_EXPECT(in.name == out.name);
63 KJ_EXPECT(in.setint.size() == out.setint.size());
64 for (auto init{in.setint.begin()}, outit{out.setint.begin()}; init != in.setint.end() && outit != out.setint.end(); ++init, ++outit) {
65 KJ_EXPECT(*init == *outit);
66 }
67 KJ_EXPECT(in.vbool.size() == out.vbool.size());
68 for (size_t i = 0; i < in.vbool.size(); ++i) {
69 KJ_EXPECT(in.vbool[i] == out.vbool[i]);
70 }
71
72 FooStruct err;
73 try {
74 foo->raise(in);
75 } catch (const FooStruct& e) {
76 err = e;
77 }
78 KJ_EXPECT(in.name == err.name);
79
80 class Callback : public ExtendedCallback
81 {
82 public:
83 Callback(int expect, int ret) : m_expect(expect), m_ret(ret) {}
84 int call(int arg) override
85 {
86 KJ_EXPECT(arg == m_expect);
87 return m_ret;
88 }
89 int callExtended(int arg) override
90 {
91 KJ_EXPECT(arg == m_expect + 10);
92 return m_ret + 10;
93 }
94 int m_expect, m_ret;
95 };
96
97 foo->initThreadMap();
98 Callback callback(1, 2);
99 KJ_EXPECT(foo->callback(callback, 1) == 2);
100 KJ_EXPECT(foo->callbackUnique(std::make_unique<Callback>(3, 4), 3) == 4);
101 KJ_EXPECT(foo->callbackShared(std::make_shared<Callback>(5, 6), 5) == 6);
102 auto saved = std::make_shared<Callback>(7, 8);
103 KJ_EXPECT(saved.use_count() == 1);
104 foo->saveCallback(saved);
105 KJ_EXPECT(saved.use_count() == 2);
106 foo->callbackSaved(7);
107 KJ_EXPECT(foo->callbackSaved(7) == 8);
108 foo->saveCallback(nullptr);
109 KJ_EXPECT(saved.use_count() == 1);
110 KJ_EXPECT(foo->callbackExtended(callback, 11) == 12);
111
112 FooCustom custom_in;
113 custom_in.v1 = "v1";
114 custom_in.v2 = 5;
115 FooCustom custom_out = foo->passCustom(custom_in);
116 KJ_EXPECT(custom_in.v1 == custom_out.v1);
117 KJ_EXPECT(custom_in.v2 == custom_out.v2);
118
119 foo->passEmpty(FooEmpty{});
120
121 FooMessage message1;
122 message1.message = "init";
123 FooMessage message2{foo->passMessage(message1)};
124 KJ_EXPECT(message2.message == "init build read call build read");
125
126 FooMutable mut;
127 mut.message = "init";
128 foo->passMutable(mut);
129 KJ_EXPECT(mut.message == "init build pass call return read");
130
131 disconnect_client();
132 thread.join();
133
134 bool destroyed = false;
135 foo->m_context.cleanup_fns.emplace_front([&destroyed]{ destroyed = true; });
136 foo.reset();
137 KJ_EXPECT(destroyed);
138}
139
140} // namespace test
141} // namespace mp
int ret
Object holding network & rpc state associated with either an incoming server connection,...
Definition: proxy-io.h:288
Event loop implementation.
Definition: proxy-io.h:134
kj::AsyncIoContext m_io_context
Capnp IO context.
Definition: proxy-io.h:219
KJ_TEST("Call FooInterface methods")
Definition: test.cpp:26
Functions to serialize / deserialize common bitcoin types.
Definition: common-types.h:57
Vat id for server side of connection.
Definition: proxy-io.h:370
std::string v1
Definition: foo.h:28
std::string message
Definition: foo.h:38
std::string message
Definition: foo.h:43
std::string name
Definition: foo.h:19
std::set< int > setint
Definition: foo.h:20
std::vector< bool > vbool
Definition: foo.h:21
#define expect(bit)