starpc 0.52.0 → 0.52.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -8
- package/dist/echo/client-test.d.ts +1 -1
- package/dist/echo/client-test.js +110 -2
- package/dist/integration/cross-language/tcp-packet-stream.d.ts +3 -0
- package/dist/integration/cross-language/tcp-packet-stream.js +112 -0
- package/dist/integration/cross-language/tcp-packet-stream.test.d.ts +1 -0
- package/dist/integration/cross-language/tcp-packet-stream.test.js +121 -0
- package/dist/integration/cross-language/ts-client.js +50 -37
- package/dist/integration/cross-language/ts-server.js +1 -36
- package/dist/rpcstream/rpcstream.d.ts +5 -1
- package/dist/rpcstream/rpcstream.js +75 -28
- package/dist/rpcstream/rpcstream.test.d.ts +1 -0
- package/dist/rpcstream/rpcstream.test.js +92 -0
- package/dist/srpc/client-rpc.d.ts +1 -0
- package/dist/srpc/client-rpc.js +9 -0
- package/dist/srpc/client-rpc.test.d.ts +1 -0
- package/dist/srpc/client-rpc.test.js +50 -0
- package/dist/srpc/client.js +18 -4
- package/dist/srpc/common-rpc.d.ts +5 -0
- package/dist/srpc/common-rpc.js +37 -8
- package/dist/srpc/common-rpc.test.js +2 -0
- package/dist/srpc/errors.d.ts +2 -0
- package/dist/srpc/errors.js +14 -0
- package/dist/srpc/index.d.ts +1 -1
- package/dist/srpc/index.js +1 -1
- package/dist/srpc/packet-codec.test.d.ts +1 -0
- package/dist/srpc/packet-codec.test.js +75 -0
- package/dist/srpc/packet.d.ts +1 -1
- package/dist/srpc/packet.js +11 -1
- package/dist/srpc/server.js +19 -6
- package/dist/srpc/server.test.js +43 -0
- package/dist/srpc/stream.d.ts +4 -1
- package/dist/srpc/stream.js +62 -3
- package/dist/srpc/stream.test.js +110 -1
- package/dist/srpc/termination.d.ts +27 -0
- package/dist/srpc/termination.js +56 -0
- package/dist/srpc/termination.test.d.ts +1 -0
- package/dist/srpc/termination.test.js +24 -0
- package/dist/testdata/packet-codec-vectors.json +64 -0
- package/echo/Cargo.toml +8 -0
- package/echo/client-test.ts +124 -2
- package/echo/echo_e2e_test.cpp +542 -985
- package/echo/echo_pb2.py +40 -0
- package/echo/echo_pb2.pyi +13 -0
- package/echo/echo_srpc.pb.cpp +3 -5
- package/echo/echo_srpc.pb.go +6 -9
- package/echo/echo_srpc.pb.hpp +23 -3
- package/echo/echo_srpc.pb.rs +61 -26
- package/echo/echo_srpc.py +309 -0
- package/echo/echo_srpc.pyi +85 -0
- package/echo/half_close_test.rs +178 -0
- package/echo/integration_server.rs +14 -21
- package/echo/main.rs +28 -48
- package/go.mod +3 -3
- package/go.sum +6 -8
- package/integration/cross-language/cpp-client.cpp +446 -402
- package/integration/cross-language/cpp-pipe-server.cpp +139 -0
- package/integration/cross-language/cpp-pipe_test.go +114 -0
- package/integration/cross-language/cpp-server.cpp +222 -186
- package/integration/cross-language/go-client/main.go +79 -3
- package/integration/cross-language/python-client.py +146 -0
- package/integration/cross-language/python-server.py +140 -0
- package/integration/cross-language/run.bash +190 -65
- package/integration/cross-language/tcp-packet-stream.test.ts +154 -0
- package/integration/cross-language/tcp-packet-stream.ts +121 -0
- package/integration/cross-language/ts-client.ts +62 -40
- package/integration/cross-language/ts-server.ts +1 -45
- package/mock/mock_pb2.py +38 -0
- package/mock/mock_pb2.pyi +11 -0
- package/mock/mock_srpc.pb.cpp +1 -1
- package/mock/mock_srpc.pb.hpp +1 -1
- package/mock/mock_srpc.pb.rs +10 -9
- package/mock/mock_srpc.py +71 -0
- package/mock/mock_srpc.pyi +27 -0
- package/package.json +19 -5
- package/srpc/CMakeLists.txt +3 -58
- package/srpc/README-cpp.md +69 -0
- package/srpc/__init__.py +0 -0
- package/srpc/accept.go +10 -4
- package/srpc/accept_test.go +25 -0
- package/srpc/build.rs +129 -34
- package/srpc/client-half-close_test.go +152 -0
- package/srpc/client-invoker.go +32 -42
- package/srpc/client-invoker_test.go +53 -0
- package/srpc/client-rpc.cpp +65 -80
- package/srpc/client-rpc.go +32 -33
- package/srpc/client-rpc.hpp +52 -38
- package/srpc/client-rpc.test.ts +67 -0
- package/srpc/client-rpc.ts +10 -0
- package/srpc/client-rpc_test.go +76 -0
- package/srpc/client.cpp +99 -87
- package/srpc/client.hpp +46 -35
- package/srpc/client.rs +78 -38
- package/srpc/client.ts +20 -4
- package/srpc/client_half_close_test.cc +331 -0
- package/srpc/client_invoker.rs +75 -0
- package/srpc/codec.rs +6 -0
- package/srpc/common-rpc.cpp +186 -146
- package/srpc/common-rpc.go +5 -4
- package/srpc/common-rpc.hpp +119 -89
- package/srpc/common-rpc.test.ts +2 -0
- package/srpc/common-rpc.ts +43 -8
- package/srpc/common-rpc_test.go +23 -0
- package/srpc/error.rs +19 -2
- package/srpc/errors.hpp +80 -50
- package/srpc/errors.ts +16 -0
- package/srpc/handler.hpp +9 -7
- package/srpc/handler.rs +7 -45
- package/srpc/index.ts +2 -0
- package/srpc/invoker.hpp +82 -55
- package/srpc/invoker.rs +14 -52
- package/srpc/lib.rs +2 -0
- package/srpc/message.hpp +17 -12
- package/srpc/msg-stream.go +1 -0
- package/srpc/msg-stream.hpp +108 -61
- package/srpc/mux.cpp +84 -84
- package/srpc/mux.hpp +48 -38
- package/srpc/mux.rs +4 -4
- package/srpc/net.go +12 -3
- package/srpc/packet-codec-vectors_test.go +195 -0
- package/srpc/packet-codec.test.ts +139 -0
- package/srpc/packet-rw.go +9 -2
- package/srpc/packet.cpp +60 -58
- package/srpc/packet.hpp +35 -20
- package/srpc/packet.rs +8 -27
- package/srpc/packet.ts +15 -2
- package/srpc/py.typed +0 -0
- package/srpc/rpc.rs +332 -115
- package/srpc/rpc_lifecycle_test.cc +333 -0
- package/srpc/rpcproto_pb2.py +40 -0
- package/srpc/rpcproto_pb2.pyi +40 -0
- package/srpc/server-cancel_test.go +39 -0
- package/srpc/server-rpc.cpp +83 -73
- package/srpc/server-rpc.go +21 -19
- package/srpc/server-rpc.hpp +56 -37
- package/srpc/server.rs +76 -131
- package/srpc/server.test.ts +50 -0
- package/srpc/server.ts +22 -6
- package/srpc/starpc.hpp +4 -2
- package/srpc/stream.go +4 -0
- package/srpc/stream.hpp +95 -34
- package/srpc/stream.rs +7 -2
- package/srpc/stream.test.ts +132 -1
- package/srpc/stream.ts +65 -9
- package/srpc/termination.test.ts +30 -0
- package/srpc/termination.ts +70 -0
- package/srpc/testing.rs +11 -66
- package/srpc/transport.rs +21 -71
- package/srpc/websocket.rs +106 -57
- package/srpc/writer.hpp +46 -32
- package/srpc/yamux.rs +82 -26
- package/srpc/tests/integration_test.rs +0 -495
package/echo/echo_e2e_test.cpp
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
//go:build deps_only
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/*
|
|
4
|
+
* Echo end-to-end test for the starpc C++ implementation: unary, streaming,
|
|
5
|
+
* and nested RpcStream calls over an in-memory transport.
|
|
6
|
+
*/
|
|
5
7
|
|
|
6
|
-
#include <
|
|
7
|
-
#include <cassert>
|
|
8
|
+
#include <condition_variable>
|
|
8
9
|
#include <iostream>
|
|
9
10
|
#include <memory>
|
|
10
11
|
#include <mutex>
|
|
11
12
|
#include <queue>
|
|
13
|
+
#include <string>
|
|
12
14
|
#include <thread>
|
|
15
|
+
#include <tuple>
|
|
16
|
+
#include <utility>
|
|
13
17
|
|
|
14
18
|
#include "echo/echo_srpc.pb.hpp"
|
|
15
19
|
#include "rpcstream/rpcstream.hpp"
|
|
@@ -18,1031 +22,584 @@
|
|
|
18
22
|
|
|
19
23
|
namespace {
|
|
20
24
|
|
|
21
|
-
const char *
|
|
25
|
+
const char *test_body = "hello world via starpc C++ e2e test";
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
/*
|
|
28
|
+
* InMemoryTransport is a bidirectional packet connection between a test
|
|
29
|
+
* client and server. Each Endpoint queues packets and wakes its readers on
|
|
30
|
+
* send or close.
|
|
31
|
+
*/
|
|
25
32
|
class InMemoryTransport {
|
|
26
33
|
public:
|
|
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
|
-
|
|
34
|
+
struct Endpoint {
|
|
35
|
+
std::mutex mtx;
|
|
36
|
+
std::condition_variable cv;
|
|
37
|
+
std::queue<std::string> packets;
|
|
38
|
+
bool closed = false;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
InMemoryTransport()
|
|
42
|
+
: client_endpoint(std::make_shared<Endpoint>()),
|
|
43
|
+
server_endpoint(std::make_shared<Endpoint>())
|
|
44
|
+
{
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* ClientToServer returns the endpoint the client writes to. */
|
|
48
|
+
std::shared_ptr<Endpoint> ClientToServer()
|
|
49
|
+
{
|
|
50
|
+
return server_endpoint;
|
|
51
|
+
}
|
|
52
|
+
/* ServerToClient returns the endpoint the server writes to. */
|
|
53
|
+
std::shared_ptr<Endpoint> ServerToClient()
|
|
54
|
+
{
|
|
55
|
+
return client_endpoint;
|
|
56
|
+
}
|
|
57
|
+
/* ClientReader returns the endpoint the client reads from. */
|
|
58
|
+
std::shared_ptr<Endpoint> ClientReader()
|
|
59
|
+
{
|
|
60
|
+
return client_endpoint;
|
|
61
|
+
}
|
|
62
|
+
/* ServerReader returns the endpoint the server reads from. */
|
|
63
|
+
std::shared_ptr<Endpoint> ServerReader()
|
|
64
|
+
{
|
|
65
|
+
return server_endpoint;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Send queues data on ep and wakes its readers. */
|
|
69
|
+
static void Send(std::shared_ptr<Endpoint> ep, const std::string &data)
|
|
70
|
+
{
|
|
71
|
+
std::lock_guard<std::mutex> lock(ep->mtx);
|
|
72
|
+
if (!ep->closed) {
|
|
73
|
+
ep->packets.push(data);
|
|
74
|
+
ep->cv.notify_all();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* Recv waits for one packet and returns false once ep is closed and
|
|
80
|
+
* drained.
|
|
81
|
+
*/
|
|
82
|
+
static bool Recv(std::shared_ptr<Endpoint> ep, std::string *out)
|
|
83
|
+
{
|
|
84
|
+
std::unique_lock<std::mutex> lock(ep->mtx);
|
|
85
|
+
ep->cv.wait(lock, [&ep]() {
|
|
86
|
+
return !ep->packets.empty() || ep->closed;
|
|
87
|
+
});
|
|
88
|
+
if (ep->packets.empty())
|
|
89
|
+
return false;
|
|
90
|
+
*out = std::move(ep->packets.front());
|
|
91
|
+
ep->packets.pop();
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Close ends the endpoint and wakes its readers. */
|
|
96
|
+
static void Close(std::shared_ptr<Endpoint> ep)
|
|
97
|
+
{
|
|
98
|
+
std::lock_guard<std::mutex> lock(ep->mtx);
|
|
99
|
+
ep->closed = true;
|
|
100
|
+
ep->cv.notify_all();
|
|
101
|
+
}
|
|
76
102
|
|
|
77
103
|
private:
|
|
78
|
-
|
|
79
|
-
|
|
104
|
+
std::shared_ptr<Endpoint> client_endpoint;
|
|
105
|
+
std::shared_ptr<Endpoint> server_endpoint;
|
|
80
106
|
};
|
|
81
107
|
|
|
82
|
-
|
|
108
|
+
/* InMemoryPacketWriter writes packets to one transport endpoint. */
|
|
83
109
|
class InMemoryPacketWriter : public starpc::PacketWriter {
|
|
84
110
|
public:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
explicit InMemoryPacketWriter(
|
|
112
|
+
std::shared_ptr<InMemoryTransport::Endpoint> ep)
|
|
113
|
+
: endpoint(ep)
|
|
114
|
+
{
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
starpc::Error WritePacket(const srpc::Packet &pkt) override
|
|
118
|
+
{
|
|
119
|
+
std::string data;
|
|
120
|
+
if (!pkt.SerializeToString(&data))
|
|
121
|
+
return starpc::Error::InvalidMessage;
|
|
122
|
+
InMemoryTransport::Send(endpoint, data);
|
|
123
|
+
return starpc::Error::OK;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
starpc::Error Close() override
|
|
127
|
+
{
|
|
128
|
+
InMemoryTransport::Close(endpoint);
|
|
129
|
+
return starpc::Error::OK;
|
|
130
|
+
}
|
|
101
131
|
|
|
102
132
|
private:
|
|
103
|
-
|
|
133
|
+
std::shared_ptr<InMemoryTransport::Endpoint> endpoint;
|
|
104
134
|
};
|
|
105
135
|
|
|
106
|
-
|
|
107
|
-
|
|
136
|
+
/*
|
|
137
|
+
* RpcStreamAdapter exposes a generated server stream as an
|
|
138
|
+
* rpcstream::RpcStream. The stream is borrowed and must outlive the adapter.
|
|
139
|
+
*/
|
|
108
140
|
class RpcStreamAdapter : public rpcstream::RpcStream {
|
|
109
141
|
public:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
142
|
+
explicit RpcStreamAdapter(echo::SRPCEchoer_RpcStreamStream *strm)
|
|
143
|
+
: strm(strm)
|
|
144
|
+
{
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
starpc::Error Send(const rpcstream::RpcStreamPacket &msg) override
|
|
148
|
+
{
|
|
149
|
+
return strm->Send(msg);
|
|
150
|
+
}
|
|
151
|
+
starpc::Error Recv(rpcstream::RpcStreamPacket *msg) override
|
|
152
|
+
{
|
|
153
|
+
return strm->Recv(msg);
|
|
154
|
+
}
|
|
155
|
+
starpc::Error CloseSend() override
|
|
156
|
+
{
|
|
157
|
+
return starpc::Error::OK;
|
|
158
|
+
}
|
|
159
|
+
starpc::Error Close() override
|
|
160
|
+
{
|
|
161
|
+
return starpc::Error::OK;
|
|
162
|
+
}
|
|
121
163
|
|
|
122
164
|
private:
|
|
123
|
-
|
|
165
|
+
echo::SRPCEchoer_RpcStreamStream *strm;
|
|
124
166
|
};
|
|
125
167
|
|
|
126
|
-
|
|
168
|
+
/* EchoServerImpl implements the echo service under test. */
|
|
127
169
|
class EchoServerImpl : public echo::SRPCEchoerServer {
|
|
128
170
|
public:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
171
|
+
/* SetRpcStreamMux selects the mux nested RpcStream calls resolve to. */
|
|
172
|
+
void SetRpcStreamMux(starpc::Mux *mux)
|
|
173
|
+
{
|
|
174
|
+
rpc_stream_mux = mux;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
starpc::Error Echo(const echo::EchoMsg &req,
|
|
178
|
+
echo::EchoMsg *resp) override
|
|
179
|
+
{
|
|
180
|
+
resp->set_body(req.body());
|
|
181
|
+
return starpc::Error::OK;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
starpc::Error
|
|
185
|
+
EchoServerStream(const echo::EchoMsg &req,
|
|
186
|
+
echo::SRPCEchoer_EchoServerStreamStream *strm) override
|
|
187
|
+
{
|
|
188
|
+
/* Send 5 copies of the message */
|
|
189
|
+
for (int i = 0; i < 5; i++) {
|
|
190
|
+
echo::EchoMsg msg;
|
|
191
|
+
msg.set_body(req.body());
|
|
192
|
+
starpc::Error err = strm->Send(msg);
|
|
193
|
+
if (err != starpc::Error::OK) {
|
|
194
|
+
return err;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return starpc::Error::OK;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
starpc::Error
|
|
201
|
+
EchoClientStream(echo::SRPCEchoer_EchoClientStreamStream *strm,
|
|
202
|
+
echo::EchoMsg *resp) override
|
|
203
|
+
{
|
|
204
|
+
/* Receive first message and return it */
|
|
205
|
+
echo::EchoMsg msg;
|
|
206
|
+
starpc::Error err = strm->Recv(&msg);
|
|
207
|
+
if (err != starpc::Error::OK) {
|
|
208
|
+
return err;
|
|
209
|
+
}
|
|
210
|
+
resp->set_body(msg.body());
|
|
211
|
+
return starpc::Error::OK;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
starpc::Error
|
|
215
|
+
EchoBidiStream(echo::SRPCEchoer_EchoBidiStreamStream *strm) override
|
|
216
|
+
{
|
|
217
|
+
/* Echo back all received messages */
|
|
218
|
+
while (true) {
|
|
219
|
+
echo::EchoMsg msg;
|
|
220
|
+
starpc::Error err = strm->Recv(&msg);
|
|
221
|
+
if (err == starpc::Error::EOF_) {
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
if (err != starpc::Error::OK) {
|
|
225
|
+
return err;
|
|
226
|
+
}
|
|
227
|
+
err = strm->Send(msg);
|
|
228
|
+
if (err != starpc::Error::OK) {
|
|
229
|
+
return err;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return starpc::Error::OK;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
starpc::Error RpcStream(echo::SRPCEchoer_RpcStreamStream *strm) override
|
|
236
|
+
{
|
|
237
|
+
auto adapter = std::make_shared<RpcStreamAdapter>(strm);
|
|
238
|
+
return rpcstream::HandleRpcStream(
|
|
239
|
+
adapter, [this](const std::string &component_id) {
|
|
240
|
+
if (!rpc_stream_mux) {
|
|
241
|
+
return std::make_tuple(
|
|
242
|
+
static_cast<starpc::Invoker *>(
|
|
243
|
+
nullptr),
|
|
244
|
+
std::function<void()>(),
|
|
245
|
+
starpc::Error::Unimplemented);
|
|
246
|
+
}
|
|
247
|
+
return std::make_tuple(
|
|
248
|
+
static_cast<starpc::Invoker *>(
|
|
249
|
+
rpc_stream_mux),
|
|
250
|
+
std::function<void()>(),
|
|
251
|
+
starpc::Error::OK);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
starpc::Error DoNothing(const google::protobuf::Empty &req,
|
|
256
|
+
google::protobuf::Empty *resp) override
|
|
257
|
+
{
|
|
258
|
+
return starpc::Error::OK;
|
|
259
|
+
}
|
|
204
260
|
|
|
205
261
|
private:
|
|
206
|
-
|
|
262
|
+
/* rpc_stream_mux is borrowed; the caller owns it. */
|
|
263
|
+
starpc::Mux *rpc_stream_mux = nullptr;
|
|
207
264
|
};
|
|
208
265
|
|
|
209
|
-
|
|
210
|
-
void RunServer(InMemoryTransport *transport, starpc::Mux *mux)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
266
|
+
/* RunServer serves packets from the transport until it closes. */
|
|
267
|
+
void RunServer(InMemoryTransport *transport, starpc::Mux *mux)
|
|
268
|
+
{
|
|
269
|
+
auto reader = transport->ServerReader();
|
|
270
|
+
auto writer = std::make_unique<InMemoryPacketWriter>(
|
|
271
|
+
transport->ServerToClient());
|
|
272
|
+
auto server_rpc = starpc::NewServerRPC(mux, writer.get());
|
|
273
|
+
|
|
274
|
+
std::string data;
|
|
275
|
+
while (InMemoryTransport::Recv(reader, &data)) {
|
|
276
|
+
starpc::Error err = server_rpc->HandlePacketData(data);
|
|
277
|
+
if (err != starpc::Error::OK &&
|
|
278
|
+
err != starpc::Error::Completed) {
|
|
279
|
+
std::cerr
|
|
280
|
+
<< "Server error: " << starpc::ErrorString(err)
|
|
281
|
+
<< std::endl;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
228
285
|
}
|
|
229
286
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
287
|
+
/*
|
|
288
|
+
* EchoServer serves one EchoServerImpl on a mux, and on a nested mux that
|
|
289
|
+
* RpcStream calls resolve to. It owns the handlers both muxes borrow.
|
|
290
|
+
*/
|
|
291
|
+
struct EchoServer {
|
|
292
|
+
EchoServerImpl impl;
|
|
293
|
+
std::unique_ptr<echo::SRPCEchoerHandler> handler;
|
|
294
|
+
std::unique_ptr<echo::SRPCEchoerHandler> nested_handler;
|
|
295
|
+
std::unique_ptr<starpc::Mux> mux = starpc::NewMux();
|
|
296
|
+
std::unique_ptr<starpc::Mux> nested_mux = starpc::NewMux();
|
|
297
|
+
|
|
298
|
+
/* Register registers impl on both muxes and reports the first error. */
|
|
299
|
+
starpc::Error Register()
|
|
300
|
+
{
|
|
301
|
+
impl.SetRpcStreamMux(nested_mux.get());
|
|
302
|
+
starpc::Error err;
|
|
303
|
+
std::tie(handler, err) =
|
|
304
|
+
echo::SRPCRegisterEchoer(mux.get(), &impl);
|
|
305
|
+
if (err != starpc::Error::OK)
|
|
306
|
+
return err;
|
|
307
|
+
std::tie(nested_handler, err) =
|
|
308
|
+
echo::SRPCRegisterEchoer(nested_mux.get(), &impl);
|
|
309
|
+
return err;
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
/*
|
|
314
|
+
* TestCall serves a mux over an in-memory transport and opens one client call
|
|
315
|
+
* on it. Its receive thread feeds server packets to the call and ends the call
|
|
316
|
+
* with EOF when the transport closes. Destroying the TestCall closes the call
|
|
317
|
+
* and both endpoints and joins both threads, so every exit path releases them.
|
|
318
|
+
* The mux must outlive the TestCall.
|
|
319
|
+
*/
|
|
320
|
+
class TestCall {
|
|
321
|
+
public:
|
|
322
|
+
TestCall(starpc::Mux *mux, const std::string &service,
|
|
323
|
+
const std::string &method)
|
|
324
|
+
: client_rpc(starpc::NewClientRPC(service, method)),
|
|
325
|
+
writer(std::make_unique<InMemoryPacketWriter>(
|
|
326
|
+
transport.ClientToServer()))
|
|
327
|
+
{
|
|
328
|
+
server_thread = std::thread(
|
|
329
|
+
[this, mux]() { RunServer(&transport, mux); });
|
|
330
|
+
recv_thread = std::thread([this]() { Receive(); });
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
TestCall(const TestCall &) = delete;
|
|
334
|
+
TestCall &operator=(const TestCall &) = delete;
|
|
335
|
+
|
|
336
|
+
~TestCall()
|
|
337
|
+
{
|
|
338
|
+
client_rpc->Close();
|
|
339
|
+
InMemoryTransport::Close(transport.ServerReader());
|
|
340
|
+
InMemoryTransport::Close(transport.ClientReader());
|
|
341
|
+
recv_thread.join();
|
|
342
|
+
server_thread.join();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* Start starts the call, sending data first when has_data is set. */
|
|
346
|
+
starpc::Error Start(bool has_data, const std::string &data)
|
|
347
|
+
{
|
|
348
|
+
return client_rpc->Start(writer.get(), has_data, data);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* Rpc returns the client call. */
|
|
352
|
+
starpc::ClientRPC *Rpc()
|
|
353
|
+
{
|
|
354
|
+
return client_rpc.get();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private:
|
|
358
|
+
/* Receive feeds packets to the call until the transport closes. */
|
|
359
|
+
void Receive()
|
|
360
|
+
{
|
|
361
|
+
auto reader = transport.ClientReader();
|
|
362
|
+
std::string data;
|
|
363
|
+
while (InMemoryTransport::Recv(reader, &data)) {
|
|
364
|
+
if (client_rpc->HandlePacketData(data) !=
|
|
365
|
+
starpc::Error::OK)
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
client_rpc->HandleStreamClose(starpc::Error::EOF_);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
InMemoryTransport transport;
|
|
372
|
+
std::unique_ptr<starpc::ClientRPC> client_rpc;
|
|
373
|
+
std::unique_ptr<InMemoryPacketWriter> writer;
|
|
374
|
+
std::thread server_thread;
|
|
375
|
+
std::thread recv_thread;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
/* Fail reports a failed step with its error and returns false. */
|
|
379
|
+
bool Fail(const std::string &step, starpc::Error err)
|
|
380
|
+
{
|
|
381
|
+
std::cerr << "FAILED: " << step << ": " << starpc::ErrorString(err)
|
|
382
|
+
<< std::endl;
|
|
383
|
+
return false;
|
|
315
384
|
}
|
|
316
385
|
|
|
317
|
-
|
|
318
|
-
bool
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// Setup server
|
|
324
|
-
auto mux = starpc::NewMux();
|
|
325
|
-
EchoServerImpl server_impl;
|
|
326
|
-
auto [handler, reg_err] = echo::SRPCRegisterEchoer(mux.get(), &server_impl);
|
|
327
|
-
if (reg_err != starpc::Error::OK) {
|
|
328
|
-
std::cerr << "FAILED: Registration error: " << starpc::ErrorString(reg_err)
|
|
329
|
-
<< std::endl;
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// Start server thread
|
|
334
|
-
std::thread server_thread(
|
|
335
|
-
[&transport, &mux]() { RunServer(&transport, mux.get()); });
|
|
336
|
-
|
|
337
|
-
// Setup client
|
|
338
|
-
auto client_rpc = starpc::NewClientRPC("echo.Echoer", "EchoServerStream");
|
|
339
|
-
auto writer =
|
|
340
|
-
std::make_unique<InMemoryPacketWriter>(transport.ClientToServer());
|
|
341
|
-
|
|
342
|
-
// Start client receive thread
|
|
343
|
-
auto client_reader = transport.ClientReader();
|
|
344
|
-
std::atomic<bool> client_done{false};
|
|
345
|
-
std::thread client_recv_thread([&client_rpc, &client_reader, &client_done]() {
|
|
346
|
-
while (!client_done.load()) {
|
|
347
|
-
std::string data;
|
|
348
|
-
if (!InMemoryTransport::Recv(client_reader, &data, 100)) {
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
starpc::Error err = client_rpc->HandlePacketData(data);
|
|
352
|
-
if (err != starpc::Error::OK) {
|
|
353
|
-
break;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
// Send request
|
|
359
|
-
echo::EchoMsg req;
|
|
360
|
-
req.set_body(kTestBody);
|
|
361
|
-
std::string req_data;
|
|
362
|
-
req.SerializeToString(&req_data);
|
|
363
|
-
|
|
364
|
-
starpc::Error err = client_rpc->Start(writer.get(), true, req_data);
|
|
365
|
-
if (err != starpc::Error::OK) {
|
|
366
|
-
std::cerr << "FAILED: Start error: " << starpc::ErrorString(err)
|
|
367
|
-
<< std::endl;
|
|
368
|
-
client_done.store(true);
|
|
369
|
-
client_recv_thread.join();
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Read 5 responses
|
|
374
|
-
int received = 0;
|
|
375
|
-
for (int i = 0; i < 5; i++) {
|
|
376
|
-
std::string resp_data;
|
|
377
|
-
err = client_rpc->ReadOne(&resp_data);
|
|
378
|
-
if (err != starpc::Error::OK) {
|
|
379
|
-
std::cerr << "FAILED: ReadOne error at message " << i << ": "
|
|
380
|
-
<< starpc::ErrorString(err) << std::endl;
|
|
381
|
-
client_done.store(true);
|
|
382
|
-
client_recv_thread.join();
|
|
383
|
-
return false;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
echo::EchoMsg resp;
|
|
387
|
-
if (!resp.ParseFromString(resp_data)) {
|
|
388
|
-
std::cerr << "FAILED: Parse response error at message " << i << std::endl;
|
|
389
|
-
client_done.store(true);
|
|
390
|
-
client_recv_thread.join();
|
|
391
|
-
return false;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (resp.body() != kTestBody) {
|
|
395
|
-
std::cerr << "FAILED: Expected '" << kTestBody << "' got '" << resp.body()
|
|
396
|
-
<< "'" << std::endl;
|
|
397
|
-
client_done.store(true);
|
|
398
|
-
client_recv_thread.join();
|
|
399
|
-
return false;
|
|
400
|
-
}
|
|
401
|
-
received++;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (received != 5) {
|
|
405
|
-
std::cerr << "FAILED: Expected 5 messages, got " << received << std::endl;
|
|
406
|
-
client_done.store(true);
|
|
407
|
-
client_recv_thread.join();
|
|
408
|
-
return false;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Cleanup
|
|
412
|
-
client_rpc->Close();
|
|
413
|
-
writer->Close();
|
|
414
|
-
client_done.store(true);
|
|
415
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
416
|
-
|
|
417
|
-
client_recv_thread.join();
|
|
418
|
-
server_thread.join();
|
|
419
|
-
|
|
420
|
-
std::cout << "PASSED" << std::endl;
|
|
421
|
-
return true;
|
|
386
|
+
/* Fail reports a failed step and returns false. */
|
|
387
|
+
bool Fail(const std::string &step)
|
|
388
|
+
{
|
|
389
|
+
std::cerr << "FAILED: " << step << std::endl;
|
|
390
|
+
return false;
|
|
422
391
|
}
|
|
423
392
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
// Setup server
|
|
431
|
-
auto mux = starpc::NewMux();
|
|
432
|
-
EchoServerImpl server_impl;
|
|
433
|
-
auto [handler, reg_err] = echo::SRPCRegisterEchoer(mux.get(), &server_impl);
|
|
434
|
-
if (reg_err != starpc::Error::OK) {
|
|
435
|
-
std::cerr << "FAILED: Registration error: " << starpc::ErrorString(reg_err)
|
|
436
|
-
<< std::endl;
|
|
437
|
-
return false;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Start server thread
|
|
441
|
-
std::thread server_thread(
|
|
442
|
-
[&transport, &mux]() { RunServer(&transport, mux.get()); });
|
|
443
|
-
|
|
444
|
-
// Setup client
|
|
445
|
-
auto client_rpc = starpc::NewClientRPC("echo.Echoer", "EchoClientStream");
|
|
446
|
-
auto writer =
|
|
447
|
-
std::make_unique<InMemoryPacketWriter>(transport.ClientToServer());
|
|
448
|
-
|
|
449
|
-
// Start client receive thread
|
|
450
|
-
auto client_reader = transport.ClientReader();
|
|
451
|
-
std::atomic<bool> client_done{false};
|
|
452
|
-
std::thread client_recv_thread([&client_rpc, &client_reader, &client_done]() {
|
|
453
|
-
while (!client_done.load()) {
|
|
454
|
-
std::string data;
|
|
455
|
-
if (!InMemoryTransport::Recv(client_reader, &data, 100)) {
|
|
456
|
-
continue;
|
|
457
|
-
}
|
|
458
|
-
starpc::Error err = client_rpc->HandlePacketData(data);
|
|
459
|
-
if (err != starpc::Error::OK) {
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
// Send request (no initial data for streaming)
|
|
466
|
-
starpc::Error err = client_rpc->Start(writer.get(), false, "");
|
|
467
|
-
if (err != starpc::Error::OK) {
|
|
468
|
-
std::cerr << "FAILED: Start error: " << starpc::ErrorString(err)
|
|
469
|
-
<< std::endl;
|
|
470
|
-
client_done.store(true);
|
|
471
|
-
client_recv_thread.join();
|
|
472
|
-
return false;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// Send first message using WriteCallData
|
|
476
|
-
echo::EchoMsg req;
|
|
477
|
-
req.set_body(kTestBody);
|
|
478
|
-
std::string req_data;
|
|
479
|
-
req.SerializeToString(&req_data);
|
|
480
|
-
|
|
481
|
-
err = client_rpc->WriteCallData(req_data, false, false, starpc::Error::OK);
|
|
482
|
-
if (err != starpc::Error::OK) {
|
|
483
|
-
std::cerr << "FAILED: WriteCallData error: " << starpc::ErrorString(err)
|
|
484
|
-
<< std::endl;
|
|
485
|
-
client_done.store(true);
|
|
486
|
-
client_recv_thread.join();
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Close send side to indicate we're done sending
|
|
491
|
-
err = client_rpc->WriteCallData("", false, true, starpc::Error::OK);
|
|
492
|
-
if (err != starpc::Error::OK) {
|
|
493
|
-
std::cerr << "FAILED: WriteCallData (close) error: "
|
|
494
|
-
<< starpc::ErrorString(err) << std::endl;
|
|
495
|
-
client_done.store(true);
|
|
496
|
-
client_recv_thread.join();
|
|
497
|
-
return false;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// Read response
|
|
501
|
-
std::string resp_data;
|
|
502
|
-
err = client_rpc->ReadOne(&resp_data);
|
|
503
|
-
if (err != starpc::Error::OK) {
|
|
504
|
-
std::cerr << "FAILED: ReadOne error: " << starpc::ErrorString(err)
|
|
505
|
-
<< std::endl;
|
|
506
|
-
client_done.store(true);
|
|
507
|
-
client_recv_thread.join();
|
|
508
|
-
return false;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
echo::EchoMsg resp;
|
|
512
|
-
if (!resp.ParseFromString(resp_data)) {
|
|
513
|
-
std::cerr << "FAILED: Parse response error" << std::endl;
|
|
514
|
-
client_done.store(true);
|
|
515
|
-
client_recv_thread.join();
|
|
516
|
-
return false;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
if (resp.body() != kTestBody) {
|
|
520
|
-
std::cerr << "FAILED: Expected '" << kTestBody << "' got '" << resp.body()
|
|
521
|
-
<< "'" << std::endl;
|
|
522
|
-
client_done.store(true);
|
|
523
|
-
client_recv_thread.join();
|
|
524
|
-
return false;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// Cleanup
|
|
528
|
-
client_rpc->Close();
|
|
529
|
-
writer->Close();
|
|
530
|
-
client_done.store(true);
|
|
531
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
532
|
-
|
|
533
|
-
client_recv_thread.join();
|
|
534
|
-
server_thread.join();
|
|
535
|
-
|
|
536
|
-
std::cout << "PASSED" << std::endl;
|
|
537
|
-
return true;
|
|
393
|
+
/* EchoRequest returns an encoded EchoMsg carrying test_body. */
|
|
394
|
+
std::string EchoRequest()
|
|
395
|
+
{
|
|
396
|
+
echo::EchoMsg req;
|
|
397
|
+
req.set_body(test_body);
|
|
398
|
+
return req.SerializeAsString();
|
|
538
399
|
}
|
|
539
400
|
|
|
540
|
-
|
|
541
|
-
bool
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Start server thread
|
|
557
|
-
std::thread server_thread(
|
|
558
|
-
[&transport, &mux]() { RunServer(&transport, mux.get()); });
|
|
559
|
-
|
|
560
|
-
// Setup client
|
|
561
|
-
auto client_rpc = starpc::NewClientRPC("echo.Echoer", "EchoBidiStream");
|
|
562
|
-
auto writer =
|
|
563
|
-
std::make_unique<InMemoryPacketWriter>(transport.ClientToServer());
|
|
564
|
-
|
|
565
|
-
// Start client receive thread
|
|
566
|
-
auto client_reader = transport.ClientReader();
|
|
567
|
-
std::atomic<bool> client_done{false};
|
|
568
|
-
std::thread client_recv_thread([&client_rpc, &client_reader, &client_done]() {
|
|
569
|
-
while (!client_done.load()) {
|
|
570
|
-
std::string data;
|
|
571
|
-
if (!InMemoryTransport::Recv(client_reader, &data, 100)) {
|
|
572
|
-
continue;
|
|
573
|
-
}
|
|
574
|
-
starpc::Error err = client_rpc->HandlePacketData(data);
|
|
575
|
-
if (err != starpc::Error::OK) {
|
|
576
|
-
break;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
// Send request (no initial data for bidi streaming)
|
|
582
|
-
starpc::Error err = client_rpc->Start(writer.get(), false, "");
|
|
583
|
-
if (err != starpc::Error::OK) {
|
|
584
|
-
std::cerr << "FAILED: Start error: " << starpc::ErrorString(err)
|
|
585
|
-
<< std::endl;
|
|
586
|
-
client_done.store(true);
|
|
587
|
-
client_recv_thread.join();
|
|
588
|
-
return false;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// Send 3 messages and receive 3 responses
|
|
592
|
-
for (int i = 0; i < 3; i++) {
|
|
593
|
-
// Send message
|
|
594
|
-
echo::EchoMsg req;
|
|
595
|
-
req.set_body(kTestBody);
|
|
596
|
-
std::string req_data;
|
|
597
|
-
req.SerializeToString(&req_data);
|
|
598
|
-
|
|
599
|
-
err = client_rpc->WriteCallData(req_data, false, false, starpc::Error::OK);
|
|
600
|
-
if (err != starpc::Error::OK) {
|
|
601
|
-
std::cerr << "FAILED: WriteCallData error at message " << i << ": "
|
|
602
|
-
<< starpc::ErrorString(err) << std::endl;
|
|
603
|
-
client_done.store(true);
|
|
604
|
-
client_recv_thread.join();
|
|
605
|
-
return false;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
// Receive echoed response
|
|
609
|
-
std::string resp_data;
|
|
610
|
-
err = client_rpc->ReadOne(&resp_data);
|
|
611
|
-
if (err != starpc::Error::OK) {
|
|
612
|
-
std::cerr << "FAILED: ReadOne error at message " << i << ": "
|
|
613
|
-
<< starpc::ErrorString(err) << std::endl;
|
|
614
|
-
client_done.store(true);
|
|
615
|
-
client_recv_thread.join();
|
|
616
|
-
return false;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
echo::EchoMsg resp;
|
|
620
|
-
if (!resp.ParseFromString(resp_data)) {
|
|
621
|
-
std::cerr << "FAILED: Parse response error at message " << i << std::endl;
|
|
622
|
-
client_done.store(true);
|
|
623
|
-
client_recv_thread.join();
|
|
624
|
-
return false;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
if (resp.body() != kTestBody) {
|
|
628
|
-
std::cerr << "FAILED: Expected '" << kTestBody << "' got '" << resp.body()
|
|
629
|
-
<< "'" << std::endl;
|
|
630
|
-
client_done.store(true);
|
|
631
|
-
client_recv_thread.join();
|
|
632
|
-
return false;
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
// Close send side
|
|
637
|
-
err = client_rpc->WriteCallData("", false, true, starpc::Error::OK);
|
|
638
|
-
if (err != starpc::Error::OK) {
|
|
639
|
-
std::cerr << "FAILED: WriteCallData (close) error: "
|
|
640
|
-
<< starpc::ErrorString(err) << std::endl;
|
|
641
|
-
client_done.store(true);
|
|
642
|
-
client_recv_thread.join();
|
|
643
|
-
return false;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
// Cleanup
|
|
647
|
-
client_rpc->Close();
|
|
648
|
-
writer->Close();
|
|
649
|
-
client_done.store(true);
|
|
650
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
651
|
-
|
|
652
|
-
client_recv_thread.join();
|
|
653
|
-
server_thread.join();
|
|
654
|
-
|
|
655
|
-
std::cout << "PASSED" << std::endl;
|
|
656
|
-
return true;
|
|
401
|
+
/* ReadEcho reads one EchoMsg from rpc and checks that it carries test_body. */
|
|
402
|
+
bool ReadEcho(starpc::ClientRPC *rpc, const std::string &step)
|
|
403
|
+
{
|
|
404
|
+
std::string data;
|
|
405
|
+
starpc::Error err = rpc->ReadOne(&data);
|
|
406
|
+
if (err != starpc::Error::OK)
|
|
407
|
+
return Fail(step + ": read", err);
|
|
408
|
+
|
|
409
|
+
echo::EchoMsg resp;
|
|
410
|
+
if (!resp.ParseFromString(data))
|
|
411
|
+
return Fail(step + ": parse");
|
|
412
|
+
if (resp.body() != test_body)
|
|
413
|
+
return Fail(step + ": got '" + resp.body() + "'");
|
|
414
|
+
return true;
|
|
657
415
|
}
|
|
658
416
|
|
|
659
|
-
|
|
660
|
-
bool
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
EchoServerImpl server_impl;
|
|
668
|
-
auto [handler, reg_err] = echo::SRPCRegisterEchoer(mux.get(), &server_impl);
|
|
669
|
-
if (reg_err != starpc::Error::OK) {
|
|
670
|
-
std::cerr << "FAILED: Registration error: " << starpc::ErrorString(reg_err)
|
|
671
|
-
<< std::endl;
|
|
672
|
-
return false;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// Start server thread
|
|
676
|
-
std::thread server_thread(
|
|
677
|
-
[&transport, &mux]() { RunServer(&transport, mux.get()); });
|
|
678
|
-
|
|
679
|
-
// Setup client
|
|
680
|
-
auto client_rpc = starpc::NewClientRPC("echo.Echoer", "DoNothing");
|
|
681
|
-
auto writer =
|
|
682
|
-
std::make_unique<InMemoryPacketWriter>(transport.ClientToServer());
|
|
683
|
-
|
|
684
|
-
// Start client receive thread
|
|
685
|
-
auto client_reader = transport.ClientReader();
|
|
686
|
-
std::thread client_recv_thread([&client_rpc, &client_reader]() {
|
|
687
|
-
while (true) {
|
|
688
|
-
std::string data;
|
|
689
|
-
if (!InMemoryTransport::Recv(client_reader, &data)) {
|
|
690
|
-
client_rpc->HandleStreamClose(starpc::Error::EOF_);
|
|
691
|
-
break;
|
|
692
|
-
}
|
|
693
|
-
starpc::Error err = client_rpc->HandlePacketData(data);
|
|
694
|
-
if (err != starpc::Error::OK) {
|
|
695
|
-
break;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
// Send request with empty message
|
|
701
|
-
google::protobuf::Empty req;
|
|
702
|
-
std::string req_data;
|
|
703
|
-
req.SerializeToString(&req_data);
|
|
704
|
-
|
|
705
|
-
starpc::Error err = client_rpc->Start(writer.get(), true, req_data);
|
|
706
|
-
if (err != starpc::Error::OK) {
|
|
707
|
-
std::cerr << "FAILED: Start error: " << starpc::ErrorString(err)
|
|
708
|
-
<< std::endl;
|
|
709
|
-
return false;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
// Read response
|
|
713
|
-
std::string resp_data;
|
|
714
|
-
err = client_rpc->ReadOne(&resp_data);
|
|
715
|
-
if (err != starpc::Error::OK) {
|
|
716
|
-
std::cerr << "FAILED: ReadOne error: " << starpc::ErrorString(err)
|
|
717
|
-
<< std::endl;
|
|
718
|
-
return false;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
google::protobuf::Empty resp;
|
|
722
|
-
if (!resp.ParseFromString(resp_data)) {
|
|
723
|
-
std::cerr << "FAILED: Parse response error" << std::endl;
|
|
724
|
-
return false;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// Cleanup
|
|
728
|
-
client_rpc->Close();
|
|
729
|
-
writer->Close();
|
|
730
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
731
|
-
|
|
732
|
-
client_recv_thread.join();
|
|
733
|
-
server_thread.join();
|
|
734
|
-
|
|
735
|
-
std::cout << "PASSED" << std::endl;
|
|
736
|
-
return true;
|
|
417
|
+
/* TestUnary pins one unary request/reply round trip. */
|
|
418
|
+
bool TestUnary(starpc::Mux *mux)
|
|
419
|
+
{
|
|
420
|
+
TestCall call(mux, "echo.Echoer", "Echo");
|
|
421
|
+
starpc::Error err = call.Start(true, EchoRequest());
|
|
422
|
+
if (err != starpc::Error::OK)
|
|
423
|
+
return Fail("start", err);
|
|
424
|
+
return ReadEcho(call.Rpc(), "reply");
|
|
737
425
|
}
|
|
738
426
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
427
|
+
/* TestServerStream pins five responses to one request. */
|
|
428
|
+
bool TestServerStream(starpc::Mux *mux)
|
|
429
|
+
{
|
|
430
|
+
TestCall call(mux, "echo.Echoer", "EchoServerStream");
|
|
431
|
+
starpc::Error err = call.Start(true, EchoRequest());
|
|
432
|
+
if (err != starpc::Error::OK)
|
|
433
|
+
return Fail("start", err);
|
|
434
|
+
|
|
435
|
+
for (int i = 0; i < 5; i++) {
|
|
436
|
+
if (!ReadEcho(call.Rpc(), "message " + std::to_string(i)))
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
std::string extra;
|
|
441
|
+
err = call.Rpc()->ReadOne(&extra);
|
|
442
|
+
if (err != starpc::Error::EOF_)
|
|
443
|
+
return Fail("end of stream", err);
|
|
444
|
+
return true;
|
|
445
|
+
}
|
|
753
446
|
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
447
|
+
/* TestClientStream pins one reply to a streamed request. */
|
|
448
|
+
bool TestClientStream(starpc::Mux *mux)
|
|
449
|
+
{
|
|
450
|
+
TestCall call(mux, "echo.Echoer", "EchoClientStream");
|
|
451
|
+
starpc::Error err = call.Start(false, "");
|
|
452
|
+
if (err != starpc::Error::OK)
|
|
453
|
+
return Fail("start", err);
|
|
454
|
+
|
|
455
|
+
err = call.Rpc()->WriteCallData(EchoRequest(), false, false,
|
|
456
|
+
starpc::Error::OK);
|
|
457
|
+
if (err != starpc::Error::OK)
|
|
458
|
+
return Fail("send", err);
|
|
459
|
+
err = call.Rpc()->WriteCallData("", false, true, starpc::Error::OK);
|
|
460
|
+
if (err != starpc::Error::OK)
|
|
461
|
+
return Fail("close send", err);
|
|
462
|
+
return ReadEcho(call.Rpc(), "reply");
|
|
463
|
+
}
|
|
757
464
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
465
|
+
/* TestBidiStream pins echo replies to each sent message. */
|
|
466
|
+
bool TestBidiStream(starpc::Mux *mux)
|
|
467
|
+
{
|
|
468
|
+
TestCall call(mux, "echo.Echoer", "EchoBidiStream");
|
|
469
|
+
starpc::Error err = call.Start(false, "");
|
|
470
|
+
if (err != starpc::Error::OK)
|
|
471
|
+
return Fail("start", err);
|
|
472
|
+
|
|
473
|
+
for (int i = 0; i < 3; i++) {
|
|
474
|
+
const std::string step = "message " + std::to_string(i);
|
|
475
|
+
err = call.Rpc()->WriteCallData(EchoRequest(), false, false,
|
|
476
|
+
starpc::Error::OK);
|
|
477
|
+
if (err != starpc::Error::OK)
|
|
478
|
+
return Fail(step + ": send", err);
|
|
479
|
+
if (!ReadEcho(call.Rpc(), step))
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
err = call.Rpc()->WriteCallData("", false, true, starpc::Error::OK);
|
|
484
|
+
if (err != starpc::Error::OK)
|
|
485
|
+
return Fail("close send", err);
|
|
486
|
+
return true;
|
|
487
|
+
}
|
|
772
488
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
continue;
|
|
791
|
-
}
|
|
792
|
-
starpc::Error err = rpc->HandlePacketData(data);
|
|
793
|
-
if (err != starpc::Error::OK) {
|
|
794
|
-
break;
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
rpc->HandleStreamClose(starpc::Error::EOF_);
|
|
798
|
-
});
|
|
799
|
-
|
|
800
|
-
return ctx;
|
|
489
|
+
/* TestDoNothing pins an empty request and empty reply. */
|
|
490
|
+
bool TestDoNothing(starpc::Mux *mux)
|
|
491
|
+
{
|
|
492
|
+
TestCall call(mux, "echo.Echoer", "DoNothing");
|
|
493
|
+
starpc::Error err =
|
|
494
|
+
call.Start(true, google::protobuf::Empty().SerializeAsString());
|
|
495
|
+
if (err != starpc::Error::OK)
|
|
496
|
+
return Fail("start", err);
|
|
497
|
+
|
|
498
|
+
std::string data;
|
|
499
|
+
err = call.Rpc()->ReadOne(&data);
|
|
500
|
+
if (err != starpc::Error::OK)
|
|
501
|
+
return Fail("read", err);
|
|
502
|
+
google::protobuf::Empty resp;
|
|
503
|
+
if (!resp.ParseFromString(data))
|
|
504
|
+
return Fail("parse");
|
|
505
|
+
return true;
|
|
801
506
|
}
|
|
802
507
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
err = ctx->client_rpc->WriteCallData(init_data, false, false,
|
|
861
|
-
starpc::Error::OK);
|
|
862
|
-
if (err != starpc::Error::OK) {
|
|
863
|
-
std::cerr << "FAILED: Send init error: " << starpc::ErrorString(err)
|
|
864
|
-
<< std::endl;
|
|
865
|
-
ctx->done.store(true);
|
|
866
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
867
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
868
|
-
server_thread.join();
|
|
869
|
-
return false;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
// Read ack packet
|
|
873
|
-
std::string ack_data;
|
|
874
|
-
err = ctx->client_rpc->ReadOne(&ack_data);
|
|
875
|
-
if (err != starpc::Error::OK) {
|
|
876
|
-
std::cerr << "FAILED: Read ack error: " << starpc::ErrorString(err)
|
|
877
|
-
<< std::endl;
|
|
878
|
-
ctx->done.store(true);
|
|
879
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
880
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
881
|
-
server_thread.join();
|
|
882
|
-
return false;
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
rpcstream::RpcStreamPacket ack_pkt;
|
|
886
|
-
if (!ack_pkt.ParseFromString(ack_data) || !ack_pkt.has_ack()) {
|
|
887
|
-
std::cerr << "FAILED: Invalid ack packet" << std::endl;
|
|
888
|
-
ctx->done.store(true);
|
|
889
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
890
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
891
|
-
server_thread.join();
|
|
892
|
-
return false;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
if (!ack_pkt.ack().error().empty()) {
|
|
896
|
-
std::cerr << "FAILED: Ack error: " << ack_pkt.ack().error() << std::endl;
|
|
897
|
-
ctx->done.store(true);
|
|
898
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
899
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
900
|
-
server_thread.join();
|
|
901
|
-
return false;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
// Create CallStart packet for Echo call
|
|
905
|
-
echo::EchoMsg req;
|
|
906
|
-
req.set_body(kTestBody);
|
|
907
|
-
std::string req_data;
|
|
908
|
-
req.SerializeToString(&req_data);
|
|
909
|
-
auto call_start =
|
|
910
|
-
starpc::NewCallStartPacket("echo.Echoer", "Echo", req_data, true);
|
|
911
|
-
|
|
912
|
-
// Wrap in RpcStreamPacket and send
|
|
913
|
-
std::string call_start_data;
|
|
914
|
-
call_start->SerializeToString(&call_start_data);
|
|
915
|
-
rpcstream::RpcStreamPacket data_pkt;
|
|
916
|
-
data_pkt.set_data(call_start_data);
|
|
917
|
-
std::string pkt_data;
|
|
918
|
-
data_pkt.SerializeToString(&pkt_data);
|
|
919
|
-
err =
|
|
920
|
-
ctx->client_rpc->WriteCallData(pkt_data, false, false, starpc::Error::OK);
|
|
921
|
-
if (err != starpc::Error::OK) {
|
|
922
|
-
std::cerr << "FAILED: Send CallStart error: " << starpc::ErrorString(err)
|
|
923
|
-
<< std::endl;
|
|
924
|
-
ctx->done.store(true);
|
|
925
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
926
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
927
|
-
server_thread.join();
|
|
928
|
-
return false;
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
// Read response (RpcStreamPacket containing srpc::Packet with CallData)
|
|
932
|
-
std::string resp_data;
|
|
933
|
-
err = ctx->client_rpc->ReadOne(&resp_data);
|
|
934
|
-
if (err != starpc::Error::OK) {
|
|
935
|
-
std::cerr << "FAILED: Read response error: " << starpc::ErrorString(err)
|
|
936
|
-
<< std::endl;
|
|
937
|
-
ctx->done.store(true);
|
|
938
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
939
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
940
|
-
server_thread.join();
|
|
941
|
-
return false;
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
rpcstream::RpcStreamPacket resp_pkt;
|
|
945
|
-
if (!resp_pkt.ParseFromString(resp_data) || !resp_pkt.has_data()) {
|
|
946
|
-
std::cerr << "FAILED: Invalid response packet" << std::endl;
|
|
947
|
-
ctx->done.store(true);
|
|
948
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
949
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
950
|
-
server_thread.join();
|
|
951
|
-
return false;
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
srpc::Packet inner_pkt;
|
|
955
|
-
if (!inner_pkt.ParseFromString(resp_pkt.data()) ||
|
|
956
|
-
!inner_pkt.has_call_data()) {
|
|
957
|
-
std::cerr << "FAILED: Invalid inner packet" << std::endl;
|
|
958
|
-
ctx->done.store(true);
|
|
959
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
960
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
961
|
-
server_thread.join();
|
|
962
|
-
return false;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
echo::EchoMsg resp;
|
|
966
|
-
if (!resp.ParseFromString(inner_pkt.call_data().data())) {
|
|
967
|
-
std::cerr << "FAILED: Parse EchoMsg error" << std::endl;
|
|
968
|
-
ctx->done.store(true);
|
|
969
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
970
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
971
|
-
server_thread.join();
|
|
972
|
-
return false;
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
if (resp.body() != kTestBody) {
|
|
976
|
-
std::cerr << "FAILED: Expected '" << kTestBody << "' got '" << resp.body()
|
|
977
|
-
<< "'" << std::endl;
|
|
978
|
-
ctx->client_rpc->Close();
|
|
979
|
-
ctx->done.store(true);
|
|
980
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
981
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
982
|
-
server_thread.join();
|
|
983
|
-
return false;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
// Close the RPC to signal server we're done
|
|
987
|
-
ctx->client_rpc->Close();
|
|
988
|
-
|
|
989
|
-
// Cleanup
|
|
990
|
-
ctx->done.store(true);
|
|
991
|
-
InMemoryTransport::Close(transport.ClientReader());
|
|
992
|
-
InMemoryTransport::Close(transport.ServerReader());
|
|
993
|
-
server_thread.join();
|
|
994
|
-
|
|
995
|
-
std::cout << "PASSED" << std::endl;
|
|
996
|
-
return true;
|
|
508
|
+
/*
|
|
509
|
+
* TestRpcStream pins a nested call: the client opens an RpcStream, the server
|
|
510
|
+
* answers init, and the nested Echo call returns through the nested mux.
|
|
511
|
+
*/
|
|
512
|
+
bool TestRpcStream(starpc::Mux *mux)
|
|
513
|
+
{
|
|
514
|
+
TestCall call(mux, "echo.Echoer", "RpcStream");
|
|
515
|
+
starpc::ClientRPC *rpc = call.Rpc();
|
|
516
|
+
starpc::Error err = call.Start(false, "");
|
|
517
|
+
if (err != starpc::Error::OK)
|
|
518
|
+
return Fail("start", err);
|
|
519
|
+
|
|
520
|
+
rpcstream::RpcStreamPacket init_pkt;
|
|
521
|
+
init_pkt.mutable_init()->set_component_id("");
|
|
522
|
+
err = rpc->WriteCallData(init_pkt.SerializeAsString(), false, false,
|
|
523
|
+
starpc::Error::OK);
|
|
524
|
+
if (err != starpc::Error::OK)
|
|
525
|
+
return Fail("send init", err);
|
|
526
|
+
|
|
527
|
+
std::string ack_data;
|
|
528
|
+
err = rpc->ReadOne(&ack_data);
|
|
529
|
+
if (err != starpc::Error::OK)
|
|
530
|
+
return Fail("read ack", err);
|
|
531
|
+
rpcstream::RpcStreamPacket ack_pkt;
|
|
532
|
+
if (!ack_pkt.ParseFromString(ack_data) || !ack_pkt.has_ack())
|
|
533
|
+
return Fail("invalid ack packet");
|
|
534
|
+
if (!ack_pkt.ack().error().empty())
|
|
535
|
+
return Fail("ack error: " + ack_pkt.ack().error());
|
|
536
|
+
|
|
537
|
+
/* The nested call starts inside an RpcStream data packet. */
|
|
538
|
+
auto call_start = starpc::NewCallStartPacket("echo.Echoer", "Echo",
|
|
539
|
+
EchoRequest(), true);
|
|
540
|
+
rpcstream::RpcStreamPacket data_pkt;
|
|
541
|
+
data_pkt.set_data(call_start->SerializeAsString());
|
|
542
|
+
err = rpc->WriteCallData(data_pkt.SerializeAsString(), false, false,
|
|
543
|
+
starpc::Error::OK);
|
|
544
|
+
if (err != starpc::Error::OK)
|
|
545
|
+
return Fail("send call start", err);
|
|
546
|
+
|
|
547
|
+
/* The reply is an RpcStream packet holding a CallData packet. */
|
|
548
|
+
std::string resp_data;
|
|
549
|
+
err = rpc->ReadOne(&resp_data);
|
|
550
|
+
if (err != starpc::Error::OK)
|
|
551
|
+
return Fail("read reply", err);
|
|
552
|
+
rpcstream::RpcStreamPacket resp_pkt;
|
|
553
|
+
if (!resp_pkt.ParseFromString(resp_data) || !resp_pkt.has_data())
|
|
554
|
+
return Fail("invalid reply packet");
|
|
555
|
+
srpc::Packet inner_pkt;
|
|
556
|
+
if (!inner_pkt.ParseFromString(resp_pkt.data()) ||
|
|
557
|
+
!inner_pkt.has_call_data())
|
|
558
|
+
return Fail("invalid inner packet");
|
|
559
|
+
echo::EchoMsg resp;
|
|
560
|
+
if (!resp.ParseFromString(inner_pkt.call_data().data()))
|
|
561
|
+
return Fail("parse reply");
|
|
562
|
+
if (resp.body() != test_body)
|
|
563
|
+
return Fail("got '" + resp.body() + "'");
|
|
564
|
+
return true;
|
|
997
565
|
}
|
|
998
566
|
|
|
999
567
|
} // namespace
|
|
1000
568
|
|
|
1001
|
-
int main()
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
if (TestRpcStream()) {
|
|
1038
|
-
passed++;
|
|
1039
|
-
} else {
|
|
1040
|
-
failed++;
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
std::cout << std::endl;
|
|
1044
|
-
std::cout << "Results: " << passed << " passed, " << failed << " failed"
|
|
1045
|
-
<< std::endl;
|
|
1046
|
-
|
|
1047
|
-
return failed > 0 ? 1 : 0;
|
|
569
|
+
int main()
|
|
570
|
+
{
|
|
571
|
+
std::cout << "=== starpc C++ E2E Tests ===" << std::endl;
|
|
572
|
+
|
|
573
|
+
EchoServer server;
|
|
574
|
+
starpc::Error err = server.Register();
|
|
575
|
+
if (err != starpc::Error::OK) {
|
|
576
|
+
Fail("register", err);
|
|
577
|
+
return 1;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const std::pair<const char *, bool (*)(starpc::Mux *)> tests[] = {
|
|
581
|
+
{"Unary", TestUnary},
|
|
582
|
+
{"ServerStream", TestServerStream},
|
|
583
|
+
{"ClientStream", TestClientStream},
|
|
584
|
+
{"BidiStream", TestBidiStream},
|
|
585
|
+
{"DoNothing", TestDoNothing},
|
|
586
|
+
{"RpcStream", TestRpcStream},
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
int passed = 0;
|
|
590
|
+
int failed = 0;
|
|
591
|
+
for (const auto &[name, test] : tests) {
|
|
592
|
+
std::cout << "Testing " << name << " RPC... " << std::flush;
|
|
593
|
+
if (test(server.mux.get())) {
|
|
594
|
+
std::cout << "PASSED" << std::endl;
|
|
595
|
+
passed++;
|
|
596
|
+
} else {
|
|
597
|
+
failed++;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
std::cout << std::endl;
|
|
602
|
+
std::cout << "Results: " << passed << " passed, " << failed << " failed"
|
|
603
|
+
<< std::endl;
|
|
604
|
+
return failed > 0 ? 1 : 0;
|
|
1048
605
|
}
|