From e93f2d9ec36c1c19ea5f8a02092cb3b1412d2a0c Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Fri, 5 Dec 2025 10:09:48 +0000 Subject: [PATCH 01/17] Skipping the reporting of grep marker if the value is empty Signed-off-by: Yogeswaran K --- source/dcautil/dca.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/dcautil/dca.c b/source/dcautil/dca.c index d77fbdf6..1685c736 100644 --- a/source/dcautil/dca.c +++ b/source/dcautil/dca.c @@ -606,6 +606,14 @@ static int getAbsolutePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* m const char *end = memchr(start, '\n', chars_left); size_t length = end ? (size_t)(end - start) : chars_left; + // Skip if the value is empty (i.e. length=0) + if (length == 0) + { + T2Debug("Skipping marker %s as the value is empty\n", marker->markerName); + marker->u.markerValue = NULL; + return 0; + } + char *result = (char*)malloc(length + 1); if (!result) { @@ -746,6 +754,13 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* const char *end = memchr(start, '\n', chars_left); size_t length = end ? (size_t)(end - start) : chars_left; + //Skip if the value is empty (length= 0) + if (length == 0) + { + T2Debug("Skipping empty value for marker %s\n", marker->markerName); + goto advance_to_next_pattern; + } + // Create result string for this occurrence char *result = (char*)malloc(length + 1); if (result) @@ -767,6 +782,7 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* } } +advance_to_next_pattern: size_t advance = (size_t)(found - cur) + patlen; cur = found + patlen; if (bytes_left < advance) From 78251d82e0f2ec070db4dcfec73bf21efec41277 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Mon, 8 Dec 2025 18:21:30 +0000 Subject: [PATCH 02/17] RDKEMW-11275: value 0 is reflected in the telemetry report for Accum Grep markers Signed-off-by: Yogeswaran K --- source/dcautil/dca.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/dcautil/dca.c b/source/dcautil/dca.c index 1685c736..624a1063 100644 --- a/source/dcautil/dca.c +++ b/source/dcautil/dca.c @@ -767,6 +767,15 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* { memcpy(result, start, length); result[length] = '\0'; + + // Skip if the value is "0" + if(strcmp(result, "0") == 0 ) + { + T2Debug("Skipping marker %s as the value is 0 for accumulate\n", marker->markerName); + free(result); + goto advance_to_next_pattern; + } + T2Debug("%s %d : result = %s\n", __FUNCTION__, __LINE__, result); Vector_PushBack(accumulatedValues, result); From 0f1164ab8f15598b1fd5c08f045d76ab655a80b0 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Mon, 8 Dec 2025 18:28:55 +0000 Subject: [PATCH 03/17] RDKEMW-11275: value 0 is reflected in the telemetry report for Accum Grep markers Signed-off-by: Yogeswaran K --- source/dcautil/dca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/dcautil/dca.c b/source/dcautil/dca.c index 624a1063..4a4a7784 100644 --- a/source/dcautil/dca.c +++ b/source/dcautil/dca.c @@ -767,7 +767,7 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* { memcpy(result, start, length); result[length] = '\0'; - + // Skip if the value is "0" if(strcmp(result, "0") == 0 ) { @@ -775,7 +775,7 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* free(result); goto advance_to_next_pattern; } - + T2Debug("%s %d : result = %s\n", __FUNCTION__, __LINE__, result); Vector_PushBack(accumulatedValues, result); From 65b396462eed9e1d1b6d5223aa2ab5a0ce7d7926 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Tue, 9 Dec 2025 08:48:35 +0000 Subject: [PATCH 04/17] RDKEMW-11275: L2 testcase updation for 0 value and empty value Signed-off-by: Yogeswaran K --- test/functional-tests/tests/report_profiles.py | 2 +- test/functional-tests/tests/test_multiprofile_msgpacket.py | 4 ++++ test/run_l2.sh | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/test/functional-tests/tests/report_profiles.py b/test/functional-tests/tests/report_profiles.py index 3a44db93..21187db7 100644 --- a/test/functional-tests/tests/report_profiles.py +++ b/test/functional-tests/tests/report_profiles.py @@ -894,7 +894,7 @@ data_temp_with_reporting_interval = '{ "profiles": [ { "name": "temp_AC732", "hash": "temp_732", "value": { "Name": "RDKB_Profile_3", "Description": "RDKB_Profile", "Version": "0.1", "Protocol": "RBUS_METHOD", "EncodingType": "JSON", "ActivationTimeout": 3600, "ReportingInterval": 20, "GenerateNow": false, "RootName": "temp_AC732", "Parameter": [ { "type": "event", "eventName": "TEST_EVENT_MARKER_1", "component": "sysint", "use": "count" }, { "type": "event", "eventName": "TEST_EVENT_MARKER_2", "component": "sysint", "use": "accumulate", "reportTimestamp":"Unix-Epoch" }, { "type": "grep", "marker": "SYS_INFO_CrashPortalUpload_success", "search": "Success loading", "logFile": "core_log.txt", "use": "count", "reportEmpty":true } ], "ReportingAdjustments": [ { "ReportOnUpdate": false, "FirstReportingInterval": 15, "MaxUploadLatency": 20000 } ], "RBUS_METHOD":{"Method":"Device.X_RDK_Xmidt.SendData","Parameters":[{"name":"msg_type","value":"event"},{"name":"source","value":"telemetry2"},{"name":"dest","value":"event:/profile-report/LTE-report"},{"name":"content_type","value":"application/json"},{"name":"qos","value":"75"}]}, "JSONEncoding": { "ReportFormat": "NameValuePair", "ReportTimestamp": "None" } } } ] }' -data_with_grep_accumulate_timestamp = '{ "profiles": [ { "name": "TR_ACCUM", "hash": "Hash234", "value":{ "Description": "Accumulate_grep", "Version": "0.1", "Protocol": "HTTP", "EncodingType": "JSON", "ReportingInterval": 10, "TimeReference": "0001-01-01T00:00:00Z", "Parameter": [ { "type": "grep", "marker": "SYS_INFO_Accum_Time", "search": "identifier:", "logFile": "accum.log", "use": "accumulate", "reportTimestamp": "Unix-Epoch" }, {"type":"grep","marker":"SYS_INFO_Accum_No_Time","search":"CollectAndReport while","logFile":"telemetry2_0.txt.0","use":"accumulate","reportTimestamp":"Unix-Epoch"}, {"type":"grep","marker":"SYS_INFO_Accum_Alone","search":"reporting interval","logFile":"telemetry2_0.txt.0","use":"accumulate"},{ "type": "grep", "marker": "Load_Average", "search": "telemetry2_0", "logFile": "top_log.txt" }, { "type": "grep", "marker": "cpu_telemetry2_0", "search": "telemetry2_0", "logFile": "top_log.txt" } ], "HTTP": { "URL": "https://mockxconf:50051/dataLakeMock/", "Compression": "None", "Method": "POST", "RequestURIParameter": [ { "Name": "profileName", "Reference": "Profile.Name" }, { "Name": "reportVersion", "Reference": "Profile.Version" } ] }, "JSONEncoding": { "ReportFormat": "NameValuePair", "ReportTimestamp": "None" } }} ] }' +data_with_grep_accumulate_timestamp = '{ "profiles": [ { "name": "TR_ACCUM", "hash": "Hash234", "value":{ "Description": "Accumulate_grep", "Version": "0.1", "Protocol": "HTTP", "EncodingType": "JSON", "ReportingInterval": 10, "TimeReference": "0001-01-01T00:00:00Z", "Parameter": [ { "type": "grep", "marker": "SYS_INFO_Accum_Time", "search": "identifier:", "logFile": "accum.log", "use": "accumulate", "reportTimestamp": "Unix-Epoch" }, {"type":"grep","marker":"SYS_INFO_Accum_No_Time","search":"CollectAndReport while","logFile":"telemetry2_0.txt.0","use":"accumulate","reportTimestamp":"Unix-Epoch"}, {"type":"grep","marker":"SYS_INFO_Accum_Alone","search":"reporting interval","logFile":"telemetry2_0.txt.0","use":"accumulate"},{ "type": "grep", "marker": "Load_Average", "search": "telemetry2_0", "logFile": "top_log.txt" }, { "type": "grep", "marker": "cpu_telemetry2_0", "search": "telemetry2_0", "logFile": "top_log.txt" },{ "type": "grep", "marker": "SYS_INFO_0_value", "search": "zero value=", "logFile": "accum.log","use":"absolute" },{ "type": "grep", "marker": "SYS_INFO_0_accum", "search": "zero value=", "logFile": "accum.log","use":"accumulate" } ], "HTTP": { "URL": "https://mockxconf:50051/dataLakeMock/", "Compression": "None", "Method": "POST", "RequestURIParameter": [ { "Name": "profileName", "Reference": "Profile.Name" }, { "Name": "reportVersion", "Reference": "Profile.Version" } ] }, "JSONEncoding": { "ReportFormat": "NameValuePair", "ReportTimestamp": "None" } }} ] }' data_with_Generate_Now = '''{ "profiles": [ diff --git a/test/functional-tests/tests/test_multiprofile_msgpacket.py b/test/functional-tests/tests/test_multiprofile_msgpacket.py index 14c753de..29240a9b 100644 --- a/test/functional-tests/tests/test_multiprofile_msgpacket.py +++ b/test/functional-tests/tests/test_multiprofile_msgpacket.py @@ -523,7 +523,11 @@ def test_grep_accumulate(): "filler updated line\n" "251007-09:29:41.335 INFO identifier:thevalue25\n" "filler line\n" + "zero value=0\n" + "zero value=0\n" ) file.close() sleep(15) + assert "SYS_INFO_0_value" not in grep_T2logs("cJSON Report ") # 0 value should not be reported in absolute use + assert "SYS_INFO_0_accum" not in grep_T2logs("cJSON Report ") # 0 value should not be reported in accumulate use assert "SYS_INFO_Accum_Time\":[\"thevalue23" in grep_T2logs("cJSON Report ") #Marker is reporting in the next cycle even if the maximum accumulation is reached in the previous report diff --git a/test/run_l2.sh b/test/run_l2.sh index 7cfe5165..8aa24468 100755 --- a/test/run_l2.sh +++ b/test/run_l2.sh @@ -34,7 +34,7 @@ fi gcc test/functional-tests/tests/app.c -o test/functional-tests/tests/t2_app -ltelemetry_msgsender -lt2utils # removing --exitfirst flag as it is causing the test to exit after first failure -pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/runs_as_daemon.json test/functional-tests/tests/test_runs_as_daemon.py -pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/bootup_sequence.json test/functional-tests/tests/test_bootup_sequence.py -pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/xconf_communications.json test/functional-tests/tests/test_xconf_communications.py --exitfirst +#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/runs_as_daemon.json test/functional-tests/tests/test_runs_as_daemon.py +#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/bootup_sequence.json test/functional-tests/tests/test_bootup_sequence.py +#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/xconf_communications.json test/functional-tests/tests/test_xconf_communications.py --exitfirst pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/msg_packet.json test/functional-tests/tests/test_multiprofile_msgpacket.py --exitfirst From 4a3f86622edfbb7404d9c84e8a75c035119fdac4 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Tue, 9 Dec 2025 15:28:42 +0000 Subject: [PATCH 05/17] RDKEMW-11275: L1 testcase updation for 0 value and empty value Signed-off-by: Yogeswaran K --- source/test/dcautils/dcautilTest.cpp | 103 +++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 7 deletions(-) diff --git a/source/test/dcautils/dcautilTest.cpp b/source/test/dcautils/dcautilTest.cpp index 5ff7a570..a4a5264a 100644 --- a/source/test/dcautils/dcautilTest.cpp +++ b/source/test/dcautils/dcautilTest.cpp @@ -463,6 +463,7 @@ TEST(GETLOADAVG, VALID_MARKER) TopMarker* topMarker = (TopMarker*) malloc(sizeof(TopMarker)); memset(topMarker, 0, sizeof(TopMarker)); EXPECT_EQ(1, getLoadAvg(topMarker)); + free(topMarker); } TEST(CREATEGREPSEEKPROFILE, SEEKMAPCREATE_CHECK) @@ -1173,8 +1174,8 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_1) Vector* vecMarkerList = NULL; Vector_Create(&vecMarkerList); - TopMarker* marker = (TopMarker*) malloc(sizeof(TopMarker)); - memset(marker, 0, sizeof(TopMarker)); + GrepMarker* marker = (GrepMarker*) malloc(sizeof(GrepMarker)); + memset(marker, 0, sizeof(GrepMarker)); marker->markerName = strdup("SYS_INFO_TEST"); marker->searchString = strdup("Test Marker"); marker->trimParam = true; @@ -1232,7 +1233,6 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_1) strncpy(mapped_mem, test_str, length - 1); return (void*)mapped_mem; }); - EXPECT_EQ(0, getDCAResultsInVector(gsProfile, vecMarkerList, true, "/opt/logs")); hash_map_destroy(gsProfile->logFileSeekMap, free); @@ -1255,8 +1255,8 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_2) Vector* vecMarkerList = NULL; Vector_Create(&vecMarkerList); - TopMarker* marker = (TopMarker*) malloc(sizeof(TopMarker)); - memset(marker, 0, sizeof(TopMarker)); + GrepMarker* marker = (GrepMarker*) malloc(sizeof(GrepMarker)); + memset(marker, 0, sizeof(GrepMarker)); marker->markerName = strdup("SYS_INFO_TEST"); marker->searchString = strdup("temp:"); marker->trimParam = true; @@ -1338,12 +1338,13 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_3) Vector* vecMarkerList = NULL; Vector_Create(&vecMarkerList); - TopMarker* marker = (TopMarker*) malloc(sizeof(TopMarker)); - memset(marker, 0, sizeof(TopMarker)); + GrepMarker* marker = (GrepMarker*) malloc(sizeof(GrepMarker)); + memset(marker, 0, sizeof(GrepMarker)); marker->markerName = strdup("SYS_INFO_TEST"); marker->searchString = strdup("Test Marker"); marker->trimParam = true; marker->u.markerValue = NULL; + marker->u.accumulatedValues = NULL; marker->regexParam = strdup("[0-9]+"); marker->logFile = strdup("Consolelog.txt.0"); marker->skipFreq = 0; @@ -1430,6 +1431,94 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_3) Vector_Destroy(vecMarkerList, freeGMarker); } + +TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) +{ + + GrepSeekProfile *gsProfile = (GrepSeekProfile *)malloc(sizeof(GrepSeekProfile)); + gsProfile->logFileSeekMap = hash_map_create(); + gsProfile->execCounter = 1; + long *tempnum; + double val = 1234; + tempnum = (long *)malloc(sizeof(long)); + *tempnum = (long)val; + hash_map_put(gsProfile->logFileSeekMap, strdup("t2_log.txt"), (void*)tempnum, free); + + Vector* vecMarkerList = NULL; + Vector_Create(&vecMarkerList); + GrepMarker* marker = (GrepMarker*) malloc(sizeof(GrepMarker)); + memset(marker, 0, sizeof(GrepMarker)); + marker->markerName = strdup("SYS_INFO_TEST"); + marker->searchString = strdup("Test Marker"); + marker->trimParam = true; + marker->u.markerValue = NULL; + marker->u.count = 0; + marker->mType = MTYPE_ACCUMULATE; + marker->reportTimestampParam = REPORTTIMESTAMP_UNIXEPOCH; + Vector_Create(&marker->u.accumulatedValues); + if(marker->reportTimestampParam == REPORTTIMESTAMP_UNIXEPOCH) + { + Vector_Create(&marker->accumulatedTimestamp); + } + marker->regexParam = strdup("[0-9]+"); + marker->logFile = strdup("Consolelog.txt.0"); + marker->skipFreq = 0; + marker->paramType = strdup("grep"); + marker->reportEmptyParam = true; + Vector_PushBack(vecMarkerList, (void*) marker); + + + //freeFileDescriptor + EXPECT_CALL(*g_fileIOMock, munmap(_, _)) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*g_fileIOMock, close(_)) + .WillRepeatedly(Return(0)); + + //getLogFileDescriptor + EXPECT_CALL(*g_fileIOMock, open(_,_)) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*g_fileIOMock, fstat(_, _)) + .WillOnce([](int fd, struct stat* statbuf) { + statbuf->st_size = 1235; // Set file size + return 0; // Success + }) + .WillOnce([](int fd, struct stat* statbuf) { + statbuf->st_size = 1000; // Set file size + return 0; // Success + }); + + //getDeltainmmapsearch + EXPECT_CALL(*g_fileIOMock, mkstemp(_)) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*g_systemMock, unlink(_)) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*g_fileIOMock,sendfile(_,_,_,_)) + .WillRepeatedly(Return(0)); + /* + EXPECT_CALL(*g_fileIOMock, mmap(_,_,_,_,_,_)) + .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { + const char* test_str = "This is a Test Marker with value 1234 in the log file.\nAnother line without the marker.\n"; + char* mapped_mem = (char*)malloc(length); + memset(mapped_mem, 0, length); + strncpy(mapped_mem, test_str, length - 1); + return (void*)mapped_mem; + }) + .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { + const char* test_str = "This is with value Test:1250 in the log file.\nAnother line without the marker.\nThe line with Test Markeris found\n"; + char* mapped_mem = (char*)malloc(length); + memset(mapped_mem, 0, length); + strncpy(mapped_mem, test_str, length - 1); + return (void*)mapped_mem; + }); +*/ + + EXPECT_EQ(0, getDCAResultsInVector(gsProfile, vecMarkerList, true, "/opt/logs")); + hash_map_destroy(gsProfile->logFileSeekMap, free); + gsProfile->logFileSeekMap = NULL; + free(gsProfile); + Vector_Destroy(vecMarkerList, freeGMarker); +} + TEST_F(dcaTestFixture, T2InitProperties) { EXPECT_CALL(*g_fileIOMock, fopen(_,_)) From 285ac814df1eef37157f707a1c243e7ae3c8d58f Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Tue, 9 Dec 2025 18:05:14 +0000 Subject: [PATCH 06/17] RDKEMW-11275: Empty values are reflected in the telemetry report for GREP markers Signed-off-by: Yogeswaran K --- source/test/dcautils/dcautilTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/test/dcautils/dcautilTest.cpp b/source/test/dcautils/dcautilTest.cpp index a4a5264a..45315f49 100644 --- a/source/test/dcautils/dcautilTest.cpp +++ b/source/test/dcautils/dcautilTest.cpp @@ -1493,8 +1493,9 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) EXPECT_CALL(*g_systemMock, unlink(_)) .WillRepeatedly(Return(0)); EXPECT_CALL(*g_fileIOMock,sendfile(_,_,_,_)) - .WillRepeatedly(Return(0)); - /* + .Times(2) + .WillOnce(Return(1000)); + //.WillOnce(Return(1235)) EXPECT_CALL(*g_fileIOMock, mmap(_,_,_,_,_,_)) .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { const char* test_str = "This is a Test Marker with value 1234 in the log file.\nAnother line without the marker.\n"; @@ -1510,7 +1511,6 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) strncpy(mapped_mem, test_str, length - 1); return (void*)mapped_mem; }); -*/ EXPECT_EQ(0, getDCAResultsInVector(gsProfile, vecMarkerList, true, "/opt/logs")); hash_map_destroy(gsProfile->logFileSeekMap, free); From 3734345ff49304a159dad8cc3803ac06b54e8618 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Tue, 9 Dec 2025 18:08:19 +0000 Subject: [PATCH 07/17] RDKEMW-11275: Empty values are reflected in the telemetry report for GREP markers Signed-off-by: Yogeswaran K --- test/run_l2.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/run_l2.sh b/test/run_l2.sh index 8aa24468..7cfe5165 100755 --- a/test/run_l2.sh +++ b/test/run_l2.sh @@ -34,7 +34,7 @@ fi gcc test/functional-tests/tests/app.c -o test/functional-tests/tests/t2_app -ltelemetry_msgsender -lt2utils # removing --exitfirst flag as it is causing the test to exit after first failure -#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/runs_as_daemon.json test/functional-tests/tests/test_runs_as_daemon.py -#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/bootup_sequence.json test/functional-tests/tests/test_bootup_sequence.py -#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/xconf_communications.json test/functional-tests/tests/test_xconf_communications.py --exitfirst +pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/runs_as_daemon.json test/functional-tests/tests/test_runs_as_daemon.py +pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/bootup_sequence.json test/functional-tests/tests/test_bootup_sequence.py +pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/xconf_communications.json test/functional-tests/tests/test_xconf_communications.py --exitfirst pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/msg_packet.json test/functional-tests/tests/test_multiprofile_msgpacket.py --exitfirst From db39da530553199a65fa40cf6ff22e082c136174 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Wed, 10 Dec 2025 12:44:20 +0000 Subject: [PATCH 08/17] RDKEMW-11275: L1 testcase updation Signed-off-by: Yogeswaran K --- source/test/dcautils/dcautilTest.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/source/test/dcautils/dcautilTest.cpp b/source/test/dcautils/dcautilTest.cpp index 45315f49..ee00eafa 100644 --- a/source/test/dcautils/dcautilTest.cpp +++ b/source/test/dcautils/dcautilTest.cpp @@ -1467,17 +1467,22 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) marker->reportEmptyParam = true; Vector_PushBack(vecMarkerList, (void*) marker); - //freeFileDescriptor EXPECT_CALL(*g_fileIOMock, munmap(_, _)) .WillRepeatedly(Return(0)); EXPECT_CALL(*g_fileIOMock, close(_)) .WillRepeatedly(Return(0)); - //getLogFileDescriptor + //getLogFileDescriptor EXPECT_CALL(*g_fileIOMock, open(_,_)) .WillRepeatedly(Return(0)); + EXPECT_CALL(*g_fileIOMock, fstat(_, _)) + .Times(4) + .WillOnce([](int fd, struct stat* statbuf) { + statbuf->st_size = 1235; // Set file size + return 0; // Success + }) .WillOnce([](int fd, struct stat* statbuf) { statbuf->st_size = 1235; // Set file size return 0; // Success @@ -1485,8 +1490,11 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) .WillOnce([](int fd, struct stat* statbuf) { statbuf->st_size = 1000; // Set file size return 0; // Success + }) + .WillOnce([](int fd, struct stat* statbuf) { + statbuf->st_size = 1000; // Set file size + return 0; // Success }); - //getDeltainmmapsearch EXPECT_CALL(*g_fileIOMock, mkstemp(_)) .WillRepeatedly(Return(0)); @@ -1494,18 +1502,18 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) .WillRepeatedly(Return(0)); EXPECT_CALL(*g_fileIOMock,sendfile(_,_,_,_)) .Times(2) + .WillOnce(Return(1235)) .WillOnce(Return(1000)); - //.WillOnce(Return(1235)) EXPECT_CALL(*g_fileIOMock, mmap(_,_,_,_,_,_)) .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - const char* test_str = "This is a Test Marker with value 1234 in the log file.\nAnother line without the marker.\n"; + const char* test_str = "This is a Test Marker with value 1234 in the log file.\nAnother line without the marker.\nLine with Test Marker"; char* mapped_mem = (char*)malloc(length); memset(mapped_mem, 0, length); strncpy(mapped_mem, test_str, length - 1); return (void*)mapped_mem; }) .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - const char* test_str = "This is with value Test:1250 in the log file.\nAnother line without the marker.\nThe line with Test Markeris found\n"; + const char* test_str = "This is with value Test:1250 in the log file.\nAnother line without the marker.\nThe line with Test Markeris found\nLine with 0 vale for Test Marker0"; char* mapped_mem = (char*)malloc(length); memset(mapped_mem, 0, length); strncpy(mapped_mem, test_str, length - 1); @@ -1513,6 +1521,7 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) }); EXPECT_EQ(0, getDCAResultsInVector(gsProfile, vecMarkerList, true, "/opt/logs")); + hash_map_destroy(gsProfile->logFileSeekMap, free); gsProfile->logFileSeekMap = NULL; free(gsProfile); From 309897d957d789b51148338b7c4ee7c1023285cb Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Wed, 10 Dec 2025 13:05:18 +0000 Subject: [PATCH 09/17] RDKEMW-11275: L1 testcase updation Signed-off-by: Yogeswaran K --- source/test/dcautils/dcautilTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/test/dcautils/dcautilTest.cpp b/source/test/dcautils/dcautilTest.cpp index ee00eafa..ccba15fe 100644 --- a/source/test/dcautils/dcautilTest.cpp +++ b/source/test/dcautils/dcautilTest.cpp @@ -1506,14 +1506,14 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) .WillOnce(Return(1000)); EXPECT_CALL(*g_fileIOMock, mmap(_,_,_,_,_,_)) .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - const char* test_str = "This is a Test Marker with value 1234 in the log file.\nAnother line without the marker.\nLine with Test Marker"; + const char* test_str = "2025-10-26T14:40:55.001Z This is a Test Marker with value 1234 in the log file.\n2025-10-26T14:40:55.001Z Another line without the marker.\n2025-10-26T14:40:55.001Z Line with Test Marker"; char* mapped_mem = (char*)malloc(length); memset(mapped_mem, 0, length); strncpy(mapped_mem, test_str, length - 1); return (void*)mapped_mem; }) .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - const char* test_str = "This is with value Test:1250 in the log file.\nAnother line without the marker.\nThe line with Test Markeris found\nLine with 0 vale for Test Marker0"; + const char* test_str = "2025-10-26T14:40:55.001Z This is with value Test:1250 in the log file.\n2025-10-26T14:40:55.001Z Another line without the marker.\n2025-10-26T14:40:55.001Z The line with Test Markeris found\n2025-10-26T14:40:55.001Z Line with 0 vale for Test Marker0"; char* mapped_mem = (char*)malloc(length); memset(mapped_mem, 0, length); strncpy(mapped_mem, test_str, length - 1); From 57437966fd657a9207dc8878fa5262acb8488657 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Wed, 10 Dec 2025 13:56:18 +0000 Subject: [PATCH 10/17] RDKEMW-11275: L1 testcase updation Signed-off-by: Yogeswaran K --- test/functional-tests/tests/report_profiles.py | 4 ++-- test/functional-tests/tests/test_multiprofile_msgpacket.py | 7 ++++++- test/functional-tests/tests/test_xconf_communications.py | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/test/functional-tests/tests/report_profiles.py b/test/functional-tests/tests/report_profiles.py index 21187db7..cd5b6509 100644 --- a/test/functional-tests/tests/report_profiles.py +++ b/test/functional-tests/tests/report_profiles.py @@ -1211,14 +1211,14 @@ "marker": "SYS_INFO_WhoAmI", "search": "WhoAmI feature is", "logFile": "telemetry2_0.txt.0", - "use": "absolute" + "use": "accumulate" }, { "type": "grep", "marker": "SYS_INFO_WhoAmI_Status", "search": "WhoAmI feature", "logFile": "telemetry2_0.txt.0", - "use": "absolute" + "use": "accumulate" }, { "type": "grep", diff --git a/test/functional-tests/tests/test_multiprofile_msgpacket.py b/test/functional-tests/tests/test_multiprofile_msgpacket.py index 29240a9b..71d637bf 100644 --- a/test/functional-tests/tests/test_multiprofile_msgpacket.py +++ b/test/functional-tests/tests/test_multiprofile_msgpacket.py @@ -60,6 +60,7 @@ def test_without_namefield(): #Enabling debug log lines to get the HASH_ERROR_MSG in the logs sleep(2) +''' rbus_set_data(T2_REPORT_PROFILE_PARAM_MSG_PCK, "string", tomsgpack(data_without_namefield)) sleep(10) @@ -374,6 +375,7 @@ def test_for_triggerCondition_negative_case(): assert "Null threshold verifyMsgPckTriggerCondition ++out" in grep_T2logs("Null threshold verifyMsgPckTriggerCondition ++out") assert "Unexpected reference verifyMsgPckTriggerCondition ++out" in grep_T2logs("Unexpected reference verifyMsgPckTriggerCondition ++out") +''' @pytest.mark.run(order=12) def test_for_subscribe_tr181(): clear_T2logs() @@ -383,7 +385,7 @@ def test_for_subscribe_tr181(): clear_persistant_files() os.makedirs('/opt/logs/PreviousLogs', exist_ok=True) file = open('/opt/logs/PreviousLogs/session0.txt', 'w') - file.write("This log file is for previous logs\n") + file.write("This log file is for previous logs with value\n") file.write("Second line in the previous logs\n") file.close() run_telemetry() @@ -416,6 +418,7 @@ def test_for_subscribe_tr181(): assert "T2_Container_0.0.3" in grep_T2logs("temp_Split_Marker") # 312 - Include data from data source Tr181 parameters as Accumulate assert "Report Sent Successfully over HTTP" in grep_T2logs ("Report Sent Successfully over HTTP") # 319 - Report sending over HTTP protocol +''' @pytest.mark.run(order=11) def test_for_triggerCondition_working_case(): clear_T2logs() @@ -531,3 +534,5 @@ def test_grep_accumulate(): assert "SYS_INFO_0_value" not in grep_T2logs("cJSON Report ") # 0 value should not be reported in absolute use assert "SYS_INFO_0_accum" not in grep_T2logs("cJSON Report ") # 0 value should not be reported in accumulate use assert "SYS_INFO_Accum_Time\":[\"thevalue23" in grep_T2logs("cJSON Report ") #Marker is reporting in the next cycle even if the maximum accumulation is reached in the previous report + +''' diff --git a/test/functional-tests/tests/test_xconf_communications.py b/test/functional-tests/tests/test_xconf_communications.py index 99a10522..84925aac 100644 --- a/test/functional-tests/tests/test_xconf_communications.py +++ b/test/functional-tests/tests/test_xconf_communications.py @@ -27,6 +27,7 @@ from helper_functions import * +''' @pytest.mark.run(order=1) def test_precondition(): adminSupport_cache() @@ -196,6 +197,7 @@ def test_xconf_datamodel(): sleep(5) assert "Test_datamodel_1" in grep_T2logs("cJSON Report") +''' pytest.mark.run(order=15) def test_xconf_split_markers(): kill_telemetry(9) From 7cfd1f72becc581dc37b26ef3fbf12b85c79f61f Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Wed, 10 Dec 2025 14:18:54 +0000 Subject: [PATCH 11/17] RDKEMW-11275: L1 testcase updation Signed-off-by: Yogeswaran K --- test/functional-tests/tests/report_profiles.py | 4 ++-- test/functional-tests/tests/test_multiprofile_msgpacket.py | 7 +------ test/functional-tests/tests/test_xconf_communications.py | 2 -- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/test/functional-tests/tests/report_profiles.py b/test/functional-tests/tests/report_profiles.py index cd5b6509..5e8836ee 100644 --- a/test/functional-tests/tests/report_profiles.py +++ b/test/functional-tests/tests/report_profiles.py @@ -1303,14 +1303,14 @@ "marker": "SYS_INFO_WhoAmI", "search": "WhoAmI feature is", "logFile": "telemetry2_0.txt.0", - "use": "absolute" + "use": "accumulate" }, { "type": "grep", "marker": "SYS_INFO_WhoAmI_Status", "search": "WhoAmI feature", "logFile": "telemetry2_0.txt.0", - "use": "absolute" + "use": "accumulate" }, { "type": "grep", diff --git a/test/functional-tests/tests/test_multiprofile_msgpacket.py b/test/functional-tests/tests/test_multiprofile_msgpacket.py index 71d637bf..7ff35191 100644 --- a/test/functional-tests/tests/test_multiprofile_msgpacket.py +++ b/test/functional-tests/tests/test_multiprofile_msgpacket.py @@ -60,7 +60,6 @@ def test_without_namefield(): #Enabling debug log lines to get the HASH_ERROR_MSG in the logs sleep(2) -''' rbus_set_data(T2_REPORT_PROFILE_PARAM_MSG_PCK, "string", tomsgpack(data_without_namefield)) sleep(10) @@ -250,7 +249,7 @@ def test_for_invalid_activation_timeout(): rbus_set_data("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Telemetry.ConfigURL", "string", "https://mockxconf:50050/loguploader2/getT2DCMSettings") os.makedirs('/opt/logs/PreviousLogs', exist_ok=True) file = open('/opt/logs/session0.txt', 'w') - file.write("This log file is for previous logs\n") + file.write("This log file is for previous logs with value\n") file.write("Second line in the previous logs\n") file.close() clear_T2logs() @@ -375,7 +374,6 @@ def test_for_triggerCondition_negative_case(): assert "Null threshold verifyMsgPckTriggerCondition ++out" in grep_T2logs("Null threshold verifyMsgPckTriggerCondition ++out") assert "Unexpected reference verifyMsgPckTriggerCondition ++out" in grep_T2logs("Unexpected reference verifyMsgPckTriggerCondition ++out") -''' @pytest.mark.run(order=12) def test_for_subscribe_tr181(): clear_T2logs() @@ -418,7 +416,6 @@ def test_for_subscribe_tr181(): assert "T2_Container_0.0.3" in grep_T2logs("temp_Split_Marker") # 312 - Include data from data source Tr181 parameters as Accumulate assert "Report Sent Successfully over HTTP" in grep_T2logs ("Report Sent Successfully over HTTP") # 319 - Report sending over HTTP protocol -''' @pytest.mark.run(order=11) def test_for_triggerCondition_working_case(): clear_T2logs() @@ -534,5 +531,3 @@ def test_grep_accumulate(): assert "SYS_INFO_0_value" not in grep_T2logs("cJSON Report ") # 0 value should not be reported in absolute use assert "SYS_INFO_0_accum" not in grep_T2logs("cJSON Report ") # 0 value should not be reported in accumulate use assert "SYS_INFO_Accum_Time\":[\"thevalue23" in grep_T2logs("cJSON Report ") #Marker is reporting in the next cycle even if the maximum accumulation is reached in the previous report - -''' diff --git a/test/functional-tests/tests/test_xconf_communications.py b/test/functional-tests/tests/test_xconf_communications.py index 84925aac..99a10522 100644 --- a/test/functional-tests/tests/test_xconf_communications.py +++ b/test/functional-tests/tests/test_xconf_communications.py @@ -27,7 +27,6 @@ from helper_functions import * -''' @pytest.mark.run(order=1) def test_precondition(): adminSupport_cache() @@ -197,7 +196,6 @@ def test_xconf_datamodel(): sleep(5) assert "Test_datamodel_1" in grep_T2logs("cJSON Report") -''' pytest.mark.run(order=15) def test_xconf_split_markers(): kill_telemetry(9) From 0e9713f13f6111f3600fa9470db37524e25d4e50 Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Wed, 10 Dec 2025 15:34:01 +0000 Subject: [PATCH 12/17] RDKEMW-11275: L1 testcase updation Signed-off-by: Yogeswaran K --- source/test/dcautils/dcautilTest.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/test/dcautils/dcautilTest.cpp b/source/test/dcautils/dcautilTest.cpp index ccba15fe..398f612e 100644 --- a/source/test/dcautils/dcautilTest.cpp +++ b/source/test/dcautils/dcautilTest.cpp @@ -1478,7 +1478,7 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) .WillRepeatedly(Return(0)); EXPECT_CALL(*g_fileIOMock, fstat(_, _)) - .Times(4) + .Times(testing::AtMost(4)) .WillOnce([](int fd, struct stat* statbuf) { statbuf->st_size = 1235; // Set file size return 0; // Success @@ -1501,10 +1501,11 @@ TEST_F(dcaTestFixture, getDCAResultsInVector_Accum) EXPECT_CALL(*g_systemMock, unlink(_)) .WillRepeatedly(Return(0)); EXPECT_CALL(*g_fileIOMock,sendfile(_,_,_,_)) - .Times(2) + .Times(testing::AtMost(2)) .WillOnce(Return(1235)) .WillOnce(Return(1000)); EXPECT_CALL(*g_fileIOMock, mmap(_,_,_,_,_,_)) + .Times(testing::AtMost(2)) .WillOnce([](void *addr, size_t length, int prot, int flags, int fd, off_t offset) { const char* test_str = "2025-10-26T14:40:55.001Z This is a Test Marker with value 1234 in the log file.\n2025-10-26T14:40:55.001Z Another line without the marker.\n2025-10-26T14:40:55.001Z Line with Test Marker"; char* mapped_mem = (char*)malloc(length); From 51c8ea2f72cde25e940dc0f1ab20da1c98098f1d Mon Sep 17 00:00:00 2001 From: shibu-kv Date: Wed, 10 Dec 2025 08:22:30 -0800 Subject: [PATCH 13/17] Changelog updates for release 1.7.2 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cda61ec8..218a438c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,25 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.7.2](https://github.com/rdkcentral/telemetry/compare/1.7.1...1.7.2) + +- RDKEMW-11275: L1 testcase updation for 0 value and empty value [`4a3f866`](https://github.com/rdkcentral/telemetry/commit/4a3f86622edfbb7404d9c84e8a75c035119fdac4) +- RDKEMW-11275: L1 testcase updation [`db39da5`](https://github.com/rdkcentral/telemetry/commit/db39da530553199a65fa40cf6ff22e082c136174) +- Skipping the reporting of grep marker if the value is empty [`e93f2d9`](https://github.com/rdkcentral/telemetry/commit/e93f2d9ec36c1c19ea5f8a02092cb3b1412d2a0c) + #### [1.7.1](https://github.com/rdkcentral/telemetry/compare/1.7.0...1.7.1) +> 26 November 2025 + - RDK-59503: L2 & L1 testcases for Accumulated Grep Markers [`#202`](https://github.com/rdkcentral/telemetry/pull/202) +- RDKB-62477:Clients related split markers with value as 0 after Upgrad… [`#211`](https://github.com/rdkcentral/telemetry/pull/211) - RDKEMW-6333: Crash fix for accumulated timestamp [`#207`](https://github.com/rdkcentral/telemetry/pull/207) - RDKB-62326: Avoid deadlocks due to logger apis invocation from forked calls [`#204`](https://github.com/rdkcentral/telemetry/pull/204) - RDKEMW-9528: Align the sequence of asynchronous rbus call [`#205`](https://github.com/rdkcentral/telemetry/pull/205) +- RDKB-62346: Devices not reporting datamodel markers with polling frequency > 0 [`#201`](https://github.com/rdkcentral/telemetry/pull/201) - RDK-59500: Fix build failure due to time_t type mismatch [`#200`](https://github.com/rdkcentral/telemetry/pull/200) +- Changelog updates for 1.7.1 release [`a937c74`](https://github.com/rdkcentral/telemetry/commit/a937c7466ee56d88bf551b5094013a6da9ec3880) +- As per legacy logic, absolute/split markers with 0 string value should not be reported [`ba0c1ab`](https://github.com/rdkcentral/telemetry/commit/ba0c1abf1eb11bfa9c288fc4daa358f6a5b1b5f5) #### [1.7.0](https://github.com/rdkcentral/telemetry/compare/1.6.8...1.7.0) From 893b4dbc94bc5f6fcc1e8776edd6b6fb90ffc28e Mon Sep 17 00:00:00 2001 From: Yogeswaran K Date: Thu, 11 Dec 2025 02:25:45 +0000 Subject: [PATCH 14/17] RDKEMW-11275: Fix type conversion error in empty string fix Signed-off-by: Yogeswaran K --- source/dcautil/dca.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/dcautil/dca.c b/source/dcautil/dca.c index 4a4a7784..dab0075c 100644 --- a/source/dcautil/dca.c +++ b/source/dcautil/dca.c @@ -689,6 +689,7 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* { // Check MAX_ACCUMULATE limit before checking for a match int arraySize = Vector_Size(accumulatedValues); + size_t advance; if (arraySize >= MAX_ACCUMULATE) { @@ -792,7 +793,7 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* } advance_to_next_pattern: - size_t advance = (size_t)(found - cur) + patlen; + advance = (size_t)(found - cur) + patlen; cur = found + patlen; if (bytes_left < advance) { From ec2291e68bdc2d7f298919cbe7e36a0c25f3dbe0 Mon Sep 17 00:00:00 2001 From: PriyaDharshini_Kathiravan Date: Thu, 11 Dec 2025 14:13:55 +0000 Subject: [PATCH 15/17] RDKEMW-11275: Fix type conversion error in empty string fix --- source/dcautil/dca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dcautil/dca.c b/source/dcautil/dca.c index dab0075c..abbc8c78 100644 --- a/source/dcautil/dca.c +++ b/source/dcautil/dca.c @@ -689,7 +689,7 @@ static int getAccumulatePatternMatch(FileDescriptor* fileDescriptor, GrepMarker* { // Check MAX_ACCUMULATE limit before checking for a match int arraySize = Vector_Size(accumulatedValues); - size_t advance; + size_t advance; if (arraySize >= MAX_ACCUMULATE) { From 8a5cbfbec59dfe97c64ffb0547e309c65e4abd84 Mon Sep 17 00:00:00 2001 From: shibu-kv Date: Thu, 11 Dec 2025 08:01:23 -0800 Subject: [PATCH 16/17] Changelog update for release 1.7.3 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 218a438c..7399bcfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,15 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.7.3](https://github.com/rdkcentral/telemetry/compare/1.7.2...1.7.3) + +- RDKEMW-11275: Fix type conversion error in empty string fix [`893b4db`](https://github.com/rdkcentral/telemetry/commit/893b4dbc94bc5f6fcc1e8776edd6b6fb90ffc28e) +- RDKEMW-11275: Fix type conversion error in empty string fix [`ec2291e`](https://github.com/rdkcentral/telemetry/commit/ec2291e68bdc2d7f298919cbe7e36a0c25f3dbe0) + #### [1.7.2](https://github.com/rdkcentral/telemetry/compare/1.7.1...1.7.2) +> 10 December 2025 + - RDKEMW-11275: L1 testcase updation for 0 value and empty value [`4a3f866`](https://github.com/rdkcentral/telemetry/commit/4a3f86622edfbb7404d9c84e8a75c035119fdac4) - RDKEMW-11275: L1 testcase updation [`db39da5`](https://github.com/rdkcentral/telemetry/commit/db39da530553199a65fa40cf6ff22e082c136174) - Skipping the reporting of grep marker if the value is empty [`e93f2d9`](https://github.com/rdkcentral/telemetry/commit/e93f2d9ec36c1c19ea5f8a02092cb3b1412d2a0c) From a272470b036602fb1bf0349f70a70d2eadb078a1 Mon Sep 17 00:00:00 2001 From: rosemarybennyy Date: Thu, 18 Dec 2025 20:00:03 +0530 Subject: [PATCH 17/17] RDK-60072: Adding L1 unit test cases to improve code coverage (#219) * RDK-60072: Adding L1 unit test cases to improve code coverage Reason for change: Adding L1 unit test cases to improve code coverage Test Procedure: Tested and verified Risks: Medium Priority: P1 Signed-off-by: Rose Mary Benny * resolved review comments from github copilot --------- Co-authored-by: Shibu Kakkoth Vayalambron --- source/test/t2parser/Makefile.am | 2 +- source/test/t2parser/t2parserTest.cpp | 260 ++++++++++++++++++++- source/test/t2parser/t2parserxconfTest.cpp | 91 ++++++++ 3 files changed, 350 insertions(+), 3 deletions(-) create mode 100644 source/test/t2parser/t2parserxconfTest.cpp diff --git a/source/test/t2parser/Makefile.am b/source/test/t2parser/Makefile.am index 45142676..1ebd1cf5 100644 --- a/source/test/t2parser/Makefile.am +++ b/source/test/t2parser/Makefile.am @@ -31,7 +31,7 @@ bin_PROGRAMS = t2parser_gtest.bin t2parser_gtest_bin_CPPFLAGS = -I$(PKG_CONFIG_SYSROOT_DIR)$(includedir)/gtest -I$(PKG_CONFIG_SYSROOT_DIR)$(includedir)/glib-2.0 -I$(PKG_CONFIG_SYSROOT_DIR)/usr/local/lib -I${top_srcdir}/source/include -I${top_srcdir}/source/xconf-client -I${top_srcdir}/source/dcautil -I${top_srcdir}/source/t2parser -I${top_srcdir}/source/bulkdata -I${top_srcdir}/source/utils -I${top_srcdir}/source/ccspinterface -I${top_srcdir}/source -I${top_srcdir}/include -I${top_srcdir}/source/reportgen -I$(PKG_CONFIG_SYSROOT_DIR)/usr/lib -I$(PKG_CONFIG_SYSROOT_DIR)/usr/include -I$(PKG_CONFIG_SYSROOT_DIR)/usr/include/cjson -I$(PKG_CONFIG_SYSROOT_DIR)/usr/include/gmock -I$(PKG_CONFIG_SYSROOT_DIR)/usr/src/googletest/googlemock/include -I$(PKG_CONFIG_SYSROOT_DIR)/usr/lib/glib-2.0/include -I$(PKG_CONFIG_SYSROOT_DIR)/usr/include/glib-2.0 -I${RDK_PROJECT_ROOT_PATH}/$(GLIB_CFLAGS) -I${PKG_CONFIG_SYSROOT_DIR}$(includedir)/glib-2.0 -I${PKG_CONFIG_SYSROOT_DIR}$(libdir)/glib-2.0/include -t2parser_gtest_bin_SOURCES = gtest_main.cpp t2parserMock.cpp ../mocks/rdklogMock.cpp ../mocks/rbusMock.cpp t2parserTest.cpp ../../utils/vector.c ../../utils/t2common.c ../../utils/t2log_wrapper.c ../../t2parser/t2parserxconf.c ../../t2parser/t2parser.c ../../dcautil/legacyutils.c ../../utils/t2collection.c +t2parser_gtest_bin_SOURCES = gtest_main.cpp t2parserMock.cpp ../mocks/rdklogMock.cpp ../mocks/rbusMock.cpp t2parserTest.cpp t2parserxconfTest.cpp ../../utils/vector.c ../../utils/t2common.c ../../utils/t2log_wrapper.c ../../t2parser/t2parserxconf.c ../../t2parser/t2parser.c ../../dcautil/legacyutils.c ../../utils/t2collection.c t2parser_gtest_bin_LDFLAGS = -lgtest -lgcov -L/src/googletest/googlemock/lib -L/usr/src/googletest/googlemock/lib/.libs -lgmock -lcjson -lcurl -lmsgpackc -L/usr/include/glib-2.0 -lglib-2.0 diff --git a/source/test/t2parser/t2parserTest.cpp b/source/test/t2parser/t2parserTest.cpp index aab8c27f..fb26d4a2 100644 --- a/source/test/t2parser/t2parserTest.cpp +++ b/source/test/t2parser/t2parserTest.cpp @@ -63,6 +63,13 @@ sigset_t blocking_signal; #include "test/mocks/rdklogMock.h" #include "test/mocks/rbusMock.h" +extern "C" { + // tell C++ about the C function defined in t2parser.c + T2ERROR verifyTriggerCondition(cJSON *jprofileTriggerCondition); + T2ERROR addTriggerCondition(Profile *profile, cJSON *jprofileTriggerCondition); + T2ERROR encodingSet(Profile* profile, cJSON *jprofileEncodingType, cJSON *jprofileJSONReportFormat, cJSON *jprofileJSONReportTimestamp); + T2ERROR protocolSet (Profile *profile, cJSON *jprofileProtocol, cJSON *jprofileHTTPURL, cJSON *jprofileHTTPRequestURIParameter, int ThisprofileHTTPRequestURIParameter_count, cJSON *jprofileRBUSMethodName, cJSON *jprofileRBUSMethodParamArr, int rbusMethodParamArrCount); +} T2parserMock *m_t2parserMock = NULL; rdklogMock *m_rdklogMock = NULL; rbusMock *g_rbusMock = NULL; @@ -154,7 +161,6 @@ TEST(PROCESSCONFIGURATION_CJSON, TEST_NULL_INVALID_PARAM) //Protocol NULL EXPECT_EQ(T2ERROR_FAILURE, processConfiguration(&data, "RDKB_Profile2", "hash2", &profile)); delete[] data; - getline(new_file, sa); len = sa.length(); data = new char[len + 1]; @@ -336,7 +342,6 @@ TEST(PROCESSCONFIGURATION_CJSON, TEST_NULL_INVALID_PARAM) strcpy(data, sa.c_str()); EXPECT_EQ(T2ERROR_SUCCESS, processConfiguration(&data, "RDKB_Profile25", "hash25", &profile)); delete[] data; - } new_file.close(); } @@ -780,4 +785,255 @@ TEST(PROCESSCONFIGURATION_MSGPACK, WORKING_CASE) } +/* Helper to create a TriggerCondition JSON object */ +static cJSON* create_tc_obj(const char* type, const char* op, const char* ref, int threshold, int report) +{ + cJSON* obj = cJSON_CreateObject(); + if (type) cJSON_AddStringToObject(obj, "type", type); + if (op) cJSON_AddStringToObject(obj, "operator", op); + if (ref) cJSON_AddStringToObject(obj, "reference", ref); + if (threshold >= 0) cJSON_AddNumberToObject(obj, "threshold", threshold); + if (report >= 0) cJSON_AddBoolToObject(obj, "report", report); + return obj; +} +/* verifyTriggerCondition failure: missing type */ +TEST(T2ParserVerifyTC, MissingTypeShouldFail) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = cJSON_CreateObject(); + // intentionally no "type" + cJSON_AddStringToObject(tc, "operator", "any"); + cJSON_AddStringToObject(tc, "reference", "Device.Param"); + cJSON_AddItemToArray(arr, tc); + + EXPECT_EQ(T2ERROR_FAILURE, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} +/* verifyTriggerCondition failure: wrong type string */ +TEST(T2ParserVerifyTC, WrongTypeShouldFail) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = create_tc_obj("notDataModel", "any", "Device.Param", -1, -1); + cJSON_AddItemToArray(arr, tc); + EXPECT_EQ(T2ERROR_FAILURE, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} + +/* verifyTriggerCondition failure: missing operator */ +TEST(T2ParserVerifyTC, MissingOperatorShouldFail) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = create_tc_obj("dataModel", NULL, "Device.Param", -1, -1); + cJSON_AddItemToArray(arr, tc); + EXPECT_EQ(T2ERROR_FAILURE, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} + +/* verifyTriggerCondition failure: invalid operator */ +TEST(T2ParserVerifyTC, InvalidOperatorShouldFail) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = create_tc_obj("dataModel", "badop", "Device.Param", -1, -1); + cJSON_AddItemToArray(arr, tc); + EXPECT_EQ(T2ERROR_FAILURE, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} + +/* verifyTriggerCondition failure: missing threshold for lt operator */ +TEST(T2ParserVerifyTC, ThresholdMissingForLtShouldFail) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = create_tc_obj("dataModel", "lt", "Device.Param", -1, -1); // no threshold + cJSON_AddItemToArray(arr, tc); + EXPECT_EQ(T2ERROR_FAILURE, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} + +/* verifyTriggerCondition failure: missing reference */ +TEST(T2ParserVerifyTC, MissingReferenceShouldFail) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = cJSON_CreateObject(); + cJSON_AddStringToObject(tc, "type", "dataModel"); + cJSON_AddStringToObject(tc, "operator", "any"); + // no reference + cJSON_AddItemToArray(arr, tc); + EXPECT_EQ(T2ERROR_FAILURE, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} + +/* verifyTriggerCondition failure: empty reference */ +TEST(T2ParserVerifyTC, EmptyReferenceShouldFail) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = create_tc_obj("dataModel", "any", "", -1, -1); + cJSON_AddItemToArray(arr, tc); + EXPECT_EQ(T2ERROR_FAILURE, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} + +/* verifyTriggerCondition success: valid tc */ +TEST(T2ParserVerifyTC, ValidShouldSucceed) +{ + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = create_tc_obj("dataModel", "any", "Device.Param", -1, -1); + cJSON_AddItemToArray(arr, tc); + EXPECT_EQ(T2ERROR_SUCCESS, verifyTriggerCondition(arr)); + cJSON_Delete(arr); +} +/* addTriggerCondition should accept a valid TC array and return success */ +TEST(T2ParserAddTC, AddTriggerConditionSuccess) +{ + Profile p; + memset(&p, 0, sizeof(p)); + // Initialize the vector pointer (function will Vector_Create) + p.triggerConditionList = NULL; + + cJSON* arr = cJSON_CreateArray(); + cJSON* tc = create_tc_obj("dataModel", "eq", "Device.Param", 5, 1); + cJSON_AddItemToArray(arr, tc); + + EXPECT_EQ(T2ERROR_SUCCESS, addTriggerCondition(&p, arr)); + // function should have created the triggerConditionList (non-NULL) + EXPECT_NE((void*)NULL, (void*)p.triggerConditionList); + + // clean up: free internal structures created by addTriggerCondition + // We don't have a public destructor here; best-effort free for the test's allocations: + // iterate vector if available (Vector API may provide size/get functions in the project), + // but to stay robust, simply free profile memory fields that addTriggerCondition could set. + // For safety, reset pointer to avoid double-free during test teardown. + // (The CI process reclaims process memory after tests.) + cJSON_Delete(arr); +} +/* encodingSet should set jsonEncoding fields based on JSON nodes */ +TEST(T2ParserEncodingSet, JSONEncodingMapping) +{ + Profile p; + memset(&p, 0, sizeof(p)); + p.jsonEncoding = (JSONEncoding*)malloc(sizeof(JSONEncoding)); + memset(p.jsonEncoding, 0, sizeof(JSONEncoding)); + + cJSON* jEncodingType = cJSON_CreateString("JSON"); + cJSON* jJSONReportFormat = cJSON_CreateString("ObjectHierarchy"); + cJSON* jJSONReportTimestamp = cJSON_CreateString("Unix-Epoch"); + + EXPECT_EQ(T2ERROR_SUCCESS, encodingSet(&p, jEncodingType, jJSONReportFormat, jJSONReportTimestamp)); + EXPECT_EQ(JSONRF_OBJHIERARCHY, p.jsonEncoding->reportFormat); + EXPECT_EQ(TIMESTAMP_UNIXEPOCH, p.jsonEncoding->tsFormat); + + if (p.jsonEncoding) + { + free(p.jsonEncoding); + p.jsonEncoding = NULL; + } + + if (p.name) + { + free(p.name); + p.name = NULL; + } + + cJSON_Delete(jEncodingType); + cJSON_Delete(jJSONReportFormat); + cJSON_Delete(jJSONReportTimestamp); +} +/* protocolSet tests: HTTP branch */ +TEST(T2ParserProtocolSet, HTTPBranchSetsURLAndParams) +{ + Profile p; + memset(&p, 0, sizeof(p)); + p.t2HTTPDest = (T2HTTP*)malloc(sizeof(T2HTTP)); + memset(p.t2HTTPDest, 0, sizeof(T2HTTP)); + p.name = strdup("TestProfile"); + + cJSON* jProtocol = cJSON_CreateString("HTTP"); + // create HTTP nested object + cJSON* jHTTP = cJSON_CreateObject(); + cJSON_AddStringToObject(jHTTP, "URL", "http://upload.test"); + cJSON_AddStringToObject(jHTTP, "Compression", "None"); + cJSON_AddStringToObject(jHTTP, "Method", "POST"); + + // RequestURIParameter array with one valid entry + cJSON* arr = cJSON_CreateArray(); + cJSON* entry = cJSON_CreateObject(); + cJSON_AddStringToObject(entry, "Reference", "someRef"); + cJSON_AddStringToObject(entry, "Name", "someName"); + cJSON_AddItemToArray(arr, entry); + cJSON_AddItemToObject(jHTTP, "RequestURIParameter", arr); + + // Call protocolSet (note: jprofileHTTPRequestURIParameter_count must be set properly by caller) + EXPECT_EQ(T2ERROR_SUCCESS, protocolSet(&p, jProtocol, cJSON_GetObjectItem(jHTTP, "URL"), cJSON_GetObjectItem(jHTTP, "RequestURIParameter"), 1, NULL, NULL, 0)); + + EXPECT_STREQ("http://upload.test", p.t2HTTPDest->URL); + // Cleanup to avoid memory leaks + if (p.t2HTTPDest) + { + if (p.t2HTTPDest->URL) + { + free(p.t2HTTPDest->URL); + p.t2HTTPDest->URL = NULL; + } + // If protocolSet allocated other heap members inside T2HTTP, free them here as needed. + + free(p.t2HTTPDest); + p.t2HTTPDest = NULL; + } + + if (p.name) + { + free(p.name); + p.name = NULL; + } + + cJSON_Delete(jProtocol); + cJSON_Delete(jHTTP); +} + +/* protocolSet tests: RBUS_METHOD branch */ +TEST(T2ParserProtocolSet, RBUSMethodBranchSetsMethodAndParams) +{ + Profile p; + memset(&p, 0, sizeof(p)); + p.t2RBUSDest = (T2RBUS*)malloc(sizeof(T2RBUS)); + memset(p.t2RBUSDest, 0, sizeof(T2RBUS)); + p.name = strdup("RbusProfile"); + + cJSON* jProtocol = cJSON_CreateString("RBUS_METHOD"); + cJSON* jRBUS = cJSON_CreateObject(); + cJSON_AddStringToObject(jRBUS, "Method", "TestMethod"); + + cJSON* params = cJSON_CreateArray(); + cJSON* param = cJSON_CreateObject(); + cJSON_AddStringToObject(param, "name", "param1"); + cJSON_AddStringToObject(param, "value", "val1"); + cJSON_AddItemToArray(params, param); + cJSON_AddItemToObject(jRBUS, "Parameters", params); + + // protocolSet expects jprofileRBUSMethodName and jprofileRBUSMethodParamArr separately; pass appropriate items + EXPECT_EQ(T2ERROR_SUCCESS, protocolSet(&p, jProtocol, NULL, NULL, 0, cJSON_GetObjectItem(jRBUS, "Method"), cJSON_GetObjectItem(jRBUS, "Parameters"), 1)); + + EXPECT_STREQ("TestMethod", p.t2RBUSDest->rbusMethodName); + // Cleanup to avoid memory leaks + if (p.t2RBUSDest) + { + // free any strings allocated by protocolSet if present + if (p.t2RBUSDest->rbusMethodName) + { + free(p.t2RBUSDest->rbusMethodName); + p.t2RBUSDest->rbusMethodName = NULL; + } + // If protocolSet allocated other heap members inside T2RBUS, free them here as needed. + free(p.t2RBUSDest); + p.t2RBUSDest = NULL; + } + + if (p.name) + { + free(p.name); + p.name = NULL; + } + + cJSON_Delete(jProtocol); + cJSON_Delete(jRBUS); +} diff --git a/source/test/t2parser/t2parserxconfTest.cpp b/source/test/t2parser/t2parserxconfTest.cpp new file mode 100644 index 00000000..9f6b2864 --- /dev/null +++ b/source/test/t2parser/t2parserxconfTest.cpp @@ -0,0 +1,91 @@ +#include +#include + +extern "C" { +#include "t2parserxconf.h" +#include "profilexconf.h" +#include "telemetry2_0.h" +} + +/* + * When required fields are missing, processConfigurationXConf should fail. + */ +TEST(T2ParserXConf, MissingRequiredFields) +{ + ProfileXConf *profile = NULL; + const char *json_missing = "{\"urn:settings:TelemetryProfile\": { \"telemetryProfile:name\": \"TestProfile\", \"telemetryProfile\": [] } }"; + // Missing uploadRepository:URL and schedule and no telemetryProfile entries -> failure + EXPECT_EQ(T2ERROR_FAILURE, processConfigurationXConf((char*)json_missing, &profile)); + EXPECT_EQ((ProfileXConf*)NULL, profile); +} + +/* + * When schedule doesn't contain a '/' pattern, default schedule is used (15 minutes -> 900 sec). + */ +TEST(T2ParserXConf, DefaultScheduleUsed) +{ + ProfileXConf *profile = NULL; + const char *json_default_schedule = + "{" + " \"urn:settings:TelemetryProfile\": {" + " \"telemetryProfile:name\": \"DefaultSched\"," + " \"uploadRepository:URL\": \"http://example.com/upload\"," + " \"schedule\": \"11 4 * * *\"," + " \"telemetryProfile\": [ {" + " \"header\": \"param1\"," + " \"content\": \"alias1\"," + " \"type\": \"/var/log/some.log\"," + " \"pollingFrequency\": \"0\"" + " } ]" + " }" + "}"; + EXPECT_EQ(T2ERROR_SUCCESS, processConfigurationXConf((char*)json_default_schedule, &profile)); + ASSERT_NE(profile, nullptr); + // default should be 15 minutes -> 900 seconds + EXPECT_EQ(900, profile->reportingInterval); + ASSERT_NE(profile->t2HTTPDest, nullptr); + EXPECT_STREQ("http://example.com/upload", profile->t2HTTPDest->URL ? profile->t2HTTPDest->URL : ""); + // minimal cleanup (full deep-free is not attempted here) + // tests rely on process teardown to reclaim memory in CI runs +} + +/* + * When schedule contains a slash pattern like "0/5 * * * *", getScheduleInSeconds should + * extract the number after the slash and use it (5 minutes -> 300 seconds). + * This test also includes a top_log.txt entry to exercise topMarker handling. + */ +TEST(T2ParserXConf, SlashScheduleAndTopLogHandling) +{ + ProfileXConf *profile = NULL; + const char *json_slash_schedule = + "{" + " \"urn:settings:TelemetryProfile\": {" + " \"telemetryProfile:name\": \"SlashSched\"," + " \"uploadRepository:URL\": \"http://example.com/upload2\"," + " \"schedule\": \"0/5 * * * *\"," + " \"telemetryProfile\": [" + " {" + " \"header\": \"tm_top\"," + " \"content\": \"search-term\"," + " \"type\": \"top_log.txt\"," + " \"pollingFrequency\": \"0\"" + " }," + " {" + " \"header\": \"param_tr181\"," + " \"content\": \"Device.DeviceInfo.Manufacturer\"," + " \"type\": \"\"," + " \"pollingFrequency\": \"0\"" + " }" + " ]" + " }" + "}"; + EXPECT_EQ(T2ERROR_SUCCESS, processConfigurationXConf((char*)json_slash_schedule, &profile)); + ASSERT_NE(profile, nullptr); + // schedule "0/5 * * * *" should parse to 5 minutes => 300 sec + EXPECT_EQ(300, profile->reportingInterval); + ASSERT_NE(profile->t2HTTPDest, nullptr); + EXPECT_STREQ("http://example.com/upload2", profile->t2HTTPDest->URL ? profile->t2HTTPDest->URL : ""); + // Ensure the profile name got set + EXPECT_STREQ("SlashSched", profile->name ? profile->name : ""); +} +