diff --git a/doc/website/release-notes/iceoryx-unreleased.md b/doc/website/release-notes/iceoryx-unreleased.md index 5746bf579e..90724a4672 100644 --- a/doc/website/release-notes/iceoryx-unreleased.md +++ b/doc/website/release-notes/iceoryx-unreleased.md @@ -60,7 +60,7 @@ - Add support for `iox::string` in `UnixDomainSocket` and created `unix_domain_socket.inl` [#2040](https://github.com/eclipse-iceoryx/iceoryx/issues/2040) - Add support for `iox::string` in `MessageQueue` and created `message_queue.inl` [#1963](https://github.com/eclipse-iceoryx/iceoryx/issues/1963) - Add support for `iox::string` in `NamedPipe` and created `named_pipe.inl` [#1693](https://github.com/eclipse-iceoryx/iceoryx/issues/1693) - +- Add an `iox1` prefix to all resources created by `iceoryx_posh` and `RouDi` [#2185](https://github.com/eclipse-iceoryx/iceoryx/issues/2185) **Bugfixes:** @@ -119,6 +119,7 @@ - Unable to acquire file status due to an unknown failure [#2023](https://github.com/eclipse-iceoryx/iceoryx/issues/2023) - Bug in `ListenerImpl` [#2137](https://github.com/eclipse-iceoryx/iceoryx/issues/2137) - Wrong memory order in `MpmcLoFFLi` fence synchronization [#2196](https://github.com/eclipse-iceoryx/iceoryx/issues/2196) +- Race condition in `PoshRuntime` during shutdown [#2192](https://github.com/eclipse-iceoryx/iceoryx/issues/2192) **Refactoring:** @@ -201,6 +202,7 @@ - Setting IOX_NO_DISCARD in QNX [#638](https://github.com/eclipse-iceoryx/iceoryx/issues/638) - Replace `iox::byte_t` with std::byte [#1900](https://github.com/eclipse-iceoryx/iceoryx/issues/1900) - Merge `iceoryx_dust` back to `iceoryx_hoofs` [#2130](https://github.com/eclipse-iceoryx/iceoryx/issues/2130) +- Activate clang-tidy for all the code in iceoryx_hoofs [#2184](https://github.com/eclipse-iceoryx/iceoryx/issues/2184) **Workflow:** diff --git a/iceoryx_binding_c/test/moduletests/test_runtime.cpp b/iceoryx_binding_c/test/moduletests/test_runtime.cpp index 08b6162c80..fe3479e0ce 100644 --- a/iceoryx_binding_c/test/moduletests/test_runtime.cpp +++ b/iceoryx_binding_c/test/moduletests/test_runtime.cpp @@ -66,14 +66,18 @@ TEST_F(BindingC_Runtime_test, SuccessfulRegistration) TEST_F(BindingC_Runtime_test, RuntimeNameLengthIsMax) { ::testing::Test::RecordProperty("TEST_ID", "854a471d-936e-4c98-b56e-ba8a7d83460e"); - std::string maxName(iox::MAX_RUNTIME_NAME_LENGTH, 's'); + + RuntimeName_t dummy{"a"}; + auto prefixLength = + runtime::ipcChannelNameToInterfaceName(dummy, ResourceType::USER_DEFINED).value().size() - dummy.size(); + std::string maxName(iox::MAX_RUNTIME_NAME_LENGTH - prefixLength, 's'); iox_runtime_init(maxName.c_str()); char actualRuntimeName[iox::MAX_RUNTIME_NAME_LENGTH + 1]; auto nameLength = iox_runtime_get_instance_name(actualRuntimeName, iox::MAX_RUNTIME_NAME_LENGTH + 1); - ASSERT_THAT(nameLength, Eq(iox::MAX_RUNTIME_NAME_LENGTH)); + ASSERT_THAT(nameLength, Eq(iox::MAX_RUNTIME_NAME_LENGTH - prefixLength)); } TEST_F(BindingC_Runtime_test, RuntimeNameLengthIsOutOfLimit) diff --git a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp index 678b9ca929..13ce4067ad 100644 --- a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp +++ b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp @@ -1,6 +1,7 @@ // Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved. // Copyright (c) 2022 by NXP. All rights reserved. +// Copyright (c) 2024 by Mathias Kraus . 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. @@ -20,6 +21,7 @@ #include "iceoryx_platform/platform_settings.hpp" #include "iceoryx_posh/iceoryx_posh_deployment.hpp" +#include "iox/detail/convert.hpp" #include "iox/duration.hpp" #include "iox/function.hpp" #include "iox/log/logstream.hpp" @@ -196,6 +198,22 @@ struct DefaultChunkQueueConfig static constexpr uint64_t MAX_QUEUE_CAPACITY = MAX_SUBSCRIBER_QUEUE_CAPACITY; }; +constexpr const char ICEORYX_RESOURCE_PREFIX[] = "iox1"; + +/// @brief The resource type is used to customize the resource prefix by adding an 'i' or 'u' depending whether the +/// resource is defined by iceoryx, e.g. the roudi IPC channel, or by the user, e.g. the runtime name. This shall +/// prevent the system from being affected by users defining resource names which are intended to be used by iceoryx. +enum class ResourceType +{ + ICEORYX_DEFINED, + USER_DEFINED, +}; + +using ResourcePrefix_t = string<13>; // 'iox1_' + MAX_UINT16_SIZE + '_' + optional 'x_' +/// @brief Returns the prefix string used for resources +/// @param[in] uniqueRouDiID to use for the prefix string +inline ResourcePrefix_t iceoryxResourcePrefix(uint16_t uniqueRouDiID, ResourceType resourceType); + // alias for string using RuntimeName_t = string; using NodeName_t = string; @@ -214,11 +232,11 @@ namespace roudi // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers) using ConfigFilePathString_t = string<1024>; -constexpr const char ROUDI_LOCK_NAME[] = "iox-unique-roudi"; +constexpr const char ROUDI_LOCK_NAME[] = "unique_roudi"; constexpr const char IPC_CHANNEL_ROUDI_NAME[] = "roudi"; /// shared memory segment for the iceoryx management data -constexpr const char SHM_NAME[] = "iceoryx_mgmt"; +constexpr const char SHM_NAME[] = "management"; // this is used by the UniquePortId constexpr uint16_t DEFAULT_UNIQUE_ROUDI_ID{0U}; diff --git a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.inl b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.inl index ecc99eb9d2..f34b7ee854 100644 --- a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.inl +++ b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.inl @@ -1,4 +1,5 @@ // Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2024 by Mathias Kraus . 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. @@ -49,6 +50,19 @@ log::LogStream& operator<<(log::LogStream& stream, ConnectionState value) noexce return stream; } +ResourcePrefix_t iceoryxResourcePrefix(uint16_t uniqueRouDiID, ResourceType resourceType) +{ + static_assert(std::is_same_v>, + "Please adjust 'MAX_UINT16_WIDTH' to the new fixed width type to have enough space for the " + "stringified unique RouDi ID"); + constexpr auto MAX_UINT16_WIDTH{5}; + iox::string uniqueRoudiIdString{TruncateToCapacity, + iox::convert::toString(uniqueRouDiID).c_str()}; + + auto resourceTypeString{resourceType == ResourceType::ICEORYX_DEFINED ? iox::string<1>{"i"} : iox::string<1>{"u"}}; + return concatenate(ICEORYX_RESOURCE_PREFIX, "_", uniqueRoudiIdString, "_", resourceTypeString, "_"); +} + namespace roudi { inline iox::log::LogStream& operator<<(iox::log::LogStream& logstream, const MonitoringMode& mode) noexcept diff --git a/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl b/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl index d14ada215b..270bf8e7a7 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl @@ -1,6 +1,6 @@ // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved. -// Copyright (c) 2023 by Mathias Kraus . All rights reserved. +// Copyright (c) 2023 - 2024 by Mathias Kraus . 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. @@ -23,6 +23,7 @@ #include "iceoryx_posh/mepoo/memory_info.hpp" #include "iceoryx_posh/mepoo/mepoo_config.hpp" #include "iox/bump_allocator.hpp" +#include "iox/detail/convert.hpp" #include "iox/logging.hpp" #include "iox/relative_pointer.hpp" @@ -72,7 +73,21 @@ inline SharedMemoryObjectType MePooSegment ShmName_t::capacity()) + { + IOX_LOG(FATAL, + "The payload segment with the name '" + << writerGroup.getName().size() + << "' would exceed the maximum allowed size when used with the '" << shmName + << "' prefix!"); + IOX_PANIC(""); + } + shmName.append(TruncateToCapacity, writerGroup.getName()); + return shmName; + }()) .memorySizeInBytes(MemoryManager::requiredChunkMemorySize(mempoolConfig)) .accessMode(AccessMode::READ_WRITE) .openMode(OpenMode::PURGE_AND_CREATE) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_base.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_base.hpp index cd6c83b1ed..55ed135465 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_base.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_base.hpp @@ -141,6 +141,12 @@ IpcMessageErrorType stringToIpcMessageErrorType(const char* str) noexcept; /// @param[in] msg enum value to convert std::string IpcMessageErrorTypeToString(const IpcMessageErrorType msg) noexcept; +/// @brief Transforms an IPC channel name to a prefixed interface name +/// @param[in] channelName the name of the channel without the 'iox1_#_' prefix +/// @param[in] resourceType to be used for the resource prefix +/// @return the interface name with the 'iox1_#_' prefix or a 'nullopt' if the resulting name would be too long +iox::optional ipcChannelNameToInterfaceName(RuntimeName_t channelName, ResourceType resourceType); + class IpcInterfaceUser; class IpcInterfaceCreator; @@ -231,7 +237,10 @@ class IpcInterface /// IPC channel needs a unique string to be identified with. IpcInterface() = delete; - IpcInterface(const RuntimeName_t& runtimeName, const uint64_t maxMessages, const uint64_t messageSize) noexcept; + IpcInterface(const RuntimeName_t& runtimeName, + const ResourceType resourceType, + const uint64_t maxMessages, + const uint64_t messageSize) noexcept; /// @brief delete copy and move ctor and assignment since they are not needed IpcInterface(const IpcInterface&) = delete; @@ -263,6 +272,7 @@ class IpcInterface bool hasClosableIpcChannel() const noexcept; protected: + RuntimeName_t m_interfaceName; RuntimeName_t m_runtimeName; uint64_t m_maxMessageSize{0U}; uint64_t m_maxMessages{0U}; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_creator.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_creator.hpp index ceeeb8a1bf..c687f0ed10 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_creator.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_creator.hpp @@ -34,9 +34,11 @@ class IpcInterfaceCreator : public IpcInterfaceBase /// If it fails isInitialized will return false. Therefore, isInitialized /// should always be called before using this class. /// @param[in] name Unique identifier of the IPC channel + /// @param[in] resourceType to be used for the resource prefix /// @param[in] maxMessages maximum number of queued messages /// @param[in] message size maximum message size IpcInterfaceCreator(const RuntimeName_t& name, + const ResourceType resourceType, const uint64_t maxMessages = ROUDI_MAX_MESSAGES, const uint64_t messageSize = ROUDI_MESSAGE_SIZE) noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_user.hpp index e416906c82..0bec2b8062 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/ipc_interface_user.hpp @@ -32,9 +32,11 @@ class IpcInterfaceUser : public IpcInterfaceBase /// Therefore, isInitialized should always be called /// before using this class. /// @param[in] name Unique identifier of the IPC channel + /// @param[in] resourceType to be used for the resource prefix /// @param[in] maxMessages maximum number of queued messages /// @param[in] message size maximum message size IpcInterfaceUser(const RuntimeName_t& name, + const ResourceType resourceType, const uint64_t maxMessages = APP_MAX_MESSAGES, const uint64_t messageSize = APP_MESSAGE_SIZE) noexcept; @@ -52,4 +54,4 @@ class IpcInterfaceUser : public IpcInterfaceBase } // namespace runtime } // namespace iox -#endif // IOX_POSH_RUNTIME_IPC_INTERFACE_USER_HPP \ No newline at end of file +#endif // IOX_POSH_RUNTIME_IPC_INTERFACE_USER_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/posh_runtime_impl.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/posh_runtime_impl.hpp index 840eb4e4bb..ceb5c97813 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/posh_runtime_impl.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/posh_runtime_impl.hpp @@ -22,8 +22,8 @@ #include "iceoryx_posh/runtime/posh_runtime.hpp" #include "iox/detail/periodic_task.hpp" #include "iox/function.hpp" -#include "iox/mutex.hpp" #include "iox/optional.hpp" +#include "iox/smart_lock.hpp" namespace iox { @@ -109,9 +109,7 @@ class PoshRuntimeImpl : public PoshRuntime expected, IpcMessageErrorType> convert_id_and_offset(IpcMessage& msg); - mutable optional m_appIpcRequestMutex; - - IpcRuntimeInterface m_ipcChannelInterface; + concurrent::smart_lock m_ipcChannelInterface; optional m_ShmInterface; optional m_heartbeat; diff --git a/iceoryx_posh/include/iceoryx_posh/roudi/memory/iceoryx_roudi_memory_manager.hpp b/iceoryx_posh/include/iceoryx_posh/roudi/memory/iceoryx_roudi_memory_manager.hpp index cc819f2f7a..9f8ff272c5 100644 --- a/iceoryx_posh/include/iceoryx_posh/roudi/memory/iceoryx_roudi_memory_manager.hpp +++ b/iceoryx_posh/include/iceoryx_posh/roudi/memory/iceoryx_roudi_memory_manager.hpp @@ -62,24 +62,7 @@ class IceOryxRouDiMemoryManager : public RouDiMemoryInterface private: // in order to prevent a second RouDi to cleanup the memory resources of a running RouDi, this resources are // protected by a file lock - FileLock fileLock = - std::move(FileLockBuilder() - .name(ROUDI_LOCK_NAME) - .permission(iox::perms::owner_read | iox::perms::owner_write) - .create() - .or_else([](auto& error) { - if (error == FileLockError::LOCKED_BY_OTHER_PROCESS) - { - IOX_LOG(FATAL, "Could not acquire lock, is RouDi still running?"); - IOX_REPORT_FATAL(PoshError::ICEORYX_ROUDI_MEMORY_MANAGER__ROUDI_STILL_RUNNING); - } - else - { - IOX_LOG(FATAL, "Error occurred while acquiring file lock named " << ROUDI_LOCK_NAME); - IOX_REPORT_FATAL(PoshError::ICEORYX_ROUDI_MEMORY_MANAGER__COULD_NOT_ACQUIRE_FILE_LOCK); - } - }) - .value()); + FileLock m_fileLock; PortPoolMemoryBlock m_portPoolBlock; optional m_portPool; diff --git a/iceoryx_posh/source/roudi/memory/iceoryx_roudi_memory_manager.cpp b/iceoryx_posh/source/roudi/memory/iceoryx_roudi_memory_manager.cpp index 6b81e2b1bb..09ee54a5fb 100644 --- a/iceoryx_posh/source/roudi/memory/iceoryx_roudi_memory_manager.cpp +++ b/iceoryx_posh/source/roudi/memory/iceoryx_roudi_memory_manager.cpp @@ -23,7 +23,26 @@ namespace iox namespace roudi { IceOryxRouDiMemoryManager::IceOryxRouDiMemoryManager(const RouDiConfig_t& roudiConfig) noexcept - : m_defaultMemory(roudiConfig) + : m_fileLock( + std::move(FileLockBuilder() + .name(concatenate(iceoryxResourcePrefix(DEFAULT_UNIQUE_ROUDI_ID, ResourceType::ICEORYX_DEFINED), + ROUDI_LOCK_NAME)) + .permission(iox::perms::owner_read | iox::perms::owner_write) + .create() + .or_else([](auto& error) { + if (error == FileLockError::LOCKED_BY_OTHER_PROCESS) + { + IOX_LOG(FATAL, "Could not acquire lock, is RouDi still running?"); + IOX_REPORT_FATAL(PoshError::ICEORYX_ROUDI_MEMORY_MANAGER__ROUDI_STILL_RUNNING); + } + else + { + IOX_LOG(FATAL, "Error occurred while acquiring file lock named " << ROUDI_LOCK_NAME); + IOX_REPORT_FATAL(PoshError::ICEORYX_ROUDI_MEMORY_MANAGER__COULD_NOT_ACQUIRE_FILE_LOCK); + } + }) + .value())) + , m_defaultMemory(roudiConfig) { m_defaultMemory.m_managementShm.addMemoryBlock(&m_portPoolBlock).or_else([](auto) { IOX_REPORT_FATAL(PoshError::ICEORYX_ROUDI_MEMORY_MANAGER__FAILED_TO_ADD_PORTPOOL_MEMORY_BLOCK); diff --git a/iceoryx_posh/source/roudi/memory/posix_shm_memory_provider.cpp b/iceoryx_posh/source/roudi/memory/posix_shm_memory_provider.cpp index e791596e42..12c4e7214a 100644 --- a/iceoryx_posh/source/roudi/memory/posix_shm_memory_provider.cpp +++ b/iceoryx_posh/source/roudi/memory/posix_shm_memory_provider.cpp @@ -17,6 +17,8 @@ #include "iceoryx_posh/roudi/memory/posix_shm_memory_provider.hpp" +#include "iceoryx_posh/iceoryx_posh_types.hpp" +#include "iox/detail/convert.hpp" #include "iox/detail/system_configuration.hpp" #include "iox/logging.hpp" @@ -55,7 +57,8 @@ expected PosixShmMemoryProvider::createMemory(const } if (!PosixSharedMemoryObjectBuilder() - .name(m_shmName) + .name( + concatenate(iceoryxResourcePrefix(DEFAULT_UNIQUE_ROUDI_ID, ResourceType::ICEORYX_DEFINED), m_shmName)) .memorySizeInBytes(size) .accessMode(m_accessMode) .openMode(m_openMode) diff --git a/iceoryx_posh/source/roudi/process.cpp b/iceoryx_posh/source/roudi/process.cpp index 326adea9c6..f620cc19dd 100644 --- a/iceoryx_posh/source/roudi/process.cpp +++ b/iceoryx_posh/source/roudi/process.cpp @@ -32,7 +32,7 @@ Process::Process(const RuntimeName_t& name, const HeartbeatPoolIndexType heartbeatPoolIndex, const uint64_t sessionId) noexcept : m_pid(pid) - , m_ipcChannel(name) + , m_ipcChannel(name, ResourceType::USER_DEFINED) , m_heartbeatPoolIndex(heartbeatPoolIndex) , m_user(user) , m_sessionId(sessionId) diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index 5960b6160a..ae8c1a30e7 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2019, 2021 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved. -// Copyright (c) 2023 by Mathias Kraus . All rights reserved. +// Copyright (c) 2023 - 2024 by Mathias Kraus . 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. @@ -248,7 +248,7 @@ void RouDi::processRuntimeMessages() noexcept { setThreadName("IPC-msg-process"); - runtime::IpcInterfaceCreator roudiIpcInterface{IPC_CHANNEL_ROUDI_NAME}; + runtime::IpcInterfaceCreator roudiIpcInterface{IPC_CHANNEL_ROUDI_NAME, ResourceType::ICEORYX_DEFINED}; IOX_LOG(INFO, "RouDi is ready for clients"); fflush(stdout); // explicitly flush 'stdout' for 'launch_testing' @@ -289,6 +289,23 @@ void RouDi::processMessage(const runtime::IpcMessage& message, const iox::runtime::IpcMessageType& cmd, const RuntimeName_t& runtimeName) noexcept { + if (runtimeName.empty()) + { + IOX_LOG(ERROR, "Got message with empty runtime name!"); + return; + } + + + for (const auto s : platform::IOX_PATH_SEPARATORS) + { + const char separator[2]{s}; + if (runtimeName.find(separator).has_value()) + { + IOX_LOG(ERROR, "Got message with a runtime name with invalid characters: \"" << runtimeName << "\"!"); + return; + } + } + switch (cmd) { case runtime::IpcMessageType::REG: diff --git a/iceoryx_posh/source/runtime/ipc_interface_base.cpp b/iceoryx_posh/source/runtime/ipc_interface_base.cpp index c07fb8057c..59422c1568 100644 --- a/iceoryx_posh/source/runtime/ipc_interface_base.cpp +++ b/iceoryx_posh/source/runtime/ipc_interface_base.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2019, 2021 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2024 by Mathias Kraus . 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. @@ -77,12 +78,48 @@ std::string IpcMessageErrorTypeToString(const IpcMessageErrorType msg) noexcept return convert::toString(static_cast(msg)); } +iox::optional ipcChannelNameToInterfaceName(RuntimeName_t channelName, ResourceType resourceType) +{ + RuntimeName_t interfaceName = iceoryxResourcePrefix(roudi::DEFAULT_UNIQUE_ROUDI_ID, resourceType); + if (interfaceName.size() + channelName.size() > RuntimeName_t::capacity()) + { + return nullopt; + } + interfaceName.append(TruncateToCapacity, channelName); + return interfaceName; +} + template IpcInterface::IpcInterface(const RuntimeName_t& runtimeName, + const ResourceType resourceType, const uint64_t maxMessages, const uint64_t messageSize) noexcept - : m_runtimeName(runtimeName) { + if (runtimeName.empty()) + { + IOX_PANIC("Then runtime name must not be empty"); + } + for (const auto s : platform::IOX_PATH_SEPARATORS) + { + const char separator[2]{s}; + if (runtimeName.find(separator).has_value()) + { + IOX_LOG(FATAL, "The runtime name '" << runtimeName << "' contains path separators"); + IOX_PANIC("Invalid characters for runtime name"); + } + } + + m_interfaceName = + ipcChannelNameToInterfaceName(runtimeName, resourceType) + .or_else([&runtimeName] { + IOX_LOG(FATAL, + "The runtime with the name '" + << runtimeName + << "' would exceed the maximum allowed size when used with the 'iox1_#_' prefix!"); + IOX_PANIC("The runtime name exceeds the max size"); + }) + .value(); + m_runtimeName = runtimeName; m_maxMessages = maxMessages; m_maxMessageSize = messageSize; if (m_maxMessageSize > platform::IoxIpcChannelType::MAX_MESSAGE_SIZE) @@ -99,7 +136,8 @@ bool IpcInterface::receive(IpcMessage& answer) const noexcept { if (!m_ipcChannel.has_value()) { - IOX_LOG(WARN, "Trying to receive data on an non-initialized IPC interface! Interface name: " << m_runtimeName); + IOX_LOG(WARN, + "Trying to receive data on an non-initialized IPC interface! Interface name: " << m_interfaceName); return false; } @@ -117,7 +155,8 @@ bool IpcInterface::timedReceive(const units::Duration timeout, I { if (!m_ipcChannel.has_value()) { - IOX_LOG(WARN, "Trying to receive data on an non-initialized IPC interface! Interface name: " << m_runtimeName); + IOX_LOG(WARN, + "Trying to receive data on an non-initialized IPC interface! Interface name: " << m_interfaceName); return false; } @@ -146,7 +185,7 @@ bool IpcInterface::send(const IpcMessage& msg) const noexcept { if (!m_ipcChannel.has_value()) { - IOX_LOG(WARN, "Trying to send data on an non-initialized IPC interface! Interface name: " << m_runtimeName); + IOX_LOG(WARN, "Trying to send data on an non-initialized IPC interface! Interface name: " << m_interfaceName); return false; } @@ -173,7 +212,7 @@ bool IpcInterface::timedSend(const IpcMessage& msg, units::Durat { if (!m_ipcChannel.has_value()) { - IOX_LOG(WARN, "Trying to send data on an non-initialized IPC interface! Interface name: " << m_runtimeName); + IOX_LOG(WARN, "Trying to send data on an non-initialized IPC interface! Interface name: " << m_interfaceName); return false; } @@ -214,7 +253,7 @@ bool IpcInterface::openIpcChannel(const PosixIpcChannelSide chan using IpcChannelBuilder_t = typename IpcChannelType::Builder_t; IpcChannelBuilder_t() - .name(m_runtimeName) + .name(m_interfaceName) .channelSide(m_channelSide) .maxMsgSize(m_maxMessageSize) .maxMsgNumber(m_maxMessages) @@ -224,7 +263,7 @@ bool IpcInterface::openIpcChannel(const PosixIpcChannelSide chan if (this->m_channelSide == PosixIpcChannelSide::SERVER) { IOX_LOG(ERROR, - "Unable to create ipc channel '" << this->m_runtimeName + "Unable to create ipc channel '" << this->m_interfaceName << "'. Error code: " << static_cast(err)); } else @@ -233,7 +272,7 @@ bool IpcInterface::openIpcChannel(const PosixIpcChannelSide chan // therefore resulting in a wall of error messages on the console which leads to missing the important // one that roudi is not running if this would be LogLevel::ERROR instead of LogLevel::TRACE IOX_LOG(TRACE, - "Unable to open ipc channel '" << this->m_runtimeName + "Unable to open ipc channel '" << this->m_interfaceName << "'. Error code: " << static_cast(err)); } }); diff --git a/iceoryx_posh/source/runtime/ipc_interface_creator.cpp b/iceoryx_posh/source/runtime/ipc_interface_creator.cpp index 8cfa1c8980..7934ad69d5 100644 --- a/iceoryx_posh/source/runtime/ipc_interface_creator.cpp +++ b/iceoryx_posh/source/runtime/ipc_interface_creator.cpp @@ -24,25 +24,27 @@ namespace iox namespace runtime { IpcInterfaceCreator::IpcInterfaceCreator(const RuntimeName_t& runtimeName, + const ResourceType resourceType, const uint64_t maxMessages, const uint64_t messageSize) noexcept - : IpcInterfaceBase(runtimeName, maxMessages, messageSize) + : IpcInterfaceBase(runtimeName, resourceType, maxMessages, messageSize) , m_fileLock(std::move(FileLockBuilder() - .name(runtimeName) + .name(m_interfaceName) .permission(iox::perms::owner_read | iox::perms::owner_write) .create() - .or_else([&runtimeName](auto& error) { + .or_else([this](auto& error) { if (error == FileLockError::LOCKED_BY_OTHER_PROCESS) { IOX_LOG(FATAL, - "An application with the name " << runtimeName + "An application with the name " << m_runtimeName << " is still running. Using the " "same name twice is not supported."); IOX_REPORT_FATAL(PoshError::IPC_INTERFACE__APP_WITH_SAME_NAME_STILL_RUNNING); } else { - IOX_LOG(FATAL, "Error occurred while acquiring file lock named " << runtimeName); + IOX_LOG(FATAL, + "Error occurred while acquiring file lock named " << m_interfaceName); IOX_REPORT_FATAL(PoshError::IPC_INTERFACE__COULD_NOT_ACQUIRE_FILE_LOCK); } }) @@ -50,7 +52,7 @@ IpcInterfaceCreator::IpcInterfaceCreator(const RuntimeName_t& runtimeName, { // check if the IPC channel is still there (e.g. because of no proper termination // of the process) - cleanupOutdatedIpcChannel(runtimeName); + cleanupOutdatedIpcChannel(m_interfaceName); openIpcChannel(PosixIpcChannelSide::SERVER); } diff --git a/iceoryx_posh/source/runtime/ipc_interface_user.cpp b/iceoryx_posh/source/runtime/ipc_interface_user.cpp index ad53b8dfd2..0ee2924b7c 100644 --- a/iceoryx_posh/source/runtime/ipc_interface_user.cpp +++ b/iceoryx_posh/source/runtime/ipc_interface_user.cpp @@ -22,9 +22,10 @@ namespace iox namespace runtime { IpcInterfaceUser::IpcInterfaceUser(const RuntimeName_t& name, + const ResourceType resourceType, const uint64_t maxMessages, const uint64_t messageSize) noexcept - : IpcInterfaceBase(name, maxMessages, messageSize) + : IpcInterfaceBase(name, resourceType, maxMessages, messageSize) { openIpcChannel(PosixIpcChannelSide::CLIENT); } diff --git a/iceoryx_posh/source/runtime/ipc_runtime_interface.cpp b/iceoryx_posh/source/runtime/ipc_runtime_interface.cpp index cd890c24eb..f352981668 100644 --- a/iceoryx_posh/source/runtime/ipc_runtime_interface.cpp +++ b/iceoryx_posh/source/runtime/ipc_runtime_interface.cpp @@ -34,9 +34,9 @@ IpcRuntimeInterface::IpcRuntimeInterface(const RuntimeName_t& roudiName, const RuntimeName_t& runtimeName, const units::Duration roudiWaitingTimeout) noexcept : m_runtimeName(runtimeName) - , m_RoudiIpcInterface(roudiName) + , m_RoudiIpcInterface(roudiName, ResourceType::ICEORYX_DEFINED) { - m_AppIpcInterface.emplace(runtimeName); + m_AppIpcInterface.emplace(runtimeName, ResourceType::USER_DEFINED); if (!m_AppIpcInterface->isInitialized()) { IOX_REPORT_FATAL(PoshError::IPC_INTERFACE__UNABLE_TO_CREATE_APPLICATION_CHANNEL); diff --git a/iceoryx_posh/source/runtime/posh_runtime_impl.cpp b/iceoryx_posh/source/runtime/posh_runtime_impl.cpp index 7a7e636e4f..2c3600ac88 100644 --- a/iceoryx_posh/source/runtime/posh_runtime_impl.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime_impl.cpp @@ -34,28 +34,27 @@ namespace runtime { PoshRuntimeImpl::PoshRuntimeImpl(optional name, const RuntimeLocation location) noexcept : PoshRuntime(name) - , m_ipcChannelInterface(roudi::IPC_CHANNEL_ROUDI_NAME, *name.value(), runtime::PROCESS_WAITING_FOR_ROUDI_TIMEOUT) + , m_ipcChannelInterface(concurrent::ForwardArgsToCTor, + roudi::IPC_CHANNEL_ROUDI_NAME, + *name.value(), + runtime::PROCESS_WAITING_FOR_ROUDI_TIMEOUT) , m_ShmInterface([&] { // in case the runtime is located in the same process like RouDi the shm is already opened; // also in case of the RouDiEnvironment this would close the shm on destruction of the runstime which is also // not desired + auto ipcInterface = m_ipcChannelInterface.get_scope_guard(); return location == RuntimeLocation::SAME_PROCESS_LIKE_ROUDI ? nullopt - : optional({m_ipcChannelInterface.getShmTopicSize(), - m_ipcChannelInterface.getSegmentId(), - m_ipcChannelInterface.getSegmentManagerAddressOffset()}); + : optional({ipcInterface->getShmTopicSize(), + ipcInterface->getSegmentId(), + ipcInterface->getSegmentManagerAddressOffset()}); }()) { - MutexBuilder() - .isInterProcessCapable(false) - .mutexType(MutexType::NORMAL) - .create(m_appIpcRequestMutex) - .expect("Failed to create Mutex"); - - auto heartbeatAddressOffset = m_ipcChannelInterface.getHeartbeatAddressOffset(); + auto ipcInterface = m_ipcChannelInterface.get_scope_guard(); + auto heartbeatAddressOffset = ipcInterface->getHeartbeatAddressOffset(); if (heartbeatAddressOffset.has_value()) { - m_heartbeat = RelativePointer::getPtr(segment_id_t{m_ipcChannelInterface.getSegmentId()}, + m_heartbeat = RelativePointer::getPtr(segment_id_t{ipcInterface->getSegmentId()}, heartbeatAddressOffset.value()); } @@ -74,7 +73,7 @@ PoshRuntimeImpl::~PoshRuntimeImpl() noexcept sendBuffer << IpcMessageTypeToString(IpcMessageType::TERMINATION) << m_appName; IpcMessage receiveBuffer; - if (m_ipcChannelInterface.sendRequestToRouDi(sendBuffer, receiveBuffer) + if (m_ipcChannelInterface->sendRequestToRouDi(sendBuffer, receiveBuffer) && (1U == receiveBuffer.getNumberOfElements())) { std::string IpcMessage = receiveBuffer.getElementAtIndex(0U); @@ -718,9 +717,7 @@ popo::ConditionVariableData* PoshRuntimeImpl::getMiddlewareConditionVariable() n bool PoshRuntimeImpl::sendRequestToRouDi(const IpcMessage& msg, IpcMessage& answer) noexcept { - // runtime must be thread safe - std::lock_guard g(m_appIpcRequestMutex.value()); - return m_ipcChannelInterface.sendRequestToRouDi(msg, answer); + return m_ipcChannelInterface->sendRequestToRouDi(msg, answer); } // this is the callback for the m_keepAliveTimer @@ -739,7 +736,7 @@ void PoshRuntimeImpl::sendKeepAliveAndHandleShutdownPreparation() noexcept sendBuffer << IpcMessageTypeToString(IpcMessageType::PREPARE_APP_TERMINATION) << m_appName; IpcMessage receiveBuffer; - if (m_ipcChannelInterface.sendRequestToRouDi(sendBuffer, receiveBuffer) + if (m_ipcChannelInterface->sendRequestToRouDi(sendBuffer, receiveBuffer) && (1U == receiveBuffer.getNumberOfElements())) { std::string IpcMessage = receiveBuffer.getElementAtIndex(0U); diff --git a/iceoryx_posh/source/runtime/shared_memory_user.cpp b/iceoryx_posh/source/runtime/shared_memory_user.cpp index 82bc8c6c06..f148c51ea2 100644 --- a/iceoryx_posh/source/runtime/shared_memory_user.cpp +++ b/iceoryx_posh/source/runtime/shared_memory_user.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2024 by Mathias Kraus . 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. @@ -18,6 +19,7 @@ #include "iceoryx_posh/internal/runtime/shared_memory_user.hpp" #include "iceoryx_posh/internal/mepoo/segment_manager.hpp" #include "iceoryx_posh/internal/posh_error_reporting.hpp" +#include "iox/detail/convert.hpp" #include "iox/logging.hpp" #include "iox/posix_user.hpp" @@ -32,7 +34,8 @@ SharedMemoryUser::SharedMemoryUser(const size_t topicSize, const UntypedRelativePointer::offset_t segmentManagerAddressOffset) noexcept { PosixSharedMemoryObjectBuilder() - .name(roudi::SHM_NAME) + .name(concatenate(iceoryxResourcePrefix(roudi::DEFAULT_UNIQUE_ROUDI_ID, ResourceType::ICEORYX_DEFINED), + roudi::SHM_NAME)) .memorySizeInBytes(topicSize) .accessMode(AccessMode::READ_WRITE) .openMode(OpenMode::OPEN_EXISTING) @@ -73,7 +76,21 @@ void SharedMemoryUser::openDataSegments(const uint64_t segmentId, { auto accessMode = segment.m_isWritable ? AccessMode::READ_WRITE : AccessMode::READ_ONLY; PosixSharedMemoryObjectBuilder() - .name(segment.m_sharedMemoryName) + .name([&segment] { + using ShmName_t = detail::PosixSharedMemory::Name_t; + ShmName_t shmName = iceoryxResourcePrefix(roudi::DEFAULT_UNIQUE_ROUDI_ID, ResourceType::USER_DEFINED); + if (shmName.size() + segment.m_sharedMemoryName.size() > ShmName_t::capacity()) + { + IOX_LOG(FATAL, + "The payload segment with the name '" + << segment.m_sharedMemoryName.size() + << "' would exceed the maximum allowed size when used with the '" << shmName + << "' prefix!"); + IOX_PANIC(""); + } + shmName.append(TruncateToCapacity, segment.m_sharedMemoryName); + return shmName; + }()) .memorySizeInBytes(segment.m_size) .accessMode(accessMode) .openMode(OpenMode::OPEN_EXISTING) diff --git a/iceoryx_posh/test/integrationtests/test_mq_interface_startup_race.cpp b/iceoryx_posh/test/integrationtests/test_mq_interface_startup_race.cpp index 0358f87ab7..b068dac32f 100644 --- a/iceoryx_posh/test/integrationtests/test_mq_interface_startup_race.cpp +++ b/iceoryx_posh/test/integrationtests/test_mq_interface_startup_race.cpp @@ -61,7 +61,7 @@ class CMqInterfaceStartupRace_test : public Test virtual void SetUp() { platform::IoxIpcChannelType::Builder_t() - .name(roudi::IPC_CHANNEL_ROUDI_NAME) + .name(m_roudiIpcChannelName) .channelSide(PosixIpcChannelSide::SERVER) .create() .and_then([this](auto& channel) { this->m_roudiQueue.emplace(std::move(channel)); }); @@ -105,7 +105,8 @@ class CMqInterfaceStartupRace_test : public Test if (!m_appQueue.has_value()) { platform::IoxIpcChannelType::Builder_t() - .name(MqAppName) + .name(runtime::ipcChannelNameToInterfaceName(MqAppName, ResourceType::USER_DEFINED) + .expect("valid interface name")) .channelSide(PosixIpcChannelSide::CLIENT) .create() .and_then([this](auto& channel) { this->m_appQueue.emplace(std::move(channel)); }); @@ -120,6 +121,9 @@ class CMqInterfaceStartupRace_test : public Test optional m_roudiQueue; std::mutex m_appQueueMutex; optional m_appQueue; + RuntimeName_t m_roudiIpcChannelName{ + runtime::ipcChannelNameToInterfaceName(roudi::IPC_CHANNEL_ROUDI_NAME, ResourceType::ICEORYX_DEFINED) + .expect("valid interface name")}; }; #if !defined(__APPLE__) @@ -150,7 +154,7 @@ TEST_F(CMqInterfaceStartupRace_test, ObsoleteRouDiMq) }); auto m_roudiQueue2 = platform::IoxIpcChannelType::Builder_t() - .name(roudi::IPC_CHANNEL_ROUDI_NAME) + .name(m_roudiIpcChannelName) .channelSide(PosixIpcChannelSide::SERVER) .create(); @@ -202,7 +206,7 @@ TEST_F(CMqInterfaceStartupRace_test, ObsoleteRouDiMqWithFullMq) }); auto newRoudi = platform::IoxIpcChannelType::Builder_t() - .name(roudi::IPC_CHANNEL_ROUDI_NAME) + .name(m_roudiIpcChannelName) .channelSide(PosixIpcChannelSide::SERVER) .create(); diff --git a/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp b/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp index 2d7ad28ff4..1569c3ca3d 100644 --- a/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp +++ b/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp @@ -154,14 +154,17 @@ TEST_F(MePooSegment_test, SharedMemoryCreationParameter) ::testing::Test::RecordProperty("TEST_ID", "0fcfefd4-3a84-43a5-9805-057a60239184"); GTEST_SKIP_FOR_ADDITIONAL_USER() << "This test requires the -DTEST_WITH_ADDITIONAL_USER=ON cmake argument"; - MePooSegment_test::SharedMemoryObject_MOCK::createVerificator = [](const detail::PosixSharedMemory::Name_t f_name, + MePooSegment_test::SharedMemoryObject_MOCK::createVerificator = [](const detail::PosixSharedMemory::Name_t name, const uint64_t, - const iox::AccessMode f_accessMode, + const iox::AccessMode accessMode, const iox::OpenMode openMode, const void*, const iox::access_rights) { - EXPECT_THAT(f_name, Eq(detail::PosixSharedMemory::Name_t("iox_roudi_test2"))); - EXPECT_THAT(f_accessMode, Eq(iox::AccessMode::READ_WRITE)); + EXPECT_THAT(name, + Eq(detail::PosixSharedMemory::Name_t( + concatenate(iceoryxResourcePrefix(roudi::DEFAULT_UNIQUE_ROUDI_ID, ResourceType::USER_DEFINED), + "iox_roudi_test2")))); + EXPECT_THAT(accessMode, Eq(iox::AccessMode::READ_WRITE)); EXPECT_THAT(openMode, Eq(iox::OpenMode::PURGE_AND_CREATE)); }; SUT sut{mepooConfig, m_managementAllocator, PosixGroup{"iox_roudi_test1"}, PosixGroup{"iox_roudi_test2"}}; diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 6ca838a509..e8521196cf 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -128,7 +128,10 @@ TEST_F(PoshRuntime_test, ValidAppName) TEST_F(PoshRuntime_test, MaxAppNameLength) { ::testing::Test::RecordProperty("TEST_ID", "dfdf3ce1-c7d4-4c57-94ea-6ed9479371e3"); - std::string maxValidName(iox::MAX_RUNTIME_NAME_LENGTH, 's'); + RuntimeName_t dummy{"a"}; + auto prefixLength = + runtime::ipcChannelNameToInterfaceName(dummy, ResourceType::USER_DEFINED).value().size() - dummy.size(); + std::string maxValidName(iox::MAX_RUNTIME_NAME_LENGTH - prefixLength, 's'); auto& runtime = PoshRuntime::initRuntime(into>(maxValidName)); diff --git a/iceoryx_posh/test/moduletests/test_posh_types.cpp b/iceoryx_posh/test/moduletests/test_posh_types.cpp new file mode 100644 index 0000000000..0bb1fb9dbc --- /dev/null +++ b/iceoryx_posh/test/moduletests/test_posh_types.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2024 by Mathias Kraus . 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 "iceoryx_posh/iceoryx_posh_types.hpp" + +#include "test.hpp" + +using namespace ::testing; +using namespace iox; + +TEST(PoshTypes_test, IceoryxResourcePrefixWithDefaultRouDiIdWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "35f1d638-8efa-41dd-859b-bcc23450844f"); + + EXPECT_THAT(iceoryxResourcePrefix(roudi::DEFAULT_UNIQUE_ROUDI_ID, ResourceType::ICEORYX_DEFINED).c_str(), + StrEq("iox1_0_i_")); +} + +TEST(PoshTypes_test, IceoryxResourcePrefixWithMaxRouDiIdWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "049e79d7-d0ca-4951-8d44-c80aebab7a88"); + + EXPECT_THAT(iceoryxResourcePrefix(std::numeric_limits::max(), ResourceType::ICEORYX_DEFINED).c_str(), + StrEq("iox1_65535_i_")); +} + +TEST(PoshTypes_test, IceoryxResourcePrefixWithMaxRouDiIdAndUserDefinedResourceTypeWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "b63bbdca-ff19-41bc-9f8a-c657b0ee8009"); + + EXPECT_THAT(iceoryxResourcePrefix(std::numeric_limits::max(), ResourceType::USER_DEFINED).c_str(), + StrEq("iox1_65535_u_")); +} diff --git a/iceoryx_posh/test/moduletests/test_roudi_posix_shm_memory_provider.cpp b/iceoryx_posh/test/moduletests/test_roudi_posix_shm_memory_provider.cpp index 7133c96bbd..18aceded0e 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_posix_shm_memory_provider.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_posix_shm_memory_provider.cpp @@ -27,6 +27,7 @@ namespace { using namespace ::testing; +using namespace iox; using namespace iox::roudi; using iox::ShmName_t; @@ -48,7 +49,8 @@ class PosixShmMemoryProvider_Test : public Test bool shmExists() { return !iox::PosixSharedMemoryObjectBuilder() - .name(TEST_SHM_NAME) + .name(concatenate(iceoryxResourcePrefix(DEFAULT_UNIQUE_ROUDI_ID, ResourceType::ICEORYX_DEFINED), + TEST_SHM_NAME)) .memorySizeInBytes(8) .accessMode(iox::AccessMode::READ_ONLY) .openMode(iox::OpenMode::OPEN_EXISTING) diff --git a/iceoryx_posh/test/moduletests/test_roudi_process_manager.cpp b/iceoryx_posh/test/moduletests/test_roudi_process_manager.cpp index 29e0267ba0..a697f2d7d5 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_process_manager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_process_manager.cpp @@ -61,7 +61,7 @@ class ProcessManager_test : public Test const bool m_isMonitored{true}; VersionInfo m_versionInfo{42U, 42U, 42U, 42U, "Foo", "Bar"}; - IpcInterfaceCreator m_processIpcInterface{m_processname}; + IpcInterfaceCreator m_processIpcInterface{m_processname, ResourceType::USER_DEFINED}; ProcessIntrospectionType m_processIntrospection; std::unique_ptr m_roudiMemoryManager{nullptr}; diff --git a/iceoryx_posh/test/moduletests/test_runtime_ipc_interface.cpp b/iceoryx_posh/test/moduletests/test_runtime_ipc_interface.cpp index 6c913144ac..1673008761 100644 --- a/iceoryx_posh/test/moduletests/test_runtime_ipc_interface.cpp +++ b/iceoryx_posh/test/moduletests/test_runtime_ipc_interface.cpp @@ -20,8 +20,10 @@ #include "iox/message_queue.hpp" #include "iox/named_pipe.hpp" #include "iox/std_chrono_support.hpp" +#include "iox/std_string_support.hpp" #include "iox/unix_domain_socket.hpp" +#include "iceoryx_hoofs/testing/fatal_failure.hpp" #include "test.hpp" #include @@ -30,6 +32,7 @@ namespace { using namespace ::testing; using namespace iox; +using namespace iox::testing; using namespace iox::units::duration_literals; #if defined(__APPLE__) @@ -66,7 +69,7 @@ class IpcInterface_test : public Test SutType(const RuntimeName_t& runtimeName, const uint64_t maxMessages = MaxMsgNumber, const uint64_t messageSize = MaxMsgSize) noexcept - : IpcChannelType(runtimeName, maxMessages, messageSize) + : IpcChannelType(runtimeName, ResourceType::USER_DEFINED, maxMessages, messageSize) { } using IpcChannelType::ipcChannelMapsToFile; @@ -113,21 +116,27 @@ TYPED_TEST(IpcInterface_test, CreateWithTooLargeMessageSizeWillBeClampedToMaxMes EXPECT_TRUE(sut.isInitialized()); } -TYPED_TEST(IpcInterface_test, CreateNoNameLeadsToError) +TYPED_TEST(IpcInterface_test, CreateWithNoNameFails) { ::testing::Test::RecordProperty("TEST_ID", "3ffe2cf2-26f4-4b93-8baf-d997dc71e610"); - typename TestFixture::SutType sut(""); - EXPECT_FALSE(sut.openIpcChannel(PosixIpcChannelSide::SERVER)); - EXPECT_FALSE(sut.isInitialized()); + + IOX_EXPECT_FATAL_FAILURE([] { typename TestFixture::SutType sut(""); }, iox::er::FATAL); +} + +TYPED_TEST(IpcInterface_test, CreateWithTooLargeNameFails) +{ + ::testing::Test::RecordProperty("TEST_ID", "1463137c-ce3c-4a09-a568-f71ad10b558a"); + + auto tooLargeName = into>(std::string(iox::MAX_RUNTIME_NAME_LENGTH, 's')); + + IOX_EXPECT_FATAL_FAILURE([&] { typename TestFixture::SutType sut(tooLargeName); }, iox::er::FATAL); } -TYPED_TEST(IpcInterface_test, CreateWithLeadingSlashWorks) +TYPED_TEST(IpcInterface_test, CreateWithLeadingSlashFails) { ::testing::Test::RecordProperty("TEST_ID", "89340ebd-f80d-480b-833f-da37dff06cef"); - typename TestFixture::SutType sut(slashName); - EXPECT_TRUE(sut.openIpcChannel(PosixIpcChannelSide::SERVER)); - EXPECT_TRUE(sut.isInitialized()); + IOX_EXPECT_FATAL_FAILURE([] { typename TestFixture::SutType sut(slashName); }, iox::er::FATAL); } TYPED_TEST(IpcInterface_test, CreateAgainWorks) diff --git a/iceoryx_posh/test/moduletests/test_runtime_ipc_interface_creator.cpp b/iceoryx_posh/test/moduletests/test_runtime_ipc_interface_creator.cpp index 6697ead567..cc154fff25 100644 --- a/iceoryx_posh/test/moduletests/test_runtime_ipc_interface_creator.cpp +++ b/iceoryx_posh/test/moduletests/test_runtime_ipc_interface_creator.cpp @@ -59,8 +59,8 @@ class IpcInterfaceCreator_test : public Test TEST_F(IpcInterfaceCreator_test, CreateWithDifferentNameWorks) { ::testing::Test::RecordProperty("TEST_ID", "4fc22f1f-1333-41a1-8709-4b1ca791a2e1"); - IpcInterfaceCreator m_sut{goodName}; - IpcInterfaceCreator m_sut2{anotherGoodName}; + IpcInterfaceCreator m_sut{goodName, ResourceType::USER_DEFINED}; + IpcInterfaceCreator m_sut2{anotherGoodName, ResourceType::USER_DEFINED}; EXPECT_TRUE(m_sut.isInitialized()); EXPECT_TRUE(m_sut2.isInitialized()); } @@ -68,10 +68,13 @@ TEST_F(IpcInterfaceCreator_test, CreateWithDifferentNameWorks) TEST_F(IpcInterfaceCreator_test, CreateWithSameNameLeadsToError) { ::testing::Test::RecordProperty("TEST_ID", "2e8c15c8-1b7b-465b-aae5-6db24fc3c34a"); - IpcInterfaceCreator m_sut{goodName}; + IpcInterfaceCreator m_sut{goodName, ResourceType::USER_DEFINED}; - IOX_EXPECT_FATAL_FAILURE([&] { IpcInterfaceCreator m_sut2{goodName}; }, - iox::PoshError::IPC_INTERFACE__APP_WITH_SAME_NAME_STILL_RUNNING); + IOX_EXPECT_FATAL_FAILURE( + [&] { + IpcInterfaceCreator m_sut2{goodName, ResourceType::USER_DEFINED}; + }, + iox::PoshError::IPC_INTERFACE__APP_WITH_SAME_NAME_STILL_RUNNING); } } // namespace