1 // Copyright 2020 The Pigweed Authors
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
7 // https://www.apache.org/licenses/LICENSE-2.0
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
15 #include "pw_rpc/client.h"
17 #include "gtest/gtest.h"
18 #include "pw_rpc/internal/packet.h"
19 #include "pw_rpc_private/internal_test_utils.h"
24 using internal::BaseClientCall;
25 using internal::Packet;
26 using internal::PacketType;
28 class TestClientCall : public BaseClientCall {
30 constexpr TestClientCall(Channel* channel,
33 : BaseClientCall(channel, service_id, method_id, ProcessPacket) {}
35 static void ProcessPacket(BaseClientCall& call, const Packet& packet) {
36 static_cast<TestClientCall&>(call).HandlePacket(packet);
39 void HandlePacket(const Packet&) { invoked_ = true; }
41 constexpr bool invoked() const { return invoked_; }
44 bool invoked_ = false;
47 TEST(Client, ProcessPacket_InvokesARegisteredClientCall) {
48 ClientContextForTest context;
51 &context.channel(), context.kServiceId, context.kMethodId);
52 EXPECT_EQ(context.SendResponse(OkStatus(), {}), OkStatus());
54 EXPECT_TRUE(call.invoked());
57 TEST(Client, ProcessPacket_SendsClientErrorOnUnregisteredCall) {
58 ClientContextForTest context;
60 EXPECT_EQ(context.SendResponse(OkStatus(), {}), Status::NotFound());
62 ASSERT_EQ(context.output().packet_count(), 1u);
63 const Packet& packet = context.output().sent_packet();
64 EXPECT_EQ(packet.type(), PacketType::CLIENT_ERROR);
65 EXPECT_EQ(packet.channel_id(), context.kChannelId);
66 EXPECT_EQ(packet.service_id(), context.kServiceId);
67 EXPECT_EQ(packet.method_id(), context.kMethodId);
68 EXPECT_TRUE(packet.payload().empty());
69 EXPECT_EQ(packet.status(), Status::FailedPrecondition());
72 TEST(Client, ProcessPacket_ReturnsDataLossOnBadPacket) {
73 ClientContextForTest context;
75 constexpr std::byte bad_packet[]{
76 std::byte{0xab}, std::byte{0xcd}, std::byte{0xef}};
77 EXPECT_EQ(context.client().ProcessPacket(bad_packet), Status::DataLoss());
80 TEST(Client, ProcessPacket_ReturnsInvalidArgumentOnServerPacket) {
81 ClientContextForTest context;
82 EXPECT_EQ(context.SendPacket(PacketType::REQUEST), Status::InvalidArgument());
83 EXPECT_EQ(context.SendPacket(PacketType::CANCEL_SERVER_STREAM),
84 Status::InvalidArgument());
88 } // namespace pw::rpc