From 0ae85865722e8cb76959bba42852cb711b9e59e6 Mon Sep 17 00:00:00 2001 From: Dennis Hezel Date: Thu, 27 Feb 2025 19:25:37 +0100 Subject: [PATCH] test: Add client test for initiating finish during read --- src/agrpc/server_rpc.hpp | 4 ++-- test/src/test_client_rpc_17.cpp | 32 +++++++++++++++++++++++++++++++- test/src/test_server_rpc_17.cpp | 2 +- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/agrpc/server_rpc.hpp b/src/agrpc/server_rpc.hpp index 8cfb8f59..768f9704 100644 --- a/src/agrpc/server_rpc.hpp +++ b/src/agrpc/server_rpc.hpp @@ -664,8 +664,8 @@ class ServerRPCBidiStreamingBase, TraitsT, Execu /** * @brief Receive a message from the client * - * May not be called currently with `finish()`/`write_and_finish()`. It is not meaningful to call it concurrently - * with another read on the same rpc since reads on the same stream are delivered in order. + * It may not be called concurrently with operations other than `write()`. It is not meaningful to call it + * concurrently with another read on the same rpc since reads on the same stream are delivered in order. * * @param token A completion token like `asio::yield_context` or `agrpc::use_sender`. The completion signature is * `void(bool)`. `true` indicates that a valid message was read. `false` when there will be no more incoming diff --git a/test/src/test_client_rpc_17.cpp b/test/src/test_client_rpc_17.cpp index 29f7a6d1..4c7b0f8a 100644 --- a/test/src/test_client_rpc_17.cpp +++ b/test/src/test_client_rpc_17.cpp @@ -317,7 +317,7 @@ TEST_CASE_FIXTURE(ClientRPCTest, "ClientStreamin } TEST_CASE_FIXTURE(ClientRPCIoContextTest, - "BidirectionalStreamingClientRPC concurrent read+write") + "BidirectionalStreamingClientRPC initiate write during read") { bool set_last_message{}; SUBCASE("no WriteOptions") {} @@ -355,6 +355,36 @@ TEST_CASE_FIXTURE(ClientRPCIoContextTest, }); } +TEST_CASE_FIXTURE(ClientRPCIoContextTest, + "BidirectionalStreamingClientRPC initiate finish during read") +{ + run_server_client_on_separate_threads( + [&](auto& rpc, const asio::yield_context& yield) + { + CHECK(rpc.finish(grpc::Status{grpc::StatusCode::ALREADY_EXISTS, ""}, yield)); + }, + [&](const asio::yield_context& yield) + { + auto rpc = create_rpc(); + start_rpc(rpc, yield); + std::promise promise; + bool read{}; + rpc.read_initial_metadata( + [&](auto&& ok) + { + read = ok; + }); + rpc.read(response, + [&](bool ok) + { + promise.set_value(ok); + }); + CHECK_EQ(grpc::StatusCode::ALREADY_EXISTS, rpc.finish(yield).error_code()); + CHECK_FALSE(promise.get_future().get()); + CHECK(read); + }); +} + TEST_CASE_FIXTURE(ClientRPCIoContextTest, "BidirectionalStreamingClientRPC cancel before write+read") { diff --git a/test/src/test_server_rpc_17.cpp b/test/src/test_server_rpc_17.cpp index 3d4e83d2..eed4091d 100644 --- a/test/src/test_server_rpc_17.cpp +++ b/test/src/test_server_rpc_17.cpp @@ -369,7 +369,7 @@ TEST_CASE_TEMPLATE("ServerRPC/ClientRPC bidi streaming success", RPC, test::Bidi } TEST_CASE_FIXTURE(ServerRPCTest, - "BidirectionalStreamingServerRPC concurrent read+finish") + "BidirectionalStreamingServerRPC initiate finish during read") { bool order{}; register_and_perform_requests(