1*61c4878aSAndroid Build Coastguard Worker // Copyright 2021 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/nanopb/test_method_context.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_nanopb_private/internal_test_utils.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_test_protos/test.rpc.pb.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::nanopb::TestService::Service<TestService> {
31*61c4878aSAndroid Build Coastguard Worker public:
TestUnaryRpc(const pw_rpc_test_TestRequest & request,pw_rpc_test_TestResponse & response)32*61c4878aSAndroid Build Coastguard Worker Status TestUnaryRpc(const pw_rpc_test_TestRequest& request,
33*61c4878aSAndroid Build Coastguard Worker pw_rpc_test_TestResponse& 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 pw_rpc_test_TestRequest & request,NanopbUnaryResponder<pw_rpc_test_TestResponse> & responder)38*61c4878aSAndroid Build Coastguard Worker void TestAnotherUnaryRpc(
39*61c4878aSAndroid Build Coastguard Worker const pw_rpc_test_TestRequest& request,
40*61c4878aSAndroid Build Coastguard Worker NanopbUnaryResponder<pw_rpc_test_TestResponse>& responder) {
41*61c4878aSAndroid Build Coastguard Worker pw_rpc_test_TestResponse 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 pw_rpc_test_TestRequest & request,ServerWriter<pw_rpc_test_TestStreamResponse> & writer)46*61c4878aSAndroid Build Coastguard Worker static void TestServerStreamRpc(
47*61c4878aSAndroid Build Coastguard Worker const pw_rpc_test_TestRequest& request,
48*61c4878aSAndroid Build Coastguard Worker ServerWriter<pw_rpc_test_TestStreamResponse>& 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<pw_rpc_test_TestRequest,pw_rpc_test_TestStreamResponse> & new_reader)59*61c4878aSAndroid Build Coastguard Worker void TestClientStreamRpc(
60*61c4878aSAndroid Build Coastguard Worker ServerReader<pw_rpc_test_TestRequest, pw_rpc_test_TestStreamResponse>&
61*61c4878aSAndroid Build Coastguard Worker new_reader) {
62*61c4878aSAndroid Build Coastguard Worker reader = std::move(new_reader);
63*61c4878aSAndroid Build Coastguard Worker }
64*61c4878aSAndroid Build Coastguard Worker
TestBidirectionalStreamRpc(ServerReaderWriter<pw_rpc_test_TestRequest,pw_rpc_test_TestStreamResponse> & new_reader_writer)65*61c4878aSAndroid Build Coastguard Worker void TestBidirectionalStreamRpc(
66*61c4878aSAndroid Build Coastguard Worker ServerReaderWriter<pw_rpc_test_TestRequest,
67*61c4878aSAndroid Build Coastguard Worker pw_rpc_test_TestStreamResponse>& new_reader_writer) {
68*61c4878aSAndroid Build Coastguard Worker reader_writer = std::move(new_reader_writer);
69*61c4878aSAndroid Build Coastguard Worker }
70*61c4878aSAndroid Build Coastguard Worker
71*61c4878aSAndroid Build Coastguard Worker ServerReader<pw_rpc_test_TestRequest, pw_rpc_test_TestStreamResponse> reader;
72*61c4878aSAndroid Build Coastguard Worker ServerReaderWriter<pw_rpc_test_TestRequest, pw_rpc_test_TestStreamResponse>
73*61c4878aSAndroid Build Coastguard Worker reader_writer;
74*61c4878aSAndroid Build Coastguard Worker };
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard Worker } // namespace test
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard Worker namespace {
79*61c4878aSAndroid Build Coastguard Worker
80*61c4878aSAndroid Build Coastguard Worker using internal::ClientContextForTest;
81*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,CompilesProperly)82*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, CompilesProperly) {
83*61c4878aSAndroid Build Coastguard Worker test::TestService service;
84*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(internal::UnwrapServiceId(service.service_id()),
85*61c4878aSAndroid Build Coastguard Worker internal::Hash("pw.rpc.test.TestService"));
86*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(service.name(), "TestService");
87*61c4878aSAndroid Build Coastguard Worker }
88*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Server_InvokeUnaryRpc)89*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Server_InvokeUnaryRpc) {
90*61c4878aSAndroid Build Coastguard Worker PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestUnaryRpc) context;
91*61c4878aSAndroid Build Coastguard Worker
92*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
93*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 123, .status_code = OkStatus().code()}));
94*61c4878aSAndroid Build Coastguard Worker
95*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(124, context.response().value);
96*61c4878aSAndroid Build Coastguard Worker
97*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::InvalidArgument(),
98*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 999,
99*61c4878aSAndroid Build Coastguard Worker .status_code = Status::InvalidArgument().code()}));
100*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1000, context.response().value);
101*61c4878aSAndroid Build Coastguard Worker }
102*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Server_InvokeAsyncUnaryRpc)103*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Server_InvokeAsyncUnaryRpc) {
104*61c4878aSAndroid Build Coastguard Worker PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) context;
105*61c4878aSAndroid Build Coastguard Worker
106*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 123, .status_code = OkStatus().code()});
107*61c4878aSAndroid Build Coastguard Worker
108*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.status());
109*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(124, context.response().value);
110*61c4878aSAndroid Build Coastguard Worker
111*61c4878aSAndroid Build Coastguard Worker context.call(
112*61c4878aSAndroid Build Coastguard Worker {.integer = 999, .status_code = Status::InvalidArgument().code()});
113*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::InvalidArgument(), context.status());
114*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1000, context.response().value);
115*61c4878aSAndroid Build Coastguard Worker }
116*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Server_InvokeServerStreamingRpc)117*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Server_InvokeServerStreamingRpc) {
118*61c4878aSAndroid Build Coastguard Worker PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestServerStreamRpc) context;
119*61c4878aSAndroid Build Coastguard Worker
120*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 0, .status_code = Status::Aborted().code()});
121*61c4878aSAndroid Build Coastguard Worker
122*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Aborted(), context.status());
123*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(context.done());
124*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.total_responses(), 0u);
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard Worker context.call({.integer = 4, .status_code = OkStatus().code()});
127*61c4878aSAndroid Build Coastguard Worker
128*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(4u, context.responses().size());
129*61c4878aSAndroid Build Coastguard Worker
130*61c4878aSAndroid Build Coastguard Worker for (size_t i = 0; i < context.responses().size(); ++i) {
131*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[i].number, i);
132*61c4878aSAndroid Build Coastguard Worker }
133*61c4878aSAndroid Build Coastguard Worker
134*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus().code(), context.status());
135*61c4878aSAndroid Build Coastguard Worker }
136*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Server_InvokeServerStreamingRpc_ManualWriting)137*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Server_InvokeServerStreamingRpc_ManualWriting) {
138*61c4878aSAndroid Build Coastguard Worker PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestServerStreamRpc, 4)
139*61c4878aSAndroid Build Coastguard Worker context;
140*61c4878aSAndroid Build Coastguard Worker
141*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(4u, context.max_packets());
142*61c4878aSAndroid Build Coastguard Worker
143*61c4878aSAndroid Build Coastguard Worker auto writer = context.writer();
144*61c4878aSAndroid Build Coastguard Worker
145*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Write({.chunk = {}, .number = 3}));
146*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Write({.chunk = {}, .number = 6}));
147*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Write({.chunk = {}, .number = 9}));
148*61c4878aSAndroid Build Coastguard Worker
149*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(context.done());
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Finish(Status::Cancelled()));
152*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(context.done());
153*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Cancelled(), context.status());
154*61c4878aSAndroid Build Coastguard Worker
155*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(3u, context.responses().size());
156*61c4878aSAndroid Build Coastguard Worker
157*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[0].number, 3u);
158*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[1].number, 6u);
159*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[2].number, 9u);
160*61c4878aSAndroid Build Coastguard Worker }
161*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Server_InvokeClientStreamingRpc)162*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Server_InvokeClientStreamingRpc) {
163*61c4878aSAndroid Build Coastguard Worker PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestClientStreamRpc) context;
164*61c4878aSAndroid Build Coastguard Worker
165*61c4878aSAndroid Build Coastguard Worker context.call();
166*61c4878aSAndroid Build Coastguard Worker
167*61c4878aSAndroid Build Coastguard Worker pw_rpc_test_TestRequest request = {};
168*61c4878aSAndroid Build Coastguard Worker context.service().reader.set_on_next(
169*61c4878aSAndroid Build Coastguard Worker [&request](const pw_rpc_test_TestRequest& req) { request = req; });
170*61c4878aSAndroid Build Coastguard Worker
171*61c4878aSAndroid Build Coastguard Worker context.SendClientStream({.integer = -99, .status_code = 10});
172*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.integer, -99);
173*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.status_code, 10u);
174*61c4878aSAndroid Build Coastguard Worker
175*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
176*61c4878aSAndroid Build Coastguard Worker context.service().reader.Finish({.chunk = {}, .number = 3},
177*61c4878aSAndroid Build Coastguard Worker Status::Unimplemented()));
178*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Unimplemented(), context.status());
179*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.response().number, 3u);
180*61c4878aSAndroid Build Coastguard Worker }
181*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Server_InvokeBidirectionalStreamingRpc)182*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Server_InvokeBidirectionalStreamingRpc) {
183*61c4878aSAndroid Build Coastguard Worker PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestBidirectionalStreamRpc)
184*61c4878aSAndroid Build Coastguard Worker context;
185*61c4878aSAndroid Build Coastguard Worker
186*61c4878aSAndroid Build Coastguard Worker context.call();
187*61c4878aSAndroid Build Coastguard Worker
188*61c4878aSAndroid Build Coastguard Worker pw_rpc_test_TestRequest request = {};
189*61c4878aSAndroid Build Coastguard Worker context.service().reader_writer.set_on_next(
190*61c4878aSAndroid Build Coastguard Worker [&request](const pw_rpc_test_TestRequest& req) { request = req; });
191*61c4878aSAndroid Build Coastguard Worker
192*61c4878aSAndroid Build Coastguard Worker context.SendClientStream({.integer = -99, .status_code = 10});
193*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.integer, -99);
194*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(request.status_code, 10u);
195*61c4878aSAndroid Build Coastguard Worker
196*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
197*61c4878aSAndroid Build Coastguard Worker context.service().reader_writer.Write({.chunk = {}, .number = 2}));
198*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.responses()[0].number, 2u);
199*61c4878aSAndroid Build Coastguard Worker
200*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
201*61c4878aSAndroid Build Coastguard Worker context.service().reader_writer.Finish(Status::NotFound()));
202*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::NotFound(), context.status());
203*61c4878aSAndroid Build Coastguard Worker }
204*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,ClientCall_DefaultConstructor)205*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, ClientCall_DefaultConstructor) {
206*61c4878aSAndroid Build Coastguard Worker NanopbUnaryReceiver<pw_rpc_test_TestResponse> unary_call;
207*61c4878aSAndroid Build Coastguard Worker NanopbClientReader<pw_rpc_test_TestStreamResponse> server_streaming_call;
208*61c4878aSAndroid Build Coastguard Worker }
209*61c4878aSAndroid Build Coastguard Worker
210*61c4878aSAndroid Build Coastguard Worker using TestServiceClient = test::pw_rpc::nanopb::TestService::Client;
211*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Client_InvokesUnaryRpcWithCallback)212*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Client_InvokesUnaryRpcWithCallback) {
213*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
214*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestUnaryRpc");
215*61c4878aSAndroid Build Coastguard Worker
216*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
217*61c4878aSAndroid Build Coastguard Worker
218*61c4878aSAndroid Build Coastguard Worker TestServiceClient test_client(context.client(), context.channel().id());
219*61c4878aSAndroid Build Coastguard Worker
220*61c4878aSAndroid Build Coastguard Worker struct {
221*61c4878aSAndroid Build Coastguard Worker Status last_status = Status::Unknown();
222*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
223*61c4878aSAndroid Build Coastguard Worker } result;
224*61c4878aSAndroid Build Coastguard Worker
225*61c4878aSAndroid Build Coastguard Worker auto call = test_client.TestUnaryRpc(
226*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
227*61c4878aSAndroid Build Coastguard Worker [&result](const pw_rpc_test_TestResponse& response, Status status) {
228*61c4878aSAndroid Build Coastguard Worker result.last_status = status;
229*61c4878aSAndroid Build Coastguard Worker result.response_value = response.value;
230*61c4878aSAndroid Build Coastguard Worker });
231*61c4878aSAndroid Build Coastguard Worker
232*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
233*61c4878aSAndroid Build Coastguard Worker
234*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
235*61c4878aSAndroid Build Coastguard Worker auto packet =
236*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
237*61c4878aSAndroid Build Coastguard Worker .last_packet();
238*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
239*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
240*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
241*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(pw_rpc_test_TestRequest, sent_proto, packet.payload());
242*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
243*61c4878aSAndroid Build Coastguard Worker
244*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(pw_rpc_test_TestResponse, response, .value = 42);
245*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(OkStatus(), response));
246*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.last_status, OkStatus());
247*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 42);
248*61c4878aSAndroid Build Coastguard Worker
249*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(call.active());
250*61c4878aSAndroid Build Coastguard Worker }
251*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Client_InvokesServerStreamingRpcWithCallback)252*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Client_InvokesServerStreamingRpcWithCallback) {
253*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
254*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestServerStreamRpc");
255*61c4878aSAndroid Build Coastguard Worker
256*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
257*61c4878aSAndroid Build Coastguard Worker
258*61c4878aSAndroid Build Coastguard Worker TestServiceClient test_client(context.client(), context.channel().id());
259*61c4878aSAndroid Build Coastguard Worker
260*61c4878aSAndroid Build Coastguard Worker struct {
261*61c4878aSAndroid Build Coastguard Worker bool active = true;
262*61c4878aSAndroid Build Coastguard Worker Status stream_status = Status::Unknown();
263*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
264*61c4878aSAndroid Build Coastguard Worker } result;
265*61c4878aSAndroid Build Coastguard Worker
266*61c4878aSAndroid Build Coastguard Worker auto call = test_client.TestServerStreamRpc(
267*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
268*61c4878aSAndroid Build Coastguard Worker [&result](const pw_rpc_test_TestStreamResponse& response) {
269*61c4878aSAndroid Build Coastguard Worker result.active = true;
270*61c4878aSAndroid Build Coastguard Worker result.response_value = response.number;
271*61c4878aSAndroid Build Coastguard Worker },
272*61c4878aSAndroid Build Coastguard Worker [&result](Status status) {
273*61c4878aSAndroid Build Coastguard Worker result.active = false;
274*61c4878aSAndroid Build Coastguard Worker result.stream_status = status;
275*61c4878aSAndroid Build Coastguard Worker });
276*61c4878aSAndroid Build Coastguard Worker
277*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
278*61c4878aSAndroid Build Coastguard Worker
279*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
280*61c4878aSAndroid Build Coastguard Worker auto packet =
281*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
282*61c4878aSAndroid Build Coastguard Worker .last_packet();
283*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
284*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
285*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
286*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(pw_rpc_test_TestRequest, sent_proto, packet.payload());
287*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(
290*61c4878aSAndroid Build Coastguard Worker pw_rpc_test_TestStreamResponse, response, .chunk = {}, .number = 11u);
291*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendServerStream(response));
292*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(result.active);
293*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 11);
294*61c4878aSAndroid Build Coastguard Worker
295*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(Status::NotFound()));
296*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(result.active);
297*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.stream_status, Status::NotFound());
298*61c4878aSAndroid Build Coastguard Worker }
299*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Client_StaticMethod_InvokesUnaryRpcWithCallback)300*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Client_StaticMethod_InvokesUnaryRpcWithCallback) {
301*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
302*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestUnaryRpc");
303*61c4878aSAndroid Build Coastguard Worker
304*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
305*61c4878aSAndroid Build Coastguard Worker
306*61c4878aSAndroid Build Coastguard Worker struct {
307*61c4878aSAndroid Build Coastguard Worker Status last_status = Status::Unknown();
308*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
309*61c4878aSAndroid Build Coastguard Worker } result;
310*61c4878aSAndroid Build Coastguard Worker
311*61c4878aSAndroid Build Coastguard Worker auto call = test::pw_rpc::nanopb::TestService::TestUnaryRpc(
312*61c4878aSAndroid Build Coastguard Worker context.client(),
313*61c4878aSAndroid Build Coastguard Worker context.channel().id(),
314*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
315*61c4878aSAndroid Build Coastguard Worker [&result](const pw_rpc_test_TestResponse& response, Status status) {
316*61c4878aSAndroid Build Coastguard Worker result.last_status = status;
317*61c4878aSAndroid Build Coastguard Worker result.response_value = response.value;
318*61c4878aSAndroid Build Coastguard Worker });
319*61c4878aSAndroid Build Coastguard Worker
320*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
321*61c4878aSAndroid Build Coastguard Worker
322*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
323*61c4878aSAndroid Build Coastguard Worker auto packet =
324*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
325*61c4878aSAndroid Build Coastguard Worker .last_packet();
326*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
327*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
328*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
329*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(pw_rpc_test_TestRequest, sent_proto, packet.payload());
330*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(pw_rpc_test_TestResponse, response, .value = 42);
333*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(OkStatus(), response));
334*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.last_status, OkStatus());
335*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 42);
336*61c4878aSAndroid Build Coastguard Worker }
337*61c4878aSAndroid Build Coastguard Worker
TEST(NanopbCodegen,Client_StaticMethod_InvokesServerStreamingRpcWithCallback)338*61c4878aSAndroid Build Coastguard Worker TEST(NanopbCodegen, Client_StaticMethod_InvokesServerStreamingRpcWithCallback) {
339*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kServiceId = internal::Hash("pw.rpc.test.TestService");
340*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kMethodId = internal::Hash("TestServerStreamRpc");
341*61c4878aSAndroid Build Coastguard Worker
342*61c4878aSAndroid Build Coastguard Worker ClientContextForTest<128, 99, kServiceId, kMethodId> context;
343*61c4878aSAndroid Build Coastguard Worker
344*61c4878aSAndroid Build Coastguard Worker struct {
345*61c4878aSAndroid Build Coastguard Worker bool active = true;
346*61c4878aSAndroid Build Coastguard Worker Status stream_status = Status::Unknown();
347*61c4878aSAndroid Build Coastguard Worker int response_value = -1;
348*61c4878aSAndroid Build Coastguard Worker } result;
349*61c4878aSAndroid Build Coastguard Worker
350*61c4878aSAndroid Build Coastguard Worker auto call = test::pw_rpc::nanopb::TestService::TestServerStreamRpc(
351*61c4878aSAndroid Build Coastguard Worker context.client(),
352*61c4878aSAndroid Build Coastguard Worker context.channel().id(),
353*61c4878aSAndroid Build Coastguard Worker {.integer = 123, .status_code = 0},
354*61c4878aSAndroid Build Coastguard Worker [&result](const pw_rpc_test_TestStreamResponse& response) {
355*61c4878aSAndroid Build Coastguard Worker result.active = true;
356*61c4878aSAndroid Build Coastguard Worker result.response_value = response.number;
357*61c4878aSAndroid Build Coastguard Worker },
358*61c4878aSAndroid Build Coastguard Worker [&result](Status status) {
359*61c4878aSAndroid Build Coastguard Worker result.active = false;
360*61c4878aSAndroid Build Coastguard Worker result.stream_status = status;
361*61c4878aSAndroid Build Coastguard Worker });
362*61c4878aSAndroid Build Coastguard Worker
363*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
364*61c4878aSAndroid Build Coastguard Worker
365*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.output().total_packets(), 1u);
366*61c4878aSAndroid Build Coastguard Worker auto packet =
367*61c4878aSAndroid Build Coastguard Worker static_cast<const internal::test::FakeChannelOutput&>(context.output())
368*61c4878aSAndroid Build Coastguard Worker .last_packet();
369*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), context.channel().id());
370*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), kServiceId);
371*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), kMethodId);
372*61c4878aSAndroid Build Coastguard Worker PW_DECODE_PB(pw_rpc_test_TestRequest, sent_proto, packet.payload());
373*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sent_proto.integer, 123);
374*61c4878aSAndroid Build Coastguard Worker
375*61c4878aSAndroid Build Coastguard Worker PW_ENCODE_PB(
376*61c4878aSAndroid Build Coastguard Worker pw_rpc_test_TestStreamResponse, response, .chunk = {}, .number = 11u);
377*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendServerStream(response));
378*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(result.active);
379*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.response_value, 11);
380*61c4878aSAndroid Build Coastguard Worker
381*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.SendResponse(Status::NotFound()));
382*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(result.active);
383*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(result.stream_status, Status::NotFound());
384*61c4878aSAndroid Build Coastguard Worker }
385*61c4878aSAndroid Build Coastguard Worker
386*61c4878aSAndroid Build Coastguard Worker } // namespace
387*61c4878aSAndroid Build Coastguard Worker } // namespace pw::rpc
388*61c4878aSAndroid Build Coastguard Worker
389*61c4878aSAndroid Build Coastguard Worker PW_MODIFY_DIAGNOSTICS_POP();
390