• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_rpc/pwpb/client_reader_writer.h"
16 
17 #include <optional>
18 
19 #include "gtest/gtest.h"
20 #include "pw_rpc/pwpb/client_testing.h"
21 #include "pw_rpc_test_protos/test.rpc.pwpb.h"
22 
23 PW_MODIFY_DIAGNOSTICS_PUSH();
24 PW_MODIFY_DIAGNOSTIC(ignored, "-Wmissing-field-initializers");
25 
26 namespace pw::rpc {
27 namespace {
28 
29 using test::pw_rpc::pwpb::TestService;
30 
31 namespace TestRequest = ::pw::rpc::test::pwpb::TestRequest;
32 namespace TestResponse = ::pw::rpc::test::pwpb::TestResponse;
33 namespace TestStreamResponse = ::pw::rpc::test::pwpb::TestStreamResponse;
34 
FailIfCalled(Status)35 void FailIfCalled(Status) { FAIL(); }
36 template <typename T>
FailIfOnNextCalled(const T &)37 void FailIfOnNextCalled(const T&) {
38   FAIL();
39 }
40 template <typename T>
FailIfOnCompletedCalled(const T &,Status)41 void FailIfOnCompletedCalled(const T&, Status) {
42   FAIL();
43 }
44 
TEST(PwpbUnaryReceiver,DefaultConstructed)45 TEST(PwpbUnaryReceiver, DefaultConstructed) {
46   PwpbUnaryReceiver<TestResponse::Message> call;
47 
48   ASSERT_FALSE(call.active());
49   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
50 
51   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
52 
53   call.set_on_completed([](const TestResponse::Message&, Status) {});
54   call.set_on_error([](Status) {});
55 }
56 
TEST(PwpbClientWriter,DefaultConstructed)57 TEST(PwpbClientWriter, DefaultConstructed) {
58   PwpbClientWriter<TestRequest::Message, TestStreamResponse::Message> call;
59 
60   ASSERT_FALSE(call.active());
61   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
62 
63   EXPECT_EQ(Status::FailedPrecondition(), call.Write({}));
64   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
65   EXPECT_EQ(Status::FailedPrecondition(), call.CloseClientStream());
66 
67   call.set_on_completed([](const TestStreamResponse::Message&, Status) {});
68   call.set_on_error([](Status) {});
69 }
70 
TEST(PwpbClientReader,DefaultConstructed)71 TEST(PwpbClientReader, DefaultConstructed) {
72   PwpbClientReader<TestStreamResponse::Message> call;
73 
74   ASSERT_FALSE(call.active());
75   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
76 
77   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
78 
79   call.set_on_completed([](Status) {});
80   call.set_on_next([](const TestStreamResponse::Message&) {});
81   call.set_on_error([](Status) {});
82 }
83 
TEST(PwpbClientReaderWriter,DefaultConstructed)84 TEST(PwpbClientReaderWriter, DefaultConstructed) {
85   PwpbClientReaderWriter<TestRequest::Message, TestStreamResponse::Message>
86       call;
87 
88   ASSERT_FALSE(call.active());
89   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
90 
91   EXPECT_EQ(Status::FailedPrecondition(), call.Write({}));
92   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
93   EXPECT_EQ(Status::FailedPrecondition(), call.CloseClientStream());
94 
95   call.set_on_completed([](Status) {});
96   call.set_on_next([](const TestStreamResponse::Message&) {});
97   call.set_on_error([](Status) {});
98 }
99 
TEST(PwpbUnaryReceiver,Closed)100 TEST(PwpbUnaryReceiver, Closed) {
101   PwpbClientTestContext ctx;
102   PwpbUnaryReceiver<TestResponse::Message> call =
103       TestService::TestUnaryRpc(ctx.client(),
104                                 ctx.channel().id(),
105                                 {},
106                                 FailIfOnCompletedCalled<TestResponse::Message>,
107                                 FailIfCalled);
108   ASSERT_EQ(OkStatus(), call.Cancel());
109 
110   ASSERT_FALSE(call.active());
111   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
112 
113   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
114 
115   call.set_on_completed([](const TestResponse::Message&, Status) {});
116   call.set_on_error([](Status) {});
117 }
118 
TEST(PwpbClientWriter,Closed)119 TEST(PwpbClientWriter, Closed) {
120   PwpbClientTestContext ctx;
121   PwpbClientWriter<TestRequest::Message, TestStreamResponse::Message> call =
122       TestService::TestClientStreamRpc(
123           ctx.client(),
124           ctx.channel().id(),
125           FailIfOnCompletedCalled<TestStreamResponse::Message>,
126           FailIfCalled);
127   ASSERT_EQ(OkStatus(), call.Cancel());
128 
129   ASSERT_FALSE(call.active());
130   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
131 
132   EXPECT_EQ(Status::FailedPrecondition(), call.Write({}));
133   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
134   EXPECT_EQ(Status::FailedPrecondition(), call.CloseClientStream());
135 
136   call.set_on_completed([](const TestStreamResponse::Message&, Status) {});
137   call.set_on_error([](Status) {});
138 }
139 
TEST(PwpbClientReader,Closed)140 TEST(PwpbClientReader, Closed) {
141   PwpbClientTestContext ctx;
142   PwpbClientReader<TestStreamResponse::Message> call =
143       TestService::TestServerStreamRpc(
144           ctx.client(),
145           ctx.channel().id(),
146           {},
147           FailIfOnNextCalled<TestStreamResponse::Message>,
148           FailIfCalled,
149           FailIfCalled);
150   ASSERT_EQ(OkStatus(), call.Cancel());
151 
152   ASSERT_FALSE(call.active());
153   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
154 
155   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
156 
157   call.set_on_completed([](Status) {});
158   call.set_on_next([](const TestStreamResponse::Message&) {});
159   call.set_on_error([](Status) {});
160 }
161 
TEST(PwpbClientReaderWriter,Closed)162 TEST(PwpbClientReaderWriter, Closed) {
163   PwpbClientTestContext ctx;
164   PwpbClientReaderWriter<TestRequest::Message, TestStreamResponse::Message>
165       call = TestService::TestBidirectionalStreamRpc(
166           ctx.client(),
167           ctx.channel().id(),
168           FailIfOnNextCalled<TestStreamResponse::Message>,
169           FailIfCalled,
170           FailIfCalled);
171   ASSERT_EQ(OkStatus(), call.Cancel());
172 
173   ASSERT_FALSE(call.active());
174   EXPECT_EQ(call.channel_id(), Channel::kUnassignedChannelId);
175 
176   EXPECT_EQ(Status::FailedPrecondition(), call.Write({}));
177   EXPECT_EQ(Status::FailedPrecondition(), call.Cancel());
178   EXPECT_EQ(Status::FailedPrecondition(), call.CloseClientStream());
179 
180   call.set_on_completed([](Status) {});
181   call.set_on_next([](const TestStreamResponse::Message&) {});
182   call.set_on_error([](Status) {});
183 }
184 
TEST(PwpbUnaryReceiver,CallbacksMoveCorrectly)185 TEST(PwpbUnaryReceiver, CallbacksMoveCorrectly) {
186   PwpbClientTestContext ctx;
187 
188   struct {
189     TestResponse::Message payload = {.value = 12345678};
190     std::optional<Status> status;
191   } reply;
192 
193   PwpbUnaryReceiver<TestResponse::Message> call_2;
194   {
195     PwpbUnaryReceiver call_1 = TestService::TestUnaryRpc(
196         ctx.client(),
197         ctx.channel().id(),
198         {},
199         [&reply](const TestResponse::Message& response, Status status) {
200           reply.payload = response;
201           reply.status = status;
202         });
203 
204     call_2 = std::move(call_1);
205   }
206 
207   ctx.server().SendResponse<TestService::TestUnaryRpc>({.value = 9000},
208                                                        Status::NotFound());
209   EXPECT_EQ(reply.payload.value, 9000);
210   EXPECT_EQ(reply.status, Status::NotFound());
211 }
212 
TEST(PwpbClientReaderWriter,CallbacksMoveCorrectly)213 TEST(PwpbClientReaderWriter, CallbacksMoveCorrectly) {
214   PwpbClientTestContext ctx;
215 
216   TestStreamResponse::Message payload = {.chunk = {}, .number = 13579};
217 
218   PwpbClientReaderWriter<TestRequest::Message, TestStreamResponse::Message>
219       call_2;
220   {
221     PwpbClientReaderWriter call_1 = TestService::TestBidirectionalStreamRpc(
222         ctx.client(),
223         ctx.channel().id(),
224         [&payload](const TestStreamResponse::Message& response) {
225           payload = response;
226         });
227 
228     call_2 = std::move(call_1);
229   }
230 
231   ctx.server().SendServerStream<TestService::TestBidirectionalStreamRpc>(
232       {.chunk = {}, .number = 5050});
233   EXPECT_EQ(payload.number, 5050u);
234 }
235 
236 }  // namespace
237 }  // namespace pw::rpc
238 
239 PW_MODIFY_DIAGNOSTICS_POP();
240