aboutsummaryrefslogtreecommitdiff
path: root/pw_rpc/pwpb/client_server_context_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'pw_rpc/pwpb/client_server_context_test.cc')
-rw-r--r--pw_rpc/pwpb/client_server_context_test.cc119
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