Skip to content

Commit c9236aa

Browse files
iox-eclipse-iceoryx#2330 Refactor ci
1 parent a5f4534 commit c9236aa

File tree

8 files changed

+304
-50
lines changed

8 files changed

+304
-50
lines changed

.github/workflows/build-test.yml

+7-32
Original file line numberDiff line numberDiff line change
@@ -205,45 +205,20 @@ jobs:
205205
- run: ./tools/ci/build-test-ubuntu-bazel.sh
206206

207207
# Check run systemd
208-
build-and-run-roudi-with-systemd-ubuntu:
208+
build-and-run-roudi-with-systemd-and-build-test-and-run-ubuntu:
209209
# prevent stuck jobs consuming runners for 6 hours
210210
timeout-minutes: 60
211211
runs-on: ubuntu-latest
212212
needs: pre-flight-check
213213
steps:
214-
- name: Update
215-
run: sudo apt update
216-
- name: Install depends
217-
run: sudo apt install -y gcc g++ cmake libacl1-dev libncurses5-dev pkg-config libsystemd-dev
218214
- name: Checkout
219215
uses: actions/checkout@v4
220-
- name: Cmake cache
221-
run: cmake -Bbuild -Hiceoryx_meta -DBUILD_SHARED_LIBS=ON -DUSE_SYSTEMD=ON
222-
- name: build
223-
run: cmake --build build -j 16
224-
- name: Install
225-
run: sudo cmake --build build --target install
226-
- name: Ldconfig run
227-
run: sudo ldconfig
228-
- name: Create unit file
229-
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
230-
- name: Show unit
231-
run: cat /usr/lib/systemd/system/test_iox.service
232-
- name: Daemon reload
233-
run: sudo systemctl daemon-reload
234-
- name: Check status
235-
run: sudo systemctl status test_iox || true
236-
- name: Start roudi
237-
run: |
238-
sudo systemctl start test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)
239-
- name: Wait for 30 seconds
240-
run: sleep 30
241-
- name: Check roudi
242-
run: sudo systemctl status test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)
243-
- name: Stop roudi
244-
run: sudo systemctl stop test_iox
245-
- name: Show journal
246-
run: sudo journalctl -u test_iox -n 100
216+
- name: Install iceoryx dependencies and clang-tidy
217+
uses: ./.github/actions/install-iceoryx-deps-and-clang
218+
- name: Build project and test and run unit test
219+
run: sudo ./tools/ci/build-test-ubuntu-support-systemd-unit.sh
220+
- name: Run integration test
221+
run: sudo ./tools/ci/build-test-ubuntu-support-systemd-integrations.sh
247222

248223
coverage-and-docs:
249224
# prevent stuck jobs consuming runners for 6 hours

iceoryx_platform/cmake/IceoryxPackageHelper.cmake

+6-1
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ Macro(iox_add_executable)
237237
target_compile_options(${IOX_TARGET} PRIVATE ${ICEORYX_CXX_FLAGS} ${ICEORYX_CXX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS} ${ICEORYX_GRCOV_FLAGS})
238238
endif()
239239

240+
if(USE_SYSTEMD AND ("${IOX_TARGET}" STREQUAL "posh_moduletests"))
241+
target_compile_definitions(${IOX_TARGET} PRIVATE USE_SYSTEMD_TEST=1)
242+
message(STATUS "[i] Configuring ${IOX_TARGET} with systemd support.")
243+
endif ()
244+
240245
if ( IOX_STACK_SIZE )
241246
if(APPLE)
242247
# @todo iox-#1287 not yet supported
@@ -341,7 +346,7 @@ Macro(iox_add_library)
341346

342347
if ( LINUX )
343348
if(USE_SYSTEMD AND ("${IOX_TARGET}" STREQUAL "iceoryx_posh_roudi"))
344-
message(STATUS "[i] Configuring iceoryx_posh_roudi with systemd support.")
349+
message(STATUS "[i] Configuring ${IOX_TARGET} with systemd support.")
345350
target_compile_definitions(${IOX_TARGET} PRIVATE USE_SYSTEMD=1)
346351
target_link_libraries(${IOX_TARGET} PUBLIC ${IOX_PUBLIC_LIBS_LINUX} PRIVATE ${IOX_PRIVATE_LIBS_LINUX} systemd)
347352
else()

iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi.hpp

+42-14
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,15 @@ class ServiceManagement
7878
ServiceManagement& operator=(ServiceManagement const& other) = delete;
7979
ServiceManagement& operator=(ServiceManagement&& other) = default;
8080

81-
/// dbus signal handler
82-
virtual void processNotify() = 0;
83-
/// Sets a shutdown flag
84-
virtual void shutdown() = 0;
81+
static constexpr const uint16_t SIZE_STRING = 4096; ///< maximum size of string // 2
82+
static constexpr const uint8_t SIZE_THREAD_NAME = 15; ///< max size for thread name // 1
83+
84+
85+
virtual void processNotify() = 0; /// dbus signal handler
86+
virtual void shutdown() = 0; /// Sets a shutdown flag
87+
virtual bool setThreadNameHelper(iox::string<SIZE_THREAD_NAME>& threadName) = 0; /// Sets a thread name
88+
virtual std::string getEnvironmentVariable(const char* const env_var) = 0; /// Get environment variable
89+
virtual bool sendSDNotifySignalHelper(const std::string_view state) = 0; /// Send notify
8590

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

