From 28c7881b543e098b96a2f5d43592a3dbab815d44 Mon Sep 17 00:00:00 2001 From: "RoseMary_Benny@comcast.com" Date: Fri, 5 Dec 2025 10:08:09 +0530 Subject: [PATCH 1/3] 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 --- source/test/t2parser/Makefile.am | 2 +- source/test/t2parser/t2parserTest.cpp | 285 ++++++++++++++++++++- source/test/t2parser/t2parserxconfTest.cpp | 91 +++++++ 3 files changed, 374 insertions(+), 4 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..660baa93 100644 --- a/source/test/t2parser/t2parserTest.cpp +++ b/source/test/t2parser/t2parserTest.cpp @@ -63,6 +63,14 @@ 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); + //void time_param_Reporting_Adjustments_valid_set(Profile *profile, cJSON *jprofileReportingInterval, cJSON *jprofileActivationTimeout, cJSON *jprofileTimeReference, cJSON *jprofileReportOnUpdate, cJSON *jprofilefirstReportingInterval, cJSON *jprofilemaxUploadLatency, cJSON* jprofileReportingAdjustments); + 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; @@ -144,7 +152,8 @@ TEST(PROCESSCONFIGURATION_CJSON, TEST_NULL_INVALID_PARAM) data = new char[len + 1]; strcpy(data, sa.c_str()); //Profilename NULL - EXPECT_EQ(T2ERROR_FAILURE, processConfiguration(&data, NULL, "hash1", &profile)); + char h1[] = "hash1"; + EXPECT_EQ(T2ERROR_FAILURE, processConfiguration(&data, "hash1", h1, &profile)); delete[] data; getline(new_file, sa); @@ -154,7 +163,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 +344,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 +787,276 @@ 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); +} +#if 0 +/* time_param_Reporting_Adjustments_valid_set: generateNow true case */ +TEST(T2ParserTimeParam, GenerateNowTrueResetsReportingAdjustments) +{ + Profile p; + memset(&p, 0, sizeof(p)); + p.generateNow = true; + p.reportingInterval = 30; + p.reportOnUpdate = true; + p.firstReportingInterval = 100; + p.maxUploadLatency = 5000; + + // pass NULL for JSON nodes, function should detect generateNow and ignore adjustments + time_param_Reporting_Adjustments_valid_set(&p, NULL, NULL, NULL, NULL, NULL, NULL); + EXPECT_EQ(0, p.reportingInterval); + EXPECT_EQ(false, p.reportOnUpdate); + EXPECT_EQ(0, p.firstReportingInterval); + EXPECT_EQ(0, p.maxUploadLatency); +} + +/* time_param_Reporting_Adjustments_valid_set: set values when generateNow is false */ +TEST(T2ParserTimeParam, ReportingAdjustmentsApplied) +{ + Profile p; + memset(&p, 0, sizeof(p)); + p.generateNow = false; + p.activationTimeoutPeriod = 1000; + p.reportingInterval = 60; + + cJSON* jReportingInterval = cJSON_CreateNumber(120); + cJSON* jActivationTimeout = cJSON_CreateNumber(400); + cJSON* jTimeReference = cJSON_CreateString("2025-01-01T00:00:00Z"); + + cJSON* jReportingAdjustments = cJSON_CreateObject(); + cJSON* jReportOnUpdate = cJSON_CreateTrue(); + cJSON_AddItemToObject(jReportingAdjustments, "ReportOnUpdate", jReportOnUpdate); + cJSON* jFirstReportingInterval = cJSON_CreateNumber(10); + cJSON_AddItemToObject(jReportingAdjustments, "FirstReportingInterval", jFirstReportingInterval); + cJSON* jMaxUploadLatency = cJSON_CreateNumber(2000); + cJSON_AddItemToObject(jReportingAdjustments, "MaxUploadLatency", jMaxUploadLatency); + + // call the function (note: signature expects separate args - pass firstReportingInterval/maxUploadLatency separately) + time_param_Reporting_Adjustments_valid_set(&p, jReportingInterval, jActivationTimeout, jTimeReference, jReportOnUpdate, jFirstReportingInterval, jMaxUploadLatency); + + // reportingInterval should be set from jReportingInterval + EXPECT_EQ(120, p.reportingInterval); + // activationTimeoutPeriod should be set from jActivationTimeout by surrounding callers; here we check timeRef was set + if (p.timeRef) { + EXPECT_STREQ("2025-01-01T00:00:00Z", p.timeRef); + free(p.timeRef); + p.timeRef = NULL; + } + // ReportOnUpdate should be true + EXPECT_EQ(true, p.reportOnUpdate); + // First reporting interval set + EXPECT_EQ(10, p.firstReportingInterval); + // MaxUploadLatency set + EXPECT_EQ(2000, p.maxUploadLatency); + + // cleanup + cJSON_Delete(jReportingAdjustments); + cJSON_Delete(jReportingInterval); + cJSON_Delete(jActivationTimeout); + cJSON_Delete(jTimeReference); +} +#endif +/* 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); + + free(p.jsonEncoding); + 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); + + free(p.t2HTTPDest); + free(p.name); + 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); + + free(p.t2RBUSDest); + free(p.name); + 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 : ""); +} + From 66a15d7e4bfe40c00c83e609937046194b50f186 Mon Sep 17 00:00:00 2001 From: "RoseMary_Benny@comcast.com" Date: Wed, 17 Dec 2025 10:57:58 +0530 Subject: [PATCH 2/3] resolved review comments from github copilot --- source/test/t2parser/t2parserTest.cpp | 125 +++++++++++--------------- 1 file changed, 51 insertions(+), 74 deletions(-) diff --git a/source/test/t2parser/t2parserTest.cpp b/source/test/t2parser/t2parserTest.cpp index 660baa93..fb26d4a2 100644 --- a/source/test/t2parser/t2parserTest.cpp +++ b/source/test/t2parser/t2parserTest.cpp @@ -67,7 +67,6 @@ extern "C" { // tell C++ about the C function defined in t2parser.c T2ERROR verifyTriggerCondition(cJSON *jprofileTriggerCondition); T2ERROR addTriggerCondition(Profile *profile, cJSON *jprofileTriggerCondition); - //void time_param_Reporting_Adjustments_valid_set(Profile *profile, cJSON *jprofileReportingInterval, cJSON *jprofileActivationTimeout, cJSON *jprofileTimeReference, cJSON *jprofileReportOnUpdate, cJSON *jprofilefirstReportingInterval, cJSON *jprofilemaxUploadLatency, cJSON* jprofileReportingAdjustments); 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); } @@ -152,8 +151,7 @@ TEST(PROCESSCONFIGURATION_CJSON, TEST_NULL_INVALID_PARAM) data = new char[len + 1]; strcpy(data, sa.c_str()); //Profilename NULL - char h1[] = "hash1"; - EXPECT_EQ(T2ERROR_FAILURE, processConfiguration(&data, "hash1", h1, &profile)); + EXPECT_EQ(T2ERROR_FAILURE, processConfiguration(&data, NULL, "hash1", &profile)); delete[] data; getline(new_file, sa); @@ -908,72 +906,6 @@ TEST(T2ParserAddTC, AddTriggerConditionSuccess) // (The CI process reclaims process memory after tests.) cJSON_Delete(arr); } -#if 0 -/* time_param_Reporting_Adjustments_valid_set: generateNow true case */ -TEST(T2ParserTimeParam, GenerateNowTrueResetsReportingAdjustments) -{ - Profile p; - memset(&p, 0, sizeof(p)); - p.generateNow = true; - p.reportingInterval = 30; - p.reportOnUpdate = true; - p.firstReportingInterval = 100; - p.maxUploadLatency = 5000; - - // pass NULL for JSON nodes, function should detect generateNow and ignore adjustments - time_param_Reporting_Adjustments_valid_set(&p, NULL, NULL, NULL, NULL, NULL, NULL); - EXPECT_EQ(0, p.reportingInterval); - EXPECT_EQ(false, p.reportOnUpdate); - EXPECT_EQ(0, p.firstReportingInterval); - EXPECT_EQ(0, p.maxUploadLatency); -} - -/* time_param_Reporting_Adjustments_valid_set: set values when generateNow is false */ -TEST(T2ParserTimeParam, ReportingAdjustmentsApplied) -{ - Profile p; - memset(&p, 0, sizeof(p)); - p.generateNow = false; - p.activationTimeoutPeriod = 1000; - p.reportingInterval = 60; - - cJSON* jReportingInterval = cJSON_CreateNumber(120); - cJSON* jActivationTimeout = cJSON_CreateNumber(400); - cJSON* jTimeReference = cJSON_CreateString("2025-01-01T00:00:00Z"); - - cJSON* jReportingAdjustments = cJSON_CreateObject(); - cJSON* jReportOnUpdate = cJSON_CreateTrue(); - cJSON_AddItemToObject(jReportingAdjustments, "ReportOnUpdate", jReportOnUpdate); - cJSON* jFirstReportingInterval = cJSON_CreateNumber(10); - cJSON_AddItemToObject(jReportingAdjustments, "FirstReportingInterval", jFirstReportingInterval); - cJSON* jMaxUploadLatency = cJSON_CreateNumber(2000); - cJSON_AddItemToObject(jReportingAdjustments, "MaxUploadLatency", jMaxUploadLatency); - - // call the function (note: signature expects separate args - pass firstReportingInterval/maxUploadLatency separately) - time_param_Reporting_Adjustments_valid_set(&p, jReportingInterval, jActivationTimeout, jTimeReference, jReportOnUpdate, jFirstReportingInterval, jMaxUploadLatency); - - // reportingInterval should be set from jReportingInterval - EXPECT_EQ(120, p.reportingInterval); - // activationTimeoutPeriod should be set from jActivationTimeout by surrounding callers; here we check timeRef was set - if (p.timeRef) { - EXPECT_STREQ("2025-01-01T00:00:00Z", p.timeRef); - free(p.timeRef); - p.timeRef = NULL; - } - // ReportOnUpdate should be true - EXPECT_EQ(true, p.reportOnUpdate); - // First reporting interval set - EXPECT_EQ(10, p.firstReportingInterval); - // MaxUploadLatency set - EXPECT_EQ(2000, p.maxUploadLatency); - - // cleanup - cJSON_Delete(jReportingAdjustments); - cJSON_Delete(jReportingInterval); - cJSON_Delete(jActivationTimeout); - cJSON_Delete(jTimeReference); -} -#endif /* encodingSet should set jsonEncoding fields based on JSON nodes */ TEST(T2ParserEncodingSet, JSONEncodingMapping) { @@ -990,7 +922,18 @@ TEST(T2ParserEncodingSet, JSONEncodingMapping) EXPECT_EQ(JSONRF_OBJHIERARCHY, p.jsonEncoding->reportFormat); EXPECT_EQ(TIMESTAMP_UNIXEPOCH, p.jsonEncoding->tsFormat); - free(p.jsonEncoding); + 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); @@ -1023,9 +966,26 @@ TEST(T2ParserProtocolSet, HTTPBranchSetsURLAndParams) 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; + } - free(p.t2HTTPDest); - free(p.name); cJSON_Delete(jProtocol); cJSON_Delete(jHTTP); } @@ -1054,9 +1014,26 @@ TEST(T2ParserProtocolSet, RBUSMethodBranchSetsMethodAndParams) 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; + } - free(p.t2RBUSDest); - free(p.name); cJSON_Delete(jProtocol); cJSON_Delete(jRBUS); } From 239dcd2be8416a2014bc5fca22101588c978aa05 Mon Sep 17 00:00:00 2001 From: "RoseMary_Benny@comcast.com" Date: Tue, 30 Dec 2025 10:23:41 +0530 Subject: [PATCH 3/3] updated the t2parserTest.cpp --- source/test/t2parser/t2parserTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/test/t2parser/t2parserTest.cpp b/source/test/t2parser/t2parserTest.cpp index fb26d4a2..1ddce3dc 100644 --- a/source/test/t2parser/t2parserTest.cpp +++ b/source/test/t2parser/t2parserTest.cpp @@ -79,7 +79,7 @@ TEST(PROCESSXCONFCONFIGURATION, TEST_NULL_INVALID) ProfileXConf *profile = 0; fstream new_file; char* data = NULL; - new_file.open("xconfInputfile.txt", ios::in); + new_file.open("source/test/t2parser/xconfInputfile.txt", ios::in); if (new_file.is_open()) { string sa; @@ -143,7 +143,7 @@ TEST(PROCESSCONFIGURATION_CJSON, TEST_NULL_INVALID_PARAM) fstream new_file; string sa; int len = 0; - new_file.open("rpInputfile.txt", ios::in); + new_file.open("source/test/t2parser/rpInputfile.txt", ios::in); char* data = NULL; if (new_file.is_open()) { getline(new_file, sa);