Skip to content

Commit e8a28b5

Browse files
committed
iox-#27 Add PortManager tests to acquire clients and servers
1 parent a34b345 commit e8a28b5

File tree

6 files changed

+191
-9
lines changed

6 files changed

+191
-9
lines changed

iceoryx_posh/include/iceoryx_posh/internal/popo/ports/client_port_data.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ struct ClientPortData : public BasePortData
4242

4343
static constexpr uint64_t HISTORY_CAPACITY_ZERO{0U};
4444

45+
ClientOptions m_options;
46+
4547
ClientChunkSenderData_t m_chunkSenderData;
4648
ClientChunkReceiverData_t m_chunkReceiverData;
4749
std::atomic_bool m_connectRequested{false};

iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_data.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ struct ServerPortData : public BasePortData
3939
mepoo::MemoryManager* const memoryManager,
4040
const mepoo::MemoryInfo& memoryInfo = mepoo::MemoryInfo()) noexcept;
4141

42+
ServerOptions m_options;
43+
4244
ServerChunkSenderData_t m_chunkSenderData;
4345
ServerChunkReceiverData_t m_chunkReceiverData;
4446
std::atomic_bool m_offeringRequested{false};

iceoryx_posh/source/popo/ports/client_port_data.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ ClientPortData::ClientPortData(const capro::ServiceDescription& serviceDescripti
3535
mepoo::MemoryManager* const memoryManager,
3636
const mepoo::MemoryInfo& memoryInfo) noexcept
3737
: BasePortData(serviceDescription, runtimeName, clientOptions.nodeName)
38+
, m_options(clientOptions)
3839
, m_chunkSenderData(memoryManager, clientOptions.serverTooSlowPolicy, HISTORY_CAPACITY_ZERO, memoryInfo)
3940
, m_chunkReceiverData(getResponseQueueType(clientOptions.responseQueueFullPolicy),
4041
clientOptions.responseQueueFullPolicy,

iceoryx_posh/source/popo/ports/server_port_data.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ ServerPortData::ServerPortData(const capro::ServiceDescription& serviceDescripti
3535
mepoo::MemoryManager* const memoryManager,
3636
const mepoo::MemoryInfo& memoryInfo) noexcept
3737
: BasePortData(serviceDescription, runtimeName, serverOptions.nodeName)
38+
, m_options(serverOptions)
3839
, m_chunkSenderData(memoryManager, serverOptions.clientTooSlowPolicy, HISTORY_REQUEST_OF_ZERO, memoryInfo)
3940
, m_chunkReceiverData(
4041
getRequestQueueType(serverOptions.requestQueueFullPolicy), serverOptions.requestQueueFullPolicy, memoryInfo)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright (c) 2019 - 2021 by Robert Bosch GmbH. All rights reserved.
2+
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
// SPDX-License-Identifier: Apache-2.0
17+
18+
#include "test_roudi_portmanager_fixture.hpp"
19+
20+
namespace iox_test_roudi_portmanager
21+
{
22+
using namespace iox::popo;
23+
24+
constexpr uint64_t RESPONSE_QUEUE_CAPACITY{2U};
25+
constexpr uint64_t REQUEST_QUEUE_CAPACITY{2U};
26+
27+
ClientOptions createTestClientOptions()
28+
{
29+
return ClientOptions{RESPONSE_QUEUE_CAPACITY, iox::NodeName_t("node")};
30+
}
31+
32+
ServerOptions createTestServerOptions()
33+
{
34+
return ServerOptions{REQUEST_QUEUE_CAPACITY, iox::NodeName_t("node")};
35+
}
36+
37+
// BEGIN aquireClientPortData tests
38+
39+
TEST_F(PortManager_test, AcquireClientPortDataReturnsPort)
40+
{
41+
::testing::Test::RecordProperty("TEST_ID", "92225f2c-619a-425b-bba0-6a014822c4c3");
42+
const ServiceDescription sd{"hyp", "no", "toad"};
43+
const RuntimeName_t runtimeName{"hypnotoad"};
44+
auto clientOptions = createTestClientOptions();
45+
clientOptions.connectOnCreate = false;
46+
clientOptions.responseQueueFullPolicy = QueueFullPolicy::BLOCK_PRODUCER;
47+
clientOptions.serverTooSlowPolicy = ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER;
48+
m_portManager->acquireClientPortData(sd, clientOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
49+
.and_then([&](const auto& clientPortData) {
50+
EXPECT_THAT(clientPortData->m_serviceDescription, Eq(sd));
51+
EXPECT_THAT(clientPortData->m_runtimeName, Eq(runtimeName));
52+
EXPECT_THAT(clientPortData->m_toBeDestroyed, Eq(false));
53+
EXPECT_THAT(clientPortData->m_options.responseQueueCapacity, Eq(clientOptions.responseQueueCapacity));
54+
EXPECT_THAT(clientPortData->m_options.nodeName, Eq(clientOptions.nodeName));
55+
EXPECT_THAT(clientPortData->m_options.connectOnCreate, Eq(clientOptions.connectOnCreate));
56+
EXPECT_THAT(clientPortData->m_options.responseQueueFullPolicy, Eq(clientOptions.responseQueueFullPolicy));
57+
EXPECT_THAT(clientPortData->m_options.serverTooSlowPolicy, Eq(clientOptions.serverTooSlowPolicy));
58+
})
59+
.or_else([&](const auto& error) {
60+
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
61+
});
62+
}
63+
64+
// END aquireClientPortData tests
65+
66+
// BEGIN aquireServerPortData tests
67+
68+
TEST_F(PortManager_test, AcquireServerPortDataReturnsPort)
69+
{
70+
::testing::Test::RecordProperty("TEST_ID", "776c51c4-074a-4404-b6a7-ed08f59f05a0");
71+
const ServiceDescription sd{"hyp", "no", "toad"};
72+
const RuntimeName_t runtimeName{"hypnotoad"};
73+
auto serverOptions = createTestServerOptions();
74+
serverOptions.offerOnCreate = false;
75+
serverOptions.requestQueueFullPolicy = QueueFullPolicy::BLOCK_PRODUCER;
76+
serverOptions.clientTooSlowPolicy = ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER;
77+
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
78+
.and_then([&](const auto& serverPortData) {
79+
EXPECT_THAT(serverPortData->m_serviceDescription, Eq(sd));
80+
EXPECT_THAT(serverPortData->m_runtimeName, Eq(runtimeName));
81+
EXPECT_THAT(serverPortData->m_toBeDestroyed, Eq(false));
82+
EXPECT_THAT(serverPortData->m_options.requestQueueCapacity, Eq(serverOptions.requestQueueCapacity));
83+
EXPECT_THAT(serverPortData->m_options.nodeName, Eq(serverOptions.nodeName));
84+
EXPECT_THAT(serverPortData->m_options.offerOnCreate, Eq(serverOptions.offerOnCreate));
85+
EXPECT_THAT(serverPortData->m_options.requestQueueFullPolicy, Eq(serverOptions.requestQueueFullPolicy));
86+
EXPECT_THAT(serverPortData->m_options.clientTooSlowPolicy, Eq(serverOptions.clientTooSlowPolicy));
87+
})
88+
.or_else([&](const auto& error) {
89+
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
90+
});
91+
}
92+
93+
TEST_F(PortManager_test, AcquireServerPortDataWithSameServiceDescriptionTwiceCallsErrorHandlerAndReturnsError)
94+
{
95+
::testing::Test::RecordProperty("TEST_ID", "9f2c24ba-192d-4ce8-a61a-fe40b42c655b");
96+
const ServiceDescription sd{"hyp", "no", "toad"};
97+
const RuntimeName_t runtimeName{"hypnotoad"};
98+
auto serverOptions = createTestServerOptions();
99+
100+
// first call must be successful
101+
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
102+
.or_else([&](const auto& error) {
103+
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
104+
});
105+
106+
iox::cxx::optional<iox::Error> detectedError;
107+
auto errorHandlerGuard =
108+
iox::ErrorHandler::setTemporaryErrorHandler([&](const auto error, const auto, const auto errorLevel) {
109+
EXPECT_THAT(error, Eq(iox::Error::kPOSH__PORT_MANAGER_SERVERPORT_NOT_UNIQUE));
110+
EXPECT_THAT(errorLevel, Eq(iox::ErrorLevel::MODERATE));
111+
detectedError.emplace(error);
112+
});
113+
114+
// second call must fail
115+
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
116+
.and_then([&](const auto&) {
117+
GTEST_FAIL() << "Expected PortPoolError::UNIQUE_SERVER_PORT_ALREADY_EXISTS but got ServerPortData";
118+
})
119+
.or_else([&](const auto& error) { EXPECT_THAT(error, Eq(PortPoolError::UNIQUE_SERVER_PORT_ALREADY_EXISTS)); });
120+
121+
EXPECT_TRUE(detectedError.has_value());
122+
}
123+
124+
TEST_F(PortManager_test, AcquireServerPortDataWithSameServiceDescriptionTwiceAndFirstPortMarkedToBeDestroyedReturnsPort)
125+
{
126+
::testing::Test::RecordProperty("TEST_ID", "d7f2815d-f1ea-403d-9355-69470d92a10f");
127+
const ServiceDescription sd{"hyp", "no", "toad"};
128+
const RuntimeName_t runtimeName{"hypnotoad"};
129+
auto serverOptions = createTestServerOptions();
130+
131+
// first call must be successful
132+
auto serverPortDataResult =
133+
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {});
134+
135+
ASSERT_FALSE(serverPortDataResult.has_error());
136+
137+
serverPortDataResult.value()->m_toBeDestroyed = true;
138+
139+
iox::cxx::optional<iox::Error> detectedError;
140+
auto errorHandlerGuard = iox::ErrorHandler::setTemporaryErrorHandler(
141+
[&](const auto error, const auto, const auto) { detectedError.emplace(error); });
142+
143+
// second call must now also succeed
144+
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
145+
.or_else([&](const auto& error) {
146+
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
147+
});
148+
149+
detectedError.and_then(
150+
[&](const auto& error) { GTEST_FAIL() << "Expected error handler to not be called but got: " << error; });
151+
}
152+
153+
// END aquireServerPortData tests
154+
155+
} // namespace iox_test_roudi_portmanager

iceoryx_posh/test/moduletests/test_roudi_portmanager_fixture.hpp

+30-9
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,29 @@
2222
#include "iceoryx_hoofs/testing/watch_dog.hpp"
2323
#include "iceoryx_posh/iceoryx_posh_types.hpp"
2424
#include "iceoryx_posh/internal/capro/capro_message.hpp"
25+
#include "iceoryx_posh/internal/popo/ports/client_port_user.hpp"
2526
#include "iceoryx_posh/internal/popo/ports/publisher_port_user.hpp"
27+
#include "iceoryx_posh/internal/popo/ports/server_port_user.hpp"
28+
#include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp"
2629
#include "iceoryx_posh/internal/roudi/port_manager.hpp"
30+
#include "iceoryx_posh/popo/client_options.hpp"
31+
#include "iceoryx_posh/popo/server_options.hpp"
2732
#include "iceoryx_posh/roudi/memory/iceoryx_roudi_memory_manager.hpp"
2833

2934
#include "test.hpp"
3035

3136
#include <cstdint>
32-
#include <limits> // std::numeric_limits
37+
#include <limits>
3338

3439
namespace iox_test_roudi_portmanager
3540
{
3641
using namespace ::testing;
42+
using namespace iox;
43+
using namespace iox::capro;
3744
using namespace iox::cxx;
45+
using namespace iox::popo;
46+
using namespace iox::roudi;
3847

39-
using iox::popo::PublisherOptions;
40-
using iox::popo::PublisherPortUser;
41-
using iox::popo::QueueFullPolicy;
42-
using iox::popo::SubscriberOptions;
43-
using iox::popo::SubscriberPortUser;
44-
using iox::roudi::IceOryxRouDiMemoryManager;
45-
using iox::roudi::PortManager;
46-
using iox::roudi::PortPoolError;
4748
using iox::runtime::PortConfigInfo;
4849

4950
class PortManagerTester : public PortManager
@@ -70,6 +71,8 @@ class PortManager_test : public Test
7071

7172
iox::RuntimeName_t m_runtimeName{"TestApp"};
7273

74+
cxx::GenericRAII suppressLogging = iox::LoggerPosh().SetLogLevelForScope(iox::log::LogLevel::kOff);
75+
7376
void SetUp() override
7477
{
7578
m_instIdCounter = m_sIdCounter = 1U;
@@ -192,6 +195,24 @@ class PortManager_test : public Test
192195
return SubscriberPortUser(
193196
m_portManager->acquireSubscriberPortData({"1", "1", "1"}, options, "schlomo", PortConfigInfo()).value());
194197
}
198+
199+
ClientPortUser createClient(const ClientOptions& options)
200+
{
201+
const ServiceDescription sd{"1", "1", "1"};
202+
const RuntimeName_t runtimeName{"guiseppe"};
203+
return ClientPortUser(
204+
*m_portManager->acquireClientPortData(sd, options, runtimeName, m_payloadDataSegmentMemoryManager, {})
205+
.value());
206+
}
207+
208+
ServerPortUser createServer(const ServerOptions& options)
209+
{
210+
const ServiceDescription sd{"1", "1", "1"};
211+
const RuntimeName_t runtimeName{"schlomo"};
212+
return ServerPortUser(
213+
*m_portManager->acquireServerPortData(sd, options, runtimeName, m_payloadDataSegmentMemoryManager, {})
214+
.value());
215+
}
195216
};
196217

197218
template <typename vector>

0 commit comments

Comments
 (0)