1+ // Copyright (c) 2025 by Valour inc. All rights reserved.
12// Copyright (c) 2024 by ekxide IO GmbH. All rights reserved.
23//
34// Licensed under the Apache License, Version 2.0 (the "License");
1617
1718#include " iox/posh/experimental/node.hpp"
1819
20+ #include " iceoryx_hoofs/testing/error_reporting/testing_support.hpp"
1921#include " iceoryx_platform/stdlib.hpp"
22+ #include " iceoryx_posh/roudi_env/roudi_env.hpp"
23+ #include " iceoryx_posh/roudi_env/roudi_env_node_builder.hpp"
2024#include " iox/deadline_timer.hpp"
25+ #include " iox/detail/convert.hpp"
2126#include " iox/detail/system_configuration.hpp"
2227#include " iox/duration.hpp"
2328#include " iox/vector.hpp"
24-
25- #include " iceoryx_hoofs/testing/error_reporting/testing_support.hpp"
26- #include " iceoryx_posh/roudi_env/roudi_env.hpp"
27- #include " iceoryx_posh/roudi_env/roudi_env_node_builder.hpp"
2829#include " test.hpp"
2930
3031#include < optional>
@@ -44,6 +45,19 @@ struct Payload
4445struct Header
4546{
4647};
48+ struct Request
49+ {
50+ uint32_t valueA;
51+ uint32_t valueB;
52+ };
53+ struct Response
54+ {
55+ uint32_t sum;
56+ };
57+
58+ constexpr uint32_t SUMMAND_A = 4 ;
59+ constexpr uint32_t SUMMAND_B = 10 ;
60+ constexpr uint32_t SUMRESULT = SUMMAND_A + SUMMAND_B;
4761
4862TEST (Node_test, CreatingNodeWithRunningRouDiWorks)
4963{
@@ -638,17 +652,6 @@ TEST(Node_test, CreatingServer)
638652{
639653 ::testing::Test::RecordProperty (" TEST_ID" , " e422d450-7e1b-4435-b9ff-d0b0530f8f45" );
640654
641- struct Request
642- {
643- uint32_t valueA;
644- uint32_t valueB;
645- };
646-
647- struct Response
648- {
649- uint32_t sum;
650- };
651-
652655 auto domainId = iox::DomainId (1 );
653656 RouDiEnv roudi (domainId);
654657
@@ -676,17 +679,6 @@ TEST(Node_test, CreatingClient)
676679{
677680 ::testing::Test::RecordProperty (" TEST_ID" , " 290badda-a938-46b8-87ff-b4998ce43d95" );
678681
679- struct Request
680- {
681- uint32_t valueA;
682- uint32_t valueB;
683- };
684-
685- struct Response
686- {
687- uint32_t sum;
688- };
689-
690682 auto domainId = iox::DomainId (1 );
691683 RouDiEnv roudi (domainId);
692684
@@ -697,20 +689,66 @@ TEST(Node_test, CreatingClient)
697689 ASSERT_FALSE (client.has_error ());
698690}
699691
700- TEST (Node_test, UntypedServerClientRequestResponse )
692+ TEST (Node_test, CreatingListenerWorks )
701693{
702- ::testing::Test::RecordProperty (" TEST_ID" , " 38c02027-f2e5-47cf-9771-65868525647a " );
694+ ::testing::Test::RecordProperty (" TEST_ID" , " 9e679ced-b907-4186-b24e-c4321f2d363f " );
703695
704- struct Request
705- {
706- uint32_t valueA;
707- uint32_t valueB;
696+ RouDiEnv roudi;
697+
698+ auto node = RouDiEnvNodeBuilder (" hypnotoad" ).create ().expect (" Creating a node should not fail!" );
699+
700+ auto listenerResult = node.listener ().create ();
701+ ASSERT_FALSE (listenerResult.has_error ());
702+
703+ auto listener = std::move (listenerResult.value ());
704+
705+ EXPECT_TRUE ((std::is_same_v<decltype (listener), iox::unique_ptr<iox::posh::experimental::Listener>>));
706+ }
707+
708+ TEST (Node_test, ExhaustingServerClientLeadsToError)
709+ {
710+ ::testing::Test::RecordProperty (" TEST_ID" , " 19df3a60-1cc2-4172-aaf4-5877c0ed2f7e" );
711+
712+ const ServiceDescription default_service_description{" all" , " glory" , " hypnotoad" };
713+
714+ auto GetUniqueEventId = [&default_service_description](const std::string& id) {
715+ auto unique_event_id = default_service_description.getServiceIDString ();
716+ unique_event_id.append (iox::TruncateToCapacity_t{}, iox::capro::IdString_t{TruncateToCapacity_t{}, id.c_str ()});
717+
718+ return ServiceDescription{default_service_description.getServiceIDString (),
719+ default_service_description.getInstanceIDString (),
720+ unique_event_id};
708721 };
709722
710- struct Response
723+ RouDiEnv roudi;
724+
725+ auto node = RouDiEnvNodeBuilder (" hypnotoad" ).create ().expect (" Creating a node should not fail!" );
726+
727+ iox::vector<iox::unique_ptr<UntypedServer>, iox::MAX_SERVERS> servers;
728+ for (uint64_t i = 0 ; i < iox::MAX_SERVERS; ++i)
711729 {
712- uint32_t sum;
713- };
730+ servers.emplace_back (
731+ node.server (GetUniqueEventId (iox::convert::toString (i))).create ().expect (" Getting server" ));
732+ }
733+
734+ iox::vector<iox::unique_ptr<UntypedClient>, iox::MAX_CLIENTS> clients;
735+ for (uint64_t i = 0 ; i < iox::MAX_CLIENTS; ++i)
736+ {
737+ clients.emplace_back (node.client (default_service_description).create ().expect (" Getting client" ));
738+ }
739+
740+ auto server_result = node.server (GetUniqueEventId (iox::convert::toString (iox::MAX_SERVERS))).create ();
741+ ASSERT_TRUE (server_result.has_error ());
742+ EXPECT_THAT (server_result.error (), Eq (ServerBuilderError::OUT_OF_RESOURCES));
743+
744+ auto client_result = node.client (default_service_description).create ();
745+ ASSERT_TRUE (client_result.has_error ());
746+ EXPECT_THAT (client_result.error (), Eq (ClientBuilderError::OUT_OF_RESOURCES));
747+ }
748+
749+ TEST (Node_test, UntypedServerClientRequestResponse)
750+ {
751+ ::testing::Test::RecordProperty (" TEST_ID" , " 38c02027-f2e5-47cf-9771-65868525647a" );
714752
715753 auto domainId = iox::DomainId (1 );
716754 RouDiEnv roudi (domainId);
@@ -720,29 +758,29 @@ TEST(Node_test, UntypedServerClientRequestResponse)
720758 auto server = node.server ({" all" , " glory" , " hypnotoad" }).offer_on_create (true ).create ().expect (" creating server" );
721759 auto client = node.client ({" all" , " glory" , " hypnotoad" }).connect_on_create (true ).create ().expect (" creating client" );
722760
723- GTEST_ASSERT_TRUE (server->hasClients ());
761+ ASSERT_TRUE (server->hasClients ());
724762
725763 client->loan (sizeof (Request), alignof (Request))
726764 .and_then ([&](auto & requestPayload) {
727765 GTEST_SUCCEED () << " Client: Successfully allocate request" ;
728766 auto requestHeader = iox::popo::RequestHeader::fromPayload (requestPayload);
729767 requestHeader->setSequenceId (1 );
730768 auto request = static_cast <Request*>(requestPayload);
731- request->valueA = 4 ;
732- request->valueB = 10 ;
769+ request->valueA = SUMMAND_A ;
770+ request->valueB = SUMMAND_B ;
733771 client->send (request).or_else (
734772 [&](auto & error) { GTEST_FAIL () << " Client: Could not send request: " << error; });
735773 })
736774 .or_else ([&](auto & error) { GTEST_FAIL () << " Client: Could not allocate data request: " << error; });
737775
738- GTEST_ASSERT_EQ (client->getConnectionState (), iox::ConnectionState::CONNECTED);
776+ ASSERT_EQ (client->getConnectionState (), iox::ConnectionState::CONNECTED);
739777
740778 server->take ()
741779 .and_then ([&](const auto & requestPayload) {
742780 auto request = static_cast <const Request*>(requestPayload);
743781 const iox::popo::RequestHeader* requestHeader = iox::popo::RequestHeader::fromPayload (requestPayload);
744782
745- GTEST_ASSERT_EQ (requestHeader->getSequenceId (), 1 );
783+ ASSERT_EQ (requestHeader->getSequenceId (), 1 );
746784 server->loan (requestHeader, sizeof (Response), alignof (Response))
747785 .and_then ([&](auto & responsePayload) {
748786 auto response = static_cast <Response*>(responsePayload);
@@ -757,19 +795,79 @@ TEST(Node_test, UntypedServerClientRequestResponse)
757795 GTEST_FAIL () << " Server: Could not get request: " << iox::popo::asStringLiteral (result);
758796 });
759797
760- GTEST_ASSERT_EQ (client->hasResponses (), true );
798+ ASSERT_EQ (client->hasResponses (), true );
761799
762800 client->take ()
763801 .and_then ([&](const auto & responsePayload) {
764802 auto responseHeader = iox::popo::ResponseHeader::fromPayload (responsePayload);
765- GTEST_ASSERT_EQ (responseHeader->getSequenceId (), 1 );
803+ ASSERT_EQ (responseHeader->getSequenceId (), 1 );
766804 auto response = static_cast <const Response*>(responsePayload);
767- GTEST_ASSERT_EQ (response->sum , 14 );
805+ ASSERT_EQ (response->sum , SUMRESULT );
768806 client->releaseResponse (responsePayload);
769807 })
770808 .or_else ([](iox::popo::ChunkReceiveResult result) {
771809 GTEST_FAIL () << " Client: Could not get response: " << iox::popo::asStringLiteral (result);
772810 });
773811}
774812
813+ TEST (Node_test, TypedServerClientRequestResponse)
814+ {
815+ ::testing::Test::RecordProperty (" TEST_ID" , " 16fe3017-9801-4d58-9ef5-55c3480c07e6" );
816+
817+ auto domainId = iox::DomainId (1 );
818+ RouDiEnv roudi (domainId);
819+
820+ auto node = RouDiEnvNodeBuilder (" hypnotoad" ).domain_id (domainId).create ().expect (" server created" );
821+
822+ auto server = node.server ({" all" , " glory" , " hypnotoad" })
823+ .offer_on_create (true )
824+ .create <Request, Response>()
825+ .expect (" creating server" );
826+ auto client = node.client ({" all" , " glory" , " hypnotoad" })
827+ .connect_on_create (true )
828+ .create <Request, Response>()
829+ .expect (" creating client" );
830+
831+ ASSERT_TRUE (server->hasClients ());
832+
833+ client->loan ()
834+ .and_then ([&](iox::popo::Request<Request>& req) {
835+ GTEST_SUCCEED () << " Client: Successfully allocate request" ;
836+ req.getRequestHeader ().setSequenceId (1 );
837+ req->valueA = SUMMAND_A;
838+ req->valueB = SUMMAND_B;
839+ req.send ().or_else ([&](auto & error) { GTEST_FAIL () << " Client: Could not send request: " << error; });
840+ })
841+ .or_else ([&](auto & error) { GTEST_FAIL () << " Client: Could not allocate data request: " << error; });
842+
843+ ASSERT_EQ (client->getConnectionState (), iox::ConnectionState::CONNECTED);
844+
845+ server->take ()
846+ .and_then ([&](const iox::popo::Request<const Request>& request) {
847+ ASSERT_EQ (request.getRequestHeader ().getSequenceId (), 1 );
848+ server->loan (request)
849+ .and_then ([&](iox::popo::Response<Response>& response) {
850+ response->sum = request->valueA + request->valueB ;
851+ response.send ().or_else ([&](auto & error) {
852+ GTEST_FAIL () << " Server: Could not send Response: " << error << std::endl;
853+ });
854+ })
855+ .or_else ([](auto & error) { GTEST_FAIL () << " Server: Could not allocate response: " << error; });
856+ })
857+ .or_else ([](iox::popo::ServerRequestResult result) {
858+ GTEST_FAIL () << " Server: Could not get request: " << iox::popo::asStringLiteral (result);
859+ });
860+
861+ ASSERT_EQ (client->hasResponses (), true );
862+
863+ client->take ()
864+ .and_then ([&](iox::popo::Response<const Response>& response) {
865+ ASSERT_EQ (response.getResponseHeader ().getSequenceId (), 1 );
866+ ASSERT_EQ (response->sum , SUMRESULT);
867+ })
868+ .or_else ([](iox::popo::ChunkReceiveResult result) {
869+ GTEST_FAIL () << " Client: Could not get response: " << iox::popo::asStringLiteral (result);
870+ });
871+ }
872+
775873} // namespace
0 commit comments