Skip to content

Commit

Permalink
iox-#2330 Refactor func for platform
Browse files Browse the repository at this point in the history
iox-#2330 Edit ci

iox-#2330 Edit ci
  • Loading branch information
khromenokroman committed Sep 5, 2024
1 parent a5f4534 commit 510c6c4
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 50 deletions.
39 changes: 7 additions & 32 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,45 +205,20 @@ jobs:
- run: ./tools/ci/build-test-ubuntu-bazel.sh

# Check run systemd
build-and-run-roudi-with-systemd-ubuntu:
build-and-run-roudi-with-systemd-and-build-test-and-run-ubuntu:
# prevent stuck jobs consuming runners for 6 hours
timeout-minutes: 60
runs-on: ubuntu-latest
needs: pre-flight-check
steps:
- name: Update
run: sudo apt update
- name: Install depends
run: sudo apt install -y gcc g++ cmake libacl1-dev libncurses5-dev pkg-config libsystemd-dev
- name: Checkout
uses: actions/checkout@v4
- name: Cmake cache
run: cmake -Bbuild -Hiceoryx_meta -DBUILD_SHARED_LIBS=ON -DUSE_SYSTEMD=ON
- name: build
run: cmake --build build -j 16
- name: Install
run: sudo cmake --build build --target install
- name: Ldconfig run
run: sudo ldconfig
- name: Create unit file
run: echo -e "[Unit]\nDescription=Test application roudi\n\n[Service]\nType=notify\nRestartSec=10\nRestart=always\nExecStart=/usr/local/bin/iox-roudi\nTimeoutStartSec=10\nWatchdogSec=5\n\n[Install]\nWantedBy=multi-user.target" | sudo tee /usr/lib/systemd/system/test_iox.service > /dev/null
- name: Show unit
run: cat /usr/lib/systemd/system/test_iox.service
- name: Daemon reload
run: sudo systemctl daemon-reload
- name: Check status
run: sudo systemctl status test_iox || true
- name: Start roudi
run: |
sudo systemctl start test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)
- name: Wait for 30 seconds
run: sleep 30
- name: Check roudi
run: sudo systemctl status test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)
- name: Stop roudi
run: sudo systemctl stop test_iox
- name: Show journal
run: sudo journalctl -u test_iox -n 100
- name: Install iceoryx dependencies and clang-tidy
uses: ./.github/actions/install-iceoryx-deps-and-clang
- name: Build project and test and run unit test
run: sudo ./tools/ci/build-test-ubuntu-support-systemd-unit.sh
- name: Run integration test
run: sudo ./tools/ci/build-test-ubuntu-support-systemd-integrations.sh

coverage-and-docs:
# prevent stuck jobs consuming runners for 6 hours
Expand Down
7 changes: 6 additions & 1 deletion iceoryx_platform/cmake/IceoryxPackageHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ Macro(iox_add_executable)
target_compile_options(${IOX_TARGET} PRIVATE ${ICEORYX_CXX_FLAGS} ${ICEORYX_CXX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS} ${ICEORYX_GRCOV_FLAGS})
endif()

if(USE_SYSTEMD AND ("${IOX_TARGET}" STREQUAL "posh_moduletests"))
target_compile_definitions(${IOX_TARGET} PRIVATE USE_SYSTEMD_TEST=1)
message(STATUS "[i] Configuring ${IOX_TARGET} with systemd support.")
endif ()

if ( IOX_STACK_SIZE )
if(APPLE)
# @todo iox-#1287 not yet supported
Expand Down Expand Up @@ -341,7 +346,7 @@ Macro(iox_add_library)

if ( LINUX )
if(USE_SYSTEMD AND ("${IOX_TARGET}" STREQUAL "iceoryx_posh_roudi"))
message(STATUS "[i] Configuring iceoryx_posh_roudi with systemd support.")
message(STATUS "[i] Configuring ${IOX_TARGET} with systemd support.")
target_compile_definitions(${IOX_TARGET} PRIVATE USE_SYSTEMD=1)
target_link_libraries(${IOX_TARGET} PUBLIC ${IOX_PUBLIC_LIBS_LINUX} PRIVATE ${IOX_PRIVATE_LIBS_LINUX} systemd)
else()
Expand Down
56 changes: 42 additions & 14 deletions iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,15 @@ class ServiceManagement
ServiceManagement& operator=(ServiceManagement const& other) = delete;
ServiceManagement& operator=(ServiceManagement&& other) = default;

/// dbus signal handler
virtual void processNotify() = 0;
/// Sets a shutdown flag
virtual void shutdown() = 0;
static constexpr const uint16_t SIZE_STRING = 4096; ///< maximum size of string // 2
static constexpr const uint8_t SIZE_THREAD_NAME = 15; ///< max size for thread name // 1


