aboutsummaryrefslogtreecommitdiff
path: root/pw_rpc/pwpb/server_callback_test.cc
blob: 7e5e27fe35bd6a6a23a61cc05ce1668e9cda4921 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include <array>

#include "gtest/gtest.h"
#include "pw_containers/vector.h"
#include "pw_rpc/pwpb/test_method_context.h"
#include "pw_rpc/service.h"
#include "pw_rpc_test_protos/test.rpc.pwpb.h"

namespace pw::rpc {

class TestServiceImpl final
    : public test::pw_rpc::pwpb::TestService::Service<TestServiceImpl> {
 public:
  Status TestUnaryRpc(const test::TestRequest::Message&,
                      test::TestResponse::Message& response) {
    response.value = 42;
    return OkStatus();
  }

  Status TestAnotherUnaryRpc(const test::TestRequest::Message&,
                             test::TestResponse::Message& response) {
    response.value = 42;
    response.repeated_field.SetEncoder(
        [](test::TestResponse::StreamEncoder& encoder) {
          constexpr std::array<uint32_t, 3> kValues = {7, 8, 9};
          return encoder.WriteRepeatedField(kValues);
        });
    return OkStatus();
  }

  void TestServerStreamRpc(
      const test::TestRequest::Message&,
      PwpbServerWriter<test::TestStreamResponse::Message>&) {}

  void TestClientStreamRpc(
      PwpbServerReader<test::TestRequest::Message,
                       test::TestStreamResponse::Message>&) {}

  void TestBidirectionalStreamRpc(
      PwpbServerReaderWriter<test::TestRequest::Message,
                             test::TestStreamResponse::Message>&) {}
};

TEST(PwpbTestMethodContext, ResponseWithoutCallbacks) {
  // Calling response() without an argument returns a Response struct without
  // any callbacks set.
  PW_PWPB_TEST_METHOD_CONTEXT(TestServiceImpl, TestUnaryRpc) ctx;
  ASSERT_EQ(ctx.call({}), OkStatus());

  test::TestResponse::Message response = ctx.response();
  EXPECT_EQ(42, response.value);
}

TEST(PwpbTestMethodContext, ResponseWithCallbacks) {
  PW_PWPB_TEST_METHOD_CONTEXT(TestServiceImpl, TestAnotherUnaryRpc) ctx;
  ASSERT_EQ(ctx.call({}), OkStatus());

  // To decode a response object that requires to set callbacks, pass it to the
  // response() method as a parameter.
  pw::Vector<uint32_t, 4> values{};

  test::TestResponse::Message response{};
  response.repeated_field.SetDecoder(
      [&values](test::TestResponse::StreamDecoder& decoder) {
        return decoder.ReadRepeatedField(values);
      });
  ctx.response(response);

  EXPECT_EQ(42, response.value);

  EXPECT_EQ(3u, values.size());
  EXPECT_EQ(7u, values[0]);
  EXPECT_EQ(8u, values[1]);
  EXPECT_EQ(9u, values[2]);
}

}  // namespace pw::rpc