blob: fc72f7f891e1ac7568c72ece468f29d1e6bca5a0 [file] [log] [blame]
Alexei Frolov26e3ae62020-05-04 17:06:17 -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
15#include "pw_rpc/server.h"
16
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070017#include <array>
18#include <cstdint>
19
Alexei Frolov26e3ae62020-05-04 17:06:17 -070020#include "gtest/gtest.h"
Wyatt Heplerf298de42021-03-19 15:06:36 -070021#include "pw_assert/check.h"
Wyatt Heplercbd09c22020-09-15 11:17:24 -070022#include "pw_rpc/internal/method.h"
Alexei Frolov33a1e8f2020-05-26 08:39:32 -070023#include "pw_rpc/internal/packet.h"
Wyatt Heplercbd09c22020-09-15 11:17:24 -070024#include "pw_rpc/internal/test_method.h"
Alexei Frolov9a4d6bf2020-08-04 10:33:26 -070025#include "pw_rpc/service.h"
Wyatt Hepler01fc15b2021-06-10 18:15:59 -070026#include "pw_rpc_private/fake_server_reader_writer.h"
Wyatt Hepler8aa02922020-07-17 08:54:37 -070027#include "pw_rpc_private/internal_test_utils.h"
Alexei Frolov26e3ae62020-05-04 17:06:17 -070028
29namespace pw::rpc {
30namespace {
31
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070032using std::byte;
33
Alexei Frolov33a1e8f2020-05-26 08:39:32 -070034using internal::Packet;
35using internal::PacketType;
Wyatt Heplercbd09c22020-09-15 11:17:24 -070036using internal::TestMethod;
Alexei Frolova4d71502020-10-14 12:43:14 -070037using internal::TestMethodUnion;
Alexei Frolov5d6d3922020-05-08 13:57:02 -070038
Alexei Frolov9a4d6bf2020-08-04 10:33:26 -070039class TestService : public Service {
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070040 public:
41 TestService(uint32_t service_id)
Alexei Frolov9a4d6bf2020-08-04 10:33:26 -070042 : Service(service_id, methods_),
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070043 methods_{
Wyatt Heplercbd09c22020-09-15 11:17:24 -070044 TestMethod(100),
45 TestMethod(200),
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070046 } {}
47
Alexei Frolova4d71502020-10-14 12:43:14 -070048 const TestMethod& method(uint32_t id) {
49 for (TestMethodUnion& method : methods_) {
50 if (method.method().id() == id) {
51 return method.test_method();
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070052 }
53 }
54
55 PW_CRASH("Invalid method ID %u", static_cast<unsigned>(id));
56 }
57
58 private:
Alexei Frolova4d71502020-10-14 12:43:14 -070059 std::array<TestMethodUnion, 2> methods_;
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070060};
61
62class BasicServer : public ::testing::Test {
63 protected:
64 static constexpr byte kDefaultPayload[] = {
65 byte(0x82), byte(0x02), byte(0xff), byte(0xff)};
66
67 BasicServer()
Wyatt Hepler51a2eb72020-06-04 14:47:00 -070068 : channels_{
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070069 Channel::Create<1>(&output_),
70 Channel::Create<2>(&output_),
71 Channel(), // available for assignment
72 },
73 server_(channels_),
74 service_(42) {
75 server_.RegisterService(service_);
76 }
77
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070078 std::span<const byte> EncodeRequest(
79 PacketType type,
80 uint32_t channel_id,
81 uint32_t service_id,
82 uint32_t method_id,
Wyatt Hepler01fc15b2021-06-10 18:15:59 -070083 std::span<const byte> payload = kDefaultPayload,
84 Status status = OkStatus()) {
85 auto result =
86 Packet(type, channel_id, service_id, method_id, payload, status)
87 .Encode(request_buffer_);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080088 EXPECT_EQ(OkStatus(), result.status());
Alexei Frolov3f2d0082020-10-04 22:30:39 -070089 return result.value_or(ConstByteSpan());
Wyatt Hepler80f26ff2020-06-01 09:30:17 -070090 }
91
Wyatt Hepler01fc15b2021-06-10 18:15:59 -070092 template <typename T = ConstByteSpan>
93 ConstByteSpan PacketForRpc(PacketType type,
94 Status status = OkStatus(),
95 T&& payload = {}) {
96 return EncodeRequest(
97 type, 1, 42, 100, std::as_bytes(std::span(payload)), status);
98 }
99
Wyatt Hepleraf835682020-06-17 11:42:53 -0700100 TestOutput<128> output_;
101 std::array<Channel, 3> channels_;
102 Server server_;
103 TestService service_;
104
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700105 private:
106 byte request_buffer_[64];
107};
108
109TEST_F(BasicServer, ProcessPacket_ValidMethod_InvokesMethod) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800110 EXPECT_EQ(OkStatus(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700111 server_.ProcessPacket(
112 EncodeRequest(PacketType::REQUEST, 1, 42, 100), output_));
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700113
Wyatt Heplercbd09c22020-09-15 11:17:24 -0700114 const TestMethod& method = service_.method(100);
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700115 EXPECT_EQ(1u, method.last_channel_id());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700116 ASSERT_EQ(sizeof(kDefaultPayload), method.last_request().payload().size());
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700117 EXPECT_EQ(std::memcmp(kDefaultPayload,
Wyatt Hepler712d3672020-07-13 15:52:11 -0700118 method.last_request().payload().data(),
119 method.last_request().payload().size()),
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700120 0);
Alexei Frolov33a1e8f2020-05-26 08:39:32 -0700121}
Alexei Frolov5d6d3922020-05-08 13:57:02 -0700122
Wyatt Hepleraf835682020-06-17 11:42:53 -0700123TEST_F(BasicServer, ProcessPacket_IncompletePacket_NothingIsInvoked) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700124 EXPECT_EQ(Status::DataLoss(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700125 server_.ProcessPacket(
126 EncodeRequest(PacketType::REQUEST, 0, 42, 101), output_));
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700127 EXPECT_EQ(Status::DataLoss(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700128 server_.ProcessPacket(EncodeRequest(PacketType::REQUEST, 1, 0, 101),
129 output_));
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700130 EXPECT_EQ(Status::DataLoss(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700131 server_.ProcessPacket(EncodeRequest(PacketType::REQUEST, 1, 42, 0),
132 output_));
Wyatt Hepleraf835682020-06-17 11:42:53 -0700133
134 EXPECT_EQ(0u, service_.method(100).last_channel_id());
135 EXPECT_EQ(0u, service_.method(200).last_channel_id());
136}
137
Wyatt Hepler712d3672020-07-13 15:52:11 -0700138TEST_F(BasicServer, ProcessPacket_NoChannel_SendsNothing) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700139 EXPECT_EQ(Status::DataLoss(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700140 server_.ProcessPacket(
141 EncodeRequest(PacketType::REQUEST, 0, 42, 101), output_));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700142
143 EXPECT_EQ(output_.packet_count(), 0u);
144}
145
146TEST_F(BasicServer, ProcessPacket_NoService_SendsDataLoss) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700147 EXPECT_EQ(Status::DataLoss(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700148 server_.ProcessPacket(EncodeRequest(PacketType::REQUEST, 1, 0, 101),
149 output_));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700150
Wyatt Hepler0f262352020-07-29 09:51:27 -0700151 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700152 EXPECT_EQ(output_.sent_packet().status(), Status::DataLoss());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700153}
154
155TEST_F(BasicServer, ProcessPacket_NoMethod_SendsDataLoss) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700156 EXPECT_EQ(Status::DataLoss(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700157 server_.ProcessPacket(EncodeRequest(PacketType::REQUEST, 1, 42, 0),
158 output_));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700159
Wyatt Hepler0f262352020-07-29 09:51:27 -0700160 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700161 EXPECT_EQ(output_.sent_packet().status(), Status::DataLoss());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700162}
163
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700164TEST_F(BasicServer, ProcessPacket_InvalidMethod_NothingIsInvoked) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800165 EXPECT_EQ(OkStatus(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700166 server_.ProcessPacket(
167 EncodeRequest(PacketType::REQUEST, 1, 42, 101), output_));
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700168
169 EXPECT_EQ(0u, service_.method(100).last_channel_id());
170 EXPECT_EQ(0u, service_.method(200).last_channel_id());
171}
172
Wyatt Hepler712d3672020-07-13 15:52:11 -0700173TEST_F(BasicServer, ProcessPacket_InvalidMethod_SendsError) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800174 EXPECT_EQ(OkStatus(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700175 server_.ProcessPacket(EncodeRequest(PacketType::REQUEST, 1, 42, 27),
176 output_));
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700177
Wyatt Hepler712d3672020-07-13 15:52:11 -0700178 const Packet& packet = output_.sent_packet();
Wyatt Hepler0f262352020-07-29 09:51:27 -0700179 EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700180 EXPECT_EQ(packet.channel_id(), 1u);
181 EXPECT_EQ(packet.service_id(), 42u);
Wyatt Hepler712d3672020-07-13 15:52:11 -0700182 EXPECT_EQ(packet.method_id(), 27u); // No method ID 27
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700183 EXPECT_EQ(packet.status(), Status::NotFound());
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700184}
185
Wyatt Hepler712d3672020-07-13 15:52:11 -0700186TEST_F(BasicServer, ProcessPacket_InvalidService_SendsError) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800187 EXPECT_EQ(OkStatus(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700188 server_.ProcessPacket(EncodeRequest(PacketType::REQUEST, 1, 43, 27),
189 output_));
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700190
Wyatt Hepler712d3672020-07-13 15:52:11 -0700191 const Packet& packet = output_.sent_packet();
Wyatt Hepler0f262352020-07-29 09:51:27 -0700192 EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
Alexei Frolov33a1e8f2020-05-26 08:39:32 -0700193 EXPECT_EQ(packet.channel_id(), 1u);
Wyatt Hepler60161aa2020-07-21 23:29:47 -0700194 EXPECT_EQ(packet.service_id(), 43u); // No service ID 43
195 EXPECT_EQ(packet.method_id(), 27u);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700196 EXPECT_EQ(packet.status(), Status::NotFound());
Alexei Frolov33a1e8f2020-05-26 08:39:32 -0700197}
198
Wyatt Hepler712d3672020-07-13 15:52:11 -0700199TEST_F(BasicServer, ProcessPacket_UnassignedChannel_AssignsToAvailableSlot) {
Wyatt Hepler51a2eb72020-06-04 14:47:00 -0700200 TestOutput<128> unassigned_output;
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800201 EXPECT_EQ(OkStatus(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700202 server_.ProcessPacket(
203 EncodeRequest(PacketType::REQUEST, /*channel_id=*/99, 42, 100),
204 unassigned_output));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700205 EXPECT_EQ(channels_[2].id(), 99u);
Alexei Frolov33a1e8f2020-05-26 08:39:32 -0700206}
207
Wyatt Hepler80f26ff2020-06-01 09:30:17 -0700208TEST_F(BasicServer,
209 ProcessPacket_UnassignedChannel_SendsResourceExhaustedIfCannotAssign) {
210 channels_[2] = Channel::Create<3>(&output_); // Occupy only available channel
Alexei Frolov33a1e8f2020-05-26 08:39:32 -0700211
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800212 EXPECT_EQ(OkStatus(),
Wyatt Hepler0f262352020-07-29 09:51:27 -0700213 server_.ProcessPacket(
214 EncodeRequest(PacketType::REQUEST, /*channel_id=*/99, 42, 27),
215 output_));
Alexei Frolov33a1e8f2020-05-26 08:39:32 -0700216
Wyatt Hepler712d3672020-07-13 15:52:11 -0700217 const Packet& packet = output_.sent_packet();
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700218 EXPECT_EQ(packet.status(), Status::ResourceExhausted());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700219 EXPECT_EQ(packet.channel_id(), 99u);
220 EXPECT_EQ(packet.service_id(), 42u);
221 EXPECT_EQ(packet.method_id(), 27u);
Alexei Frolov26e3ae62020-05-04 17:06:17 -0700222}
223
Wyatt Hepler712d3672020-07-13 15:52:11 -0700224TEST_F(BasicServer, ProcessPacket_Cancel_MethodNotActive_SendsError) {
Wyatt Hepleraf835682020-06-17 11:42:53 -0700225 // Set up a fake ServerWriter representing an ongoing RPC.
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800226 EXPECT_EQ(OkStatus(),
Wyatt Heplera9211162021-06-12 15:40:11 -0700227 server_.ProcessPacket(EncodeRequest(PacketType::CANCEL, 1, 42, 100),
228 output_));
Wyatt Hepleraf835682020-06-17 11:42:53 -0700229
Wyatt Hepler712d3672020-07-13 15:52:11 -0700230 const Packet& packet = output_.sent_packet();
Wyatt Hepler0f262352020-07-29 09:51:27 -0700231 EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
Wyatt Hepler712d3672020-07-13 15:52:11 -0700232 EXPECT_EQ(packet.channel_id(), 1u);
233 EXPECT_EQ(packet.service_id(), 42u);
234 EXPECT_EQ(packet.method_id(), 100u);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700235 EXPECT_EQ(packet.status(), Status::FailedPrecondition());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700236}
Wyatt Hepleraf835682020-06-17 11:42:53 -0700237
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700238class BidiMethod : public BasicServer {
Wyatt Hepler712d3672020-07-13 15:52:11 -0700239 protected:
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700240 BidiMethod()
Wyatt Hepler712d3672020-07-13 15:52:11 -0700241 : call_(static_cast<internal::Server&>(server_),
242 static_cast<internal::Channel&>(channels_[0]),
243 service_,
244 service_.method(100)),
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700245 responder_(call_) {
246 ASSERT_TRUE(responder_.open());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700247 }
248
249 internal::ServerCall call_;
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700250 internal::test::FakeServerReaderWriter responder_;
Wyatt Hepler712d3672020-07-13 15:52:11 -0700251};
252
Wyatt Hepler85e91402021-08-05 12:48:03 -0700253TEST_F(BidiMethod, DuplicateCall_CancelsExistingThenCallsAgain) {
254 bool cancelled = false;
255 responder_.set_on_error([&cancelled](Status error) {
256 if (error.IsCancelled()) {
257 cancelled = true;
258 }
259 });
260
261 const TestMethod& method = service_.method(100);
262 ASSERT_EQ(method.invocations(), 0u);
263
264 EXPECT_EQ(OkStatus(),
265 server_.ProcessPacket(PacketForRpc(PacketType::REQUEST), output_));
266
267 EXPECT_TRUE(cancelled);
268 EXPECT_EQ(method.invocations(), 1u);
269}
270
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700271TEST_F(BidiMethod, Cancel_ClosesServerWriter) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800272 EXPECT_EQ(OkStatus(),
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700273 server_.ProcessPacket(PacketForRpc(PacketType::CANCEL), output_));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700274
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700275 EXPECT_FALSE(responder_.open());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700276}
277
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700278TEST_F(BidiMethod, Cancel_SendsNoResponse) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800279 EXPECT_EQ(OkStatus(),
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700280 server_.ProcessPacket(PacketForRpc(PacketType::CANCEL), output_));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700281
Wyatt Hepler5ba80642021-06-18 12:56:17 -0700282 EXPECT_EQ(output_.packet_count(), 0u);
Wyatt Hepleraf835682020-06-17 11:42:53 -0700283}
284
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700285TEST_F(BidiMethod, ClientError_ClosesServerWriterWithoutResponse) {
286 ASSERT_EQ(
287 OkStatus(),
288 server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_ERROR), output_));
Alexei Frolov062ed182020-09-28 16:23:06 -0700289
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700290 EXPECT_FALSE(responder_.open());
Alexei Frolov062ed182020-09-28 16:23:06 -0700291 EXPECT_EQ(output_.packet_count(), 0u);
292}
293
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700294TEST_F(BidiMethod, ClientError_CallsOnErrorCallback) {
295 Status status = Status::Unknown();
296 responder_.set_on_error([&status](Status error) { status = error; });
297
298 ASSERT_EQ(OkStatus(),
299 server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_ERROR,
300 Status::Unauthenticated()),
301 output_));
302
303 EXPECT_EQ(status, Status::Unauthenticated());
304}
305
306TEST_F(BidiMethod, Cancel_CallsOnErrorCallback) {
307 Status status = Status::Unknown();
308 responder_.set_on_error([&status](Status error) { status = error; });
309
310 ASSERT_EQ(OkStatus(),
311 server_.ProcessPacket(PacketForRpc(PacketType::CANCEL), output_));
312 EXPECT_EQ(status, Status::Cancelled());
313}
314
315TEST_F(BidiMethod, Cancel_IncorrectChannel) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800316 EXPECT_EQ(OkStatus(),
Wyatt Heplera9211162021-06-12 15:40:11 -0700317 server_.ProcessPacket(EncodeRequest(PacketType::CANCEL, 2, 42, 100),
318 output_));
Wyatt Hepleraf835682020-06-17 11:42:53 -0700319
Wyatt Hepler0f262352020-07-29 09:51:27 -0700320 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700321 EXPECT_EQ(output_.sent_packet().status(), Status::FailedPrecondition());
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700322 EXPECT_TRUE(responder_.open());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700323}
324
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700325TEST_F(BidiMethod, Cancel_IncorrectService) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800326 EXPECT_EQ(OkStatus(),
Wyatt Heplera9211162021-06-12 15:40:11 -0700327 server_.ProcessPacket(EncodeRequest(PacketType::CANCEL, 1, 43, 100),
328 output_));
Wyatt Hepler712d3672020-07-13 15:52:11 -0700329
Wyatt Hepler0f262352020-07-29 09:51:27 -0700330 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700331 EXPECT_EQ(output_.sent_packet().status(), Status::NotFound());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700332 EXPECT_EQ(output_.sent_packet().service_id(), 43u);
Wyatt Hepler60161aa2020-07-21 23:29:47 -0700333 EXPECT_EQ(output_.sent_packet().method_id(), 100u);
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700334 EXPECT_TRUE(responder_.open());
Wyatt Hepler712d3672020-07-13 15:52:11 -0700335}
336
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700337TEST_F(BidiMethod, Cancel_IncorrectMethod) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800338 EXPECT_EQ(OkStatus(),
Wyatt Heplera9211162021-06-12 15:40:11 -0700339 server_.ProcessPacket(EncodeRequest(PacketType::CANCEL, 1, 42, 101),
340 output_));
Wyatt Hepler0f262352020-07-29 09:51:27 -0700341 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700342 EXPECT_EQ(output_.sent_packet().status(), Status::NotFound());
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700343 EXPECT_TRUE(responder_.open());
344}
345
346TEST_F(BidiMethod, ClientStream_CallsCallback) {
347 ConstByteSpan data = std::as_bytes(std::span("?"));
348 responder_.set_on_next([&data](ConstByteSpan payload) { data = payload; });
349
350 ASSERT_EQ(OkStatus(),
351 server_.ProcessPacket(
352 PacketForRpc(PacketType::CLIENT_STREAM, {}, "hello"), output_));
353
354 EXPECT_EQ(output_.packet_count(), 0u);
355 EXPECT_STREQ(reinterpret_cast<const char*>(data.data()), "hello");
356}
357
Wyatt Hepler379b2fc2021-06-22 22:54:33 -0700358#if PW_RPC_CLIENT_STREAM_END_CALLBACK
359
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700360TEST_F(BidiMethod, ClientStreamEnd_CallsCallback) {
361 bool called = false;
362 responder_.set_on_client_stream_end([&called]() { called = true; });
363
364 ASSERT_EQ(OkStatus(),
365 server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_STREAM_END),
366 output_));
367
368 EXPECT_EQ(output_.packet_count(), 0u);
369 EXPECT_TRUE(called);
370}
371
372TEST_F(BidiMethod, ClientStreamEnd_ErrorWhenClosed) {
373 const auto end = PacketForRpc(PacketType::CLIENT_STREAM_END);
374 ASSERT_EQ(OkStatus(), server_.ProcessPacket(end, output_));
375
376 bool called = false;
377 responder_.set_on_client_stream_end([&called]() { called = true; });
378
379 ASSERT_EQ(OkStatus(), server_.ProcessPacket(end, output_));
380
381 ASSERT_EQ(output_.packet_count(), 1u);
382 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
383 EXPECT_EQ(output_.sent_packet().status(), Status::FailedPrecondition());
384}
385
Wyatt Hepler379b2fc2021-06-22 22:54:33 -0700386#endif // PW_RPC_CLIENT_STREAM_END_CALLBACK
387
Wyatt Hepler01fc15b2021-06-10 18:15:59 -0700388class ServerStreamingMethod : public BasicServer {
389 protected:
390 ServerStreamingMethod()
391 : call_(static_cast<internal::Server&>(server_),
392 static_cast<internal::Channel&>(channels_[0]),
393 service_,
394 service_.method(100)),
395 responder_(call_) {
396 ASSERT_TRUE(responder_.open());
397 }
398
399 internal::ServerCall call_;
400 internal::test::FakeServerWriter responder_;
401};
402
403TEST_F(ServerStreamingMethod, ClientStream_InvalidArgumentError) {
404 ASSERT_EQ(
405 OkStatus(),
406 server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_STREAM), output_));
407
408 ASSERT_EQ(output_.packet_count(), 1u);
409 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
410 EXPECT_EQ(output_.sent_packet().status(), Status::InvalidArgument());
411}
412
413TEST_F(ServerStreamingMethod, ClientStreamEnd_InvalidArgumentError) {
414 ASSERT_EQ(OkStatus(),
415 server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_STREAM_END),
416 output_));
417
418 ASSERT_EQ(output_.packet_count(), 1u);
419 EXPECT_EQ(output_.sent_packet().type(), PacketType::SERVER_ERROR);
420 EXPECT_EQ(output_.sent_packet().status(), Status::InvalidArgument());
Wyatt Hepleraf835682020-06-17 11:42:53 -0700421}
422
Alexei Frolov26e3ae62020-05-04 17:06:17 -0700423} // namespace
424} // namespace pw::rpc