1 // Copyright 2021 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 <cstring> 17 18 #include "pw_bytes/span.h" 19 #include "pw_rpc/internal/call_context.h" 20 #include "pw_rpc/internal/server_call.h" 21 #include "pw_rpc/method_type.h" 22 23 namespace pw::rpc::internal::test { 24 25 // Fake server reader/writer classes for testing use. These also serve as a 26 // model for how the RPC implementations (raw, pwpb, Nanopb) structure their 27 // reader/writer classes. 28 // 29 // Readers/writers use an unusual inheritance hierarchy. Rather than having the 30 // ServerReaderWriter inherit from both the Reader and Writer classes, the 31 // readers and writers inherit from it, but hide the unsupported functionality. 32 // A ReaderWriter defines conversions to Reader and Writer, so it acts as if it 33 // inherited from both. This approach is unusual but necessary to have all 34 // classes use a single IntrusiveList::Item base and to avoid virtual methods or 35 // virtual inheritance. 36 // 37 // Call's public API is intended for rpc::Server, so hide the public methods 38 // with private inheritance. 39 class FakeServerReaderWriter : private internal::ServerCall { 40 public: 41 constexpr FakeServerReaderWriter() = default; 42 43 // On a real reader/writer, this constructor would not be exposed. 44 FakeServerReaderWriter(const CallContext& context, 45 MethodType type = MethodType::kBidirectionalStreaming) ServerCall(context,type)46 : ServerCall(context, type) {} 47 48 FakeServerReaderWriter(FakeServerReaderWriter&&) = default; 49 FakeServerReaderWriter& operator=(FakeServerReaderWriter&&) = default; 50 51 // Pull in protected functions from the hidden Call base as needed. 52 using Call::active; 53 using Call::set_on_error; 54 using Call::set_on_next; 55 using ServerCall::set_on_client_stream_end; 56 57 Status Finish(Status status = OkStatus()) { 58 return CloseAndSendResponse(status); 59 } 60 61 using Call::Write; 62 63 // Expose a few additional methods for test use. as_server_call()64 ServerCall& as_server_call() { return *this; } 65 }; 66 67 class FakeServerWriter : private FakeServerReaderWriter { 68 public: 69 constexpr FakeServerWriter() = default; 70 FakeServerWriter(const CallContext & context)71 FakeServerWriter(const CallContext& context) 72 : FakeServerReaderWriter(context, MethodType::kServerStreaming) {} 73 FakeServerWriter(FakeServerWriter&&) = default; 74 75 // Common reader/writer functions. 76 using FakeServerReaderWriter::active; 77 using FakeServerReaderWriter::Finish; 78 using FakeServerReaderWriter::set_on_error; 79 using FakeServerReaderWriter::Write; 80 81 // Functions for test use. 82 using FakeServerReaderWriter::as_server_call; 83 }; 84 85 class FakeServerReader : private FakeServerReaderWriter { 86 public: 87 constexpr FakeServerReader() = default; 88 FakeServerReader(const CallContext & context)89 FakeServerReader(const CallContext& context) 90 : FakeServerReaderWriter(context, MethodType::kClientStreaming) {} 91 92 FakeServerReader(FakeServerReader&&) = default; 93 94 using FakeServerReaderWriter::active; 95 using FakeServerReaderWriter::as_server_call; 96 }; 97 98 } // namespace pw::rpc::internal::test 99