diff options
Diffstat (limited to 'pw_rpc/pwpb/client_server_context_test.cc')
-rw-r--r-- | pw_rpc/pwpb/client_server_context_test.cc | 119 |
1 files changed, 115 insertions, 4 deletions
diff --git a/pw_rpc/pwpb/client_server_context_test.cc b/pw_rpc/pwpb/client_server_context_test.cc index bd45154ef..184bc3948 100644 --- a/pw_rpc/pwpb/client_server_context_test.cc +++ b/pw_rpc/pwpb/client_server_context_test.cc @@ -12,9 +12,13 @@ // License for the specific language governing permissions and limitations under // the License. +#include <mutex> +#include <utility> + #include "gtest/gtest.h" #include "pw_rpc/pwpb/client_server_testing.h" #include "pw_rpc_test_protos/test.rpc.pwpb.h" +#include "pw_sync/mutex.h" namespace pw::rpc { namespace { @@ -37,8 +41,16 @@ class TestService final : public GeneratedService::Service<TestService> { return static_cast<Status::Code>(request.status_code); } - void TestAnotherUnaryRpc(const TestRequest::Message&, - PwpbUnaryResponder<TestResponse::Message>&) {} + Status TestAnotherUnaryRpc(const TestRequest::Message& request, + TestResponse::Message& response) { + response.value = 42; + response.repeated_field.SetEncoder( + [](TestResponse::StreamEncoder& encoder) { + constexpr std::array<uint32_t, 3> kValues = {7, 8, 9}; + return encoder.WriteRepeatedField(kValues); + }); + return static_cast<Status::Code>(request.status_code); + } static void TestServerStreamRpc(const TestRequest::Message&, ServerWriter<TestStreamResponse::Message>&) {} @@ -54,7 +66,7 @@ class TestService final : public GeneratedService::Service<TestService> { namespace { -TEST(PwpbClientServerTestContext, ReceivesUnaryRpcReponse) { +TEST(PwpbClientServerTestContext, ReceivesUnaryRpcResponse) { PwpbClientServerTestContext<> ctx; test::TestService service; ctx.server().RegisterService(service); @@ -79,7 +91,7 @@ TEST(PwpbClientServerTestContext, ReceivesUnaryRpcReponse) { EXPECT_EQ(request.integer, sent_request.integer); } -TEST(PwpbClientServerTestContext, ReceivesMultipleReponses) { +TEST(PwpbClientServerTestContext, ReceivesMultipleResponses) { PwpbClientServerTestContext<> ctx; test::TestService service; ctx.server().RegisterService(service); @@ -119,5 +131,104 @@ TEST(PwpbClientServerTestContext, ReceivesMultipleReponses) { EXPECT_EQ(request2.integer, sent_request2.integer); } +TEST(PwpbClientServerTestContext, + ReceivesMultipleResponsesWithPacketProcessor) { + using ProtectedInt = std::pair<int, pw::sync::Mutex>; + ProtectedInt server_counter{}; + auto server_processor = [&server_counter]( + ClientServer& client_server, + pw::ConstByteSpan packet) -> pw::Status { + server_counter.second.lock(); + ++server_counter.first; + server_counter.second.unlock(); + return client_server.ProcessPacket(packet); + }; + + ProtectedInt client_counter{}; + auto client_processor = [&client_counter]( + ClientServer& client_server, + pw::ConstByteSpan packet) -> pw::Status { + client_counter.second.lock(); + ++client_counter.first; + client_counter.second.unlock(); + return client_server.ProcessPacket(packet); + }; + + PwpbClientServerTestContext<> ctx(server_processor, client_processor); + test::TestService service; + ctx.server().RegisterService(service); + + TestResponse::Message response1 = {}; + TestResponse::Message response2 = {}; + auto handler1 = [&response1](const TestResponse::Message& server_response, + pw::Status) { response1 = server_response; }; + auto handler2 = [&response2](const TestResponse::Message& server_response, + pw::Status) { response2 = server_response; }; + + TestRequest::Message request1{.integer = 1, .status_code = OkStatus().code()}; + TestRequest::Message request2{.integer = 2, .status_code = OkStatus().code()}; + const auto call1 = test::GeneratedService::TestUnaryRpc( + ctx.client(), ctx.channel().id(), request1, handler1); + // Force manual forwarding of packets as context is not threaded + ctx.ForwardNewPackets(); + const auto call2 = test::GeneratedService::TestUnaryRpc( + ctx.client(), ctx.channel().id(), request2, handler2); + // Force manual forwarding of packets as context is not threaded + ctx.ForwardNewPackets(); + + const auto sent_request1 = + ctx.request<test::pw_rpc::pwpb::TestService::TestUnaryRpc>(0); + const auto sent_request2 = + ctx.request<test::pw_rpc::pwpb::TestService::TestUnaryRpc>(1); + const auto sent_response1 = + ctx.response<test::pw_rpc::pwpb::TestService::TestUnaryRpc>(0); + const auto sent_response2 = + ctx.response<test::pw_rpc::pwpb::TestService::TestUnaryRpc>(1); + + EXPECT_EQ(response1.value, request1.integer + 1); + EXPECT_EQ(response2.value, request2.integer + 1); + EXPECT_EQ(response1.value, sent_response1.value); + EXPECT_EQ(response2.value, sent_response2.value); + EXPECT_EQ(request1.integer, sent_request1.integer); + EXPECT_EQ(request2.integer, sent_request2.integer); + + server_counter.second.lock(); + EXPECT_EQ(server_counter.first, 2); + server_counter.second.unlock(); + client_counter.second.lock(); + EXPECT_EQ(client_counter.first, 2); + client_counter.second.unlock(); +} + +TEST(PwpbClientServerTestContext, ResponseWithCallbacks) { + PwpbClientServerTestContext<> ctx; + test::TestService service; + ctx.server().RegisterService(service); + + TestRequest::Message request{}; + const auto call = test::GeneratedService::TestAnotherUnaryRpc( + ctx.client(), ctx.channel().id(), request); + // Force manual forwarding of packets as context is not threaded + ctx.ForwardNewPackets(); + + // To decode a response object that requires to set callbacks, pass it to the + // response() method as a parameter. + pw::Vector<uint32_t, 4> values{}; + + TestResponse::Message response{}; + response.repeated_field.SetDecoder( + [&values](TestResponse::StreamDecoder& decoder) { + return decoder.ReadRepeatedField(values); + }); + ctx.response<test::GeneratedService::TestAnotherUnaryRpc>(0, response); + + EXPECT_EQ(42, response.value); + + EXPECT_EQ(3u, values.size()); + EXPECT_EQ(7u, values[0]); + EXPECT_EQ(8u, values[1]); + EXPECT_EQ(9u, values[2]); +} + } // namespace } // namespace pw::rpc |