Skip to content

Commit 2621221

Browse files
committed
iox-#27 Test setup and initial tests for client port
Signed-off-by: Mathias Kraus <[email protected]>
1 parent 64dfe6d commit 2621221

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
#include "iceoryx_posh/internal/popo/ports/client_port_data.hpp"
18+
#include "iceoryx_posh/internal/popo/ports/client_port_roudi.hpp"
19+
#include "iceoryx_posh/internal/popo/ports/client_port_user.hpp"
20+
21+
#include "iceoryx_hoofs/testing/watch_dog.hpp"
22+
#include "iceoryx_posh/internal/mepoo/memory_manager.hpp"
23+
#include "iceoryx_posh/mepoo/mepoo_config.hpp"
24+
25+
#include "test.hpp"
26+
27+
namespace
28+
{
29+
using namespace ::testing;
30+
using namespace iox::popo;
31+
32+
class ClientPort_test : public Test
33+
{
34+
// keep this the very first and also private
35+
iox::cxx::GenericRAII m_uniqueRouDiId{[] { iox::popo::internal::setUniqueRouDiId(0); },
36+
[] { iox::popo::internal::unsetUniqueRouDiId(); }};
37+
38+
public:
39+
ClientPort_test()
40+
{
41+
constexpr uint32_t NUM_CHUNKS = 20;
42+
constexpr uint32_t CHUNK_SIZE = 128;
43+
iox::mepoo::MePooConfig mempoolconf;
44+
mempoolconf.addMemPool({CHUNK_SIZE, NUM_CHUNKS});
45+
m_memoryManager.configureMemoryManager(mempoolconf, m_memoryAllocator, m_memoryAllocator);
46+
}
47+
48+
void SetUp() override
49+
{
50+
m_deadlockWatchdog.watchAndActOnFailure([] { std::terminate(); });
51+
52+
// this is basically what RouDi does when a client is requested
53+
tryAdvanceToState(clientPortDataWithConnectOnCreate, iox::ConnectionState::CONNECTED);
54+
tryAdvanceToState(clientPortDataWithoutConnectOnCreate, iox::ConnectionState::NOT_CONNECTED);
55+
}
56+
57+
void TearDown() override
58+
{
59+
}
60+
61+
void tryAdvanceToState(ClientPortData& clientPortData, const iox::ConnectionState state)
62+
{
63+
ClientPortRouDi clientPortRouDi{clientPortData};
64+
auto maybeCaProMessage = clientPortRouDi.tryGetCaProMessage();
65+
if (state == iox::ConnectionState::NOT_CONNECTED && clientPortData.m_connectionState == state)
66+
{
67+
return;
68+
}
69+
70+
ASSERT_THAT(clientPortData.m_connectionState, Eq(iox::ConnectionState::CONNECT_REQUESTED));
71+
if (clientPortData.m_connectionState == state)
72+
{
73+
return;
74+
}
75+
76+
iox::capro::CaproMessage serverMessage{
77+
iox::capro::CaproMessageType::OFFER, m_serviceDescription, iox::capro::CaproMessageSubType::NOSUBTYPE};
78+
serverMessage.m_chunkQueueData = &serverChunkQueueData;
79+
clientPortRouDi.dispatchCaProMessageAndGetPossibleResponse(serverMessage);
80+
ASSERT_THAT(clientPortData.m_connectionState, Eq(iox::ConnectionState::CONNECT_HANDSHAKE));
81+
if (clientPortData.m_connectionState == state)
82+
{
83+
return;
84+
}
85+
86+
serverMessage = iox::capro::CaproMessage{
87+
iox::capro::CaproMessageType::ACK, m_serviceDescription, iox::capro::CaproMessageSubType::NOSUBTYPE};
88+
clientPortRouDi.dispatchCaProMessageAndGetPossibleResponse(serverMessage);
89+
ASSERT_THAT(clientPortData.m_connectionState, Eq(iox::ConnectionState::CONNECTED));
90+
if (clientPortData.m_connectionState == state)
91+
{
92+
return;
93+
}
94+
95+
constexpr bool NOT_IMPLEMENTED{true};
96+
ASSERT_FALSE(NOT_IMPLEMENTED);
97+
}
98+
99+
uint32_t getNumberOfUsedChunks() const
100+
{
101+
return m_memoryManager.getMemPoolInfo(0).m_usedChunks;
102+
}
103+
104+
private:
105+
static constexpr iox::units::Duration DEADLOCK_TIMEOUT{5_s};
106+
Watchdog m_deadlockWatchdog{DEADLOCK_TIMEOUT};
107+
108+
static constexpr size_t MEMORY_SIZE = 1024 * 1024;
109+
uint8_t m_memory[MEMORY_SIZE];
110+
iox::posix::Allocator m_memoryAllocator{m_memory, MEMORY_SIZE};
111+
iox::mepoo::MemoryManager m_memoryManager;
112+
113+
iox::capro::ServiceDescription m_serviceDescription{"hyp", "no", "toad"};
114+
iox::RuntimeName_t m_runtimeName{"hypnotoad"};
115+
116+
ClientOptions m_withConnectOnCreate = [] {
117+
ClientOptions options;
118+
options.connectOnCreate = true;
119+
return options;
120+
}();
121+
ClientOptions m_withoutConnectOnCreate = [] {
122+
ClientOptions options;
123+
options.connectOnCreate = false;
124+
return options;
125+
}();
126+
127+
public:
128+
static constexpr uint32_t USER_PAYLOAD_SIZE{32};
129+
static constexpr uint32_t USER_PAYLOAD_ALIGNMENT{8};
130+
131+
ServerChunkQueueData_t serverChunkQueueData{iox::popo::QueueFullPolicy::DISCARD_OLDEST_DATA,
132+
iox::cxx::VariantQueueTypes::SoFi_MultiProducerSingleConsumer};
133+
134+
// client port with connect on create
135+
ClientPortData clientPortDataWithConnectOnCreate{
136+
m_serviceDescription, m_runtimeName, m_withConnectOnCreate, &m_memoryManager};
137+
ClientPortUser clientPortUserWithConnectOnCreate{clientPortDataWithConnectOnCreate};
138+
ClientPortRouDi clientPortRouDiWithConnectOnCreate{clientPortDataWithConnectOnCreate};
139+
140+
// client port without connect on create
141+
ClientPortData clientPortDataWithoutConnectOnCreate{
142+
m_serviceDescription, m_runtimeName, m_withoutConnectOnCreate, &m_memoryManager};
143+
ClientPortUser clientPortUserWithoutConnectOnCreate{clientPortDataWithoutConnectOnCreate};
144+
ClientPortRouDi clientPortRouDiWithoutConnectOnCreate{clientPortDataWithoutConnectOnCreate};
145+
};
146+
constexpr iox::units::Duration ClientPort_test::DEADLOCK_TIMEOUT;
147+
148+
TEST_F(ClientPort_test, InitialConnectionStateOnPortWithConnectOnCreateIs_CONNECTED)
149+
{
150+
EXPECT_THAT(clientPortUserWithConnectOnCreate.getConnectionState(), Eq(iox::ConnectionState::CONNECTED));
151+
}
152+
153+
TEST_F(ClientPort_test, InitialConnectionStateOnPortWithoutConnectOnCreateIs_NOT_CONNECTED)
154+
{
155+
EXPECT_THAT(clientPortUserWithoutConnectOnCreate.getConnectionState(), Eq(iox::ConnectionState::NOT_CONNECTED));
156+
}
157+
158+
TEST_F(ClientPort_test, AllocateRequestDoesNotFailAndUsesTheMempool)
159+
{
160+
EXPECT_THAT(getNumberOfUsedChunks(), Eq(0U));
161+
162+
auto maybeRequest = clientPortUserWithConnectOnCreate.allocateRequest(USER_PAYLOAD_SIZE, USER_PAYLOAD_ALIGNMENT);
163+
ASSERT_FALSE(maybeRequest.has_error());
164+
165+
EXPECT_THAT(getNumberOfUsedChunks(), Eq(1U));
166+
}
167+
168+
TEST_F(ClientPort_test, FreeRequestWorksAndReleasesTheChunkToTheMempool)
169+
{
170+
clientPortUserWithConnectOnCreate.allocateRequest(USER_PAYLOAD_SIZE, USER_PAYLOAD_ALIGNMENT)
171+
.and_then([&](auto& requestHeader) {
172+
EXPECT_THAT(getNumberOfUsedChunks(), Eq(1U));
173+
clientPortUserWithConnectOnCreate.freeRequest(requestHeader);
174+
EXPECT_THAT(getNumberOfUsedChunks(), Eq(0U));
175+
})
176+
.or_else([&](auto&) {
177+
constexpr bool UNREACHABLE{false};
178+
EXPECT_TRUE(UNREACHABLE);
179+
});
180+
}
181+
182+
} // namespace

0 commit comments

Comments
 (0)