Skip to content

Commit

Permalink
iox-#27 Add PortManager tests to acquire clients and servers
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Feb 17, 2022
1 parent a34b345 commit 609b161
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 9 deletions.
155 changes: 155 additions & 0 deletions iceoryx_posh/test/moduletests/test_roudi_portmanager_client_server.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright (c) 2019 - 2021 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "test_roudi_portmanager_fixture.hpp"

namespace iox_test_roudi_portmanager
{
using namespace iox::popo;

constexpr uint64_t RESPONSE_QUEUE_CAPACITY{2U};
constexpr uint64_t REQUEST_QUEUE_CAPACITY{2U};

ClientOptions createTestClientOptions()
{
return ClientOptions{RESPONSE_QUEUE_CAPACITY, iox::NodeName_t("node")};
}

ServerOptions createTestServerOptions()
{
return ServerOptions{REQUEST_QUEUE_CAPACITY, iox::NodeName_t("node")};
}

// BEGIN aquireClientPortData tests

TEST_F(PortManager_test, AcquireClientPortDataReturnsPort)
{
::testing::Test::RecordProperty("TEST_ID", "92225f2c-619a-425b-bba0-6a014822c4c3");
const ServiceDescription sd{"hyp", "no", "toad"};
const RuntimeName_t runtimeName{"hypnotoad"};
auto clientOptions = createTestClientOptions();
clientOptions.connectOnCreate = false;
clientOptions.responseQueueFullPolicy = QueueFullPolicy::BLOCK_PRODUCER;
clientOptions.serverTooSlowPolicy = ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER;
m_portManager->acquireClientPortData(sd, clientOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
.and_then([&](const auto& clientPortData) {
EXPECT_THAT(clientPortData->m_serviceDescription, Eq(sd));
EXPECT_THAT(clientPortData->m_runtimeName, Eq(runtimeName));
EXPECT_THAT(clientPortData->m_nodeName, Eq(clientOptions.nodeName));
EXPECT_THAT(clientPortData->m_toBeDestroyed, Eq(false));
EXPECT_THAT(clientPortData->m_chunkReceiverData.m_queue.capacity() , Eq(clientOptions.responseQueueCapacity));
EXPECT_THAT(clientPortData->m_connectRequested, Eq(clientOptions.connectOnCreate));
EXPECT_THAT(clientPortData->m_chunkReceiverData.m_queueFullPolicy, Eq(clientOptions.responseQueueFullPolicy));
EXPECT_THAT(clientPortData->m_chunkSenderData.m_consumerTooSlowPolicy, Eq(clientOptions.serverTooSlowPolicy));
})
.or_else([&](const auto& error) {
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
});
}

// END aquireClientPortData tests

// BEGIN aquireServerPortData tests

TEST_F(PortManager_test, AcquireServerPortDataReturnsPort)
{
::testing::Test::RecordProperty("TEST_ID", "776c51c4-074a-4404-b6a7-ed08f59f05a0");
const ServiceDescription sd{"hyp", "no", "toad"};
const RuntimeName_t runtimeName{"hypnotoad"};
auto serverOptions = createTestServerOptions();
serverOptions.offerOnCreate = false;
serverOptions.requestQueueFullPolicy = QueueFullPolicy::BLOCK_PRODUCER;
serverOptions.clientTooSlowPolicy = ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER;
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
.and_then([&](const auto& serverPortData) {
EXPECT_THAT(serverPortData->m_serviceDescription, Eq(sd));
EXPECT_THAT(serverPortData->m_runtimeName, Eq(runtimeName));
EXPECT_THAT(serverPortData->m_nodeName, Eq(serverOptions.nodeName));
EXPECT_THAT(serverPortData->m_toBeDestroyed, Eq(false));
EXPECT_THAT(serverPortData->m_chunkReceiverData.m_queue.capacity(), Eq(serverOptions.requestQueueCapacity));
EXPECT_THAT(serverPortData->m_offeringRequested, Eq(serverOptions.offerOnCreate));
EXPECT_THAT(serverPortData->m_chunkReceiverData.m_queueFullPolicy, Eq(serverOptions.requestQueueFullPolicy));
EXPECT_THAT(serverPortData->m_chunkSenderData.m_consumerTooSlowPolicy, Eq(serverOptions.clientTooSlowPolicy));
})
.or_else([&](const auto& error) {
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
});
}

TEST_F(PortManager_test, AcquireServerPortDataWithSameServiceDescriptionTwiceCallsErrorHandlerAndReturnsError)
{
::testing::Test::RecordProperty("TEST_ID", "9f2c24ba-192d-4ce8-a61a-fe40b42c655b");
const ServiceDescription sd{"hyp", "no", "toad"};
const RuntimeName_t runtimeName{"hypnotoad"};
auto serverOptions = createTestServerOptions();

// first call must be successful
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
.or_else([&](const auto& error) {
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
});

iox::cxx::optional<iox::Error> detectedError;
auto errorHandlerGuard =
iox::ErrorHandler::setTemporaryErrorHandler([&](const auto error, const auto, const auto errorLevel) {
EXPECT_THAT(error, Eq(iox::Error::kPOSH__PORT_MANAGER_SERVERPORT_NOT_UNIQUE));
EXPECT_THAT(errorLevel, Eq(iox::ErrorLevel::MODERATE));
detectedError.emplace(error);
});

// second call must fail
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
.and_then([&](const auto&) {
GTEST_FAIL() << "Expected PortPoolError::UNIQUE_SERVER_PORT_ALREADY_EXISTS but got ServerPortData";
})
.or_else([&](const auto& error) { EXPECT_THAT(error, Eq(PortPoolError::UNIQUE_SERVER_PORT_ALREADY_EXISTS)); });

EXPECT_TRUE(detectedError.has_value());
}

TEST_F(PortManager_test, AcquireServerPortDataWithSameServiceDescriptionTwiceAndFirstPortMarkedToBeDestroyedReturnsPort)
{
::testing::Test::RecordProperty("TEST_ID", "d7f2815d-f1ea-403d-9355-69470d92a10f");
const ServiceDescription sd{"hyp", "no", "toad"};
const RuntimeName_t runtimeName{"hypnotoad"};
auto serverOptions = createTestServerOptions();

// first call must be successful
auto serverPortDataResult =
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {});

ASSERT_FALSE(serverPortDataResult.has_error());

serverPortDataResult.value()->m_toBeDestroyed = true;

iox::cxx::optional<iox::Error> detectedError;
auto errorHandlerGuard = iox::ErrorHandler::setTemporaryErrorHandler(
[&](const auto error, const auto, const auto) { detectedError.emplace(error); });

// second call must now also succeed
m_portManager->acquireServerPortData(sd, serverOptions, runtimeName, m_payloadDataSegmentMemoryManager, {})
.or_else([&](const auto& error) {
GTEST_FAIL() << "Expected ClientPortData but got PortPoolError: " << static_cast<uint8_t>(error);
});

detectedError.and_then(
[&](const auto& error) { GTEST_FAIL() << "Expected error handler to not be called but got: " << error; });
}

// END aquireServerPortData tests

} // namespace iox_test_roudi_portmanager
39 changes: 30 additions & 9 deletions iceoryx_posh/test/moduletests/test_roudi_portmanager_fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,29 @@
#include "iceoryx_hoofs/testing/watch_dog.hpp"
#include "iceoryx_posh/iceoryx_posh_types.hpp"
#include "iceoryx_posh/internal/capro/capro_message.hpp"
#include "iceoryx_posh/internal/popo/ports/client_port_user.hpp"
#include "iceoryx_posh/internal/popo/ports/publisher_port_user.hpp"
#include "iceoryx_posh/internal/popo/ports/server_port_user.hpp"
#include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp"
#include "iceoryx_posh/internal/roudi/port_manager.hpp"
#include "iceoryx_posh/popo/client_options.hpp"
#include "iceoryx_posh/popo/server_options.hpp"
#include "iceoryx_posh/roudi/memory/iceoryx_roudi_memory_manager.hpp"

