blob: 52638c402db3f78de5a4476f03600156b11b69b6 [file] [log] [blame]
Wyatt Hepler948f5472020-06-02 16:52:28 -07001// 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
Wyatt Hepler8ec2cf82021-07-09 17:18:41 -070015#include "pw_rpc/nanopb/internal/method.h"
Wyatt Hepler948f5472020-06-02 16:52:28 -070016
17#include <array>
18
19#include "gtest/gtest.h"
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -070020#include "pw_rpc/internal/method_impl_tester.h"
21#include "pw_rpc/internal/test_utils.h"
Wyatt Hepler8ec2cf82021-07-09 17:18:41 -070022#include "pw_rpc/nanopb/internal/method_union.h"
Wyatt Hepler948f5472020-06-02 16:52:28 -070023#include "pw_rpc/server_context.h"
Alexei Frolov9a4d6bf2020-08-04 10:33:26 -070024#include "pw_rpc/service.h"
Alexei Frolov4d2adde2020-08-04 10:19:24 -070025#include "pw_rpc_nanopb_private/internal_test_utils.h"
Wyatt Hepler948f5472020-06-02 16:52:28 -070026#include "pw_rpc_test_protos/test.pb.h"
27
28namespace pw::rpc::internal {
29namespace {
30
31using std::byte;
32
Wyatt Heplerb6495b32020-11-23 07:50:59 -080033struct FakePb {};
34
35// Create a fake service for use with the MethodImplTester.
36class TestNanopbService final : public Service {
37 public:
Wyatt Hepler59b37f72021-06-15 16:23:44 -070038 // Unary signatures
39
Wyatt Heplerb6495b32020-11-23 07:50:59 -080040 Status Unary(ServerContext&, const FakePb&, FakePb&) { return Status(); }
41
42 static Status StaticUnary(ServerContext&, const FakePb&, FakePb&) {
43 return Status();
44 }
45
Wyatt Heplerb6495b32020-11-23 07:50:59 -080046 Status UnaryWrongArg(ServerContext&, FakePb&, FakePb&) { return Status(); }
47
48 static void StaticUnaryVoidReturn(ServerContext&, const FakePb&, FakePb&) {}
49
Wyatt Hepler59b37f72021-06-15 16:23:44 -070050 // Server streaming signatures
51
52 void ServerStreaming(ServerContext&,
53 const FakePb&,
54 NanopbServerWriter<FakePb>&) {}
55
56 static void StaticServerStreaming(ServerContext&,
57 const FakePb&,
58 NanopbServerWriter<FakePb>&) {}
59
Wyatt Heplerb6495b32020-11-23 07:50:59 -080060 int ServerStreamingBadReturn(ServerContext&,
61 const FakePb&,
Wyatt Hepler59b37f72021-06-15 16:23:44 -070062 NanopbServerWriter<FakePb>&) {
Wyatt Heplerb6495b32020-11-23 07:50:59 -080063 return 5;
64 }
65
66 static void StaticServerStreamingMissingArg(const FakePb&,
Wyatt Hepler59b37f72021-06-15 16:23:44 -070067 NanopbServerWriter<FakePb>&) {}
68
69 // Client streaming signatures
70
71 void ClientStreaming(ServerContext&, NanopbServerReader<FakePb, FakePb>&) {}
72
73 static void StaticClientStreaming(ServerContext&,
74 NanopbServerReader<FakePb, FakePb>&) {}
75
76 int ClientStreamingBadReturn(ServerContext&,
77 NanopbServerReader<FakePb, FakePb>&) {
78 return 0;
79 }
80
81 static void StaticClientStreamingMissingArg(
82 NanopbServerReader<FakePb, FakePb>&) {}
83
84 // Bidirectional streaming signatures
85
86 void BidirectionalStreaming(ServerContext&,
87 NanopbServerReaderWriter<FakePb, FakePb>&) {}
88
89 static void StaticBidirectionalStreaming(
90 ServerContext&, NanopbServerReaderWriter<FakePb, FakePb>&) {}
91
92 int BidirectionalStreamingBadReturn(
93 ServerContext&, NanopbServerReaderWriter<FakePb, FakePb>&) {
94 return 0;
95 }
96
97 static void StaticBidirectionalStreamingMissingArg(
98 NanopbServerReaderWriter<FakePb, FakePb>&) {}
Wyatt Heplerb6495b32020-11-23 07:50:59 -080099};
100
Wyatt Hepler38f87082021-02-23 17:00:09 -0800101struct WrongPb;
102
103// Test matches() rejects incorrect request/response types.
Wyatt Hepler59b37f72021-06-15 16:23:44 -0700104// clang-format off
105static_assert(!NanopbMethod::template matches<&TestNanopbService::Unary, WrongPb, FakePb>());
106static_assert(!NanopbMethod::template matches<&TestNanopbService::Unary, FakePb, WrongPb>());
107static_assert(!NanopbMethod::template matches<&TestNanopbService::Unary, WrongPb, WrongPb>());
108static_assert(!NanopbMethod::template matches<&TestNanopbService::StaticUnary, FakePb, WrongPb>());
Wyatt Hepler38f87082021-02-23 17:00:09 -0800109
Wyatt Hepler59b37f72021-06-15 16:23:44 -0700110static_assert(!NanopbMethod::template matches<&TestNanopbService::ServerStreaming, WrongPb, FakePb>());
111static_assert(!NanopbMethod::template matches<&TestNanopbService::StaticServerStreaming, FakePb, WrongPb>());
Wyatt Hepler38f87082021-02-23 17:00:09 -0800112
Wyatt Hepler59b37f72021-06-15 16:23:44 -0700113static_assert(!NanopbMethod::template matches<&TestNanopbService::ClientStreaming, WrongPb, FakePb>());
114static_assert(!NanopbMethod::template matches<&TestNanopbService::StaticClientStreaming, FakePb, WrongPb>());
115
116static_assert(!NanopbMethod::template matches<&TestNanopbService::BidirectionalStreaming, WrongPb, FakePb>());
117static_assert(!NanopbMethod::template matches<&TestNanopbService::StaticBidirectionalStreaming, FakePb, WrongPb>());
118// clang-format on
119
120static_assert(MethodImplTests<NanopbMethod, TestNanopbService>().Pass(
121 MatchesTypes<FakePb, FakePb>(), CreationArgs<nullptr, nullptr>()));
Wyatt Heplerb6495b32020-11-23 07:50:59 -0800122
Alexei Frolova4d71502020-10-14 12:43:14 -0700123pw_rpc_test_TestRequest last_request;
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700124NanopbServerWriter<pw_rpc_test_TestResponse> last_writer;
125NanopbServerReader<pw_rpc_test_TestRequest, pw_rpc_test_TestResponse>
126 last_reader;
127NanopbServerReaderWriter<pw_rpc_test_TestRequest, pw_rpc_test_TestResponse>
128 last_reader_writer;
Alexei Frolova4d71502020-10-14 12:43:14 -0700129
Wyatt Heplere95bd722020-11-23 07:49:47 -0800130Status AddFive(ServerContext&,
Alexei Frolova4d71502020-10-14 12:43:14 -0700131 const pw_rpc_test_TestRequest& request,
132 pw_rpc_test_TestResponse& response) {
133 last_request = request;
134 response.value = request.integer + 5;
135 return Status::Unauthenticated();
136}
137
Wyatt Heplere95bd722020-11-23 07:49:47 -0800138Status DoNothing(ServerContext&, const pw_rpc_test_Empty&, pw_rpc_test_Empty&) {
Alexei Frolova4d71502020-10-14 12:43:14 -0700139 return Status::Unknown();
140}
141
Wyatt Heplere95bd722020-11-23 07:49:47 -0800142void StartStream(ServerContext&,
Alexei Frolova4d71502020-10-14 12:43:14 -0700143 const pw_rpc_test_TestRequest& request,
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700144 NanopbServerWriter<pw_rpc_test_TestResponse>& writer) {
Alexei Frolova4d71502020-10-14 12:43:14 -0700145 last_request = request;
146 last_writer = std::move(writer);
147}
148
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700149void ClientStream(ServerContext&,
150 NanopbServerReader<pw_rpc_test_TestRequest,
151 pw_rpc_test_TestResponse>& reader) {
152 last_reader = std::move(reader);
153}
154
155void BidirectionalStream(
156 ServerContext&,
157 NanopbServerReaderWriter<pw_rpc_test_TestRequest, pw_rpc_test_TestResponse>&
158 reader_writer) {
159 last_reader_writer = std::move(reader_writer);
160}
161
Alexei Frolova4d71502020-10-14 12:43:14 -0700162class FakeService : public Service {
Wyatt Hepler948f5472020-06-02 16:52:28 -0700163 public:
Alexei Frolova4d71502020-10-14 12:43:14 -0700164 FakeService(uint32_t id) : Service(id, kMethods) {}
Wyatt Hepler948f5472020-06-02 16:52:28 -0700165
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700166 static constexpr std::array<NanopbMethodUnion, 5> kMethods = {
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700167 NanopbMethod::Unary<DoNothing>(
Wyatt Hepler948f5472020-06-02 16:52:28 -0700168 10u, pw_rpc_test_Empty_fields, pw_rpc_test_Empty_fields),
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700169 NanopbMethod::Unary<AddFive>(
Wyatt Hepler948f5472020-06-02 16:52:28 -0700170 11u, pw_rpc_test_TestRequest_fields, pw_rpc_test_TestResponse_fields),
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700171 NanopbMethod::ServerStreaming<StartStream>(
Wyatt Hepler948f5472020-06-02 16:52:28 -0700172 12u, pw_rpc_test_TestRequest_fields, pw_rpc_test_TestResponse_fields),
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700173 NanopbMethod::ClientStreaming<ClientStream>(
174 13u, pw_rpc_test_TestRequest_fields, pw_rpc_test_TestResponse_fields),
175 NanopbMethod::BidirectionalStreaming<BidirectionalStream>(
176 14u,
177 pw_rpc_test_TestRequest_fields,
178 pw_rpc_test_TestResponse_fields)};
Wyatt Hepler948f5472020-06-02 16:52:28 -0700179};
180
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700181constexpr const NanopbMethod& kDoNothing =
182 std::get<0>(FakeService::kMethods).nanopb_method();
183constexpr const NanopbMethod& kAddFive =
184 std::get<1>(FakeService::kMethods).nanopb_method();
185constexpr const NanopbMethod& kStartStream =
186 std::get<2>(FakeService::kMethods).nanopb_method();
187constexpr const NanopbMethod& kClientStream =
188 std::get<3>(FakeService::kMethods).nanopb_method();
189constexpr const NanopbMethod& kBidirectionalStream =
190 std::get<4>(FakeService::kMethods).nanopb_method();
191
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700192TEST(NanopbMethod, UnaryRpc_SendsResponse) {
Alexei Frolov4d2adde2020-08-04 10:19:24 -0700193 PW_ENCODE_PB(
194 pw_rpc_test_TestRequest, request, .integer = 123, .status_code = 0);
Wyatt Hepler948f5472020-06-02 16:52:28 -0700195
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700196 ServerContextForTest<FakeService> context(kAddFive);
197 kAddFive.Invoke(context.get(), context.request(request));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700198
199 const Packet& response = context.output().sent_packet();
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700200 EXPECT_EQ(response.status(), Status::Unauthenticated());
Wyatt Hepler948f5472020-06-02 16:52:28 -0700201
202 // Field 1 (encoded as 1 << 3) with 128 as the value.
203 constexpr std::byte expected[]{
204 std::byte{0x08}, std::byte{0x80}, std::byte{0x01}};
205
Wyatt Hepler712d3672020-07-13 15:52:11 -0700206 EXPECT_EQ(sizeof(expected), response.payload().size());
207 EXPECT_EQ(0,
208 std::memcmp(expected, response.payload().data(), sizeof(expected)));
Wyatt Hepler948f5472020-06-02 16:52:28 -0700209
210 EXPECT_EQ(123, last_request.integer);
211}
212
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700213TEST(NanopbMethod, UnaryRpc_InvalidPayload_SendsError) {
Wyatt Hepler712d3672020-07-13 15:52:11 -0700214 std::array<byte, 8> bad_payload{byte{0xFF}, byte{0xAA}, byte{0xDD}};
215
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700216 ServerContextForTest<FakeService> context(kDoNothing);
217 kDoNothing.Invoke(context.get(), context.request(bad_payload));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700218
219 const Packet& packet = context.output().sent_packet();
Wyatt Hepler0f262352020-07-29 09:51:27 -0700220 EXPECT_EQ(PacketType::SERVER_ERROR, packet.type());
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700221 EXPECT_EQ(Status::DataLoss(), packet.status());
Ewout van Bekkum5ea33402021-03-31 11:00:02 -0700222 EXPECT_EQ(context.service_id(), packet.service_id());
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700223 EXPECT_EQ(kDoNothing.id(), packet.method_id());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700224}
225
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700226TEST(NanopbMethod, UnaryRpc_BufferTooSmallForResponse_SendsInternalError) {
Wyatt Hepler712d3672020-07-13 15:52:11 -0700227 constexpr int64_t value = 0x7FFFFFFF'FFFFFF00ll;
Alexei Frolov4d2adde2020-08-04 10:19:24 -0700228 PW_ENCODE_PB(
Wyatt Hepler85eb7c92020-08-06 13:45:20 -0700229 pw_rpc_test_TestRequest, request, .integer = value, .status_code = 0);
Wyatt Hepler948f5472020-06-02 16:52:28 -0700230
Wyatt Hepler712d3672020-07-13 15:52:11 -0700231 // Output buffer is too small for the response, but can fit an error packet.
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700232 ServerContextForTest<FakeService, 22> context(kAddFive);
Wyatt Hepler5ba80642021-06-18 12:56:17 -0700233 ASSERT_LT(
234 context.output().buffer_size(),
235 context.request(request).MinEncodedSizeBytes() + request.size() + 1);
Wyatt Hepler948f5472020-06-02 16:52:28 -0700236
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700237 kAddFive.Invoke(context.get(), context.request(request));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700238
239 const Packet& packet = context.output().sent_packet();
Wyatt Hepler0f262352020-07-29 09:51:27 -0700240 EXPECT_EQ(PacketType::SERVER_ERROR, packet.type());
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700241 EXPECT_EQ(Status::Internal(), packet.status());
Ewout van Bekkum5ea33402021-03-31 11:00:02 -0700242 EXPECT_EQ(context.service_id(), packet.service_id());
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700243 EXPECT_EQ(kAddFive.id(), packet.method_id());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700244
245 EXPECT_EQ(value, last_request.integer);
Wyatt Hepler948f5472020-06-02 16:52:28 -0700246}
247
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700248TEST(NanopbMethod, ServerStreamingRpc_SendsNothingWhenInitiallyCalled) {
Alexei Frolov4d2adde2020-08-04 10:19:24 -0700249 PW_ENCODE_PB(
250 pw_rpc_test_TestRequest, request, .integer = 555, .status_code = 0);
Wyatt Hepler948f5472020-06-02 16:52:28 -0700251
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700252 ServerContextForTest<FakeService> context(kStartStream);
Wyatt Hepler948f5472020-06-02 16:52:28 -0700253
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700254 kStartStream.Invoke(context.get(), context.request(request));
Wyatt Hepler948f5472020-06-02 16:52:28 -0700255
Wyatt Hepler712d3672020-07-13 15:52:11 -0700256 EXPECT_EQ(0u, context.output().packet_count());
Wyatt Hepler948f5472020-06-02 16:52:28 -0700257 EXPECT_EQ(555, last_request.integer);
258}
259
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700260TEST(NanopbMethod, ServerWriter_SendsResponse) {
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700261 ServerContextForTest<FakeService> context(kStartStream);
Wyatt Hepler712d3672020-07-13 15:52:11 -0700262
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700263 kStartStream.Invoke(context.get(), context.request({}));
Wyatt Hepler948f5472020-06-02 16:52:28 -0700264
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800265 EXPECT_EQ(OkStatus(), last_writer.Write({.value = 100}));
Wyatt Hepler948f5472020-06-02 16:52:28 -0700266
Alexei Frolov4d2adde2020-08-04 10:19:24 -0700267 PW_ENCODE_PB(pw_rpc_test_TestResponse, payload, .value = 100);
Wyatt Hepler948f5472020-06-02 16:52:28 -0700268 std::array<byte, 128> encoded_response = {};
Wyatt Hepler5ba80642021-06-18 12:56:17 -0700269 auto encoded = context.server_stream(payload).Encode(encoded_response);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800270 ASSERT_EQ(OkStatus(), encoded.status());
Wyatt Hepler948f5472020-06-02 16:52:28 -0700271
Alexei Frolov3f2d0082020-10-04 22:30:39 -0700272 ASSERT_EQ(encoded.value().size(), context.output().sent_data().size());
Wyatt Hepler948f5472020-06-02 16:52:28 -0700273 EXPECT_EQ(0,
Alexei Frolov3f2d0082020-10-04 22:30:39 -0700274 std::memcmp(encoded.value().data(),
Wyatt Hepler712d3672020-07-13 15:52:11 -0700275 context.output().sent_data().data(),
Alexei Frolov3f2d0082020-10-04 22:30:39 -0700276 encoded.value().size()));
Wyatt Hepler948f5472020-06-02 16:52:28 -0700277}
278
Alexei Frolove22570a2020-11-18 14:56:18 -0800279TEST(NanopbMethod, ServerWriter_WriteWhenClosed_ReturnsFailedPrecondition) {
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700280 ServerContextForTest<FakeService> context(kStartStream);
Alexei Frolove22570a2020-11-18 14:56:18 -0800281
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700282 kStartStream.Invoke(context.get(), context.request({}));
Alexei Frolove22570a2020-11-18 14:56:18 -0800283
Wyatt Heplerd08e5822021-02-18 17:53:38 -0800284 EXPECT_EQ(OkStatus(), last_writer.Finish());
Alexei Frolove22570a2020-11-18 14:56:18 -0800285 EXPECT_TRUE(last_writer.Write({.value = 100}).IsFailedPrecondition());
286}
287
Wyatt Heplerd08e5822021-02-18 17:53:38 -0800288TEST(NanopbMethod, ServerWriter_WriteAfterMoved_ReturnsFailedPrecondition) {
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700289 ServerContextForTest<FakeService> context(kStartStream);
Wyatt Heplerd08e5822021-02-18 17:53:38 -0800290
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700291 kStartStream.Invoke(context.get(), context.request({}));
292 NanopbServerWriter<pw_rpc_test_TestResponse> new_writer =
293 std::move(last_writer);
Wyatt Heplerd08e5822021-02-18 17:53:38 -0800294
295 EXPECT_EQ(OkStatus(), new_writer.Write({.value = 100}));
296
297 EXPECT_EQ(Status::FailedPrecondition(), last_writer.Write({.value = 100}));
298 EXPECT_EQ(Status::FailedPrecondition(), last_writer.Finish());
299
300 EXPECT_EQ(OkStatus(), new_writer.Finish());
301}
302
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700303TEST(NanopbMethod,
304 ServerStreamingRpc_ServerWriterBufferTooSmall_InternalError) {
Wyatt Hepler5ba80642021-06-18 12:56:17 -0700305 constexpr size_t kNoPayloadPacketSize =
306 2 /* type */ + 2 /* channel */ + 5 /* service */ + 5 /* method */ +
307 0 /* payload (when empty) */ + 0 /* status (when OK)*/;
Wyatt Hepler948f5472020-06-02 16:52:28 -0700308
Wyatt Hepler712d3672020-07-13 15:52:11 -0700309 // Make the buffer barely fit a packet with no payload.
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700310 ServerContextForTest<FakeService, kNoPayloadPacketSize> context(kStartStream);
Wyatt Hepler712d3672020-07-13 15:52:11 -0700311
312 // Verify that the encoded size of a packet with an empty payload is correct.
Wyatt Hepler948f5472020-06-02 16:52:28 -0700313 std::array<byte, 128> encoded_response = {};
Wyatt Hepler5ba80642021-06-18 12:56:17 -0700314 auto encoded = context.request({}).Encode(encoded_response);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800315 ASSERT_EQ(OkStatus(), encoded.status());
Alexei Frolov3f2d0082020-10-04 22:30:39 -0700316 ASSERT_EQ(kNoPayloadPacketSize, encoded.value().size());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700317
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700318 kStartStream.Invoke(context.get(), context.request({}));
Wyatt Hepler948f5472020-06-02 16:52:28 -0700319
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800320 EXPECT_EQ(OkStatus(), last_writer.Write({})); // Barely fits
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700321 EXPECT_EQ(Status::Internal(), last_writer.Write({.value = 1})); // Too big
Wyatt Hepler948f5472020-06-02 16:52:28 -0700322}
323
Wyatt Heplerfa6edcc2021-08-20 08:30:08 -0700324TEST(NanopbMethod, ServerReader_HandlesRequests) {
325 ServerContextForTest<FakeService> context(kClientStream);
326
327 kBidirectionalStream.Invoke(context.get(), context.request({}));
328
329 pw_rpc_test_TestRequest request_struct{};
330 last_reader_writer.set_on_next(
331 [&request_struct](const pw_rpc_test_TestRequest& req) {
332 request_struct = req;
333 });
334
335 PW_ENCODE_PB(
336 pw_rpc_test_TestRequest, request, .integer = 1 << 30, .status_code = 9);
337 std::array<byte, 128> encoded_request = {};
338 auto encoded = context.client_stream(request).Encode(encoded_request);
339 ASSERT_EQ(OkStatus(), encoded.status());
340 ASSERT_EQ(OkStatus(),
341 context.server().ProcessPacket(*encoded, context.output()));
342
343 EXPECT_EQ(request_struct.integer, 1 << 30);
344 EXPECT_EQ(request_struct.status_code, 9u);
345}
346
347TEST(NanopbMethod, ServerReaderWriter_WritesResponses) {
348 ServerContextForTest<FakeService> context(kBidirectionalStream);
349
350 kBidirectionalStream.Invoke(context.get(), context.request({}));
351
352 EXPECT_EQ(OkStatus(), last_reader_writer.Write({.value = 100}));
353
354 PW_ENCODE_PB(pw_rpc_test_TestResponse, payload, .value = 100);
355 std::array<byte, 128> encoded_response = {};
356 auto encoded = context.server_stream(payload).Encode(encoded_response);
357 ASSERT_EQ(OkStatus(), encoded.status());
358
359 ASSERT_EQ(encoded.value().size(), context.output().sent_data().size());
360 EXPECT_EQ(0,
361 std::memcmp(encoded.value().data(),
362 context.output().sent_data().data(),
363 encoded.value().size()));
364}
365
366TEST(NanopbMethod, ServerReaderWriter_HandlesRequests) {
367 ServerContextForTest<FakeService> context(kBidirectionalStream);
368
369 kBidirectionalStream.Invoke(context.get(), context.request({}));
370
371 pw_rpc_test_TestRequest request_struct{};
372 last_reader_writer.set_on_next(
373 [&request_struct](const pw_rpc_test_TestRequest& req) {
374 request_struct = req;
375 });
376
377 PW_ENCODE_PB(
378 pw_rpc_test_TestRequest, request, .integer = 1 << 30, .status_code = 9);
379 std::array<byte, 128> encoded_request = {};
380 auto encoded = context.client_stream(request).Encode(encoded_request);
381 ASSERT_EQ(OkStatus(), encoded.status());
382 ASSERT_EQ(OkStatus(),
383 context.server().ProcessPacket(*encoded, context.output()));
384
385 EXPECT_EQ(request_struct.integer, 1 << 30);
386 EXPECT_EQ(request_struct.status_code, 9u);
387}
Wyatt Hepler07e3ba02021-07-02 00:54:13 -0700388
Wyatt Hepler948f5472020-06-02 16:52:28 -0700389} // namespace
390} // namespace pw::rpc::internal