Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_rpc / nanopb / nanopb_client_call_test.cc
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_rpc/nanopb_client_call.h"
16
17 #include "gtest/gtest.h"
18 #include "pw_rpc_nanopb_private/internal_test_utils.h"
19 #include "pw_rpc_private/internal_test_utils.h"
20 #include "pw_rpc_test_protos/test.pb.h"
21
22 namespace pw::rpc {
23 namespace {
24
25 constexpr uint32_t kServiceId = 16;
26 constexpr uint32_t kUnaryMethodId = 111;
27 constexpr uint32_t kServerStreamingMethodId = 112;
28
29 class FakeGeneratedServiceClient {
30  public:
31   static NanopbClientCall<UnaryResponseHandler<pw_rpc_test_TestResponse>>
32   TestRpc(Channel& channel,
33           const pw_rpc_test_TestRequest& request,
34           UnaryResponseHandler<pw_rpc_test_TestResponse>& callback) {
35     auto call = NanopbClientCall(&channel,
36                                  kServiceId,
37                                  kUnaryMethodId,
38                                  callback,
39                                  pw_rpc_test_TestRequest_fields,
40                                  pw_rpc_test_TestResponse_fields);
41     call.SendRequest(&request);
42     return call;
43   }
44
45   static NanopbClientCall<
46       ServerStreamingResponseHandler<pw_rpc_test_TestStreamResponse>>
47   TestStreamRpc(Channel& channel,
48                 const pw_rpc_test_TestRequest& request,
49                 ServerStreamingResponseHandler<pw_rpc_test_TestStreamResponse>&
50                     callback) {
51     auto call = NanopbClientCall(&channel,
52                                  kServiceId,
53                                  kServerStreamingMethodId,
54                                  callback,
55                                  pw_rpc_test_TestRequest_fields,
56                                  pw_rpc_test_TestStreamResponse_fields);
57     call.SendRequest(&request);
58     return call;
59   }
60 };
61
62 using internal::TestServerStreamingResponseHandler;
63 using internal::TestUnaryResponseHandler;
64
65 TEST(NanopbClientCall, Unary_SendsRequestPacket) {
66   ClientContextForTest context;
67   TestUnaryResponseHandler<pw_rpc_test_TestResponse> handler;
68
69   auto call = FakeGeneratedServiceClient::TestRpc(
70       context.channel(), {.integer = 123, .status_code = 0}, handler);
71
72   EXPECT_EQ(context.output().packet_count(), 1u);
73   auto packet = context.output().sent_packet();
74   EXPECT_EQ(packet.channel_id(), context.channel().id());
75   EXPECT_EQ(packet.service_id(), kServiceId);
76   EXPECT_EQ(packet.method_id(), kUnaryMethodId);
77
78   PW_DECODE_PB(pw_rpc_test_TestRequest, sent_proto, packet.payload());
79   EXPECT_EQ(sent_proto.integer, 123);
80 }
81
82 TEST(NanopbClientCall, Unary_InvokesCallbackOnValidResponse) {
83   ClientContextForTest context;
84   TestUnaryResponseHandler<pw_rpc_test_TestResponse> handler;
85
86   auto call = FakeGeneratedServiceClient::TestRpc(
87       context.channel(), {.integer = 123, .status_code = 0}, handler);
88
89   PW_ENCODE_PB(pw_rpc_test_TestResponse, response, .value = 42);
90   context.SendResponse(OkStatus(), response);
91
92   ASSERT_EQ(handler.responses_received(), 1u);
93   EXPECT_EQ(handler.last_status(), OkStatus());
94   EXPECT_EQ(handler.last_response().value, 42);
95 }
96
97 TEST(NanopbClientCall, Unary_InvokesErrorCallbackOnInvalidResponse) {
98   ClientContextForTest context;
99   TestUnaryResponseHandler<pw_rpc_test_TestResponse> handler;
100
101   auto call = FakeGeneratedServiceClient::TestRpc(
102       context.channel(), {.integer = 123, .status_code = 0}, handler);
103
104   constexpr std::byte bad_payload[]{
105       std::byte{0xab}, std::byte{0xcd}, std::byte{0xef}};
106   context.SendResponse(OkStatus(), bad_payload);
107
108   EXPECT_EQ(handler.responses_received(), 0u);
109   EXPECT_EQ(handler.rpc_error(), Status::DataLoss());
110 }
111
112 TEST(NanopbClientCall, Unary_InvokesErrorCallbackOnServerError) {
113   ClientContextForTest context;
114   TestUnaryResponseHandler<pw_rpc_test_TestResponse> handler;
115
116   auto call = FakeGeneratedServiceClient::TestRpc(
117       context.channel(), {.integer = 123, .status_code = 0}, handler);
118
119   context.SendPacket(internal::PacketType::SERVER_ERROR, Status::NotFound());
120
121   EXPECT_EQ(handler.responses_received(), 0u);
122   EXPECT_EQ(handler.rpc_error(), Status::NotFound());
123 }
124
125 TEST(NanopbClientCall, Unary_OnlyReceivesOneResponse) {
126   ClientContextForTest context;
127   TestUnaryResponseHandler<pw_rpc_test_TestResponse> handler;
128
129   auto call = FakeGeneratedServiceClient::TestRpc(
130       context.channel(), {.integer = 123, .status_code = 0}, handler);
131
132   PW_ENCODE_PB(pw_rpc_test_TestResponse, r1, .value = 42);
133   context.SendResponse(Status::Unimplemented(), r1);
134   PW_ENCODE_PB(pw_rpc_test_TestResponse, r2, .value = 44);
135   context.SendResponse(Status::OutOfRange(), r2);
136   PW_ENCODE_PB(pw_rpc_test_TestResponse, r3, .value = 46);
137   context.SendResponse(Status::Internal(), r3);
138
139   EXPECT_EQ(handler.responses_received(), 1u);
140   EXPECT_EQ(handler.last_status(), Status::Unimplemented());
141   EXPECT_EQ(handler.last_response().value, 42);
142 }
143
144 TEST(NanopbClientCall, ServerStreaming_SendsRequestPacket) {
145   ClientContextForTest<128, 128, 99, kServiceId, kServerStreamingMethodId>
146       context;
147   TestServerStreamingResponseHandler<pw_rpc_test_TestStreamResponse> handler;
148
149   auto call = FakeGeneratedServiceClient::TestStreamRpc(
150       context.channel(), {.integer = 71, .status_code = 0}, handler);
151
152   EXPECT_EQ(context.output().packet_count(), 1u);
153   auto packet = context.output().sent_packet();
154   EXPECT_EQ(packet.channel_id(), context.channel().id());
155   EXPECT_EQ(packet.service_id(), kServiceId);
156   EXPECT_EQ(packet.method_id(), kServerStreamingMethodId);
157
158   PW_DECODE_PB(pw_rpc_test_TestRequest, sent_proto, packet.payload());
159   EXPECT_EQ(sent_proto.integer, 71);
160 }
161
162 TEST(NanopbClientCall, ServerStreaming_InvokesCallbackOnValidResponse) {
163   ClientContextForTest<128, 128, 99, kServiceId, kServerStreamingMethodId>
164       context;
165   TestServerStreamingResponseHandler<pw_rpc_test_TestStreamResponse> handler;
166
167   auto call = FakeGeneratedServiceClient::TestStreamRpc(
168       context.channel(), {.integer = 71, .status_code = 0}, handler);
169
170   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r1, .chunk = {}, .number = 11u);
171   context.SendResponse(OkStatus(), r1);
172   EXPECT_TRUE(handler.active());
173   EXPECT_EQ(handler.responses_received(), 1u);
174   EXPECT_EQ(handler.last_response().number, 11u);
175
176   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r2, .chunk = {}, .number = 22u);
177   context.SendResponse(OkStatus(), r2);
178   EXPECT_TRUE(handler.active());
179   EXPECT_EQ(handler.responses_received(), 2u);
180   EXPECT_EQ(handler.last_response().number, 22u);
181
182   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r3, .chunk = {}, .number = 33u);
183   context.SendResponse(OkStatus(), r3);
184   EXPECT_TRUE(handler.active());
185   EXPECT_EQ(handler.responses_received(), 3u);
186   EXPECT_EQ(handler.last_response().number, 33u);
187 }
188
189 TEST(NanopbClientCall, ServerStreaming_ClosesOnFinish) {
190   ClientContextForTest<128, 128, 99, kServiceId, kServerStreamingMethodId>
191       context;
192   TestServerStreamingResponseHandler<pw_rpc_test_TestStreamResponse> handler;
193
194   auto call = FakeGeneratedServiceClient::TestStreamRpc(
195       context.channel(), {.integer = 71, .status_code = 0}, handler);
196
197   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r1, .chunk = {}, .number = 11u);
198   context.SendResponse(OkStatus(), r1);
199   EXPECT_TRUE(handler.active());
200
201   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r2, .chunk = {}, .number = 22u);
202   context.SendResponse(OkStatus(), r2);
203   EXPECT_TRUE(handler.active());
204
205   // Close the stream.
206   context.SendPacket(internal::PacketType::SERVER_STREAM_END,
207                      Status::NotFound());
208
209   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r3, .chunk = {}, .number = 33u);
210   context.SendResponse(OkStatus(), r3);
211   EXPECT_FALSE(handler.active());
212
213   EXPECT_EQ(handler.responses_received(), 2u);
214 }
215
216 TEST(NanopbClientCall, ServerStreaming_InvokesErrorCallbackOnInvalidResponses) {
217   ClientContextForTest<128, 128, 99, kServiceId, kServerStreamingMethodId>
218       context;
219   TestServerStreamingResponseHandler<pw_rpc_test_TestStreamResponse> handler;
220
221   auto call = FakeGeneratedServiceClient::TestStreamRpc(
222       context.channel(), {.integer = 71, .status_code = 0}, handler);
223
224   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r1, .chunk = {}, .number = 11u);
225   context.SendResponse(OkStatus(), r1);
226   EXPECT_TRUE(handler.active());
227   EXPECT_EQ(handler.responses_received(), 1u);
228   EXPECT_EQ(handler.last_response().number, 11u);
229
230   constexpr std::byte bad_payload[]{
231       std::byte{0xab}, std::byte{0xcd}, std::byte{0xef}};
232   context.SendResponse(OkStatus(), bad_payload);
233   EXPECT_EQ(handler.responses_received(), 1u);
234   EXPECT_EQ(handler.rpc_error(), Status::DataLoss());
235
236   PW_ENCODE_PB(pw_rpc_test_TestStreamResponse, r2, .chunk = {}, .number = 22u);
237   context.SendResponse(OkStatus(), r2);
238   EXPECT_TRUE(handler.active());
239   EXPECT_EQ(handler.responses_received(), 2u);
240   EXPECT_EQ(handler.last_response().number, 22u);
241
242   context.SendPacket(internal::PacketType::SERVER_ERROR, Status::NotFound());
243   EXPECT_EQ(handler.responses_received(), 2u);
244   EXPECT_EQ(handler.rpc_error(), Status::NotFound());
245 }
246
247 }  // namespace
248 }  // namespace pw::rpc