1*61c4878aSAndroid Build Coastguard Worker // Copyright 2022 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker #include "pw_preprocessor/compiler.h"
16*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/hash.h"
17*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/test_utils.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/pwpb/test_method_context.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_pwpb_private/internal_test_utils.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_test_protos/test.rpc.pwpb.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
22*61c4878aSAndroid Build Coastguard Worker
23*61c4878aSAndroid Build Coastguard Worker PW_MODIFY_DIAGNOSTICS_PUSH();
24*61c4878aSAndroid Build Coastguard Worker PW_MODIFY_DIAGNOSTIC(ignored, "-Wmissing-field-initializers");
25*61c4878aSAndroid Build Coastguard Worker
26*61c4878aSAndroid Build Coastguard Worker namespace pw::rpc {
27*61c4878aSAndroid Build Coastguard Worker namespace test {
28*61c4878aSAndroid Build Coastguard Worker
29*61c4878aSAndroid Build Coastguard Worker class TestService final
30*61c4878aSAndroid Build Coastguard Worker : public pw_rpc::pwpb::TestService::Service<TestService> {
31*61c4878aSAndroid Build Coastguard Worker public:
TestUnaryRpc(const pwpb::TestRequest::Message & request,pwpb::TestResponse::Message & response)32*61c4878aSAndroid Build Coastguard Worker Status TestUnaryRpc(const pwpb::TestRequest::Message& request,
33*61c4878aSAndroid Build Coastguard Worker pwpb::TestResponse::Message& response) {
34*61c4878aSAndroid Build Coastguard Worker response.value = request.integer + 1;
35*61c4878aSAndroid Build Coastguard Worker return static_cast<Status::Code>(request.status_code);
36*61c4878aSAndroid Build Coastguard Worker }
37*61c4878aSAndroid Build Coastguard Worker
TestAnotherUnaryRpc(const pwpb::TestRequest::Message & request,PwpbUnaryResponder<pwpb::TestResponse::Message> & responder)38*61c4878aSAndroid Build Coastguard Worker void TestAnotherUnaryRpc(
39*61c4878aSAndroid Build Coastguard Worker const pwpb::TestRequest::Message& request,
40*61c4878aSAndroid Build Coastguard Worker PwpbUnaryResponder<pwpb::TestResponse::Message>& responder) {
41*61c4878aSAndroid Build Coastguard Worker pwpb::TestResponse::Message response{};
42*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
43*61c4878aSAndroid Build Coastguard Worker responder.Finish(response, TestUnaryRpc(request, response)));
44*61c4878aSAndroid Build Coastguard Worker }
45*61c4878aSAndroid Build Coastguard Worker
TestServerStreamRpc(const pwpb::TestRequest::Message & request,ServerWriter<pwpb::TestStreamResponse::Message> & writer)46*61c4878aSAndroid Build Coastguard Worker static void TestServerStreamRpc(
47*61c4878aSAndroid Build Coastguard Worker const pwpb::TestRequest::Message& request,
48*61c4878aSAndroid Build Coastguard Worker ServerWriter<pwpb::TestStreamResponse::Message>& writer) {
49*61c4878aSAndroid Build Coastguard Worker for (int i = 0; i < request.integer; ++i) {
50*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
51*61c4878aSAndroid Build Coastguard Worker OkStatus(),
52*61c4878aSAndroid Build Coastguard Worker writer.Write({.chunk = {}, .number = static_cast<uint32_t>(i)}));
53*61c4878aSAndroid Build Coastguard Worker }
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
56*61c4878aSAndroid Build Coastguard Worker writer.Finish(static_cast<Status::Code>(request.status_code)));
57*61c4878aSAndroid Build Coastguard Worker }
58*61c4878aSAndroid Build Coastguard Worker
TestClientStreamRpc(ServerReader<pwpb::TestRequest::Message,pwpb::TestStreamResponse::Message> & new_reader)59*61c4878aSAndroid Build Coastguard Worker void TestClientStreamRpc(
60*61c4878aSAndroid Build Coastguard Worker ServerReader<pwpb::TestRequest::Message,
61*61c4878aSAndroid Build Coastguard Worker pwpb::TestStreamResponse::Message>& new_reader) {
62*61c4878aSAndroid Build Coastguard Worker reader = std::move(new_reader);
63*61c4878aSAndroid Build Coastguard Worker }
64*61c4878aSAndroid Build Coastguard Worker
TestBidirectionalStreamRpc(ServerReaderWriter<pwpb::TestRequest::Message,pwpb::TestStreamResponse::Message> & new_reader_writer)65*61c4878aSAndroid Build Coastguard Worker void TestBidirectionalStreamRpc(
66*61c4878aSAndroid Build Coastguard Worker ServerReaderWriter<pwpb::TestRequest::Message,
67*61c4878aSAndroid Build Coastguard Worker pwpb::TestStreamResponse::Message>&
68*61c4878aSAndroid Build Coastguard Worker new_reader_writer) {
69*61c4878aSAndroid Build Coastguard Worker reader_writer = std::move(new_reader_writer);
70*61c4878aSAndroid Build Coastguard Worker }
71*61c4878aSAndroid Build Coastguard Worker
72*61c4878aSAndroid Build Coastguard Worker ServerReader<pwpb::TestRequest::Message, pwpb::TestStreamResponse::Message>
73*61c4878aSAndroid Build Coastguard Worker reader;
74*61c4878aSAndroid Build Coastguard Worker ServerReaderWriter<pwpb::TestRequest::Message,
75*61c4878aSAndroid Build Coastguard Worker pwpb::TestStreamResponse::Message>
76*61c4878aSAndroid Build Coastguard Worker reader_writer;
77*61c4878aSAndroid Build Coastguard Worker };
78*61c4878aSAndroid Build Coastguard Worker
79*61c4878aSAndroid Build Coastguard Worker } // namespace test
80*61c4878aSAndroid Build Coastguard Worker
81*61c4878aSAndroid Build Coastguard Worker namespace {
82*61c4878aSAndroid Build Coastguard Worker
83*61c4878aSAndroid Build Coastguard Worker using internal::ClientContextForTest;
84*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,CompilesProperly)85*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, CompilesProperly) {
86*61c4878aSAndroid Build Coastguard Worker test::TestService service;
87*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(internal::UnwrapServiceId(service.service_id()),
88*61c4878aSAndroid Build Coastguard Worker internal::Hash("pw.rpc.test.TestService"));
89*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(service.name(), "TestService");
90*61c4878aSAndroid Build Coastguard Worker }
91*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Server_InvokeUnaryRpc)92*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Server_InvokeUnaryRpc) {
93*61c4878aSAndroid Build Coastguard Worker PW_PWPB_TEST_METHOD_CONTEXT(test::TestService, TestUnaryRpc) context;
94*61c4878aSAndroid Build Coastguard Worker
95*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
96*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 123, .status_code = OkStatus().code()}));
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(124, context.response().value);
99*61c4878aSAndroid Build Coastguard Worker
100*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::InvalidArgument(),
101*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 999,
102*61c4878aSAndroid Build Coastguard Worker .status_code = Status::InvalidArgument().code()}));
103*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1000, context.response().value);
104*61c4878aSAndroid Build Coastguard Worker }
105*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Server_InvokeAsyncUnaryRpc)106*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Server_InvokeAsyncUnaryRpc) {
107*61c4878aSAndroid Build Coastguard Worker PW_PWPB_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) context;
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 123, .status_code = OkStatus().code()});
110*61c4878aSAndroid Build Coastguard Worker
111*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.status());
112*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(124, context.response().value);
113*61c4878aSAndroid Build Coastguard Worker
114*61c4878aSAndroid Build Coastguard Worker context.call(
115*61c4878aSAndroid Build Coastguard Worker {.integer = 999, .status_code = Status::InvalidArgument().code()});
116*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::InvalidArgument(), context.status());
117*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1000, context.response().value);
118*61c4878aSAndroid Build Coastguard Worker }
119*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Server_InvokeServerStreamingRpc)120*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Server_InvokeServerStreamingRpc) {
121*61c4878aSAndroid Build Coastguard Worker PW_PWPB_TEST_METHOD_CONTEXT(test::TestService, TestServerStreamRpc) context;
122*61c4878aSAndroid Build Coastguard Worker
123*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 0, .status_code = Status::Aborted().code()});
124*61c4878aSAndroid Build Coastguard Worker
125*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Aborted(), context.status());
126*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(context.done());
127*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.total_responses(), 0u);
128*61c4878aSAndroid Build Coastguard Worker
129*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 4, .status_code = OkStatus().code()});
130*61c4878aSAndroid Build Coastguard Worker
131*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(4u, context.responses().size());
132*61c4878aSAndroid Build Coastguard Worker
133*61c4878aSAndroid Build Coastguard Worker for (size_t i = 0; i < context.responses().size(); ++i) {
134*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[i].number, i);
135*61c4878aSAndroid Build Coastguard Worker }
136*61c4878aSAndroid Build Coastguard Worker
137*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus().code(), context.status());
138*61c4878aSAndroid Build Coastguard Worker }
139*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Server_InvokeServerStreamingRpc_ManualWriting)140*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Server_InvokeServerStreamingRpc_ManualWriting) {
141*61c4878aSAndroid Build Coastguard Worker PW_PWPB_TEST_METHOD_CONTEXT(test::TestService, TestServerStreamRpc, 4)
142*61c4878aSAndroid Build Coastguard Worker context;
143*61c4878aSAndroid Build Coastguard Worker
144*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(4u, context.max_packets());
145*61c4878aSAndroid Build Coastguard Worker
146*61c4878aSAndroid Build Coastguard Worker auto writer = context.writer();
147*61c4878aSAndroid Build Coastguard Worker
148*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Write({.chunk = {}, .number = 3}));
149*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Write({.chunk = {}, .number = 6}));
150*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Write({.chunk = {}, .number = 9}));
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(context.done());
153*61c4878aSAndroid Build Coastguard Worker
154*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Finish(Status::Cancelled()));
155*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(context.done());
156*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Cancelled(), context.status());
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(3u, context.responses().size());
159*61c4878aSAndroid Build Coastguard Worker
160*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[0].number, 3u);
161*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[1].number, 6u);
162*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[2].number, 9u);
163*61c4878aSAndroid Build Coastguard Worker }
164*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Server_InvokeClientStreamingRpc)165*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Server_InvokeClientStreamingRpc) {
166*61c4878aSAndroid Build Coastguard Worker PW_PWPB_TEST_METHOD_CONTEXT(test::TestService, TestClientStreamRpc) context;
167*61c4878aSAndroid Build Coastguard Worker
168*61c4878aSAndroid Build Coastguard Worker context.call();
169*61c4878aSAndroid Build Coastguard Worker
170*61c4878aSAndroid Build Coastguard Worker test::pwpb::TestRequest::Message request = {};
171*61c4878aSAndroid Build Coastguard Worker context.service().reader.set_on_next(
172*61c4878aSAndroid Build Coastguard Worker [&request](const test::pwpb::TestRequest::Message& req) {
173*61c4878aSAndroid Build Coastguard Worker request = req;
174*61c4878aSAndroid Build Coastguard Worker });
175*61c4878aSAndroid Build Coastguard Worker
176*61c4878aSAndroid Build Coastguard Worker context.SendClientStream({.integer = -99, .status_code = 10});
177*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.integer, -99);
178*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.status_code, 10u);
179*61c4878aSAndroid Build Coastguard Worker
180*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
181*61c4878aSAndroid Build Coastguard Worker context.service().reader.Finish({.chunk = {}, .number = 3},
182*61c4878aSAndroid Build Coastguard Worker Status::Unimplemented()));
183*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Unimplemented(), context.status());
184*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.response().number, 3u);
185*61c4878aSAndroid Build Coastguard Worker }
186*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Server_InvokeBidirectionalStreamingRpc)187*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Server_InvokeBidirectionalStreamingRpc) {
188*61c4878aSAndroid Build Coastguard Worker PW_PWPB_TEST_METHOD_CONTEXT(test::TestService, TestBidirectionalStreamRpc)
189*61c4878aSAndroid Build Coastguard Worker context;
190*61c4878aSAndroid Build Coastguard Worker
191*61c4878aSAndroid Build Coastguard Worker context.call();
192*61c4878aSAndroid Build Coastguard Worker
193*61c4878aSAndroid Build Coastguard Worker test::pwpb::TestRequest::Message request = {};
194*61c4878aSAndroid Build Coastguard Worker context.service().reader_writer.set_on_next(
195*61c4878aSAndroid Build Coastguard Worker [&request](const test::pwpb::TestRequest::Message& req) {
196*61c4878aSAndroid Build Coastguard Worker request = req;
197*61c4878aSAndroid Build Coastguard Worker });
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker context.SendClientStream({.integer = -99, .status_code = 10});
200*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.integer, -99);
201*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.status_code, 10u);
202*61c4878aSAndroid Build Coastguard Worker
203*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
204*61c4878aSAndroid Build Coastguard Worker context.service().reader_writer.Write({.chunk = {}, .number = 2}));
205*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[0].number, 2u);
206*61c4878aSAndroid Build Coastguard Worker
207*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
208*61c4878aSAndroid Build Coastguard Worker context.service().reader_writer.Finish(Status::NotFound()));
209*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::NotFound(), context.status());
210*61c4878aSAndroid Build Coastguard Worker }
211*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,ClientCall_DefaultConstructor)212*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, ClientCall_DefaultConstructor) {
213*61c4878aSAndroid Build Coastguard Worker PwpbUnaryReceiver<test::pwpb::TestResponse::Message> unary_call;
214*61c4878aSAndroid Build Coastguard Worker PwpbClientReader<test::pwpb::TestStreamResponse::Message>
215*61c4878aSAndroid Build Coastguard Worker server_streaming_call;
216*61c4878aSAndroid Build Coastguard Worker }
217*61c4878aSAndroid Build Coastguard Worker
218*61c4878aSAndroid Build Coastguard Worker using TestServiceClient = test::pw_rpc::pwpb::TestService::Client;
219*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Client_InvokesUnaryRpcWithCallback)220*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Client_InvokesUnaryRpcWithCallback) {
221*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
222*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestUnaryRpc");
223*61c4878aSAndroid Build Coastguard Worker
224*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
225*61c4878aSAndroid Build Coastguard Worker
226*61c4878aSAndroid Build Coastguard Worker TestServiceClient test_client(context.client(), context.channel().id());
227*61c4878aSAndroid Build Coastguard Worker
228*61c4878aSAndroid Build Coastguard Worker struct {
229*61c4878aSAndroid Build Coastguard Worker Status last_status = Status::Unknown();
230*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
231*61c4878aSAndroid Build Coastguard Worker } result;
232*61c4878aSAndroid Build Coastguard Worker
233*61c4878aSAndroid Build Coastguard Worker auto call = test_client.TestUnaryRpc(
234*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
235*61c4878aSAndroid Build Coastguard Worker [&result](const test::pwpb::TestResponse::Message& response,
236*61c4878aSAndroid Build Coastguard Worker Status status) {
237*61c4878aSAndroid Build Coastguard Worker result.last_status = status;
238*61c4878aSAndroid Build Coastguard Worker result.response_value = response.value;
239*61c4878aSAndroid Build Coastguard Worker });
240*61c4878aSAndroid Build Coastguard Worker
241*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
242*61c4878aSAndroid Build Coastguard Worker
243*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
244*61c4878aSAndroid Build Coastguard Worker auto packet =
245*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
246*61c4878aSAndroid Build Coastguard Worker .last_packet();
247*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
248*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
249*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
250*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(test::pwpb::TestRequest, sent_proto, packet.payload());
251*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
252*61c4878aSAndroid Build Coastguard Worker
253*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(test::pwpb::TestResponse, response, .value = 42);
254*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(OkStatus(), response));
255*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.last_status, OkStatus());
256*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 42);
257*61c4878aSAndroid Build Coastguard Worker
258*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(call.active());
259*61c4878aSAndroid Build Coastguard Worker }
260*61c4878aSAndroid Build Coastguard Worker
261*61c4878aSAndroid Build Coastguard Worker #if PW_RPC_DYNAMIC_ALLOCATION
262*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,DynamicClient_InvokesUnaryRpcWithCallback)263*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, DynamicClient_InvokesUnaryRpcWithCallback) {
264*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
265*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestUnaryRpc");
266*61c4878aSAndroid Build Coastguard Worker
267*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
268*61c4878aSAndroid Build Coastguard Worker
269*61c4878aSAndroid Build Coastguard Worker test::pw_rpc::pwpb::TestService::DynamicClient test_client(
270*61c4878aSAndroid Build Coastguard Worker context.client(), context.channel().id());
271*61c4878aSAndroid Build Coastguard Worker
272*61c4878aSAndroid Build Coastguard Worker struct {
273*61c4878aSAndroid Build Coastguard Worker Status last_status = Status::Unknown();
274*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
275*61c4878aSAndroid Build Coastguard Worker } result;
276*61c4878aSAndroid Build Coastguard Worker
277*61c4878aSAndroid Build Coastguard Worker auto call = test_client.TestUnaryRpc(
278*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
279*61c4878aSAndroid Build Coastguard Worker [&result](const test::pwpb::TestResponse::Message& response,
280*61c4878aSAndroid Build Coastguard Worker Status status) {
281*61c4878aSAndroid Build Coastguard Worker result.last_status = status;
282*61c4878aSAndroid Build Coastguard Worker result.response_value = response.value;
283*61c4878aSAndroid Build Coastguard Worker });
284*61c4878aSAndroid Build Coastguard Worker
285*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call->active());
286*61c4878aSAndroid Build Coastguard Worker
287*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
288*61c4878aSAndroid Build Coastguard Worker auto packet =
289*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
290*61c4878aSAndroid Build Coastguard Worker .last_packet();
291*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
292*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
293*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
294*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(test::pwpb::TestRequest, sent_proto, packet.payload());
295*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
296*61c4878aSAndroid Build Coastguard Worker
297*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(test::pwpb::TestResponse, response, .value = 42);
298*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(OkStatus(), response));
299*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.last_status, OkStatus());
300*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 42);
301*61c4878aSAndroid Build Coastguard Worker
302*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(call->active());
303*61c4878aSAndroid Build Coastguard Worker }
304*61c4878aSAndroid Build Coastguard Worker
305*61c4878aSAndroid Build Coastguard Worker #endif // PW_RPC_DYNAMIC_ALLOCATION
306*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Client_InvokesServerStreamingRpcWithCallback)307*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Client_InvokesServerStreamingRpcWithCallback) {
308*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
309*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestServerStreamRpc");
310*61c4878aSAndroid Build Coastguard Worker
311*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
312*61c4878aSAndroid Build Coastguard Worker
313*61c4878aSAndroid Build Coastguard Worker TestServiceClient test_client(context.client(), context.channel().id());
314*61c4878aSAndroid Build Coastguard Worker
315*61c4878aSAndroid Build Coastguard Worker struct {
316*61c4878aSAndroid Build Coastguard Worker bool active = true;
317*61c4878aSAndroid Build Coastguard Worker Status stream_status = Status::Unknown();
318*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
319*61c4878aSAndroid Build Coastguard Worker } result;
320*61c4878aSAndroid Build Coastguard Worker
321*61c4878aSAndroid Build Coastguard Worker auto call = test_client.TestServerStreamRpc(
322*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
323*61c4878aSAndroid Build Coastguard Worker [&result](const test::pwpb::TestStreamResponse::Message& response) {
324*61c4878aSAndroid Build Coastguard Worker result.active = true;
325*61c4878aSAndroid Build Coastguard Worker result.response_value = response.number;
326*61c4878aSAndroid Build Coastguard Worker },
327*61c4878aSAndroid Build Coastguard Worker [&result](Status status) {
328*61c4878aSAndroid Build Coastguard Worker result.active = false;
329*61c4878aSAndroid Build Coastguard Worker result.stream_status = status;
330*61c4878aSAndroid Build Coastguard Worker });
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
333*61c4878aSAndroid Build Coastguard Worker
334*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
335*61c4878aSAndroid Build Coastguard Worker auto packet =
336*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
337*61c4878aSAndroid Build Coastguard Worker .last_packet();
338*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
339*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
340*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
341*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(test::pwpb::TestRequest, sent_proto, packet.payload());
342*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
343*61c4878aSAndroid Build Coastguard Worker
344*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(
345*61c4878aSAndroid Build Coastguard Worker test::pwpb::TestStreamResponse, response, .chunk = {}, .number = 11u);
346*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendServerStream(response));
347*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(result.active);
348*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 11);
349*61c4878aSAndroid Build Coastguard Worker
350*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(Status::NotFound()));
351*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(result.active);
352*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.stream_status, Status::NotFound());
353*61c4878aSAndroid Build Coastguard Worker }
354*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Client_StaticMethod_InvokesUnaryRpcWithCallback)355*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Client_StaticMethod_InvokesUnaryRpcWithCallback) {
356*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
357*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestUnaryRpc");
358*61c4878aSAndroid Build Coastguard Worker
359*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
360*61c4878aSAndroid Build Coastguard Worker
361*61c4878aSAndroid Build Coastguard Worker struct {
362*61c4878aSAndroid Build Coastguard Worker Status last_status = Status::Unknown();
363*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
364*61c4878aSAndroid Build Coastguard Worker } result;
365*61c4878aSAndroid Build Coastguard Worker
366*61c4878aSAndroid Build Coastguard Worker auto call = test::pw_rpc::pwpb::TestService::TestUnaryRpc(
367*61c4878aSAndroid Build Coastguard Worker context.client(),
368*61c4878aSAndroid Build Coastguard Worker context.channel().id(),
369*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
370*61c4878aSAndroid Build Coastguard Worker [&result](const test::pwpb::TestResponse::Message& response,
371*61c4878aSAndroid Build Coastguard Worker Status status) {
372*61c4878aSAndroid Build Coastguard Worker result.last_status = status;
373*61c4878aSAndroid Build Coastguard Worker result.response_value = response.value;
374*61c4878aSAndroid Build Coastguard Worker });
375*61c4878aSAndroid Build Coastguard Worker
376*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
377*61c4878aSAndroid Build Coastguard Worker
378*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
379*61c4878aSAndroid Build Coastguard Worker auto packet =
380*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
381*61c4878aSAndroid Build Coastguard Worker .last_packet();
382*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
383*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
384*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
385*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(test::pwpb::TestRequest, sent_proto, packet.payload());
386*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
387*61c4878aSAndroid Build Coastguard Worker
388*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(test::pwpb::TestResponse, response, .value = 42);
389*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(OkStatus(), response));
390*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.last_status, OkStatus());
391*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 42);
392*61c4878aSAndroid Build Coastguard Worker }
393*61c4878aSAndroid Build Coastguard Worker
TEST(PwpbCodegen,Client_StaticMethod_InvokesServerStreamingRpcWithCallback)394*61c4878aSAndroid Build Coastguard Worker TEST(PwpbCodegen, Client_StaticMethod_InvokesServerStreamingRpcWithCallback) {
395*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
396*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestServerStreamRpc");
397*61c4878aSAndroid Build Coastguard Worker
398*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
399*61c4878aSAndroid Build Coastguard Worker
400*61c4878aSAndroid Build Coastguard Worker struct {
401*61c4878aSAndroid Build Coastguard Worker bool active = true;
402*61c4878aSAndroid Build Coastguard Worker Status stream_status = Status::Unknown();
403*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
404*61c4878aSAndroid Build Coastguard Worker } result;
405*61c4878aSAndroid Build Coastguard Worker
406*61c4878aSAndroid Build Coastguard Worker auto call = test::pw_rpc::pwpb::TestService::TestServerStreamRpc(
407*61c4878aSAndroid Build Coastguard Worker context.client(),
408*61c4878aSAndroid Build Coastguard Worker context.channel().id(),
409*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
410*61c4878aSAndroid Build Coastguard Worker [&result](const test::pwpb::TestStreamResponse::Message& response) {
411*61c4878aSAndroid Build Coastguard Worker result.active = true;
412*61c4878aSAndroid Build Coastguard Worker result.response_value = response.number;
413*61c4878aSAndroid Build Coastguard Worker },
414*61c4878aSAndroid Build Coastguard Worker [&result](Status status) {
415*61c4878aSAndroid Build Coastguard Worker result.active = false;
416*61c4878aSAndroid Build Coastguard Worker result.stream_status = status;
417*61c4878aSAndroid Build Coastguard Worker });
418*61c4878aSAndroid Build Coastguard Worker
419*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
420*61c4878aSAndroid Build Coastguard Worker
421*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
422*61c4878aSAndroid Build Coastguard Worker auto packet =
423*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
424*61c4878aSAndroid Build Coastguard Worker .last_packet();
425*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
426*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
427*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
428*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(test::pwpb::TestRequest, sent_proto, packet.payload());
429*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
430*61c4878aSAndroid Build Coastguard Worker
431*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(
432*61c4878aSAndroid Build Coastguard Worker test::pwpb::TestStreamResponse, response, .chunk = {}, .number = 11u);
433*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendServerStream(response));
434*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(result.active);
435*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 11);
436*61c4878aSAndroid Build Coastguard Worker
437*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(Status::NotFound()));
438*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(result.active);
439*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.stream_status, Status::NotFound());
440*61c4878aSAndroid Build Coastguard Worker }
441*61c4878aSAndroid Build Coastguard Worker
442*61c4878aSAndroid Build Coastguard Worker } // namespace
443*61c4878aSAndroid Build Coastguard Worker } // namespace pw::rpc
444*61c4878aSAndroid Build Coastguard Worker
445*61c4878aSAndroid Build Coastguard Worker PW_MODIFY_DIAGNOSTICS_POP();
446