diff --git a/AampLogManager.h b/AampLogManager.h index 52fd6c5bb..c32c061c0 100644 --- a/AampLogManager.h +++ b/AampLogManager.h @@ -51,7 +51,7 @@ extern const char* GetMediaTypeName( AampMediaType mediaType ); // from AampUtil do { \ if( (LEVEL) >= AampLogManager::aampLoglevel ) \ { \ -logprintf( LEVEL, __FUNCTION__, __LINE__, FORMAT, ##__VA_ARGS__); \ +logprintf( LEVEL, __FILE__, __FUNCTION__, __LINE__, FORMAT, ##__VA_ARGS__); \ } \ } while(0) @@ -126,7 +126,7 @@ struct AAMPAbrInfo * @param[in] format - printf style string * @return void */ -extern void logprintf(AAMP_LogLevel level, const char* file, int line,const char *format, ...) __attribute__ ((format (printf, 4, 5))); +extern void logprintf(AAMP_LogLevel level, const char* file, const char* func, int line,const char *format, ...) __attribute__ ((format (printf, 5, 6))); extern thread_local int gPlayerId; @@ -169,7 +169,7 @@ class AampLogManager /* loggerData is the playerId ... set it in case we are in a helper thread that the ** caller has spawned. */ UsingPlayerId playerId(loggerData); - logprintf(eLOGLEVEL_MIL , __FUNCTION__, __LINE__, "%s", tsbMessage.c_str()); + logprintf(eLOGLEVEL_MIL , __FILE__, __FUNCTION__, __LINE__, "%s", tsbMessage.c_str()); } /** @@ -186,7 +186,7 @@ class AampLogManager std::string location; std::string symptom; ParseContentUrl(url, location, symptom, type); - logprintf( eLOGLEVEL_WARN, __FUNCTION__, __LINE__, "AAMPLogNetworkLatency downloadTime=%d downloadThreshold=%d type='%s' location='%s' symptom='%s' url='%s'", + logprintf( eLOGLEVEL_WARN, __FILE__, __FUNCTION__, __LINE__, "AAMPLogNetworkLatency downloadTime=%d downloadThreshold=%d type='%s' location='%s' symptom='%s' url='%s'", downloadTime, downloadThresholdTimeoutMs, GetMediaTypeName(type), location.c_str(), symptom.c_str(), url); } @@ -211,14 +211,14 @@ class AampLogManager { if(errorCode >= 400) { - logprintf( eLOGLEVEL_ERROR, __FUNCTION__, __LINE__, "AAMPLogNetworkError error='http error %d' type='%s' location='%s' symptom='%s' url='%s'", + logprintf( eLOGLEVEL_ERROR, __FILE__, __FUNCTION__, __LINE__, "AAMPLogNetworkError error='http error %d' type='%s' location='%s' symptom='%s' url='%s'", errorCode, GetMediaTypeName(type), location.c_str(), symptom.c_str(), url ); } } break; /*AAMPNetworkErrorHttp*/ case AAMPNetworkErrorTimeout: - logprintf( eLOGLEVEL_ERROR, __FUNCTION__, __LINE__, "AAMPLogNetworkError error='timeout %d' type='%s' location='%s' symptom='%s' url='%s'", + logprintf( eLOGLEVEL_ERROR, __FILE__, __FUNCTION__, __LINE__, "AAMPLogNetworkError error='timeout %d' type='%s' location='%s' symptom='%s' url='%s'", errorCode, GetMediaTypeName(type), location.c_str(), symptom.c_str(), url ); break; /*AAMPNetworkErrorTimeout*/ @@ -226,7 +226,7 @@ class AampLogManager { if(errorCode > 0) { - logprintf( eLOGLEVEL_ERROR, __FUNCTION__, __LINE__, "AAMPLogNetworkError error='curl error %d' type='%s' location='%s' symptom='%s' url='%s'", + logprintf( eLOGLEVEL_ERROR, __FILE__, __FUNCTION__, __LINE__, "AAMPLogNetworkError error='curl error %d' type='%s' location='%s' symptom='%s' url='%s'", errorCode, GetMediaTypeName(type), location.c_str(), symptom.c_str(), url ); } } @@ -353,7 +353,7 @@ class AampLogManager symptom += " (or) freeze/buffering"; } - logprintf( eLOGLEVEL_WARN, __FUNCTION__, __LINE__, "AAMPLogABRInfo : switching to '%s' profile '%d -> %d' currentBandwidth[%ld]->desiredBandwidth[%ld] nwBandwidth[%ld] reason='%s' symptom='%s'", + logprintf( eLOGLEVEL_WARN, __FILE__, __FUNCTION__, __LINE__, "AAMPLogABRInfo : switching to '%s' profile '%d -> %d' currentBandwidth[%ld]->desiredBandwidth[%ld] nwBandwidth[%ld] reason='%s' symptom='%s'", profile.c_str(), pstAbrInfo->currentProfileIndex, pstAbrInfo->desiredProfileIndex, pstAbrInfo->currentBandwidth, pstAbrInfo->desiredBandwidth, pstAbrInfo->networkBandwidth, reason.c_str(), symptom.c_str()); } diff --git a/aamplogging.cpp b/aamplogging.cpp index b617e0dbb..bca636746 100644 --- a/aamplogging.cpp +++ b/aamplogging.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "priv_aamp.h" using namespace std; @@ -79,11 +81,17 @@ bool AampLogManager::locked = false; thread_local int gPlayerId = -1; +// Sequential log counter for tracking missing log lines +static std::atomic gLogCounter(0); + /** * @brief Print logs to console / log file */ -void logprintf(AAMP_LogLevel logLevelIndex, const char* file, int line, const char *format, ...) +void logprintf(AAMP_LogLevel logLevelIndex, const char* file, const char* func, int line, const char *format, ...) { + // Increment log counter for each log line + uint32_t logSeqNum = gLogCounter.fetch_add(1, std::memory_order_relaxed) % 1000; + char timestamp[AAMPCLI_TIMESTAMP_PREFIX_MAX_CHARS]; timestamp[0] = 0x00; if( AampLogManager::disableLogRedirection ) @@ -98,12 +106,13 @@ void logprintf(AAMP_LogLevel logLevelIndex, const char* file, int line, const ch for( int pass=0; pass<2; pass++ ) { // two pass: measure required bytes then populate format string format_bytes = snprintf(format_ptr, format_bytes, - "%s[AAMP-PLAYER][%d][%s][%zx][%s][%d]%s\n", + "%s[AAMP-PLAYER][%03u][%d][%s][%zx][%s][%d]%s\n", timestamp, + logSeqNum, gPlayerId, mLogLevelStr[logLevelIndex], GetPrintableThreadID(), - file, line, + func, line, format ); if( format_bytes<=0 ) { // should never happen! diff --git a/middleware/playerLogManager/PlayerLogManager.cpp b/middleware/playerLogManager/PlayerLogManager.cpp index 1508ac127..b97b7b31b 100644 --- a/middleware/playerLogManager/PlayerLogManager.cpp +++ b/middleware/playerLogManager/PlayerLogManager.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "PlayerLogManager.h" #include "PlayerUtils.h" @@ -81,6 +82,9 @@ bool PlayerLogManager::disableLogRedirection = false; bool PlayerLogManager::enableEthanLogRedirection = false; static std::hash std_thread_hasher; + +// Sequential log counter for tracking missing log lines +static std::atomic gMWLogCounter(0); std::size_t GetPlayerPrintableThreadID( void ) { return std_thread_hasher( std::this_thread::get_id() ); @@ -88,8 +92,11 @@ std::size_t GetPlayerPrintableThreadID( void ) /** * @brief Print logs to console / log file */ -void logprintf(MW_LogLevel logLevelIndex, const char* file, int line, const char *format, ...) +void logprintf(MW_LogLevel logLevelIndex, const char* file, const char* func, int line, const char *format, ...) { + // Increment log counter for each log line, wrap at 1000 for consistent 3-digit formatting + uint32_t logSeqNum = gMWLogCounter.fetch_add(1, std::memory_order_relaxed) % 1000; + char timestamp[MW_CLI_TIMESTAMP_PREFIX_MAX_CHARS]; timestamp[0] = 0x00; if( PlayerLogManager::disableLogRedirection ) @@ -103,11 +110,12 @@ void logprintf(MW_LogLevel logLevelIndex, const char* file, int line, const char for( int pass=0; pass<2; pass++ ) { format_bytes = snprintf(format_ptr, format_bytes, - "%s[PLAYER_IF][%s][%zx][%s][%d]%s\n", + "%s[PLAYER_IF][%03u][%s][%zx][%s][%d]%s\n", timestamp, + logSeqNum, mLogLevelStr[logLevelIndex], GetPlayerPrintableThreadID(), - file, line, + func, line, format ); if( format_bytes<=0 ) { // should never happen! diff --git a/middleware/playerLogManager/PlayerLogManager.h b/middleware/playerLogManager/PlayerLogManager.h index 1a906f1da..c7d98016e 100644 --- a/middleware/playerLogManager/PlayerLogManager.h +++ b/middleware/playerLogManager/PlayerLogManager.h @@ -131,7 +131,7 @@ void DumpBinaryBlob(const unsigned char *ptr, size_t len); * @param[in] format - printf style string * @return void */ -extern void logprintf(MW_LogLevel logLevelIndex, const char* file, int line, const char *format, ...) __attribute__ ((format (printf, 4, 5))); +extern void logprintf(MW_LogLevel logLevelIndex, const char* file, const char* func, int line, const char *format, ...) __attribute__ ((format (printf, 5, 6))); #define MW_CLI_TIMESTAMP_PREFIX_MAX_CHARS 20 #define MW_CLI_TIMESTAMP_PREFIX_FORMAT "%u.%03u: " @@ -140,7 +140,7 @@ extern void logprintf(MW_LogLevel logLevelIndex, const char* file, int line, con do{\ if( (LEVEL) >= PlayerLogManager::mwLoglevel ) \ { \ - logprintf( LEVEL, __FUNCTION__, __LINE__, FORMAT, ##__VA_ARGS__); \ + logprintf( LEVEL, __FILE__, __FUNCTION__, __LINE__, FORMAT, ##__VA_ARGS__); \ }\ }while(0) diff --git a/test/utests/drm/mocks/aampMocks.cpp b/test/utests/drm/mocks/aampMocks.cpp index 1ea8642a4..8ed267b7d 100644 --- a/test/utests/drm/mocks/aampMocks.cpp +++ b/test/utests/drm/mocks/aampMocks.cpp @@ -176,7 +176,7 @@ bool AampLogManager::enableEthanLogRedirection = false; AAMP_LogLevel AampLogManager::aampLoglevel = eLOGLEVEL_WARN; bool AampLogManager::locked = false; -void logprintf(AAMP_LogLevel level, const char *file, int line, const char *format, +void logprintf(AAMP_LogLevel level, const char *file, const char *func, int line, const char *format, ...) { int playerId = -1; @@ -188,7 +188,7 @@ void logprintf(AAMP_LogLevel level, const char *file, int line, const char *form "[AAMP-PLAYER][%d][%s][%s][%d]%s\n", playerId, mLogLevelStr[level], - file, + func, line, format ); vprintf(fmt, args); diff --git a/test/utests/fakes/FakeAampLogManager.cpp b/test/utests/fakes/FakeAampLogManager.cpp index 9ecc06fb5..4041ef899 100644 --- a/test/utests/fakes/FakeAampLogManager.cpp +++ b/test/utests/fakes/FakeAampLogManager.cpp @@ -52,7 +52,7 @@ bool AampLogManager::locked = true; thread_local int gPlayerId = -1; -void logprintf(AAMP_LogLevel level, const char* file, int line, const char *format, ...) +void logprintf(AAMP_LogLevel level, const char* file, const char* func, int line, const char *format, ...) { char timestamp[AAMPCLI_TIMESTAMP_PREFIX_MAX_CHARS]; timestamp[0] = 0x00; @@ -72,7 +72,7 @@ void logprintf(AAMP_LogLevel level, const char* file, int line, const char *form gPlayerId, mLogLevelStr[level], std_thread_hasher( std::this_thread::get_id() ), - file, line, + func, line, format ); assert( format_bytes>0 ); if( pass==0 ) diff --git a/test/utests/fakes/FakePlayerLogManager.cpp b/test/utests/fakes/FakePlayerLogManager.cpp index 84d224c79..25e0f5c35 100644 --- a/test/utests/fakes/FakePlayerLogManager.cpp +++ b/test/utests/fakes/FakePlayerLogManager.cpp @@ -32,7 +32,7 @@ bool PlayerLogManager::enableEthanLogRedirection = false; /** * @brief Print logs to console / log file */ -void logprintf(MW_LogLevel logLevelIndex, const char* file, int line, const char *format, ...) +void logprintf(MW_LogLevel logLevelIndex, const char* file, const char* func, int line, const char *format, ...) { } diff --git a/test/utests/tests/AampLogManagerTests/AampLogManagerTests.cpp b/test/utests/tests/AampLogManagerTests/AampLogManagerTests.cpp index fa55e9386..9556174e6 100644 --- a/test/utests/tests/AampLogManagerTests/AampLogManagerTests.cpp +++ b/test/utests/tests/AampLogManagerTests/AampLogManagerTests.cpp @@ -580,12 +580,13 @@ TEST_F(AampLogManagerTest, logprintf_Test1) //Arrange: Creating the variables for passing to arguments AAMP_LogLevel level = eLOGLEVEL_INFO; const char* file = "test.cpp"; + const char* func = "testFunction"; int line = 2; const char *format = "s3"; const char *format2 = "s4"; //Act: Calling the function for test - logprintf(level,file,line,format,format2); + logprintf(level,file,func,line,format,format2); } TEST_F(AampLogManagerTest, timestampStringify ) @@ -675,8 +676,13 @@ TEST_F(AampLogManagerTest, AAMPLOG_INFO) TEST_F(AampLogManagerTest, AAMPLOG_WARN) { const std::string message{"Test WARN log line"}; - /* The printed log line must contain the default player ID (-1) and the message. */ - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[-1]"), HasSubstr("[WARN]"), HasSubstr(message.c_str())))); + // The printed log line must contain the sequence number, default player ID (-1), level and the message + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[-1]"), + HasSubstr("[WARN]"), + HasSubstr(message.c_str())))); AAMPLOG_WARN("%s", message.c_str()); } @@ -687,8 +693,13 @@ TEST_F(AampLogManagerTest, AAMPLOG_WARN) TEST_F(AampLogManagerTest, AAMPLOG_MIL) { const std::string message{"Test MIL log line"}; - /* The printed log line must contain the default player ID (-1) and the message. */ - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[-1]"), HasSubstr("[MIL]"), HasSubstr(message.c_str())))); + // The printed log line must contain the sequence number, default player ID (-1), level and the message + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[-1]"), + HasSubstr("[MIL]"), + HasSubstr(message.c_str())))); AAMPLOG_MIL("%s", message.c_str()); } @@ -699,8 +710,13 @@ TEST_F(AampLogManagerTest, AAMPLOG_MIL) TEST_F(AampLogManagerTest, AAMPLOG_ERR) { const std::string message{"Test ERROR log line"}; - /* The printed log line must contain the default player ID (-1) and the message. */ - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[-1]"), HasSubstr("[ERROR]"), HasSubstr(message.c_str())))); + // The printed log line must contain the sequence number, default player ID (-1), level and the message + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[-1]"), + HasSubstr("[ERROR]"), + HasSubstr(message.c_str())))); AAMPLOG_ERR("%s", message.c_str()); } @@ -712,8 +728,13 @@ TEST_F(AampLogManagerTest, setLogLevelMil_AAMPLOG_MIL) { const std::string message{"Test MIL log line"}; AampLogManager::setLogLevel(eLOGLEVEL_MIL); - /* The printed log line must contain the default player ID (-1) and the message. */ - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[-1]"), HasSubstr("[MIL]"), HasSubstr(message.c_str())))); + // The printed log line must contain the sequence number, default player ID (-1), level and the message + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[-1]"), + HasSubstr("[MIL]"), + HasSubstr(message.c_str())))); AAMPLOG_MIL("%s", message.c_str()); } @@ -733,22 +754,36 @@ TEST_F(AampLogManagerTest, logprintf_TRACE) { AAMP_LogLevel level = eLOGLEVEL_TRACE; std::string file("test.cpp"); + std::string func("testFunc"); int line = 2; std::string message("message"); - // The printed log line must contain the player ID, level, file and the message / - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[" + std::to_string(-1) + "]"), HasSubstr("[TRACE]"), HasSubstr("[" + file + "]"), HasSubstr(message)))); - logprintf(level, file.c_str(), line, "%s", message.c_str()); + // The printed log line must contain the sequence number, default player ID (-1), level, function and the message + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[" + std::to_string(-1) + "]"), + HasSubstr("[TRACE]"), + HasSubstr("[" + func + "]"), + HasSubstr(message)))); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message.c_str()); } TEST_F(AampLogManagerTest, logprintf_INFO) { AAMP_LogLevel level = eLOGLEVEL_INFO; std::string file("test.cpp"); + std::string func("testFunc"); int line = 2; std::string message("message"); - // The printed log line must contain the player ID, level, file and the message / - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[" + std::to_string(-1) + "]"), HasSubstr("[INFO]"), HasSubstr("[" + file + "]"), HasSubstr(message)))); - logprintf(level, file.c_str(), line, "%s", message.c_str()); + // The printed log line must contain the sequence number, default player ID (-1), level, function and the message + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[" + std::to_string(-1) + "]"), + HasSubstr("[INFO]"), + HasSubstr("[" + func + "]"), + HasSubstr(message)))); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message.c_str()); } /* @@ -761,10 +796,16 @@ TEST_F(AampLogManagerTest, logprintf_LongFile) { AAMP_LogLevel level = eLOGLEVEL_INFO; std::string file(MAX_DEBUG_LOG_BUFF_SIZE, '*'); + std::string func("testFunc"); int line = 2; std::string message("message"); - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[" + std::to_string(-1) + "]"), HasSubstr("[INFO]")))); - logprintf(level, file.c_str(), line, "%s", message.c_str()); + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[" + std::to_string(-1) + "]"), + HasSubstr("[INFO]"), + HasSubstr("[" + func + "]")))); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message.c_str()); } /* @@ -775,11 +816,16 @@ TEST_F(AampLogManagerTest, logprintf_LongMessage) { AAMP_LogLevel level = eLOGLEVEL_INFO; std::string file("test.cpp"); + std::string func("testFunc"); int line = 2; std::string message(MAX_DEBUG_LOG_BUFF_SIZE, '*'); - EXPECT_CALL(*g_mockSdJournal, - sd_journal_print_mock( LOG_NOTICE, AllOf(HasSubstr("[" + std::to_string(-1) + "]"), HasSubstr("[INFO]"), HasSubstr("[" + file + "]")))); - logprintf(level, file.c_str(), line, "%s", message.c_str()); + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[" + std::to_string(-1) + "]"), + HasSubstr("[INFO]"), + HasSubstr("[" + func + "]")))); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message.c_str()); } /* @@ -790,13 +836,20 @@ TEST_F(AampLogManagerTest, logprintf_MaxMessage) { AAMP_LogLevel level = eLOGLEVEL_INFO; std::string file("test.cpp"); + std::string func("testFunc"); int line = 2; std::ostringstream ossthread; ossthread << std::this_thread::get_id(); - std::string header("[AAMP-PLAYER][" + std::to_string(-1) + "][INFO][" + ossthread.str() + "][" + file + "][" + std::to_string(line) + "]"); + std::string header("[AAMP-PLAYER][000][" + std::to_string(-1) + "][INFO][" + ossthread.str() + "][" + func + "][" + std::to_string(line) + "]"); std::string message((MAX_DEBUG_LOG_BUFF_SIZE - header.length() - 1), '*'); - EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, AllOf(HasSubstr("[" + std::to_string(-1) + "]"), HasSubstr("[INFO]"), HasSubstr("[" + file + "]"), HasSubstr(message)))); - logprintf(level, file.c_str(), line, "%s", message.c_str()); + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + ContainsRegex("\\[AAMP-PLAYER\\]\\[[0-9]{3}\\]"), + HasSubstr("[" + std::to_string(-1) + "]"), + HasSubstr("[INFO]"), + HasSubstr("[" + func + "]"), + HasSubstr(message)))); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message.c_str()); } TEST_F(AampLogManagerTest, snprintf_tests) @@ -826,3 +879,62 @@ TEST_F(AampLogManagerTest, snprintf_tests) } } } + +/* + Helper function to format sequence number as 3-digit zero-padded string +*/ +std::string formatSeqNum(int seqNum) +{ + std::string numStr = std::to_string(seqNum); + return (std::string(3 - numStr.length(), '0') + numStr); +} + +/* + Test that sequential log numbers are added to log lines + This test verifies that each log line gets a sequential number and that the numbers are consecutive +*/ +TEST_F(AampLogManagerTest, logprintf_SequentialNumbers) +{ + // Log three messages and verify they have sequential numbers + AAMP_LogLevel level = eLOGLEVEL_WARN; + std::string file("test.cpp"); + std::string func("testFunc"); + int line = 10; + int seqNum = 0; + std::string message1("First message"); + std::string message2("Second message"); + std::string message3("Third message"); + + // The format is: [AAMP-PLAYER][seqNum][playerId][level][threadId][func][line]message + // The sequence number is a 3-digit zero-padded number [000]-[999] + // Verify that all three logs contain the proper 3-digit sequence number format + // One log line is printed by the Setup() function, so start from 1 + // If the Setup() function is modified this might need to be adjusted + seqNum++; + + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + HasSubstr("[" + formatSeqNum(seqNum) + "]"), + HasSubstr("[WARN]"), + HasSubstr(message1) + ))).Times(1); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message1.c_str()); + seqNum++; + + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + HasSubstr("[" + formatSeqNum(seqNum) + "]"), + HasSubstr("[WARN]"), + HasSubstr(message2) + ))).Times(1); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message2.c_str()); + seqNum++; + + EXPECT_CALL(*g_mockSdJournal, sd_journal_print_mock(LOG_NOTICE, + AllOf( + HasSubstr("[" + formatSeqNum(seqNum) + "]"), + HasSubstr("[WARN]"), + HasSubstr(message3) + ))).Times(1); + logprintf(level, file.c_str(), func.c_str(), line, "%s", message3.c_str()); +}