Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions .github/workflows/cpp_ubuntu20_04.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,38 @@ on:
jobs:
build:
runs-on: [ self-hosted, linux ]
env:
rosdistro: ${{ matrix.ubuntu == '20.04' && 'noetic' || 'one' }}
strategy:
fail-fast: false
fail-fast: true
matrix:
rosdistro: [ 'noetic' ]
gcc: [ '8', '9', '10', '11', '13' ]
gcc: [ '8', '9', '10', '11', '12', '13' ]
cxx: [ '11', '14', '17', '20' ]
ubuntu: [ '20.04', '22.04', '24.04']
exclude:
# Exclude GCC 8 on unsupported Ubuntu versions
- gcc: '8'
ubuntu: '22.04'
- gcc: '8'
ubuntu: '24.04'
# Exclude GCC 12 on unsupported Ubuntu version
- gcc: '12'
ubuntu: '20.04'
# Exclude all combinations of Ubuntu 22.04 or 24.04 with CXX 11 or 14
- ubuntu: '22.04'
cxx: '11'
- ubuntu: '22.04'
cxx: '14'
- ubuntu: '24.04'
cxx: '11'
- ubuntu: '24.04'
cxx: '14'
container:
image: omavteam/ubuntu-omav-ros:ros-noetic-ros-base
image: omavteam/ubuntu-omav-ros:ros-ros-base-${{ matrix.ubuntu }}
credentials:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
name: ROS ${{ matrix.rosdistro }} - GCC ${{ matrix.gcc }} - C++${{ matrix.cxx }}
name: Ubuntu ${{ matrix.ubuntu }} - GCC ${{ matrix.gcc }} - C++${{ matrix.cxx }}
steps:
- uses: actions/checkout@v4
name: Checkout lpp
Expand All @@ -37,11 +57,11 @@ jobs:
g++ --version

- name: Build lpp
run: source /opt/ros/${{ matrix.rosdistro }}/setup.bash && catkin build -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DLPP_BUILD_TESTS=1 lpp && source ${GITHUB_WORKSPACE}/catkin_ws/devel/setup.bash
run: source /opt/ros/${{ env.rosdistro }}/setup.bash && catkin build -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} -DLPP_BUILD_TESTS=1 lpp && source ${GITHUB_WORKSPACE}/catkin_ws/devel/setup.bash
working-directory: catkin_ws
shell: bash

- name: Run unittests
run: source /opt/ros/${{ matrix.rosdistro }}/setup.bash && source ${GITHUB_WORKSPACE}/catkin_ws/devel/setup.bash && rosrun lpp test_lpp && rosrun lpp test_glog && rosrun lpp test_lpp_custom && rosrun lpp test_nolog && rosrun lpp test_default && rosrun lpp test_roslog
run: source /opt/ros/${{ env.rosdistro }}/setup.bash && source ${GITHUB_WORKSPACE}/catkin_ws/devel/setup.bash && rosrun lpp test_lpp && rosrun lpp test_glog && rosrun lpp test_lpp_custom && rosrun lpp test_nolog && rosrun lpp test_default && rosrun lpp test_roslog
working-directory: catkin_ws
shell: bash
20 changes: 15 additions & 5 deletions include/log++.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ inline static Init lppInit;
#undef DLOG_EVERY_N
#undef DLOG_IF_EVERY_N
#undef LOG_STRING
#if defined(LOG_EVERY_T)
#undef LOG_EVERY_T
#undef DLOG_EVERY_T
#define LPP_IS_GLOG_V0_6
#define LPP_GLOG_V0_6_WARNING(str)
#endif
#endif

#ifndef LPP_GLOG_V0_6_WARNING
#define LPP_GLOG_V0_6_WARNING(str) LPP_WARN(str)
#endif

