diff --git a/.circleci/config.yml b/.circleci/config.yml index b5756e3..9fc7ca8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: name: Install dependencies command: | sudo apt-get update - sudo apt-get -y install libgtest-dev libcurl4-openssl-dev libboost-dev libgps-dev + sudo apt-get -y install libgtest-dev libgmock-dev libcurl4-openssl-dev libboost-dev libgps-dev - run: name: "Build" command: "make ENABLE_DEBUG=1 USE_GPSD=1" @@ -39,7 +39,7 @@ jobs: name: Install dependencies command: | sudo apt-get update - sudo apt-get -y install libgtest-dev libcurl4-openssl-dev libboost-dev libgps-dev + sudo apt-get -y install libgtest-dev libgmock-dev libcurl4-openssl-dev libboost-dev libgps-dev - run: name: "Build" command: "make USE_GPSD=1" @@ -60,7 +60,7 @@ jobs: name: Install dependencies command: | sudo apt-get update - sudo apt-get -y install libgtest-dev libcurl4-openssl-dev libboost-dev + sudo apt-get -y install libgtest-dev libgmock-dev libcurl4-openssl-dev libboost-dev - run: name: "Build" command: "make ENABLE_DEBUG=1" @@ -81,7 +81,7 @@ jobs: name: Install dependencies command: | sudo apt-get update - sudo apt-get -y install libgtest-dev libcurl4-openssl-dev libboost-dev + sudo apt-get -y install libgtest-dev libgmock-dev libcurl4-openssl-dev libboost-dev - run: name: "Build" command: "make" diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 6d6532b..9f00615 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -13,10 +13,7 @@ "USE_GPSD=1", "all" ], - "group": { - "kind": "build", - "isDefault": true - }, + "group": "build", "problemMatcher": [] }, { @@ -94,7 +91,10 @@ "ENABLE_DEBUG=1", "USE_GPSD=1" ], - "group": "build", + "group": { + "kind": "build", + "isDefault": true + }, "problemMatcher": [] } ] diff --git a/BaseCommon/Log.cpp b/BaseCommon/Log.cpp index 689e69f..6f749e1 100644 --- a/BaseCommon/Log.cpp +++ b/BaseCommon/Log.cpp @@ -27,6 +27,10 @@ bool CLog::m_addedTargets(false); std::recursive_mutex CLog::m_targetsMutex; std::vector CLog::m_targets = { new CLogConsoleTarget(LOG_DEBUG) }; +std::string CLog::m_prevMsg = ""; +uint CLog::m_prevMsgCount = 0U; +uint CLog::m_repeatThreshold = 2U; + void CLog::addTarget(CLogTarget* target) { @@ -51,6 +55,13 @@ void CLog::finalise() } m_targets.clear(); + m_prevMsg.clear(); + m_prevMsgCount = 0; +} + +uint& CLog::getRepeatThreshold() +{ + return CLog::m_repeatThreshold; } void CLog::getTimeStamp(std::string & s) diff --git a/BaseCommon/Log.h b/BaseCommon/Log.h index e2afcc1..7bf9638 100644 --- a/BaseCommon/Log.h +++ b/BaseCommon/Log.h @@ -35,6 +35,9 @@ private: static std::vector m_targets; static bool m_addedTargets; static std::recursive_mutex m_targetsMutex; + static std::string m_prevMsg; + static uint m_prevMsgCount; + static uint m_repeatThreshold; static void getTimeStamp(std::string& s); @@ -68,20 +71,17 @@ private: break; } - std::string timestamp; - getTimeStamp(timestamp); - - std::string f2("[%s] [%s] "); + std::string f2("[%s] "); f2.append(f); - CStringUtils::string_format_in_place(output, f2, timestamp.c_str(), severityStr.c_str(), args...); + CStringUtils::string_format_in_place(output, f2, severityStr.c_str(), args...); boost::trim_if(output, [](char c){ return c == '\n' || c == '\r' || c == ' ' || c == '\t'; }); output.push_back('\n'); } public: - static void addTarget(CLogTarget * target); static void finalise(); + static uint& getRepeatThreshold(); template static void logTrace(const std::string & f, Args... args) { @@ -117,15 +117,41 @@ public: { std::lock_guard lockTarget(m_targetsMutex); + if(m_targets.empty()) + return; + std::string msg; - for(auto target : m_targets) { - if(severity >= target->getLevel()) { + formatLogMessage(msg, severity, f, args...); + + bool repeatedMsg = (msg.compare(m_prevMsg) == 0); - if(msg.empty()) - formatLogMessage(msg, severity, f, args...); + if(repeatedMsg && m_repeatThreshold > 0U) { + m_prevMsgCount++; + if(m_prevMsgCount >= m_repeatThreshold) + return; + } + + m_prevMsg.assign(msg); - target->printLog(msg); + if(m_prevMsgCount >= m_repeatThreshold && !repeatedMsg && m_repeatThreshold > 0U) { + formatLogMessage(msg, severity, "Previous message repeated %d times", m_prevMsgCount - m_repeatThreshold + 1); + m_prevMsg.clear(); + } + + std::string timestamp; + getTimeStamp(timestamp); + std::string msgts; + CStringUtils::string_format_in_place(msgts, "[%s] %s", timestamp.c_str(), msg.c_str()); + + for(auto target : m_targets) { + if(severity >= target->getLevel()) { + target->printLog(msgts); } } + + if(m_prevMsgCount != 0 && !repeatedMsg) { + m_prevMsgCount = 0; + log(severity, f, args ...); + } } }; diff --git a/DStarGateway/DStarGatewayConfig.cpp b/DStarGateway/DStarGatewayConfig.cpp index 15b2028..da334be 100644 --- a/DStarGateway/DStarGatewayConfig.cpp +++ b/DStarGateway/DStarGatewayConfig.cpp @@ -181,6 +181,11 @@ bool CDStarGatewayConfig::loadLog(const CConfig & cfg) else if(levelStr == "none") m_log.displayLevel = LOG_NONE; } + std::string thresholdStr; + ret = cfg.getValue("log", "repeatthreshold", thresholdStr, "2", {"disabled", "1", "2", "3", "4","5", "6", "7", "8", "9", "10"}) && ret; + if(thresholdStr == "disabled") m_log.repeatThreshold = 0; + else m_log.repeatThreshold = ::atoi(thresholdStr.c_str()); + return ret; } diff --git a/DStarGateway/DStarGatewayConfig.h b/DStarGateway/DStarGatewayConfig.h index d148987..1a15d65 100644 --- a/DStarGateway/DStarGatewayConfig.h +++ b/DStarGateway/DStarGatewayConfig.h @@ -88,6 +88,7 @@ typedef struct { LOG_SEVERITY fileLevel; std::string fileRoot; bool fileRotate; + uint repeatThreshold; } TLog; typedef struct { diff --git a/DStarGateway/example.cfg b/DStarGateway/example.cfg index 731da4e..73d7b09 100644 --- a/DStarGateway/example.cfg +++ b/DStarGateway/example.cfg @@ -152,6 +152,7 @@ fileRoot= # defaults to dstarGateway fileRotate= # rotate log files daily, defaults to true fileLevel= # defaults to info, valid values are trace, debug, info, warning, error, fatal, none displayLevel= # defaults to info, valid values are trace, debug, info, warning, error, fatal, none +repeatThreshold=#defaults to 2, valid values are disbaled and 1 to 10. Prevents flooding of logs from repeated log messages. [Paths] data=/usr/local/share/dstargateway.d/ #Path where the data (hostfiles, audio files etc) can be found diff --git a/README.md b/README.md index b0470af..45fd43e 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ The testing framwework used is Google Test. # 5. Version History ## 5.1. Version 1.0 +- [**Improvement**] Limit log reporting ([#44](https://github.com/F4FXL/DStarGateway/issues/44)) - [**Improvement**] Improve CI to include all variants of build configurations ([#40](https://github.com/F4FXL/DStarGateway/issues/40)) - [**Bugfix**] Fix #43 Cache not updated when answering ircddb gateway is only conected to one network ([#43](https://github.com/F4FXL/DStarGateway/issues/43)) - [**Bugfix**] Fix #37 Unable to transmit multiple files (DGWVoiceTransmit) ([#37](https://github.com/F4FXL/DStarGateway/issues/37)) diff --git a/Tests/Log/FakeLogTarget.h b/Tests/Log/FakeLogTarget.h new file mode 100644 index 0000000..6e71ad9 --- /dev/null +++ b/Tests/Log/FakeLogTarget.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021-2024 by Geoffrey Merck F4FXL / KC3FRA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "LogTarget.h" + +class CFakeLogTarget : public CLogTarget +{ +public: + CFakeLogTarget(LOG_SEVERITY logLevel) : + CLogTarget(logLevel) + { + + } + + virtual void printLogInt(const std::string& msg) + { + m_messages.push_back(msg); + std::cout << msg; + } + + std::vector m_messages; +}; \ No newline at end of file diff --git a/Tests/Log/logDebug.cpp b/Tests/Log/logDebug.cpp new file mode 100644 index 0000000..2c751e2 --- /dev/null +++ b/Tests/Log/logDebug.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2021-2024 by Geoffrey Merck F4FXL / KC3FRA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "Log.h" +#include "LogSeverity.h" +#include "FakeLogTarget.h" + +using ::testing::EndsWith; + +namespace LogDebugTests +{ + class Log_logDebug: public ::testing::Test { + protected: + CFakeLogTarget * m_logTarget; + + void SetUp() override + { + m_logTarget = new CFakeLogTarget(LOG_DEBUG); + CLog::addTarget((CLogTarget *)m_logTarget); + } + + void TearDown() override + { + CLog::finalise(); + } + }; + + TEST_F(Log_logDebug, PutError) { + CLog::logError("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + } + + TEST_F(Log_logDebug, PutDebug) { + CLog::logDebug("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be no message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[DEBUG ] One Message\n")); + } + + TEST_F(Log_logDebug, PutInfo) { + CLog::logInfo("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be no message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[INFO ] One Message\n")); + } + + TEST_F(Log_logDebug, PutWarning) { + CLog::logWarning("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[WARNING] One Message\n")); + } + + TEST_F(Log_logDebug, PutTrace) { + CLog::logTrace("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } +} \ No newline at end of file diff --git a/Tests/Log/logError.cpp b/Tests/Log/logError.cpp new file mode 100644 index 0000000..2c5fa3e --- /dev/null +++ b/Tests/Log/logError.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021-2024 by Geoffrey Merck F4FXL / KC3FRA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "Log.h" +#include "LogSeverity.h" +#include "FakeLogTarget.h" + +using ::testing::EndsWith; + +namespace LogErrorTests +{ + class Log_logError: public ::testing::Test { + protected: + CFakeLogTarget * m_logTarget; + + void SetUp() override + { + m_logTarget = new CFakeLogTarget(LOG_ERROR); + CLog::addTarget((CLogTarget *)m_logTarget); + } + + void TearDown() override + { + CLog::finalise(); + } + }; + + TEST_F(Log_logError, PutError) { + CLog::logError("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + } + + TEST_F(Log_logError, PutDebug) { + CLog::logDebug("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } + + TEST_F(Log_logError, PutInfo) { + CLog::logInfo("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } + + TEST_F(Log_logError, PutWarning) { + CLog::logWarning("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } + + TEST_F(Log_logError, PutTrace) { + CLog::logTrace("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } +} \ No newline at end of file diff --git a/Tests/Log/logInfo.cpp b/Tests/Log/logInfo.cpp new file mode 100644 index 0000000..96f28fd --- /dev/null +++ b/Tests/Log/logInfo.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2021-2024 by Geoffrey Merck F4FXL / KC3FRA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "Log.h" +#include "LogSeverity.h" +#include "FakeLogTarget.h" + +using ::testing::EndsWith; + +namespace LogInfoTests +{ + class Log_logInfo: public ::testing::Test { + protected: + CFakeLogTarget * m_logTarget; + + void SetUp() override + { + m_logTarget = new CFakeLogTarget(LOG_INFO); + CLog::addTarget((CLogTarget *)m_logTarget); + } + + void TearDown() override + { + CLog::finalise(); + } + }; + + TEST_F(Log_logInfo, PutError) { + CLog::logError("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + } + + TEST_F(Log_logInfo, PutDebug) { + CLog::logDebug("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } + + TEST_F(Log_logInfo, PutInfo) { + CLog::logInfo("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[INFO ] One Message\n")); + } + + TEST_F(Log_logInfo, PutWarning) { + CLog::logWarning("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[WARNING] One Message\n")); + } + + TEST_F(Log_logInfo, PutTrace) { + CLog::logTrace("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } +} \ No newline at end of file diff --git a/Tests/Log/logRepeat.cpp b/Tests/Log/logRepeat.cpp new file mode 100644 index 0000000..99a6b8a --- /dev/null +++ b/Tests/Log/logRepeat.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2021-2024 by Geoffrey Merck F4FXL / KC3FRA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "Log.h" +#include "LogSeverity.h" +#include "FakeLogTarget.h" + +using ::testing::EndsWith; + +namespace LogRepeatTests +{ + class LogRepeat: public ::testing::Test { + protected: + CFakeLogTarget * m_logTarget; + + void SetUp() override + { + m_logTarget = new CFakeLogTarget(LOG_ERROR); + CLog::addTarget((CLogTarget *)m_logTarget); + } + + void TearDown() override + { + CLog::finalise(); + } + }; + + TEST_F(LogRepeat, TwoMessage) { + CLog::logError("One Message"); + CLog::logError("Two Message"); + + EXPECT_EQ(2, m_logTarget->m_messages.size()) << "There should be exactly two messages in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + EXPECT_THAT(m_logTarget->m_messages[1].c_str(), EndsWith("[ERROR ] Two Message\n")); + } + + TEST_F(LogRepeat, ThreeIdenticalMessageThreshold1) { + CLog::getRepeatThreshold() = 1U; + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + } + + TEST_F(LogRepeat, NineIdenticalMessageTwoDifferentThreshold1) { + CLog::getRepeatThreshold() = 1U; + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("Another Message"); + CLog::logError("And here is another Message"); + + EXPECT_EQ(4, m_logTarget->m_messages.size()) << "There should be two message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + EXPECT_THAT(m_logTarget->m_messages[1].c_str(), EndsWith("[ERROR ] Previous message repeated 8 times\n")); + EXPECT_THAT(m_logTarget->m_messages[2].c_str(), EndsWith("[ERROR ] Another Message\n")); + EXPECT_THAT(m_logTarget->m_messages[3].c_str(), EndsWith("[ERROR ] And here is another Message\n")); + } + + + TEST_F(LogRepeat, ThreeIdenticalMessageThreshold2) { + CLog::getRepeatThreshold() = 2U; + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + + EXPECT_EQ(2, m_logTarget->m_messages.size()) << "There should be two messages in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + EXPECT_THAT(m_logTarget->m_messages[1].c_str(), EndsWith("[ERROR ] One Message\n")); + } + + TEST_F(LogRepeat, NineIdenticalMessageTwoDifferentThreshold2) { + CLog::getRepeatThreshold() = 2U; + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("One Message"); + CLog::logError("Another Message"); + CLog::logError("And here is another Message"); + + EXPECT_EQ(5, m_logTarget->m_messages.size()) << "There should be two message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + EXPECT_THAT(m_logTarget->m_messages[1].c_str(), EndsWith("[ERROR ] One Message\n")); + EXPECT_THAT(m_logTarget->m_messages[2].c_str(), EndsWith("[ERROR ] Previous message repeated 7 times\n")); + EXPECT_THAT(m_logTarget->m_messages[3].c_str(), EndsWith("[ERROR ] Another Message\n")); + EXPECT_THAT(m_logTarget->m_messages[4].c_str(), EndsWith("[ERROR ] And here is another Message\n")); + } +} \ No newline at end of file diff --git a/Tests/Log/logTrace.cpp b/Tests/Log/logTrace.cpp new file mode 100644 index 0000000..4b725bb --- /dev/null +++ b/Tests/Log/logTrace.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021-2024 by Geoffrey Merck F4FXL / KC3FRA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "Log.h" +#include "LogSeverity.h" +#include "FakeLogTarget.h" + +using ::testing::EndsWith; + +namespace LogTraceTests +{ + class Log_logTrace: public ::testing::Test { + protected: + CFakeLogTarget * m_logTarget; + + void SetUp() override + { + m_logTarget = new CFakeLogTarget(LOG_TRACE); + CLog::addTarget((CLogTarget *)m_logTarget); + } + + void TearDown() override + { + CLog::finalise(); + } + }; + + TEST_F(Log_logTrace, PutError) { + CLog::logError("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + } + + TEST_F(Log_logTrace, PutDebug) { + CLog::logDebug("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[DEBUG ] One Message\n")); + } + + TEST_F(Log_logTrace, PutInfo) { + CLog::logInfo("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[INFO ] One Message\n")); + } + + TEST_F(Log_logTrace, PutWarning) { + CLog::logWarning("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[WARNING] One Message\n")); + } + + TEST_F(Log_logTrace, PutTrace) { + CLog::logTrace("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[TRACE ] One Message\n")); + } +} \ No newline at end of file diff --git a/Tests/Log/logWarning.cpp b/Tests/Log/logWarning.cpp new file mode 100644 index 0000000..62938d0 --- /dev/null +++ b/Tests/Log/logWarning.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2021-2024 by Geoffrey Merck F4FXL / KC3FRA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "Log.h" +#include "LogSeverity.h" +#include "FakeLogTarget.h" + +using ::testing::EndsWith; + +namespace LogWarningTests +{ + class Log_logWarning: public ::testing::Test { + protected: + CFakeLogTarget * m_logTarget; + + void SetUp() override + { + m_logTarget = new CFakeLogTarget(LOG_WARNING); + CLog::addTarget((CLogTarget *)m_logTarget); + } + + void TearDown() override + { + CLog::finalise(); + } + }; + + TEST_F(Log_logWarning, PutError) { + CLog::logError("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[ERROR ] One Message\n")); + } + + TEST_F(Log_logWarning, PutDebug) { + CLog::logDebug("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } + + TEST_F(Log_logWarning, PutInfo) { + CLog::logInfo("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } + + TEST_F(Log_logWarning, PutWarning) { + CLog::logWarning("One Message"); + + EXPECT_EQ(1, m_logTarget->m_messages.size()) << "There should be one message in the log."; + EXPECT_THAT(m_logTarget->m_messages[0].c_str(), EndsWith("[WARNING] One Message\n")); + } + + TEST_F(Log_logWarning, PutTrace) { + CLog::logTrace("One Message"); + + EXPECT_EQ(0, m_logTarget->m_messages.size()) << "There should be no message in the log."; + } +} \ No newline at end of file diff --git a/Tests/Makefile b/Tests/Makefile index d3b30bb..c31eb4c 100644 --- a/Tests/Makefile +++ b/Tests/Makefile @@ -3,7 +3,7 @@ OBJS = $(SRCS:.cpp=.o) DEPS = $(SRCS:.cpp=.d) dstargateway_tests: ../VersionInfo/GitVersion.h $(OBJS) ../APRS/APRS.a ../IRCDDB/IRCDDB.a ../DStarBase/DStarBase.a ../BaseCommon/BaseCommon.a ../Common/Common.a - $(CC) $(CPPFLAGS) -o dstargateway_tests $(OBJS) ../Common/Common.a ../APRS/APRS.a ../DStarBase/DStarBase.a ../IRCDDB/IRCDDB.a ../BaseCommon/BaseCommon.a $(LDFLAGS) -lgtest -lgtest_main + $(CC) $(CPPFLAGS) -o dstargateway_tests $(OBJS) ../Common/Common.a ../APRS/APRS.a ../DStarBase/DStarBase.a ../IRCDDB/IRCDDB.a ../BaseCommon/BaseCommon.a $(LDFLAGS) -lgtest -lgtest_main -lgmock %.o : %.cpp $(CC) $(CPPFLAGS) -DUNIT_TESTS -I../APRS -I../Common -I../BaseCommon -I../DStarBase -I../IRCDDB -I../VersionInfo -MMD -MD -c $< -o $@