pw_rpc: Rework the FakeChannelOutput classes
- Update Raw/NanopbFakeChannelOutput so it can be used for both client
and service testing. Record all packets sent and support iterating
over payloads by RPC. Store payloads in a single buffer rather than a
list of fixed-size buffers to support different payload sizes with
less memory.
- Allow encoding/decoding individual proto methods with NanopbSerde.
- Update tests to use the new FakeChannelOutput API.
- Adapt the test method contexts to use the new FakeChannelOutput. A
test server class with improved functionality (and no macros) will be
created in the future.
Requires: pigweed-internal:16580
Change-Id: I10eb11cdf8e7a3ee656d2a00d5a6517bc0179281
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/64962
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
diff --git a/pw_rpc/fake_channel_output.cc b/pw_rpc/fake_channel_output.cc
index 7c0a9e5..4f688e8 100644
--- a/pw_rpc/fake_channel_output.cc
+++ b/pw_rpc/fake_channel_output.cc
@@ -15,23 +15,24 @@
#include "pw_rpc/internal/fake_channel_output.h"
#include "pw_assert/check.h"
+#include "pw_log/log.h"
#include "pw_result/result.h"
#include "pw_rpc/internal/packet.h"
namespace pw::rpc::internal::test {
void FakeChannelOutput::clear() {
- ClearResponses();
+ payloads_.clear();
+ packets_.clear();
total_response_packets_ = 0;
total_stream_packets_ = 0;
- last_status_ = Status::Unknown();
send_status_ = OkStatus();
return_after_packet_count_ = -1;
}
Status FakeChannelOutput::SendAndReleaseBuffer(
std::span<const std::byte> buffer) {
- PW_CHECK_PTR_EQ(buffer.data(), packet_buffer_.data());
+ PW_CHECK_PTR_EQ(buffer.data(), encoding_buffer_.data());
// If the buffer is empty, this is just releasing an unused buffer.
if (buffer.empty()) {
@@ -51,20 +52,22 @@
Result<Packet> result = Packet::FromBuffer(buffer);
PW_CHECK_OK(result.status());
- last_status_ = result.value().status();
+ PW_CHECK(!packets_.full(),
+ "Attempted to store more than %u packets. Increase the kMaxPackets "
+ "template arg to store more packets.",
+ static_cast<unsigned>(packets_.size()));
+
+ packets_.push_back(*result);
+
+ CopyPayloadToBuffer(packets_.back().payload());
switch (result.value().type()) {
case PacketType::RESPONSE:
- // Server streaming RPCs don't have a payload in their response packet.
- if (!HasServerStream(method_type_)) {
- ProcessResponse(result.value().payload());
- }
++total_response_packets_;
break;
case PacketType::SERVER_ERROR:
PW_CRASH("Server error: %s", result.value().status().str());
case PacketType::SERVER_STREAM:
- ProcessResponse(result.value().payload());
++total_stream_packets_;
break;
default:
@@ -74,4 +77,22 @@
return OkStatus();
}
+void FakeChannelOutput::CopyPayloadToBuffer(const ConstByteSpan& payload) {
+ if (payload.empty()) {
+ return;
+ }
+
+ const size_t available_bytes = payloads_.max_size() - payloads_.size();
+ PW_CHECK_UINT_GE(available_bytes,
+ payload.size(),
+ "Ran out of payload buffer space. Increase "
+ "kPayloadBufferSizeBytes (%u) or use smaller payloads.",
+ static_cast<unsigned>(payloads_.max_size()));
+
+ const size_t start = payloads_.size();
+ payloads_.resize(payloads_.size() + payload.size());
+ std::memcpy(&payloads_[start], payload.data(), payload.size());
+ packets_.back().set_payload(std::span(&payloads_[start], payload.size()));
+}
+
} // namespace pw::rpc::internal::test