xref: /aosp_15_r20/external/pigweed/pw_rpc/nanopb/public/pw_rpc/nanopb/client_server_testing.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 #pragma once
15 
16 #include <cinttypes>
17 
18 #include "pb_decode.h"
19 #include "pb_encode.h"
20 #include "pw_rpc/internal/client_server_testing.h"
21 #include "pw_rpc/nanopb/fake_channel_output.h"
22 
23 namespace pw::rpc {
24 namespace internal {
25 
26 template <size_t kOutputSize,
27           size_t kMaxPackets,
28           size_t kPayloadsBufferSizeBytes>
29 class NanopbForwardingChannelOutput final
30     : public ForwardingChannelOutput<
31           NanopbFakeChannelOutput<kMaxPackets, kPayloadsBufferSizeBytes>,
32           kOutputSize,
33           kMaxPackets,
34           kPayloadsBufferSizeBytes> {
35  private:
36   template <auto kMethod>
37   using MethodInfo = internal::MethodInfo<kMethod>;
38   template <auto kMethod>
39   using Response = typename MethodInfo<kMethod>::Response;
40   template <auto kMethod>
41   using Request = typename MethodInfo<kMethod>::Request;
42 
43   using Base = ForwardingChannelOutput<
44       NanopbFakeChannelOutput<kMaxPackets, kPayloadsBufferSizeBytes>,
45       kOutputSize,
46       kMaxPackets,
47       kPayloadsBufferSizeBytes>;
48 
49  public:
50   constexpr NanopbForwardingChannelOutput(
51       TestPacketProcessor&& server_packet_processor = nullptr,
52       TestPacketProcessor&& client_packet_processor = nullptr)
Base(std::move (server_packet_processor),std::move (client_packet_processor))53       : Base(std::move(server_packet_processor),
54              std::move(client_packet_processor)) {}
55 
56   template <auto kMethod>
response(uint32_t channel_id,uint32_t index)57   Response<kMethod> response(uint32_t channel_id, uint32_t index) {
58     PW_ASSERT(Base::PacketCount() >= index);
59     return Base::output_.template responses<kMethod>(channel_id)[index];
60   }
61 
62   template <auto kMethod>
response(uint32_t channel_id,uint32_t index,Response<kMethod> & response)63   void response(uint32_t channel_id,
64                 uint32_t index,
65                 Response<kMethod>& response) {
66     PW_ASSERT(Base::PacketCount() >= index);
67     auto payloads_view = Base::output_.template responses<kMethod>(channel_id);
68     PW_ASSERT(payloads_view.serde()
69                   .Decode(payloads_view.payloads()[index], response)
70                   .ok());
71   }
72 
73   template <auto kMethod>
request(uint32_t channel_id,uint32_t index)74   Request<kMethod> request(uint32_t channel_id, uint32_t index) {
75     PW_ASSERT(Base::PacketCount() >= index);
76     return Base::output_.template requests<kMethod>(channel_id)[index];
77   }
78 };
79 
80 }  // namespace internal
81 
82 template <size_t kOutputSize = 128,
83           size_t kMaxPackets = 16,
84           size_t kPayloadsBufferSizeBytes = 128>
85 class NanopbClientServerTestContext final
86     : public internal::ClientServerTestContext<
87           internal::NanopbForwardingChannelOutput<kOutputSize,
88                                                   kMaxPackets,
89                                                   kPayloadsBufferSizeBytes>,
90           kOutputSize,
91           kMaxPackets,
92           kPayloadsBufferSizeBytes> {
93  private:
94   template <auto kMethod>
95   using MethodInfo = internal::MethodInfo<kMethod>;
96   template <auto kMethod>
97   using Response = typename MethodInfo<kMethod>::Response;
98   template <auto kMethod>
99   using Request = typename MethodInfo<kMethod>::Request;
100 
101   using Base = internal::ClientServerTestContext<
102       internal::NanopbForwardingChannelOutput<kOutputSize,
103                                               kMaxPackets,
104                                               kPayloadsBufferSizeBytes>,
105       kOutputSize,
106       kMaxPackets,
107       kPayloadsBufferSizeBytes>;
108 
109  public:
110   NanopbClientServerTestContext(
111       TestPacketProcessor&& server_packet_processor = nullptr,
112       TestPacketProcessor&& client_packet_processor = nullptr)
Base(std::move (server_packet_processor),std::move (client_packet_processor))113       : Base(std::move(server_packet_processor),
114              std::move(client_packet_processor)) {}
115 
116   // Retrieve copy of request indexed by order of occurance
117   template <auto kMethod>
request(uint32_t index)118   Request<kMethod> request(uint32_t index) {
119     return Base::channel_output_.template request<kMethod>(Base::channel().id(),
120                                                            index);
121   }
122 
123   // Retrieve copy of response indexed by order of occurance
124   template <auto kMethod>
response(uint32_t index)125   Response<kMethod> response(uint32_t index) {
126     return Base::channel_output_.template response<kMethod>(
127         Base::channel().id(), index);
128   }
129 
130   // Gives access to the RPC's indexed by order of occurance using passed
131   // Response object to parse using nanopb. Use this version when you need
132   // to set callback fields in the Response object before parsing.
133   template <auto kMethod>
response(uint32_t index,Response<kMethod> & response)134   void response(uint32_t index, Response<kMethod>& response) {
135     return Base::channel_output_.template response<kMethod>(
136         Base::channel().id(), index, response);
137   }
138 };
139 
140 }  // namespace pw::rpc
141