virtual void processNotify() = 0; /// dbus signal handler
virtual void shutdown() = 0; /// Sets a shutdown flag
virtual bool setThreadNameHelper(iox::string<SIZE_THREAD_NAME>& threadName) = 0; /// Sets a thread name
virtual std::string getEnvironmentVariable(const char* const env_var) = 0; /// Get environment variable
virtual bool sendSDNotifySignalHelper(const std::string_view state) = 0; /// Send notify

protected:
ServiceManagement() = default;
Expand All @@ -97,11 +102,7 @@ class ServiceManagementSystemd final : public ServiceManagement
std::condition_variable watchdogNotifyCondition; ///< watch dog notification condition // 48
std::mutex watchdogMutex; ///< watch dog mutex // 40
std::thread m_listenThreadWatchdog; ///< thread that listens to systemd watchdog signals // 8
public:
static constexpr const uint16_t SIZE_STRING = 4096; ///< maximum size of string // 2
static constexpr const uint8_t SIZE_THREAD_NAME = 15; ///< max size for thread name // 1
private:
std::atomic_bool m_shutdown{false}; ///< indicates if service is being shutdown // 1
std::atomic_bool m_shutdown{false}; ///< indicates if service is being shutdown // 1

public:
ServiceManagementSystemd() = default;
Expand All @@ -125,22 +126,22 @@ class ServiceManagementSystemd final : public ServiceManagement
* @param env_var Pointer to environment variable
* @return Environment variable as std::string
**/
static std::string getEnvironmentVariable(const char* const env_var);
std::string getEnvironmentVariable(const char* const env_var) final;

/**
* @brief Helper function to set thread name
* @param threadName Thread name to be set
* @return True if successfully set, otherwise false
**/
static bool setThreadNameHelper(iox::string<SIZE_THREAD_NAME>& threadName);
bool setThreadNameHelper(iox::string<SIZE_THREAD_NAME>& threadName) final;

#ifdef USE_SYSTEMD
/**
* @brief Helper function to send SDNotify signals
* @param state SDNotify state to be sent
* @return True if signal sending is successful, otherwise false
**/
static bool sendSDNotifySignalHelper(const std::string_view state)
#ifdef USE_SYSTEMD
bool sendSDNotifySignalHelper(const std::string_view state) final
{
auto result = IOX_POSIX_CALL(sd_notify)(0, state.data()).successReturnValue(1).evaluate();
if (result.has_error())
Expand All @@ -153,7 +154,7 @@ class ServiceManagementSystemd final : public ServiceManagement
return true;
}
#else
static bool sendSDNotifySignalHelper([[maybe_unused]] const std::string_view state)
bool sendSDNotifySignalHelper([[maybe_unused]] const std::string_view state) final
{
// empty implementation
return true;
Expand Down Expand Up @@ -203,6 +204,33 @@ class NoServiceManagementSystemd final : public ServiceManagement
{
// empty implementation
}

/**
* @brief Empty implementation of get environment variable
**/
std::string getEnvironmentVariable([[maybe_unused]] const char* const env_var) final
{
// empty implementation
return "no implement";
}

/**
* @brief Empty implementation set thread name
**/
bool setThreadNameHelper([[maybe_unused]] iox::string<SIZE_THREAD_NAME>& threadName) final
{
// empty implementation
return true;
}

/**
* @brief Empty implementation send SDNotify signals
**/
bool sendSDNotifySignalHelper([[maybe_unused]] const std::string_view state) final
{
// empty implementation
return true;
}
};
} // namespace service_management

Expand Down
8 changes: 5 additions & 3 deletions iceoryx_posh/source/roudi/roudi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,9 +607,10 @@ std::string ServiceManagementSystemd::getEnvironmentVariable(const char* const e

str.unsafe_raw_access([&](auto* buffer, auto const info) {
size_t actualSizeWithNull{0};
auto result = IOX_POSIX_CALL(iox_getenv_s)(&actualSizeWithNull, buffer, info.total_size, env_var)
.failureReturnValue(-1)
.evaluate();
auto result =
IOX_POSIX_CALL(iox_getenv_s)(&actualSizeWithNull, buffer, static_cast<size_t>(info.total_size), env_var)
.failureReturnValue(-1)
.evaluate();

if (result.has_error() && result.error().errnum == ERANGE)
{
Expand Down Expand Up @@ -680,6 +681,7 @@ void ServiceManagementSystemd::processNotify()
}
}


} // namespace service_management
} // namespace roudi
} // namespace iox
129 changes: 129 additions & 0 deletions iceoryx_posh/test/moduletests/test_roudi_system_manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_posh/internal/roudi/roudi.hpp"
#include <gtest/gtest.h>

#if defined(_WIN32) || defined(_WIN64)
#define GTEST_SKIP_FOR_WINDOWS() GTEST_SKIP() << "Skipping this test on Windows."
#else
#define GTEST_SKIP_FOR_WINDOWS() (void)0
#endif