#if defined LPP_ROSLOG_SUPPORTED && !defined MODE_ROSLOG && !defined MODE_DEFAULT
Expand Down Expand Up @@ -277,11 +287,11 @@ inline void LOG_INIT([[maybe_unused]] char *argv, [[maybe_unused]] const std::fu
#if defined MODE_GLOG || defined MODE_DEFAULT
#define LOG_1(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()

#ifndef LOG_EVERY_T
#define LPP_INTL_LOG_EVERY_T(severity, t) LPP_WARN("LOG_EVERY_T is only defined in GLOG v0.6 or newer. File name and line numbers will be invalid in the log output.") \
LPP_INTL::InternalPolicyLog<float>(LPP_GET_KEY(), t, toBase(severity), LPP_INTL::PolicyType::TIMED)

#define LOG_EVERY_T(severity, t) LPP_WARN("LOG_EVERY_T is only defined in GLOG v0.6 or newer.") \
#define LPP_INTL_LOG_EVERY_T(severity, t) LPP_GLOG_V0_6_WARNING("LOG_EVERY_T is only defined in GLOG v0.6 or newer. File name and line numbers will be invalid in the log output.") \
LPP_INTL::InternalPolicyLog<float>(LPP_GET_KEY(), t, toBase(severity), LPP_INTL::PolicyType::TIMED)
#ifndef LOG_EVERY_T
#define LOG_EVERY_T(severity, t) LPP_GLOG_V0_6_WARNING("LOG_EVERY_T is only defined in GLOG v0.6 or newer.") \
LPP_INTL::InternalPolicyLog<float>(LPP_GET_KEY(), t, toBase(LPP_INTL::GlogSeverity::severity), LPP_INTL::PolicyType::TIMED)
#endif

Expand Down Expand Up @@ -409,7 +419,7 @@ if constexpr(LPP_INTL::LppSeverity::severity == LPP_INTL::LppSeverity::I

#if defined MODE_ROSLOG || defined MODE_LPP
#define LOG_EVERY_N(severity, n) LPP_INTL::InternalPolicyLog<unsigned int>(LPP_GET_KEY(), n, LPP_INTL::toBase(LPP_INTL::GlogSeverity::severity), LPP_INTL::PolicyType::EVERY_N)
#define LOG_EVERY_T(severity, t) LPP_WARN("LOG_EVERY_T is only defined in GLOG v0.6 or newer.") LPP_INTL::InternalPolicyLog<float>(LPP_GET_KEY(), t, LPP_INTL::toBase(LPP_INTL::GlogSeverity::severity), LPP_INTL::PolicyType::TIMED)
#define LOG_EVERY_T(severity, t) LPP_GLOG_V0_6_WARNING("LOG_EVERY_T is only defined in GLOG v0.6 or newer.") LPP_INTL::InternalPolicyLog<float>(LPP_GET_KEY(), t, LPP_INTL::toBase(LPP_INTL::GlogSeverity::severity), LPP_INTL::PolicyType::TIMED)
#define LOG_IF_EVERY_N(severity, condition, n) if (condition) LOG_EVERY_N(severity, n)
#define LOG_FIRST_N(severity, n) LPP_INTL::InternalPolicyLog<unsigned int>(LPP_GET_KEY(), n, LPP_INTL::toBase(LPP_INTL::GlogSeverity::severity), LPP_INTL::PolicyType::FIRST_N)

Expand Down
39 changes: 27 additions & 12 deletions test/common/async_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ enum StreamType {

struct AsyncTest {
std::string class_name;
std::string expected_output;
std::vector<std::string> expected_output;
std::function<void()> fn;
CompareType compare_type;
StreamType stream_type;
Expand Down Expand Up @@ -111,11 +111,12 @@ class TestResult {

if ((i == 0 || i % 4 == 0)) {
if (!compare(a.compare_type, output, a.expected_output)) {
std::cout << a.class_name << " failed. Output: " << output << " expected output: " << a.expected_output

std::cout << a.class_name << " failed. Output: " << output << " expected output: " << a.expected_output[0]
<< std::endl;
test_status = false;
}
} else if (!compare(a.compare_type, output, "")) {
} else if (!compare(a.compare_type, output, {""})) {
std::cout << a.class_name << " failed. Output: " << output << " expected output: " << "\"\"" << std::endl;
test_status = false;
}
Expand All @@ -125,7 +126,7 @@ class TestResult {
}

//gtest assertions only work on main thread
static inline bool compare(CompareType compare_type, const std::string &output, const std::string &expected_output) {
static inline bool compare(CompareType compare_type, const std::string &output, const std::vector<std::string> &expected_output) {
switch (compare_type) {
case EQUAL:return compareEquality(output, expected_output);
case IS_SUBSTRING: return compareSubstring(output, expected_output);
Expand All @@ -134,19 +135,33 @@ class TestResult {
}
}

static inline bool compareSubstring(const std::string &output, const std::string &expected_output) {
if (expected_output.empty()) {
return output.empty();
static inline bool compareSubstring(const std::string &output, const std::vector<std::string> &expected_output) {
bool res = false;
for (const auto &eo: expected_output) {
if (isSubstring(output, eo)) {
res = true;
break;
}
}
return isSubstring(output, expected_output);
return res;
};

static inline bool compareEquality(const std::string &output, const std::string &expected_output) {
return output == expected_output;
static inline bool compareEquality(const std::string &output, const std::vector<std::string> &expected_output) {
for (const auto &eo: expected_output) {
if (output == eo) {
return true;
}
}
return false;
};

static inline bool compareRemoveNumbersFromString(const std::string &output, const std::string &expected_output) {
return expected_output == removeNumbersFromString(output);
static inline bool compareRemoveNumbersFromString(const std::string &output, const std::vector<std::string> &expected_output) {
for (const auto &eo: expected_output) {
if (removeNumbersFromString(output) == removeNumbersFromString(eo)) {
return true;
}
}
return false;
}

inline void insert(const std::string &test_name, bool test_status) {
Expand Down
29 changes: 25 additions & 4 deletions test/common/test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
extern char **test_argv;

inline static bool isSubstring(const std::string &string, const std::string &substring) {
if (string.empty() && substring.empty()) {
return true;
}

bool res = (string.find(substring) != std::string::npos);

if(!res) {
Expand Down Expand Up @@ -89,16 +93,20 @@ namespace testing {
inline static constexpr const char *ERROR_MESSAGE = "Base angle (%f) is less than the minimum angle (%f)";
inline static const std::string EXPECTED_ERROR_MESSAGE = "Base angle (3.300000) is less than the minimum angle (5.500000)\n";
}
}


namespace lpp {
namespace rostest{
namespace rostest {
inline static const std::string debug = "\x1B[m[DEBUG] [.]: Test\x1B[m\n";
inline static const std::string info = "\x1B[m[ INFO] [.]: Test\x1B[m\n";
inline static const std::string warning = "\x1B[m[ WARN] [.]: Test\x1B[m\n";
inline static const std::string error = "\x1B[m[ERROR] [.]: Test\x1B[m\n";
inline static const std::string fatal = "\x1B[m[FATAL] [.]: Test\x1B[m\n";
namespace v2 {
inline static const std::string debug = rostest::debug;
inline static const std::string info = "\x1B[m[INFO] [.]: Test\x1B[m\n";
inline static const std::string warning = "\x1B[m[WARN] [.]: Test\x1B[m\n";
inline static const std::string error = rostest::error;
inline static const std::string fatal = rostest::fatal;
}
}


Expand All @@ -108,6 +116,13 @@ inline static const std::string info = "\x1B[m[ INFO] [.]: Base angle (.) is les
inline static const std::string warning = "\x1B[m[ WARN] [.]: Base angle (.) is less than the minimum angle (.)\x1B[m\n";
inline static const std::string error = "\x1B[m[ERROR] [.]: Base angle (.) is less than the minimum angle (.)\x1B[m\n";
inline static const std::string fatal = "\x1B[m[FATAL] [.]: Base angle (.) is less than the minimum angle (.)\x1B[m\n";
namespace v2 {
inline static const std::string debug = rosprintf::debug;
inline static const std::string info = "\x1B[m[INFO] [.]: Base angle (.) is less than the minimum angle (.)\x1B[m\n";
inline static const std::string warning = "\x1B[m[WARN] [.]: Base angle (.) is less than the minimum angle (.)\x1B[m\n";
inline static const std::string error = rosprintf::error;
inline static const std::string fatal = rosprintf::fatal;
}
}


Expand All @@ -116,6 +131,12 @@ inline static const std::string info = "\x1B[m[ INFO] [.]: LOG_STRING: collected
inline static const std::string warning = "\x1B[m[ WARN] [.]: LOG_STRING: collected warn\x1B[m\n";
inline static const std::string error = "\x1B[m[ERROR] [.]: LOG_STRING: collected error\x1B[m\n";
inline static const std::string fatal = "\x1B[m[FATAL] [.]: LOG_STRING: collected fatal\x1B[m\n";
namespace v2 {
inline static const std::string info = "\x1B[m[INFO] [.]: LOG_STRING: collected info\x1B[m\n";
inline static const std::string warning = "\x1B[m[WARN] [.]: LOG_STRING: collected warn\x1B[m\n";
inline static const std::string error = logstr::error;
inline static const std::string fatal = logstr::fatal;
}
}

namespace custom {
Expand Down
22 changes: 11 additions & 11 deletions test/default/test_default_basic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,70 +93,70 @@ TEST(default_basic, lpp_syntax_severity_fatal) {
TEST(default_basic, roslog_syntax_severity_debug) {
LOG_INIT(*test_argv);

std::string output1 = LPP_CAPTURE_STDOUT(ROS_DEBUG("Test"));
ASSERT_EQ(debug, removeNumbersFromString(output1));
std::string output = LPP_CAPTURE_STDOUT(ROS_DEBUG("Test"));
EXPECT_TRUE(debug == removeNumbersFromString(output) || v2::debug == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_debug_stream) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDOUT(ROS_DEBUG_STREAM("Test"));
ASSERT_EQ(debug, removeNumbersFromString(output));
EXPECT_TRUE(debug == removeNumbersFromString(output) || v2::debug == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_info) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDOUT(ROS_INFO("Test"));
ASSERT_EQ(info, removeNumbersFromString(output));
EXPECT_TRUE(info == removeNumbersFromString(output) || v2::info == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_info_stream) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDOUT(ROS_INFO_STREAM("Test"));
ASSERT_EQ(info, removeNumbersFromString(output));
EXPECT_TRUE(info == removeNumbersFromString(output) || v2::info == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_warning) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDERR(ROS_WARN("Test"));
ASSERT_EQ(warning, removeNumbersFromString(output));
EXPECT_TRUE(warning == removeNumbersFromString(output) || v2::warning == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_warning_stream) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDERR(ROS_WARN_STREAM("Test"));
ASSERT_EQ(warning, removeNumbersFromString(output));
EXPECT_TRUE(warning == removeNumbersFromString(output) || v2::warning == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_error) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDERR(ROS_ERROR("Test"));
ASSERT_EQ(error, removeNumbersFromString(output));
EXPECT_TRUE(error == removeNumbersFromString(output) || v2::error == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_error_stream) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDERR(ROS_ERROR_STREAM("" << "Test"));
ASSERT_EQ(error, removeNumbersFromString(output));
EXPECT_TRUE(error == removeNumbersFromString(output) || v2::error == removeNumbersFromString(output));
}

TEST(default_basic, roslog_syntax_severity_fatal) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDERR(ROS_FATAL("Test"));
ASSERT_EQ(fatal, removeNumbersFromString(output));
EXPECT_TRUE(fatal == removeNumbersFromString(output) || v2::fatal == removeNumbersFromString(output));

}

TEST(default_basic, roslog_syntax_severity_fatal_stream) {
LOG_INIT(*test_argv);

std::string output = LPP_CAPTURE_STDERR(ROS_FATAL_STREAM("" << "Test"));
ASSERT_EQ(fatal, removeNumbersFromString(output));
EXPECT_TRUE(fatal == removeNumbersFromString(output) || v2::fatal == removeNumbersFromString(output));
}
Loading