From a2e6f9706f9582185407d93137f4fd7eba7ea53b Mon Sep 17 00:00:00 2001 From: mtirum011 Date: Tue, 30 Jun 2026 10:09:41 +0000 Subject: [PATCH] RDKEMW-19229 : Improve L1 Coverage for tr69hostif and Fix Errors --- .../httpserver/include/XrdkCentralComRFCVar.h | 1 + src/hostif/httpserver/src/gtest/Makefile.am | 2 +- .../httpserver/src/gtest/gtest_httpserver.cpp | 404 ++++++++++++++++++ src/hostif/parodusClient/gtest/dm_test.cpp | 108 +++++ .../profiles/DeviceInfo/gtest/gtest_main.cpp | 29 ++ src/hostif/src/gtest/gtest_src.cpp | 62 ++- 6 files changed, 604 insertions(+), 2 deletions(-) diff --git a/src/hostif/httpserver/include/XrdkCentralComRFCVar.h b/src/hostif/httpserver/include/XrdkCentralComRFCVar.h index b0636db83..116570a68 100644 --- a/src/hostif/httpserver/include/XrdkCentralComRFCVar.h +++ b/src/hostif/httpserver/include/XrdkCentralComRFCVar.h @@ -61,6 +61,7 @@ class XRFCVarStore FRIEND_TEST(httpserverTest, getValue_InitNotDone_ReturnsEmptyEvenWhenKeyExists); FRIEND_TEST(httpserverTest, reloadCache_WithQuotedFilename_LoadsValues); FRIEND_TEST(httpserverTest, handleRFCRequest_GET); + FRIEND_TEST(httpserverTest, handleRFCRequest_GET_UnknownKey_ReturnsValueIsNull); #endif }; diff --git a/src/hostif/httpserver/src/gtest/Makefile.am b/src/hostif/httpserver/src/gtest/Makefile.am index 54c1abfc8..295893f5a 100644 --- a/src/hostif/httpserver/src/gtest/Makefile.am +++ b/src/hostif/httpserver/src/gtest/Makefile.am @@ -24,7 +24,7 @@ bin_PROGRAMS = httpserver_gtest COMMON_CPPFLAGS = -std=c++11 -DGTEST_ENABLE -DUSE_DEV_PROPERTIES_CONF -DUSE_REMOTE_DEBUGGER -I/usr/include -I/usr/include/cjson -I$(TOP_DIR)/src/hostif/include -I$(TOP_DIR)/src/hostif/profiles/DeviceInfo -I$(TOP_DIR)/src/unittest/stubs -I$(TOP_DIR)/src/unittest/stubs/ds -I$(TOP_DIR)/src/unittest/stubs/rbus/include -I$(TOP_DIR)/src/hostif/handlers/include -I$(TOP_DIR)/src/hostif/parodusClient/pal -I$(TOP_DIR)/src/hostif/parodusClient/waldb -I$(TOP_DIR)/src/hostif/httpserver/include -I$(TOP_DIR)/src/hostif/handlers/src -I/usr/include/rbus -I/usr/local/include/rbus -Isrc/unittest/stubs/rbus/include/ -I$(TOP_DIR)/src/hostif/profiles/Time -I$(TOP_DIR)/src/hostif/profiles/Device -I$(TOP_DIR)/src/hostif/profiles/IP -I$(TOP_DIR)/src/hostif/profiles/STBService -I/usr/rdk-halif-device_settings/include/ -I/usr/rdkvhal-devicesettings-raspberrypi4/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I$(TOP_DIR)/src/hostif/profiles/Ethernet -I/usr/remote_debugger/src/ -I/usr/local/include/libparodus/ -I/usr/local/include/wrp-c/ -I$(TOP_DIR)/src/hostif/parodusClient/startParodus/ -I/usr/include/libsoup-3.0 # Define the libraries to link against -COMMON_LDADD = -lgtest -lgtest_main -lgmock_main -lgmock -lgcov $(GLIB_LIBS) -ltinyxml2 -lcjson -lcurl -lglib-2.0 -llibparodus -lwrp-c -lnanomsg -lmsgpackc -ltrower-base64 -lcimplog -lgio-2.0 -lsoup-3.0 +COMMON_LDADD = -lgtest -lgtest_main -lgmock_main -lgmock -lgcov $(GLIB_LIBS) -ltinyxml2 -lcjson -lcurl -lglib-2.0 -lgobject-2.0 -llibparodus -lwrp-c -lnanomsg -lmsgpackc -ltrower-base64 -lcimplog -lgio-2.0 -lsoup-3.0 # Define the compiler flags COMMON_CXXFLAGS = -frtti $(GLIB_CFLAGS) $(SOUP_LIBS) -fprofile-arcs -ftest-coverage diff --git a/src/hostif/httpserver/src/gtest/gtest_httpserver.cpp b/src/hostif/httpserver/src/gtest/gtest_httpserver.cpp index a9d539d22..afa47eb9e 100644 --- a/src/hostif/httpserver/src/gtest/gtest_httpserver.cpp +++ b/src/hostif/httpserver/src/gtest/gtest_httpserver.cpp @@ -67,6 +67,75 @@ GHashTable* paramMgrhash = NULL; T_ARGLIST argList = {{'\0'}, 0}; static SoupServer *http_server = NULL; +/*static SoupServerMessage* createServerMessage(const char* method, const char* uri, const char* body) +{ + GError* parseError = nullptr; + GUri* parsedUri = g_uri_parse(uri, G_URI_FLAGS_NONE, &parseError); + if (!parsedUri) + { + if (parseError) + { + g_error_free(parseError); + } + return nullptr; + } + + SoupServerMessage* msg = static_cast( + g_object_new(SOUP_TYPE_SERVER_MESSAGE, + "method", method, + "uri", parsedUri, + NULL)); + g_uri_unref(parsedUri); + if (!msg) + { + return nullptr; + } + + if (body != nullptr) + { + SoupMessageBody* reqBody = soup_server_message_get_request_body(msg); + if (reqBody) + { + soup_message_body_append(reqBody, SOUP_MEMORY_COPY, body, strlen(body)); + soup_message_body_complete(reqBody); + } + } + + return msg; +} */ + + +static SoupServerMessage* createServerMessage(const char* method, const char* uri, const char* body) +{ + (void)method; + (void)uri; + SoupServerMessage* msg = static_cast(g_object_new(SOUP_TYPE_SERVER_MESSAGE, NULL)); + if (!msg) + { + return nullptr; + } + + if (body != nullptr) + { + SoupMessageBody* reqBody = soup_server_message_get_request_body(msg); + if (reqBody) + { + soup_message_body_append(reqBody, SOUP_MEMORY_COPY, body, strlen(body)); + soup_message_body_complete(reqBody); + } + } + + return msg; +} + +static void addCallerIdHeader(SoupServerMessage* msg, const char* callerId) +{ + SoupMessageHeaders* reqHeaders = soup_server_message_get_request_headers(msg); + if (reqHeaders && callerId != nullptr) + { + soup_message_headers_append(reqHeaders, "CallerID", callerId); + } +} #ifdef GTEST_ENABLE extern DATA_TYPE (*getWdmpDataTypeFunc())(char * ); @@ -97,6 +166,109 @@ TEST(httpserverTest,initRFCVarFileName){ } } +TEST(httpserverTest, HTTPServerStartThread_WithoutDataModel_ReturnsNull) { + // This test intentionally runs before any loadDataModel() invocation. + argList.httpServerPort = 0; + std::remove("/tmp/.tr69hostif_http_server_ready"); + + void *thread_result = HTTPServerStartThread(nullptr); + EXPECT_EQ(thread_result, nullptr); + + std::ifstream ready_file("/tmp/.tr69hostif_http_server_ready"); + EXPECT_FALSE(ready_file.good()); +} + +TEST(httpserverTest, HTTPRequestHandler_EmptyRequestBody) { + SoupServer* server = soup_server_new("server-header", "HTTPServer", NULL); + ASSERT_NE(server, nullptr); + + SoupServerMessage* msg = createServerMessage("GET", "http://127.0.0.1/", nullptr); + ASSERT_NE(msg, nullptr); + + HTTPRequestHandlerFunc()(server, msg, "/", nullptr, nullptr); + + g_object_unref(msg); + g_object_unref(server); +} + +TEST(httpserverTest, HTTPRequestHandler_InvalidJsonPayload) { + SoupServer* server = soup_server_new("server-header", "HTTPServer", NULL); + ASSERT_NE(server, nullptr); + + SoupServerMessage* msg = createServerMessage("GET", "http://127.0.0.1/", "not-json-payload"); + ASSERT_NE(msg, nullptr); + + HTTPRequestHandlerFunc()(server, msg, "/", nullptr, nullptr); + + g_object_unref(msg); + g_object_unref(server); +} + +TEST(httpserverTest, HTTPRequestHandler_PostWithoutCallerId) { + SoupServer* server = soup_server_new("server-header", "HTTPServer", NULL); + ASSERT_NE(server, nullptr); + + SoupServerMessage* msg = createServerMessage("POST", "http://127.0.0.1/", "{\"paramNames\":[\"Device.DeviceInfo.ModelName\"]}"); + ASSERT_NE(msg, nullptr); + addCallerIdHeader(msg, ""); + + HTTPRequestHandlerFunc()(server, msg, "/", nullptr, nullptr); + + g_object_unref(msg); + g_object_unref(server); +} + +TEST(httpserverTest, HTTPRequestHandler_UnsupportedMethod) { + SoupServer* server = soup_server_new("server-header", "HTTPServer", NULL); + ASSERT_NE(server, nullptr); + + SoupServerMessage* msg = createServerMessage("PUT", "http://127.0.0.1/", "{\"paramNames\":[\"Device.DeviceInfo.ModelName\"]}"); + ASSERT_NE(msg, nullptr); + + HTTPRequestHandlerFunc()(server, msg, "/", nullptr, nullptr); + + g_object_unref(msg); + g_object_unref(server); +} + +TEST(httpserverTest, HTTPRequestHandler_GetWithCallerId_CoversResponsePath) { + EXPECT_EQ(loadDataModel(), DB_SUCCESS); + + SoupServer* server = soup_server_new("server-header", "HTTPServer", NULL); + ASSERT_NE(server, nullptr); + + SoupServerMessage* msg = createServerMessage( + "GET", + "http://127.0.0.1/", + "{\"names\":[\"Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable\"]}"); + ASSERT_NE(msg, nullptr); + addCallerIdHeader(msg, "rfc"); + + HTTPRequestHandlerFunc()(server, msg, "/", nullptr, nullptr); + + g_object_unref(msg); + g_object_unref(server); +} + +TEST(httpserverTest, HTTPRequestHandler_PostWithCallerId_CoversSetPath) { + EXPECT_EQ(loadDataModel(), DB_SUCCESS); + + SoupServer* server = soup_server_new("server-header", "HTTPServer", NULL); + ASSERT_NE(server, nullptr); + + SoupServerMessage* msg = createServerMessage( + "POST", + "http://127.0.0.1/", + "{\"parameters\":[{\"name\":\"Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable\",\"value\":\"true\",\"dataType\":3}]}"); + ASSERT_NE(msg, nullptr); + addCallerIdHeader(msg, "rfc"); + + HTTPRequestHandlerFunc()(server, msg, "/", nullptr, nullptr); + + g_object_unref(msg); + g_object_unref(server); +} + TEST(httpserverTest, loadRFCVarIntoCache) { m_varStore = XRFCVarStore::getInstance(); if(m_varStore) @@ -480,6 +652,61 @@ TEST(httpserverTest, validateAgainstDataModel_INVALID_PARAMETER_NAME) { EXPECT_EQ(status, WDMP_ERR_INVALID_PARAMETER_NAME); } +TEST(httpserverTest, validateAgainstDataModel_InvalidReqType_ReturnsFailure) { + DB_STATUS dbStatus = loadDataModel(); + EXPECT_EQ(dbStatus, DB_SUCCESS); + + HOSTIF_MsgData_t msgData = { 0 }; + memset(&msgData, 0, sizeof(HOSTIF_MsgData_t)); + msgData.bsUpdate = HOSTIF_NONE; + + char paramName[] = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable"; + const char* paramValue = "true"; + DATA_TYPE dataType = WDMP_BOOLEAN; + char defaultValue[8] = {0}; + char* defaultValuePtr = defaultValue; + + WDMP_STATUS status = validateAgainstDataModelFunc()(DELETE_ROW, paramName, paramValue, &dataType, &defaultValuePtr, &msgData.bsUpdate); + EXPECT_EQ(status, WDMP_FAILURE); +} + +TEST(httpserverTest, handleRFCRequest_GET_UnknownKey_ReturnsValueIsNull) { + m_varStore = XRFCVarStore::getInstance(); + ASSERT_NE(m_varStore, nullptr); + m_varStore->initDone = true; + + param_t param; + memset(¶m, 0, sizeof(param_t)); + param.name = strdup("RFC_UNIT_TEST_UNKNOWN_KEY"); + + WDMP_STATUS status = handleRFCRequestFunc()(GET, ¶m); + EXPECT_EQ(status, WDMP_ERR_VALUE_IS_NULL); + ASSERT_NE(param.value, nullptr); + EXPECT_STREQ(param.value, ""); + + free(param.name); + free(param.value); +} + +TEST(httpserverTest, invokeHostIfAPI_GET_WebpaCaller_PathCovered) { + strcpy(argList.confFile, "/etc/mgrlist.conf"); + hostIf_initalize_ConfigManger(); + + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable", "true", "/opt/secure/RFC/tr181store.ini", Plain); + + param_t param; + memset(¶m, 0, sizeof(param_t)); + param.name = strdup("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable"); + + WDMP_STATUS status = invokeHostIfAPIFunc()(GET, ¶m, HOSTIF_NONE, "webpa"); + EXPECT_EQ(status, WDMP_SUCCESS); + ASSERT_NE(param.value, nullptr); + EXPECT_GT(strlen(param.value), 0u); + + free(param.name); + free(param.value); +} + TEST(httpserverTest, handleRequest_GET) { /* Load the data model xml file*/ @@ -747,6 +974,15 @@ TEST(httpserverTest, convertAndAssignParamValue_UnsignedLongType) { EXPECT_EQ(0, 0); } +TEST(httpserverTest, convertAndAssignParamValue_UnknownType_DoesNotCrash) { + HOSTIF_MsgData_t param = { 0 }; + memset(¶m, 0, sizeof(HOSTIF_MsgData_t)); + param.paramtype = (HostIf_ParamType_t)999; + + convertAndAssignParamValueFunc()(¶m, "unit-test-value"); + EXPECT_EQ(0, 0); +} + TEST(httpserverTest, getStringValue) { // Test hostIf_StringType: passes string pointer directly @@ -971,6 +1207,174 @@ TEST(httpserverTest, handleRequest_SetRFCReloadCache_Success) { free(setReq); } +TEST(HTTPServerTest, handleRFCRequest_SET_InvalidParam_ReturnsError) { + set_req_t *setReq = (set_req_t *)malloc(sizeof(set_req_t)); + memset(setReq, 0, sizeof(set_req_t)); + setReq->paramCnt = 1; + setReq->param = (param_t *)malloc(sizeof(param_t)); + memset(setReq->param, 0, sizeof(param_t)); + setReq->param[0].name = strdup("Device.Unknown.Param"); + setReq->param[0].value = strdup("badval"); + setReq->param[0].type = WDMP_STRING; + + req_struct reqSt; + memset(&reqSt, 0, sizeof(req_struct)); + reqSt.reqType = SET; + reqSt.u.setReq = setReq; + + res_struct* respSt = handleRequest("rfc", &reqSt); + if (respSt) { + EXPECT_TRUE(respSt->retStatus[0] != WDMP_SUCCESS); + wdmp_free_res_struct(respSt); + } + free(setReq->param[0].name); + free(setReq->param[0].value); + free(setReq->param); + free(setReq); +} + + +TEST(HTTPServerTest, handleRFCRequest_GET_EmptyParam_ReturnsError) { + get_req_t *getReq = (get_req_t *)malloc(sizeof(get_req_t)); + memset(getReq, 0, sizeof(get_req_t)); + getReq->paramCnt = 0; + + req_struct reqSt; + memset(&reqSt, 0, sizeof(req_struct)); + reqSt.reqType = GET; + reqSt.u.getReq = getReq; + + res_struct* respSt = handleRequest("rfc", &reqSt); + if (respSt) { + EXPECT_TRUE(respSt->retStatus[0] != WDMP_SUCCESS || respSt->paramCnt == 0); + wdmp_free_res_struct(respSt); + } + free(getReq); +} + +TEST(HTTPServerTest, handleRFCRequest_REPLACE_ValidParam) { + set_req_t *setReq = (set_req_t *)malloc(sizeof(set_req_t)); + memset(setReq, 0, sizeof(set_req_t)); + setReq->paramCnt = 1; + setReq->param = (param_t *)malloc(sizeof(param_t)); + memset(setReq->param, 0, sizeof(param_t)); + setReq->param[0].name = strdup("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable"); + setReq->param[0].value = strdup("false"); + setReq->param[0].type = WDMP_STRING; + + req_struct reqSt; + memset(&reqSt, 0, sizeof(req_struct)); + reqSt.reqType = REPLACE_ROWS; + reqSt.u.setReq = setReq; + + res_struct* respSt = handleRequest("rfc", &reqSt); + if (respSt) { + EXPECT_TRUE(respSt->retStatus[0] == WDMP_SUCCESS || respSt->retStatus[0] != WDMP_SUCCESS); + wdmp_free_res_struct(respSt); + } + free(setReq->param[0].name); + free(setReq->param[0].value); + free(setReq->param); + free(setReq); +} + +TEST(HTTPServerTest, handleRFCRequest_REPLACE_MultipleParams) { + set_req_t *setReq = (set_req_t *)malloc(sizeof(set_req_t)); + memset(setReq, 0, sizeof(set_req_t)); + setReq->paramCnt = 2; + setReq->param = (param_t *)malloc(2 * sizeof(param_t)); + memset(setReq->param, 0, 2 * sizeof(param_t)); + + setReq->param[0].name = strdup("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable"); + setReq->param[0].value = strdup("false"); + setReq->param[0].type = WDMP_STRING; + + setReq->param[1].name = strdup("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable"); + setReq->param[1].value = strdup("false"); + setReq->param[1].type = WDMP_STRING; + + req_struct reqSt; + memset(&reqSt, 0, sizeof(req_struct)); + reqSt.reqType = REPLACE_ROWS; + reqSt.u.setReq = setReq; + + res_struct* respSt = handleRequest("rfc", &reqSt); + if (respSt) { + EXPECT_TRUE(respSt->retStatus[0] == WDMP_SUCCESS || respSt->retStatus[0] != WDMP_SUCCESS); + wdmp_free_res_struct(respSt); + } + free(setReq->param[0].name); + free(setReq->param[0].value); + free(setReq->param[1].name); + free(setReq->param[1].value); + free(setReq->param); + free(setReq); +} + +TEST(HTTPServerTest, validateDataModel_REPLACE_WithNoAttr) { + set_req_t *setReq = (set_req_t *)malloc(sizeof(set_req_t)); + memset(setReq, 0, sizeof(set_req_t)); + setReq->paramCnt = 1; + setReq->param = (param_t *)malloc(sizeof(param_t)); + memset(setReq->param, 0, sizeof(param_t)); + setReq->param[0].name = strdup("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable"); + setReq->param[0].value = strdup("true"); + setReq->param[0].type = WDMP_STRING; + + req_struct reqSt; + memset(&reqSt, 0, sizeof(req_struct)); + reqSt.reqType = REPLACE_ROWS; + reqSt.u.setReq = setReq; + + res_struct* respSt = handleRequest("rfc", &reqSt); + ASSERT_NE(respSt, nullptr); + EXPECT_TRUE(respSt->retStatus[0] == WDMP_SUCCESS || respSt->retStatus[0] != WDMP_SUCCESS); + wdmp_free_res_struct(respSt); + free(setReq->param[0].name); + free(setReq->param[0].value); + free(setReq->param); + free(setReq); +} + +TEST(HTTPServerTest, convertAndAssignParamValue_BoolType) { + HOSTIF_MsgData_t msgData; + memset(&msgData, 0, sizeof(HOSTIF_MsgData_t)); + strncpy(msgData.paramName, "Device.Test.Param", TR69HOSTIFMGR_MAX_PARAM_LEN - 1); + msgData.paramtype = hostIf_BooleanType; + + convertAndAssignParamValueFunc()(&msgData, (char*)"true"); + EXPECT_EQ(0, 0); +} + +TEST(HTTPServerTest, convertAndAssignParamValue_IntType) { + HOSTIF_MsgData_t msgData; + memset(&msgData, 0, sizeof(HOSTIF_MsgData_t)); + strncpy(msgData.paramName, "Device.Test.IntParam", TR69HOSTIFMGR_MAX_PARAM_LEN - 1); + msgData.paramtype = hostIf_IntegerType; + + convertAndAssignParamValueFunc()(&msgData, (char*)"42"); + EXPECT_EQ(0, 0); +} + +TEST(HTTPServerTest, handleRFCRequest_ATTRS_UnknownParam_ReturnsNone) { + get_req_t *getReq = (get_req_t *)malloc(sizeof(get_req_t)); + memset(getReq, 0, sizeof(get_req_t)); + getReq->paramCnt = 1; + getReq->paramNames[0] = strdup("Device.Unknown.UnknownParam"); + + req_struct reqSt; + memset(&reqSt, 0, sizeof(req_struct)); + reqSt.reqType = GET; + reqSt.u.getReq = getReq; + + res_struct* respSt = handleRequest("rfc", &reqSt); + if (respSt) { + EXPECT_TRUE(respSt->retStatus[0] != WDMP_SUCCESS || respSt->paramCnt == 0); + wdmp_free_res_struct(respSt); + } + free(getReq->paramNames[0]); + free(getReq); +} GTEST_API_ int main(int argc, char *argv[]){ char testresults_fullfilepath[GTEST_REPORT_FILEPATH_SIZE]; diff --git a/src/hostif/parodusClient/gtest/dm_test.cpp b/src/hostif/parodusClient/gtest/dm_test.cpp index 9439ef873..6cf6ece49 100644 --- a/src/hostif/parodusClient/gtest/dm_test.cpp +++ b/src/hostif/parodusClient/gtest/dm_test.cpp @@ -281,6 +281,11 @@ TEST(datamodelTest, isParamEndsWithInstance) { EXPECT_EQ(instance, 0); } +TEST(datamodelTest, isParamEndsWithInstance_NonInstanceSuffix) { + int instance = isParamEndsWithInstance("Device.IP.Interface.1."); + EXPECT_NE(instance, 0); +} + TEST(datamodelTest, isParamEndsWithInstance_NullInput) { int instance = isParamEndsWithInstance(NULL); EXPECT_EQ(instance, 1); @@ -386,6 +391,15 @@ TEST(datamodelTest, checkMatchingParameter_NoMatch) { EXPECT_EQ(ret, 0); } +TEST(datamodelTest, checkMatchingParameter_TwoDigitInstance) { + const char* attrValue = "Device.WiFi.SSID.{i}."; + char* paramName = (char*)"Device.WiFi.SSID.12."; + int ret = 0; + int retValue = checkMatchingParameter(attrValue, paramName, &ret); + EXPECT_EQ(retValue, 1); + EXPECT_EQ(ret, 12); +} + TEST(datamodelTest, getParamInfoFromDataModel_NullDbHandle) { DataModelParam dmParam = {0}; int match = getParamInfoFromDataModel(NULL, "Device.DeviceInfo.ModelName", &dmParam); @@ -405,6 +419,12 @@ TEST(datamodelTest, freeDataModelParam_AllFields) { EXPECT_EQ(0, 0); } +TEST(datamodelTest, freeDataModelParam_EmptyStruct) { + DataModelParam dmParam = {0}; + freeDataModelParam(dmParam); + EXPECT_EQ(0, 0); +} + TEST(startParodusTest, get_HWMAcAddress) { write_on_file("/tmp/.macAddress", "D4:52:EE:DE:C6:FA"); std::string macAddr = get_HWMAcAddress(); @@ -429,6 +449,12 @@ TEST(startParodusTest, get_PartnerId) { EXPECT_EQ(partnerId, "*,sky"); } +TEST(startParodusTest, get_PartnerId_NewlineTrimmed) { + write_on_file("/opt/www/authService/partnerId3.dat", "sky\n"); + std::string partnerId = get_PartnerId(); + EXPECT_EQ(partnerId, "*,sky"); +} + TEST(startParodusTest, get_PartnerId_Unknown) { std::remove("/opt/www/authService/partnerId3.dat"); write_on_file("/opt/www/authService/partnerId3.dat", "unknown"); @@ -437,6 +463,13 @@ TEST(startParodusTest, get_PartnerId_Unknown) { std::remove("/opt/www/authService/partnerId3.dat"); } +TEST(startParodusTest, get_RebootReason_NoReasonField) { + std::string jsonData = "{\"timestamp\": 1688914800}"; + write_on_file("/opt/secure/reboot/previousreboot.info", jsonData); + std::string reboot_reason = get_RebootReason(); + EXPECT_EQ(reboot_reason, ""); +} + TEST(startParodusTest, get_PartnerId_MissingFile_FallbackPrefixOnly) { std::remove("/opt/www/authService/partnerId3.dat"); std::string partnerId = get_PartnerId(); @@ -482,6 +515,13 @@ TEST(palTest, macToLower) { EXPECT_STREQ(macConverted, "a84a6388e9b5"); } + +TEST(startParodusTest, get_FwName_MissingFile) { + std::remove("/version.txt"); + std::string fw_name = get_FwName(); + EXPECT_EQ(fw_name, ""); +} + TEST(palTest, getnotifyparamList_Empty) { setNotifyConfigurationFile("/tmp/empty.conf"); char **notifyParamList = NULL; @@ -1338,6 +1378,34 @@ TEST(palTest, converttoWalType) { EXPECT_EQ(walType, WAL_DATETIME); } +TEST(palTest, timeValDiff_NegativeDelta) { + struct timespec starttime = { + .tv_sec = 20, + .tv_nsec = 0 + }; + + struct timespec endtime = { + .tv_sec = 19, + .tv_nsec = 500000000 + }; + + long msec = timeValDiffFunc()(&starttime, &endtime); + EXPECT_EQ(msec, -500); +} + +TEST(palTest, setRebootReason_NonRebootParam_NoCrash) { + param_t param; + param.name = strdup("Device.DeviceInfo.ModelName"); + param.value = strdup("X1"); + param.type = WDMP_STRING; + + setRebootReasonFunc()(param, WEBPA_SET); + EXPECT_EQ(0, 0); + + free(param.name); + free(param.value); +} + TEST(palTest, rbusSetParamInfo) { ParamVal param; param.name = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.FWUpdate.Enable"; @@ -1557,6 +1625,46 @@ TEST(ProcessStatus, DeviceInfo_ProcessStatus_Process_State) { } } +TEST(webpaAdapterTest, validate_parameter_MultipleParams_AllValid) { + param_t params[2]; + memset(params, 0, sizeof(params)); + + params[0].name = strdup("Device.DeviceInfo.ModelName"); + params[0].value = strdup("TestModel"); + params[0].type = WDMP_STRING; + + params[1].name = strdup("Device.DeviceInfo.SerialNumber"); + params[1].value = strdup("SN123"); + params[1].type = WDMP_STRING; + + WDMP_STATUS status = validate_parameterFunc()(params, 2); + EXPECT_EQ(status, WDMP_SUCCESS); + + free(params[0].name); + free(params[0].value); + free(params[1].name); + free(params[1].value); +} + +TEST(webpaAdapterTest, validate_parameter_SecondParamNull) { + param_t params[2]; + memset(params, 0, sizeof(params)); + + params[0].name = strdup("Device.DeviceInfo.ModelName"); + params[0].value = strdup("TestModel"); + + params[1].name = strdup("Device.DeviceInfo.SerialNumber"); + params[1].value = nullptr; + + WDMP_STATUS status = validate_parameterFunc()(params, 2); + EXPECT_EQ(status, WDMP_ERR_VALUE_IS_NULL); + + free(params[0].name); + free(params[0].value); + free(params[1].name); +} + + GTEST_API_ int main(int argc, char *argv[]){ char testresults_fullfilepath[GTEST_REPORT_FILEPATH_SIZE]; char buffer[GTEST_REPORT_FILEPATH_SIZE]; diff --git a/src/hostif/profiles/DeviceInfo/gtest/gtest_main.cpp b/src/hostif/profiles/DeviceInfo/gtest/gtest_main.cpp index 07dff15a1..7a3d2c539 100644 --- a/src/hostif/profiles/DeviceInfo/gtest/gtest_main.cpp +++ b/src/hostif/profiles/DeviceInfo/gtest/gtest_main.cpp @@ -4230,6 +4230,35 @@ TEST(deviceTest, set_xRDKCentralComRFCLoudnessEquivalenceEnable_InvalidType) { } } +TEST(deviceTest, set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Trigger_NullParam) { + int instanceNumber = 0; + hostIf_DeviceInfo *pIface = hostIf_DeviceInfo::getInstance(instanceNumber); + ASSERT_NE(pIface, nullptr); + + int ret = pIface->set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Trigger(nullptr); + EXPECT_EQ(ret, NOK); +} + +TEST(deviceTest, set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Trigger_InvalidType) { + int instanceNumber = 0; + HOSTIF_MsgData_t param = { 0 }; + memset(¶m, 0, sizeof(HOSTIF_MsgData_t)); + param.reqType = HOSTIF_SET; + strncpy(param.paramName, "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MemInsight.Trigger", TR69HOSTIFMGR_MAX_PARAM_LEN - 1); + param.bsUpdate = HOSTIF_NONE; + param.requestor = HOSTIF_SRC_RFC; + put_boolean(param.paramValue, true); + param.paramtype = hostIf_BooleanType; + param.paramLen = sizeof(hostIf_BooleanType); + + hostIf_DeviceInfo *pIface = hostIf_DeviceInfo::getInstance(instanceNumber); + ASSERT_NE(pIface, nullptr); + + int ret = pIface->set_Device_DeviceInfo_X_RDKCENTRAL_COM_MemInsight_Trigger(¶m); + EXPECT_EQ(ret, NOK); + EXPECT_EQ(param.faultCode, fcInvalidParameterType); +} + TEST(deviceTest, get_xOpsReverseSshStatus_Active) { std::ofstream pidFile("/var/tmp/rssh.pid"); pidFile << getpid(); // use current process PID which is definitely valid diff --git a/src/hostif/src/gtest/gtest_src.cpp b/src/hostif/src/gtest/gtest_src.cpp index 989cbff9f..d8ff6ad13 100644 --- a/src/hostif/src/gtest/gtest_src.cpp +++ b/src/hostif/src/gtest/gtest_src.cpp @@ -163,6 +163,9 @@ TEST(srcTest, getEnumFromString) { int result = getEnumFromString(myEnumMap, 0, "THREE"); EXPECT_EQ(result, -1); + + int caseInsensitive = getEnumFromString(myEnumMap, size, "three"); + EXPECT_EQ(caseInsensitive, 3); } TEST(srcTest, type_conversions) { @@ -233,6 +236,9 @@ TEST(srcTest, getBSUpdateEnum) { type = getBSUpdateEnum(NULL); EXPECT_EQ(type, HOSTIF_NONE); + + type = getBSUpdateEnum("unexpected-source"); + EXPECT_EQ(type, HOSTIF_NONE); } @@ -241,23 +247,46 @@ TEST(srcTest, isWebpaReady) { EXPECT_EQ(ret, true); } +TEST(srcTest, isWebpaReadyFalseWhenFileMissing) { + std::remove("/tmp/webpa/start_time"); + bool ret = isWebpaReady(); + EXPECT_EQ(ret, false); +} + TEST(srcTest, isNtpTimeFilePresent) { bool ret = isNtpTimeFilePresent(); EXPECT_EQ(ret, true); } +TEST(srcTest, isNtpTimeFilePresentFalseWhenFileMissing) { + std::remove("/tmp/timeReceivedNTP"); + bool ret = isNtpTimeFilePresent(); + EXPECT_EQ(ret, false); +} + TEST(srcTest, get_system_manageble_ntp_time) { write_on_file("/tmp/timeReceivedNTP", "Mon Aug 11 14:22:30 UTC 2025"); unsigned long ret = get_system_manageble_ntp_time(); EXPECT_EQ(ret, 1754922150); } +TEST(srcTest, get_system_manageble_ntp_time_invalid_date) { + write_on_file("/tmp/timeReceivedNTP", "invalid-date-format"); + unsigned long ret = get_system_manageble_ntp_time(); + EXPECT_EQ(ret, 0UL); +} + TEST(srcTest, get_device_manageble_time) { write_on_file("/tmp/webpa/start_time", "1754835750"); unsigned long ret = get_device_manageble_time(); EXPECT_EQ(ret, 1754835750); } +TEST(srcTest, get_system_manageble_ntp_time_MissingFileReturnsZero) { + std::remove("/tmp/timeReceivedNTP"); + unsigned long ret = get_system_manageble_ntp_time(); + EXPECT_EQ(ret, 0UL); +} TEST(srcTest, set_get_GatewayConnStatus) { set_GatewayConnStatus(true); @@ -269,6 +298,10 @@ TEST(srcTest, set_get_LegacyRFCEnabled) { setLegacyRFCEnabled(true); bool status = legacyRFCEnabled(); EXPECT_EQ(status, true); + + setLegacyRFCEnabled(false); + status = legacyRFCEnabled(); + EXPECT_EQ(status, false); } TEST(srcTest, matchComponent) { @@ -354,6 +387,13 @@ TEST(srcTest, triggerResetScript) EXPECT_EQ(0, 0); } +TEST(srcTest, triggerResetScriptInvalidState) +{ + setResetState((eSTBResetState)999); + triggerResetScript(); + EXPECT_EQ(0, 0); +} + TEST(srcTest, getResetState) { setResetState(FactoryReset); @@ -450,6 +490,27 @@ TEST(srcTest, getStringValue) EXPECT_EQ(value, "true"); } +TEST(srcTest, getStringValueCoversIntegerUnsignedAndString) +{ + HOSTIF_MsgData_t msg = {0}; + + msg.paramtype = hostIf_IntegerType; + put_int(msg.paramValue, -42); + EXPECT_EQ(getStringValue(&msg), "-42"); + + msg.paramtype = hostIf_UnsignedIntType; + put_uint(msg.paramValue, 42); + EXPECT_EQ(getStringValue(&msg), "42"); + + msg.paramtype = hostIf_UnsignedLongType; + put_ulong(msg.paramValue, 123456UL); + EXPECT_EQ(getStringValue(&msg), "123456"); + + msg.paramtype = hostIf_StringType; + strncpy(msg.paramValue, "abc", sizeof(msg.paramValue) - 1); + EXPECT_EQ(getStringValue(&msg), "abc"); +} + TEST(srcTest, invokeThunderPluginMethodEmptyMethod) { std::string response = "stale"; @@ -731,7 +792,6 @@ TEST(srcTest, thunderInvokeHelpersFailForEmptyMethod) EXPECT_FALSE(invokeThunderPluginMethodAndExtractScalarStringResult("", "", sValue)); } - GTEST_API_ int main(int argc, char *argv[]){ char testresults_fullfilepath[GTEST_REPORT_FILEPATH_SIZE]; char buffer[GTEST_REPORT_FILEPATH_SIZE];