1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/testkit/time_bomb.h>
#include <vespa/fnet/transport.h>
#include <vespa/fnet/transport_thread.h>
#include <vespa/fnet/transport_debugger.h>
#include <vespa/fnet/task.h>
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/fnet/frt/rpcrequest.h>
#include <vespa/fnet/frt/invoker.h>
#include <vespa/fnet/frt/target.h>
#include <vespa/vespalib/net/tls/tls_crypto_engine.h>
#include <vespa/vespalib/test/make_tls_options_for_testing.h>
vespalib::CryptoEngine::SP tls_crypto = std::make_shared<vespalib::TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing());
struct Service : FRT_Invokable {
fnet::frt::StandaloneFRT frt;
Service(fnet::TimeTools::SP time_tools)
: frt(fnet::TransportConfig(4).crypto(tls_crypto).time_tools(time_tools))
{
init_rpc();
ASSERT_TRUE(frt.supervisor().Listen(0));
}
FNET_Transport &transport() { return *frt.supervisor().GetTransport(); }
int listen_port() const {
return frt.supervisor().GetListenPort();
}
FRT_Target *connect(int port) {
return frt.supervisor().GetTarget(port);
}
void init_rpc() {
FRT_ReflectionBuilder rb(&frt.supervisor());
rb.DefineMethod("inc", "l", "l", FRT_METHOD(Service::rpc_inc), this);
rb.MethodDesc("increment a 64-bit integer, returns after 5 seconds");
rb.ParamDesc("in", "an integer (64 bit)");
rb.ReturnDesc("out", "in + 1 (64 bit)");
}
struct ReturnLater : FNET_Task {
FRT_RPCRequest *req;
ReturnLater(FNET_Scheduler *scheduler, FRT_RPCRequest *req_in)
: FNET_Task(scheduler), req(req_in) {}
void PerformTask() override { req->Return(); }
};
void rpc_inc(FRT_RPCRequest *req) {
req->Detach();
FRT_Values ¶ms = *req->GetParams();
FRT_Values &ret = *req->GetReturn();
ret.AddInt64(params[0]._intval64 + 1);
auto my_scheduler = req->GetConnection()->Owner()->GetScheduler();
auto &task = req->getStash().create<ReturnLater>(my_scheduler, req);
task.Schedule(5.0);
}
~Service() = default;
};
struct Fixture {
fnet::TransportDebugger debugger;
Service server;
Service client;
Fixture()
: debugger(),
server(debugger.time_tools()),
client(debugger.time_tools())
{
debugger.attach({server.transport(), client.transport()});
}
~Fixture() {
debugger.detach();
}
};
struct MyWait : FRT_IRequestWait {
FRT_RPCRequest *req = nullptr;
void RequestDone(FRT_RPCRequest *r) override { req = r; }
};
TEST_FF("transport layers can be run with transport debugger", Fixture(), vespalib::TimeBomb(60)) {
MyWait w4; // short timeout, should fail
MyWait w6; // long timeout, should be ok
FRT_Target *target = f1.client.connect(f1.server.listen_port());
FRT_RPCRequest *req4 = f1.client.frt.supervisor().AllocRPCRequest();
req4->SetMethodName("inc");
req4->GetParams()->AddInt64(3);
target->InvokeAsync(req4, 4.0, &w4);
FRT_RPCRequest *req6 = f1.client.frt.supervisor().AllocRPCRequest();
req6->SetMethodName("inc");
req6->GetParams()->AddInt64(7);
target->InvokeAsync(req6, 6.0, &w6);
bool got4 = false;
bool got6 = false;
size_t steps = 0;
while (!(got4 && got6)) {
f1.debugger.step();
++steps;
if (!got4 && w4.req) {
got4 = true;
fprintf(stderr, "request with 4s timeout completed after %zu steps (~%zu ms)\n", steps, steps * 5);
}
if (!got6 && w6.req) {
got6 = true;
fprintf(stderr, "request with 6s timeout completed after %zu steps (~%zu ms)\n", steps, steps * 5);
}
}
ASSERT_EQUAL(req4, w4.req);
ASSERT_EQUAL(req6, w6.req);
EXPECT_EQUAL(req4->GetErrorCode(), FRTE_RPC_TIMEOUT);
ASSERT_TRUE(req6->CheckReturnTypes("l"));
EXPECT_EQUAL(req6->GetReturn()->GetValue(0)._intval64, 8u);
target->internal_subref();
req4->internal_subref();
req6->internal_subref();
}
TEST_MAIN() { TEST_RUN_ALL(); }
|