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 <optional>
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include "pw_protobuf/decoder.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/hash.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/raw/client_testing.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/raw/test_method_context.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_test_protos/no_package.raw_rpc.pb.h"
22*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_test_protos/test.pwpb.h"
23*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc_test_protos/test.raw_rpc.pb.h"
24*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
25*61c4878aSAndroid Build Coastguard Worker
26*61c4878aSAndroid Build Coastguard Worker namespace pw::rpc {
27*61c4878aSAndroid Build Coastguard Worker namespace {
28*61c4878aSAndroid Build Coastguard Worker
29*61c4878aSAndroid Build Coastguard Worker namespace TestRequest = ::pw::rpc::test::pwpb::TestRequest;
30*61c4878aSAndroid Build Coastguard Worker namespace TestResponse = ::pw::rpc::test::pwpb::TestResponse;
31*61c4878aSAndroid Build Coastguard Worker namespace TestStreamResponse = ::pw::rpc::test::pwpb::TestStreamResponse;
32*61c4878aSAndroid Build Coastguard Worker
EncodeRequest(int integer,Status status)33*61c4878aSAndroid Build Coastguard Worker Vector<std::byte, 64> EncodeRequest(int integer, Status status) {
34*61c4878aSAndroid Build Coastguard Worker Vector<std::byte, 64> buffer(64);
35*61c4878aSAndroid Build Coastguard Worker TestRequest::MemoryEncoder test_request(buffer);
36*61c4878aSAndroid Build Coastguard Worker
37*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), test_request.WriteInteger(integer));
38*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), test_request.WriteStatusCode(status.code()));
39*61c4878aSAndroid Build Coastguard Worker
40*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), test_request.status());
41*61c4878aSAndroid Build Coastguard Worker buffer.resize(test_request.size());
42*61c4878aSAndroid Build Coastguard Worker return buffer;
43*61c4878aSAndroid Build Coastguard Worker }
44*61c4878aSAndroid Build Coastguard Worker
EncodeResponse(int number)45*61c4878aSAndroid Build Coastguard Worker Vector<std::byte, 64> EncodeResponse(int number) {
46*61c4878aSAndroid Build Coastguard Worker Vector<std::byte, 64> buffer(64);
47*61c4878aSAndroid Build Coastguard Worker TestStreamResponse::MemoryEncoder test_response(buffer);
48*61c4878aSAndroid Build Coastguard Worker
49*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), test_response.WriteNumber(number));
50*61c4878aSAndroid Build Coastguard Worker
51*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), test_response.status());
52*61c4878aSAndroid Build Coastguard Worker buffer.resize(test_response.size());
53*61c4878aSAndroid Build Coastguard Worker return buffer;
54*61c4878aSAndroid Build Coastguard Worker }
55*61c4878aSAndroid Build Coastguard Worker
56*61c4878aSAndroid Build Coastguard Worker } // namespace
57*61c4878aSAndroid Build Coastguard Worker
58*61c4878aSAndroid Build Coastguard Worker namespace test {
59*61c4878aSAndroid Build Coastguard Worker
60*61c4878aSAndroid Build Coastguard Worker class TestService final
61*61c4878aSAndroid Build Coastguard Worker : public pw_rpc::raw::TestService::Service<TestService> {
62*61c4878aSAndroid Build Coastguard Worker public:
TestUnaryRpc(ConstByteSpan request,RawUnaryResponder & responder)63*61c4878aSAndroid Build Coastguard Worker static void TestUnaryRpc(ConstByteSpan request,
64*61c4878aSAndroid Build Coastguard Worker RawUnaryResponder& responder) {
65*61c4878aSAndroid Build Coastguard Worker int64_t integer;
66*61c4878aSAndroid Build Coastguard Worker Status status;
67*61c4878aSAndroid Build Coastguard Worker
68*61c4878aSAndroid Build Coastguard Worker if (!DecodeRequest(request, integer, status)) {
69*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(OkStatus(), responder.Finish({}, Status::DataLoss()));
70*61c4878aSAndroid Build Coastguard Worker return;
71*61c4878aSAndroid Build Coastguard Worker }
72*61c4878aSAndroid Build Coastguard Worker
73*61c4878aSAndroid Build Coastguard Worker std::byte response[64] = {};
74*61c4878aSAndroid Build Coastguard Worker TestResponse::MemoryEncoder test_response(response);
75*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), test_response.WriteValue(integer + 1));
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(
78*61c4878aSAndroid Build Coastguard Worker OkStatus(),
79*61c4878aSAndroid Build Coastguard Worker responder.Finish(span(response).first(test_response.size()), status));
80*61c4878aSAndroid Build Coastguard Worker }
81*61c4878aSAndroid Build Coastguard Worker
TestAnotherUnaryRpc(ConstByteSpan request,RawUnaryResponder & responder)82*61c4878aSAndroid Build Coastguard Worker void TestAnotherUnaryRpc(ConstByteSpan request,
83*61c4878aSAndroid Build Coastguard Worker RawUnaryResponder& responder) {
84*61c4878aSAndroid Build Coastguard Worker if (request.empty()) {
85*61c4878aSAndroid Build Coastguard Worker last_responder_ = std::move(responder);
86*61c4878aSAndroid Build Coastguard Worker } else {
87*61c4878aSAndroid Build Coastguard Worker TestUnaryRpc(request, responder);
88*61c4878aSAndroid Build Coastguard Worker }
89*61c4878aSAndroid Build Coastguard Worker }
90*61c4878aSAndroid Build Coastguard Worker
TestServerStreamRpc(ConstByteSpan request,RawServerWriter & writer)91*61c4878aSAndroid Build Coastguard Worker void TestServerStreamRpc(ConstByteSpan request, RawServerWriter& writer) {
92*61c4878aSAndroid Build Coastguard Worker int64_t integer;
93*61c4878aSAndroid Build Coastguard Worker Status status;
94*61c4878aSAndroid Build Coastguard Worker
95*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(DecodeRequest(request, integer, status));
96*61c4878aSAndroid Build Coastguard Worker for (int i = 0; i < integer; ++i) {
97*61c4878aSAndroid Build Coastguard Worker std::byte buffer[32] = {};
98*61c4878aSAndroid Build Coastguard Worker TestStreamResponse::MemoryEncoder test_stream_response(buffer);
99*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), test_stream_response.WriteNumber(i));
100*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Write(test_stream_response));
101*61c4878aSAndroid Build Coastguard Worker }
102*61c4878aSAndroid Build Coastguard Worker
103*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), writer.Finish(status));
104*61c4878aSAndroid Build Coastguard Worker }
105*61c4878aSAndroid Build Coastguard Worker
TestClientStreamRpc(RawServerReader & reader)106*61c4878aSAndroid Build Coastguard Worker void TestClientStreamRpc(RawServerReader& reader) {
107*61c4878aSAndroid Build Coastguard Worker last_reader_ = std::move(reader);
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard Worker last_reader_.set_on_next([this](ConstByteSpan payload) {
110*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(),
111*61c4878aSAndroid Build Coastguard Worker last_reader_.Finish(EncodeResponse(ReadInteger(payload)),
112*61c4878aSAndroid Build Coastguard Worker Status::Unauthenticated()));
113*61c4878aSAndroid Build Coastguard Worker });
114*61c4878aSAndroid Build Coastguard Worker }
115*61c4878aSAndroid Build Coastguard Worker
TestBidirectionalStreamRpc(RawServerReaderWriter & reader_writer)116*61c4878aSAndroid Build Coastguard Worker void TestBidirectionalStreamRpc(RawServerReaderWriter& reader_writer) {
117*61c4878aSAndroid Build Coastguard Worker last_reader_writer_ = std::move(reader_writer);
118*61c4878aSAndroid Build Coastguard Worker
119*61c4878aSAndroid Build Coastguard Worker last_reader_writer_.set_on_next([this](ConstByteSpan payload) {
120*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
121*61c4878aSAndroid Build Coastguard Worker OkStatus(),
122*61c4878aSAndroid Build Coastguard Worker last_reader_writer_.Write(EncodeResponse(ReadInteger(payload))));
123*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), last_reader_writer_.Finish(Status::NotFound()));
124*61c4878aSAndroid Build Coastguard Worker });
125*61c4878aSAndroid Build Coastguard Worker }
126*61c4878aSAndroid Build Coastguard Worker
last_responder()127*61c4878aSAndroid Build Coastguard Worker RawUnaryResponder& last_responder() { return last_responder_; }
128*61c4878aSAndroid Build Coastguard Worker
129*61c4878aSAndroid Build Coastguard Worker private:
ReadInteger(ConstByteSpan request)130*61c4878aSAndroid Build Coastguard Worker static uint32_t ReadInteger(ConstByteSpan request) {
131*61c4878aSAndroid Build Coastguard Worker uint32_t integer = 0;
132*61c4878aSAndroid Build Coastguard Worker
133*61c4878aSAndroid Build Coastguard Worker protobuf::Decoder decoder(request);
134*61c4878aSAndroid Build Coastguard Worker while (decoder.Next().ok()) {
135*61c4878aSAndroid Build Coastguard Worker switch (static_cast<TestRequest::Fields>(decoder.FieldNumber())) {
136*61c4878aSAndroid Build Coastguard Worker case TestRequest::Fields::kInteger:
137*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), decoder.ReadUint32(&integer));
138*61c4878aSAndroid Build Coastguard Worker break;
139*61c4878aSAndroid Build Coastguard Worker case TestRequest::Fields::kStatusCode:
140*61c4878aSAndroid Build Coastguard Worker break;
141*61c4878aSAndroid Build Coastguard Worker default:
142*61c4878aSAndroid Build Coastguard Worker ADD_FAILURE();
143*61c4878aSAndroid Build Coastguard Worker }
144*61c4878aSAndroid Build Coastguard Worker }
145*61c4878aSAndroid Build Coastguard Worker
146*61c4878aSAndroid Build Coastguard Worker return integer;
147*61c4878aSAndroid Build Coastguard Worker }
148*61c4878aSAndroid Build Coastguard Worker
DecodeRequest(ConstByteSpan request,int64_t & integer,Status & status)149*61c4878aSAndroid Build Coastguard Worker static bool DecodeRequest(ConstByteSpan request,
150*61c4878aSAndroid Build Coastguard Worker int64_t& integer,
151*61c4878aSAndroid Build Coastguard Worker Status& status) {
152*61c4878aSAndroid Build Coastguard Worker protobuf::Decoder decoder(request);
153*61c4878aSAndroid Build Coastguard Worker Status decode_status;
154*61c4878aSAndroid Build Coastguard Worker bool has_integer = false;
155*61c4878aSAndroid Build Coastguard Worker bool has_status = false;
156*61c4878aSAndroid Build Coastguard Worker
157*61c4878aSAndroid Build Coastguard Worker while (decoder.Next().ok()) {
158*61c4878aSAndroid Build Coastguard Worker switch (static_cast<TestRequest::Fields>(decoder.FieldNumber())) {
159*61c4878aSAndroid Build Coastguard Worker case TestRequest::Fields::kInteger:
160*61c4878aSAndroid Build Coastguard Worker decode_status = decoder.ReadInt64(&integer);
161*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), decode_status);
162*61c4878aSAndroid Build Coastguard Worker has_integer = decode_status.ok();
163*61c4878aSAndroid Build Coastguard Worker break;
164*61c4878aSAndroid Build Coastguard Worker case TestRequest::Fields::kStatusCode: {
165*61c4878aSAndroid Build Coastguard Worker uint32_t status_code;
166*61c4878aSAndroid Build Coastguard Worker decode_status = decoder.ReadUint32(&status_code);
167*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), decode_status);
168*61c4878aSAndroid Build Coastguard Worker has_status = decode_status.ok();
169*61c4878aSAndroid Build Coastguard Worker status = static_cast<Status::Code>(status_code);
170*61c4878aSAndroid Build Coastguard Worker break;
171*61c4878aSAndroid Build Coastguard Worker }
172*61c4878aSAndroid Build Coastguard Worker }
173*61c4878aSAndroid Build Coastguard Worker }
174*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(has_integer);
175*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(has_status);
176*61c4878aSAndroid Build Coastguard Worker return has_integer && has_status;
177*61c4878aSAndroid Build Coastguard Worker }
178*61c4878aSAndroid Build Coastguard Worker
179*61c4878aSAndroid Build Coastguard Worker RawUnaryResponder last_responder_;
180*61c4878aSAndroid Build Coastguard Worker RawServerReader last_reader_;
181*61c4878aSAndroid Build Coastguard Worker RawServerReaderWriter last_reader_writer_;
182*61c4878aSAndroid Build Coastguard Worker };
183*61c4878aSAndroid Build Coastguard Worker
184*61c4878aSAndroid Build Coastguard Worker // Test that code generation succeeds when no proto package is specified.
185*61c4878aSAndroid Build Coastguard Worker class NoPackageTestService final
186*61c4878aSAndroid Build Coastguard Worker : public ::pw_rpc::raw::PwRpcTestService::Service<NoPackageTestService> {
187*61c4878aSAndroid Build Coastguard Worker public:
TestUnaryRpc(ConstByteSpan,RawUnaryResponder &)188*61c4878aSAndroid Build Coastguard Worker static void TestUnaryRpc(ConstByteSpan, RawUnaryResponder&) {}
189*61c4878aSAndroid Build Coastguard Worker
TestAnotherUnaryRpc(ConstByteSpan,RawUnaryResponder &)190*61c4878aSAndroid Build Coastguard Worker void TestAnotherUnaryRpc(ConstByteSpan, RawUnaryResponder&) {}
191*61c4878aSAndroid Build Coastguard Worker
TestServerStreamRpc(ConstByteSpan,RawServerWriter &)192*61c4878aSAndroid Build Coastguard Worker void TestServerStreamRpc(ConstByteSpan, RawServerWriter&) {}
193*61c4878aSAndroid Build Coastguard Worker
TestClientStreamRpc(RawServerReader &)194*61c4878aSAndroid Build Coastguard Worker void TestClientStreamRpc(RawServerReader&) {}
195*61c4878aSAndroid Build Coastguard Worker
TestBidirectionalStreamRpc(RawServerReaderWriter &)196*61c4878aSAndroid Build Coastguard Worker void TestBidirectionalStreamRpc(RawServerReaderWriter&) {}
197*61c4878aSAndroid Build Coastguard Worker };
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker } // namespace test
200*61c4878aSAndroid Build Coastguard Worker
201*61c4878aSAndroid Build Coastguard Worker namespace {
202*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_CompilesProperly)203*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_CompilesProperly) {
204*61c4878aSAndroid Build Coastguard Worker test::TestService service;
205*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(internal::UnwrapServiceId(service.service_id()),
206*61c4878aSAndroid Build Coastguard Worker internal::Hash("pw.rpc.test.TestService"));
207*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(service.name(), "TestService");
208*61c4878aSAndroid Build Coastguard Worker }
209*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_InvokeUnaryRpc)210*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_InvokeUnaryRpc) {
211*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestUnaryRpc) context;
212*61c4878aSAndroid Build Coastguard Worker
213*61c4878aSAndroid Build Coastguard Worker context.call(EncodeRequest(123, OkStatus()));
214*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.status());
215*61c4878aSAndroid Build Coastguard Worker
216*61c4878aSAndroid Build Coastguard Worker protobuf::Decoder decoder(context.response());
217*61c4878aSAndroid Build Coastguard Worker
218*61c4878aSAndroid Build Coastguard Worker while (decoder.Next().ok()) {
219*61c4878aSAndroid Build Coastguard Worker switch (static_cast<TestResponse::Fields>(decoder.FieldNumber())) {
220*61c4878aSAndroid Build Coastguard Worker case TestResponse::Fields::kValue: {
221*61c4878aSAndroid Build Coastguard Worker int32_t value;
222*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), decoder.ReadInt32(&value));
223*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(value, 124);
224*61c4878aSAndroid Build Coastguard Worker break;
225*61c4878aSAndroid Build Coastguard Worker }
226*61c4878aSAndroid Build Coastguard Worker case TestResponse::Fields::kRepeatedField:
227*61c4878aSAndroid Build Coastguard Worker break; // Ignore this field
228*61c4878aSAndroid Build Coastguard Worker }
229*61c4878aSAndroid Build Coastguard Worker }
230*61c4878aSAndroid Build Coastguard Worker }
231*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_InvokeAsyncUnaryRpc)232*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_InvokeAsyncUnaryRpc) {
233*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) context;
234*61c4878aSAndroid Build Coastguard Worker
235*61c4878aSAndroid Build Coastguard Worker context.call(EncodeRequest(123, OkStatus()));
236*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), context.status());
237*61c4878aSAndroid Build Coastguard Worker
238*61c4878aSAndroid Build Coastguard Worker protobuf::Decoder decoder(context.response());
239*61c4878aSAndroid Build Coastguard Worker
240*61c4878aSAndroid Build Coastguard Worker while (decoder.Next().ok()) {
241*61c4878aSAndroid Build Coastguard Worker switch (static_cast<TestResponse::Fields>(decoder.FieldNumber())) {
242*61c4878aSAndroid Build Coastguard Worker case TestResponse::Fields::kValue: {
243*61c4878aSAndroid Build Coastguard Worker int32_t value;
244*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), decoder.ReadInt32(&value));
245*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(value, 124);
246*61c4878aSAndroid Build Coastguard Worker break;
247*61c4878aSAndroid Build Coastguard Worker }
248*61c4878aSAndroid Build Coastguard Worker case TestResponse::Fields::kRepeatedField:
249*61c4878aSAndroid Build Coastguard Worker break; // Ignore this field
250*61c4878aSAndroid Build Coastguard Worker }
251*61c4878aSAndroid Build Coastguard Worker }
252*61c4878aSAndroid Build Coastguard Worker }
253*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_HandleError)254*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_HandleError) {
255*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) ctx;
256*61c4878aSAndroid Build Coastguard Worker
257*61c4878aSAndroid Build Coastguard Worker ASSERT_FALSE(ctx.service().last_responder().active());
258*61c4878aSAndroid Build Coastguard Worker ctx.call({});
259*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(ctx.service().last_responder().active());
260*61c4878aSAndroid Build Coastguard Worker
261*61c4878aSAndroid Build Coastguard Worker ctx.SendClientError(Status::Unimplemented());
262*61c4878aSAndroid Build Coastguard Worker
263*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(ctx.service().last_responder().active());
264*61c4878aSAndroid Build Coastguard Worker }
265*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_Finish)266*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_Finish) {
267*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) ctx;
268*61c4878aSAndroid Build Coastguard Worker
269*61c4878aSAndroid Build Coastguard Worker ASSERT_FALSE(ctx.service().last_responder().active());
270*61c4878aSAndroid Build Coastguard Worker ctx.call({});
271*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(ctx.service().last_responder().active());
272*61c4878aSAndroid Build Coastguard Worker
273*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), ctx.service().last_responder().Finish({}));
274*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(ctx.service().last_responder().active());
275*61c4878aSAndroid Build Coastguard Worker }
276*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_MoveCalls)277*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_MoveCalls) {
278*61c4878aSAndroid Build Coastguard Worker // Create two call objects on different channels so they are unique.
279*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) ctx;
280*61c4878aSAndroid Build Coastguard Worker
281*61c4878aSAndroid Build Coastguard Worker RawUnaryResponder call;
282*61c4878aSAndroid Build Coastguard Worker
283*61c4878aSAndroid Build Coastguard Worker ctx.call({});
284*61c4878aSAndroid Build Coastguard Worker
285*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(ctx.service().last_responder().active());
286*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(call.active());
287*61c4878aSAndroid Build Coastguard Worker
288*61c4878aSAndroid Build Coastguard Worker call = std::move(ctx.service().last_responder());
289*61c4878aSAndroid Build Coastguard Worker
290*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(ctx.service().last_responder().active());
291*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(call.active());
292*61c4878aSAndroid Build Coastguard Worker }
293*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_MoveBetweenActiveCallsWithBuffers)294*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_MoveBetweenActiveCallsWithBuffers) {
295*61c4878aSAndroid Build Coastguard Worker // Create two call objects on different channels so they are unique.
296*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) ctx_1;
297*61c4878aSAndroid Build Coastguard Worker ctx_1.set_channel_id(1);
298*61c4878aSAndroid Build Coastguard Worker
299*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestAnotherUnaryRpc) ctx_2;
300*61c4878aSAndroid Build Coastguard Worker ctx_2.set_channel_id(2);
301*61c4878aSAndroid Build Coastguard Worker
302*61c4878aSAndroid Build Coastguard Worker ctx_1.call({});
303*61c4878aSAndroid Build Coastguard Worker ctx_2.call({});
304*61c4878aSAndroid Build Coastguard Worker
305*61c4878aSAndroid Build Coastguard Worker ctx_1.service().last_responder() =
306*61c4878aSAndroid Build Coastguard Worker std::move(ctx_2.service().last_responder());
307*61c4878aSAndroid Build Coastguard Worker
308*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(ctx_1.service().last_responder().active());
309*61c4878aSAndroid Build Coastguard Worker ASSERT_FALSE(ctx_2.service().last_responder().active());
310*61c4878aSAndroid Build Coastguard Worker
311*61c4878aSAndroid Build Coastguard Worker ctx_2.service().last_responder() =
312*61c4878aSAndroid Build Coastguard Worker std::move(ctx_1.service().last_responder());
313*61c4878aSAndroid Build Coastguard Worker
314*61c4878aSAndroid Build Coastguard Worker ASSERT_FALSE(ctx_1.service().last_responder().active());
315*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(ctx_2.service().last_responder().active());
316*61c4878aSAndroid Build Coastguard Worker }
317*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_InvokeServerStreamingRpc)318*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_InvokeServerStreamingRpc) {
319*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestServerStreamRpc) context;
320*61c4878aSAndroid Build Coastguard Worker
321*61c4878aSAndroid Build Coastguard Worker context.call(EncodeRequest(5, Status::Unauthenticated()));
322*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(context.done());
323*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Unauthenticated(), context.status());
324*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(context.total_responses(), 5u);
325*61c4878aSAndroid Build Coastguard Worker
326*61c4878aSAndroid Build Coastguard Worker protobuf::Decoder decoder(context.responses().back());
327*61c4878aSAndroid Build Coastguard Worker while (decoder.Next().ok()) {
328*61c4878aSAndroid Build Coastguard Worker switch (static_cast<TestStreamResponse::Fields>(decoder.FieldNumber())) {
329*61c4878aSAndroid Build Coastguard Worker case TestStreamResponse::Fields::kNumber: {
330*61c4878aSAndroid Build Coastguard Worker int32_t value;
331*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), decoder.ReadInt32(&value));
332*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(value, 4);
333*61c4878aSAndroid Build Coastguard Worker break;
334*61c4878aSAndroid Build Coastguard Worker }
335*61c4878aSAndroid Build Coastguard Worker case TestStreamResponse::Fields::kChunk:
336*61c4878aSAndroid Build Coastguard Worker FAIL();
337*61c4878aSAndroid Build Coastguard Worker break;
338*61c4878aSAndroid Build Coastguard Worker }
339*61c4878aSAndroid Build Coastguard Worker }
340*61c4878aSAndroid Build Coastguard Worker }
341*61c4878aSAndroid Build Coastguard Worker
ReadResponseNumber(ConstByteSpan data)342*61c4878aSAndroid Build Coastguard Worker int32_t ReadResponseNumber(ConstByteSpan data) {
343*61c4878aSAndroid Build Coastguard Worker int32_t value = -1;
344*61c4878aSAndroid Build Coastguard Worker protobuf::Decoder decoder(data);
345*61c4878aSAndroid Build Coastguard Worker while (decoder.Next().ok()) {
346*61c4878aSAndroid Build Coastguard Worker switch (static_cast<TestStreamResponse::Fields>(decoder.FieldNumber())) {
347*61c4878aSAndroid Build Coastguard Worker case TestStreamResponse::Fields::kNumber: {
348*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), decoder.ReadInt32(&value));
349*61c4878aSAndroid Build Coastguard Worker break;
350*61c4878aSAndroid Build Coastguard Worker }
351*61c4878aSAndroid Build Coastguard Worker case TestStreamResponse::Fields::kChunk:
352*61c4878aSAndroid Build Coastguard Worker default:
353*61c4878aSAndroid Build Coastguard Worker ADD_FAILURE();
354*61c4878aSAndroid Build Coastguard Worker break;
355*61c4878aSAndroid Build Coastguard Worker }
356*61c4878aSAndroid Build Coastguard Worker }
357*61c4878aSAndroid Build Coastguard Worker
358*61c4878aSAndroid Build Coastguard Worker return value;
359*61c4878aSAndroid Build Coastguard Worker }
360*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_InvokeClientStreamingRpc)361*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_InvokeClientStreamingRpc) {
362*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestClientStreamRpc) ctx;
363*61c4878aSAndroid Build Coastguard Worker
364*61c4878aSAndroid Build Coastguard Worker ctx.call();
365*61c4878aSAndroid Build Coastguard Worker ctx.SendClientStream(EncodeRequest(123, OkStatus()));
366*61c4878aSAndroid Build Coastguard Worker
367*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(ctx.done());
368*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::Unauthenticated(), ctx.status());
369*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ctx.total_responses(), 1u);
370*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadResponseNumber(ctx.responses().back()), 123);
371*61c4878aSAndroid Build Coastguard Worker }
372*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Server_InvokeBidirectionalStreamingRpc)373*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Server_InvokeBidirectionalStreamingRpc) {
374*61c4878aSAndroid Build Coastguard Worker PW_RAW_TEST_METHOD_CONTEXT(test::TestService, TestBidirectionalStreamRpc)
375*61c4878aSAndroid Build Coastguard Worker ctx;
376*61c4878aSAndroid Build Coastguard Worker
377*61c4878aSAndroid Build Coastguard Worker ctx.call();
378*61c4878aSAndroid Build Coastguard Worker ctx.SendClientStream(EncodeRequest(456, OkStatus()));
379*61c4878aSAndroid Build Coastguard Worker
380*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(ctx.done());
381*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(Status::NotFound(), ctx.status());
382*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(ctx.total_responses(), 1u);
383*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadResponseNumber(ctx.responses().back()), 456);
384*61c4878aSAndroid Build Coastguard Worker }
385*61c4878aSAndroid Build Coastguard Worker
TEST(RawCodegen,Client_ClientClass)386*61c4878aSAndroid Build Coastguard Worker TEST(RawCodegen, Client_ClientClass) {
387*61c4878aSAndroid Build Coastguard Worker RawClientTestContext context;
388*61c4878aSAndroid Build Coastguard Worker
389*61c4878aSAndroid Build Coastguard Worker test::pw_rpc::raw::TestService::Client service_client(context.client(),
390*61c4878aSAndroid Build Coastguard Worker context.channel().id());
391*61c4878aSAndroid Build Coastguard Worker
392*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(service_client.channel_id(), context.channel().id());
393*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(&service_client.client(), &context.client());
394*61c4878aSAndroid Build Coastguard Worker }
395*61c4878aSAndroid Build Coastguard Worker
396*61c4878aSAndroid Build Coastguard Worker class RawCodegenClientTest : public ::testing::Test {
397*61c4878aSAndroid Build Coastguard Worker protected:
RawCodegenClientTest()398*61c4878aSAndroid Build Coastguard Worker RawCodegenClientTest()
399*61c4878aSAndroid Build Coastguard Worker : service_client_(context_.client(), context_.channel().id()) {}
400*61c4878aSAndroid Build Coastguard Worker
401*61c4878aSAndroid Build Coastguard Worker // Assumes the payload is a null-terminated string, not a protobuf.
OnNext()402*61c4878aSAndroid Build Coastguard Worker Function<void(ConstByteSpan)> OnNext() {
403*61c4878aSAndroid Build Coastguard Worker return [this](ConstByteSpan c_string) { CopyPayload(c_string); };
404*61c4878aSAndroid Build Coastguard Worker }
405*61c4878aSAndroid Build Coastguard Worker
OnCompleted()406*61c4878aSAndroid Build Coastguard Worker Function<void(Status)> OnCompleted() {
407*61c4878aSAndroid Build Coastguard Worker return [this](Status status) { status_ = status; };
408*61c4878aSAndroid Build Coastguard Worker }
409*61c4878aSAndroid Build Coastguard Worker
UnaryOnCompleted()410*61c4878aSAndroid Build Coastguard Worker Function<void(ConstByteSpan, Status)> UnaryOnCompleted() {
411*61c4878aSAndroid Build Coastguard Worker return [this](ConstByteSpan c_string, Status status) {
412*61c4878aSAndroid Build Coastguard Worker CopyPayload(c_string);
413*61c4878aSAndroid Build Coastguard Worker status_ = status;
414*61c4878aSAndroid Build Coastguard Worker };
415*61c4878aSAndroid Build Coastguard Worker }
416*61c4878aSAndroid Build Coastguard Worker
OnError()417*61c4878aSAndroid Build Coastguard Worker Function<void(Status)> OnError() {
418*61c4878aSAndroid Build Coastguard Worker return [this](Status error) { error_ = error; };
419*61c4878aSAndroid Build Coastguard Worker }
420*61c4878aSAndroid Build Coastguard Worker
421*61c4878aSAndroid Build Coastguard Worker RawClientTestContext<> context_;
422*61c4878aSAndroid Build Coastguard Worker
423*61c4878aSAndroid Build Coastguard Worker test::pw_rpc::raw::TestService::Client service_client_;
424*61c4878aSAndroid Build Coastguard Worker
425*61c4878aSAndroid Build Coastguard Worker // Store the payload as a null-terminated string for convenience. Use nullptr
426*61c4878aSAndroid Build Coastguard Worker // for an empty payload.
427*61c4878aSAndroid Build Coastguard Worker std::optional<const char*> payload_;
428*61c4878aSAndroid Build Coastguard Worker std::optional<Status> status_;
429*61c4878aSAndroid Build Coastguard Worker std::optional<Status> error_;
430*61c4878aSAndroid Build Coastguard Worker
431*61c4878aSAndroid Build Coastguard Worker private:
CopyPayload(ConstByteSpan c_string)432*61c4878aSAndroid Build Coastguard Worker void CopyPayload(ConstByteSpan c_string) {
433*61c4878aSAndroid Build Coastguard Worker ASSERT_LE(c_string.size(), sizeof(buffer_));
434*61c4878aSAndroid Build Coastguard Worker
435*61c4878aSAndroid Build Coastguard Worker if (c_string.empty()) {
436*61c4878aSAndroid Build Coastguard Worker payload_ = nullptr;
437*61c4878aSAndroid Build Coastguard Worker } else {
438*61c4878aSAndroid Build Coastguard Worker std::memcpy(buffer_, c_string.data(), c_string.size());
439*61c4878aSAndroid Build Coastguard Worker payload_ = buffer_;
440*61c4878aSAndroid Build Coastguard Worker }
441*61c4878aSAndroid Build Coastguard Worker }
442*61c4878aSAndroid Build Coastguard Worker
443*61c4878aSAndroid Build Coastguard Worker char buffer_[64];
444*61c4878aSAndroid Build Coastguard Worker };
445*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeUnaryRpc_Ok)446*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeUnaryRpc_Ok) {
447*61c4878aSAndroid Build Coastguard Worker RawUnaryReceiver call = test::pw_rpc::raw::TestService::TestUnaryRpc(
448*61c4878aSAndroid Build Coastguard Worker context_.client(),
449*61c4878aSAndroid Build Coastguard Worker context_.channel().id(),
450*61c4878aSAndroid Build Coastguard Worker as_bytes(span("This is the request")),
451*61c4878aSAndroid Build Coastguard Worker UnaryOnCompleted(),
452*61c4878aSAndroid Build Coastguard Worker OnError());
453*61c4878aSAndroid Build Coastguard Worker
454*61c4878aSAndroid Build Coastguard Worker context_.server().SendResponse<test::pw_rpc::raw::TestService::TestUnaryRpc>(
455*61c4878aSAndroid Build Coastguard Worker as_bytes(span("(ㆆ_ㆆ)")), OkStatus());
456*61c4878aSAndroid Build Coastguard Worker
457*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(payload_.has_value());
458*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(payload_.value(), "(ㆆ_ㆆ)");
459*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(status_, OkStatus());
460*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(error_.has_value());
461*61c4878aSAndroid Build Coastguard Worker }
462*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeUnaryRpc_Error)463*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeUnaryRpc_Error) {
464*61c4878aSAndroid Build Coastguard Worker RawUnaryReceiver call = service_client_.TestUnaryRpc(
465*61c4878aSAndroid Build Coastguard Worker as_bytes(span("This is the request")), UnaryOnCompleted(), OnError());
466*61c4878aSAndroid Build Coastguard Worker
467*61c4878aSAndroid Build Coastguard Worker context_.server()
468*61c4878aSAndroid Build Coastguard Worker .SendServerError<test::pw_rpc::raw::TestService::TestUnaryRpc>(
469*61c4878aSAndroid Build Coastguard Worker Status::NotFound());
470*61c4878aSAndroid Build Coastguard Worker
471*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(payload_.has_value());
472*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(status_.has_value());
473*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(error_, Status::NotFound());
474*61c4878aSAndroid Build Coastguard Worker }
475*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeServerStreamRpc_Ok)476*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeServerStreamRpc_Ok) {
477*61c4878aSAndroid Build Coastguard Worker RawClientReader call = test::pw_rpc::raw::TestService::TestServerStreamRpc(
478*61c4878aSAndroid Build Coastguard Worker context_.client(),
479*61c4878aSAndroid Build Coastguard Worker context_.channel().id(),
480*61c4878aSAndroid Build Coastguard Worker as_bytes(span("This is the request")),
481*61c4878aSAndroid Build Coastguard Worker OnNext(),
482*61c4878aSAndroid Build Coastguard Worker OnCompleted(),
483*61c4878aSAndroid Build Coastguard Worker OnError());
484*61c4878aSAndroid Build Coastguard Worker
485*61c4878aSAndroid Build Coastguard Worker context_.server()
486*61c4878aSAndroid Build Coastguard Worker .SendServerStream<test::pw_rpc::raw::TestService::TestServerStreamRpc>(
487*61c4878aSAndroid Build Coastguard Worker as_bytes(span("(⌐□_□)")));
488*61c4878aSAndroid Build Coastguard Worker
489*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(payload_.has_value());
490*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(payload_.value(), "(⌐□_□)");
491*61c4878aSAndroid Build Coastguard Worker
492*61c4878aSAndroid Build Coastguard Worker context_.server()
493*61c4878aSAndroid Build Coastguard Worker .SendServerStream<test::pw_rpc::raw::TestService::TestServerStreamRpc>(
494*61c4878aSAndroid Build Coastguard Worker as_bytes(span("(o_O)")));
495*61c4878aSAndroid Build Coastguard Worker
496*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(payload_.value(), "(o_O)");
497*61c4878aSAndroid Build Coastguard Worker
498*61c4878aSAndroid Build Coastguard Worker context_.server()
499*61c4878aSAndroid Build Coastguard Worker .SendResponse<test::pw_rpc::raw::TestService::TestServerStreamRpc>(
500*61c4878aSAndroid Build Coastguard Worker Status::InvalidArgument());
501*61c4878aSAndroid Build Coastguard Worker
502*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(status_, Status::InvalidArgument());
503*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(error_.has_value());
504*61c4878aSAndroid Build Coastguard Worker }
505*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeServerStreamRpc_Error)506*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeServerStreamRpc_Error) {
507*61c4878aSAndroid Build Coastguard Worker RawClientReader call =
508*61c4878aSAndroid Build Coastguard Worker service_client_.TestServerStreamRpc(as_bytes(span("This is the request")),
509*61c4878aSAndroid Build Coastguard Worker OnNext(),
510*61c4878aSAndroid Build Coastguard Worker OnCompleted(),
511*61c4878aSAndroid Build Coastguard Worker OnError());
512*61c4878aSAndroid Build Coastguard Worker
513*61c4878aSAndroid Build Coastguard Worker context_.server()
514*61c4878aSAndroid Build Coastguard Worker .SendServerError<test::pw_rpc::raw::TestService::TestServerStreamRpc>(
515*61c4878aSAndroid Build Coastguard Worker Status::FailedPrecondition());
516*61c4878aSAndroid Build Coastguard Worker
517*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(payload_.has_value());
518*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(status_.has_value());
519*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(error_, Status::FailedPrecondition());
520*61c4878aSAndroid Build Coastguard Worker }
521*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeClientStreamRpc_Ok)522*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeClientStreamRpc_Ok) {
523*61c4878aSAndroid Build Coastguard Worker RawClientWriter call = test::pw_rpc::raw::TestService::TestClientStreamRpc(
524*61c4878aSAndroid Build Coastguard Worker context_.client(),
525*61c4878aSAndroid Build Coastguard Worker context_.channel().id(),
526*61c4878aSAndroid Build Coastguard Worker UnaryOnCompleted(),
527*61c4878aSAndroid Build Coastguard Worker OnError());
528*61c4878aSAndroid Build Coastguard Worker
529*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), call.Write(as_bytes(span("(•‿•)"))));
530*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(
531*61c4878aSAndroid Build Coastguard Worker reinterpret_cast<const char*>(
532*61c4878aSAndroid Build Coastguard Worker context_.output()
533*61c4878aSAndroid Build Coastguard Worker .payloads<test::pw_rpc::raw::TestService::TestClientStreamRpc>()
534*61c4878aSAndroid Build Coastguard Worker .back()
535*61c4878aSAndroid Build Coastguard Worker .data()),
536*61c4878aSAndroid Build Coastguard Worker "(•‿•)");
537*61c4878aSAndroid Build Coastguard Worker
538*61c4878aSAndroid Build Coastguard Worker context_.server()
539*61c4878aSAndroid Build Coastguard Worker .SendResponse<test::pw_rpc::raw::TestService::TestClientStreamRpc>(
540*61c4878aSAndroid Build Coastguard Worker as_bytes(span("(⌐□_□)")), Status::InvalidArgument());
541*61c4878aSAndroid Build Coastguard Worker
542*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(payload_.has_value());
543*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(payload_.value(), "(⌐□_□)");
544*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(status_, Status::InvalidArgument());
545*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(error_.has_value());
546*61c4878aSAndroid Build Coastguard Worker }
547*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,ClientStream_Finish)548*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, ClientStream_Finish) {
549*61c4878aSAndroid Build Coastguard Worker RawClientWriter call = test::pw_rpc::raw::TestService::TestClientStreamRpc(
550*61c4878aSAndroid Build Coastguard Worker context_.client(),
551*61c4878aSAndroid Build Coastguard Worker context_.channel().id(),
552*61c4878aSAndroid Build Coastguard Worker UnaryOnCompleted(),
553*61c4878aSAndroid Build Coastguard Worker OnError());
554*61c4878aSAndroid Build Coastguard Worker
555*61c4878aSAndroid Build Coastguard Worker context_.server()
556*61c4878aSAndroid Build Coastguard Worker .SendResponse<test::pw_rpc::raw::TestService::TestClientStreamRpc>(
557*61c4878aSAndroid Build Coastguard Worker {}, OkStatus());
558*61c4878aSAndroid Build Coastguard Worker
559*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(payload_.has_value());
560*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(payload_.value(), nullptr);
561*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(status_, OkStatus());
562*61c4878aSAndroid Build Coastguard Worker }
563*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,ClientStream_Cancel)564*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, ClientStream_Cancel) {
565*61c4878aSAndroid Build Coastguard Worker RawClientWriter call = test::pw_rpc::raw::TestService::TestClientStreamRpc(
566*61c4878aSAndroid Build Coastguard Worker context_.client(),
567*61c4878aSAndroid Build Coastguard Worker context_.channel().id(),
568*61c4878aSAndroid Build Coastguard Worker UnaryOnCompleted(),
569*61c4878aSAndroid Build Coastguard Worker OnError());
570*61c4878aSAndroid Build Coastguard Worker
571*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(call.Cancel(), OkStatus());
572*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(call.active());
573*61c4878aSAndroid Build Coastguard Worker }
574*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,ClientStream_Move)575*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, ClientStream_Move) {
576*61c4878aSAndroid Build Coastguard Worker RawClientWriter call = test::pw_rpc::raw::TestService::TestClientStreamRpc(
577*61c4878aSAndroid Build Coastguard Worker context_.client(),
578*61c4878aSAndroid Build Coastguard Worker context_.channel().id(),
579*61c4878aSAndroid Build Coastguard Worker UnaryOnCompleted(),
580*61c4878aSAndroid Build Coastguard Worker OnError());
581*61c4878aSAndroid Build Coastguard Worker
582*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), call.RequestCompletion());
583*61c4878aSAndroid Build Coastguard Worker
584*61c4878aSAndroid Build Coastguard Worker RawClientWriter call_2;
585*61c4878aSAndroid Build Coastguard Worker
586*61c4878aSAndroid Build Coastguard Worker call = std::move(call_2);
587*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(call.active());
588*61c4878aSAndroid Build Coastguard Worker }
589*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeClientStreamRpc_Error)590*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeClientStreamRpc_Error) {
591*61c4878aSAndroid Build Coastguard Worker RawClientWriter call =
592*61c4878aSAndroid Build Coastguard Worker service_client_.TestClientStreamRpc(UnaryOnCompleted(), OnError());
593*61c4878aSAndroid Build Coastguard Worker
594*61c4878aSAndroid Build Coastguard Worker context_.server()
595*61c4878aSAndroid Build Coastguard Worker .SendServerError<test::pw_rpc::raw::TestService::TestClientStreamRpc>(
596*61c4878aSAndroid Build Coastguard Worker Status::FailedPrecondition());
597*61c4878aSAndroid Build Coastguard Worker
598*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(payload_.has_value());
599*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(status_.has_value());
600*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(error_, Status::FailedPrecondition());
601*61c4878aSAndroid Build Coastguard Worker }
602*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeBidirectionalStreamRpc_Ok)603*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeBidirectionalStreamRpc_Ok) {
604*61c4878aSAndroid Build Coastguard Worker RawClientReaderWriter call =
605*61c4878aSAndroid Build Coastguard Worker test::pw_rpc::raw::TestService::TestBidirectionalStreamRpc(
606*61c4878aSAndroid Build Coastguard Worker context_.client(),
607*61c4878aSAndroid Build Coastguard Worker context_.channel().id(),
608*61c4878aSAndroid Build Coastguard Worker OnNext(),
609*61c4878aSAndroid Build Coastguard Worker OnCompleted(),
610*61c4878aSAndroid Build Coastguard Worker OnError());
611*61c4878aSAndroid Build Coastguard Worker
612*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(OkStatus(), call.Write(as_bytes(span("(•‿•)"))));
613*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(
614*61c4878aSAndroid Build Coastguard Worker reinterpret_cast<const char*>(
615*61c4878aSAndroid Build Coastguard Worker context_.output()
616*61c4878aSAndroid Build Coastguard Worker .payloads<
617*61c4878aSAndroid Build Coastguard Worker test::pw_rpc::raw::TestService::TestBidirectionalStreamRpc>()
618*61c4878aSAndroid Build Coastguard Worker .back()
619*61c4878aSAndroid Build Coastguard Worker .data()),
620*61c4878aSAndroid Build Coastguard Worker "(•‿•)");
621*61c4878aSAndroid Build Coastguard Worker
622*61c4878aSAndroid Build Coastguard Worker context_.server()
623*61c4878aSAndroid Build Coastguard Worker .SendServerStream<
624*61c4878aSAndroid Build Coastguard Worker test::pw_rpc::raw::TestService::TestBidirectionalStreamRpc>(
625*61c4878aSAndroid Build Coastguard Worker as_bytes(span("(⌐□_□)")));
626*61c4878aSAndroid Build Coastguard Worker
627*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(payload_.has_value());
628*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(payload_.value(), "(⌐□_□)");
629*61c4878aSAndroid Build Coastguard Worker
630*61c4878aSAndroid Build Coastguard Worker context_.server()
631*61c4878aSAndroid Build Coastguard Worker .SendResponse<test::pw_rpc::raw::TestService::TestBidirectionalStreamRpc>(
632*61c4878aSAndroid Build Coastguard Worker Status::InvalidArgument());
633*61c4878aSAndroid Build Coastguard Worker
634*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(status_, Status::InvalidArgument());
635*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(error_.has_value());
636*61c4878aSAndroid Build Coastguard Worker }
637*61c4878aSAndroid Build Coastguard Worker
TEST_F(RawCodegenClientTest,InvokeBidirectionalStreamRpc_Error)638*61c4878aSAndroid Build Coastguard Worker TEST_F(RawCodegenClientTest, InvokeBidirectionalStreamRpc_Error) {
639*61c4878aSAndroid Build Coastguard Worker RawClientReaderWriter call = service_client_.TestBidirectionalStreamRpc(
640*61c4878aSAndroid Build Coastguard Worker OnNext(), OnCompleted(), OnError());
641*61c4878aSAndroid Build Coastguard Worker
642*61c4878aSAndroid Build Coastguard Worker context_.server()
643*61c4878aSAndroid Build Coastguard Worker .SendServerError<
644*61c4878aSAndroid Build Coastguard Worker test::pw_rpc::raw::TestService::TestBidirectionalStreamRpc>(
645*61c4878aSAndroid Build Coastguard Worker Status::Internal());
646*61c4878aSAndroid Build Coastguard Worker
647*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(payload_.has_value());
648*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(status_.has_value());
649*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(error_, Status::Internal());
650*61c4878aSAndroid Build Coastguard Worker }
651*61c4878aSAndroid Build Coastguard Worker
652*61c4878aSAndroid Build Coastguard Worker } // namespace
653*61c4878aSAndroid Build Coastguard Worker } // namespace pw::rpc
654