#include "test.hpp"

#include <cstdint>
#include <limits> // std::numeric_limits
#include <limits>

namespace iox_test_roudi_portmanager
{
using namespace ::testing;
using namespace iox;
using namespace iox::capro;
using namespace iox::cxx;
using namespace iox::popo;
using namespace iox::roudi;

using iox::popo::PublisherOptions;
using iox::popo::PublisherPortUser;
using iox::popo::QueueFullPolicy;
using iox::popo::SubscriberOptions;
using iox::popo::SubscriberPortUser;
using iox::roudi::IceOryxRouDiMemoryManager;
using iox::roudi::PortManager;
using iox::roudi::PortPoolError;
using iox::runtime::PortConfigInfo;

class PortManagerTester : public PortManager
Expand All @@ -70,6 +71,8 @@ class PortManager_test : public Test

iox::RuntimeName_t m_runtimeName{"TestApp"};

cxx::GenericRAII suppressLogging = iox::LoggerPosh().SetLogLevelForScope(iox::log::LogLevel::kOff);

void SetUp() override
{
m_instIdCounter = m_sIdCounter = 1U;
Expand Down Expand Up @@ -192,6 +195,24 @@ class PortManager_test : public Test
return SubscriberPortUser(
m_portManager->acquireSubscriberPortData({"1", "1", "1"}, options, "schlomo", PortConfigInfo()).value());
}

ClientPortUser createClient(const ClientOptions& options)
{
const ServiceDescription sd{"1", "1", "1"};
const RuntimeName_t runtimeName{"guiseppe"};
return ClientPortUser(
*m_portManager->acquireClientPortData(sd, options, runtimeName, m_payloadDataSegmentMemoryManager, {})
.value());
}

ServerPortUser createServer(const ServerOptions& options)
{
const ServiceDescription sd{"1", "1", "1"};
const RuntimeName_t runtimeName{"schlomo"};
return ServerPortUser(
*m_portManager->acquireServerPortData(sd, options, runtimeName, m_payloadDataSegmentMemoryManager, {})
.value());
}
};

template <typename vector>
Expand Down

0 comments on commit 609b161

Please sign in to comment.