pw_rpc: Fix destructor ordering problem in test helpers
During destruction, the FakeChannelOutput& in the InvocationContext base
class would be used to send a final RPC message. The ChannelOutput
instance it pointed to was in a derived class, so would be destructed
before the RPC packet was sent, resulting in "pure virtual function
call" crashes in tests.
- Move the FakeChannelOutput instance to the base InvocationContext so
it is destructed last, after any responses are sent.
- Explicitly delete some copies/moves.
- Fix typo in transfer_test.cc.
- Handle some ignored Status returns.
Change-Id: I1439dc9af59070507c5dbedab58211f2d165c35d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/59761
Reviewed-by: Carlos Chinchilla <cachinchilla@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
diff --git a/pw_rpc/nanopb/public/pw_rpc/nanopb/fake_channel_output.h b/pw_rpc/nanopb/public/pw_rpc/nanopb/fake_channel_output.h
index facdb0f..d04110e 100644
--- a/pw_rpc/nanopb/public/pw_rpc/nanopb/fake_channel_output.h
+++ b/pw_rpc/nanopb/public/pw_rpc/nanopb/fake_channel_output.h
@@ -13,8 +13,8 @@
// the License.
#pragma once
-#include <array>
#include <cstddef>
+#include <cstdint>
#include "pw_assert/assert.h"
#include "pw_bytes/span.h"
@@ -23,16 +23,11 @@
#include "pw_rpc/nanopb/internal/method.h"
namespace pw::rpc {
-namespace internal::test::nanopb {
-
-template <typename, auto, uint32_t, size_t, size_t>
-class NanopbInvocationContext;
-
-} // namespace internal::test::nanopb
// A ChannelOutput implementation that stores the outgoing payloads and status.
template <typename Response, size_t kMaxResponses, size_t kOutputSize>
-class NanopbFakeChannelOutput final : public internal::test::FakeChannelOutput {
+class NanopbFakeChannelOutput final
+ : public internal::test::FakeChannelOutputBuffer<kOutputSize> {
public:
template <auto kMethod, uint32_t kMethodId, typename ServiceType>
static NanopbFakeChannelOutput Create() {
@@ -41,6 +36,13 @@
internal::MethodTraits<decltype(kMethod)>::kType);
}
+ // Private constructor, do not use. This constructor is exposed so this class
+ // can be constructed using std::make_from_tuple in InvocationContext.
+ NanopbFakeChannelOutput(MethodType method_type,
+ const internal::NanopbMethod& kMethod)
+ : internal::test::FakeChannelOutputBuffer<kOutputSize>(method_type),
+ method_(kMethod) {}
+
const Vector<Response>& responses() const { return responses_; }
const Response& last_response() const {
@@ -56,13 +58,6 @@
}
private:
- template <typename, auto, uint32_t, size_t, size_t>
- friend class NanopbInvocationContext;
-
- NanopbFakeChannelOutput(const internal::NanopbMethod& kMethod,
- MethodType method_type)
- : FakeChannelOutput(packet_buffer_, method_type), method_(kMethod) {}
-
void AppendResponse(ConstByteSpan response) override {
Response& response_struct = AllocateResponse();
PW_ASSERT(method_.serde().DecodeResponse(response, &response_struct));
@@ -72,7 +67,6 @@
const internal::NanopbMethod& method_;
Vector<Response, kMaxResponses> responses_;
- std::array<std::byte, kOutputSize> packet_buffer_;
};
} // namespace pw::rpc
diff --git a/pw_rpc/nanopb/public/pw_rpc/nanopb/server_reader_writer.h b/pw_rpc/nanopb/public/pw_rpc/nanopb/server_reader_writer.h
index 85065b1..c36f76a 100644
--- a/pw_rpc/nanopb/public/pw_rpc/nanopb/server_reader_writer.h
+++ b/pw_rpc/nanopb/public/pw_rpc/nanopb/server_reader_writer.h
@@ -30,7 +30,7 @@
namespace test {
-template <typename, uint32_t>
+template <typename, typename, uint32_t>
class InvocationContext;
} // namespace test
@@ -129,7 +129,7 @@
private:
friend class internal::NanopbMethod;
- template <typename, uint32_t>
+ template <typename, typename, uint32_t>
friend class internal::test::InvocationContext;
NanopbServerReaderWriter(const internal::CallContext& call)
@@ -166,7 +166,7 @@
private:
friend class internal::NanopbMethod;
- template <typename, uint32_t>
+ template <typename, typename, uint32_t>
friend class internal::test::InvocationContext;
NanopbServerReader(const internal::CallContext& call)
@@ -210,7 +210,7 @@
private:
friend class internal::NanopbMethod;
- template <typename, uint32_t>
+ template <typename, typename, uint32_t>
friend class internal::test::InvocationContext;
NanopbServerWriter(const internal::CallContext& call)
diff --git a/pw_rpc/nanopb/public/pw_rpc/nanopb/test_method_context.h b/pw_rpc/nanopb/public/pw_rpc/nanopb/test_method_context.h
index c09f59f..c530f17 100644
--- a/pw_rpc/nanopb/public/pw_rpc/nanopb/test_method_context.h
+++ b/pw_rpc/nanopb/public/pw_rpc/nanopb/test_method_context.h
@@ -92,55 +92,51 @@
uint32_t kMethodId,
size_t kMaxResponses,
size_t kOutputSize>
-class NanopbInvocationContext : public InvocationContext<Service, kMethodId> {
+class NanopbInvocationContext
+ : public InvocationContext<
+ NanopbFakeChannelOutput<internal::Response<kMethod>,
+ kMaxResponses,
+ kOutputSize>,
+ Service,
+ kMethodId> {
public:
using Request = internal::Request<kMethod>;
using Response = internal::Response<kMethod>;
- // Returns the responses that have been recorded. The maximum number of
- // responses is responses().max_size(). responses().back() is always the most
- // recent response, even if total_responses() > responses().max_size().
- const Vector<Response>& responses() const { return output_.responses(); }
-
- // Gives access to the RPC's response.
- const Response& response() const {
- PW_ASSERT(!responses().empty());
- return responses().back();
- }
+ // Gives access to the RPC's most recent response.
+ const Response& response() const { return Base::output().last_response(); }
protected:
template <typename... Args>
NanopbInvocationContext(Args&&... args)
- : InvocationContext<Service, kMethodId>(
- kMethodInfo, output_, std::forward<Args>(args)...),
- output_(
- decltype(output_)::template Create<kMethod, kMethodId, Service>()) {
- }
-
- NanopbFakeChannelOutput<Response, kMaxResponses, kOutputSize>& output() {
- return output_;
- }
+ : Base(kMethodInfo,
+ std::forward_as_tuple(MethodTraits<decltype(kMethod)>::kType,
+ kMethodInfo),
+ std::forward<Args>(args)...) {}
void SendClientStream(const Request& request) {
// Borrow a buffer from the ChannelOutput for sending the request.
- ChannelOutput& channel_output = static_cast<rpc::ChannelOutput&>(output());
+ ChannelOutput& channel_output = Base::output();
std::span buffer = channel_output.AcquireBuffer();
- InvocationContext<Service, kMethodId>::SendClientStream(buffer.first(
+ Base::SendClientStream(buffer.first(
kMethodInfo.serde().EncodeRequest(&request, buffer).size()));
channel_output.DiscardBuffer(buffer);
}
private:
+ using Base = InvocationContext<
+ NanopbFakeChannelOutput<Response, kMaxResponses, kOutputSize>,
+ Service,
+ kMethodId>;
+
static constexpr NanopbMethod kMethodInfo =
MethodLookup::GetNanopbMethod<Service, kMethodId>();
-
- NanopbFakeChannelOutput<Response, kMaxResponses, kOutputSize> output_;
};
// Method invocation context for a unary RPC. Returns the status in
-// server_call() and provides the response through the response() method.
+// call_context() and provides the response through the response() method.
template <typename Service,
auto kMethod,
uint32_t kMethodId,
@@ -150,6 +146,7 @@
kMethodId,
1,
kOutputSize> {
+ private:
using Base =
NanopbInvocationContext<Service, kMethod, kMethodId, 1, kOutputSize>;
@@ -165,7 +162,7 @@
Base::output().clear();
Response& response = Base::output().AllocateResponse();
return CallMethodImplFunction<kMethod>(
- Base::server_call(), request, response);
+ Base::call_context(), request, response);
}
};
diff --git a/pw_rpc/public/pw_rpc/internal/fake_channel_output.h b/pw_rpc/public/pw_rpc/internal/fake_channel_output.h
index 2a2329c..355f2ce 100644
--- a/pw_rpc/public/pw_rpc/internal/fake_channel_output.h
+++ b/pw_rpc/public/pw_rpc/internal/fake_channel_output.h
@@ -13,6 +13,8 @@
// the License.
#pragma once
+#include <cstddef>
+
#include "pw_bytes/span.h"
#include "pw_rpc/channel.h"
#include "pw_rpc/method_type.h"
@@ -22,6 +24,12 @@
// A ChannelOutput implementation that stores the outgoing payloads and status.
class FakeChannelOutput : public ChannelOutput {
public:
+ FakeChannelOutput(const FakeChannelOutput&) = delete;
+ FakeChannelOutput(FakeChannelOutput&&) = delete;
+
+ FakeChannelOutput& operator=(const FakeChannelOutput&) = delete;
+ FakeChannelOutput& operator=(FakeChannelOutput&&) = delete;
+
Status last_status() const {
PW_ASSERT(done());
return last_status_;
@@ -35,9 +43,9 @@
void clear();
protected:
- constexpr FakeChannelOutput(ByteSpan buffer, MethodType method_type)
+ constexpr FakeChannelOutput(MethodType method_type, ByteSpan packet_buffer)
: ChannelOutput("pw::rpc::internal::test::FakeChannelOutput"),
- packet_buffer_(buffer),
+ packet_buffer_(packet_buffer),
method_type_(method_type) {}
private:
@@ -60,4 +68,14 @@
const MethodType method_type_;
};
+// Adds the packet output buffer to a FakeChannelOutput.
+template <size_t kOutputSizeBytes>
+class FakeChannelOutputBuffer : public FakeChannelOutput {
+ protected:
+ constexpr FakeChannelOutputBuffer(MethodType method_type)
+ : FakeChannelOutput(method_type, packet_bytes), packet_bytes{} {}
+
+ std::byte packet_bytes[kOutputSizeBytes];
+};
+
} // namespace pw::rpc::internal::test
diff --git a/pw_rpc/public/pw_rpc/internal/test_method_context.h b/pw_rpc/public/pw_rpc/internal/test_method_context.h
index 9f162f2..a7b7261 100644
--- a/pw_rpc/public/pw_rpc/internal/test_method_context.h
+++ b/pw_rpc/public/pw_rpc/internal/test_method_context.h
@@ -13,7 +13,6 @@
// the License.
#pragma once
-#include <array>
#include <cstddef>
#include "pw_assert/assert.h"
@@ -26,9 +25,15 @@
namespace pw::rpc::internal::test {
// Collects everything needed to invoke a particular RPC.
-template <typename Service, uint32_t kMethodId>
+template <typename Output, typename Service, uint32_t kMethodId>
class InvocationContext {
public:
+ InvocationContext(const InvocationContext&) = delete;
+ InvocationContext(InvocationContext&&) = delete;
+
+ InvocationContext& operator=(const InvocationContext&) = delete;
+ InvocationContext& operator=(InvocationContext&&) = delete;
+
Service& service() { return service_; }
// Sets the channel ID, which defaults to an arbitrary value.
@@ -38,6 +43,11 @@
// responses.max_size().
size_t total_responses() const { return output_.total_responses(); }
+ // Returns the responses that have been recorded. The maximum number of
+ // responses is responses().max_size(). responses().back() is always the most
+ // recent response, even if total_responses() > responses().max_size().
+ const auto& responses() const { return output().responses(); }
+
// True if the RPC has completed.
bool done() const { return output_.done(); }
@@ -76,21 +86,28 @@
}
protected:
- template <typename... Args>
+ // Constructs the invocation context. The args for the ChannelOutput type are
+ // passed in a std::tuple. The args for the Service are forwarded directly
+ // from the callsite.
+ template <typename OutputArgTuple, typename... ServiceArgs>
InvocationContext(const Method& method,
- FakeChannelOutput& output,
- Args&&... service_args)
- : output_(output),
+ OutputArgTuple&& output_args,
+ ServiceArgs&&... service_args)
+ : output_(std::make_from_tuple<Output>(
+ std::forward<OutputArgTuple>(output_args))),
channel_(Channel::Create<123>(&output_)),
server_(std::span(&channel_, 1)),
- service_(std::forward<Args>(service_args)...),
- server_call_(static_cast<internal::Server&>(server_),
- static_cast<internal::Channel&>(channel_),
- service_,
- method) {
+ service_(std::forward<ServiceArgs>(service_args)...),
+ context_(static_cast<internal::Server&>(server_),
+ static_cast<internal::Channel&>(channel_),
+ service_,
+ method) {
server_.RegisterService(service_);
}
+ const Output& output() const { return output_; }
+ Output& output() { return output_; }
+
template <size_t kMaxPayloadSize = 32>
void SendClientStream(ConstByteSpan payload) {
std::byte packet[kNoPayloadPacketSizeBytes + 3 + kMaxPayloadSize];
@@ -126,28 +143,26 @@
output_.clear();
T responder = GetResponder<T>();
return CallMethodImplFunction<kMethod>(
- InvocationContext<Service, kMethodId>::server_call(),
- std::forward<RequestArg>(request)...,
- responder);
+ call_context(), std::forward<RequestArg>(request)..., responder);
}
template <typename T>
T GetResponder() {
- return T(InvocationContext<Service, kMethodId>::server_call());
+ return T(call_context());
}
- internal::CallContext& server_call() { return server_call_; }
+ internal::CallContext& call_context() { return context_; }
private:
static constexpr size_t kNoPayloadPacketSizeBytes =
2 /* type */ + 2 /* channel */ + 5 /* service */ + 5 /* method */ +
2 /* status */;
- FakeChannelOutput& output_;
+ Output output_;
rpc::Channel channel_;
rpc::Server server_;
Service service_;
- internal::CallContext server_call_;
+ internal::CallContext context_;
};
} // namespace pw::rpc::internal::test
diff --git a/pw_rpc/raw/codegen_test.cc b/pw_rpc/raw/codegen_test.cc
index 6d7de57..dcf6ba4 100644
--- a/pw_rpc/raw/codegen_test.cc
+++ b/pw_rpc/raw/codegen_test.cc
@@ -26,10 +26,8 @@
Vector<std::byte, 64> buffer(64);
test::TestRequest::MemoryEncoder test_request(buffer);
- test_request.WriteInteger(integer)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
- test_request.WriteStatusCode(status.code())
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), test_request.WriteInteger(integer));
+ EXPECT_EQ(OkStatus(), test_request.WriteStatusCode(status.code()));
EXPECT_EQ(OkStatus(), test_request.status());
buffer.resize(test_request.size());
@@ -40,8 +38,7 @@
Vector<std::byte, 64> buffer(64);
test::TestStreamResponse::MemoryEncoder test_response(buffer);
- test_response.WriteNumber(number)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), test_response.WriteNumber(number));
EXPECT_EQ(OkStatus(), test_response.status());
buffer.resize(test_response.size());
@@ -65,8 +62,7 @@
}
TestResponse::MemoryEncoder test_response(response);
- test_response.WriteValue(integer + 1)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), test_response.WriteValue(integer + 1));
return StatusWithSize(status, test_response.size());
}
@@ -82,24 +78,20 @@
ByteSpan buffer = writer.PayloadBuffer();
TestStreamResponse::MemoryEncoder test_stream_response(buffer);
- test_stream_response.WriteNumber(i)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
- writer.Write(test_stream_response)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), test_stream_response.WriteNumber(i));
+ EXPECT_EQ(OkStatus(), writer.Write(test_stream_response));
}
- writer.Finish(status)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), writer.Finish(status));
}
void TestClientStreamRpc(ServerContext&, RawServerReader& reader) {
last_reader_ = std::move(reader);
last_reader_.set_on_next([this](ConstByteSpan payload) {
- last_reader_
- .Finish(EncodeResponse(ReadInteger(payload)),
- Status::Unauthenticated())
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(),
+ last_reader_.Finish(EncodeResponse(ReadInteger(payload)),
+ Status::Unauthenticated()));
});
}
@@ -108,10 +100,10 @@
last_reader_writer_ = std::move(reader_writer);
last_reader_writer_.set_on_next([this](ConstByteSpan payload) {
- last_reader_writer_.Write(EncodeResponse(ReadInteger(payload)))
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
- last_reader_writer_.Finish(Status::NotFound())
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(
+ OkStatus(),
+ last_reader_writer_.Write(EncodeResponse(ReadInteger(payload))));
+ EXPECT_EQ(OkStatus(), last_reader_writer_.Finish(Status::NotFound()));
});
}
@@ -192,8 +184,7 @@
switch (static_cast<test::TestResponse::Fields>(decoder.FieldNumber())) {
case test::TestResponse::Fields::VALUE: {
int32_t value;
- decoder.ReadInt32(&value)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), decoder.ReadInt32(&value));
EXPECT_EQ(value, 124);
break;
}
@@ -215,8 +206,7 @@
static_cast<test::TestStreamResponse::Fields>(decoder.FieldNumber())) {
case test::TestStreamResponse::Fields::NUMBER: {
int32_t value;
- decoder.ReadInt32(&value)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), decoder.ReadInt32(&value));
EXPECT_EQ(value, 4);
break;
}
@@ -234,8 +224,7 @@
switch (
static_cast<test::TestStreamResponse::Fields>(decoder.FieldNumber())) {
case test::TestStreamResponse::Fields::NUMBER: {
- decoder.ReadInt32(&value)
- .IgnoreError(); // TODO(pwbug/387): Handle Status properly
+ EXPECT_EQ(OkStatus(), decoder.ReadInt32(&value));
break;
}
default:
diff --git a/pw_rpc/raw/public/pw_rpc/raw/fake_channel_output.h b/pw_rpc/raw/public/pw_rpc/raw/fake_channel_output.h
index 55ab6c2..c7b62fd 100644
--- a/pw_rpc/raw/public/pw_rpc/raw/fake_channel_output.h
+++ b/pw_rpc/raw/public/pw_rpc/raw/fake_channel_output.h
@@ -26,10 +26,11 @@
// A ChannelOutput implementation that stores the outgoing payloads and status.
template <size_t kOutputSize, size_t kMaxResponses>
-class RawFakeChannelOutput final : public internal::test::FakeChannelOutput {
+class RawFakeChannelOutput final
+ : public internal::test::FakeChannelOutputBuffer<kOutputSize> {
public:
RawFakeChannelOutput(MethodType method_type)
- : FakeChannelOutput(packet_buffer_, method_type) {}
+ : internal::test::FakeChannelOutputBuffer<kOutputSize>(method_type) {}
const Vector<ByteSpan>& responses() const { return responses_; }
@@ -65,7 +66,6 @@
response_buffers_.clear();
}
- std::array<std::byte, kOutputSize> packet_buffer_;
Vector<ByteSpan, kMaxResponses> responses_;
Vector<std::array<std::byte, kOutputSize>, kMaxResponses> response_buffers_;
};
diff --git a/pw_rpc/raw/public/pw_rpc/raw/server_reader_writer.h b/pw_rpc/raw/public/pw_rpc/raw/server_reader_writer.h
index 39852f8..7c3523a 100644
--- a/pw_rpc/raw/public/pw_rpc/raw/server_reader_writer.h
+++ b/pw_rpc/raw/public/pw_rpc/raw/server_reader_writer.h
@@ -31,7 +31,7 @@
namespace test {
-template <typename, uint32_t>
+template <typename, typename, uint32_t>
class InvocationContext;
} // namespace test
@@ -88,7 +88,7 @@
private:
friend class internal::RawMethod;
- template <typename, uint32_t>
+ template <typename, typename, uint32_t>
friend class internal::test::InvocationContext;
};
@@ -119,7 +119,7 @@
private:
friend class internal::RawMethod; // Needed for conversions from ReaderWriter
- template <typename, uint32_t>
+ template <typename, typename, uint32_t>
friend class internal::test::InvocationContext;
RawServerReader(const internal::CallContext& call)
@@ -149,7 +149,7 @@
private:
friend class RawServerReaderWriter; // Needed for conversions.
- template <typename, uint32_t>
+ template <typename, typename, uint32_t>
friend class internal::test::InvocationContext;
friend class internal::RawMethod;
diff --git a/pw_rpc/raw/public/pw_rpc/raw/test_method_context.h b/pw_rpc/raw/public/pw_rpc/raw/test_method_context.h
index d0d257f..33b2c84 100644
--- a/pw_rpc/raw/public/pw_rpc/raw/test_method_context.h
+++ b/pw_rpc/raw/public/pw_rpc/raw/test_method_context.h
@@ -96,32 +96,26 @@
uint32_t kMethodId,
size_t kMaxResponses,
size_t kOutputSize>
-class RawInvocationContext : public InvocationContext<Service, kMethodId> {
+class RawInvocationContext
+ : public InvocationContext<RawFakeChannelOutput<kOutputSize, kMaxResponses>,
+ Service,
+ kMethodId> {
public:
- // Returns the responses that have been recorded. The maximum number of
- // responses is responses().max_size(). responses().back() is always the most
- // recent response, even if total_responses() > responses().max_size().
- const Vector<ByteSpan>& responses() const { return output_.responses(); }
-
// Gives access to the RPC's most recent response.
- ConstByteSpan response() const {
- PW_ASSERT(!responses().empty());
- return responses().back();
- }
+ ConstByteSpan response() const { return Base::output().last_response(); }
protected:
template <typename... Args>
RawInvocationContext(Args&&... args)
- : InvocationContext<Service, kMethodId>(
- MethodLookup::GetRawMethod<Service, kMethodId>(),
- output_,
- std::forward<Args>(args)...),
- output_(MethodTraits<decltype(kMethod)>::kType) {}
-
- RawFakeChannelOutput<kOutputSize, kMaxResponses>& output() { return output_; }
+ : Base(MethodLookup::GetRawMethod<Service, kMethodId>(),
+ std::forward_as_tuple(MethodTraits<decltype(kMethod)>::kType),
+ std::forward<Args>(args)...) {}
private:
- RawFakeChannelOutput<kOutputSize, kMaxResponses> output_;
+ using Base =
+ InvocationContext<RawFakeChannelOutput<kOutputSize, kMaxResponses>,
+ Service,
+ kMethodId>;
};
// Method invocation context for a unary RPC. Returns the status in call() and
@@ -143,8 +137,8 @@
StatusWithSize call(ConstByteSpan request) {
Base::output().clear();
ByteSpan& response = Base::output().AllocateResponse();
- auto sws =
- CallMethodImplFunction<kMethod>(Base::server_call(), request, response);
+ auto sws = CallMethodImplFunction<kMethod>(
+ Base::call_context(), request, response);
response = response.first(sws.size());
return sws;
}
diff --git a/pw_transfer/public/pw_transfer/transfer.h b/pw_transfer/public/pw_transfer/transfer.h
index febe3d1..9a512e0 100644
--- a/pw_transfer/public/pw_transfer/transfer.h
+++ b/pw_transfer/public/pw_transfer/transfer.h
@@ -45,6 +45,12 @@
max_chunk_size_bytes_(max_chunk_size_bytes),
default_max_bytes_to_receive_(default_max_bytes_to_receive) {}
+ TransferService(const TransferService&) = delete;
+ TransferService(TransferService&&) = delete;
+
+ TransferService& operator=(const TransferService&) = delete;
+ TransferService& operator=(TransferService&&) = delete;
+
void Read(ServerContext&, RawServerReaderWriter& reader_writer);
void Write(ServerContext&, RawServerReaderWriter& reader_writer);
diff --git a/pw_transfer/transfer_test.cc b/pw_transfer/transfer_test.cc
index 0032caf..e29fe3c 100644
--- a/pw_transfer/transfer_test.cc
+++ b/pw_transfer/transfer_test.cc
@@ -71,7 +71,7 @@
stream::MemoryReader reader_;
};
-TEST(Tranfser, Read_SingleChunk) {
+TEST(Transfer, Read_SingleChunk) {
constexpr auto data = bytes::Initialized<32>([](size_t i) { return i; });
SimpleReadTransfer handler(3, data);
@@ -108,7 +108,7 @@
EXPECT_EQ(handler.finalize_read_status, OkStatus());
}
-TEST(Tranfser, Read_MultiChunk) {
+TEST(Transfer, Read_MultiChunk) {
constexpr auto data = bytes::Initialized<32>([](size_t i) { return i; });
SimpleReadTransfer handler(3, data);
@@ -157,7 +157,7 @@
EXPECT_EQ(handler.finalize_read_status, OkStatus());
}
-TEST(Tranfser, Read_MaxChunkSize_Client) {
+TEST(Transfer, Read_MaxChunkSize_Client) {
constexpr auto data = bytes::Initialized<32>([](size_t i) { return i; });
SimpleReadTransfer handler(3, data);
@@ -212,7 +212,7 @@
EXPECT_EQ(handler.finalize_read_status, OkStatus());
}
-TEST(Tranfser, Read_MaxChunkSize_Server) {
+TEST(Transfer, Read_MaxChunkSize_Server) {
constexpr auto data = bytes::Initialized<32>([](size_t i) { return i; });
SimpleReadTransfer handler(3, data);
@@ -269,7 +269,7 @@
EXPECT_EQ(handler.finalize_read_status, OkStatus());
}
-TEST(Tranfser, Read_ClientError) {
+TEST(Transfer, Read_ClientError) {
constexpr auto data = bytes::Initialized<32>([](size_t i) { return i; });
SimpleReadTransfer handler(3, data);
@@ -294,7 +294,7 @@
EXPECT_EQ(handler.finalize_read_status, Status::OutOfRange());
}
-TEST(Tranfser, Read_MalformedParametersChunk) {
+TEST(Transfer, Read_MalformedParametersChunk) {
constexpr auto data = bytes::Initialized<32>([](size_t i) { return i; });
SimpleReadTransfer handler(3, data);
@@ -318,7 +318,7 @@
EXPECT_EQ(chunk.status.value(), Status::InvalidArgument());
}
-TEST(Tranfser, Read_UnregisteredHandler) {
+TEST(Transfer, Read_UnregisteredHandler) {
PW_RAW_TEST_METHOD_CONTEXT(TransferService, Read) ctx(64, 64);
ctx.call();
@@ -647,7 +647,7 @@
int call_count_;
};
-TEST(Tranfser, PrepareError) {
+TEST(Transfer, PrepareError) {
constexpr auto data = bytes::Initialized<32>([](size_t i) { return i; });
SometimesUnavailableReadHandler handler(3, data);