106107
public:
107108
ServiceManagementSystemd() = default;
@@ -125,22 +126,22 @@ class ServiceManagementSystemd final : public ServiceManagement
125126
* @param env_var Pointer to environment variable
126127
* @return Environment variable as std::string
127128
**/
128-
static std::string getEnvironmentVariable(const char* const env_var);
129+
std::string getEnvironmentVariable(const char* const env_var) final;
129130

130131
/**
131132
* @brief Helper function to set thread name
132133
* @param threadName Thread name to be set
133134
* @return True if successfully set, otherwise false
134135
**/
135-
static bool setThreadNameHelper(iox::string<SIZE_THREAD_NAME>& threadName);
136+
bool setThreadNameHelper(iox::string<SIZE_THREAD_NAME>& threadName) final;
136137

137-
#ifdef USE_SYSTEMD
138138
/**
139139
* @brief Helper function to send SDNotify signals
140140
* @param state SDNotify state to be sent
141141
* @return True if signal sending is successful, otherwise false
142142
**/
143-
static bool sendSDNotifySignalHelper(const std::string_view state)
143+
#ifdef USE_SYSTEMD
144+
bool sendSDNotifySignalHelper(const std::string_view state) final
144145
{
145146
auto result = IOX_POSIX_CALL(sd_notify)(0, state.data()).successReturnValue(1).evaluate();
146147
if (result.has_error())
@@ -153,7 +154,7 @@ class ServiceManagementSystemd final : public ServiceManagement
153154
return true;
154155
}
155156
#else
156-
static bool sendSDNotifySignalHelper([[maybe_unused]] const std::string_view state)
157+
bool sendSDNotifySignalHelper([[maybe_unused]] const std::string_view state) final
157158
{
158159
// empty implementation
159160
return true;
@@ -203,6 +204,33 @@ class NoServiceManagementSystemd final : public ServiceManagement
203204
{
204205
// empty implementation
205206
}
207+
208+
/**
209+
* @brief Empty implementation of get environment variable
210+
**/
211+
std::string getEnvironmentVariable([[maybe_unused]] const char* const env_var) final
212+
{
213+
// empty implementation
214+
return "no implement";
215+
}
216+
217+
/**
218+
* @brief Empty implementation set thread name
219+
**/
220+
bool setThreadNameHelper([[maybe_unused]] iox::string<SIZE_THREAD_NAME>& threadName) final
221+
{
222+
// empty implementation
223+
return true;
224+
}
225+
226+
/**
227+
* @brief Empty implementation send SDNotify signals
228+
**/
229+
bool sendSDNotifySignalHelper([[maybe_unused]] const std::string_view state) final
230+
{
231+
// empty implementation
232+
return true;
233+
}
206234
};
207235
} // namespace service_management
208236

iceoryx_posh/source/roudi/roudi.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,10 @@ std::string ServiceManagementSystemd::getEnvironmentVariable(const char* const e
607607

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

614615
if (result.has_error() && result.error().errnum == ERANGE)
615616
{
@@ -680,6 +681,7 @@ void ServiceManagementSystemd::processNotify()
680681
}
681682
}
682683

