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 <array>
16
17 #include "gtest/gtest.h"
18 #include "pw_containers/vector.h"
19 #include "pw_rpc/pwpb/test_method_context.h"
20 #include "pw_rpc/service.h"
21 #include "pw_rpc_test_protos/test.rpc.pwpb.h"
22
23 namespace pw::rpc {
24 namespace {
25
26 namespace TestRequest = ::pw::rpc::test::pwpb::TestRequest;
27 namespace TestResponse = ::pw::rpc::test::pwpb::TestResponse;
28 namespace TestStreamResponse = ::pw::rpc::test::pwpb::TestStreamResponse;
29
30 class TestServiceImpl final
31 : public test::pw_rpc::pwpb::TestService::Service<TestServiceImpl> {
32 public:
TestUnaryRpc(const TestRequest::Message &,TestResponse::Message & response)33 Status TestUnaryRpc(const TestRequest::Message&,
34 TestResponse::Message& response) {
35 response.value = 42;
36 return OkStatus();
37 }
38
TestAnotherUnaryRpc(const TestRequest::Message &,TestResponse::Message & response)39 Status TestAnotherUnaryRpc(const TestRequest::Message&,
40 TestResponse::Message& response) {
41 response.value = 42;
42 response.repeated_field.SetEncoder(
43 [](TestResponse::StreamEncoder& encoder) {
44 constexpr std::array<uint32_t, 3> kValues = {7, 8, 9};
45 return encoder.WriteRepeatedField(kValues);
46 });
47 return OkStatus();
48 }
49
TestServerStreamRpc(const TestRequest::Message &,PwpbServerWriter<TestStreamResponse::Message> &)50 void TestServerStreamRpc(const TestRequest::Message&,
51 PwpbServerWriter<TestStreamResponse::Message>&) {}
52
TestClientStreamRpc(PwpbServerReader<TestRequest::Message,TestStreamResponse::Message> &)53 void TestClientStreamRpc(
54 PwpbServerReader<TestRequest::Message, TestStreamResponse::Message>&) {}
55
TestBidirectionalStreamRpc(PwpbServerReaderWriter<TestRequest::Message,TestStreamResponse::Message> &)56 void TestBidirectionalStreamRpc(
57 PwpbServerReaderWriter<TestRequest::Message,
58 TestStreamResponse::Message>&) {}
59 };
60
TEST(PwpbTestMethodContext,ResponseWithoutCallbacks)61 TEST(PwpbTestMethodContext, ResponseWithoutCallbacks) {
62 // Calling response() without an argument returns a Response struct without
63 // any callbacks set.
64 PW_PWPB_TEST_METHOD_CONTEXT(TestServiceImpl, TestUnaryRpc) ctx;
65 ASSERT_EQ(ctx.call({}), OkStatus());
66
67 TestResponse::Message response = ctx.response();
68 EXPECT_EQ(42, response.value);
69 }
70
TEST(PwpbTestMethodContext,ResponseWithCallbacks)71 TEST(PwpbTestMethodContext, ResponseWithCallbacks) {
72 PW_PWPB_TEST_METHOD_CONTEXT(TestServiceImpl, TestAnotherUnaryRpc) ctx;
73 ASSERT_EQ(ctx.call({}), OkStatus());
74
75 // To decode a response object that requires to set callbacks, pass it to the
76 // response() method as a parameter.
77 pw::Vector<uint32_t, 4> values{};
78
79 TestResponse::Message response{};
80 response.repeated_field.SetDecoder(
81 [&values](TestResponse::StreamDecoder& decoder) {
82 return decoder.ReadRepeatedField(values);
83 });
84 ctx.response(response);
85
86 EXPECT_EQ(42, response.value);
87
88 EXPECT_EQ(3u, values.size());
89 EXPECT_EQ(7u, values[0]);
90 EXPECT_EQ(8u, values[1]);
91 EXPECT_EQ(9u, values[2]);
92 }
93
94 } // namespace
95 } // namespace pw::rpc
96