#ifdef USE_SYSTEMD_TEST
#define GTEST_SKIP_NOT_SUPPORT_SYSTEMD() (void)0
#else
#define GTEST_SKIP_NOT_SUPPORT_SYSTEMD() GTEST_SKIP() << "Skipping this test when systemd is not use."
#endif


TEST(RoudiSystemD, CreateObject)
{
::testing::Test::RecordProperty("TEST_ID", "aa77b5f6-ffb3-4267-982d-dfe85da384ca");
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
}

TEST(RoudiSystemD, CheckConstantsSizeThreadName)
{
::testing::Test::RecordProperty("TEST_ID", "9c39f45c-a63c-43ec-9606-e50c33247b3f");
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
ASSERT_EQ(roudiSendMessage->SIZE_THREAD_NAME, 15) << "Size thread must equal 15 simbols";
}

TEST(RoudiSystemD, CheckConstantsSizeString)
{
::testing::Test::RecordProperty("TEST_ID", "0b3e3058-6052-49cc-8a67-723f3775a745");
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
ASSERT_EQ(roudiSendMessage->SIZE_STRING, 4096) << "Size string must equal 4096 simbols";
}

TEST(RoudiSystemD, SetThreadNameHelper)
{
::testing::Test::RecordProperty("TEST_ID", "b9ff9e83-9dde-4221-bd1e-c1016ec2d5ff");
GTEST_SKIP_FOR_WINDOWS();
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
#ifdef USE_SYSTEMD_TEST
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
bool result = true;

ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
iox::string<SendMessageServiceManagement::SIZE_THREAD_NAME> nameThread = "test";
ASSERT_NO_THROW(result = roudiSendMessage->setThreadNameHelper(nameThread));
ASSERT_EQ(result, true) << "Can not change name thread";
#else
/* need add test (other OS) */
ASSERT_EQ(true, true);
#endif
}

TEST(RoudiSystemD, GetEnvironmentVariableReturnsCorrectValue)
{
::testing::Test::RecordProperty("TEST_ID", "12dfa746-d1f1-4b4e-864d-2cb28ee49f70");
GTEST_SKIP_FOR_WINDOWS();
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
#ifdef USE_SYSTEMD_TEST
const char* const env_var_name = "TEST_ENV_VAR";
const char* const env_var_value = "test_value";

auto set_env = IOX_POSIX_CALL(setenv)(env_var_name, env_var_value, 1).failureReturnValue(-1).evaluate();
EXPECT_FALSE(set_env.has_error()) << "setenv failed with error: " << set_env.get_error().errnum;

SendMessageServiceManagement sut;

std::string result = sut.getEnvironmentVariable(env_var_name);
if (result != "no implement")
{
EXPECT_EQ(result, env_var_value);
}
else
{
EXPECT_EQ(result, "no implement");
}
#else
/* need add test (other OS) */
ASSERT_EQ(true, true);
#endif
}

TEST(RoudiSystemD, GetEnvironmentVariableHandlesNonExistentVar)
{
::testing::Test::RecordProperty("TEST_ID", "9595728f-a504-46e3-8672-b074696326a4");
GTEST_SKIP_FOR_WINDOWS();
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
#ifdef USE_SYSTEMD_TEST
SendMessageServiceManagement sut;

std::string result = sut.getEnvironmentVariable("NON_EXISTENT_VAR");
if (result != "no implement")
{
EXPECT_TRUE(result.empty());
}
else
{
EXPECT_EQ(result, "no implement");
}
#else
/* need add test (other OS) */
ASSERT_EQ(true, true);
#endif
}
59 changes: 59 additions & 0 deletions tools/ci/build-test-ubuntu-support-systemd-integrations.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash
# Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

# This script builds iceoryx_hoofs und iceoryx_posh and executes all tests

set -e

if [ "$USER" != "root" ]; then
echo "Please run this as root or with sudo"
exit 1
fi

msg() {
printf "\033[1;32m%s: %s\033[0m\n" ${FUNCNAME[1]} "$1"
}

WORKSPACE=$(git rev-parse --show-toplevel)
DIR_BUILD="build"

msg "Create unit file"
echo -e "[Unit]\nDescription=Test application roudi\n\n[Service]\nType=notify\nRestartSec=10\nRestart=always\nExecStart=${WORKSPACE}/${DIR_BUILD}/iox-roudi\nTimeoutStartSec=10\nWatchdogSec=5\n\n[Install]\nWantedBy=multi-user.target" | tee /usr/lib/systemd/system/test_iox.service > /dev/null

msg "Show unit"
cat /usr/lib/systemd/system/test_iox.service

msg "Daemon reload"
systemctl daemon-reload

msg "Check status"
systemctl status test_iox || true

msg "Start roudi"
systemctl start test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)

msg "Wait for 30 seconds"
sleep 30

msg "Check roudi"
systemctl status test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)

msg "Stop roudi"
systemctl stop test_iox

msg "Show journal"
journalctl -u test_iox -n 100
Loading

0 comments on commit 510c6c4

Please sign in to comment.