684+
683685
} // namespace service_management
684686
} // namespace roudi
685687
} // namespace iox
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
2+
// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
// SPDX-License-Identifier: Apache-2.0
17+
18+
#include "iceoryx_posh/internal/roudi/roudi.hpp"
19+
#include <gtest/gtest.h>
20+
21+
#if defined(_WIN32) || defined(_WIN64)
22+
#define GTEST_SKIP_FOR_WINDOWS() GTEST_SKIP() << "Skipping this test on Windows."
23+
#else
24+
#define GTEST_SKIP_FOR_WINDOWS() (void)0
25+
#endif
26+
27+
#ifdef USE_SYSTEMD_TEST
28+
#define GTEST_SKIP_NOT_SUPPORT_SYSTEMD() (void)0
29+
#else
30+
#define GTEST_SKIP_NOT_SUPPORT_SYSTEMD() GTEST_SKIP() << "Skipping this test when systemd is not use."
31+
#endif
32+
33+
34+
TEST(RoudiSystemD, CreateObject)
35+
{
36+
::testing::Test::RecordProperty("TEST_ID", "aa77b5f6-ffb3-4267-982d-dfe85da384ca");
37+
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
38+
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
39+
ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
40+
}
41+
42+
TEST(RoudiSystemD, CheckConstantsSizeThreadName)
43+
{
44+
::testing::Test::RecordProperty("TEST_ID", "9c39f45c-a63c-43ec-9606-e50c33247b3f");
45+
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
46+
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
47+
ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
48+
ASSERT_EQ(roudiSendMessage->SIZE_THREAD_NAME, 15) << "Size thread must equal 15 simbols";
49+
}
50+
51+
TEST(RoudiSystemD, CheckConstantsSizeString)
52+
{
53+
::testing::Test::RecordProperty("TEST_ID", "0b3e3058-6052-49cc-8a67-723f3775a745");
54+
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
55+
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
56+
ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
57+
ASSERT_EQ(roudiSendMessage->SIZE_STRING, 4096) << "Size string must equal 4096 simbols";
58+
}
59+
60+
TEST(RoudiSystemD, SetThreadNameHelper)
61+
{
62+
::testing::Test::RecordProperty("TEST_ID", "b9ff9e83-9dde-4221-bd1e-c1016ec2d5ff");
63+
GTEST_SKIP_FOR_WINDOWS();
64+
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
65+
#ifdef USE_SYSTEMD_TEST
66+
std::unique_ptr<SendMessageServiceManagement> roudiSendMessage;
67+
bool result = true;
68+
69+
ASSERT_NO_THROW(roudiSendMessage = std::make_unique<SendMessageServiceManagement>());
70+
iox::string<SendMessageServiceManagement::SIZE_THREAD_NAME> nameThread = "test";
71+
ASSERT_NO_THROW(result = roudiSendMessage->setThreadNameHelper(nameThread));
72+
ASSERT_EQ(result, true) << "Can not change name thread";
73+
#else
74+
/* need add test (other OS) */
75+
ASSERT_EQ(true, true);
76+
#endif
77+
}
78+
79+
TEST(RoudiSystemD, GetEnvironmentVariableReturnsCorrectValue)
80+
{
81+
::testing::Test::RecordProperty("TEST_ID", "12dfa746-d1f1-4b4e-864d-2cb28ee49f70");
82+
GTEST_SKIP_FOR_WINDOWS();
83+
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
84+
#ifdef USE_SYSTEMD_TEST
85+
const char* const env_var_name = "TEST_ENV_VAR";
86+
const char* const env_var_value = "test_value";
87+
88+
auto set_env = IOX_POSIX_CALL(setenv)(env_var_name, env_var_value, 1).failureReturnValue(-1).evaluate();
89+
EXPECT_FALSE(set_env.has_error()) << "setenv failed with error: " << set_env.get_error().errnum;
90+
91+
SendMessageServiceManagement sut;
92+
93+
std::string result = sut.getEnvironmentVariable(env_var_name);
94+
if (result != "no implement")
95+
{
96+
EXPECT_EQ(result, env_var_value);
97+
}
98+
else
99+
{
100+
EXPECT_EQ(result, "no implement");
101+
}
102+
#else
103+
/* need add test (other OS) */
104+
ASSERT_EQ(true, true);
105+
#endif
106+
}
107+
108+
TEST(RoudiSystemD, GetEnvironmentVariableHandlesNonExistentVar)
109+
{
110+
::testing::Test::RecordProperty("TEST_ID", "9595728f-a504-46e3-8672-b074696326a4");
111+
GTEST_SKIP_FOR_WINDOWS();
112+
GTEST_SKIP_NOT_SUPPORT_SYSTEMD();
113+
#ifdef USE_SYSTEMD_TEST
114+
SendMessageServiceManagement sut;
115+
116+
std::string result = sut.getEnvironmentVariable("NON_EXISTENT_VAR");
117+
if (result != "no implement")
118+
{
119+
EXPECT_TRUE(result.empty());
120+
}
121+
else
122+
{
123+
EXPECT_EQ(result, "no implement");
124+
}
125+
#else
126+
/* need add test (other OS) */
127+
ASSERT_EQ(true, true);
128+
#endif
129+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
# Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
# SPDX-License-Identifier: Apache-2.0
17+
18+
# This script builds iceoryx_hoofs und iceoryx_posh and executes all tests
19+
20+
set -e
21+
22+
if [ "$USER" != "root" ]; then
23+
echo "Please run this as root or with sudo"
24+
exit 1
25+
fi
26+
27+
msg() {
28+
printf "\033[1;32m%s: %s\033[0m\n" ${FUNCNAME[1]} "$1"
29+
}
30+
31+
WORKSPACE=$(git rev-parse --show-toplevel)
32+
DIR_BUILD="build"
33+
34+
msg "Create unit file"
35+
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
36+
37+
msg "Show unit"
38+
cat /usr/lib/systemd/system/test_iox.service
39+
40+
msg "Daemon reload"
41+
systemctl daemon-reload
42+
43+
msg "Check status"
44+
systemctl status test_iox || true
45+
46+
msg "Start roudi"
47+
systemctl start test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)
48+
49+
msg "Wait for 30 seconds"
50+
sleep 30
51+
52+
msg "Check roudi"
53+
systemctl status test_iox || (echo "Failed to start service"; sudo journalctl -u test_iox -n 50; exit 1)
54+
55+
msg "Stop roudi"
56+
systemctl stop test_iox
57+
58+
msg "Show journal"
59+
journalctl -u test_iox -n 100

0 commit comments

Comments
 (0)