diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index dbaf84ade2..df3807c43b 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -73,8 +73,8 @@ jobs: - name: Build tests run: $GITHUB_WORKSPACE/tools/iceoryx_build_test.sh build-test - # - name: Run tests - # run: | - # cd $GITHUB_WORKSPACE/build - # ../tools/run_all_tests.sh + - name: Run tests + run: | + cd $GITHUB_WORKSPACE/build + ../tools/run_all_tests.sh disable-timing-tests diff --git a/README.md b/README.md index 559b22f7db..2588bad199 100644 --- a/README.md +++ b/README.md @@ -75,24 +75,33 @@ the interwebs on a lonely evening, he finds out about iceoryx: Free-to-use, high runtime overhead, real-time support! Brilliant! Maybe even Robby's biggest wish for a network binding will come true, so he can stream his favorite [video](https://www.youtube.com/watch?v=g5NkgZXWl0w) even faster! -## Download +## Installation - +#### Mac OS -### Development +Before installing iceoryx you need a XCode installation, git and optional an installed ncurses library for +the introspection client. To install ncurses locally into your build folder follow these steps +``` +cd iceoryx +ICEORYX_DIR=$PWD +mkdir -p build +cd build +git clone https://github.com/mirror/ncurses.git +cd ncurses +git checkout v6.2 +./configure --prefix=$ICEORYX_DIR/build/dependencies/ --exec-prefix=$ICEORYX_DIR/build/dependencies/ --with-termlib +make -j12 +make install +``` -Great that you want start developing iceoryx! In order to get started please consider the next sections. +If you would like to use our Cyclone DDS Gateway you have to install Cyclone DDS first, see +[https://github.com/eclipse-cyclonedds/cyclonedds](https://github.com/eclipse-cyclonedds/cyclonedds). -#### Prerequisites +#### Linux Although we strive to be fully POSIX-compliant, we recommend using Ubuntu 18.04 and at least GCC 7.4.0 for development. @@ -103,40 +112,66 @@ You will need to install the following packages: Additionally, there is an optional dependency to the MIT licensed cpptoml library, which is used to parse a RouDi config file for the mempool config. [cpptoml](https://github.com/skystrife/cpptoml) -#### Build from sources - -iceoryx_utils and iceoryx_posh are deployed as independent cmake packages. Posh is using some functions from utils and is depending on it. You are able to build posh and utils and integrate in into existing cmake projects. +### Build with CMake (all supported platforms) -##### Build Script -For the first start, we advise to use our build-test script for building everything. +**NOTE:** Requires CMake version 3.14 or higher. If you only have CMake version 3.5 or higher available please use the +build script. +The `CMakeLists.txt` from `iceoryx_meta` can be used to easily develop iceoryx with an IDE. + + 1. Clone the repository + ``` git clone https://github.com/eclipse/iceoryx.git - ./tools/iceoryx_build_test.sh - -In default-mode, the script is not building the provided test. For a clean build just add "clean" as first argument to the script. - -If the script is not used, keep in mind to pass `-DTOML_CONFIG=on` to cmake if the optional RouDi config file feature shall be built. - -**NOTE:** Users who wish to build iceoryx with cmake can follow the below steps (Requires CMake 3.14 or higher). - -* Step into root folder of iceoryx. - -* Execute the below commands. - -``` -iceoryx$ cmake -Bbuild -Hiceoryx_meta // Customisation possible with cmake switches -iceoryx$ cmake --build build -``` - -#### Build with tests - -To build iceoryx with tests, just add "test" as first argument to the script. + ``` + + 2. Generate the necessary build files + ```bash + cd iceoryx + cmake -Bbuild -Hiceoryx_meta -DTOML_CONFIG=ON + # when you have installed external dependencies like ncurses you have to add them + # to your prefix path + cmake -Bbuild -Hiceoryx_meta -DTOML_CONFIG=ON -DCMAKE_PREFIX_PATH=$(PWD)/build/dependencies/ + ``` + ``` + 3. Compile the source code + ``` + cmake --build build + ``` + +With the following CMake switches you can add additional features: + + | switch | description | + |:---------|:-------------| + | ```dds``` | builds the iceoryx dds gateway which requires an installed CycloneDDS, see [https://github.com/eclipse-cyclonedds/cyclonedds](https://github.com/eclipse-cyclonedds/cyclonedds) | + | ```examples``` | builds all examples | + | ```introspection``` | the console introspection client which requires an installed ncurses library with terminfo support | + | ```test``` | enables module-, integration- and component-tests | + | ```TOML_CONFIG``` | activates config file support by using toml, if this is deactivated the central broker ```RouDi``` is not being build | + +### Build with the build script (only Linux and QNX) + +As an alternative we provide our build-test script which we use to integrate +iceoryx into our infrastructure. + + 1. Clone the repository + ``` + git clone https://github.com/eclipse/iceoryx.git + ``` - ./tools/iceoryx_build_test.sh test + 2. Build everything + ``` + cd iceoryx + ./tools/iceoryx_build_test.sh + ``` -The Googletest-Framework will be automatically fetched from github and the test will be executed and the end of the script. +With the following arguments you can add additional features: + + | switch | description | + |:---------|:-------------| + | ```clean``` | Removes the build directory and performs a clean build. If you have installed ncurses locally into your build directory you have to reinstall it first. | + | ```test``` | Enables module-, integration- and component-tests. The Googletest-Framework will be automatically fetched from github and the test will be executed and the end of the script. | -##### Build with colcon +### Build with colcon Alternatively, iceoryx can be built with [colcon](https://colcon.readthedocs.io/en/released/user/installation.html) to provide a smooth integration for ROS2 developers. @@ -152,7 +187,7 @@ This build method makes the most sense in combination with [rmw_iceoryx](https:/ Congrats! You've build all the necessary things to continue playing around with the examples. -##### Build and run in a Docker environment +### Build and run in a Docker environment If you want to avoid installing anything on your host machine but you have Docker installed, it is possible to use it to build and run iceoryx applications. diff --git a/cmake/cpptoml/CMakeLists.txt b/cmake/cpptoml/CMakeLists.txt index 56eacfadaf..025829a473 100644 --- a/cmake/cpptoml/CMakeLists.txt +++ b/cmake/cpptoml/CMakeLists.txt @@ -1,11 +1,17 @@ cmake_minimum_required(VERSION 3.5) project(cpptoml-build CXX) +if(WIN32) + set(CREATE_PATH_COMMAND mkdir) +else() + set(CREATE_PATH_COMMAND mkdir -p) +endif(WIN32) + # set download config, source and build paths -set(DOWNLOAD_CONFIG_DIR ${CMAKE_BINARY_DIR}/cpptoml-download) -set(SOURCE_DIR ${CMAKE_BINARY_DIR}/cpptoml-src) -set(BUILD_DIR ${CMAKE_BINARY_DIR}/cpptoml-build) -set(INSTALL_DIR ${CMAKE_INSTALL_PREFIX}) +set(DOWNLOAD_CONFIG_DIR ${CMAKE_BINARY_DIR}/dependencies/cpptoml/download) +set(SOURCE_DIR ${CMAKE_BINARY_DIR}/dependencies/cpptoml/src) +set(BUILD_DIR ${CMAKE_BINARY_DIR}/dependencies/cpptoml/build) +set(INSTALL_DIR ${CMAKE_BINARY_DIR}/dependencies/install) # Download and unpack cpptoml at configure time configure_file(cpptoml.cmake.in ${DOWNLOAD_CONFIG_DIR}/CMakeLists.txt) @@ -23,7 +29,7 @@ if(result) message(FATAL_ERROR "Build step [download] for cpptoml failed: ${result}") endif() -execute_process(COMMAND mkdir -p "${BUILD_DIR}" +execute_process(COMMAND ${CREATE_PATH_COMMAND} "${BUILD_DIR}" RESULT_VARIABLE result WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) if(result) diff --git a/cmake/cpptoml/cpptoml.cmake.in b/cmake/cpptoml/cpptoml.cmake.in index 75201ec7a2..ea8986a3e6 100644 --- a/cmake/cpptoml/cpptoml.cmake.in +++ b/cmake/cpptoml/cpptoml.cmake.in @@ -6,8 +6,8 @@ include(ExternalProject) ExternalProject_Add(ext_cpptoml GIT_REPOSITORY https://github.com/skystrife/cpptoml.git GIT_TAG v0.1.1 - SOURCE_DIR "${CMAKE_BINARY_DIR}/cpptoml-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/cpptoml-build" + SOURCE_DIR "${CMAKE_BINARY_DIR}/dependencies/cpptoml/src" + BINARY_DIR "${CMAKE_BINARY_DIR}/dependencies/cpptoml/build" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/cmake/googletest/CMakeLists.txt b/cmake/googletest/CMakeLists.txt index e260f6495f..5d4830d630 100644 --- a/cmake/googletest/CMakeLists.txt +++ b/cmake/googletest/CMakeLists.txt @@ -4,13 +4,16 @@ project(googletest-build CXX) if(test) if(WIN32) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + set(CREATE_PATH_COMMAND mkdir) + else() + set(CREATE_PATH_COMMAND mkdir -p) endif(WIN32) # set download confi, source and build paths - set(DOWNLOAD_CONFIG_DIR ${CMAKE_BINARY_DIR}/googletest-download) - set(SOURCE_DIR ${CMAKE_BINARY_DIR}/googletest-src) - set(BUILD_DIR ${CMAKE_BINARY_DIR}/googletest-build) - set(INSTALL_DIR ${CMAKE_INSTALL_PREFIX}) + set(DOWNLOAD_CONFIG_DIR ${CMAKE_BINARY_DIR}/dependencies/googletest/download) + set(SOURCE_DIR ${CMAKE_BINARY_DIR}/dependencies/googletest/src) + set(BUILD_DIR ${CMAKE_BINARY_DIR}/dependencies/googletest/build) + set(INSTALL_DIR ${CMAKE_BINARY_DIR}/dependencies/install) # Download and unpack googletest at configure time configure_file(googletest.cmake.in ${DOWNLOAD_CONFIG_DIR}/CMakeLists.txt) @@ -28,7 +31,7 @@ if(test) message(FATAL_ERROR "Build step [download] for googletest failed: ${result}") endif() - execute_process(COMMAND mkdir -p "${BUILD_DIR}" + execute_process(COMMAND ${CREATE_PATH_COMMAND} "${BUILD_DIR}" RESULT_VARIABLE result WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) if(result) diff --git a/cmake/googletest/googletest.cmake.in b/cmake/googletest/googletest.cmake.in index e402f918d5..368ddccab0 100644 --- a/cmake/googletest/googletest.cmake.in +++ b/cmake/googletest/googletest.cmake.in @@ -7,8 +7,8 @@ if(WIN32) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.10.0 - SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" + SOURCE_DIR "${CMAKE_BINARY_DIR}/dependencies/googletest/src" + BINARY_DIR "${CMAKE_BINARY_DIR}/dependencies/googletest/build" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" @@ -18,8 +18,8 @@ else() ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.1 - SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" + SOURCE_DIR "${CMAKE_BINARY_DIR}/dependencies/googletest/src" + BINARY_DIR "${CMAKE_BINARY_DIR}/dependencies/googletest/build" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/iceoryx_dds/COLCON_IGNORE b/iceoryx_dds/COLCON_IGNORE new file mode 100644 index 0000000000..e69de29bb2 diff --git a/iceoryx_meta/CMakeLists.txt b/iceoryx_meta/CMakeLists.txt index 91e58133b5..573ab9588e 100644 --- a/iceoryx_meta/CMakeLists.txt +++ b/iceoryx_meta/CMakeLists.txt @@ -1,53 +1,38 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.5) file (STRINGS "../VERSION" iceoryx_VERSION) project(iceoryx VERSION ${iceoryx_VERSION}) -#uncomment this as soon the ExternalProject install path issue is solved -#if(test) -# add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/googletest ${CMAKE_BINARY_DIR}/gtest) -#endif(test) +option(TOML_CONFIG "activates or deactivates TOML support - without TOML RouDi will not be build" ON) +option(test "Build tests" ON) +option(examples "build with iceoryx examples" ON) +option(introspection "builds the introspection client which requires the ncurses library with an activated terminfo feature" OFF) +option(diagnostic "enables allmost all compiler warnings" OFF) +option(dds "enables dds support by compiling the iceoryx dds gateway" OFF) +if(TOML_CONFIG) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/cpptoml/ ${CMAKE_BINARY_DIR}/dependencies/cpptoml/prebuild) +endif(TOML_CONFIG) -include(FetchContent) +if(diagnostic) + add_compile_options(-Wall -W -Wextra -pedantic) +endif(diagnostic) -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) if(test) -FetchContent_Declare( - GOOGLETEST - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.10.0 -) -FetchContent_GetProperties(GOOGLETEST) -if (NOT googletest_POPULATED) - message(STATUS "updating: googletest" ) - FetchContent_Populate(GOOGLETEST) - add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) - set(GTest_FOUND true) - add_library(GTest::gtest ALIAS gtest) - add_library(GTest::gmock ALIAS gmock) -endif(NOT googletest_POPULATED) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/googletest ${CMAKE_BINARY_DIR}/dependencies/googletest/prebuild) endif(test) -# must be additionally defined here, otherwise TOML_CONFIG is on default off -# and the module is loaded only after the second cmake -Bbuild -Hiceoryx_meta command call -option(TOML_CONFIG "activates or deactivates TOML support - without TOML RouDi will not be build" ON) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_utils ${CMAKE_BINARY_DIR}/utils) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_posh ${CMAKE_BINARY_DIR}/posh) -if (TOML_CONFIG ) - FetchContent_Declare( - CPPTOML - GIT_REPOSITORY https://github.com/skystrife/cpptoml - GIT_TAG v0.1.1 - ) - FetchContent_GetProperties(CPPTOML) - if (NOT cpptoml_POPULATED) - message(STATUS "updating: cpptoml" ) - FetchContent_Populate(CPPTOML) - add_subdirectory(${cpptoml_SOURCE_DIR} ${cpptoml_BINARY_DIR}) - set(cpptoml_FOUND true) - endif(NOT cpptoml_POPULATED) -endif(TOML_CONFIG) +if(introspection) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../tools/introspection ${CMAKE_BINARY_DIR}/iceoryx_introspection) +endif(introspection) + +if(examples) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/icedelivery ${CMAKE_BINARY_DIR}/iceoryx_examples/icedelivery) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/iceperf ${CMAKE_BINARY_DIR}/iceoryx_examples/iceperf) +endif(examples) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_utils ${CMAKE_BINARY_DIR}/iceoryx_utils ) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_posh ${CMAKE_BINARY_DIR}/iceoryx_posh ) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/icedelivery ${CMAKE_BINARY_DIR}/examples/icedelivery ) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/iceperf ${CMAKE_BINARY_DIR}/examples/iceperf ) +if(dds) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_dds ${CMAKE_BINARY_DIR}/iceoryx_dds) +endif(dds) diff --git a/iceoryx_posh/CMakeLists.txt b/iceoryx_posh/CMakeLists.txt index a3e6efda2c..47772ca493 100644 --- a/iceoryx_posh/CMakeLists.txt +++ b/iceoryx_posh/CMakeLists.txt @@ -266,16 +266,14 @@ endif(ICEORYX_LARGE_DEPLOYMENT) # ########## exporting library ########## # +if(TOML_CONFIG) + set(ROUDI_EXPORT RouDi) +endif(TOML_CONFIG) + setup_install_directories_and_export_package( - TARGETS iceoryx_posh iceoryx_posh_roudi + TARGETS iceoryx_posh iceoryx_posh_roudi ${ROUDI_EXPORT} INCLUDE_DIRECTORY include/ ) -if(TOML_CONFIG) - setup_install_directories_and_export_package( - TARGETS RouDi - INCLUDE_DIRECTORY include/ - ) -endif(TOML_CONFIG) if(test) add_subdirectory(test) diff --git a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp index 5613bcfdec..3a01dbdf57 100644 --- a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp +++ b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp @@ -28,11 +28,24 @@ namespace popo class SenderPort; class ReceiverPort; } // namespace popo +namespace posix +{ +class UnixDomainSocket; +class MessageQueue; +} // namespace posix using SenderPortType = iox::popo::SenderPort; using ReceiverPortType = iox::popo::ReceiverPort; constexpr char MQ_ROUDI_NAME[] = "/roudi"; +/// @brief The socket is created in the current path if no absolute path is given hence +/// we need an absolut path so that every application knows where our sockets can +/// be found. +#if defined(__APPLE__) +using IpcChannelType = iox::posix::UnixDomainSocket; +#else +using IpcChannelType = iox::posix::MessageQueue; +#endif /// shared memmory segment for the iceoryx managment data constexpr char SHM_NAME[] = "/iceoryx_mgmt"; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_distributor.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_distributor.hpp index bd61465dcf..6103d5a8ab 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_distributor.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_distributor.hpp @@ -74,7 +74,8 @@ class ChunkDistributor /// @param[in] requestedHistory number of last chunks from history to send if available. If history size is smaller /// then the available history size chunks are provided /// @return if the queue could be added it returns success, otherwiese a ChunkDistributor error - cxx::expected addQueue(cxx::not_null queueToAdd, uint64_t requestedHistory = 0) noexcept; + cxx::expected addQueue(cxx::not_null queueToAdd, + uint64_t requestedHistory = 0) noexcept; /// @brief Remove a queue from the internal list of chunk queues /// @param[in] chunk queue to remove from the list @@ -123,7 +124,7 @@ class ChunkDistributor MemberType_t* getMembers() noexcept; private: - MemberType_t* const m_chunkDistrubutorDataPtr; + MemberType_t* m_chunkDistrubutorDataPtr; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index 2cf40cd123..42e1d2f493 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -87,7 +87,7 @@ class ChunkQueuePopper MemberType_t* getMembers() noexcept; private: - MemberType_t* const m_chunkQueueDataPtr; + MemberType_t* m_chunkQueueDataPtr; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp index 10f4f57b9b..bd6fb468ca 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp @@ -52,7 +52,7 @@ class ChunkQueuePusher MemberType_t* getMembers() noexcept; private: - MemberType_t* const m_chunkQueueDataPtr; + MemberType_t* m_chunkQueueDataPtr; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/base_port_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/base_port_data.hpp index 4ca0c505e5..85b0ccd9c8 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/base_port_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/base_port_data.hpp @@ -25,12 +25,11 @@ namespace iox { namespace runtime { -struct RunnableData; +class RunnableData; } namespace popo { - /// @brief Defines different base port data struct BasePortData { @@ -43,8 +42,7 @@ struct BasePortData /// @param[in] portType Type of port to be created /// @param[in] processName Name of the process /// @param[in] runnable The runnable where this port is attached to - BasePortData(const capro::ServiceDescription& serviceDescription, - const cxx::CString100& processName) noexcept; + BasePortData(const capro::ServiceDescription& serviceDescription, const cxx::CString100& processName) noexcept; BasePortData(const BasePortData&) = delete; BasePortData& operator=(const BasePortData&) = delete; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi_environment/roudi_environment.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi_environment/roudi_environment.hpp index ed225f150d..88d3558972 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi_environment/roudi_environment.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi_environment/roudi_environment.hpp @@ -62,7 +62,11 @@ class RouDiEnvironment private: RuntimeTestInterface m_runtimes; +#if defined(__APPLE__) + std::chrono::milliseconds m_interOpWaitingTime = std::chrono::milliseconds(1000); +#else std::chrono::milliseconds m_interOpWaitingTime = std::chrono::milliseconds(200); +#endif std::unique_ptr m_roudiComponents; std::unique_ptr m_roudiApp; }; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp index bbdaafe2b4..c3d002556f 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp @@ -17,6 +17,7 @@ #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/runtime/message_queue_message.hpp" #include "iceoryx_utils/internal/posix_wrapper/message_queue.hpp" +#include "iceoryx_utils/internal/posix_wrapper/unix_domain_socket.hpp" #include "iceoryx_utils/internal/units/duration.hpp" #include "iceoryx_utils/platform/fcntl.hpp" #include "iceoryx_utils/platform/mqueue.hpp" @@ -185,7 +186,7 @@ class MqBase MqBase() = delete; // TODO: unique identifier problem, multiple MqBase objects with the // same InterfaceName are using the same message queue - MqBase(const std::string& InterfaceName, const int64_t maxMessages, const int64_t messageSize) noexcept; + MqBase(const std::string& InterfaceName, const uint64_t maxMessages, const uint64_t messageSize) noexcept; virtual ~MqBase() = default; /// @brief delete copy and move ctor and assignment since they are not needed @@ -224,10 +225,10 @@ class MqBase protected: std::string m_interfaceName; - long m_maxMessageSize{0}; - long m_maxMessages{0}; + uint64_t m_maxMessageSize{0}; + uint64_t m_maxMessages{0}; iox::posix::IpcChannelSide m_channelSide{posix::IpcChannelSide::CLIENT}; - iox::posix::MessageQueue m_mq; + IpcChannelType m_mq; }; /// @brief Class for handling a message queue via mq_open and mq_close. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/runnable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/runnable_data.hpp index da4bd30bc2..2fdc9ff713 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/runnable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/runnable_data.hpp @@ -23,8 +23,9 @@ namespace iox namespace runtime { /// @brief struct which contains all the members of an object of type Runnable -struct RunnableData +class RunnableData { + public: /// @brief constructor /// @param[in] name name of the runnable /// @param[in] runnableDeviceIdentifier identifier of the device on which the runnable will run diff --git a/iceoryx_posh/include/iceoryx_posh/popo/gateway_discovery.hpp b/iceoryx_posh/include/iceoryx_posh/popo/gateway_discovery.hpp index 0b071d0042..8fdd0b74ae 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/gateway_discovery.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/gateway_discovery.hpp @@ -21,7 +21,7 @@ namespace iox { namespace capro { -struct CaproMessage; +class CaproMessage; } namespace popo { diff --git a/iceoryx_posh/include/iceoryx_posh/popo/gateway_generic.hpp b/iceoryx_posh/include/iceoryx_posh/popo/gateway_generic.hpp index a88da5b70b..96c4bb440a 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/gateway_generic.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/gateway_generic.hpp @@ -24,7 +24,7 @@ namespace iox { namespace capro { -struct CaproMessage; +class CaproMessage; } namespace popo { diff --git a/iceoryx_posh/include/iceoryx_posh/runtime/runnable.hpp b/iceoryx_posh/include/iceoryx_posh/runtime/runnable.hpp index 6e0c5dcb7c..c8e8b8a3ba 100644 --- a/iceoryx_posh/include/iceoryx_posh/runtime/runnable.hpp +++ b/iceoryx_posh/include/iceoryx_posh/runtime/runnable.hpp @@ -21,7 +21,7 @@ namespace iox { namespace runtime { -struct RunnableData; +class RunnableData; /// @brief class which represents a runnable class Runnable diff --git a/iceoryx_posh/source/runtime/message_queue_interface.cpp b/iceoryx_posh/source/runtime/message_queue_interface.cpp index d1bbdd7964..8e28ccf305 100644 --- a/iceoryx_posh/source/runtime/message_queue_interface.cpp +++ b/iceoryx_posh/source/runtime/message_queue_interface.cpp @@ -60,7 +60,7 @@ std::string mqMessageErrorTypeToString(const MqMessageErrorType msg) noexcept return std::to_string(static_cast::type>(msg)); } -MqBase::MqBase(const std::string& InterfaceName, const int64_t maxMessages, const int64_t messageSize) noexcept +MqBase::MqBase(const std::string& InterfaceName, const uint64_t maxMessages, const uint64_t messageSize) noexcept : m_interfaceName(InterfaceName) { m_maxMessages = maxMessages; @@ -160,10 +160,9 @@ bool MqBase::openMessageQueue(const posix::IpcChannelSide channelSide) noexcept m_mq.destroy(); m_channelSide = channelSide; - posix::MessageQueue::create( + IpcChannelType::create( m_interfaceName, posix::IpcChannelMode::BLOCKING, m_channelSide, m_maxMessageSize, m_maxMessages) - .on_success( - [this](cxx::expected& mq) { this->m_mq = std::move(*mq); }); + .on_success([this](cxx::expected& mq) { this->m_mq = std::move(*mq); }); return m_mq.isInitialized(); } diff --git a/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_findservice.cpp b/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_findservice.cpp index 642ef68662..daf7f21e78 100644 --- a/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_findservice.cpp +++ b/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_findservice.cpp @@ -78,7 +78,7 @@ TEST_F(RoudiFindService_test, SubscribeAnyInstance) receiverRuntime->findService({"service1", "65535"}, instanceContainer); ASSERT_THAT(instanceContainer.size(), Eq(3u)); - ContainersEq(instanceContainer, instanceContainerExp); + EXPECT_TRUE(instanceContainer == instanceContainerExp); } TEST_F(RoudiFindService_test, OfferSingleMethodServiceMultiInstance) @@ -242,7 +242,7 @@ TEST_F(RoudiFindService_test, findServiceMaxInstances) auto status = receiverRuntime->findService({"s", "65535"}, instanceContainer); EXPECT_THAT(instanceContainer.size(), Eq(iox::MAX_NUMBER_OF_INSTANCES)); - ContainersEq(instanceContainer, instanceContainerExp); + EXPECT_TRUE(instanceContainer == instanceContainerExp); ASSERT_THAT(status.has_error(), Eq(false)); } @@ -262,6 +262,6 @@ TEST_F(RoudiFindService_test, findServiceInstanceContainerOverflowError) auto status = receiverRuntime->findService({"s", "65535"}, instanceContainer); EXPECT_THAT(instanceContainer.size(), Eq(iox::MAX_NUMBER_OF_INSTANCES)); - ContainersEq(instanceContainer, instanceContainerExp); + EXPECT_TRUE(instanceContainer == instanceContainerExp); ASSERT_THAT(status.has_error(), Eq(true)); } diff --git a/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_service_discovery.hpp b/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_service_discovery.hpp index 5640a1ee1d..fd5b79104a 100644 --- a/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_service_discovery.hpp +++ b/iceoryx_posh/test/integrationtests/service_discovery/test_roudi_service_discovery.hpp @@ -31,15 +31,6 @@ class RouDiServiceDiscoveryTest : public RouDi_GTest dest.push_back(IdString(iox::cxx::TruncateToCapacity, src[i])); } } - - static void ContainersEq(const InstanceContainer& cont1, const InstanceContainer& cont2) - { - ASSERT_THAT(cont1.size(), Eq(cont2.size())); - for (size_t i = 0; i < cont1.size(); i++) - { - ASSERT_THAT(cont1[i], Eq(cont2[i])); - } - } }; #endif // IOX_POSH_SERVICE_DISCOVERY_TEST_ROUDI_SERVICE_DISCOVERY_HPP 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 d43f8e7e3c..29b6cb12cf 100644 --- a/iceoryx_posh/test/integrationtests/test_mq_interface_startup_race.cpp +++ b/iceoryx_posh/test/integrationtests/test_mq_interface_startup_race.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "iceoryx_posh/iceoryx_posh_types.hpp" #include "test.hpp" #include "iceoryx_posh/internal/runtime/message_queue_interface.hpp" @@ -33,12 +34,12 @@ using iox::runtime::MqMessage; using iox::runtime::MqMessageType; using iox::runtime::MqRuntimeInterface; -using MQueue = iox::posix::MessageQueue; - -constexpr char MqRouDiName[] = "/roudi"; -constexpr char MqAppName[] = "/racer"; +#if !defined(__APPLE__) constexpr char DeleteRouDiMessageQueue[] = "rm /dev/mqueue/roudi"; +#endif + +constexpr char MqAppName[] = "/racer"; class StringToMessage : public MqBase { @@ -50,7 +51,7 @@ class CMqInterfaceStartupRace_test : public Test { public: CMqInterfaceStartupRace_test() - : m_appQueue{MQueue::create()} + : m_appQueue{IpcChannelType::create()} { } @@ -93,7 +94,7 @@ class CMqInterfaceStartupRace_test : public Test if (m_appQueue.has_error()) { - m_appQueue = MQueue::create(MqAppName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); + m_appQueue = IpcChannelType::create(MqAppName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); } ASSERT_THAT(m_appQueue.has_error(), false); @@ -102,12 +103,13 @@ class CMqInterfaceStartupRace_test : public Test /// @note smart_lock in combination with optional is currently not really usable std::mutex m_roudiQueueMutex; - MQueue::result_t m_roudiQueue{ - MQueue::create(MqRouDiName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER)}; + IpcChannelType::result_t m_roudiQueue{ + IpcChannelType::create(MQ_ROUDI_NAME, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER)}; std::mutex m_appQueueMutex; - MQueue::result_t m_appQueue; + IpcChannelType::result_t m_appQueue; }; +#if !defined(__APPLE__) TEST_F(CMqInterfaceStartupRace_test, ObsoleteRouDiMq) { /// @note this test checks if the application handles the situation when the roudi mqueue was not properly cleaned @@ -127,7 +129,7 @@ TEST_F(CMqInterfaceStartupRace_test, ObsoleteRouDiMq) // simulate the restart of RouDi with the mqueue cleanup system(DeleteRouDiMessageQueue); - auto m_roudiQueue2 = MQueue::create(MqRouDiName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto m_roudiQueue2 = IpcChannelType::create(MQ_ROUDI_NAME, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); // check if the app retries to register at RouDi request = m_roudiQueue2->timedReceive(15_s); @@ -143,7 +145,7 @@ TEST_F(CMqInterfaceStartupRace_test, ObsoleteRouDiMq) } }); - MqRuntimeInterface dut(MqRouDiName, MqAppName, 35_s); + MqRuntimeInterface dut(MQ_ROUDI_NAME, MqAppName, 35_s); shutdown = true; roudi.join(); @@ -169,7 +171,7 @@ TEST_F(CMqInterfaceStartupRace_test, ObsoleteRouDiMqWithFullMq) // simulate the restart of RouDi with the mqueue cleanup system(DeleteRouDiMessageQueue); - auto newRoudi = MQueue::create(MqRouDiName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto newRoudi = IpcChannelType::create(MQ_ROUDI_NAME, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); // check if the app retries to register at RouDi auto request = newRoudi->timedReceive(15_s); @@ -192,11 +194,12 @@ TEST_F(CMqInterfaceStartupRace_test, ObsoleteRouDiMqWithFullMq) } }); - MqRuntimeInterface dut(MqRouDiName, MqAppName, 35_s); + MqRuntimeInterface dut(MQ_ROUDI_NAME, MqAppName, 35_s); shutdown = true; roudi.join(); } +#endif TEST_F(CMqInterfaceStartupRace_test, ObsoleteRegAck) { @@ -231,7 +234,7 @@ TEST_F(CMqInterfaceStartupRace_test, ObsoleteRegAck) } }); - MqRuntimeInterface dut(MqRouDiName, MqAppName, 35_s); + MqRuntimeInterface dut(MQ_ROUDI_NAME, MqAppName, 35_s); shutdown = true; roudi.join(); diff --git a/iceoryx_posh/test/integrationtests/test_posh_mepoo.cpp b/iceoryx_posh/test/integrationtests/test_posh_mepoo.cpp index 47d91e713e..6a7207797a 100644 --- a/iceoryx_posh/test/integrationtests/test_posh_mepoo.cpp +++ b/iceoryx_posh/test/integrationtests/test_posh_mepoo.cpp @@ -18,6 +18,7 @@ #include "iceoryx_posh/runtime/posh_runtime.hpp" #include "iceoryx_utils/cxx/optional.hpp" #include "iceoryx_utils/internal/units/duration.hpp" +#include "timing_test.hpp" #include #include @@ -72,6 +73,19 @@ class Mepoo_IntegrationTest : public Test // just to prevent the "hides overloaded virtual function" warning virtual void SetUp() { + internal::CaptureStderr(); + } + + virtual void TearDown() + { + senderPort.deactivate(); + receiverPort.unsubscribe(); + + std::string output = internal::GetCapturedStderr(); + if (Test::HasFailure()) + { + std::cout << output << std::endl; + } } enum class configType @@ -148,17 +162,11 @@ class Mepoo_IntegrationTest : public Test void PrintTiming(iox::units::Duration start) { - std::cout << "RouDi startup took " << start.milliSeconds() << " milliseconds, " + std::cerr << "RouDi startup took " << start.milliSeconds() << " milliseconds, " << "(which is " << start.seconds() << " seconds)" << "(which is " << start.minutes() << " minutes)" << std::endl; } - virtual void TearDown() - { - senderPort.deactivate(); - receiverPort.unsubscribe(); - } - template struct MemPoolTestTopic { @@ -426,8 +434,7 @@ TEST_F(Mepoo_IntegrationTest, DISABLED_SampleOverflow) EXPECT_DEATH({ sendreceivesample(repetition1); }, ".*"); } -TEST_F(Mepoo_IntegrationTest, MempoolCreationTimeDefaultConfig) -{ +TIMING_TEST_F(Mepoo_IntegrationTest, MempoolCreationTimeDefaultConfig, Repeat(5), [&] { MemPoolInfoContainer memPoolTestContainer; auto testMempoolConfig = defaultMemPoolConfig(); @@ -445,7 +452,7 @@ TEST_F(Mepoo_IntegrationTest, MempoolCreationTimeDefaultConfig) /// Currently we expect that the RouDi is ready at least after 2 seconds auto maxtime = 2000_ms; EXPECT_THAT(timediff, Le(maxtime)); -} +}); TEST_F(Mepoo_IntegrationTest, DISABLED_MempoolCreationTime2GBConfig) { diff --git a/iceoryx_posh/test/integrationtests/test_shm_sigbus_handler.cpp b/iceoryx_posh/test/integrationtests/test_shm_sigbus_handler.cpp index 1f364d55b6..f25539c4a6 100644 --- a/iceoryx_posh/test/integrationtests/test_shm_sigbus_handler.cpp +++ b/iceoryx_posh/test/integrationtests/test_shm_sigbus_handler.cpp @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License.#include "test.hpp" +#if !defined(__APPLE__) + #include "iceoryx_posh/iceoryx_posh_config.hpp" #include "iceoryx_posh/internal/roudi/memory/mempool_collection_memory_block.hpp" #include "iceoryx_posh/mepoo/mepoo_config.hpp" @@ -52,3 +54,5 @@ TEST(ShmCreatorDeathTest, AllocatingTooMuchMemoryLeadsToExitWithSIGBUS) goodShmProvider.create(); } } // namespace + +#endif diff --git a/iceoryx_posh/test/mocks/chunk_mock.hpp b/iceoryx_posh/test/mocks/chunk_mock.hpp index 334db6c2aa..61081d2964 100644 --- a/iceoryx_posh/test/mocks/chunk_mock.hpp +++ b/iceoryx_posh/test/mocks/chunk_mock.hpp @@ -30,15 +30,8 @@ class ChunkMock public: ChunkMock() { -#if defined(QNX) || defined(QNX__) || defined(__QNX__) - m_rawMemory = static_cast(memalign(Alignment, Size)); -#elif defined(_WIN32) - m_rawMemory = static_cast(_aligned_malloc(Alignment, Size)); -#else - m_rawMemory = static_cast(aligned_alloc(Alignment, Size)); -#endif + m_rawMemory = static_cast(iox::cxx::alignedAlloc(Alignment, Size)); assert(m_rawMemory != nullptr && "Could not get aligned memory"); - memset(m_rawMemory, 0xFF, Size); m_chunkHeader = new (m_rawMemory) iox::mepoo::ChunkHeader(); @@ -52,7 +45,7 @@ class ChunkMock } if (m_rawMemory != nullptr) { - free(m_rawMemory); + iox::cxx::alignedFree(m_rawMemory); m_rawMemory = nullptr; } } diff --git a/iceoryx_posh/test/mocks/roudi_memory_provider_mock.hpp b/iceoryx_posh/test/mocks/roudi_memory_provider_mock.hpp index bc4a71a70f..10d7a034b7 100644 --- a/iceoryx_posh/test/mocks/roudi_memory_provider_mock.hpp +++ b/iceoryx_posh/test/mocks/roudi_memory_provider_mock.hpp @@ -40,11 +40,7 @@ class MemoryProviderTestImpl : public iox::roudi::MemoryProvider createMemoryMock(size, alignment); } -#if defined(QNX) || defined(QNX__) || defined(__QNX__) - dummyMemory = static_cast(memalign(alignment, size)); -#else - dummyMemory = static_cast(aligned_alloc(alignment, size)); -#endif + dummyMemory = static_cast(iox::cxx::alignedAlloc(alignment, size)); return iox::cxx::success(dummyMemory); } MOCK_METHOD2(createMemoryMock, void(uint64_t, uint64_t)); @@ -56,7 +52,7 @@ class MemoryProviderTestImpl : public iox::roudi::MemoryProvider destroyMemoryMock(); } - free(dummyMemory); + iox::cxx::alignedFree(dummyMemory); dummyMemory = nullptr; return iox::cxx::success(); diff --git a/iceoryx_posh/test/moduletests/test_base_port.cpp b/iceoryx_posh/test/moduletests/test_base_port.cpp index fc5ddc6cd5..b50ffe895f 100644 --- a/iceoryx_posh/test/moduletests/test_base_port.cpp +++ b/iceoryx_posh/test/moduletests/test_base_port.cpp @@ -57,8 +57,7 @@ BasePort* CreateReceiverPort() BasePort* CreateInterfacePort() { - InterfacePortData* interfacePortData = - new InterfacePortData("InterfacePort", iox::capro::Interfaces::INTERNAL); + InterfacePortData* interfacePortData = new InterfacePortData("InterfacePort", iox::capro::Interfaces::INTERNAL); return new InterfacePort(interfacePortData); } @@ -191,10 +190,11 @@ TEST_P(BasePortParamtest, getApplicationname) } } -INSTANTIATE_TEST_CASE_P(CaPro, - BasePortParamtest, - Values(&CreateCaProPort, - &CreateReceiverPort, - &CreateSenderPort, - &CreateInterfacePort, - &CreateApplicationPort)); +/// we require INSTANTIATE_TEST_CASE since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +INSTANTIATE_TEST_CASE_P( + CaPro, + BasePortParamtest, + Values(&CreateCaProPort, &CreateReceiverPort, &CreateSenderPort, &CreateInterfacePort, &CreateApplicationPort)); +#pragma GCC diagnostic pop diff --git a/iceoryx_posh/test/moduletests/test_popo_chunk_distributor.cpp b/iceoryx_posh/test/moduletests/test_popo_chunk_distributor.cpp index a67dc26d6e..13a57c2e70 100644 --- a/iceoryx_posh/test/moduletests/test_popo_chunk_distributor.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_chunk_distributor.cpp @@ -31,7 +31,11 @@ using namespace iox::cxx; using namespace iox::mepoo; using ChunkDistributorTestSubjects = Types; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(ChunkDistributor_test, ChunkDistributorTestSubjects); +#pragma GCC diagnostic pop template class ChunkDistributor_test : public Test @@ -110,8 +114,10 @@ TYPED_TEST(ChunkDistributor_test, QueueOverflow) typename TestFixture::ChunkDistributor_t sut(sutData.get()); auto errorHandlerCalled{false}; - auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler([&errorHandlerCalled]( - const iox::Error, const std::function, const iox::ErrorLevel) { errorHandlerCalled = true; }); + auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( + [&errorHandlerCalled](const iox::Error, const std::function, const iox::ErrorLevel) { + errorHandlerCalled = true; + }); for (uint32_t i = 0; i < this->MAX_NUMBER_QUEUES; ++i) { diff --git a/iceoryx_posh/test/moduletests/test_popo_chunk_queue.cpp b/iceoryx_posh/test/moduletests/test_popo_chunk_queue.cpp index 3976511e55..2ac688ab7d 100644 --- a/iceoryx_posh/test/moduletests/test_popo_chunk_queue.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_chunk_queue.cpp @@ -65,10 +65,14 @@ class ChunkQueue_test : public TestWithParam, publi ChunkQueuePusher m_pusher{&m_chunkData}; }; +/// we require INSTANTIATE_TEST_CASE since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" INSTANTIATE_TEST_CASE_P(ChunkQueueAll, ChunkQueue_test, Values(iox::cxx::VariantQueueTypes::FiFo_SingleProducerSingleConsumer, iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer)); +#pragma GCC diagnostic pop TEST_P(ChunkQueue_test, InitialEmpty) { diff --git a/iceoryx_posh/test/moduletests/test_roudi_mempool_introspection.cpp b/iceoryx_posh/test/moduletests/test_roudi_mempool_introspection.cpp index 1174295948..1297ea0e25 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_mempool_introspection.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_mempool_introspection.cpp @@ -16,6 +16,7 @@ #include "mocks/mepoo_memory_manager_mock.hpp" #include "mocks/senderport_mock.hpp" #include "test.hpp" +#include "timing_test.hpp" using namespace ::testing; using ::testing::Return; @@ -209,14 +210,13 @@ TEST_F(MemPoolIntrospection_test, DISABLED_send_withSubscribers) EXPECT_THAT(compareMemPoolInfo(memPoolInfoContainer, chunk.sample()->m_mempoolInfo), Eq(true)); } -TEST_F(MemPoolIntrospection_test, thread) -{ +TIMING_TEST_F(MemPoolIntrospection_test, thread, Repeat(5), [&] { auto mock = m_senderPortImpl_mock.details; MemPoolIntrospection m_introspection( m_rouDiInternalMemoryManager_mock, m_segmentManager_mock, std::move(m_senderPortImpl_mock)); MemPoolInfoContainer memPoolInfoContainer; - MemPoolInfo memPoolInfo{0, 0, 0, 0}; + MemPoolInfo memPoolInfo(0, 0, 0, 0); initMemPoolInfoContainer(memPoolInfoContainer); EXPECT_CALL(m_rouDiInternalMemoryManager_mock, getMemPoolInfo(_)).WillRepeatedly(Invoke([&](uint32_t index) { initMemPoolInfo(index, memPoolInfo); @@ -226,12 +226,17 @@ TEST_F(MemPoolIntrospection_test, thread) // we use the hasSubscribers call to check how often the thread calls the send method mock->hasSubscribersReturn = false; - m_introspection.setSnapshotInterval(10); + using namespace iox::units::duration_literals; + iox::units::Duration snapshotInterval(100_ms); + + m_introspection.setSnapshotInterval(snapshotInterval.milliSeconds()); m_introspection.start(); - std::this_thread::sleep_for(std::chrono::milliseconds(55)); // within this time, the thread should have run 6 times + std::this_thread::sleep_for(std::chrono::milliseconds( + 6 * snapshotInterval.milliSeconds())); // within this time, the thread should have run 6 times m_introspection.wait(); - std::this_thread::sleep_for(std::chrono::milliseconds(55)); // the thread should sleep, if not, we have 12 runs + std::this_thread::sleep_for(std::chrono::milliseconds( + 6 * snapshotInterval.milliSeconds())); // the thread should sleep, if not, we have 12 runs m_introspection.terminate(); - EXPECT_THAT(4 <= mock->hasSubscribers && mock->hasSubscribers <= 8, Ge(true)); -} + TIMING_TEST_EXPECT_TRUE(4 <= mock->hasSubscribers && mock->hasSubscribers <= 8); +}); diff --git a/iceoryx_utils/CMakeLists.txt b/iceoryx_utils/CMakeLists.txt index e4fad5c8ec..cf2035d43a 100644 --- a/iceoryx_utils/CMakeLists.txt +++ b/iceoryx_utils/CMakeLists.txt @@ -52,6 +52,7 @@ if(GTest_FOUND) # only GTest_FOUND, just in case someone want's to use iceoryx_u add_library(iceoryx_utils_testing testutils/mocks/mqueue_mock.cpp testutils/mocks/time_mock.cpp + testutils/timing_test.cpp ) add_library(iceoryx_utils_testing::iceoryx_utils_testing ALIAS iceoryx_utils_testing) @@ -127,6 +128,7 @@ add_library(iceoryx_utils source/concurrent/active_object.cpp source/concurrent/loffli.cpp source/concurrent/locked_loffli.cpp + source/cxx/helplets.cpp source/cxx/generic_raii.cpp source/error_handling/error_handling.cpp source/file_reader/file_reader.cpp @@ -138,7 +140,6 @@ add_library(iceoryx_utils source/log/logstream.cpp source/log/ac3log_shim/simplelogger.cpp source/posix_wrapper/access_control.cpp - source/posix_wrapper/argv_inspection.cpp source/posix_wrapper/mutex.cpp source/posix_wrapper/semaphore.cpp source/posix_wrapper/timer.cpp diff --git a/iceoryx_utils/README.md b/iceoryx_utils/README.md index 7be875f3db..4e4e8112cb 100644 --- a/iceoryx_utils/README.md +++ b/iceoryx_utils/README.md @@ -95,7 +95,7 @@ abstractions or add a new one when using POSIX resources like semaphores, shared |`IpcChannel` | i | | Helper types used by the `MessageQueue`and the `UnixDomainSocket`. | |`MessageQueue` | i | | Interface for Message Queues, see [ManPage mq_overview](https://www.man7.org/linux/man-pages/man7/mq_overview.7.html). | |`mutex` | i | | Mutex interface, see [ManPage pthread_mutex_lock](https://man7.org/linux/man-pages/man3/pthread_mutex_lock.3p.html). | -|`posix_access_rights` | | Rights and user management interface. | +|`posix_access_rights` | | | Rights and user management interface. | |`Semaphore` | | | Semaphore interface, see [ManPage sem_overview](https://man7.org/linux/man-pages/man7/sem_overview.7.html) | |`shared_memory_object/Allocator` | i | | Helper class for the `SharedMemoryObject`. | |`shared_memory_object/MemoryMap` | i | | Abstraction of `mmap`, `munmap` and helper class for the `SharedMemoryObject`.| diff --git a/iceoryx_utils/include/iceoryx_utils/communication_channel/bidirectional_communication_channel.hpp b/iceoryx_utils/include/iceoryx_utils/communication_channel/bidirectional_communication_channel.hpp deleted file mode 100644 index a24a73f84d..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/communication_channel/bidirectional_communication_channel.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_BIDIRECTIONAL_COMMUNICATION_CHANNEL_HPP -#define IOX_UTILS_COMMUNICATION_CHANNEL_BIDIRECTIONAL_COMMUNICATION_CHANNEL_HPP - -#include "iceoryx_utils/internal/cxx/pair.hpp" -#include "iceoryx_utils/internal/communication_channel/transceiver.hpp" - -namespace iox -{ -/// @brief implementation of the bidirectional communication channel which -/// can be used for inter process communication through different -/// transport layers (aka. protocols) like message queue, qnx message -/// passing, sockets or shared memory fifo variations -/// @code -/// // create communication channel in shared memory -/// BidirectionalCommunicationChannel channel; -/// -/// auto transceiverA = channel.getFirstTransceiver(); -/// auto transceiverB = channel.getSecondTransceiver(); -/// SendTransceiverToApplicationA(transceiverA); -/// SendTransceiverToApplicationB(transceiverB); -/// -/// // in application A -/// channelToApplicationB.Send("Hello World"); -/// -/// // in application B -/// auto message = channelToApplicationA.BlockingReceive(); -/// if ( message.has_value() ) { -/// std::cout << "received message " << message.value() << " from application A\n"; -/// } -/// @endcode -template class TransportLayer> -class BidirectionalCommunicationChannel -{ - public: - using TransportLayer_t = TransportLayer; - using Transceiver_t = Transceiver; - using TransceiverPair_t = cxx::pair; - using TransportLayerPair_t = cxx::pair; - - /// @brief creates a new communication channel - BidirectionalCommunicationChannel(); - - /// @brief creates a communication channel and forwards the transportLayer arguments - /// into the corresponding transportlayer constructor - /// if you need more then one constructor argument you have to pack all the - /// required constructor arguments into one struct and give this as a parameter - /// @param[in] argumentAliceToBob constructor argument for the layer from alice to bob - /// @param[in] argumentBobToAlice constructor argument for the layer from bob to alice - template - BidirectionalCommunicationChannel(const TransportLayerCTorArgument& argumentAliceToBob, - const TransportLayerCTorArgument& argumentBobToAlice); - - /// @brief the copy/move constructor and assignment operator must be disabled since - /// transceiver pair is holding a pointer to the transportLayer which is - /// stored inside this channel - BidirectionalCommunicationChannel(const BidirectionalCommunicationChannel&) = delete; - BidirectionalCommunicationChannel(BidirectionalCommunicationChannel&&) = delete; - BidirectionalCommunicationChannel& operator=(const BidirectionalCommunicationChannel&) = delete; - BidirectionalCommunicationChannel& operator=(BidirectionalCommunicationChannel&&) = delete; - - /// @brief retrieves a pair of transceivers over which two communication partners can communicate. - /// IMPORTANT: distribute this pair ONLY to one communication partner pair. If you have - /// multiple communication partners you have to create multiple channels! - Transceiver_t* getFirstTransceiver(); - Transceiver_t* getSecondTransceiver(); - - private: - TransportLayerPair_t m_transportLayerPair; - TransceiverPair_t m_transceiverPair; -}; -} // namespace iox - -#include "iceoryx_utils/internal/communication_channel/bidirectional_communication_channel.inl" - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_BIDIRECTIONAL_COMMUNICATION_CHANNEL_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp b/iceoryx_utils/include/iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp deleted file mode 100644 index 4acd62cf35..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_PROTOCOL_FIFO_PROTOCOL_HPP -#define IOX_UTILS_COMMUNICATION_CHANNEL_PROTOCOL_FIFO_PROTOCOL_HPP - -#include "iceoryx_utils/internal/concurrent/fifo.hpp" -#include "iceoryx_utils/cxx/optional.hpp" -#include "iceoryx_utils/posix_wrapper/semaphore.hpp" -#include "iceoryx_utils/internal/units/duration.hpp" - -namespace iox -{ -/// @brief the communication channel fifo protocol which can be used by the -/// communication channel to communicate -/// @param[in] DataType the datatype which should be transferred -/// @param[in] Capacity capacity of the underlying fifo -template -class FiFoProtocol -{ - public: - /// @brief non blocking send which delivers a message - /// @param[in] f_message message which should be send - /// @return if the message cannot be delivered it returns false, otherwise true - bool Send(const DataType& f_message); - - /// @brief non blocking receive. - /// @return if the protocol received a message the optional does contain the - /// message otherwise a cxx::nullopt is returned - cxx::optional TryReceive(); - - /// @brief blocking receive. if the protocol received a message the - /// optional does contain it. - /// @return if the destructor is called from a different thread - /// then this method returns a cxx::nullopt and this class should not be - /// used anymore. - cxx::optional BlockingReceive(); - - /// @brief blocking receive with timeout. - /// @param[in] f_timeout timeout of timedReceive - /// @return if a message is received during the - /// timeout period the message is stored inside the optional, otherwise - /// the optional contains a cxx::nullopt - cxx::optional timedReceive(const units::Duration& f_timeout); - - private: - concurrent::FiFo m_fifo; - posix::Semaphore m_semaphore = std::move(posix::Semaphore::create(0) - .on_error([] { - std::cerr << "unable to create the semaphore for the fifo protocol" - << std::endl; - std::terminate(); - }) - .get_value()); -}; -} // namespace iox - -#include "iceoryx_utils/internal/communication_channel/protocol/fifo_protocol.inl" - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_PROTOCOL_FIFO_PROTOCOL_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/communication_channel/unidirectional_communication_channel.hpp b/iceoryx_utils/include/iceoryx_utils/communication_channel/unidirectional_communication_channel.hpp deleted file mode 100644 index 2f9e550369..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/communication_channel/unidirectional_communication_channel.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_UNIDIRECTIONAL_COMMUNICATION_CHANNEL_HPP -#define IOX_UTILS_COMMUNICATION_CHANNEL_UNIDIRECTIONAL_COMMUNICATION_CHANNEL_HPP - -#include "iceoryx_utils/internal/communication_channel/receiver.hpp" -#include "iceoryx_utils/internal/communication_channel/transmitter.hpp" - -namespace iox -{ -/// @brief implementation of the unidirectional communication channel which -/// can be used for inter process communication through different -/// transport layers (aka. protocols) like message queue, qnx message -/// passing, sockets or shared memory fifo variations -/// @code -/// // create communication channel in shared memory -/// UniidirectionalCommunicationChannel channel; -/// -/// SendTransmitterToApplicationA(channel.getTransmitter()); -/// SendReceiverToApplicationB(channel.getReceiver()); -/// -/// // in application A -/// channelToApplicationB.Send("Hello World"); -/// -/// // in application B -/// auto message = channelToApplicationA.BlockingReceive(); -/// if ( message.has_value() ) { -/// std::cout << "received message " << message.value() << " from application A\n"; -/// } -/// @endcode -template class TransportLayer> -class UnidirectionalCommunicationChannel -{ - public: - using TransportLayer_t = TransportLayer; - using Transmitter_t = Transmitter; - using Receiver_t = Receiver; - - /// @brief creates a new communication channel - UnidirectionalCommunicationChannel(); - - /// @brief the copy/move constructor and assignment operator must be disabled since - /// transceiver pair is holding a pointer to the transportLayer which is - /// stored inside this channel - UnidirectionalCommunicationChannel(const UnidirectionalCommunicationChannel&) = delete; - UnidirectionalCommunicationChannel(UnidirectionalCommunicationChannel&&) = delete; - UnidirectionalCommunicationChannel& operator=(const UnidirectionalCommunicationChannel&) = delete; - UnidirectionalCommunicationChannel& operator=(UnidirectionalCommunicationChannel&&) = delete; - - /// @brief creates a communication channel and forwards the transportLayer argument - /// into the corresponding transportlayer constructor - /// if you need more then one constructor argument you have to pack all the - /// required constructor arguments into one struct and give this as a parameter - /// @param[in] argument constructor argument for the layer - template - UnidirectionalCommunicationChannel(const TransportLayerCTorArgument& argument); - - /// @brief returns the transmitter so that it can be given to the sender partner - Transmitter_t* getTransmitter(); - - /// @brief returns the receiver so that it can be given to the receiving partner - Receiver_t* getReceiver(); - - private: - TransportLayer_t m_transportLayer; - Transmitter_t m_transmitter; - Receiver_t m_receiver; -}; -} // namespace iox - -#include "iceoryx_utils/internal/communication_channel/unidirectional_communication_channel.inl" - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_UNIDIRECTIONAL_COMMUNICATION_CHANNEL_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index 857a57c4d0..9b0bcc3e5c 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -112,6 +112,16 @@ T align(const T value, const T alignment) return value + ((remainder == 0u) ? 0u : alignment - remainder); } +/// @brief allocates aligned memory which can only be free'd by alignedFree +/// @param[in] alignment, alignment of the memory +/// @param[in] size, memory size +/// @return void pointer to the aligned memory +void* alignedAlloc(const uint64_t alignment, const uint64_t size) noexcept; + +/// @brief frees aligned memory allocated with alignedAlloc +/// @param[in] memory, pointer to the aligned memory +void alignedFree(void* const memory); + /// template recursion stopper for maximum alignment calculation template constexpr size_t maxAlignment() diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/vector.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/vector.hpp index fdb895dc82..f6bac8789c 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/vector.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/vector.hpp @@ -168,6 +168,12 @@ class vector } // namespace cxx } // namespace iox +template +bool operator==(const iox::cxx::vector& lhs, const iox::cxx::vector& rhs) noexcept; + +template +bool operator!=(const iox::cxx::vector& lhs, const iox::cxx::vector& rhs) noexcept; + #include "iceoryx_utils/internal/cxx/vector.inl" #endif // IOX_UTILS_CXX_VECTOR_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/bidirectional_communication_channel.inl b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/bidirectional_communication_channel.inl deleted file mode 100644 index c0e29e70c4..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/bidirectional_communication_channel.inl +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_BIDIRECTIONAL_COMMUNICATION_CHANNEL_INL -#define IOX_UTILS_COMMUNICATION_CHANNEL_BIDIRECTIONAL_COMMUNICATION_CHANNEL_INL - -#include "iceoryx_utils/communication_channel/bidirectional_communication_channel.hpp" - -namespace iox -{ -template class TransportLayer> -inline BidirectionalCommunicationChannel::BidirectionalCommunicationChannel() - : m_transportLayerPair() - , m_transceiverPair{{&m_transportLayerPair.first, &m_transportLayerPair.second}, - {&m_transportLayerPair.second, &m_transportLayerPair.first}} -{ -} - -template class TransportLayer> -template -inline BidirectionalCommunicationChannel::BidirectionalCommunicationChannel( - const TransportLayerCTorArgument& argumentAliceToBob, const TransportLayerCTorArgument& argumentBobToAlice) - : m_transportLayerPair({{argumentAliceToBob}, {argumentBobToAlice}}) - , m_transceiverPair{{&m_transportLayerPair.first, &m_transportLayerPair.second}, - {&m_transportLayerPair.second, &m_transportLayerPair.first}} -{ -} - -template class TransportLayer> -inline typename BidirectionalCommunicationChannel::Transceiver_t* -BidirectionalCommunicationChannel::getFirstTransceiver() -{ - return &m_transceiverPair.first; -} - -template class TransportLayer> -inline typename BidirectionalCommunicationChannel::Transceiver_t* -BidirectionalCommunicationChannel::getSecondTransceiver() -{ - return &m_transceiverPair.second; -} - -} // namespace iox - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_BIDIRECTIONAL_COMMUNICATION_CHANNEL_INL diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/protocol/fifo_protocol.inl b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/protocol/fifo_protocol.inl deleted file mode 100644 index 92f65fe8ce..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/protocol/fifo_protocol.inl +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_PROTOCOL_FIFO_PROTOCOL_INL -#define IOX_UTILS_COMMUNICATION_CHANNEL_PROTOCOL_FIFO_PROTOCOL_INL - -#include "iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp" - -namespace iox -{ -template -inline bool FiFoProtocol::Send(const DataType& message) -{ - if (m_fifo.push(message)) - { - m_semaphore.post(); - return true; - } - return false; -} - -template -inline cxx::optional FiFoProtocol::TryReceive() -{ - if (m_semaphore.tryWait()) - { - return m_fifo.pop(); - } - return cxx::nullopt_t(); -} - -template -inline cxx::optional FiFoProtocol::BlockingReceive() -{ - if (m_semaphore.wait()) - { - return m_fifo.pop(); - } - return cxx::nullopt_t(); -} - -template -inline cxx::optional FiFoProtocol::timedReceive(const units::Duration& timeout) -{ - auto timeoutAsTimespec = timeout.timespec(units::TimeSpecReference::Epoch); - if (m_semaphore.timedWait(&timeoutAsTimespec, true)) - { - return m_fifo.pop(); - } - return cxx::nullopt_t(); -} - -} // namespace iox - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_PROTOCOL_FIFO_PROTOCOL_INL diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/receiver.hpp b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/receiver.hpp deleted file mode 100644 index 8a0d54cbc1..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/receiver.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_RECEIVER_HPP -#define IOX_UTILS_COMMUNICATION_CHANNEL_RECEIVER_HPP - -#include "iceoryx_utils/cxx/optional.hpp" -#include "iceoryx_utils/internal/units/duration.hpp" - -namespace iox -{ -/// @brief the Receiver part of the communication channel used by one of the -/// communication partners to receive messages. it is also used by the -/// transceiver which inherits from it to provide a sending and receiving -/// interface -template class TransportLayer> -class Receiver -{ - public: - using TransportLayer_t = TransportLayer; - - /// @brief constructor of the receiver which requires a pointer to a non - /// changing memory position of the transportlayer - /// @param[in] f_transportLayer transportLayer where the receiver can receive from - Receiver(TransportLayer_t* const f_transportLayer); - - /// @brief blocking receive with timeout. - /// @param[in] f_timeout the timeout - /// @return if no message was received it returns cxx::nullopt otherwise - /// the message is contained in the optional - cxx::optional timedReceive(const units::Duration& f_timeout); - - /// @brief blocking receive - /// @return if the destructor from another was called it returns cxx::nullopt otherwise - /// the message is contained in the optional. - cxx::optional BlockingReceive(); - - /// @brief non blocking receive - /// @return if no message was received it returns cxx::nullopt otherwise - /// the message is contained in the optional - cxx::optional TryReceive(); - - private: - TransportLayer_t* m_transportLayer; -}; -} // namespace iox - -#include "iceoryx_utils/internal/communication_channel/receiver.inl" - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_RECEIVER_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/receiver.inl b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/receiver.inl deleted file mode 100644 index e5ecd2eeda..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/receiver.inl +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_RECEIVER_INL -#define IOX_UTILS_COMMUNICATION_CHANNEL_RECEIVER_INL - -#include "iceoryx_utils/internal/communication_channel/receiver.hpp" - -namespace iox -{ -template class TransportLayer> -inline Receiver::Receiver(TransportLayer_t* const f_transportLayer) - : m_transportLayer(f_transportLayer) -{ -} - -template class TransportLayer> -inline cxx::optional Receiver::timedReceive(const units::Duration& f_timeout) -{ - return m_transportLayer->timedReceive(f_timeout); -} - -template class TransportLayer> -inline cxx::optional Receiver::BlockingReceive() -{ - return m_transportLayer->BlockingReceive(); -} - -template class TransportLayer> -inline cxx::optional Receiver::TryReceive() -{ - return m_transportLayer->TryReceive(); -} -} // namespace iox - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_RECEIVER_INL diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transceiver.hpp b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transceiver.hpp deleted file mode 100644 index 4bcce6d859..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transceiver.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_TRANSCEIVER_HPP -#define IOX_UTILS_COMMUNICATION_CHANNEL_TRANSCEIVER_HPP - -#include "receiver.hpp" -#include "transmitter.hpp" - -namespace iox -{ -/// @brief offers the combined interface of the Transmitter and Receiver for -/// bidirectional communication channel usage. every communication partner -/// will get one transceiver over which they can communicate. -template class TransportLayer> -class Transceiver : public Receiver, public Transmitter -{ - public: - using TransportLayer_t = TransportLayer; - - /// @brief the constructor requires two transportLayer pointer since a transportLayer is only - /// unidirectional. - Transceiver(TransportLayer_t* const f_transportLayerAliceToBob, TransportLayer_t* const f_transportLayerBobToAlice); -}; -} // namespace iox - -#include "iceoryx_utils/internal/communication_channel/transceiver.inl" - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_TRANSCEIVER_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transceiver.inl b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transceiver.inl deleted file mode 100644 index 07c38f7caa..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transceiver.inl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_TRANSCEIVER_INL -#define IOX_UTILS_COMMUNICATION_CHANNEL_TRANSCEIVER_INL - -#include "iceoryx_utils/internal/communication_channel/transceiver.hpp" - -namespace iox -{ -template class TransportLayer> -inline Transceiver::Transceiver(TransportLayer_t* const f_transportLayerAliceToBob, - TransportLayer_t* const f_transportLayerBobToAlice) - : Receiver(f_transportLayerAliceToBob) - , Transmitter(f_transportLayerBobToAlice) -{ -} -} // namespace iox - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_TRANSCEIVER_INL diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transmitter.hpp b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transmitter.hpp deleted file mode 100644 index d060b822de..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transmitter.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_TRANSMITTER_HPP -#define IOX_UTILS_COMMUNICATION_CHANNEL_TRANSMITTER_HPP - -namespace iox -{ -/// @brief the Transmitter part of the communication channel used by one of the -/// communication partners to send messages. it is also used by the -/// transceiver which inherits from it to provide a sending and receiving -/// interface -template class TransportLayer> -class Transmitter -{ - public: - using TransportLayer_t = TransportLayer; - - /// @brief constructor of the transmitter which requires a pointer to a non - /// changing memory position of the transportlayer - /// @param[in] f_transportLayer transportLayer where the transmitter can send to - Transmitter(TransportLayer_t* const f_transportLayer); - - /// @brief sends a message - /// @param[in] f_message message which should be send - /// @return if the message could not be sent it returns false, otherwise true - bool Send(const DataType& f_message); - - private: - TransportLayer_t* m_transportLayer; -}; - -} // namespace iox - -#include "iceoryx_utils/internal/communication_channel/transmitter.inl" - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_TRANSMITTER_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transmitter.inl b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transmitter.inl deleted file mode 100644 index 0ea72ef1d0..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/transmitter.inl +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_TRANSMITTER_INL -#define IOX_UTILS_COMMUNICATION_CHANNEL_TRANSMITTER_INL - -#include "iceoryx_utils/internal/communication_channel/transmitter.hpp" - -namespace iox -{ -template class TransportLayer> -inline Transmitter::Transmitter(TransportLayer_t* const f_transportLayer) - : m_transportLayer(f_transportLayer) -{ -} - -template class TransportLayer> -inline bool Transmitter::Send(const DataType& f_message) -{ - return m_transportLayer->Send(f_message); -} -} // namespace iox - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_TRANSMITTER_INL diff --git a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/unidirectional_communication_channel.inl b/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/unidirectional_communication_channel.inl deleted file mode 100644 index a1e0cfc8e5..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/communication_channel/unidirectional_communication_channel.inl +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_COMMUNICATION_CHANNEL_UNIDIRECTIONAL_COMMUNICATION_CHANNEL_INL -#define IOX_UTILS_COMMUNICATION_CHANNEL_UNIDIRECTIONAL_COMMUNICATION_CHANNEL_INL - -#include "iceoryx_utils/communication_channel/unidirectional_communication_channel.hpp" - -namespace iox -{ -template class TransportLayer> -inline UnidirectionalCommunicationChannel::UnidirectionalCommunicationChannel() - : m_transportLayer() - , m_transmitter(&m_transportLayer) - , m_receiver(&m_transportLayer) -{ -} - -template class TransportLayer> -template -inline UnidirectionalCommunicationChannel::UnidirectionalCommunicationChannel( - const TransportLayerCTorArgument& argument) - : m_transportLayer(argument) - , m_transmitter(&m_transportLayer) - , m_receiver(&m_transportLayer) -{ -} - -template class TransportLayer> -inline typename UnidirectionalCommunicationChannel::Transmitter_t* -UnidirectionalCommunicationChannel::getTransmitter() -{ - return &m_transmitter; -} - -template class TransportLayer> -inline typename UnidirectionalCommunicationChannel::Receiver_t* -UnidirectionalCommunicationChannel::getReceiver() -{ - return &m_receiver; -} -} // namespace iox - -#endif // IOX_UTILS_COMMUNICATION_CHANNEL_UNIDIRECTIONAL_COMMUNICATION_CHANNEL_INL diff --git a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.hpp b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.hpp index 70fb4bb1d1..f8bf390d26 100755 --- a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.hpp @@ -128,7 +128,7 @@ class IndexQueue IndexQueue& operator=(IndexQueue&&) = delete; /// @brief constructs an empty IndexQueue - constexpr IndexQueue(ConstructEmpty_t = ConstructEmpty) noexcept; + IndexQueue(ConstructEmpty_t = ConstructEmpty) noexcept; /// @brief constructs IndexQueue filled with all indices 0,1,...capacity-1 IndexQueue(ConstructFull_t) noexcept; @@ -177,6 +177,10 @@ class IndexQueue using Index = CyclicIndex; using Cell = std::atomic; + /// this member has to be initialized explicitly in the constructor since + /// the default atomic constructor does not call the default constructor of the + /// underlying class. + /// See, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0883r0.pdf Cell m_cells[Capacity]; std::atomic m_readPosition; diff --git a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.inl b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.inl index da8b7419dc..ab03cccf55 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.inl +++ b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/lockfree_queue/index_queue.inl @@ -3,10 +3,14 @@ namespace iox namespace concurrent { template -constexpr IndexQueue::IndexQueue(ConstructEmpty_t) noexcept +IndexQueue::IndexQueue(ConstructEmpty_t) noexcept : m_readPosition(Index(Capacity)) , m_writePosition(Index(Capacity)) { + for (uint64_t i = 0u; i < Capacity; ++i) + { + m_cells[i].store(Index(0), std::memory_order_relaxed); + } } template @@ -16,7 +20,7 @@ IndexQueue::IndexQueue(ConstructFull_t) noexcept { for (uint64_t i = 0u; i < Capacity; ++i) { - m_cells[i].store(Index(i)); + m_cells[i].store(Index(i), std::memory_order_relaxed); } } @@ -253,4 +257,4 @@ IndexQueue::loadvalueAt(const Index& position, std::memory_ } // namespace concurrent -} // namespace iox \ No newline at end of file +} // namespace iox diff --git a/iceoryx_utils/include/iceoryx_utils/internal/cxx/vector.inl b/iceoryx_utils/include/iceoryx_utils/internal/cxx/vector.inl index 3d4de5f02f..cf2e042743 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/cxx/vector.inl +++ b/iceoryx_utils/include/iceoryx_utils/internal/cxx/vector.inl @@ -197,7 +197,7 @@ inline T& vector::at(const uint64_t index) { /// @rationale /// const cast to avoid code duplication - return const_cast(const_cast*>(this)->at(index)); // PRQA S 3066 + return const_cast(const_cast*>(this)->at(index)); // PRQA S 3066 } template @@ -205,7 +205,7 @@ inline const T& vector::at(const uint64_t index) const { if (index + 1u > m_size) { - std::cerr << "out of bounds access, current size is " << m_size << " but given index is " << index << std::endl; + std::cerr << "out of bounds access, current size is " << m_size << " but given index is " << index << std::endl; std::terminate(); } return reinterpret_cast(m_data)[index]; @@ -311,4 +311,30 @@ inline typename vector::iterator vector::erase(iterato } // namespace cxx } // namespace iox +template +bool operator==(const iox::cxx::vector& lhs, const iox::cxx::vector& rhs) noexcept +{ + uint64_t vectorSize = lhs.size(); + if (vectorSize != rhs.size()) + { + return false; + } + + for (uint64_t i = 0u; i < vectorSize; ++i) + { + if (lhs[i] != rhs[i]) + { + return false; + } + } + return true; +} + +template +bool operator!=(const iox::cxx::vector& lhs, const iox::cxx::vector& rhs) noexcept +{ + return !(lhs == rhs); +} + + #endif // IOX_UTILS_CXX_VECTOR_INL diff --git a/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/argv_inspection.hpp b/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/argv_inspection.hpp deleted file mode 100644 index 8ebefff470..0000000000 --- a/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/argv_inspection.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. -#ifndef IOX_UTILS_POSIX_WRAPPER_ARGV_INSPECTION_HPP -#define IOX_UTILS_POSIX_WRAPPER_ARGV_INSPECTION_HPP - -#include "iceoryx_utils/cxx/optional.hpp" - -#include - -namespace iox -{ -namespace posix -{ -/// @brief wrapper class holding the command line arguments of the current process -/// @code -/// // program has been called with ./program arg1 foo -/// ArgvInspector inspector; -/// std::string result; -/// inspector.getCmdlineArgument(2, result); // result = "foo" -/// @endcode - -class ArgvInspector -{ - public: - /// @brief C'tor of the ArgvInspector class. Tries to open the Linux /proc/self/cmdline file and extract the command - /// line arguments of the running process. - ArgvInspector(); - - /// @brief get the command line argument at position f_argNumber and store into f_argument input parameter. - /// @return false if the /proc filesystem could not be accessed or if the argument number exceeds the actual command - /// line arguments - bool getCmdlineArgument(const int32_t f_argNumber, std::string& f_argument) const; - - private: - cxx::optional m_cmdline; -}; -} // namespace posix -} // namespace iox - -#endif // IOX_UTILS_POSIX_WRAPPER_ARGV_INSPECTION_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/ipc_channel.hpp b/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/ipc_channel.hpp index b75cde12f1..d7cedcd2ee 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/ipc_channel.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/ipc_channel.hpp @@ -36,6 +36,7 @@ enum class IpcChannelError : uint8_t OUT_OF_MEMORY, INVALID_FILE_DESCRIPTOR, I_O_ERROR, + CONNECTION_RESET_BY_PEER, UNDEFINED }; diff --git a/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/unix_domain_socket.hpp b/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/unix_domain_socket.hpp index 4be26f2f34..2b439b95b5 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/unix_domain_socket.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/posix_wrapper/unix_domain_socket.hpp @@ -32,11 +32,21 @@ namespace posix class UnixDomainSocket : public DesignPattern::Creation { public: - static constexpr size_t MAX_MESSAGE_SIZE = 4096u; + struct NoPathPrefix_t + { + }; + static constexpr NoPathPrefix_t NoPathPrefix{}; + + /// @brief Max message size is on linux = 4096 and on mac os = 2048. To have + /// the same behavior on every platform we use 2048. + static constexpr size_t MAX_MESSAGE_SIZE = 2048u; static constexpr size_t SHORTEST_VALID_NAME = 2u; - static constexpr size_t LONGEST_VALID_NAME = 100u; + /// @brief The name has to contain the full path besides the name and has to + /// be therefore much longer then the message queue pendant. + static constexpr size_t LONGEST_VALID_NAME = 1024u; static constexpr int32_t ERROR_CODE = -1; static constexpr int32_t INVALID_FD = -1; + static constexpr char PATH_PREFIX[] = "/tmp/"; /// @brief for calling private constructor in create method friend class DesignPattern::Creation; @@ -58,28 +68,34 @@ class UnixDomainSocket : public DesignPattern::Creation unlinkIfExists(const std::string& name) noexcept; + /// @brief unlink the provided unix domain socket + /// @param NoPathPrefix signalling that this method does not add a path prefix + /// @param name of the unix domain socket to unlink + /// @return true if the unix domain socket could be unlinked, false otherwise, IpcChannelError if error occured + static cxx::expected unlinkIfExists(const NoPathPrefix_t, const std::string& name) noexcept; + /// @brief close the unix domain socket. cxx::expected destroy() noexcept; /// @brief send a message using std::string. /// @param msg to send /// @return IpcChannelError if error occured - cxx::expected send(const std::string& msg) noexcept; + cxx::expected send(const std::string& msg) const noexcept; /// @brief try to send a message for a given timeout duration using std::string /// @param msg to send /// @param timout for the send operation /// @return IpcChannelError if error occured - cxx::expected timedSend(const std::string& msg, const units::Duration& timeout) noexcept; + cxx::expected timedSend(const std::string& msg, const units::Duration& timeout) const noexcept; /// @brief receive message using std::string. /// @return received message. In case of an error, IpcChannelError is returned and msg is empty. - cxx::expected receive() noexcept; + cxx::expected receive() const noexcept; /// @brief try to receive message for a given timeout duration using std::string. /// @param timout for the receive operation /// @return received message. In case of an error, IpcChannelError is returned and msg is empty. - cxx::expected timedReceive(const units::Duration& timeout) noexcept; + cxx::expected timedReceive(const units::Duration& timeout) const noexcept; /// @brief checks whether the unix domain socket is outdated /// @return true if the unix domain socket is outdated, false otherwise, IpcChannelError if error occured @@ -98,6 +114,21 @@ class UnixDomainSocket : public DesignPattern::Creation createErrorFromErrnum(const int32_t errnum) noexcept; + cxx::error createErrorFromErrnum(const int32_t errnum) const noexcept; + + static bool isNameValid(const std::string& name) noexcept; private: std::string m_name; diff --git a/iceoryx_utils/include/iceoryx_utils/internal/units/duration.inl b/iceoryx_utils/include/iceoryx_utils/internal/units/duration.inl index 05375350d8..53b292df02 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/units/duration.inl +++ b/iceoryx_utils/include/iceoryx_utils/internal/units/duration.inl @@ -71,12 +71,12 @@ inline constexpr Duration::Duration(const struct itimerspec& value) } inline constexpr Duration::Duration(const std::chrono::milliseconds& value) - : durationInSeconds(static_cast(value.count()) / 1000.0) + : Duration(static_cast(value.count()) / 1000.0) { } inline constexpr Duration::Duration(const std::chrono::nanoseconds& value) - : durationInSeconds(static_cast(value.count()) / 1000000000.0) + : Duration(static_cast(value.count()) / 1000000000.0) { } diff --git a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/acl.hpp b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/acl.hpp index dab5360cbe..375ea11575 100644 --- a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/acl.hpp +++ b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/acl.hpp @@ -33,17 +33,17 @@ using acl_perm_t = int; using acl_entry_t = int; using acl_tag_t = int; -inline int acl_valid(acl_t acl) +inline int acl_valid(acl_t) { return 0; } -inline int acl_set_fd(int fd, acl_t acl) +inline int acl_set_fd(int, acl_t) { return 0; } -inline acl_t acl_init(int count) +inline acl_t acl_init(int) { static struct __acl_ext stub; return &stub; @@ -54,42 +54,42 @@ inline int acl_free(void*) return 0; } -inline int acl_create_entry(acl_t* acl_p, acl_entry_t* entry_p) +inline int acl_create_entry(acl_t*, acl_entry_t*) { return 0; } -inline int acl_set_tag_type(acl_entry_t entry_d, acl_tag_t tag_type) +inline int acl_set_tag_type(acl_entry_t, acl_tag_t) { return 0; } -inline int acl_set_qualifier(acl_entry_t entry_d, const void* qualifier_p) +inline int acl_set_qualifier(acl_entry_t, const void*) { return 0; } -inline int acl_get_permset(acl_entry_t entry_d, acl_permset_t* permset_p) +inline int acl_get_permset(acl_entry_t, acl_permset_t*) { return 0; } -inline int acl_add_perm(acl_permset_t permset_d, acl_perm_t perm) +inline int acl_add_perm(acl_permset_t, acl_perm_t) { return 0; } -inline char* acl_to_text(acl_t acl, ssize_t* len_p) +inline char* acl_to_text(acl_t, ssize_t*) { return nullptr; } -inline acl_t acl_from_text(const char* buf_p) +inline acl_t acl_from_text(const char*) { return acl_t(); } -inline acl_t acl_get_fd(int fd) +inline acl_t acl_get_fd(int) { return acl_t(); } diff --git a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/grp.hpp b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/grp.hpp index b574d0f41f..87e81592ad 100644 --- a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/grp.hpp +++ b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/grp.hpp @@ -27,7 +27,7 @@ // with the correct argument types and just forward all arguments inline int getgrouplist(const char* user, gid_t group, gid_t* groups, int* ngroups) { - return getgrouplist(user, group, groups, ngroups); + return getgrouplist(user, static_cast(group), reinterpret_cast(groups), ngroups); } #endif // IOX_UTILS_MAC_PLATFORM_GRP_HPP diff --git a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/mqueue.hpp b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/mqueue.hpp index d183a27f63..74e3177ad2 100644 --- a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/mqueue.hpp +++ b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/mqueue.hpp @@ -28,39 +28,37 @@ struct mq_attr long mq_curmsgs; }; -inline int mq_send(mqd_t mqdes, const char* msg_ptr, size_t msg_len, unsigned int msg_prio) +inline int mq_send(mqd_t, const char*, size_t, unsigned int) { return 0; } -inline int mq_timedsend( - mqd_t mqdes, const char* msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec* abs_timeout) +inline int mq_timedsend(mqd_t, const char*, size_t, unsigned int, const struct timespec*) { return 0; } -inline int mq_close(mqd_t mqdes) +inline int mq_close(mqd_t) { return 0; } -inline mqd_t mq_open(const char* name, int oflag, mode_t mode, struct mq_attr* attr) +inline mqd_t mq_open(const char*, int, mode_t, struct mq_attr*) { return 0; } -inline ssize_t mq_receive(mqd_t mqdes, char* msg_ptr, size_t msg_len, unsigned int* msg_prio) +inline ssize_t mq_receive(mqd_t, char*, size_t, unsigned int*) { return 0; } -inline ssize_t -mq_timedreceive(mqd_t mqdes, char* msg_ptr, size_t msg_len, unsigned int* msg_prio, const struct timespec* abs_timeout) +inline ssize_t mq_timedreceive(mqd_t, char*, size_t, unsigned int*, const struct timespec*) { return 0; } -inline int mq_unlink(const char* name) +inline int mq_unlink(const char*) { return 0; } diff --git a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/pthread.hpp b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/pthread.hpp index 22b41321cc..e9ffb5e014 100644 --- a/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/pthread.hpp +++ b/iceoryx_utils/platform/mac/include/iceoryx_utils/platform/pthread.hpp @@ -16,7 +16,7 @@ #include -inline int pthread_setname_np(pthread_t thread, const char* name) +inline int pthread_setname_np(pthread_t, const char* name) { return pthread_setname_np(name); } diff --git a/iceoryx_utils/platform/mac/source/semaphore.cpp b/iceoryx_utils/platform/mac/source/semaphore.cpp index 3db685a6c8..4899b28af8 100644 --- a/iceoryx_utils/platform/mac/source/semaphore.cpp +++ b/iceoryx_utils/platform/mac/source/semaphore.cpp @@ -215,7 +215,7 @@ int iox_sem_destroy(iox_sem_t* sem) return 0; } -int iox_sem_init(iox_sem_t* sem, int pshared, unsigned int value) +int iox_sem_init(iox_sem_t* sem, int, unsigned int value) { sem->m_hasPosixHandle = false; sem->m_handle.dispatch = dispatch_semaphore_create(value); @@ -236,6 +236,11 @@ int iox_sem_unlink(const char* name) iox_sem_t* iox_sem_open_impl(const char* name, int oflag, ...) { + if (strlen(name) == 0 || name[0] == 0) + { + return reinterpret_cast(SEM_FAILED); + } + iox_sem_t* sem = new iox_sem_t; if (oflag & (O_CREAT | O_EXCL)) diff --git a/iceoryx_utils/platform/mac/source/time.cpp b/iceoryx_utils/platform/mac/source/time.cpp index eaea95c2a9..df85a79538 100644 --- a/iceoryx_utils/platform/mac/source/time.cpp +++ b/iceoryx_utils/platform/mac/source/time.cpp @@ -66,7 +66,7 @@ setTimeParameters(timer_t timerid, const itimerspec& timeParameters, const bool timerid->parameter.isTimerRunning = isTimerRunning; } -int timer_create(clockid_t clockid, struct sigevent* sevp, timer_t* timerid) +int timer_create(clockid_t, struct sigevent* sevp, timer_t* timerid) { timer_t timer = new appleTimer_t(); timer->callback = sevp->sigev_notify_function; @@ -103,7 +103,7 @@ int timer_delete(timer_t timerid) return 0; } -int timer_settime(timer_t timerid, int flags, const struct itimerspec* new_value, struct itimerspec* old_value) +int timer_settime(timer_t timerid, int, const struct itimerspec* new_value, struct itimerspec*) { // disarm timer if (new_value->it_value.tv_sec == 0 && new_value->it_value.tv_nsec == 0) @@ -145,7 +145,7 @@ int timer_gettime(timer_t timerid, struct itimerspec* curr_value) return 0; } -int timer_getoverrun(timer_t timerid) +int timer_getoverrun(timer_t) { return 0; } diff --git a/iceoryx_utils/source/cxx/helplets.cpp b/iceoryx_utils/source/cxx/helplets.cpp new file mode 100644 index 0000000000..85e775ca10 --- /dev/null +++ b/iceoryx_utils/source/cxx/helplets.cpp @@ -0,0 +1,30 @@ +#include "iceoryx_utils/cxx/helplets.hpp" + +namespace iox +{ +namespace cxx +{ +void* alignedAlloc(const uint64_t alignment, const uint64_t size) noexcept +{ + // -1 == since the max alignment addition is alignment - 1 otherwise the + // memory is already aligned and we have to do nothing + uint64_t memory = reinterpret_cast(malloc(size + alignment + sizeof(void*) - 1)); + if (memory == 0) + { + return nullptr; + } + uint64_t alignedMemory = align(memory + sizeof(void*), alignment); + reinterpret_cast(alignedMemory)[-1] = reinterpret_cast(memory); + + return reinterpret_cast(alignedMemory); +} + +void alignedFree(void* const memory) +{ + if (memory != nullptr) + { + free(reinterpret_cast(memory)[-1]); + } +} +} // namespace cxx +} // namespace iox diff --git a/iceoryx_utils/source/posix_wrapper/argv_inspection.cpp b/iceoryx_utils/source/posix_wrapper/argv_inspection.cpp deleted file mode 100644 index a0d9cf9f4c..0000000000 --- a/iceoryx_utils/source/posix_wrapper/argv_inspection.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. - -#include "iceoryx_utils/internal/posix_wrapper/argv_inspection.hpp" - -#include -#include - -namespace iox -{ -namespace posix -{ -ArgvInspector::ArgvInspector() -{ - std::fstream fileStream("/proc/self/cmdline", std::fstream::in); - if (fileStream) - { - std::string str; - std::getline(fileStream, str); - m_cmdline.emplace(str); - } -} - -bool ArgvInspector::getCmdlineArgument(const int32_t f_argNumber, std::string& f_argument) const -{ - std::size_t startPos = 0u; - std::size_t endPos = std::string::npos; - - if (!m_cmdline.has_value()) - { - f_argument = std::string(); - return false; - } - - for (int32_t index = 0; index <= f_argNumber; ++index) - { - endPos = m_cmdline->find('\0', startPos); - - if (endPos == std::string::npos) - { - f_argument = std::string(); - return false; - } - - f_argument = m_cmdline->substr(startPos, endPos - startPos); - - startPos = endPos + 1u; - } - - return true; -} -} // namespace posix -} // namespace iox diff --git a/iceoryx_utils/source/posix_wrapper/message_queue.cpp b/iceoryx_utils/source/posix_wrapper/message_queue.cpp index 9585179fdf..2b3b289294 100644 --- a/iceoryx_utils/source/posix_wrapper/message_queue.cpp +++ b/iceoryx_utils/source/posix_wrapper/message_queue.cpp @@ -165,7 +165,7 @@ cxx::expected MessageQueue::destroy() cxx::expected MessageQueue::send(const std::string& msg) const { const size_t messageSize = static_cast(msg.size()) + NULL_TERMINATOR_SIZE; - if (messageSize > m_attributes.mq_msgsize) + if (messageSize > static_cast(m_attributes.mq_msgsize)) { return cxx::error(IpcChannelError::MESSAGE_TOO_LONG); } @@ -318,7 +318,7 @@ cxx::expected MessageQueue::timedReceive(const uni cxx::expected MessageQueue::timedSend(const std::string& msg, const units::Duration& timeout) const { const size_t messageSize = static_cast(msg.size()) + NULL_TERMINATOR_SIZE; - if (messageSize > m_attributes.mq_msgsize) + if (messageSize > static_cast(m_attributes.mq_msgsize)) { std::cerr << "the message \"" << msg << "\" which should be sent to the message queue \"" << m_name << "\" is too long" << std::endl; diff --git a/iceoryx_utils/source/posix_wrapper/timer.cpp b/iceoryx_utils/source/posix_wrapper/timer.cpp index d87e68dcc2..d30cd50e2b 100644 --- a/iceoryx_utils/source/posix_wrapper/timer.cpp +++ b/iceoryx_utils/source/posix_wrapper/timer.cpp @@ -61,8 +61,7 @@ void Timer::OsTimer::callbackHelper(sigval data) auto index = Timer::OsTimerCallbackHandle::sigvalToIndex(data); auto descriptor = Timer::OsTimerCallbackHandle::sigvalToDescriptor(data); - /// @todo cxx::expect - if (index >= Timer::OsTimerCallbackHandle::MAX_DESCRIPTOR_VALUE) + if (static_cast(index) >= Timer::OsTimerCallbackHandle::MAX_DESCRIPTOR_VALUE) { ///@todo decide if to print a warning return; diff --git a/iceoryx_utils/source/posix_wrapper/unix_domain_socket.cpp b/iceoryx_utils/source/posix_wrapper/unix_domain_socket.cpp index a54a89ab52..dd3f2d4ef4 100644 --- a/iceoryx_utils/source/posix_wrapper/unix_domain_socket.cpp +++ b/iceoryx_utils/source/posix_wrapper/unix_domain_socket.cpp @@ -31,6 +31,31 @@ UnixDomainSocket::UnixDomainSocket() noexcept } UnixDomainSocket::UnixDomainSocket(const std::string& name, + const IpcChannelMode mode, + const IpcChannelSide channelSide, + const size_t maxMsgSize, + const uint64_t maxMsgNumber) noexcept + : UnixDomainSocket( + NoPathPrefix, + [&]() -> std::string { + /// invalid names will be forwarded and handled by the other constructor + /// separately + if (!isNameValid(name)) + { + return name; + } + return std::string(PATH_PREFIX) + name; + }(), + mode, + channelSide, + maxMsgSize, + maxMsgNumber) +{ +} + + +UnixDomainSocket::UnixDomainSocket(const NoPathPrefix_t, + const std::string& name, const IpcChannelMode mode, const IpcChannelSide channelSide, const size_t maxMsgSize, @@ -38,6 +63,13 @@ UnixDomainSocket::UnixDomainSocket(const std::string& name, : m_name(name) , m_channelSide(channelSide) { + if (!isNameValid(name)) + { + this->m_isInitialized = false; + this->m_errorValue = IpcChannelError::INVALID_CHANNEL_NAME; + return; + } + if (maxMsgSize > MAX_MESSAGE_SIZE) { this->m_isInitialized = false; @@ -83,6 +115,8 @@ UnixDomainSocket& UnixDomainSocket::operator=(UnixDomainSocket&& other) noexcept m_channelSide = std::move(other.m_channelSide); m_sockfd = std::move(other.m_sockfd); m_sockAddr = std::move(other.m_sockAddr); + m_isInitialized = std::move(other.m_isInitialized); + m_errorValue = std::move(other.m_errorValue); other.m_sockfd = INVALID_FD; m_maxMessageSize = std::move(other.m_maxMessageSize); moveCreationPatternValues(std::move(other)); @@ -93,15 +127,19 @@ UnixDomainSocket& UnixDomainSocket::operator=(UnixDomainSocket&& other) noexcept cxx::expected UnixDomainSocket::unlinkIfExists(const std::string& name) noexcept { - if (name.empty() || name.size() < SHORTEST_VALID_NAME || name.size() > LONGEST_VALID_NAME || name.at(0) != '/') + return unlinkIfExists(NoPathPrefix, std::string(PATH_PREFIX) + name); +} + +cxx::expected UnixDomainSocket::unlinkIfExists(const NoPathPrefix_t, + const std::string& name) noexcept +{ + if (!isNameValid(name)) { return cxx::error(IpcChannelError::INVALID_CHANNEL_NAME); } - auto nameCStr = name.c_str(); - nameCStr++; // don't use the leading '/' for the unix domain socket name auto unlinkCall = - cxx::makeSmartC(unlink, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, {ERROR_CODE}, {ENOENT}, nameCStr); + cxx::makeSmartC(unlink, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, {ERROR_CODE}, {ENOENT}, name.c_str()); if (!unlinkCall.hasErrors()) { @@ -142,19 +180,15 @@ cxx::expected UnixDomainSocket::destroy() noexcept return cxx::success(); } -cxx::expected UnixDomainSocket::send(const std::string& msg) noexcept +cxx::expected UnixDomainSocket::send(const std::string& msg) const noexcept { // we also support timedSend. The setsockopt call sets the timeout for all further sendto calls, so we must set // it to 0 to turn the timeout off - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - - return timedSend(msg, units::Duration(tv)); + return timedSend(msg, units::Duration::seconds(0ULL)); } -cxx::expected UnixDomainSocket::timedSend(const std::string& msg, - const units::Duration& timeout) noexcept +cxx::expected UnixDomainSocket::timedSend(const std::string& msg, const units::Duration& timeout) const + noexcept { if (msg.size() >= m_maxMessageSize) // message sizes with null termination must be smaller than m_maxMessageSize { @@ -168,6 +202,15 @@ cxx::expected UnixDomainSocket::timedSend(const std::string& ms } struct timeval tv = timeout; +#if defined(__APPLE__) + if (tv.tv_sec != 0 || tv.tv_usec != 0) + { + std::cerr + << "socket: \"" << m_name + << "\", timedSend with a timeout != 0 is not supported on MacOS. timedSend will behave like send instead." + << std::endl; + } +#endif auto setsockoptCall = cxx::makeSmartC(setsockopt, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, @@ -207,7 +250,7 @@ cxx::expected UnixDomainSocket::timedSend(const std::string& ms } } -cxx::expected UnixDomainSocket::receive() noexcept +cxx::expected UnixDomainSocket::receive() const noexcept { // we also support timedReceive. The setsockopt call sets the timeout for all further recvfrom calls, so we must set // it to 0 to turn the timeout off @@ -219,7 +262,8 @@ cxx::expected UnixDomainSocket::receive() noexcept } -cxx::expected UnixDomainSocket::timedReceive(const units::Duration& timeout) noexcept +cxx::expected UnixDomainSocket::timedReceive(const units::Duration& timeout) const + noexcept { if (IpcChannelSide::CLIENT == m_channelSide) { @@ -246,11 +290,10 @@ cxx::expected UnixDomainSocket::timedReceive(const else { char message[MAX_MESSAGE_SIZE + 1]; - auto recvCall = cxx::makeSmartC(recvfrom, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, {static_cast(ERROR_CODE)}, - {}, + {EAGAIN}, m_sockfd, &(message[0]), MAX_MESSAGE_SIZE, @@ -261,7 +304,12 @@ cxx::expected UnixDomainSocket::timedReceive(const if (recvCall.hasErrors()) { - // timeout is also an error and would return here + return createErrorFromErrnum(recvCall.getErrNum()); + } + /// we have to handle the timeout separately since it is not actual an + /// error, it is expected behavior. but we have to still inform the user + else if (recvCall.getErrNum() == EAGAIN) + { return createErrorFromErrnum(recvCall.getErrNum()); } else @@ -274,18 +322,10 @@ cxx::expected UnixDomainSocket::timedReceive(const cxx::expected UnixDomainSocket::createSocket(const IpcChannelMode mode) noexcept { - if (m_name.empty() || m_name.size() < SHORTEST_VALID_NAME || m_name.size() > LONGEST_VALID_NAME - || m_name.at(0) != '/') - { - return cxx::error(IpcChannelError::INVALID_CHANNEL_NAME); - } - auto nameCStr = m_name.c_str(); - nameCStr++; // don't use the leading '/' for the unix domain socket name - // initialize the sockAddr data structure with the provided name memset(&m_sockAddr, 0, sizeof(m_sockAddr)); m_sockAddr.sun_family = AF_LOCAL; - strncpy(m_sockAddr.sun_path, nameCStr, m_name.size() - 1); // since we don't use the leading '/' + strncpy(m_sockAddr.sun_path, m_name.c_str(), m_name.size()); // we currently don't support a IpcChannelMode::NON_BLOCKING, for send and receive timouts can be used, the other // calls are blocking @@ -358,7 +398,7 @@ cxx::expected UnixDomainSocket::isOutdated() noexcept } -cxx::error UnixDomainSocket::createErrorFromErrnum(const int32_t errnum) noexcept +cxx::error UnixDomainSocket::createErrorFromErrnum(const int32_t errnum) const noexcept { switch (errnum) { @@ -467,6 +507,11 @@ cxx::error UnixDomainSocket::createErrorFromErrnum(const int32_ std::cerr << "No server for unix domain socket \"" << m_name << "\"" << std::endl; return cxx::error(IpcChannelError::NO_SUCH_CHANNEL); } + case ECONNRESET: + { + std::cerr << "connection was reset by peer for \"" << m_name << "\"" << std::endl; + return cxx::error(IpcChannelError::CONNECTION_RESET_BY_PEER); + } case EWOULDBLOCK: { // no error message needed since this is a normal use case @@ -480,5 +525,12 @@ cxx::error UnixDomainSocket::createErrorFromErrnum(const int32_ } } +bool UnixDomainSocket::isNameValid(const std::string& name) noexcept +{ + return !(name.empty() || name.size() < SHORTEST_VALID_NAME || name.size() > LONGEST_VALID_NAME + || name.at(0) != '/'); +} + + } // namespace posix } // namespace iox diff --git a/iceoryx_utils/source/units/duration.cpp b/iceoryx_utils/source/units/duration.cpp index 69bfafc270..af9e376df4 100644 --- a/iceoryx_utils/source/units/duration.cpp +++ b/iceoryx_utils/source/units/duration.cpp @@ -21,10 +21,12 @@ namespace units { struct timespec Duration::timespec(const TimeSpecReference& reference) const { + constexpr int64_t NanoSecondsPerSecond{1000000000}; if (reference == TimeSpecReference::None) { - return {this->seconds(), - static_cast(this->nanoSeconds() - this->seconds() * 1000000000)}; + int64_t timeInNanoSeconds = this->nanoSeconds(); + int64_t seconds = timeInNanoSeconds / NanoSecondsPerSecond; + return {seconds, timeInNanoSeconds - seconds * NanoSecondsPerSecond}; } else { @@ -41,11 +43,12 @@ struct timespec Duration::timespec(const TimeSpecReference& reference) const } else { - constexpr int64_t NanoSecondsPerSecond{1000000000}; - int64_t remainingNanoSecondsTimeout = this->nanoSeconds() % NanoSecondsPerSecond; + int64_t timeInNanoSeconds = this->nanoSeconds(); + int64_t remainingNanoSecondsTimeout = timeInNanoSeconds % NanoSecondsPerSecond; int64_t sumOfNanoSeconds = remainingNanoSecondsTimeout + referenceTime.tv_nsec; - int64_t seconds = this->seconds() + referenceTime.tv_sec + sumOfNanoSeconds / NanoSecondsPerSecond; - int64_t nanoSeconds = sumOfNanoSeconds - (sumOfNanoSeconds / NanoSecondsPerSecond) * NanoSecondsPerSecond; + int64_t additionalSeconds = sumOfNanoSeconds / NanoSecondsPerSecond; + int64_t seconds = timeInNanoSeconds / NanoSecondsPerSecond + referenceTime.tv_sec + additionalSeconds; + int64_t nanoSeconds = sumOfNanoSeconds - additionalSeconds * NanoSecondsPerSecond; return {seconds, nanoSeconds}; } diff --git a/iceoryx_utils/test/moduletests/test_lockfree_queue_concurrent.cpp b/iceoryx_utils/test/integrationtests/test_lockfree_queue_stresstest.cpp similarity index 93% rename from iceoryx_utils/test/moduletests/test_lockfree_queue_concurrent.cpp rename to iceoryx_utils/test/integrationtests/test_lockfree_queue_stresstest.cpp index 80a8573d24..4eb2e087c7 100755 --- a/iceoryx_utils/test/moduletests/test_lockfree_queue_concurrent.cpp +++ b/iceoryx_utils/test/integrationtests/test_lockfree_queue_stresstest.cpp @@ -347,12 +347,16 @@ using LargeQueue = TestQueue<1000000>; typedef ::testing::Types TestQueues; // typedef ::testing::Types TestQueues; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(LockFreeQueueStressTest, TestQueues); +#pragma GCC diagnostic pop ///@brief Tests concurrent operation of one prodcuer and one consumer /// The producer pushes a fixed number of data elements which the consumer pops and checks. /// The order of popped elements and completeness (no data loss) is checked. -TYPED_TEST(LockFreeQueueStressTest, singleProducerSingleConsumer) +TYPED_TEST(LockFreeQueueStressTest, DISABLED_singleProducerSingleConsumer) { using Queue = typename TestFixture::Queue; @@ -375,7 +379,7 @@ TYPED_TEST(LockFreeQueueStressTest, singleProducerSingleConsumer) ///@brief Tests concurrent operation of multiple prodcuers and one consumer. /// The producers push a fixed number of data elements which the consumer pops and checks. /// The order of popped elements and completeness (no data loss) is checked. -TYPED_TEST(LockFreeQueueStressTest, multiProducerSingleConsumer) +TYPED_TEST(LockFreeQueueStressTest, DISABLED_multiProducerSingleConsumer) { using Queue = typename TestFixture::Queue; @@ -414,7 +418,7 @@ TYPED_TEST(LockFreeQueueStressTest, multiProducerSingleConsumer) /// with multiple consumers > 2, so for now we just do this for 2 consumers. /// This is especially the case for many producers/iterations since we need to store intermediate /// states from the consumers to check later (which can get quite large). -TYPED_TEST(LockFreeQueueStressTest, multiProducerTwoConsumer) +TYPED_TEST(LockFreeQueueStressTest, DISABLED_multiProducerTwoConsumer) { using Queue = typename TestFixture::Queue; @@ -456,7 +460,7 @@ TYPED_TEST(LockFreeQueueStressTest, multiProducerTwoConsumer) /// data item back into the queue. /// Finally it is checked whether the queue still contains all elements it was initialized with ///(likely in a different order). -TYPED_TEST(LockFreeQueueStressTest, timedMultiProducerMultiConsumer) +TYPED_TEST(LockFreeQueueStressTest, DISABLED_timedMultiProducerMultiConsumer) { using Queue = typename TestFixture::Queue; @@ -526,7 +530,7 @@ TYPED_TEST(LockFreeQueueStressTest, timedMultiProducerMultiConsumer) /// aggregated over the queue and the local lists of each thread /// all elements occur exactly as often as there are threads + 1 (i.e. nothing was lost, the +1 is /// due to the initial values in the queue itself). -TYPED_TEST(LockFreeQueueStressTest, timedMultiProducerMultiConsumer0verflow) +TYPED_TEST(LockFreeQueueStressTest, DISABLED_timedMultiProducerMultiConsumer0verflow) { using Queue = typename TestFixture::Queue; @@ -613,4 +617,4 @@ TYPED_TEST(LockFreeQueueStressTest, timedMultiProducerMultiConsumer0verflow) EXPECT_EQ(testResult, true); } -} // namespace \ No newline at end of file +} // namespace diff --git a/iceoryx_utils/test/moduletests/test_argv_inspection.cpp b/iceoryx_utils/test/moduletests/test_argv_inspection.cpp deleted file mode 100644 index 76e9d539ee..0000000000 --- a/iceoryx_utils/test/moduletests/test_argv_inspection.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. - -#include "iceoryx_utils/internal/posix_wrapper/argv_inspection.hpp" - -#include -#include - -using namespace ::testing; - -/// @note This test should be called with multiple command line arguments! - -// this global variable are set in main in test_utils_modules.cpp -extern int g_argc; -extern char** g_argv; - -TEST(ArgvInspector_test, compare_arguments) -{ - iox::posix::ArgvInspector argvInspector; - - ASSERT_THAT(g_argc, Ge(1)); - - int argNum = 0; - for(int i = 0; argNum < g_argc; ++i) - { - - std::string argUnderTest; - ASSERT_TRUE(argvInspector.getCmdlineArgument(i, argUnderTest)); - - // parameters starting with "--gtest" are filtered by gtest and not passed the the application - // therefore the params differ from the ones in /proc/self/cmdline - if(argUnderTest.rfind("--gtest", 0) == 0) - { - continue; - } - - ASSERT_EQ(g_argv[argNum], argUnderTest); - argNum++; - } -} diff --git a/iceoryx_utils/test/moduletests/test_bidirectional_communication_channel.cpp b/iceoryx_utils/test/moduletests/test_bidirectional_communication_channel.cpp deleted file mode 100644 index e3d8274ecf..0000000000 --- a/iceoryx_utils/test/moduletests/test_bidirectional_communication_channel.cpp +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. - -#include "iceoryx_utils/communication_channel/bidirectional_communication_channel.hpp" -#include "iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp" - -#include -#include -#include - -using namespace testing; -using namespace iox; -using namespace iox::units; - -template -class BidirectionalCommunicationChannel_Test : public Test -{ - public: - BidirectionalCommunicationChannel_Test() - : sut() - , transceiverA2B(sut.getFirstTransceiver()) - , transceiverB2A(sut.getSecondTransceiver()) - { - } - - void SetUp() override - { - } - - void TearDown() override - { - } - - typename BidirectionalCommunicationChannel_t::TransportLayer_t transportLayerA2B; - typename BidirectionalCommunicationChannel_t::TransportLayer_t transportLayerB2A; - BidirectionalCommunicationChannel_t sut; - typename BidirectionalCommunicationChannel_t::Transceiver_t* transceiverA2B; - typename BidirectionalCommunicationChannel_t::Transceiver_t* transceiverB2A; -}; - -template -using FiFoTestProtocol = FiFoProtocol; - -using Implementations = Types>; -TYPED_TEST_CASE(BidirectionalCommunicationChannel_Test, Implementations); - -TYPED_TEST(BidirectionalCommunicationChannel_Test, SendAndTryReceiveA2B) -{ - ASSERT_THAT(this->transceiverA2B->Send(313), Eq(true)); - auto result = this->transceiverB2A->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(313)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, SendAndTryReceiveB2A) -{ - ASSERT_THAT(this->transceiverB2A->Send(5313), Eq(true)); - auto result = this->transceiverA2B->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(5313)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, TryReceiveWithoutSendA2B) -{ - auto result = this->transceiverA2B->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, TryReceiveWithoutSendB2A) -{ - auto result = this->transceiverB2A->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, MultiSendAndTryReceiveA2B) -{ - int limit = 14; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transceiverA2B->Send(i * 87), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->transceiverB2A->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 87)); - } -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, MultiSendAndTryReceiveB2A) -{ - int limit = 15; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transceiverB2A->Send(i * 71), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->transceiverA2B->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 71)); - } -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, OneSendAndTwoTryReceiveA2B) -{ - ASSERT_THAT(this->transceiverA2B->Send(781), Eq(true)); - - auto result = this->transceiverB2A->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(781)); - - auto result2 = this->transceiverB2A->TryReceive(); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, OneSendAndTwoTryReceiveB2A) -{ - ASSERT_THAT(this->transceiverB2A->Send(983), Eq(true)); - - auto result = this->transceiverA2B->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(983)); - - auto result2 = this->transceiverA2B->TryReceive(); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, SendAndTimedReceiveA2B) -{ - ASSERT_THAT(this->transceiverA2B->Send(313), Eq(true)); - auto result = this->transceiverB2A->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(313)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, SendAndTimedReceiveB2A) -{ - ASSERT_THAT(this->transceiverB2A->Send(5313), Eq(true)); - auto result = this->transceiverA2B->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(5313)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, TimedReceiveWithoutSendA2B) -{ - auto result = this->transceiverA2B->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, TimedReceiveWithoutSendB2A) -{ - auto result = this->transceiverB2A->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, MultiSendAndTimedReceiveA2B) -{ - int limit = 14; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transceiverA2B->Send(i * 87), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->transceiverB2A->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 87)); - } -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, MultiSendAndTimedReceiveB2A) -{ - int limit = 15; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transceiverB2A->Send(i * 71), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->transceiverA2B->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 71)); - } -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, OneSendAndTwoTimedReceiveA2B) -{ - ASSERT_THAT(this->transceiverA2B->Send(781), Eq(true)); - - auto result = this->transceiverB2A->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(781)); - - auto result2 = this->transceiverB2A->timedReceive(1_ms); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, OneSendAndTwoTimedReceiveB2A) -{ - ASSERT_THAT(this->transceiverB2A->Send(983), Eq(true)); - - auto result = this->transceiverA2B->timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(983)); - - auto result2 = this->transceiverA2B->timedReceive(1_ms); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, SendAndBlockingReceiveA2B) -{ - ASSERT_THAT(this->transceiverA2B->Send(313), Eq(true)); - auto result = this->transceiverB2A->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(313)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, SendAndBlockingReceiveB2A) -{ - ASSERT_THAT(this->transceiverB2A->Send(5313), Eq(true)); - auto result = this->transceiverA2B->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(5313)); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, MultiSendAndBlockingReceiveA2B) -{ - int limit = 14; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transceiverA2B->Send(i * 87), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->transceiverB2A->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 87)); - } -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, MultiSendAndBlockingReceiveB2A) -{ - int limit = 15; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transceiverB2A->Send(i * 71), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->transceiverA2B->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 71)); - } -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, BlockingReceiveIsBlockingTillDataIsSendA2B) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->transceiverB2A->BlockingReceive(); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->transceiverA2B->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, BlockingReceiveIsBlockingTillDataIsSendB2A) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->transceiverA2B->BlockingReceive(); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->transceiverB2A->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, TimedReceiveIsBlockingTillDataIsSendA2B) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->transceiverB2A->BlockingReceive(); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->transceiverA2B->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -TYPED_TEST(BidirectionalCommunicationChannel_Test, TimedReceiveIsBlockingTillDataIsSendB2A) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->transceiverA2B->BlockingReceive(); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->transceiverB2A->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -namespace BidirectionalCommunicationChannelTestInternals -{ -static std::string ctorTest; -template -class TestProtocol -{ - public: - TestProtocol(const std::string& testName) - { - ctorTest.append(testName); - } - bool Send(const T& f_message) - { - return true; - } - cxx::optional TryReceive() - { - return cxx::nullopt_t(); - } - cxx::optional BlockingReceive() - { - return cxx::nullopt_t(); - } - cxx::optional timedReceive(const units::Duration&) - { - return cxx::nullopt_t(); - } -}; -} // namespace BidirectionalCommunicationChannelTestInternals - -TEST(BidirectionalCommunicationChannel_BaseTest, ConstructorArgumentsForTransportLayer) -{ - BidirectionalCommunicationChannel sut("ctor1", - "ctor2"); - EXPECT_THAT(BidirectionalCommunicationChannelTestInternals::ctorTest, Eq("ctor1ctor2")); -} diff --git a/iceoryx_utils/test/moduletests/test_communication_channel_generic_protocol.cpp b/iceoryx_utils/test/moduletests/test_communication_channel_generic_protocol.cpp deleted file mode 100644 index f32cb1c6bf..0000000000 --- a/iceoryx_utils/test/moduletests/test_communication_channel_generic_protocol.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. - -#include "iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp" - -#include -#include -#include - -using namespace testing; -using namespace iox; -using namespace iox::units; - -/// @brief Every communication channel protocol MUST pass this test. To add a -/// new protocol procede as following: -/// 1. create a new factory method for your protocol -/// template<> MyNewProtocol * CreateProtocol() ... -/// 2. Add the new protocol into the Implementations alias like -/// using Implementations = Types<...., MyNewProtocol >; -/// If all tests are passing you are ready to go! - -template -T* CreateProtocol(); - -template -using FiFoTestProtocol = FiFoProtocol; - - -template <> -FiFoTestProtocol* CreateProtocol() -{ - return new FiFoTestProtocol(); -} - -template -class CommunicationChannelGenericProtocol_Test : public Test -{ - public: - CommunicationChannelGenericProtocol_Test() - : sut(CreateProtocol()) - { - } - - ~CommunicationChannelGenericProtocol_Test() - { - delete sut; - } - - void SetUp() override - { - } - - void TearDown() override - { - } - - CommunicationChannelGenericProtocol_t* sut; -}; - -using Implementations = Types>; -TYPED_TEST_CASE(CommunicationChannelGenericProtocol_Test, Implementations); - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, SendAndTryReceive) -{ - ASSERT_THAT(this->sut->Send(313), Eq(true)); - auto result = this->sut->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(313)); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, TryReceiveWithoutSend) -{ - auto result = this->sut->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, MultipleSendAndTryReceive) -{ - int limit = 12; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->sut->Send(i), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->sut->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, OneSendTwoTryReceive) -{ - ASSERT_THAT(this->sut->Send(8001), Eq(true)); - - auto result = this->sut->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(8001)); - - auto result2 = this->sut->TryReceive(); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, SendAndBlockingReceive) -{ - ASSERT_THAT(this->sut->Send(6313), Eq(true)); - auto result = this->sut->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(6313)); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, MultipleSendAndBlockingReceive) -{ - int limit = 12; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->sut->Send(i * 5), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->sut->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 5)); - } -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, SendAndTimedReceive) -{ - ASSERT_THAT(this->sut->Send(313), Eq(true)); - auto result = this->sut->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(313)); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, TimedReceiveWithoutSend) -{ - auto result = this->sut->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, MultipleSendAndTimedReceive) -{ - int limit = 12; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->sut->Send(i), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->sut->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, OneSendTwoTimedReceive) -{ - ASSERT_THAT(this->sut->Send(8001), Eq(true)); - - auto result = this->sut->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(8001)); - - auto result2 = this->sut->timedReceive(10_ms); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, BlockingReceiveIsBlockingTillDataIsSend) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->sut->BlockingReceive(); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->sut->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, TimedReceiveIsBlockingTillDataIsSend) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->sut->timedReceive(1000_s); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->sut->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -TYPED_TEST(CommunicationChannelGenericProtocol_Test, TimedReceiveHasTimeout) -{ - std::atomic_bool hasTimeout{false}; - std::thread t1([&] { - this->sut->timedReceive(100_ms); - hasTimeout.store(true); - }); - - ASSERT_THAT(hasTimeout.load(), Eq(false)); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - ASSERT_THAT(hasTimeout.load(), Eq(true)); - - t1.join(); -} diff --git a/iceoryx_utils/test/moduletests/test_communication_channel_receiver.cpp b/iceoryx_utils/test/moduletests/test_communication_channel_receiver.cpp deleted file mode 100644 index ed402f49db..0000000000 --- a/iceoryx_utils/test/moduletests/test_communication_channel_receiver.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. - -#include "iceoryx_utils/internal/communication_channel/receiver.hpp" -#include "iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp" - -#include -#include -#include - -using namespace testing; -using namespace iox; -using namespace iox::units; - - -template -class CommunicationChannelReceiver_Test : public Test -{ - public: - CommunicationChannelReceiver_Test() - : sut(&transportLayer) - { - } - - void SetUp() override - { - } - - void TearDown() override - { - } - - typename Receiver_t::TransportLayer_t transportLayer; - Receiver_t sut; -}; - -template -using FiFoTestProtocol = FiFoProtocol; - -using Implementations = Types>; -TYPED_TEST_CASE(CommunicationChannelReceiver_Test, Implementations); - -TYPED_TEST(CommunicationChannelReceiver_Test, TryReceiveWithoutSample) -{ - auto result = this->sut.TryReceive(); - EXPECT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(CommunicationChannelReceiver_Test, TryReceiveWithSample) -{ - this->transportLayer.Send(123); - auto result = this->sut.TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(123)); -} - -TYPED_TEST(CommunicationChannelReceiver_Test, TryReceiveMultipleSampleCorrectOrdering) -{ - int limit = 10; - for (int i = 0; i < limit; ++i) - this->transportLayer.Send(i); - - for (int i = 0; i < limit; ++i) - { - auto result = this->sut.TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} - -TYPED_TEST(CommunicationChannelReceiver_Test, BlockingReceiveWithSample) -{ - this->transportLayer.Send(912); - auto result = this->sut.BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(912)); -} - -TYPED_TEST(CommunicationChannelReceiver_Test, BlockingReceiveMultipleSampleCorrectOrdering) -{ - int limit = 10; - for (int i = 0; i < limit; ++i) - this->transportLayer.Send(i); - - for (int i = 0; i < limit; ++i) - { - auto result = this->sut.BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} - -TYPED_TEST(CommunicationChannelReceiver_Test, TimedReceiveWithoutSample) -{ - auto result = this->sut.timedReceive(1_ms); - EXPECT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(CommunicationChannelReceiver_Test, TimedReceiveWithSample) -{ - this->transportLayer.Send(123); - auto result = this->sut.timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(123)); -} - -TYPED_TEST(CommunicationChannelReceiver_Test, TimedReceiveMultipleSampleCorrectOrdering) -{ - int limit = 10; - for (int i = 0; i < limit; ++i) - this->transportLayer.Send(i); - - for (int i = 0; i < limit; ++i) - { - auto result = this->sut.timedReceive(1_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} - -TYPED_TEST(CommunicationChannelReceiver_Test, BlockingReceiveIsBlocking) -{ - std::atomic_bool hasReceivedData{false}; - - std::thread t([&] { - auto result = this->sut.BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(9192)); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - - this->transportLayer.Send(9192); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - t.join(); -} - -TYPED_TEST(CommunicationChannelReceiver_Test, TimedReceiveIsBlocking) -{ - std::atomic_bool hasReceivedData{false}; - - std::thread t([&] { - auto result = this->sut.timedReceive(1_d); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(9112)); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - - this->transportLayer.Send(9112); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - t.join(); -} - -TYPED_TEST(CommunicationChannelReceiver_Test, TimedReceiveHasTimeout) -{ - std::atomic_bool hasTimeoutOccurred{false}; - - std::thread t([&] { - auto result = this->sut.timedReceive(100_ms); - ASSERT_THAT(result.has_value(), Eq(false)); - hasTimeoutOccurred.store(true); - }); - - ASSERT_THAT(hasTimeoutOccurred.load(), Eq(false)); - - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - ASSERT_THAT(hasTimeoutOccurred.load(), Eq(true)); - t.join(); -} diff --git a/iceoryx_utils/test/moduletests/test_communication_channel_transmitter.cpp b/iceoryx_utils/test/moduletests/test_communication_channel_transmitter.cpp deleted file mode 100644 index 517f613f9d..0000000000 --- a/iceoryx_utils/test/moduletests/test_communication_channel_transmitter.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. - -#include "iceoryx_utils/internal/communication_channel/transmitter.hpp" -#include "iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp" - -#include -#include -#include - -using namespace testing; -using namespace iox; -using namespace iox::units; - -template -class CommunicationChannelTransmitter_Test : public Test -{ - public: - CommunicationChannelTransmitter_Test() - : sut(&transportLayer) - { - } - - void SetUp() override - { - } - - void TearDown() override - { - } - - typename Transmitter_t::TransportLayer_t transportLayer; - Transmitter_t sut; -}; - -template -using FiFoTestProtocol = FiFoProtocol; - -using Implementations = Types>; -TYPED_TEST_CASE(CommunicationChannelTransmitter_Test, Implementations); - -TYPED_TEST(CommunicationChannelTransmitter_Test, SuccessfulSend) -{ - ASSERT_THAT(this->sut.Send(441), Eq(true)); - auto result = this->transportLayer.TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(441)); -} - -TYPED_TEST(CommunicationChannelTransmitter_Test, SuccessfulMultiSend) -{ - int limit = 10; - for (int i = 0; i < limit; ++i) - { - ASSERT_THAT(this->sut.Send(i), Eq(true)); - } - - for (int i = 0; i < limit; ++i) - { - auto result = this->transportLayer.TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} diff --git a/iceoryx_utils/test/moduletests/test_concurrent_loffli.cpp b/iceoryx_utils/test/moduletests/test_concurrent_loffli.cpp index ee9cb2c496..6bb0fe5f70 100644 --- a/iceoryx_utils/test/moduletests/test_concurrent_loffli.cpp +++ b/iceoryx_utils/test/moduletests/test_concurrent_loffli.cpp @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "test.hpp" #include "iceoryx_utils/internal/concurrent/locked_loffli.hpp" #include "iceoryx_utils/internal/concurrent/loffli.hpp" +#include "test.hpp" #include #include @@ -25,7 +25,11 @@ using namespace ::testing; constexpr uint32_t Size{4}; using LoFFLiTestSubjects = Types; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(LoFFLi_test, LoFFLiTestSubjects); +#pragma GCC diagnostic pop template class LoFFLi_test : public Test diff --git a/iceoryx_utils/test/moduletests/test_concurrent_trigger_queue.cpp b/iceoryx_utils/test/moduletests/test_concurrent_trigger_queue.cpp index f15f7356c6..894888dd33 100644 --- a/iceoryx_utils/test/moduletests/test_concurrent_trigger_queue.cpp +++ b/iceoryx_utils/test/moduletests/test_concurrent_trigger_queue.cpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "test.hpp" #include "iceoryx_utils/internal/concurrent/trigger_queue.hpp" +#include "test.hpp" using namespace ::testing; @@ -44,7 +44,11 @@ constexpr uint64_t GetCapacity(iox::concurrent::TriggerQueue&) using TriggerQueueTestSubjects = Types, iox::concurrent::TriggerQueue, iox::concurrent::TriggerQueue>; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(TriggerQueue_test, TriggerQueueTestSubjects); +#pragma GCC diagnostic pop TYPED_TEST(TriggerQueue_test, EmptyWhenEmpty) { diff --git a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp index 2471502908..75f3fca49b 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "test.hpp" #include "iceoryx_utils/cxx/helplets.hpp" +#include "test.hpp" using namespace ::testing; @@ -21,19 +21,19 @@ namespace { class Bar { - alignas(8) uint8_t m_dummy[73]; + [[gnu::unused]] alignas(8) uint8_t m_dummy[73]; }; class Foo { - uint8_t m_dummy[73]; + [[gnu::unused]] uint8_t m_dummy[73]; }; class FooBar { - alignas(32) uint8_t m_dummy[73]; + [[gnu::unused]] alignas(32) uint8_t m_dummy[73]; }; class FuBar { - alignas(32) uint8_t m_dummy[73]; + [[gnu::unused]] alignas(32) uint8_t m_dummy[73]; }; } // namespace diff --git a/iceoryx_utils/test/moduletests/test_cxx_poor_mans_heap.cpp b/iceoryx_utils/test/moduletests/test_cxx_poor_mans_heap.cpp index 4dd09a5dfa..a641eee4b9 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_poor_mans_heap.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_poor_mans_heap.cpp @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "test.hpp" -#include "iceoryx_utils/cxx/poor_mans_heap.hpp" #include "iceoryx_utils/cxx/helplets.hpp" - +#include "iceoryx_utils/cxx/poor_mans_heap.hpp" +#include "test.hpp" using namespace ::testing; @@ -93,7 +92,7 @@ class Foo : public Interface } private: - alignas(32) uint8_t m_dummy[73]; + [[gnu::unused]] alignas(32) uint8_t m_dummy[73]; }; } // namespace diff --git a/iceoryx_utils/test/moduletests/test_cxx_string.cpp b/iceoryx_utils/test/moduletests/test_cxx_string.cpp index c85950139c..370b4bf06d 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_string.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_string.cpp @@ -28,7 +28,11 @@ class stringTyped_test : public Test }; using Implementations = Types, string<15>, string<100>, string<1000>>; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(stringTyped_test, Implementations); +#pragma GCC diagnostic pop /// @note string() noexcept TYPED_TEST(stringTyped_test, EmptyInitializationResultsInSize0) diff --git a/iceoryx_utils/test/moduletests/test_cxx_vector.cpp b/iceoryx_utils/test/moduletests/test_cxx_vector.cpp index 61d723ab43..4613682d01 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_vector.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_vector.cpp @@ -899,3 +899,138 @@ TEST_F(vector_test, ConstructorWithSizeParameterGreaterThanCapacity) EXPECT_THAT(vector_test::copyCTor, Eq(5)); ASSERT_THAT(sut.size(), Eq(5)); } + +TEST_F(vector_test, TwoEmptyVectorOfSameCapacityAreEqual) +{ + vector a, b; + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +TEST_F(vector_test, TwoEmptyVectorOfDifferentCapacityAreEqual) +{ + vector a; + vector b; + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +TEST_F(vector_test, TwoEqualVectorsWithSameCapacityAreEqual) +{ + vector a, b; + a.emplace_back(1); + a.emplace_back(2); + a.emplace_back(3); + + b.emplace_back(1); + b.emplace_back(2); + b.emplace_back(3); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +TEST_F(vector_test, TwoEqualVectorsWithDifferentCapacityAreEqual) +{ + vector a; + a.emplace_back(4); + a.emplace_back(5); + a.emplace_back(6); + + vector b; + b.emplace_back(4); + b.emplace_back(5); + b.emplace_back(6); + + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); +} + +TEST_F(vector_test, TwoVectorsWithDifferentSizeAndSameCapacityAreNotEqual) +{ + vector a, b; + a.emplace_back(7); + a.emplace_back(8); + a.emplace_back(9); + + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); +} + +TEST_F(vector_test, TwoNonEqualVectorsWithDifferentCapacityAreNotEqual) +{ + vector a; + a.emplace_back(7); + a.emplace_back(8); + a.emplace_back(9); + + vector b; + b.emplace_back(1); + b.emplace_back(2); + b.emplace_back(3); + + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); +} + +TEST_F(vector_test, SubsetVectorWithSameCapacityIsNotEqual) +{ + vector a, b; + a.emplace_back(7); + a.emplace_back(8); + a.emplace_back(9); + + b.emplace_back(7); + b.emplace_back(8); + + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); +} + +TEST_F(vector_test, SubsetVectorWithDifferentCapacityIsNotEqual) +{ + vector a; + a.emplace_back(11); + a.emplace_back(12); + a.emplace_back(13); + + vector b; + b.emplace_back(11); + b.emplace_back(12); + + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); +} + +TEST_F(vector_test, PartiallyEqualVectorsWithSameCapacityAreNotEqual) +{ + vector a, b; + a.emplace_back(14); + a.emplace_back(15); + a.emplace_back(16); + + b.emplace_back(14); + b.emplace_back(15); + b.emplace_back(666); + + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); +} + +TEST_F(vector_test, PartiallyEqualVectorsWithDifferentCapacityAreNotEqual) +{ + vector a; + a.emplace_back(17); + a.emplace_back(18); + a.emplace_back(19); + + vector b; + b.emplace_back(17); + b.emplace_back(18); + b.emplace_back(999); + + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); +} diff --git a/iceoryx_utils/test/moduletests/test_index_queue.cpp b/iceoryx_utils/test/moduletests/test_index_queue.cpp index e752e32833..efc2c9ad55 100644 --- a/iceoryx_utils/test/moduletests/test_index_queue.cpp +++ b/iceoryx_utils/test/moduletests/test_index_queue.cpp @@ -57,7 +57,11 @@ TEST(LockFreeQueueTest, capacityIsConsistent) typedef ::testing::Types, IndexQueue<10>, IndexQueue<1000>> TestQueues; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(IndexQueueTest, TestQueues); +#pragma GCC diagnostic pop TYPED_TEST(IndexQueueTest, defaultConstructedQueueIsEmpty) diff --git a/iceoryx_utils/test/moduletests/test_index_queue_unique_index.cpp b/iceoryx_utils/test/moduletests/test_index_queue_unique_index.cpp index b865cdd057..d44e53bbae 100644 --- a/iceoryx_utils/test/moduletests/test_index_queue_unique_index.cpp +++ b/iceoryx_utils/test/moduletests/test_index_queue_unique_index.cpp @@ -128,8 +128,11 @@ TEST_F(UniqueIndexTest, moveAssignmentInvalidatesValidIndex) TEST_F(UniqueIndexTest, selfMoveAssignmentDoesNotInvalidateValidIndex) { auto index = acquireIndex(); - + /// we are testing self move here therefore we do not need a warning that we do +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wself-move" index = std::move(index); +#pragma GCC diagnostic pop EXPECT_TRUE(index.isValid()); EXPECT_EQ(index, 1); } @@ -138,7 +141,11 @@ TEST_F(UniqueIndexTest, selfMoveAssignedInvalidIndexStaysInvalid) { UniqueIndex index(UniqueIndex::invalid); + /// we are testing self move here therefore we do not need a warning that we do +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wself-move" index = std::move(index); +#pragma GCC diagnostic pop EXPECT_FALSE(index.isValid()); } @@ -207,4 +214,4 @@ TEST_F(UniqueIndexTest, conversionToValueTypeDoesNotInvalidateIndex) } -} // namespace \ No newline at end of file +} // namespace diff --git a/iceoryx_utils/test/moduletests/test_lockfree_queue.cpp b/iceoryx_utils/test/moduletests/test_lockfree_queue.cpp index 23828eed60..1597fcb924 100755 --- a/iceoryx_utils/test/moduletests/test_lockfree_queue.cpp +++ b/iceoryx_utils/test/moduletests/test_lockfree_queue.cpp @@ -86,7 +86,11 @@ TEST(LockFreeQueueTest, capacityIsConsistent) // for Integer and int (primarily for tryPush) typedef ::testing::Types, IntegerQueue<10>, IntQueue<10>> TestQueues; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(LockFreeQueueTest, TestQueues); +#pragma GCC diagnostic pop TYPED_TEST(LockFreeQueueTest, constructedQueueIsEmpty) { @@ -253,4 +257,4 @@ TYPED_TEST(LockFreeQueueTest, checkEmptynessAfterFullQueueWasEmptied) EXPECT_EQ(q.size(), 0); } -} // namespace \ No newline at end of file +} // namespace diff --git a/iceoryx_utils/test/moduletests/test_lockfree_queue_buffer.cpp b/iceoryx_utils/test/moduletests/test_lockfree_queue_buffer.cpp index 3bc761d4b6..4f52b63ba9 100644 --- a/iceoryx_utils/test/moduletests/test_lockfree_queue_buffer.cpp +++ b/iceoryx_utils/test/moduletests/test_lockfree_queue_buffer.cpp @@ -83,7 +83,11 @@ TEST(LockFreeQueueBufferTest, capacityIsCorrect) typedef ::testing::Types, Buffer> TestBuffers; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(LockFreeQueueBufferTest, TestBuffers); +#pragma GCC diagnostic pop TYPED_TEST(LockFreeQueueBufferTest, accessElements) { @@ -149,4 +153,4 @@ TYPED_TEST(LockFreeQueueBufferTest, accessElementsOfConstBufferViaPtr) } } -} // namespace \ No newline at end of file +} // namespace diff --git a/iceoryx_utils/test/moduletests/test_lockfree_queue_cyclic_index.cpp b/iceoryx_utils/test/moduletests/test_lockfree_queue_cyclic_index.cpp index a850c8142d..d56345b28d 100644 --- a/iceoryx_utils/test/moduletests/test_lockfree_queue_cyclic_index.cpp +++ b/iceoryx_utils/test/moduletests/test_lockfree_queue_cyclic_index.cpp @@ -47,7 +47,11 @@ class LockFreeQueueCyclicIndexTest : public ::testing::Test typedef ::testing::Types, CyclicIndex<2>, CyclicIndex<10>, CyclicIndex<1000>> TestIndices; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(LockFreeQueueCyclicIndexTest, TestIndices); +#pragma GCC diagnostic pop // note that in all tests we will check whether the getCycle and getIndex methods // behave as expected after certain operations (mainly addition), @@ -166,7 +170,11 @@ TYPED_TEST(LockFreeQueueCyclicIndexTest, selfAssignmentWorks) const auto c = Index::MAX_CYCLE / 2; Index index(i, c); +/// we are testing self assignment +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wself-assign-overloaded" index = index; +#pragma GCC diagnostic pop EXPECT_EQ(index.getIndex(), i); EXPECT_EQ(index.getCycle(), c); diff --git a/iceoryx_utils/test/moduletests/test_logger.cpp b/iceoryx_utils/test/moduletests/test_logger.cpp index 47425a4a8a..506e21b061 100644 --- a/iceoryx_utils/test/moduletests/test_logger.cpp +++ b/iceoryx_utils/test/moduletests/test_logger.cpp @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "test.hpp" +#include "iceoryx_utils/cxx/optional.hpp" #include "iceoryx_utils/log/logger.hpp" #include "iceoryx_utils/log/logging.hpp" -#include "iceoryx_utils/cxx/optional.hpp" +#include "test.hpp" #include #include @@ -135,6 +135,9 @@ class IoxLoggerLogLevel_test : public TestWithParam, public } }; +/// we require INSTANTIATE_TEST_CASE_P since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" INSTANTIATE_TEST_CASE_P(AllLogLevel, IoxLoggerLogLevel_test, Values(iox::log::LogLevel::kOff, @@ -144,6 +147,7 @@ INSTANTIATE_TEST_CASE_P(AllLogLevel, iox::log::LogLevel::kInfo, iox::log::LogLevel::kDebug, iox::log::LogLevel::kVerbose)); +#pragma GCC diagnostic pop TEST_P(IoxLoggerLogLevel_test, LogLevel) { diff --git a/iceoryx_utils/test/moduletests/test_logstream.cpp b/iceoryx_utils/test/moduletests/test_logstream.cpp index df196b22a7..48f3cb2b02 100644 --- a/iceoryx_utils/test/moduletests/test_logstream.cpp +++ b/iceoryx_utils/test/moduletests/test_logstream.cpp @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "test.hpp" -#include "mocks/logger_mock.hpp" #include "iceoryx_utils/log/logging.hpp" #include "iceoryx_utils/log/logstream.hpp" +#include "mocks/logger_mock.hpp" +#include "test.hpp" #include #include @@ -187,7 +187,11 @@ class IoxLogStreamHexBin_test : public IoxLogStream_test using LogHexBinTypes = Types; +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(IoxLogStreamHexBin_test, LogHexBinTypes); +#pragma GCC diagnostic pop template void testStreamOperatorLogHex(Logger_Mock& loggerMock, LogType logValue) @@ -252,7 +256,12 @@ TYPED_TEST(IoxLogStreamHexBin_test, StreamOperatorLogBin_ValueMax) using ArithmeticTypes = Types; + +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(IoxLogStreamArithmetic_test, ArithmeticTypes); +#pragma GCC diagnostic pop template class IoxLogStreamArithmetic_test : public IoxLogStream_test diff --git a/iceoryx_utils/test/moduletests/test_message_queue.cpp b/iceoryx_utils/test/moduletests/test_message_queue.cpp index 2fe1e98358..281b60037a 100644 --- a/iceoryx_utils/test/moduletests/test_message_queue.cpp +++ b/iceoryx_utils/test/moduletests/test_message_queue.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if !defined(_WIN32) && !defined(__APPLE__) +#if !defined(_WIN32) #include "iceoryx_utils/internal/posix_wrapper/message_queue.hpp" #include "iceoryx_utils/internal/posix_wrapper/unix_domain_socket.hpp" @@ -24,7 +24,11 @@ using namespace ::testing; using namespace iox; using namespace iox::posix; -using IpcChannel = MessageQueue; +#if defined(__APPLE__) +using IpcChannelType = UnixDomainSocket; +#else +using IpcChannelType = MessageQueue; +#endif constexpr char goodName[] = "/channel_test"; constexpr char anotherGoodName[] = "/horst"; @@ -36,14 +40,14 @@ class MessageQueue_test : public Test public: void SetUp() { - auto serverResult = - IpcChannel::create(goodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER, MaxMsgSize, MaxMsgNumber); + auto serverResult = IpcChannelType::create( + goodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER, MaxMsgSize, MaxMsgNumber); ASSERT_THAT(serverResult.has_error(), Eq(false)); server = std::move(serverResult.get_value()); internal::CaptureStderr(); - auto clientResult = - IpcChannel::create(goodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT, MaxMsgSize, MaxMsgNumber); + auto clientResult = IpcChannelType::create( + goodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT, MaxMsgSize, MaxMsgNumber); ASSERT_THAT(clientResult.has_error(), Eq(false)); client = std::move(clientResult.get_value()); } @@ -61,34 +65,34 @@ class MessageQueue_test : public Test { } - static constexpr size_t MaxMsgSize = IpcChannel::MAX_MESSAGE_SIZE; + static const size_t MaxMsgSize; static constexpr uint64_t MaxMsgNumber = 10u; - IpcChannel server; - IpcChannel client; + IpcChannelType server; + IpcChannelType client; }; -constexpr size_t MessageQueue_test::MaxMsgSize; +const size_t MessageQueue_test::MaxMsgSize = IpcChannelType::MAX_MESSAGE_SIZE; constexpr uint64_t MessageQueue_test::MaxMsgNumber; TEST_F(MessageQueue_test, createNoName) { - auto mq2 = IpcChannel::create("", IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto mq2 = IpcChannelType::create("", IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_TRUE(mq2.has_error()); ASSERT_THAT(mq2.get_error(), Eq(IpcChannelError::INVALID_CHANNEL_NAME)); } TEST_F(MessageQueue_test, createBadName) { - auto mq2 = IpcChannel::create(badName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto mq2 = IpcChannelType::create(badName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_TRUE(mq2.has_error()); } TEST_F(MessageQueue_test, createAgain) { // if there is a leftover from a crashed channel, we can create a new one. This is simulated by creating twice - auto first = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto first = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_FALSE(first.has_error()); - auto second = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto second = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_FALSE(second.has_error()); } @@ -98,11 +102,11 @@ TEST_F(MessageQueue_test, createAgainAndEmpty) using namespace iox::units; using namespace std::chrono; - auto serverResult = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto serverResult = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_FALSE(serverResult.has_error()); auto server = std::move(serverResult.get_value()); - auto clientResult = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); + auto clientResult = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); EXPECT_FALSE(clientResult.has_error()); auto client = std::move(clientResult.get_value()); @@ -120,7 +124,7 @@ TEST_F(MessageQueue_test, createAgainAndEmpty) sent = client.send(newMessage).has_error(); EXPECT_FALSE(sent); - auto second = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto second = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_FALSE(second.has_error()); server = std::move(second.get_value()); @@ -132,7 +136,7 @@ TEST_F(MessageQueue_test, createAgainAndEmpty) TEST_F(MessageQueue_test, clientWithoutServerFails) { - auto clientResult = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); + auto clientResult = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); EXPECT_TRUE(clientResult.has_error()); ASSERT_THAT(clientResult.get_error(), Eq(IpcChannelError::NO_SUCH_CHANNEL)); } @@ -140,11 +144,11 @@ TEST_F(MessageQueue_test, clientWithoutServerFails) TEST_F(MessageQueue_test, NotOutdatedOne) { - auto serverResult = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto serverResult = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_FALSE(serverResult.has_error()); auto server = std::move(serverResult.get_value()); - auto clientResult = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); + auto clientResult = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); EXPECT_FALSE(clientResult.has_error()); auto client = std::move(clientResult.get_value()); @@ -156,17 +160,17 @@ TEST_F(MessageQueue_test, NotOutdatedOne) TEST_F(MessageQueue_test, OutdatedOne) { - if (std::is_same::value) + if (std::is_same::value) { // isOutdated cannot be realized for unix domain sockets return; } - auto serverResult = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto serverResult = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_FALSE(serverResult.has_error()); auto server = std::move(serverResult.get_value()); - auto clientResult = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); + auto clientResult = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::CLIENT); EXPECT_FALSE(clientResult.has_error()); auto client = std::move(clientResult.get_value()); @@ -181,16 +185,16 @@ TEST_F(MessageQueue_test, OutdatedOne) TEST_F(MessageQueue_test, unlinkExistingOne) { - auto first = IpcChannel::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); + auto first = IpcChannelType::create(anotherGoodName, IpcChannelMode::BLOCKING, IpcChannelSide::SERVER); EXPECT_FALSE(first.has_error()); - auto ret = IpcChannel::unlinkIfExists(anotherGoodName); + auto ret = IpcChannelType::unlinkIfExists(anotherGoodName); EXPECT_FALSE(ret.has_error()); EXPECT_TRUE(ret.get_value()); } TEST_F(MessageQueue_test, unlinkNonExistingOne) { - auto ret = IpcChannel::unlinkIfExists(theUnknown); + auto ret = IpcChannelType::unlinkIfExists(theUnknown); EXPECT_FALSE(ret.has_error()); EXPECT_FALSE(ret.get_value()); } @@ -234,7 +238,7 @@ TEST_F(MessageQueue_test, sendAfterClientDestroy) TEST_F(MessageQueue_test, sendAfterServerDestroy) { - if (std::is_same::value) + if (std::is_same::value) { // We still can send to the message queue is we destroy the server // it would be outdated, this is checked in another test @@ -247,7 +251,6 @@ TEST_F(MessageQueue_test, sendAfterServerDestroy) std::string message = "Try to send me"; auto sendResult = client.send(message); EXPECT_TRUE(sendResult.has_error()); - EXPECT_THAT(sendResult.get_error(), Eq(IpcChannelError::NO_SUCH_CHANNEL)); } @@ -290,10 +293,11 @@ TEST_F(MessageQueue_test, sendMaxMessageSize) TEST_F(MessageQueue_test, wildCreate) { - auto result = IpcChannel::create(); + auto result = IpcChannelType::create(); ASSERT_THAT(result.has_error(), Eq(true)); } +#if !defined(__APPLE__) TEST_F(MessageQueue_test, timedSend) { using namespace iox::units; @@ -327,6 +331,7 @@ TEST_F(MessageQueue_test, timedSend) } } } +#endif TEST_F(MessageQueue_test, timedReceive) { diff --git a/iceoryx_utils/test/moduletests/test_posix_timer.cpp b/iceoryx_utils/test/moduletests/test_posix_timer.cpp index ee2b7e7284..4106008b20 100644 --- a/iceoryx_utils/test/moduletests/test_posix_timer.cpp +++ b/iceoryx_utils/test/moduletests/test_posix_timer.cpp @@ -72,23 +72,21 @@ TIMING_TEST_F(TimerStopWatch_test, DurationOfNonZeroIsExpiresAfterTimeout, Repea TIMING_TEST_EXPECT_TRUE(sut.hasExpiredComparedToCreationTime()); }); -TEST_F(TimerStopWatch_test, ResetWithDurationIsExpired) -{ +TIMING_TEST_F(TimerStopWatch_test, ResetWithDurationIsExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * TIMEOUT.milliSeconds())); - EXPECT_THAT(sut.hasExpiredComparedToCreationTime(), Eq(true)); + TIMING_TEST_EXPECT_TRUE(sut.hasExpiredComparedToCreationTime()); sut.resetCreationTime(); - EXPECT_THAT(sut.hasExpiredComparedToCreationTime(), Eq(false)); -} + TIMING_TEST_EXPECT_FALSE(sut.hasExpiredComparedToCreationTime()); +}); -TEST_F(TimerStopWatch_test, ResetWhenNotExpiredIsStillNotExpired) -{ +TIMING_TEST_F(TimerStopWatch_test, ResetWhenNotExpiredIsStillNotExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * TIMEOUT.milliSeconds() / 3)); sut.resetCreationTime(); std::this_thread::sleep_for(std::chrono::milliseconds(2 * TIMEOUT.milliSeconds() / 3)); - EXPECT_THAT(sut.hasExpiredComparedToCreationTime(), Eq(false)); -} + TIMING_TEST_EXPECT_FALSE(sut.hasExpiredComparedToCreationTime()); +}); TIMING_TEST_F(TimerStopWatch_test, ResetAfterBeingExpiredIsNotExpired, Repeat(5), [&] { Timer sut(TIMEOUT); diff --git a/iceoryx_utils/test/moduletests/test_relative_pointer.cpp b/iceoryx_utils/test/moduletests/test_relative_pointer.cpp index 4d2b6d9ca5..bb15262fdf 100644 --- a/iceoryx_utils/test/moduletests/test_relative_pointer.cpp +++ b/iceoryx_utils/test/moduletests/test_relative_pointer.cpp @@ -107,7 +107,12 @@ class MemMap }; typedef testing::Types Types; + +/// we require TYPED_TEST since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" TYPED_TEST_CASE(relativeptrtests, Types); +#pragma GCC diagnostic pop TYPED_TEST(relativeptrtests, ConstrTests) diff --git a/iceoryx_utils/test/moduletests/test_relocatable_ptr.cpp b/iceoryx_utils/test/moduletests/test_relocatable_ptr.cpp index 6881fb74f3..e36c8761c9 100644 --- a/iceoryx_utils/test/moduletests/test_relocatable_ptr.cpp +++ b/iceoryx_utils/test/moduletests/test_relocatable_ptr.cpp @@ -75,8 +75,6 @@ TEST_F(RelocatablePointer_test, relocation) uint8_t* base1 = block1[0]; uint8_t* base2 = block2[0]; - EXPECT_EQ(base2 - base1, BLOCK_SIZE); - int offset = BLOCK_SIZE / 2; auto adr1 = reinterpret_cast(base1 + offset); auto adr2 = reinterpret_cast(base2 + offset); @@ -119,4 +117,4 @@ TEST_F(RelocatablePointer_test, relocation) // only has primitive members and the test ends here) rp->~relocatable_ptr(); } -} \ No newline at end of file +} // namespace diff --git a/iceoryx_utils/test/moduletests/test_semaphore_module.cpp b/iceoryx_utils/test/moduletests/test_semaphore_module.cpp index 18bc416bb1..b06e7c4327 100644 --- a/iceoryx_utils/test/moduletests/test_semaphore_module.cpp +++ b/iceoryx_utils/test/moduletests/test_semaphore_module.cpp @@ -101,7 +101,11 @@ class SemaphoreCreate_test : public Test } }; +/// we require INSTANTIATE_TEST_CASE since we support gtest 1.8 for our safety targets +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" INSTANTIATE_TEST_CASE_P(Semaphore_test, Semaphore_test, Values(&CreateNamedSemaphore, &CreateUnnamedSemaphore)); +#pragma GCC diagnostic pop TEST_F(SemaphoreCreate_test, CreateNamedSemaphore) { @@ -131,6 +135,12 @@ TEST_F(SemaphoreCreate_test, OpenNamedSemaphore) EXPECT_THAT(semaphore2.has_error(), Eq(false)); } +TEST_F(SemaphoreCreate_test, OpenNamedSemaphoreWithEmptyNameFails) +{ + auto semaphore = iox::posix::Semaphore::create("", S_IRUSR | S_IWUSR, 10); + EXPECT_THAT(semaphore.has_error(), Eq(true)); +} + TEST_F(SemaphoreCreate_test, OpenNonExistingNamedSemaphore) { auto semaphore2 = iox::posix::Semaphore::create("/fuuSem", S_IRUSR | S_IWUSR); diff --git a/iceoryx_utils/test/moduletests/test_unidirectional_communication_channel.cpp b/iceoryx_utils/test/moduletests/test_unidirectional_communication_channel.cpp deleted file mode 100644 index 5791d84d6e..0000000000 --- a/iceoryx_utils/test/moduletests/test_unidirectional_communication_channel.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) 2019 by Robert Bosch GmbH. 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. - -#include "iceoryx_utils/communication_channel/protocol/fifo_protocol.hpp" -#include "iceoryx_utils/communication_channel/unidirectional_communication_channel.hpp" - -#include -#include -#include - -using namespace testing; -using namespace iox; -using namespace iox::units; - -template -class UnidirectionalCommunicationChannel_Test : public Test -{ - public: - UnidirectionalCommunicationChannel_Test() - : sut() - , transmitter(sut.getTransmitter()) - , receiver(sut.getReceiver()) - { - } - - void SetUp() override - { - } - - void TearDown() override - { - } - - UnidirectionalCommunicationChannel_t sut; - typename UnidirectionalCommunicationChannel_t::Transmitter_t* transmitter; - typename UnidirectionalCommunicationChannel_t::Receiver_t* receiver; -}; - -template -using FiFoTestProtocol = FiFoProtocol; - -using Implementations = Types>; -TYPED_TEST_CASE(UnidirectionalCommunicationChannel_Test, Implementations); - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, SendAndTryReceive) -{ - ASSERT_THAT(this->transmitter->Send(313), Eq(true)); - auto result = this->receiver->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(313)); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, TryReceiveWithoutSend) -{ - auto result = this->receiver->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, MultipleSendAndTryReceive) -{ - int limit = 12; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transmitter->Send(i), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->receiver->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, OneSendTwoTryReceive) -{ - ASSERT_THAT(this->transmitter->Send(8001), Eq(true)); - - auto result = this->receiver->TryReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(8001)); - - auto result2 = this->receiver->TryReceive(); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, SendAndBlockingReceive) -{ - ASSERT_THAT(this->transmitter->Send(6313), Eq(true)); - auto result = this->receiver->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(6313)); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, MultipleSendAndBlockingReceive) -{ - int limit = 12; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transmitter->Send(i * 5), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->receiver->BlockingReceive(); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i * 5)); - } -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, SendAndTimedReceive) -{ - ASSERT_THAT(this->transmitter->Send(313), Eq(true)); - auto result = this->receiver->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(313)); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, TimedReceiveWithoutSend) -{ - auto result = this->receiver->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(false)); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, MultipleSendAndTimedReceive) -{ - int limit = 12; - for (int i = 0; i < limit; ++i) - ASSERT_THAT(this->transmitter->Send(i), Eq(true)); - - for (int i = 0; i < limit; ++i) - { - auto result = this->receiver->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(i)); - } -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, OneSendTwoTimedReceive) -{ - ASSERT_THAT(this->transmitter->Send(8001), Eq(true)); - - auto result = this->receiver->timedReceive(10_ms); - ASSERT_THAT(result.has_value(), Eq(true)); - EXPECT_THAT(*result, Eq(8001)); - - auto result2 = this->receiver->timedReceive(10_ms); - ASSERT_THAT(result2.has_value(), Eq(false)); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, BlockingReceiveIsBlockingTillDataIsSend) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->receiver->BlockingReceive(); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->transmitter->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, TimedReceiveIsBlockingTillDataIsSend) -{ - std::atomic_bool hasReceivedData{false}; - std::thread t1([&] { - this->receiver->timedReceive(1000_s); - hasReceivedData.store(true); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(false)); - ASSERT_THAT(this->transmitter->Send(8001), Eq(true)); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(hasReceivedData.load(), Eq(true)); - - t1.join(); -} - -TYPED_TEST(UnidirectionalCommunicationChannel_Test, TimedReceiveHasTimeout) -{ - std::atomic_bool hasTimeout{false}; - std::thread t1([&] { - this->receiver->timedReceive(100_ms); - hasTimeout.store(true); - }); - - ASSERT_THAT(hasTimeout.load(), Eq(false)); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - ASSERT_THAT(hasTimeout.load(), Eq(true)); - - t1.join(); -} - -namespace UnidirectionalCommunicationChannelTestInternals -{ -static std::string ctorTest; -template -class TestProtocol -{ - public: - TestProtocol(const std::string& testName) - { - ctorTest.append(testName); - } - bool Send(const T& f_message) - { - return true; - } - cxx::optional TryReceive() - { - return cxx::nullopt_t(); - } - cxx::optional BlockingReceive() - { - return cxx::nullopt_t(); - } - cxx::optional timedReceive(const units::Duration&) - { - return cxx::nullopt_t(); - } -}; -} // namespace UnidirectionalCommunicationChannelTestInternals - -TEST(UnidirectionalCommunicationChannel_BaseTest, ConstructorArgumentForTransportLayer) -{ - UnidirectionalCommunicationChannel sut( - "ctorFuu"); - EXPECT_THAT(UnidirectionalCommunicationChannelTestInternals::ctorTest, Eq("ctorFuu")); -} diff --git a/iceoryx_utils/test/moduletests/test_unit_duration.cpp b/iceoryx_utils/test/moduletests/test_unit_duration.cpp index b836c24544..5d3398b4c0 100644 --- a/iceoryx_utils/test/moduletests/test_unit_duration.cpp +++ b/iceoryx_utils/test/moduletests/test_unit_duration.cpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "test.hpp" #include "iceoryx_utils/internal/units/duration.hpp" +#include "test.hpp" using namespace ::testing; using namespace iox::units; @@ -221,3 +221,15 @@ TEST(Duration_test, constructFromTimeval) Duration result(value); EXPECT_EQ(result.microSeconds(), 42 + 1000000 * 1337); } + +TEST(Duration_test, isZeroWhenConstructedFromNegativeChronoMilliSeconds) +{ + Duration result(std::chrono::milliseconds(-1)); + EXPECT_EQ(result.milliSeconds(), 0u); +} + +TEST(Duration_test, isZeroWhenConstructedFromNegativeChronoNanoSeconds) +{ + Duration result(std::chrono::nanoseconds(-1)); + EXPECT_EQ(result.nanoSeconds(), 0u); +} diff --git a/iceoryx_utils/testutils/timing_test.cpp b/iceoryx_utils/testutils/timing_test.cpp new file mode 100644 index 0000000000..c2feb6e414 --- /dev/null +++ b/iceoryx_utils/testutils/timing_test.cpp @@ -0,0 +1,58 @@ +// Copyright (c) 2019 by Robert Bosch GmbH. 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. + +#include "timing_test.hpp" + +namespace iox +{ +namespace testutils +{ +bool performingTimingTest(const std::function& testCallback, + const uint64_t repetitions, + std::atomic_bool& testResult) noexcept +{ + for (uint64_t i = 0u; i < repetitions; ++i) + { + // new test run therefore we have to reset the testResult + testResult.store(true); + // testResult will be set to false if a test failes + testCallback(); + + if (testResult.load()) + { + return true; + } + } + return false; +} + +std::string verifyTimingTestResult(const char* file, + const int line, + const char* valueStr, + const bool value, + const bool expected, + std::atomic_bool& result) noexcept +{ + std::string errorMessage; + if (value != expected) + { + errorMessage += "Timing Test failure in:\n"; + errorMessage += std::string(file) + ":" + std::to_string(line) + "\n"; + errorMessage += "Value of: " + std::string(valueStr) + " should be true\n"; + result.store(false); + } + return errorMessage; +} +} // namespace testutils +} // namespace iox diff --git a/iceoryx_utils/testutils/timing_test.hpp b/iceoryx_utils/testutils/timing_test.hpp index e55429f7f1..2fb39771db 100644 --- a/iceoryx_utils/testutils/timing_test.hpp +++ b/iceoryx_utils/testutils/timing_test.hpp @@ -103,42 +103,18 @@ namespace iox { namespace testutils { -inline bool performingTimingTest(const std::function& testCallback, - const uint64_t repetitions, - std::atomic_bool& testResult) noexcept -{ - for (uint64_t i = 0u; i < repetitions; ++i) - { - // new test run therefore we have to reset the testResult - testResult.store(true); - // testResult will be set to false if a test failes - testCallback(); +bool performingTimingTest(const std::function& testCallback, + const uint64_t repetitions, + std::atomic_bool& testResult) noexcept; - if (testResult.load()) - { - return true; - } - } - return false; -} -inline std::string verifyTimingTestResult(const char* file, - const int line, - const char* valueStr, - const bool value, - const bool expected, - std::atomic_bool& result) noexcept -{ - std::string errorMessage; - if (value != expected) - { - errorMessage += "Timing Test failure in:\n"; - errorMessage += std::string(file) + ":" + std::to_string(line) + "\n"; - errorMessage += "Value of: " + std::string(valueStr) + " should be true\n"; - result.store(false); - } - return errorMessage; -} +std::string verifyTimingTestResult(const char* file, + const int line, + const char* valueStr, + const bool value, + const bool expected, + std::atomic_bool& result) noexcept; + } // namespace testutils } // namespace iox diff --git a/tools/iceoryx_build_test.sh b/tools/iceoryx_build_test.sh index fa79e071b3..025b591c7d 100755 --- a/tools/iceoryx_build_test.sh +++ b/tools/iceoryx_build_test.sh @@ -26,15 +26,12 @@ set -e WORKSPACE=$(git rev-parse --show-toplevel) ICEORYX_INSTALL_PREFIX=$WORKSPACE/build/install/prefix/ -DEPENDENCIES_INSTALL_PREFIX=$WORKSPACE/build/dependencies/ CLEAN_BUILD=false BUILD_TYPE="" TEST_FLAG="off" RUN_TEST=false -BUILD_INTROSPECTION=true -DOWNLOAD_GTEST=true -DOWNLOAD_CPPTOML=true +INTROSPECTION_FLAG="on" for arg in "$@" do @@ -57,13 +54,7 @@ do TEST_FLAG="on" ;; "skip-introspection") - BUILD_INTROSPECTION=false - ;; - "no-gtest-download") - DOWNLOAD_GTEST=false - ;; - "no-cpptoml-download") - DOWNLOAD_CPPTOML=false + INTROSPECTION_FLAG="off" ;; "help") echo "Build script for iceoryx." @@ -77,10 +68,6 @@ do echo " test Builds and runs the tests" echo " build-test Builds the tests (doesn't tun)" echo " skip-introspection Skips building iceoryx introspection" - echo " no-gtest-download Gtest will not be downloaded, but searched in the system" - echo " Be careful, there might be problems due to incompatible versions" - echo " no-cpptoml-download Cpptoml will not be downloaded, but searched in the system" - echo " Be careful, there might be problems due to incompatible versions" echo " help Prints this help" echo "" echo "e.g. iceoryx_build_test.sh clean test release" @@ -114,64 +101,10 @@ cd build echo " [i] Current working directory:" pwd -# Download and build googletest -if [[ $TEST_FLAG == "on" && $DOWNLOAD_GTEST == true ]] -then - cd $WORKSPACE/build - mkdir -p googletest - cd googletest - - echo ">>>>>> Start building googletest dependency <<<<<<" - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=$DEPENDENCIES_INSTALL_PREFIX -Dtest=$TEST_FLAG $WORKSPACE/cmake/googletest - echo ">>>>>> finished building googletest dependency <<<<<<" -fi - -# Build download and build cpptoml -if [ $DOWNLOAD_CPPTOML == true ] -then - cd $WORKSPACE/build - mkdir -p cpptoml - cd cpptoml - - echo ">>>>>> Start building cpptoml dependency <<<<<<" - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=$DEPENDENCIES_INSTALL_PREFIX $WORKSPACE/cmake/cpptoml - echo ">>>>>> finished building googletest dependency <<<<<<" -fi - -# Build iceoryx_utils -cd $WORKSPACE/build -mkdir -p utils -cd utils - -echo ">>>>>> Start building iceoryx utils package <<<<<<" -cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PREFIX_PATH=$DEPENDENCIES_INSTALL_PREFIX -DCMAKE_INSTALL_PREFIX=$ICEORYX_INSTALL_PREFIX -Dtest=$TEST_FLAG $WORKSPACE/iceoryx_utils +echo ">>>>>> Start building iceoryx package <<<<<<" +cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=$ICEORYX_INSTALL_PREFIX -DTOML_CONFIG=on -Dtest=$TEST_FLAG -Droudi_environment=on -Dexamples=OFF -Dintrospection=$INTROSPECTION_FLAG $WORKSPACE/iceoryx_meta cmake --build . --target install -echo ">>>>>> finished building iceoryx utils package <<<<<<" - -# Build iceoryx_posh -cd $WORKSPACE/build -mkdir -p posh -cd posh - -echo ">>>>>> Start building iceoryx posh package <<<<<<" -cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PREFIX_PATH=$DEPENDENCIES_INSTALL_PREFIX -DCMAKE_INSTALL_PREFIX=$ICEORYX_INSTALL_PREFIX -DTOML_CONFIG=on -Dtest=$TEST_FLAG -Droudi_environment=on $WORKSPACE/iceoryx_posh -cmake --build . --target install -echo ">>>>>> finished building iceoryx posh package <<<<<<" - -if [ $BUILD_INTROSPECTION == true ] -then - # Build iceoryx_introspection - cd $WORKSPACE/build - mkdir -p iceoryx_introspection - cd iceoryx_introspection - - echo ">>>>>> Start building iceoryx introspection <<<<<<" - cmake -DCMAKE_PREFIX_PATH=$ICEORYX_INSTALL_PREFIX -DCMAKE_INSTALL_PREFIX=$ICEORYX_INSTALL_PREFIX -Dtest=$TEST_FLAG -Droudi_environment=on $WORKSPACE/tools/introspection - cmake --build . --target install - echo ">>>>>> finished building iceoryx introspection package <<<<<<" -else - echo ">>>>>> Skipping iceoryx introspection <<<<<<" -fi +echo ">>>>>> finished building iceoryx package <<<<<<" echo ">>>>>> Start building iceoryx examples <<<<<<" cd $WORKSPACE/build diff --git a/tools/run_all_tests.sh b/tools/run_all_tests.sh index 5c96ac1da5..f8675f76e1 100755 --- a/tools/run_all_tests.sh +++ b/tools/run_all_tests.sh @@ -16,7 +16,33 @@ # This file runs all tests for Ice0ryx -component_folder="posh utils" +component_folder="utils posh" + +GTEST_FILTER="*" + +for arg in "$@" +do + case "$arg" in + "disable-timing-tests") + GTEST_FILTER="-*.TimingTest_*" + ;; + "only-timing-tests") + GTEST_FILTER="*.TimingTest_*" + ;; + *) + echo "" + echo "Test script for iceoryx." + echo "By default all module-, integration- and componenttests are executed." + echo "" + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " disable-timing-tests Disables all timing tests" + echo " only-timing-tests Runs only timing tests" + echo "" + exit -1 + ;; + esac +done #check if this script is sourced by another script, # if yes then exit properly, so the other script can use this @@ -34,18 +60,18 @@ echo ">>>>>> Running Ice0ryx Tests <<<<<<" set -e +BASE_DIRECTORY=$PWD + for folder in $component_folder; do echo "" echo "######################## processing moduletests & componenttests in $folder ########################" echo $PWD - cd $folder/$folder/test - - ./"$folder"_moduletests --gtest_output="xml:$TEST_RESULT_FOLDER/"$folder"_ModuleTestResults.xml" - ./"$folder"_componenttests --gtest_output="xml:$TEST_RESULT_FOLDER/"$folder"_ComponenttestTestResults.xml" - ./"$folder"_integrationtests --gtest_output="xml:$TEST_RESULT_FOLDER/"$folder"_IntegrationTestResults.xml" + cd $BASE_DIRECTORY/$folder/test - cd ../../.. + ./"$folder"_moduletests --gtest_filter="${GTEST_FILTER}" --gtest_output="xml:$TEST_RESULT_FOLDER/"$folder"_ModuleTestResults.xml" + ./"$folder"_componenttests --gtest_filter="${GTEST_FILTER}" --gtest_output="xml:$TEST_RESULT_FOLDER/"$folder"_ComponenttestTestResults.xml" + ./"$folder"_integrationtests --gtest_filter="${GTEST_FILTER}" --gtest_output="xml:$TEST_RESULT_FOLDER/"$folder"_IntegrationTestResults.xml" done