1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 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_rpc/server.h"
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include <array>
18*61c4878aSAndroid Build Coastguard Worker #include <cstdint>
19*61c4878aSAndroid Build Coastguard Worker
20*61c4878aSAndroid Build Coastguard Worker #include "pw_assert/check.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/call.h"
22*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/method.h"
23*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/packet.h"
24*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/test_utils.h"
25*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/service.h"
26*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_private/fake_server_reader_writer.h"
27*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_private/test_method.h"
28*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
29*61c4878aSAndroid Build Coastguard Worker
30*61c4878aSAndroid Build Coastguard Worker namespace pw::rpc {
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker class ServerTestHelper {
33*61c4878aSAndroid Build Coastguard Worker public:
FindMethod(Server & server,uint32_t service_id,uint32_t method_id)34*61c4878aSAndroid Build Coastguard Worker static std::tuple<Service*, const internal::Method*> FindMethod(
35*61c4878aSAndroid Build Coastguard Worker Server& server, uint32_t service_id, uint32_t method_id) {
36*61c4878aSAndroid Build Coastguard Worker return server.FindMethod(service_id, method_id);
37*61c4878aSAndroid Build Coastguard Worker }
38*61c4878aSAndroid Build Coastguard Worker };
39*61c4878aSAndroid Build Coastguard Worker
40*61c4878aSAndroid Build Coastguard Worker namespace {
41*61c4878aSAndroid Build Coastguard Worker
42*61c4878aSAndroid Build Coastguard Worker using std::byte;
43*61c4878aSAndroid Build Coastguard Worker
44*61c4878aSAndroid Build Coastguard Worker using internal::Packet;
45*61c4878aSAndroid Build Coastguard Worker using internal::TestMethod;
46*61c4878aSAndroid Build Coastguard Worker using internal::TestMethodUnion;
47*61c4878aSAndroid Build Coastguard Worker using internal::pwpb::PacketType;
48*61c4878aSAndroid Build Coastguard Worker
49*61c4878aSAndroid Build Coastguard Worker class TestService : public Service {
50*61c4878aSAndroid Build Coastguard Worker public:
TestService(uint32_t service_id)51*61c4878aSAndroid Build Coastguard Worker TestService(uint32_t service_id)
52*61c4878aSAndroid Build Coastguard Worker : Service(service_id, methods_),
53*61c4878aSAndroid Build Coastguard Worker methods_{
54*61c4878aSAndroid Build Coastguard Worker TestMethod(100, MethodType::kBidirectionalStreaming),
55*61c4878aSAndroid Build Coastguard Worker TestMethod(200),
56*61c4878aSAndroid Build Coastguard Worker } {}
57*61c4878aSAndroid Build Coastguard Worker
method(uint32_t id)58*61c4878aSAndroid Build Coastguard Worker const TestMethod& method(uint32_t id) {
59*61c4878aSAndroid Build Coastguard Worker for (TestMethodUnion& method : methods_) {
60*61c4878aSAndroid Build Coastguard Worker if (method.method().id() == id) {
61*61c4878aSAndroid Build Coastguard Worker return method.test_method();
62*61c4878aSAndroid Build Coastguard Worker }
63*61c4878aSAndroid Build Coastguard Worker }
64*61c4878aSAndroid Build Coastguard Worker
65*61c4878aSAndroid Build Coastguard Worker PW_CRASH("Invalid method ID %u", static_cast<unsigned>(id));
66*61c4878aSAndroid Build Coastguard Worker }
67*61c4878aSAndroid Build Coastguard Worker
68*61c4878aSAndroid Build Coastguard Worker private:
69*61c4878aSAndroid Build Coastguard Worker std::array<TestMethodUnion, 2> methods_;
70*61c4878aSAndroid Build Coastguard Worker };
71*61c4878aSAndroid Build Coastguard Worker
72*61c4878aSAndroid Build Coastguard Worker class EmptyService : public Service {
73*61c4878aSAndroid Build Coastguard Worker public:
EmptyService()74*61c4878aSAndroid Build Coastguard Worker constexpr EmptyService() : Service(200, methods_) {}
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard Worker private:
77*61c4878aSAndroid Build Coastguard Worker static constexpr std::array<TestMethodUnion, 0> methods_ = {};
78*61c4878aSAndroid Build Coastguard Worker };
79*61c4878aSAndroid Build Coastguard Worker
80*61c4878aSAndroid Build Coastguard Worker uint32_t kDefaultCallId = 24601;
81*61c4878aSAndroid Build Coastguard Worker
82*61c4878aSAndroid Build Coastguard Worker class BasicServer : public ::testing::Test {
83*61c4878aSAndroid Build Coastguard Worker protected:
84*61c4878aSAndroid Build Coastguard Worker static constexpr byte kDefaultPayload[] = {
85*61c4878aSAndroid Build Coastguard Worker byte(0x82), byte(0x02), byte(0xff), byte(0xff)};
86*61c4878aSAndroid Build Coastguard Worker
BasicServer()87*61c4878aSAndroid Build Coastguard Worker BasicServer()
88*61c4878aSAndroid Build Coastguard Worker : channels_{
89*61c4878aSAndroid Build Coastguard Worker Channel::Create<1>(&output_),
90*61c4878aSAndroid Build Coastguard Worker Channel::Create<2>(&output_),
91*61c4878aSAndroid Build Coastguard Worker Channel(), // available for assignment
92*61c4878aSAndroid Build Coastguard Worker },
93*61c4878aSAndroid Build Coastguard Worker server_(channels_),
94*61c4878aSAndroid Build Coastguard Worker service_1_(1),
95*61c4878aSAndroid Build Coastguard Worker service_42_(42) {
96*61c4878aSAndroid Build Coastguard Worker server_.RegisterService(service_1_, service_42_, empty_service_);
97*61c4878aSAndroid Build Coastguard Worker }
98*61c4878aSAndroid Build Coastguard Worker
EncodePacket(PacketType type,uint32_t channel_id,uint32_t service_id,uint32_t method_id,uint32_t call_id=kDefaultCallId)99*61c4878aSAndroid Build Coastguard Worker span<const byte> EncodePacket(PacketType type,
100*61c4878aSAndroid Build Coastguard Worker uint32_t channel_id,
101*61c4878aSAndroid Build Coastguard Worker uint32_t service_id,
102*61c4878aSAndroid Build Coastguard Worker uint32_t method_id,
103*61c4878aSAndroid Build Coastguard Worker uint32_t call_id = kDefaultCallId) {
104*61c4878aSAndroid Build Coastguard Worker return EncodePacketWithBody(type,
105*61c4878aSAndroid Build Coastguard Worker channel_id,
106*61c4878aSAndroid Build Coastguard Worker service_id,
107*61c4878aSAndroid Build Coastguard Worker method_id,
108*61c4878aSAndroid Build Coastguard Worker call_id,
109*61c4878aSAndroid Build Coastguard Worker kDefaultPayload,
110*61c4878aSAndroid Build Coastguard Worker OkStatus());
111*61c4878aSAndroid Build Coastguard Worker }
112*61c4878aSAndroid Build Coastguard Worker
EncodeCancel(uint32_t channel_id=1,uint32_t service_id=42,uint32_t method_id=100,uint32_t call_id=kDefaultCallId)113*61c4878aSAndroid Build Coastguard Worker span<const byte> EncodeCancel(uint32_t channel_id = 1,
114*61c4878aSAndroid Build Coastguard Worker uint32_t service_id = 42,
115*61c4878aSAndroid Build Coastguard Worker uint32_t method_id = 100,
116*61c4878aSAndroid Build Coastguard Worker uint32_t call_id = kDefaultCallId) {
117*61c4878aSAndroid Build Coastguard Worker return EncodePacketWithBody(PacketType::CLIENT_ERROR,
118*61c4878aSAndroid Build Coastguard Worker channel_id,
119*61c4878aSAndroid Build Coastguard Worker service_id,
120*61c4878aSAndroid Build Coastguard Worker method_id,
121*61c4878aSAndroid Build Coastguard Worker call_id,
122*61c4878aSAndroid Build Coastguard Worker {},
123*61c4878aSAndroid Build Coastguard Worker Status::Cancelled());
124*61c4878aSAndroid Build Coastguard Worker }
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard Worker template <typename T = ConstByteSpan>
PacketForRpc(PacketType type,Status status=OkStatus (),T && payload={},uint32_t call_id=kDefaultCallId)127*61c4878aSAndroid Build Coastguard Worker ConstByteSpan PacketForRpc(PacketType type,
128*61c4878aSAndroid Build Coastguard Worker Status status = OkStatus(),
129*61c4878aSAndroid Build Coastguard Worker T&& payload = {},
130*61c4878aSAndroid Build Coastguard Worker uint32_t call_id = kDefaultCallId) {
131*61c4878aSAndroid Build Coastguard Worker return EncodePacketWithBody(
132*61c4878aSAndroid Build Coastguard Worker type, 1, 42, 100, call_id, as_bytes(span(payload)), status);
133*61c4878aSAndroid Build Coastguard Worker }
134*61c4878aSAndroid Build Coastguard Worker
135*61c4878aSAndroid Build Coastguard Worker RawFakeChannelOutput<2> output_;
136*61c4878aSAndroid Build Coastguard Worker std::array<Channel, 3> channels_;
137*61c4878aSAndroid Build Coastguard Worker Server server_;
138*61c4878aSAndroid Build Coastguard Worker TestService service_1_;
139*61c4878aSAndroid Build Coastguard Worker TestService service_42_;
140*61c4878aSAndroid Build Coastguard Worker EmptyService empty_service_;
141*61c4878aSAndroid Build Coastguard Worker
142*61c4878aSAndroid Build Coastguard Worker private:
143*61c4878aSAndroid Build Coastguard Worker byte request_buffer_[64];
144*61c4878aSAndroid Build Coastguard Worker
EncodePacketWithBody(PacketType type,uint32_t channel_id,uint32_t service_id,uint32_t method_id,uint32_t call_id,span<const byte> payload,Status status)145*61c4878aSAndroid Build Coastguard Worker span<const byte> EncodePacketWithBody(PacketType type,
146*61c4878aSAndroid Build Coastguard Worker uint32_t channel_id,
147*61c4878aSAndroid Build Coastguard Worker uint32_t service_id,
148*61c4878aSAndroid Build Coastguard Worker uint32_t method_id,
149*61c4878aSAndroid Build Coastguard Worker uint32_t call_id,
150*61c4878aSAndroid Build Coastguard Worker span<const byte> payload,
151*61c4878aSAndroid Build Coastguard Worker Status status) {
152*61c4878aSAndroid Build Coastguard Worker auto result =
153*61c4878aSAndroid Build Coastguard Worker Packet(
154*61c4878aSAndroid Build Coastguard Worker type, channel_id, service_id, method_id, call_id, payload, status)
155*61c4878aSAndroid Build Coastguard Worker .Encode(request_buffer_);
156*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), result.status());
157*61c4878aSAndroid Build Coastguard Worker return result.value_or(ConstByteSpan());
158*61c4878aSAndroid Build Coastguard Worker }
159*61c4878aSAndroid Build Coastguard Worker };
160*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,IsServiceRegistered)161*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, IsServiceRegistered) {
162*61c4878aSAndroid Build Coastguard Worker TestService unregisteredService(0);
163*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(server_.IsServiceRegistered(unregisteredService));
164*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(server_.IsServiceRegistered(service_1_));
165*61c4878aSAndroid Build Coastguard Worker }
166*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_ValidMethodInService1_InvokesMethod)167*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_ValidMethodInService1_InvokesMethod) {
168*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
169*61c4878aSAndroid Build Coastguard Worker OkStatus(),
170*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 1, 100)));
171*61c4878aSAndroid Build Coastguard Worker
172*61c4878aSAndroid Build Coastguard Worker const TestMethod& method = service_1_.method(100);
173*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, method.last_channel_id());
174*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kDefaultPayload), method.last_request().payload().size());
175*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(std::memcmp(kDefaultPayload,
176*61c4878aSAndroid Build Coastguard Worker method.last_request().payload().data(),
177*61c4878aSAndroid Build Coastguard Worker method.last_request().payload().size()),
178*61c4878aSAndroid Build Coastguard Worker 0);
179*61c4878aSAndroid Build Coastguard Worker }
180*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_ValidMethodInService42_InvokesMethod)181*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_ValidMethodInService42_InvokesMethod) {
182*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
183*61c4878aSAndroid Build Coastguard Worker OkStatus(),
184*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 42, 200)));
185*61c4878aSAndroid Build Coastguard Worker
186*61c4878aSAndroid Build Coastguard Worker const TestMethod& method = service_42_.method(200);
187*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, method.last_channel_id());
188*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kDefaultPayload), method.last_request().payload().size());
189*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(std::memcmp(kDefaultPayload,
190*61c4878aSAndroid Build Coastguard Worker method.last_request().payload().data(),
191*61c4878aSAndroid Build Coastguard Worker method.last_request().payload().size()),
192*61c4878aSAndroid Build Coastguard Worker 0);
193*61c4878aSAndroid Build Coastguard Worker }
194*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,UnregisterService_CannotCallMethod)195*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, UnregisterService_CannotCallMethod) {
196*61c4878aSAndroid Build Coastguard Worker const uint32_t kCallId = 8675309;
197*61c4878aSAndroid Build Coastguard Worker server_.UnregisterService(service_1_, service_42_);
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
200*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
201*61c4878aSAndroid Build Coastguard Worker EncodePacket(PacketType::REQUEST, 1, 1, 100, kCallId)));
202*61c4878aSAndroid Build Coastguard Worker
203*61c4878aSAndroid Build Coastguard Worker const Packet& packet =
204*61c4878aSAndroid Build Coastguard Worker static_cast<internal::test::FakeChannelOutput&>(output_).last_packet();
205*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
206*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), 1u);
207*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), 1u);
208*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), 100u);
209*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.call_id(), kCallId);
210*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.status(), Status::NotFound());
211*61c4878aSAndroid Build Coastguard Worker }
212*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,UnregisterService_AlreadyUnregistered_DoesNothing)213*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, UnregisterService_AlreadyUnregistered_DoesNothing) {
214*61c4878aSAndroid Build Coastguard Worker server_.UnregisterService(service_42_, service_42_, service_42_);
215*61c4878aSAndroid Build Coastguard Worker server_.UnregisterService(service_42_);
216*61c4878aSAndroid Build Coastguard Worker
217*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
218*61c4878aSAndroid Build Coastguard Worker OkStatus(),
219*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 1, 100)));
220*61c4878aSAndroid Build Coastguard Worker
221*61c4878aSAndroid Build Coastguard Worker const TestMethod& method = service_1_.method(100);
222*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(1u, method.last_channel_id());
223*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(sizeof(kDefaultPayload), method.last_request().payload().size());
224*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(std::memcmp(kDefaultPayload,
225*61c4878aSAndroid Build Coastguard Worker method.last_request().payload().data(),
226*61c4878aSAndroid Build Coastguard Worker method.last_request().payload().size()),
227*61c4878aSAndroid Build Coastguard Worker 0);
228*61c4878aSAndroid Build Coastguard Worker }
229*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_IncompletePacket_NothingIsInvoked)230*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_IncompletePacket_NothingIsInvoked) {
231*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
232*61c4878aSAndroid Build Coastguard Worker Status::DataLoss(),
233*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 0, 42, 101)));
234*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
235*61c4878aSAndroid Build Coastguard Worker Status::DataLoss(),
236*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 0, 101)));
237*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::DataLoss(),
238*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 42, 0)));
239*61c4878aSAndroid Build Coastguard Worker
240*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, service_42_.method(100).last_channel_id());
241*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, service_42_.method(200).last_channel_id());
242*61c4878aSAndroid Build Coastguard Worker }
243*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_NoChannel_SendsNothing)244*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_NoChannel_SendsNothing) {
245*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
246*61c4878aSAndroid Build Coastguard Worker Status::DataLoss(),
247*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 0, 42, 101)));
248*61c4878aSAndroid Build Coastguard Worker
249*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
250*61c4878aSAndroid Build Coastguard Worker }
251*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_NoService_SendsNothing)252*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_NoService_SendsNothing) {
253*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
254*61c4878aSAndroid Build Coastguard Worker Status::DataLoss(),
255*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 0, 101)));
256*61c4878aSAndroid Build Coastguard Worker
257*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
258*61c4878aSAndroid Build Coastguard Worker }
259*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_NoMethod_SendsNothing)260*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_NoMethod_SendsNothing) {
261*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::DataLoss(),
262*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 42, 0)));
263*61c4878aSAndroid Build Coastguard Worker
264*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
265*61c4878aSAndroid Build Coastguard Worker }
266*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_InvalidMethod_NothingIsInvoked)267*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_InvalidMethod_NothingIsInvoked) {
268*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
269*61c4878aSAndroid Build Coastguard Worker OkStatus(),
270*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 42, 101)));
271*61c4878aSAndroid Build Coastguard Worker
272*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, service_42_.method(100).last_channel_id());
273*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, service_42_.method(200).last_channel_id());
274*61c4878aSAndroid Build Coastguard Worker }
275*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_ClientErrorWithInvalidMethod_NoResponse)276*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_ClientErrorWithInvalidMethod_NoResponse) {
277*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
278*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
279*61c4878aSAndroid Build Coastguard Worker EncodePacket(PacketType::CLIENT_ERROR, 1, 42, 101)));
280*61c4878aSAndroid Build Coastguard Worker
281*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, output_.total_packets());
282*61c4878aSAndroid Build Coastguard Worker }
283*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_InvalidMethod_SendsError)284*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_InvalidMethod_SendsError) {
285*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
286*61c4878aSAndroid Build Coastguard Worker OkStatus(),
287*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 42, 27)));
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker const Packet& packet =
290*61c4878aSAndroid Build Coastguard Worker static_cast<internal::test::FakeChannelOutput&>(output_).last_packet();
291*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
292*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), 1u);
293*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), 42u);
294*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), 27u); // No method ID 27
295*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.status(), Status::NotFound());
296*61c4878aSAndroid Build Coastguard Worker }
297*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_InvalidService_SendsError)298*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_InvalidService_SendsError) {
299*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
300*61c4878aSAndroid Build Coastguard Worker OkStatus(),
301*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 43, 27)));
302*61c4878aSAndroid Build Coastguard Worker
303*61c4878aSAndroid Build Coastguard Worker const Packet& packet =
304*61c4878aSAndroid Build Coastguard Worker static_cast<internal::test::FakeChannelOutput&>(output_).last_packet();
305*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
306*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), 1u);
307*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), 43u); // No service ID 43
308*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), 27u);
309*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.status(), Status::NotFound());
310*61c4878aSAndroid Build Coastguard Worker }
311*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_UnassignedChannel)312*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_UnassignedChannel) {
313*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Unavailable(),
314*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
315*61c4878aSAndroid Build Coastguard Worker EncodePacket(PacketType::REQUEST, /*channel_id=*/99, 42, 27)));
316*61c4878aSAndroid Build Coastguard Worker }
317*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_ClientErrorOnUnassignedChannel_NoResponse)318*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_ClientErrorOnUnassignedChannel_NoResponse) {
319*61c4878aSAndroid Build Coastguard Worker channels_[2] = Channel::Create<3>(&output_); // Occupy only available channel
320*61c4878aSAndroid Build Coastguard Worker
321*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Unavailable(),
322*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(
323*61c4878aSAndroid Build Coastguard Worker PacketType::CLIENT_ERROR, /*channel_id=*/99, 42, 27)));
324*61c4878aSAndroid Build Coastguard Worker
325*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0u, output_.total_packets());
326*61c4878aSAndroid Build Coastguard Worker }
327*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,ProcessPacket_Cancel_MethodNotActive_SendsNothing)328*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, ProcessPacket_Cancel_MethodNotActive_SendsNothing) {
329*61c4878aSAndroid Build Coastguard Worker // Set up a fake ServerWriter representing an ongoing RPC.
330*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel(1, 42, 100)));
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
333*61c4878aSAndroid Build Coastguard Worker }
334*61c4878aSAndroid Build Coastguard Worker
GetChannel(internal::Endpoint & endpoint,uint32_t id)335*61c4878aSAndroid Build Coastguard Worker const internal::ChannelBase* GetChannel(internal::Endpoint& endpoint,
336*61c4878aSAndroid Build Coastguard Worker uint32_t id) {
337*61c4878aSAndroid Build Coastguard Worker internal::RpcLockGuard lock;
338*61c4878aSAndroid Build Coastguard Worker return endpoint.GetInternalChannel(id);
339*61c4878aSAndroid Build Coastguard Worker }
340*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,CloseChannel_NoCalls)341*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, CloseChannel_NoCalls) {
342*61c4878aSAndroid Build Coastguard Worker EXPECT_NE(nullptr, GetChannel(server_, 2));
343*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.CloseChannel(2));
344*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, GetChannel(server_, 2));
345*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(output_.total_packets(), 0u);
346*61c4878aSAndroid Build Coastguard Worker }
347*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,CloseChannel_UnknownChannel)348*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, CloseChannel_UnknownChannel) {
349*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(nullptr, GetChannel(server_, 13579));
350*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::NotFound(), server_.CloseChannel(13579));
351*61c4878aSAndroid Build Coastguard Worker }
352*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,CloseChannel_PendingCall)353*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, CloseChannel_PendingCall) {
354*61c4878aSAndroid Build Coastguard Worker EXPECT_NE(nullptr, GetChannel(server_, 1));
355*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<internal::Endpoint&>(server_).active_call_count(), 0u);
356*61c4878aSAndroid Build Coastguard Worker
357*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerReaderWriter call;
358*61c4878aSAndroid Build Coastguard Worker service_42_.method(100).keep_call_active(call);
359*61c4878aSAndroid Build Coastguard Worker
360*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
361*61c4878aSAndroid Build Coastguard Worker OkStatus(),
362*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(EncodePacket(PacketType::REQUEST, 1, 42, 100)));
363*61c4878aSAndroid Build Coastguard Worker
364*61c4878aSAndroid Build Coastguard Worker Status on_error_status;
365*61c4878aSAndroid Build Coastguard Worker call.set_on_error(
366*61c4878aSAndroid Build Coastguard Worker [&on_error_status](Status error) { on_error_status = error; });
367*61c4878aSAndroid Build Coastguard Worker
368*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(call.active());
369*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<internal::Endpoint&>(server_).active_call_count(), 1u);
370*61c4878aSAndroid Build Coastguard Worker
371*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.CloseChannel(1));
372*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, GetChannel(server_, 1));
373*61c4878aSAndroid Build Coastguard Worker
374*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<internal::Endpoint&>(server_).active_call_count(), 0u);
375*61c4878aSAndroid Build Coastguard Worker
376*61c4878aSAndroid Build Coastguard Worker // Should call on_error, but not send a packet since the channel is closed.
377*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Aborted(), on_error_status);
378*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(output_.total_packets(), 0u);
379*61c4878aSAndroid Build Coastguard Worker }
380*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,OpenChannel_UnusedSlot)381*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, OpenChannel_UnusedSlot) {
382*61c4878aSAndroid Build Coastguard Worker const span request = EncodePacket(PacketType::REQUEST, 9, 42, 100);
383*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Unavailable(), server_.ProcessPacket(request));
384*61c4878aSAndroid Build Coastguard Worker
385*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.OpenChannel(9, output_));
386*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.ProcessPacket(request));
387*61c4878aSAndroid Build Coastguard Worker
388*61c4878aSAndroid Build Coastguard Worker const Packet& packet =
389*61c4878aSAndroid Build Coastguard Worker static_cast<internal::test::FakeChannelOutput&>(output_).last_packet();
390*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.type(), PacketType::RESPONSE);
391*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.channel_id(), 9u);
392*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.service_id(), 42u);
393*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.method_id(), 100u);
394*61c4878aSAndroid Build Coastguard Worker }
395*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,OpenChannel_AlreadyExists)396*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, OpenChannel_AlreadyExists) {
397*61c4878aSAndroid Build Coastguard Worker ASSERT_NE(nullptr, GetChannel(server_, 1));
398*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::AlreadyExists(), server_.OpenChannel(1, output_));
399*61c4878aSAndroid Build Coastguard Worker }
400*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,OpenChannel_AdditionalSlot)401*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, OpenChannel_AdditionalSlot) {
402*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.OpenChannel(3, output_));
403*61c4878aSAndroid Build Coastguard Worker
404*61c4878aSAndroid Build Coastguard Worker constexpr Status kExpected =
405*61c4878aSAndroid Build Coastguard Worker PW_RPC_DYNAMIC_ALLOCATION == 0 ? Status::ResourceExhausted() : OkStatus();
406*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(kExpected, server_.OpenChannel(19823, output_));
407*61c4878aSAndroid Build Coastguard Worker }
408*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,FindMethod_FoundOkOptionallyCheckType)409*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, FindMethod_FoundOkOptionallyCheckType) {
410*61c4878aSAndroid Build Coastguard Worker const auto [service, method] = ServerTestHelper::FindMethod(server_, 1, 100);
411*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(service != nullptr);
412*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(method != nullptr);
413*61c4878aSAndroid Build Coastguard Worker #if PW_RPC_METHOD_STORES_TYPE
414*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(MethodType::kBidirectionalStreaming, method->type());
415*61c4878aSAndroid Build Coastguard Worker #endif
416*61c4878aSAndroid Build Coastguard Worker }
417*61c4878aSAndroid Build Coastguard Worker
TEST_F(BasicServer,FindMethod_NotFound)418*61c4878aSAndroid Build Coastguard Worker TEST_F(BasicServer, FindMethod_NotFound) {
419*61c4878aSAndroid Build Coastguard Worker {
420*61c4878aSAndroid Build Coastguard Worker const auto [service, method] =
421*61c4878aSAndroid Build Coastguard Worker ServerTestHelper::FindMethod(server_, 2, 100);
422*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(service == nullptr);
423*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(method == nullptr);
424*61c4878aSAndroid Build Coastguard Worker }
425*61c4878aSAndroid Build Coastguard Worker
426*61c4878aSAndroid Build Coastguard Worker {
427*61c4878aSAndroid Build Coastguard Worker const auto [service, method] =
428*61c4878aSAndroid Build Coastguard Worker ServerTestHelper::FindMethod(server_, 1, 101);
429*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(service != nullptr);
430*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(method == nullptr);
431*61c4878aSAndroid Build Coastguard Worker }
432*61c4878aSAndroid Build Coastguard Worker }
433*61c4878aSAndroid Build Coastguard Worker
434*61c4878aSAndroid Build Coastguard Worker class BidiMethod : public BasicServer {
435*61c4878aSAndroid Build Coastguard Worker protected:
BidiMethod()436*61c4878aSAndroid Build Coastguard Worker BidiMethod() {
437*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().lock();
438*61c4878aSAndroid Build Coastguard Worker internal::CallContext context(server_,
439*61c4878aSAndroid Build Coastguard Worker channels_[0].id(),
440*61c4878aSAndroid Build Coastguard Worker service_42_,
441*61c4878aSAndroid Build Coastguard Worker service_42_.method(100),
442*61c4878aSAndroid Build Coastguard Worker kDefaultCallId);
443*61c4878aSAndroid Build Coastguard Worker // A local temporary is required since the constructor requires a lock,
444*61c4878aSAndroid Build Coastguard Worker // but the *move* constructor takes out the lock.
445*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerReaderWriter responder_temp(
446*61c4878aSAndroid Build Coastguard Worker context.ClaimLocked());
447*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().unlock();
448*61c4878aSAndroid Build Coastguard Worker responder_ = std::move(responder_temp);
449*61c4878aSAndroid Build Coastguard Worker PW_CHECK(responder_.active());
450*61c4878aSAndroid Build Coastguard Worker }
451*61c4878aSAndroid Build Coastguard Worker
452*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerReaderWriter responder_;
453*61c4878aSAndroid Build Coastguard Worker };
454*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,DuplicateCallId_CancelsExistingThenCallsAgain)455*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, DuplicateCallId_CancelsExistingThenCallsAgain) {
456*61c4878aSAndroid Build Coastguard Worker int cancelled = 0;
457*61c4878aSAndroid Build Coastguard Worker responder_.set_on_error([&cancelled](Status error) {
458*61c4878aSAndroid Build Coastguard Worker if (error.IsCancelled()) {
459*61c4878aSAndroid Build Coastguard Worker cancelled += 1;
460*61c4878aSAndroid Build Coastguard Worker }
461*61c4878aSAndroid Build Coastguard Worker });
462*61c4878aSAndroid Build Coastguard Worker
463*61c4878aSAndroid Build Coastguard Worker const TestMethod& method = service_42_.method(100);
464*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(method.invocations(), 0u);
465*61c4878aSAndroid Build Coastguard Worker
466*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
467*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(PacketType::REQUEST)));
468*61c4878aSAndroid Build Coastguard Worker
469*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(cancelled, 1);
470*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(method.invocations(), 1u);
471*61c4878aSAndroid Build Coastguard Worker }
472*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,DuplicateMethodDifferentCallId_NotCancelled)473*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, DuplicateMethodDifferentCallId_NotCancelled) {
474*61c4878aSAndroid Build Coastguard Worker int cancelled = 0;
475*61c4878aSAndroid Build Coastguard Worker responder_.set_on_error([&cancelled](Status error) {
476*61c4878aSAndroid Build Coastguard Worker if (error.IsCancelled()) {
477*61c4878aSAndroid Build Coastguard Worker cancelled += 1;
478*61c4878aSAndroid Build Coastguard Worker }
479*61c4878aSAndroid Build Coastguard Worker });
480*61c4878aSAndroid Build Coastguard Worker
481*61c4878aSAndroid Build Coastguard Worker const uint32_t kSecondCallId = 1625;
482*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
483*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(
484*61c4878aSAndroid Build Coastguard Worker PacketType::REQUEST, OkStatus(), {}, kSecondCallId)));
485*61c4878aSAndroid Build Coastguard Worker
486*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(cancelled, 0);
487*61c4878aSAndroid Build Coastguard Worker }
488*61c4878aSAndroid Build Coastguard Worker
span_as_cstr(ConstByteSpan span)489*61c4878aSAndroid Build Coastguard Worker const char* span_as_cstr(ConstByteSpan span) {
490*61c4878aSAndroid Build Coastguard Worker return reinterpret_cast<const char*>(span.data());
491*61c4878aSAndroid Build Coastguard Worker }
492*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,DuplicateMethodDifferentCallIdEachCallGetsSeparateResponse)493*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, DuplicateMethodDifferentCallIdEachCallGetsSeparateResponse) {
494*61c4878aSAndroid Build Coastguard Worker const uint32_t kSecondCallId = 1625;
495*61c4878aSAndroid Build Coastguard Worker
496*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().lock();
497*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerReaderWriter responder_2(
498*61c4878aSAndroid Build Coastguard Worker internal::CallContext(server_,
499*61c4878aSAndroid Build Coastguard Worker channels_[0].id(),
500*61c4878aSAndroid Build Coastguard Worker service_42_,
501*61c4878aSAndroid Build Coastguard Worker service_42_.method(100),
502*61c4878aSAndroid Build Coastguard Worker kSecondCallId)
503*61c4878aSAndroid Build Coastguard Worker .ClaimLocked());
504*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().unlock();
505*61c4878aSAndroid Build Coastguard Worker
506*61c4878aSAndroid Build Coastguard Worker ConstByteSpan data_1 = as_bytes(span("data_1_unset"));
507*61c4878aSAndroid Build Coastguard Worker responder_.set_on_next(
508*61c4878aSAndroid Build Coastguard Worker [&data_1](ConstByteSpan payload) { data_1 = payload; });
509*61c4878aSAndroid Build Coastguard Worker
510*61c4878aSAndroid Build Coastguard Worker ConstByteSpan data_2 = as_bytes(span("data_2_unset"));
511*61c4878aSAndroid Build Coastguard Worker responder_2.set_on_next(
512*61c4878aSAndroid Build Coastguard Worker [&data_2](ConstByteSpan payload) { data_2 = payload; });
513*61c4878aSAndroid Build Coastguard Worker
514*61c4878aSAndroid Build Coastguard Worker const char* kMessage1 = "hello_1";
515*61c4878aSAndroid Build Coastguard Worker const char* kMessage2 = "hello_2";
516*61c4878aSAndroid Build Coastguard Worker
517*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
518*61c4878aSAndroid Build Coastguard Worker OkStatus(),
519*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(
520*61c4878aSAndroid Build Coastguard Worker PacketType::CLIENT_STREAM, OkStatus(), "hello_2", kSecondCallId)));
521*61c4878aSAndroid Build Coastguard Worker
522*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(span_as_cstr(data_2), kMessage2);
523*61c4878aSAndroid Build Coastguard Worker
524*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
525*61c4878aSAndroid Build Coastguard Worker OkStatus(),
526*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(
527*61c4878aSAndroid Build Coastguard Worker PacketType::CLIENT_STREAM, OkStatus(), "hello_1", kDefaultCallId)));
528*61c4878aSAndroid Build Coastguard Worker
529*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(span_as_cstr(data_1), kMessage1);
530*61c4878aSAndroid Build Coastguard Worker }
531*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,Cancel_ClosesServerWriter)532*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, Cancel_ClosesServerWriter) {
533*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel()));
534*61c4878aSAndroid Build Coastguard Worker
535*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(responder_.active());
536*61c4878aSAndroid Build Coastguard Worker }
537*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,Cancel_SendsNoResponse)538*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, Cancel_SendsNoResponse) {
539*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel()));
540*61c4878aSAndroid Build Coastguard Worker
541*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
542*61c4878aSAndroid Build Coastguard Worker }
543*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientError_ClosesServerWriterWithoutResponse)544*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientError_ClosesServerWriterWithoutResponse) {
545*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
546*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_ERROR)));
547*61c4878aSAndroid Build Coastguard Worker
548*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(responder_.active());
549*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
550*61c4878aSAndroid Build Coastguard Worker }
551*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientError_CallsOnErrorCallback)552*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientError_CallsOnErrorCallback) {
553*61c4878aSAndroid Build Coastguard Worker Status status = Status::Unknown();
554*61c4878aSAndroid Build Coastguard Worker responder_.set_on_error([&status](Status error) { status = error; });
555*61c4878aSAndroid Build Coastguard Worker
556*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
557*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_ERROR,
558*61c4878aSAndroid Build Coastguard Worker Status::Unauthenticated())));
559*61c4878aSAndroid Build Coastguard Worker
560*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(status, Status::Unauthenticated());
561*61c4878aSAndroid Build Coastguard Worker }
562*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,Cancel_CallsOnErrorCallback)563*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, Cancel_CallsOnErrorCallback) {
564*61c4878aSAndroid Build Coastguard Worker Status status = Status::Unknown();
565*61c4878aSAndroid Build Coastguard Worker responder_.set_on_error([&status](Status error) { status = error; });
566*61c4878aSAndroid Build Coastguard Worker
567*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel()));
568*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(status, Status::Cancelled());
569*61c4878aSAndroid Build Coastguard Worker }
570*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,Cancel_IncorrectChannel_SendsNothing)571*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, Cancel_IncorrectChannel_SendsNothing) {
572*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel(2, 42, 100)));
573*61c4878aSAndroid Build Coastguard Worker
574*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
575*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(responder_.active());
576*61c4878aSAndroid Build Coastguard Worker }
577*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,Cancel_IncorrectService_SendsNothing)578*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, Cancel_IncorrectService_SendsNothing) {
579*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel(1, 43, 100)));
580*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
581*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(responder_.active());
582*61c4878aSAndroid Build Coastguard Worker }
583*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,Cancel_IncorrectMethod_SendsNothing)584*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, Cancel_IncorrectMethod_SendsNothing) {
585*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel(1, 42, 101)));
586*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
587*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(responder_.active());
588*61c4878aSAndroid Build Coastguard Worker }
589*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientStream_CallsCallback)590*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientStream_CallsCallback) {
591*61c4878aSAndroid Build Coastguard Worker ConstByteSpan data = as_bytes(span("?"));
592*61c4878aSAndroid Build Coastguard Worker responder_.set_on_next([&data](ConstByteSpan payload) { data = payload; });
593*61c4878aSAndroid Build Coastguard Worker
594*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
595*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
596*61c4878aSAndroid Build Coastguard Worker PacketForRpc(PacketType::CLIENT_STREAM, {}, "hello")));
597*61c4878aSAndroid Build Coastguard Worker
598*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
599*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(span_as_cstr(data), "hello");
600*61c4878aSAndroid Build Coastguard Worker }
601*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientStream_CallsCallbackOnCallWithOpenId)602*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientStream_CallsCallbackOnCallWithOpenId) {
603*61c4878aSAndroid Build Coastguard Worker ConstByteSpan data = as_bytes(span("?"));
604*61c4878aSAndroid Build Coastguard Worker responder_.set_on_next([&data](ConstByteSpan payload) { data = payload; });
605*61c4878aSAndroid Build Coastguard Worker
606*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(
607*61c4878aSAndroid Build Coastguard Worker OkStatus(),
608*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(
609*61c4878aSAndroid Build Coastguard Worker PacketType::CLIENT_STREAM, {}, "hello", internal::kOpenCallId)));
610*61c4878aSAndroid Build Coastguard Worker
611*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
612*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(span_as_cstr(data), "hello");
613*61c4878aSAndroid Build Coastguard Worker }
614*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientStream_CallsCallbackOnCallWithLegacyOpenId)615*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientStream_CallsCallbackOnCallWithLegacyOpenId) {
616*61c4878aSAndroid Build Coastguard Worker ConstByteSpan data = as_bytes(span("?"));
617*61c4878aSAndroid Build Coastguard Worker responder_.set_on_next([&data](ConstByteSpan payload) { data = payload; });
618*61c4878aSAndroid Build Coastguard Worker
619*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
620*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_STREAM,
621*61c4878aSAndroid Build Coastguard Worker {},
622*61c4878aSAndroid Build Coastguard Worker "hello",
623*61c4878aSAndroid Build Coastguard Worker internal::kLegacyOpenCallId)));
624*61c4878aSAndroid Build Coastguard Worker
625*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
626*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(span_as_cstr(data), "hello");
627*61c4878aSAndroid Build Coastguard Worker }
628*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientStream_CallsOpenIdOnCallWithDifferentId)629*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientStream_CallsOpenIdOnCallWithDifferentId) {
630*61c4878aSAndroid Build Coastguard Worker const uint32_t kSecondCallId = 1625;
631*61c4878aSAndroid Build Coastguard Worker internal::CallContext context(server_,
632*61c4878aSAndroid Build Coastguard Worker channels_[0].id(),
633*61c4878aSAndroid Build Coastguard Worker service_42_,
634*61c4878aSAndroid Build Coastguard Worker service_42_.method(100),
635*61c4878aSAndroid Build Coastguard Worker internal::kOpenCallId);
636*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().lock();
637*61c4878aSAndroid Build Coastguard Worker auto temp_responder =
638*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerReaderWriter(context.ClaimLocked());
639*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().unlock();
640*61c4878aSAndroid Build Coastguard Worker responder_ = std::move(temp_responder);
641*61c4878aSAndroid Build Coastguard Worker
642*61c4878aSAndroid Build Coastguard Worker ConstByteSpan data = as_bytes(span("?"));
643*61c4878aSAndroid Build Coastguard Worker responder_.set_on_next([&data](ConstByteSpan payload) { data = payload; });
644*61c4878aSAndroid Build Coastguard Worker
645*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
646*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(
647*61c4878aSAndroid Build Coastguard Worker PacketType::CLIENT_STREAM, {}, "hello", kSecondCallId)));
648*61c4878aSAndroid Build Coastguard Worker
649*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
650*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(span_as_cstr(data), "hello");
651*61c4878aSAndroid Build Coastguard Worker
652*61c4878aSAndroid Build Coastguard Worker internal::RpcLockGuard lock;
653*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(responder_.as_server_call().id(), kSecondCallId);
654*61c4878aSAndroid Build Coastguard Worker }
655*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientStream_CallsLegacyOpenIdOnCallWithDifferentId)656*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientStream_CallsLegacyOpenIdOnCallWithDifferentId) {
657*61c4878aSAndroid Build Coastguard Worker const uint32_t kSecondCallId = 1625;
658*61c4878aSAndroid Build Coastguard Worker internal::CallContext context(server_,
659*61c4878aSAndroid Build Coastguard Worker channels_[0].id(),
660*61c4878aSAndroid Build Coastguard Worker service_42_,
661*61c4878aSAndroid Build Coastguard Worker service_42_.method(100),
662*61c4878aSAndroid Build Coastguard Worker internal::kLegacyOpenCallId);
663*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().lock();
664*61c4878aSAndroid Build Coastguard Worker auto temp_responder =
665*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerReaderWriter(context.ClaimLocked());
666*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().unlock();
667*61c4878aSAndroid Build Coastguard Worker responder_ = std::move(temp_responder);
668*61c4878aSAndroid Build Coastguard Worker
669*61c4878aSAndroid Build Coastguard Worker ConstByteSpan data = as_bytes(span("?"));
670*61c4878aSAndroid Build Coastguard Worker responder_.set_on_next([&data](ConstByteSpan payload) { data = payload; });
671*61c4878aSAndroid Build Coastguard Worker
672*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
673*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(
674*61c4878aSAndroid Build Coastguard Worker PacketType::CLIENT_STREAM, {}, "hello", kSecondCallId)));
675*61c4878aSAndroid Build Coastguard Worker
676*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
677*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(span_as_cstr(data), "hello");
678*61c4878aSAndroid Build Coastguard Worker
679*61c4878aSAndroid Build Coastguard Worker internal::RpcLockGuard lock;
680*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(responder_.as_server_call().id(), kSecondCallId);
681*61c4878aSAndroid Build Coastguard Worker }
682*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,UnregsiterService_AbortsActiveCalls)683*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, UnregsiterService_AbortsActiveCalls) {
684*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(responder_.active());
685*61c4878aSAndroid Build Coastguard Worker
686*61c4878aSAndroid Build Coastguard Worker Status on_error_status = OkStatus();
687*61c4878aSAndroid Build Coastguard Worker responder_.set_on_error(
688*61c4878aSAndroid Build Coastguard Worker [&on_error_status](Status status) { on_error_status = status; });
689*61c4878aSAndroid Build Coastguard Worker
690*61c4878aSAndroid Build Coastguard Worker server_.UnregisterService(service_42_);
691*61c4878aSAndroid Build Coastguard Worker
692*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(responder_.active());
693*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Aborted(), on_error_status);
694*61c4878aSAndroid Build Coastguard Worker }
695*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientRequestedCompletion_CallsCallback)696*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientRequestedCompletion_CallsCallback) {
697*61c4878aSAndroid Build Coastguard Worker bool called = false;
698*61c4878aSAndroid Build Coastguard Worker #if PW_RPC_COMPLETION_REQUEST_CALLBACK
699*61c4878aSAndroid Build Coastguard Worker responder_.set_on_completion_requested([&called]() { called = true; });
700*61c4878aSAndroid Build Coastguard Worker #endif
701*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
702*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
703*61c4878aSAndroid Build Coastguard Worker PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION)));
704*61c4878aSAndroid Build Coastguard Worker
705*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
706*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(called, PW_RPC_COMPLETION_REQUEST_CALLBACK);
707*61c4878aSAndroid Build Coastguard Worker }
708*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientRequestedCompletion_CallsCallbackIfEnabled)709*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientRequestedCompletion_CallsCallbackIfEnabled) {
710*61c4878aSAndroid Build Coastguard Worker bool called = false;
711*61c4878aSAndroid Build Coastguard Worker responder_.set_on_completion_requested_if_enabled(
712*61c4878aSAndroid Build Coastguard Worker [&called]() { called = true; });
713*61c4878aSAndroid Build Coastguard Worker
714*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
715*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
716*61c4878aSAndroid Build Coastguard Worker PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION)));
717*61c4878aSAndroid Build Coastguard Worker
718*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
719*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(called, PW_RPC_COMPLETION_REQUEST_CALLBACK);
720*61c4878aSAndroid Build Coastguard Worker }
721*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientRequestedCompletion_ErrorWhenClosed)722*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientRequestedCompletion_ErrorWhenClosed) {
723*61c4878aSAndroid Build Coastguard Worker const auto end = PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION);
724*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(end));
725*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(end));
726*61c4878aSAndroid Build Coastguard Worker
727*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(output_.total_packets(), 0u);
728*61c4878aSAndroid Build Coastguard Worker }
729*61c4878aSAndroid Build Coastguard Worker
TEST_F(BidiMethod,ClientRequestedCompletion_ErrorWhenAlreadyClosed)730*61c4878aSAndroid Build Coastguard Worker TEST_F(BidiMethod, ClientRequestedCompletion_ErrorWhenAlreadyClosed) {
731*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel()));
732*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(responder_.active());
733*61c4878aSAndroid Build Coastguard Worker
734*61c4878aSAndroid Build Coastguard Worker const auto end = PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION);
735*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(end));
736*61c4878aSAndroid Build Coastguard Worker
737*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(output_.total_packets(), 1u);
738*61c4878aSAndroid Build Coastguard Worker const Packet& packet =
739*61c4878aSAndroid Build Coastguard Worker static_cast<internal::test::FakeChannelOutput&>(output_).last_packet();
740*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
741*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.status(), Status::FailedPrecondition());
742*61c4878aSAndroid Build Coastguard Worker }
743*61c4878aSAndroid Build Coastguard Worker
744*61c4878aSAndroid Build Coastguard Worker class ServerStreamingMethod : public BasicServer {
745*61c4878aSAndroid Build Coastguard Worker protected:
ServerStreamingMethod()746*61c4878aSAndroid Build Coastguard Worker ServerStreamingMethod() {
747*61c4878aSAndroid Build Coastguard Worker internal::CallContext context(server_,
748*61c4878aSAndroid Build Coastguard Worker channels_[0].id(),
749*61c4878aSAndroid Build Coastguard Worker service_42_,
750*61c4878aSAndroid Build Coastguard Worker service_42_.method(100),
751*61c4878aSAndroid Build Coastguard Worker kDefaultCallId);
752*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().lock();
753*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerWriter responder_temp(context.ClaimLocked());
754*61c4878aSAndroid Build Coastguard Worker internal::rpc_lock().unlock();
755*61c4878aSAndroid Build Coastguard Worker responder_ = std::move(responder_temp);
756*61c4878aSAndroid Build Coastguard Worker PW_CHECK(responder_.active());
757*61c4878aSAndroid Build Coastguard Worker }
758*61c4878aSAndroid Build Coastguard Worker
759*61c4878aSAndroid Build Coastguard Worker internal::test::FakeServerWriter responder_;
760*61c4878aSAndroid Build Coastguard Worker };
761*61c4878aSAndroid Build Coastguard Worker
TEST_F(ServerStreamingMethod,ClientStream_InvalidArgumentError)762*61c4878aSAndroid Build Coastguard Worker TEST_F(ServerStreamingMethod, ClientStream_InvalidArgumentError) {
763*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
764*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(PacketForRpc(PacketType::CLIENT_STREAM)));
765*61c4878aSAndroid Build Coastguard Worker
766*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(output_.total_packets(), 1u);
767*61c4878aSAndroid Build Coastguard Worker const Packet& packet =
768*61c4878aSAndroid Build Coastguard Worker static_cast<internal::test::FakeChannelOutput&>(output_).last_packet();
769*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
770*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.status(), Status::InvalidArgument());
771*61c4878aSAndroid Build Coastguard Worker }
772*61c4878aSAndroid Build Coastguard Worker
TEST_F(ServerStreamingMethod,ClientRequestedCompletion_CallsCallback)773*61c4878aSAndroid Build Coastguard Worker TEST_F(ServerStreamingMethod, ClientRequestedCompletion_CallsCallback) {
774*61c4878aSAndroid Build Coastguard Worker bool called = false;
775*61c4878aSAndroid Build Coastguard Worker #if PW_RPC_COMPLETION_REQUEST_CALLBACK
776*61c4878aSAndroid Build Coastguard Worker responder_.set_on_completion_requested([&called]() { called = true; });
777*61c4878aSAndroid Build Coastguard Worker #endif
778*61c4878aSAndroid Build Coastguard Worker
779*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
780*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
781*61c4878aSAndroid Build Coastguard Worker PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION)));
782*61c4878aSAndroid Build Coastguard Worker
783*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
784*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(called, PW_RPC_COMPLETION_REQUEST_CALLBACK);
785*61c4878aSAndroid Build Coastguard Worker }
786*61c4878aSAndroid Build Coastguard Worker
TEST_F(ServerStreamingMethod,ClientRequestedCompletion_CallsCallbackIfEnabled)787*61c4878aSAndroid Build Coastguard Worker TEST_F(ServerStreamingMethod,
788*61c4878aSAndroid Build Coastguard Worker ClientRequestedCompletion_CallsCallbackIfEnabled) {
789*61c4878aSAndroid Build Coastguard Worker bool called = false;
790*61c4878aSAndroid Build Coastguard Worker responder_.set_on_completion_requested_if_enabled(
791*61c4878aSAndroid Build Coastguard Worker [&called]() { called = true; });
792*61c4878aSAndroid Build Coastguard Worker
793*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(),
794*61c4878aSAndroid Build Coastguard Worker server_.ProcessPacket(
795*61c4878aSAndroid Build Coastguard Worker PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION)));
796*61c4878aSAndroid Build Coastguard Worker
797*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(output_.total_packets(), 0u);
798*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(called, PW_RPC_COMPLETION_REQUEST_CALLBACK);
799*61c4878aSAndroid Build Coastguard Worker }
800*61c4878aSAndroid Build Coastguard Worker
TEST_F(ServerStreamingMethod,ClientRequestedCompletion_ErrorWhenClosed)801*61c4878aSAndroid Build Coastguard Worker TEST_F(ServerStreamingMethod, ClientRequestedCompletion_ErrorWhenClosed) {
802*61c4878aSAndroid Build Coastguard Worker const auto end = PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION);
803*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(end));
804*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(end));
805*61c4878aSAndroid Build Coastguard Worker
806*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(output_.total_packets(), 0u);
807*61c4878aSAndroid Build Coastguard Worker }
808*61c4878aSAndroid Build Coastguard Worker
TEST_F(ServerStreamingMethod,ClientRequestedCompletion_ErrorWhenAlreadyClosed)809*61c4878aSAndroid Build Coastguard Worker TEST_F(ServerStreamingMethod,
810*61c4878aSAndroid Build Coastguard Worker ClientRequestedCompletion_ErrorWhenAlreadyClosed) {
811*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(EncodeCancel()));
812*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(responder_.active());
813*61c4878aSAndroid Build Coastguard Worker
814*61c4878aSAndroid Build Coastguard Worker const auto end = PacketForRpc(PacketType::CLIENT_REQUEST_COMPLETION);
815*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), server_.ProcessPacket(end));
816*61c4878aSAndroid Build Coastguard Worker
817*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(output_.total_packets(), 1u);
818*61c4878aSAndroid Build Coastguard Worker const Packet& packet =
819*61c4878aSAndroid Build Coastguard Worker static_cast<internal::test::FakeChannelOutput&>(output_).last_packet();
820*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.type(), PacketType::SERVER_ERROR);
821*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(packet.status(), Status::FailedPrecondition());
822*61c4878aSAndroid Build Coastguard Worker }
823*61c4878aSAndroid Build Coastguard Worker
824*61c4878aSAndroid Build Coastguard Worker } // namespace
825*61c4878aSAndroid Build Coastguard Worker } // namespace pw::rpc
826