• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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/client_server.h"
16 
17 #include "gtest/gtest.h"
18 #include "pw_rpc/internal/packet.h"
19 #include "pw_rpc/internal/test_utils.h"
20 #include "pw_rpc/raw/fake_channel_output.h"
21 #include "pw_rpc/raw/internal/method_union.h"
22 #include "pw_rpc/service.h"
23 
24 namespace pw::rpc::internal {
25 namespace {
26 
27 constexpr uint32_t kFakeChannelId = 1;
28 constexpr uint32_t kFakeServiceId = 3;
29 constexpr uint32_t kFakeMethodId = 10;
30 
31 RawFakeChannelOutput<1> output;
32 rpc::Channel channels[] = {Channel::Create<kFakeChannelId>(&output)};
33 
FakeMethod(ConstByteSpan,RawUnaryResponder & responder)34 void FakeMethod(ConstByteSpan, RawUnaryResponder& responder) {
35   ASSERT_EQ(OkStatus(), responder.Finish({}, Status::Unimplemented()));
36 }
37 
38 class FakeService : public Service {
39  public:
FakeService(uint32_t id)40   FakeService(uint32_t id) : Service(id, kMethods) {}
41 
42   static constexpr std::array<RawMethodUnion, 1> kMethods = {
43       RawMethod::AsynchronousUnary<FakeMethod>(kFakeMethodId),
44   };
45 };
46 
47 FakeService service(kFakeServiceId);
48 
TEST(ClientServer,ProcessPacket_CallsServer)49 TEST(ClientServer, ProcessPacket_CallsServer) {
50   ClientServer client_server(channels);
51   client_server.server().RegisterService(service);
52 
53   Packet packet(
54       PacketType::REQUEST, kFakeChannelId, kFakeServiceId, kFakeMethodId);
55   std::array<std::byte, 32> buffer;
56   Result result = packet.Encode(buffer);
57   EXPECT_EQ(result.status(), OkStatus());
58 
59   EXPECT_EQ(client_server.ProcessPacket(result.value(), output), OkStatus());
60 }
61 
TEST(ClientServer,ProcessPacket_CallsClient)62 TEST(ClientServer, ProcessPacket_CallsClient) {
63   ClientServer client_server(channels);
64   client_server.server().RegisterService(service);
65 
66   // Same packet as above, but type RESPONSE will skip the server and call into
67   // the client.
68   Packet packet(
69       PacketType::RESPONSE, kFakeChannelId, kFakeServiceId, kFakeMethodId);
70   std::array<std::byte, 32> buffer;
71   Result result = packet.Encode(buffer);
72   EXPECT_EQ(result.status(), OkStatus());
73 
74   // No calls are registered on the client, so nothing should happen. The
75   // ProcessPacket call still returns OK since the client handled it.
76   EXPECT_EQ(client_server.ProcessPacket(result.value(), output), OkStatus());
77 }
78 
TEST(ClientServer,ProcessPacket_BadData)79 TEST(ClientServer, ProcessPacket_BadData) {
80   ClientServer client_server(channels);
81   EXPECT_EQ(client_server.ProcessPacket({}, output), Status::DataLoss());
82 }
83 
84 }  // namespace
85 }  // namespace pw::rpc::internal
86