diff --git a/CHANGELOG.md b/CHANGELOG.md index a4150cca..a22c171d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,47 @@ 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.1.2](https://github.com/rdkcentral/rfc/compare/1.1.1...1.1.2) + +- RDKEMW-5971: Review and cleanup RFC scripts [`#55`](https://github.com/rdkcentral/rfc/pull/55) +- RDKEMW-5675 [RDKE] onDeviceMgtUpdate sent slightly before RFC processing is complete [`#52`](https://github.com/rdkcentral/rfc/pull/52) +- RDKEMW-5593 [RDKE] Excessive Logging in rfcscript.log curl response [`#51`](https://github.com/rdkcentral/rfc/pull/51) +- Merge tag '1.1.1' into develop [`77b8f1f`](https://github.com/rdkcentral/rfc/commit/77b8f1f00a13e231cb0e8a13f526809425a1e362) + +#### [1.1.1](https://github.com/rdkcentral/rfc/compare/1.1.0...1.1.1) + +> 25 June 2025 + +- RDK-57914: Dynamic WhoAmI feature control for rfcMgr [`#35`](https://github.com/rdkcentral/rfc/pull/35) +- 1.1.1 release changelog updates [`0fdbe08`](https://github.com/rdkcentral/rfc/commit/0fdbe08ff4df491b75797a27fb800a90100299af) +- Merge tag '1.1.0' into develop [`cdd5014`](https://github.com/rdkcentral/rfc/commit/cdd5014d7162beaa4861179a306e41d0e8f83b67) + +#### [1.1.0](https://github.com/rdkcentral/rfc/compare/1.0.9...1.1.0) + +> 18 June 2025 + +- RDKCOM-5158: RDKBDEV-3006: Fix memory leaks in "rfc" [`#9`](https://github.com/rdkcentral/rfc/pull/9) +- DELIA-68312: RFC Lock file not deleted after RFC Configuration complete [`#41`](https://github.com/rdkcentral/rfc/pull/41) +- Update run_ut.sh [`#38`](https://github.com/rdkcentral/rfc/pull/38) +- RDK-57916: Update T2 Event Markers for rfcscript.log [`#34`](https://github.com/rdkcentral/rfc/pull/34) +- 1.1.0 release changelog updates [`163ee11`](https://github.com/rdkcentral/rfc/commit/163ee115f22417d8fc9ca449dc08b4be496c7f8a) +- Merge tag '1.0.9' into develop [`e162b5f`](https://github.com/rdkcentral/rfc/commit/e162b5fb69d7f8aae74b6c1446fe38825964c1af) + +#### [1.0.9](https://github.com/rdkcentral/rfc/compare/1.0.8...1.0.9) + +> 19 May 2025 + +- RDKE-791 : Generating Minidump for RFC [`#31`](https://github.com/rdkcentral/rfc/pull/31) +- 1.0.9 release changelog updates [`621ceaf`](https://github.com/rdkcentral/rfc/commit/621ceafb4091302a34501262c5a86f3f9dfc7f86) +- Merge tag '1.0.8' into develop [`4c2a89b`](https://github.com/rdkcentral/rfc/commit/4c2a89b93f9226f3ed80f6abbba86a3cd27addbd) + #### [1.0.8](https://github.com/rdkcentral/rfc/compare/1.0.7...1.0.8) +> 27 April 2025 + - RDK-56121 [RDK-E] Fix coverity issues in rfc [`#22`](https://github.com/rdkcentral/rfc/pull/22) - RDK-56121 Fix coverity issues in rfc [`#17`](https://github.com/rdkcentral/rfc/pull/17) +- 1.0.8 release changelog updates [`784661f`](https://github.com/rdkcentral/rfc/commit/784661fb1bebb580b38311d3c7acb9322ef4294a) - Merge tag '1.0.7' into develop [`51dfdee`](https://github.com/rdkcentral/rfc/commit/51dfdee0092fafda84f5fff29efc02bdf2ce598b) - RDK-56121 [RDK-E] Add L1 for coverity issues in rfc [`c546c43`](https://github.com/rdkcentral/rfc/commit/c546c4383268f2c0801bfef6140c5288ad0c1d9a) diff --git a/rfcInit.sh b/rfcInit.sh deleted file mode 100644 index 781be8ba..00000000 --- a/rfcInit.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/sh -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2018 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -# -################################################################## -## Script to perform Remote Feature Control -## Updates the following information in the settop box -## list of features that are enabled or disabled -## if feature configuration is effective immediately -## updates startup parameters for each feature -## updates the list of variables in a single file -## Author: Milorad -################################################################## - -. /etc/include.properties -. /etc/device.properties -. /etc/rfc.properties - - -RFC_LOG_FILE="/opt/logs/rfcscript.log" - - -##################################################################### -## RFC Logging helper function -##################################################################### -rfcLogging () -{ - echo "`/bin/timestamp` [RFC]:: $1" >> $RFC_LOG_FILE -} -##################################################################### - - - -## Get update times - -oldTime=0 -newTime=0 -RFC_INIT_LOCK="/opt/.rfcInitInProgress" - -rfcMoveToNewLoc() -{ - ## check if RFC transition has to take place from old to new secure location - if [ ! -d $RFC_BASE ]; then - rfcLogging "ERROR configuring RFC location NewLoc=$RFC_BASE, no parent folder" >> $RFC_LOG_FILE - else - # mark transition in progress - touch $RFC_INIT_LOCK - if [ -d $RFC_BASE/RFC ]; then - rm -r $RFC_BASE/RFC - fi - rfcLogging "Changing RFC location CurrentLoc=$OLD_RFC_BASE/RFC, NewLoc=$RFC_BASE/RFC" - ls -l $OLD_RFC_BASE/RFC >> $RFC_LOG_FILE - - cp -r $OLD_RFC_BASE/RFC $RFC_BASE - - # update list files - cp $RFC_PATH/$RFC_LIST_FILE_NAME_PREFIX*$RFC_LIST_FILE_NAME_SUFFIX $RFC_RAM_PATH/. - - # remove transition lock file - rm -f $RFC_INIT_LOCK - fi - - -} -######################################## - -if [ "$DEVICE_TYPE" != "broadband" ]; then - if [ -f $OLD_RFC_BASE/RFC/tr181store.ini ]; then - oldTime=`grep ConfigSetTime $OLD_RFC_BASE/RFC/tr181store.ini|sed 's/=/ = /'|awk '{print $3}'` - fi - - if [ -f $RFC_BASE/RFC/tr181store.ini ]; then - newTime=`grep ConfigSetTime $RFC_BASE/RFC/tr181store.ini|sed 's/=/ = /'|awk '{print $3}'` - fi - - ## check if RFC transition has to take place from old to new secure location - if [ -z "$oldTime" ] || [ -z "$newTime" ]; then - echo "`/bin/timestamp` RFC: Old time or New time is empty. The value of oldTime = $oldTime and newTime = $newTime." >> $RFC_LOG_FILE - else - if [ $oldTime -gt $newTime ] || [ -f $RFC_INIT_LOCK ]; then - echo "`/bin/timestamp` RFC: Transition - Old time $oldTime is greater then new time $newTime." >> $RFC_LOG_FILE - rfcMoveToNewLoc - else - echo "`/bin/timestamp` RFC: No Transition - Old time $oldTime is SMALLER then new time $newTime." >> $RFC_LOG_FILE - fi - fi - - if [ ! -f /tmp/rfcdefaults.ini ]; then - for f in /etc/rfcdefaults/*.ini; do (cat "${f}"; echo) >> /tmp/rfcdefaults.ini; done - else - echo "`/bin/timestamp` rfcInit: rfcdefaults.ini exist" >> $RFC_LOG_FILE - fi -fi - diff --git a/rfcMgr/gtest/Makefile.am b/rfcMgr/gtest/Makefile.am index 6e941b36..355d3398 100644 --- a/rfcMgr/gtest/Makefile.am +++ b/rfcMgr/gtest/Makefile.am @@ -19,12 +19,38 @@ AUTOMAKE_OPTIONS = subdir-objects # Define the program name and the source files -bin_PROGRAMS = rfcMgr_gtest +bin_PROGRAMS = rfcMgr_gtest rfcapi_gtest tr181api_gtest utils_gtest -rfcMgr_gtest_SOURCES = $(TOP_DIR)/tr181api/tr181api.cpp $(TOP_DIR)/rfcMgr/rfc_manager.cpp $(TOP_DIR)/rfcMgr/rfc_common.cpp $(TOP_DIR)/rfcMgr/mtlsUtils.cpp $(TOP_DIR)/rfcMgr/rfc_xconf_handler.cpp $(TOP_DIR)/rfcMgr/xconf_handler.cpp $(TOP_DIR)/rfcapi/rfcapi.cpp $(TOP_DIR)/rfcMgr/gtest/gtest_main.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/secure_wrapper.c $(TOP_DIR)/rfcMgr/gtest/mocks/common_device_api.c $(TOP_DIR)/rfcMgr/gtest/mocks/curl_debug.c $(TOP_DIR)/rfcMgr/gtest/mocks/downloadUtil.c $(TOP_DIR)/rfcMgr/gtest/mocks/json_parse.c $(TOP_DIR)/rfcMgr/gtest/mocks/rdk_fwdl_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/system_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/urlHelper.c $(TOP_DIR)/rfcMgr/gtest/mocks/rfcMgr_stubs.cpp +COMMON_CPPFLAGS = -std=c++17 -DGTEST_ENABLE -DRDK_LOGGER -DUSE_IARMBUS -I${TOP_DIR}/rfcMgr/ -I${TOP_DIR}/rfcapi/ -I/usr/include -I/usr/include/cjson -I${TOP_DIR}/rfcMgr/gtest/mocks/ -I${TOP_DIR}/rfcMgr/gtest/mocks/wdmp-c/ -I$(TOP_DIR)/tr181api/ -I$(TOP_DIR)/utils/ +COMMON_CXXFLAGS = -frtti -fprofile-arcs -ftest-coverage +COMMON_LDADD = -lgtest -lgtest_main -lgmock_main -lgmock -lgcov -lcjson -lcurl -AM_CPPFLAGS = -std=c++17 -DGTEST_ENABLE -DRDK_LOGGER -DUSE_IARMBUS -I${TOP_DIR}/rfcMgr/ -I${TOP_DIR}/rfcapi/ -I/usr/include -I/usr/include/cjson -I${TOP_DIR}/rfcMgr/gtest/mocks/ -I${TOP_DIR}/rfcMgr/gtest/mocks/wdmp-c/ -I$(TOP_DIR)/tr181api/ -AM_CXXFLAGS = -frtti -fprofile-arcs -ftest-coverage -AM_LDFLAGS = -lgtest -lgtest_main -lgmock_main -lgmock -lgcov -lcjson -lcurl +rfcapi_gtest_SOURCES = $(TOP_DIR)/rfcMgr/gtest/gtest_rfcapi.cpp $(TOP_DIR)/rfcapi/rfcapi.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/secure_wrapper.c $(TOP_DIR)/rfcMgr/gtest/mocks/common_device_api.c $(TOP_DIR)/rfcMgr/gtest/mocks/curl_debug.c $(TOP_DIR)/rfcMgr/gtest/mocks/downloadUtil.c $(TOP_DIR)/rfcMgr/gtest/mocks/json_parse.c $(TOP_DIR)/rfcMgr/gtest/mocks/rdk_fwdl_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/system_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/urlHelper.c $(TOP_DIR)/rfcMgr/gtest/mocks/rfcMgr_stubs.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/mock_curl.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/tr181_store_writer.cpp + +tr181api_gtest_SOURCES = $(TOP_DIR)/rfcMgr/gtest/gtest_tr181api.cpp $(TOP_DIR)/rfcapi/rfcapi.cpp $(TOP_DIR)/tr181api/tr181api.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/secure_wrapper.c $(TOP_DIR)/rfcMgr/gtest/mocks/common_device_api.c $(TOP_DIR)/rfcMgr/gtest/mocks/curl_debug.c $(TOP_DIR)/rfcMgr/gtest/mocks/downloadUtil.c $(TOP_DIR)/rfcMgr/gtest/mocks/json_parse.c $(TOP_DIR)/rfcMgr/gtest/mocks/rdk_fwdl_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/system_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/urlHelper.c $(TOP_DIR)/rfcMgr/gtest/mocks/rfcMgr_stubs.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/mock_curl.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/tr181_store_writer.cpp + +utils_gtest_SOURCES = $(TOP_DIR)/utils/tr181utils.cpp $(TOP_DIR)/tr181api/tr181api.cpp $(TOP_DIR)/rfcapi/rfcapi.cpp $(TOP_DIR)/utils/jsonhandler.cpp $(TOP_DIR)/rfcMgr/gtest/gtest_utils.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/secure_wrapper.c $(TOP_DIR)/rfcMgr/gtest/mocks/common_device_api.c $(TOP_DIR)/rfcMgr/gtest/mocks/curl_debug.c $(TOP_DIR)/rfcMgr/gtest/mocks/downloadUtil.c $(TOP_DIR)/rfcMgr/gtest/mocks/json_parse.c $(TOP_DIR)/rfcMgr/gtest/mocks/rdk_fwdl_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/system_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/urlHelper.c $(TOP_DIR)/rfcMgr/gtest/mocks/rfcMgr_stubs.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/mock_curl.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/tr181_store_writer.cpp + +rfcMgr_gtest_SOURCES = $(TOP_DIR)/rfcMgr/rfc_manager.cpp $(TOP_DIR)/rfcMgr/rfc_common.cpp $(TOP_DIR)/rfcMgr/mtlsUtils.cpp $(TOP_DIR)/rfcMgr/rfc_xconf_handler.cpp $(TOP_DIR)/rfcMgr/xconf_handler.cpp $(TOP_DIR)/rfcapi/rfcapi.cpp $(TOP_DIR)/utils/jsonhandler.cpp $(TOP_DIR)/rfcMgr/gtest/gtest_main.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/secure_wrapper.c $(TOP_DIR)/rfcMgr/gtest/mocks/common_device_api.c $(TOP_DIR)/rfcMgr/gtest/mocks/curl_debug.c $(TOP_DIR)/rfcMgr/gtest/mocks/downloadUtil.c $(TOP_DIR)/rfcMgr/gtest/mocks/json_parse.c $(TOP_DIR)/rfcMgr/gtest/mocks/rdk_fwdl_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/system_utils.c $(TOP_DIR)/rfcMgr/gtest/mocks/urlHelper.c $(TOP_DIR)/rfcMgr/gtest/mocks/rfcMgr_stubs.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/mock_curl.cpp $(TOP_DIR)/rfcMgr/gtest/mocks/tr181_store_writer.cpp + + + +rfcMgr_gtest_CPPFLAGS = $(COMMON_CPPFLAGS) +rfcMgr_gtest_LDADD = $(COMMON_LDADD) +rfcMgr_gtest_CXXFLAGS = $(COMMON_CXXFLAGS) + + +rfcapi_gtest_CPPFLAGS = $(COMMON_CPPFLAGS) +rfcapi_gtest_LDADD = $(COMMON_LDADD) +rfcapi_gtest_CXXFLAGS = $(COMMON_CXXFLAGS) + +tr181api_gtest_CPPFLAGS = $(COMMON_CPPFLAGS) +tr181api_gtest_LDADD = $(COMMON_LDADD) +tr181api_gtest_CXXFLAGS = $(COMMON_CXXFLAGS) + +utils_gtest_CPPFLAGS = $(COMMON_CPPFLAGS) +utils_gtest_LDADD = $(COMMON_LDADD) +utils_gtest_CXXFLAGS = $(COMMON_CXXFLAGS) + diff --git a/rfcMgr/configure.ac b/rfcMgr/gtest/configure.ac similarity index 97% rename from rfcMgr/configure.ac rename to rfcMgr/gtest/configure.ac index ba64e47d..c09a8df4 100644 --- a/rfcMgr/configure.ac +++ b/rfcMgr/gtest/configure.ac @@ -45,7 +45,7 @@ AC_FUNC_REALLOC PKG_CHECK_MODULES([GLIB], [glib-2.0]) # Generate the Makefile - AC_CONFIG_FILES([gtest/Makefile]) + AC_CONFIG_FILES([Makefile]) # Generate the configure script AC_OUTPUT diff --git a/rfcMgr/gtest/gtest_main.cpp b/rfcMgr/gtest/gtest_main.cpp index d0575dae..72415886 100644 --- a/rfcMgr/gtest/gtest_main.cpp +++ b/rfcMgr/gtest/gtest_main.cpp @@ -30,50 +30,20 @@ #include "rfc_common.h" #include "rfc_xconf_handler.h" #include "tr181api.h" +#include "rfc_manager.h" +#include "xconf_handler.h" #include +#include "rfcapi.h" +#include "jsonhandler.h" +#include "tr181_store_writer.h" using namespace std; +using namespace rfc; +#define TR181_LOCAL_STORE_FILE "/opt/secure/RFC/tr181localstore.ini" +#define RFCDEFAULTS_ETC_DIR "/etc/rfcdefaults/" +extern bool tr69hostif_http_server_ready; -void writeToTr181storeFile(const std::string& key, const std::string& value, const std::string& filePath) { - // Check if the file exists and is openable in read mode - std::ifstream fileStream(filePath); - bool found = false; - std::string line; - std::vector lines; - - if (fileStream.is_open()) { - while (getline(fileStream, line)) { - // Check if the current line contains the key - if (line.find(key) != std::string::npos && line.substr(0, key.length()) == key) { - // Replace the line with the new key-value pair - line = key + "=\"" + value + "\""; - found = true; - } - lines.push_back(line); - } - fileStream.close(); - } else { - std::cout << "File does not exist or cannot be opened for reading. It will be created." << std::endl; - } - - // If the key was not found in an existing file or the file did not exist, add it to the vector - if (!found) { - lines.push_back(key + "=\"" + value + "\""); - } - - // Open the file in write mode to overwrite old content or create new file - std::ofstream outFileStream(filePath); - if (outFileStream.is_open()) { - for (const auto& outputLine : lines) { - outFileStream << outputLine << std::endl; - } - outFileStream.close(); - std::cout << "Configuration updated successfully." << std::endl; - } else { - std::cout << "Error opening file for writing." << std::endl; - } -} // Helper function to trim right whitespace or specific characters std::string rtrim(const std::string &s) { @@ -164,7 +134,16 @@ char xconfResp[] = R"({ "tr181.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Telemetry.Version": "2.0.1" }, "featureInstance": "Telemetry_2.0-31099" - } + }, + { + "name": "PartnerId", + "enable": true, + "effectiveImmediate": true, + "configData": { + "tr181.Device.DeviceInfo.X_RDKCENTRAL-COM_Syndication.PartnerId": "comcast" + }, + "featureInstance": "PartnerId" + } ] } })"; @@ -188,6 +167,16 @@ TEST(rfcMgrTest, readRFCParam) { EXPECT_NE(ret, -1); } +TEST(rfcMgrTest, readRFCParam_nullkey) { + int ret = -1; + char data[RFC_VALUE_BUF_SIZE]; + + ret = read_RFCProperty("RDKFirmwareUpgrader", "nullptr", data, 0); + SWLOG_ERROR("read_RFCProperty() return Status %d\n", ret); + + EXPECT_EQ(ret, -1); +} + TEST(rfcMgrTest, checkSpecialChars) { std::string value = "hah$#aga"; bool ret = CheckSpecialCharacters(value); @@ -269,7 +258,7 @@ TEST(rfcMgrTest, getLastProcessedFirmware) { } TEST(rfcMgrTest, getAccountID) { - writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID", "TestAccount", "/opt/secure/RFC/tr181store.ini"); + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID", "TestAccount", "/opt/secure/RFC/tr181store.ini", Quoted); RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); rfcObj->GetAccountID(); EXPECT_EQ(rfcObj->_accountId, "TestAccount"); @@ -329,7 +318,7 @@ TEST(rfcMgrTest, getServURL) { } TEST(rfcMgrTest, getBootstrapXconfUrl) { - writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.XconfUrl", "https://mockxconf", "/opt/secure/RFC/bootstrap.ini"); + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.XconfUrl", "https://mockxconf", "/opt/secure/RFC/bootstrap.ini", Quoted); RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); std::string boot_strap_xconf_url; int ret = rfcObj->GetBootstrapXconfUrl(boot_strap_xconf_url); @@ -340,7 +329,7 @@ TEST(rfcMgrTest, getBootstrapXconfUrl) { } TEST(rfcMgrTest, checkBootstrap) { - writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.XconfUrl", "https://mockxconf", "/opt/secure/RFC/bootstrap.ini"); + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.XconfUrl", "https://mockxconf", "/opt/secure/RFC/bootstrap.ini", Quoted); RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); bool is_Bootstrap = rfcObj->checkBootstrap(BS_STORE_FILENAME, "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.XconfUrl"); @@ -349,7 +338,7 @@ TEST(rfcMgrTest, checkBootstrap) { } TEST(rfcMgrTest, isXconfSelectorSlotProd) { - writeToTr181storeFile(XCONF_SELECTOR_KEY_STR, "prod", "/opt/secure/RFC/tr181store.ini"); + writeToTr181storeFile(XCONF_SELECTOR_KEY_STR, "prod", "/opt/secure/RFC/tr181store.ini", Quoted); RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); bool ret = rfcObj->isXconfSelectorSlotProd(); @@ -359,8 +348,8 @@ TEST(rfcMgrTest, isXconfSelectorSlotProd) { } TEST(rfcMgrTest, getStoredHashAndTime) { - writeToTr181storeFile(RFC_CONFIG_SET_HASH, "TestConfigSetHash", "/opt/secure/RFC/tr181store.ini"); - writeToTr181storeFile(RFC_CONFIG_SET_TIME, "TestConfigSetTime", "/opt/secure/RFC/tr181store.ini"); + writeToTr181storeFile(RFC_CONFIG_SET_HASH, "TestConfigSetHash", "/opt/secure/RFC/tr181store.ini", Quoted); + writeToTr181storeFile(RFC_CONFIG_SET_TIME, "TestConfigSetTime", "/opt/secure/RFC/tr181store.ini", Quoted); RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); std::string hashValue; @@ -401,7 +390,7 @@ TEST(rfcMgrTest, processJsonResponse) { std::string actualContent = readFileContent("/opt/secure/RFC/rfcFeature.list"); // Check if the content of the file is equal to "TEMP_VERSION" - EXPECT_EQ(actualContent, "11=true,ARU:E_29=true,AccountId=true,LSA_End2End=true,SSHWhiteList:E_N=true,Telemetry_2.0-31099=true,"); + EXPECT_EQ(actualContent, "11=true,ARU:E_29=true,AccountId=true,LSA_End2End=true,SSHWhiteList:E_N=true,Telemetry_2.0-31099=true,PartnerId=true,"); } @@ -474,19 +463,443 @@ TEST(rfcMgrTest, cleanAllFile) { } +TEST(rfcMgrTest, checkWhoamiSupport) { + writeToTr181storeFile("WHOAMI_SUPPORT", "true", "/tmp/device.properties", Plain); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + bool result = rfcObj->checkWhoamiSupport(); + delete rfcObj; + EXPECT_EQ(result, true); +} + +TEST(rfcMgrTest, isDebugServicesEnabled) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Identity.DbgServices.Enable", "true", "/opt/secure/RFC/tr181store.ini", Quoted); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + bool result = rfcObj->isDebugServicesEnabled(); + delete rfcObj; + EXPECT_EQ(result,true); +} + +TEST(rfcMgrTest, isMaintenanceEnabled) { + writeToTr181storeFile("ENABLE_MAINTENANCE", "true", "/tmp/device.properties", Plain); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + bool result = rfcObj->isMaintenanceEnabled(); + delete rfcObj; + EXPECT_EQ(result, true); +} + +TEST(rfcMgrTest, GetOsClass) { + writeToTr181storeFile("WHOAMI_SUPPORT", "true", "/tmp/device.properties", Plain); + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.OsClass", "TestOsClass", "/opt/secure/RFC/tr181store.ini", Quoted); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->GetOsClass(); + EXPECT_EQ(rfcObj->_osclass, "TestOsClass"); + delete rfcObj; +} + +TEST(rfcMgrTest, NotifyTelemetry2Value) { + string xconf_server_url = "https://mockxconf/featureControl/getSettings"; + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->NotifyTelemetry2Value("SYST_INFO_RFC_XconflocalURL", xconf_server_url.c_str()); + delete rfcObj; +} + +TEST(rfcMgrTest, GetValidPartnerId) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->rfc_state = Init; + rfcObj->_is_first_request = true; + rfcObj->PreProcessJsonResponse(xconfResp); + rfcObj->GetValidPartnerId(); + EXPECT_EQ(rfcObj->_partner_id, "comcast"); + delete rfcObj; +} + +TEST(rfcMgrTest, CreateXconfHTTPUrl) { + writeToTr181storeFile("WHOAMI_SUPPORT", "true", "/tmp/device.properties", Plain); + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.OsClass", "TestOsClass", "/opt/secure/RFC/tr181store.ini", Quoted); + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID", "4123705941507160514", "/opt/secure/RFC/tr181store.ini", Quoted); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->_RFCKeyAndValueMap[RFC_PARNER_ID_KEY_STR] = "sky"; + rfcObj->_RFCKeyAndValueMap[XCONF_URL_KEY_STR] = "https://xconf.xdp.eu-1.xcal.tv"; + rfcObj->PreProcessJsonResponse(xconfResp); + rfcObj->GetValidPartnerId(); + rfcObj->GetOsClass(); + rfcObj->GetAccountID(); + rfcObj->GetXconfSelect(); + std:stringstream url = rfcObj->CreateXconfHTTPUrl(); + EXPECT_EQ(url.str(), "https://xconf.xdp.eu-1.xcal.tv?estbMacAddress=&firmwareVersion=&env=&model=&manufacturer=&controllerId=2504&channelMapId=2345&VodId=15660&partnerId=sky&osClass=TestOsClass&accountId=4123705941507160514&Experience=&version=2"); + delete rfcObj; +} + +TEST(rfcMgrTest, isConfigValueChange) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Telemetry.Enable", "false", "/opt/secure/RFC/tr181store.ini", Quoted); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + std::string name = "rfc"; + std::string newKey = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Telemetry.Enable"; + std::string newValue = "true"; + std::string currentValue = "false"; + bool result = rfcObj->isConfigValueChange(name, newKey, newValue, currentValue); + EXPECT_EQ(result, true); + delete rfcObj; +} + +TEST(rfcMgrTest, CreateConfigDataValueMap) { + JSON *pJson = ParseJsonStr(xconfResp); + if(pJson) + { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + JSON *features = rfcObj->GetRuntimeFeatureControlJSON(pJson); + if(features) + { + rfcObj->CreateConfigDataValueMap(features); + } + EXPECT_EQ(rfcObj->_RFCKeyAndValueMap.size(), 15); + delete rfcObj; + } +} + +TEST(rfcMgrTest, IsDirectBlocked) { + write_on_file(DIRECT_BLOCK_FILENAME, "currenttime"); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + bool result = rfcObj->IsDirectBlocked(); + EXPECT_EQ(result, true); + delete rfcObj; +} + +TEST(rfcMgrTest, getRFCName) { + JSON *pJson = ParseJsonStr(xconfResp); + if (pJson) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + JSON *features = rfcObj->GetRuntimeFeatureControlJSON(pJson); + + if (features) { + int numFeatures = GetJsonArraySize(features); + + if (numFeatures) { + JSON* feature = GetJsonArrayItem(features, 1); + RuntimeFeatureControlProcessor::RuntimeFeatureControlObject *rfccObj = new RuntimeFeatureControlProcessor::RuntimeFeatureControlObject; + + int result = rfcObj->getRFCName(feature, rfccObj); + EXPECT_EQ(rfccObj->name, "ARU"); + EXPECT_EQ(result, SUCCESS); + + delete rfccObj; + } + } + + delete rfcObj; + } +} + +TEST(rfcMgrTest, getFeatureInstance) { + JSON *pJson = ParseJsonStr(xconfResp); + if (pJson) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + JSON *features = rfcObj->GetRuntimeFeatureControlJSON(pJson); + + if (features) { + int numFeatures = GetJsonArraySize(features); + + if (numFeatures) { + JSON* feature = GetJsonArrayItem(features, 1); + RuntimeFeatureControlProcessor::RuntimeFeatureControlObject *rfccObj = new RuntimeFeatureControlProcessor::RuntimeFeatureControlObject; + + int result = rfcObj->getFeatureInstance(feature, rfccObj); + EXPECT_EQ(rfccObj->featureInstance, "ARU:E_29"); + EXPECT_EQ(result, SUCCESS); + + delete rfccObj; + } + } + + delete rfcObj; + } +} + +TEST(rfcMgrTest, getRFCEnableParam) { + JSON *pJson = ParseJsonStr(xconfResp); + if (pJson) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + JSON *features = rfcObj->GetRuntimeFeatureControlJSON(pJson); + + if (features) { + int numFeatures = GetJsonArraySize(features); + + if (numFeatures) { + JSON* feature = GetJsonArrayItem(features, 1); + RuntimeFeatureControlProcessor::RuntimeFeatureControlObject *rfccObj = new RuntimeFeatureControlProcessor::RuntimeFeatureControlObject; + + int result = rfcObj->getRFCEnableParam(feature, rfccObj); + EXPECT_EQ(rfccObj->enable, true); + EXPECT_EQ(result, SUCCESS); + + delete rfccObj; + } + } + + delete rfcObj; + } +} + + +TEST(rfcMgrTest, getEffectiveImmediateParam) { + JSON *pJson = ParseJsonStr(xconfResp); + if (pJson) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + JSON *features = rfcObj->GetRuntimeFeatureControlJSON(pJson); + + if (features) { + int numFeatures = GetJsonArraySize(features); + + if (numFeatures) { + JSON* feature = GetJsonArrayItem(features, 1); + RuntimeFeatureControlProcessor::RuntimeFeatureControlObject *rfccObj = new RuntimeFeatureControlProcessor::RuntimeFeatureControlObject; + + int result = rfcObj->getEffectiveImmediateParam(feature, rfccObj); + EXPECT_EQ(rfccObj->effectiveImmediate, false); + EXPECT_EQ(result, SUCCESS); + + delete rfccObj; + } + } + + delete rfcObj; + } +} + +TEST(rfcMgrTest, rfcStashStoreParams) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID", "6964630676518908063", "/opt/secure/RFC/tr181store.ini", Quoted); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->rfcStashStoreParams(); + EXPECT_EQ(rfcObj->stashAccountId, "6964630676518908063"); + delete rfcObj; +} + +TEST(rfcMgrTest, rfcStashRetrieveParams) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID", "6964630676518908063", "/opt/secure/RFC/tr181store.ini", Quoted); + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->rfcStashStoreParams(); + rfcObj->rfcStashRetrieveParams(); + EXPECT_EQ(rfcObj->_accountId, "6964630676518908063"); + delete rfcObj; +} + +TEST(rfcMgrTest, clearDB) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->clearDB(); + delete rfcObj; +} + +TEST(rfcMgrTest, clearDBEnd) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->clearDBEnd(); + delete rfcObj; +} + + +TEST(rfcMgrTest, InitDownloadData) { + DownloadData DwnLoc; + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->InitDownloadData(&DwnLoc); + EXPECT_EQ(DwnLoc.pvOut, nullptr); + EXPECT_EQ(DwnLoc.datasize, 0); + EXPECT_EQ(DwnLoc.memsize, 0); + delete rfcObj; +} + +TEST(rfcMgrTest, set_RFCProperty) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + std::string name = "rfc"; + std::string value = "https://rdkautotool.ccp.xcal.tv/featureControl/getSettings"; + std::string xconfURL = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.XconfUrl"; + writeToTr181storeFile(xconfURL, "https://rdkautotool.ccp.xcal.tv/featureControl/getSettings", "/opt/secure/RFC/tr181store.ini", Quoted); + WDMP_STATUS status = rfcObj->set_RFCProperty(name, xconfURL, value); + EXPECT_EQ(status, WDMP_SUCCESS); + delete rfcObj; +} + +TEST(rfcMgrTest, GetXconfSelect) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + rfcObj->_RFCKeyAndValueMap[XCONF_URL_KEY_STR] = "https://xconf.xdp.eu-1.xcal.tv"; + rfcObj->_RFCKeyAndValueMap[XCONF_SELECTOR_KEY_STR] = "automation"; + rfcObj->GetXconfSelect(); + + EXPECT_EQ(rfcObj->rfc_state, Redo); + EXPECT_EQ(rfcObj->rfcSelectorSlot, "19"); + delete rfcObj; + +} + +TEST(rfcMgrTest, getJRPCTokenData) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + char post_data[] = "{\"jsonrpc\":\"2.0\",\"id\":\"3\",\"method\":\"org.rdk.AuthService.getExperience\", \"params\":{}}"; + char token_str[] = "id"; + int result = rfcObj->getJRPCTokenData(token_str, post_data , sizeof(token_str)); + + EXPECT_EQ(result , 0); + delete rfcObj; + +} + +TEST(rfcMgrTest, isStateRedSupported) { + int ret = isStateRedSupported(); + EXPECT_EQ(ret , 0); +} -TEST(rfcMgrTest, getDefaultValue) { - - const char* pcParameterName ="Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable"; - char *pcCallerID ="rfcdefaults"; - TR181_ParamData_t pstParamData; +TEST(rfcMgrTest, isInStateRed) { + int ret = isInStateRed(); + EXPECT_EQ(ret , 0); +} - tr181ErrorCode_t status = getDefaultValue(pcCallerID,pcParameterName,&pstParamData); - EXPECT_EQ(status, 0); - +TEST(rfcMgrTest, executeCommandAndGetOutput) { + const char *pArgs; + std::string result; + int ret = executeCommandAndGetOutput(eWpeFrameworkSecurityUtility, pArgs, result); + EXPECT_EQ(ret , 0); } +TEST(rfcMgrTest, executeCommandAndGetOutput_eRdkSsaCli) { + const char *pArgs = NULL; + std::string result; + int ret = executeCommandAndGetOutput(eRdkSsaCli, pArgs, result); + EXPECT_EQ(ret , -1); +} +TEST(rfcMgrTest, getRebootRequirement) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + bool result = rfcObj->getRebootRequirement(); + EXPECT_EQ(result, false); + delete rfcObj; +} + +TEST(rfcMgrTest, ProcessXconfUrl) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + std::string xconfURL = "https://xconf.xdp.eu-1.xcal.tv"; + int result = rfcObj->ProcessXconfUrl(xconfURL.c_str()); + EXPECT_EQ(result , 0); + delete rfcObj; +} + +TEST(rfcMgrTest, updateTR181File) { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + std::list paramList; + std::string newKey = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable"; + std::string newValue = "true"; + std::string data = "TR181: " + newKey + " " + newValue; + int result ; + paramList.push_back(data); + rfcObj->updateTR181File(TR181_FILE_LIST, paramList); + EXPECT_EQ(paramList.size() , 0); + delete rfcObj; +} + +TEST(rfcMgrTest, processXconfResponseConfigDataPart) { + JSON *pJson = ParseJsonStr(xconfResp); + if(pJson) + { + RuntimeFeatureControlProcessor *rfcObj = new RuntimeFeatureControlProcessor(); + JSON *features = rfcObj->GetRuntimeFeatureControlJSON(pJson); + JSON *bkp_features = features; + if(bkp_features) + { + rfcObj->processXconfResponseConfigDataPart(bkp_features); + } + delete rfcObj; + } +} + +TEST(rfcMgrTest, CheckDeviceIsOFFline) { + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + rfc::DeviceStatus status = rfcmgrObj->CheckDeviceIsOnline(); + EXPECT_EQ(status, RFCMGR_DEVICE_OFFLINE); + delete rfcmgrObj; +} + +TEST(rfcMgrTest, CheckDeviceIsOnline) { + write_on_file(GATEWAYIP_FILE, "IPV4 8.8.4.4"); + write_on_file(DNS_RESOLV_FILE, "nameserver 2.4.6.8"); + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + rfc::DeviceStatus status = rfcmgrObj->CheckDeviceIsOnline(); + EXPECT_EQ(status, RFCMGR_DEVICE_ONLINE); + delete rfcmgrObj; +} + +TEST(rfcMgrTest, RFCManagerPostProcess) { + write_on_file(RFC_MGR_IPTBLE_INIT_SCRIPT, "executing the iptables init script"); + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + int result = rfcmgrObj->RFCManagerPostProcess(); + EXPECT_EQ(result, 0); +} + +TEST(rfcMgrTest, CheckIProuteConnectivity) { + write_on_file(GATEWAYIP_FILE, "IPV4 8.8.4.4"); + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + int result = rfcmgrObj->CheckIProuteConnectivity(GATEWAYIP_FILE); + EXPECT_EQ(result, true); + delete rfcmgrObj; +} + +TEST(rfcMgrTest, removed_GatewayIPFile) { + std::string cmd = std::string("rm -rf ") + GATEWAYIP_FILE; + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + int result = rfcmgrObj->CheckIProuteConnectivity(GATEWAYIP_FILE); + EXPECT_EQ(result, true); + delete rfcmgrObj; +} + +TEST(rfcMgrTest, IsIarmBusConnected) { + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + bool result = rfcmgrObj->IsIarmBusConnected(); + EXPECT_EQ(result, true); + delete rfcmgrObj; +} + +TEST(rfcMgrTest, InitializeIARM) { + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + bool result = true; + rfcmgrObj->InitializeIARM(); + EXPECT_EQ(result, true); + delete rfcmgrObj; +} + +TEST(rfcMgrTest, isDnsResolve) { + write_on_file(DNS_RESOLV_FILE, "nameserver 2.4.6.8"); + int result = isDnsResolve(DNS_RESOLV_FILE); + EXPECT_EQ(result, true); +} + +TEST(rfcMgrTest, removed_DnsResolveFile) { + std::string cmd = std::string("rm -rf ") + DNS_RESOLV_FILE; + int status = system(cmd.c_str()); + EXPECT_EQ(status, 0); + int result = isDnsResolve(DNS_RESOLV_FILE); + EXPECT_EQ(result, false); +} + + +TEST(rfcMgrTest, RFCManagerProcessXconfRequest) { + rfc::RFCManager *rfcmgrObj = new rfc::RFCManager(); + int result = rfcmgrObj->RFCManagerProcessXconfRequest(); + EXPECT_EQ(result, FAILURE); + delete rfcmgrObj; +} + +TEST(rfcMgrTest, initializeXconf) { + write_on_file("/tmp/partnerId3.dat", "default-parter"); + write_on_file("/tmp/estbmacfile", "01:23:45:67:89:ab"); + write_on_file("/tmp/version.txt", "imagename:TestImage"); + write_on_file("/tmp/device.properties", "MODEL_NUM=SKXI11ADS"); + write_on_file("/tmp/device.properties", "BUILD_TYPE=dev"); + write_on_file("/tmp/.manufacturer", "TestMFRname"); + xconf::XconfHandler *xconfObj = new xconf::XconfHandler(); + int resutl = xconfObj->initializeXconfHandler(); + EXPECT_EQ(xconfObj->_estb_mac_address, "01:23:45:67:89:ab"); + EXPECT_EQ(xconfObj->_partner_id, "default-parter"); + EXPECT_EQ(xconfObj->_firmware_version, "TestImage"); + EXPECT_EQ(xconfObj->_model_number, "SKXI11ADS"); + EXPECT_EQ(xconfObj->_build_type_str, "dev"); + EXPECT_EQ(xconfObj->_manufacturer, "TestMFRname"); + delete xconfObj; +} GTEST_API_ int main(int argc, char *argv[]){ ::testing::InitGoogleTest(&argc, argv); diff --git a/rfcMgr/gtest/gtest_rfcapi.cpp b/rfcMgr/gtest/gtest_rfcapi.cpp new file mode 100644 index 00000000..4d1e87db --- /dev/null +++ b/rfcMgr/gtest/gtest_rfcapi.cpp @@ -0,0 +1,169 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2018 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rfcapi.h" +#include "tr181_store_writer.h" + +using namespace std; +#define RFCDEFAULTS_ETC_DIR "/etc/rfcdefaults/" + +#ifdef GTEST_ENABLE +extern size_t (*getWriteCurlResponse(void))(void *ptr, size_t size, size_t nmemb, std::string stream); +#endif + +TEST(rfcapiTest, init_rfcdefaults) { + bool result = init_rfcdefaults(); + EXPECT_EQ(result, true); +} + +TEST(rfcapiTest, init_rfcdefaults_removed_etc_dir) { + std::string cmd = std::string("rm -rf ") + RFCDEFAULTS_ETC_DIR; + int status = system(cmd.c_str()); + EXPECT_EQ(status, 0); + bool result = init_rfcdefaults(); + EXPECT_EQ(result, false); +} + +TEST(rfcapiTest, writeCurlResponse) { + const char* input = "MockCurlData"; + size_t size = 1; + size_t nmemb = strlen(input); + std::string response; + size_t written = getWriteCurlResponse()((void*)input, size, nmemb, response); + EXPECT_EQ(written, nmemb); +} + +TEST(rfcapiTest, getRFCParameter) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.LogServerUrl", "logs.xcal.tv", "/opt/secure/RFC/tr181store.ini", Plain); + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.LogUpload.LogServerUrl"; + char *pcCallerID = "rfcdefaults"; + RFC_ParamData_t pstParamData; + WDMP_STATUS result = getRFCParameter(pcCallerID, pcParameterName, &pstParamData); + EXPECT_STREQ(pstParamData.value, "logs.xcal.tv"); + EXPECT_EQ(result, WDMP_SUCCESS); +} + +TEST(rfcapiTest, getRFCParameter_rfcdefault) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.LowSpeed", "12800", "/opt/secure/RFC/bootstrap.ini", Plain); + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.LowSpeed"; + char *pcCallerID = "rfcdefaults"; + RFC_ParamData_t pstParamData; + WDMP_STATUS result = getRFCParameter(pcCallerID, pcParameterName, &pstParamData); + EXPECT_EQ(result, WDMP_SUCCESS); + EXPECT_STREQ(pstParamData.value, "12800"); +} + +TEST(rfcapiTest, getRFCParameter_HTTP) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable"; + char *pcCallerID = "rfcdefaults"; + write_on_file("/tmp/.tr69hostif_http_server_ready", ".tr69hostif_http_server_ready"); + RFC_ParamData_t pstParamData; + WDMP_STATUS result = getRFCParameter(pcCallerID, pcParameterName, &pstParamData); + EXPECT_STREQ(pstParamData.value, "true"); + EXPECT_EQ(result, WDMP_SUCCESS); +} + +TEST(rfcapiTest, getRFCParameter_wildcard) { + const char* pcParameterName = "Device.DeviceInfo."; + char *pcCallerID = "rfcdefaults"; + RFC_ParamData_t pstParamData; + WDMP_STATUS result = getRFCParameter(pcCallerID, pcParameterName, &pstParamData); + EXPECT_EQ(result, WDMP_FAILURE); +} + +TEST(rfcapiTest, setRFCParameter_wildcard) { + const char* pcParameterName = "Device.DeviceInfo."; + char *pcCallerID = "rfcdefaults"; + const char* pcParameterValue = NULL; + RFC_ParamData_t pstParamData; + WDMP_STATUS result = setRFCParameter(pcCallerID, pcParameterName, pcParameterValue, WDMP_STRING); + EXPECT_EQ(result, WDMP_FAILURE); +} + +TEST(rfcapiTest, setRFCParameter) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.SsrUrl"; + char *pcCallerID = "rfcdefaults"; + const char* pcParameterValue = "https://ssr.ccp.xcal.tv"; + RFC_ParamData_t pstParamData; + WDMP_STATUS result = setRFCParameter(pcCallerID, pcParameterName, pcParameterValue, WDMP_STRING); + EXPECT_EQ(result, WDMP_SUCCESS); +} + +TEST(rfcapiTest, getRFCErrorString) { + EXPECT_STREQ(getRFCErrorString(WDMP_SUCCESS), " Success"); + EXPECT_STREQ(getRFCErrorString(WDMP_FAILURE), " Request Failed"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_TIMEOUT), " Request Timeout"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_PARAMETER_NAME), " Invalid Parameter Name"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_PARAMETER_TYPE), " Invalid Parameter Type"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_PARAMETER_VALUE), " Invalid Parameter Value"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_NOT_WRITABLE), " Not writable"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_SETATTRIBUTE_REJECTED), " SetAttribute Rejected"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_NAMESPACE_OVERLAP), " Namespace Overlap"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_UNKNOWN_COMPONENT), " Unknown Component"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_NAMESPACE_MISMATCH), " Namespace Mismatch"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_UNSUPPORTED_NAMESPACE), " Unsupported Namespace"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_DP_COMPONENT_VERSION_MISMATCH), " Component Version Mismatch"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_PARAM), " Invalid Param"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_UNSUPPORTED_DATATYPE), " Unsupported Datatype"); + EXPECT_STREQ(getRFCErrorString(WDMP_STATUS_RESOURCES), " Resources"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_WIFI_BUSY), " Wifi Busy"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_ATTRIBUTES), " Invalid Attributes"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_WILDCARD_NOT_SUPPORTED), " Wildcard Not Supported"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_SET_OF_CMC_OR_CID_NOT_SUPPORTED), " Set of CMC or CID Not Supported"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_VALUE_IS_EMPTY), " Value is Empty"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_VALUE_IS_NULL), " Value is Null"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_DATATYPE_IS_NULL), " Datatype is Null"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_CMC_TEST_FAILED), " CMC Test Failed"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_NEW_CID_IS_MISSING), " New CID is Missing"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_CID_TEST_FAILED), " CID Test Failed"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_SETTING_CMC_OR_CID), " Setting CMC or CID"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_INPUT_PARAMETER), " Invalid Input Parameter"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_ATTRIBUTES_IS_NULL), " Attributes is Null"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_NOTIFY_IS_NULL), " Notify is Null"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_WIFI_INDEX), " Invalid Wifi Index"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INVALID_RADIO_INDEX), " Invalid Radio Index"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_ATOMIC_GET_SET_FAILED), " Atomic Get Set Failed"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_METHOD_NOT_SUPPORTED), " Method Not Supported"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_INTERNAL_ERROR), " Internal Error"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_DEFAULT_VALUE), " Default Value"); + EXPECT_STREQ(getRFCErrorString(WDMP_ERR_MAX_REQUEST), " Unknown error code"); +} + +TEST(rfcapiTest, isRFCEnabled) { + bool result = isRFCEnabled("Instance"); + EXPECT_EQ(result, false); +} + +GTEST_API_ int main(int argc, char *argv[]){ + ::testing::InitGoogleTest(&argc, argv); + + cout << "Starting GTEST===========================>" << endl; + return RUN_ALL_TESTS(); +} diff --git a/rfcMgr/gtest/gtest_tr181api.cpp b/rfcMgr/gtest/gtest_tr181api.cpp new file mode 100644 index 00000000..4e712246 --- /dev/null +++ b/rfcMgr/gtest/gtest_tr181api.cpp @@ -0,0 +1,204 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2018 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tr181api.h" +#include "tr181_store_writer.h" + +using namespace std; + +#define TR181_LOCAL_STORE_FILE "/opt/secure/RFC/tr181localstore.ini" +#define RFCDEFAULTS_ETC_DIR "/etc/rfcdefaults/" + +TEST(tr181apiTest, getTR181ErrorString) { + EXPECT_STREQ(getTR181ErrorString(tr181Success) , " Success"); + EXPECT_STREQ(getTR181ErrorString(tr181InternalError) , " Internal Error"); + EXPECT_STREQ(getTR181ErrorString(tr181InvalidParameterName), " Invalid Parameter Name"); + EXPECT_STREQ(getTR181ErrorString(tr181InvalidParameterValue), " Invalid Parameter Value"); + EXPECT_STREQ(getTR181ErrorString(tr181Failure), " Failure"); + EXPECT_STREQ(getTR181ErrorString(tr181InvalidType), " Invalid type"); + EXPECT_STREQ(getTR181ErrorString(tr181NotWritable), " Not writable"); + EXPECT_STREQ(getTR181ErrorString(tr181ValueIsEmpty), " Value is empty"); + EXPECT_STREQ(getTR181ErrorString(tr181ValueIsNull), " Value is Null"); + EXPECT_STREQ(getTR181ErrorString(tr181DefaultValue), " Default Value"); +} + +TEST(tr181apiTest, getType) { + EXPECT_EQ(getType(WDMP_STRING), TR181_STRING); + EXPECT_EQ(getType(WDMP_INT), TR181_INT); + EXPECT_EQ(getType(WDMP_UINT), TR181_UINT); + EXPECT_EQ(getType(WDMP_BOOLEAN), TR181_BOOLEAN); + EXPECT_EQ(getType(WDMP_DATETIME), TR181_DATETIME); + EXPECT_EQ(getType(WDMP_BASE64), TR181_BASE64); + EXPECT_EQ(getType(WDMP_LONG), TR181_LONG); + EXPECT_EQ(getType(WDMP_ULONG), TR181_ULONG); + EXPECT_EQ(getType(WDMP_FLOAT), TR181_FLOAT); + EXPECT_EQ(getType(WDMP_DOUBLE), TR181_DOUBLE); + EXPECT_EQ(getType(WDMP_BYTE), TR181_BYTE); + EXPECT_EQ(getType(WDMP_NONE), TR181_NONE); +} + +TEST(tr181apiTest, getErrorCode) { + EXPECT_EQ(getErrorCode(WDMP_SUCCESS), tr181Success); + EXPECT_EQ(getErrorCode(WDMP_FAILURE), tr181Failure); + EXPECT_EQ(getErrorCode(WDMP_ERR_TIMEOUT), tr181Timeout); + EXPECT_EQ(getErrorCode(WDMP_ERR_INVALID_PARAMETER_NAME), tr181InvalidParameterName); + EXPECT_EQ(getErrorCode(WDMP_ERR_INVALID_PARAMETER_VALUE), tr181InvalidParameterValue); + EXPECT_EQ(getErrorCode(WDMP_ERR_INVALID_PARAMETER_TYPE), tr181InvalidType); + EXPECT_EQ(getErrorCode(WDMP_ERR_NOT_WRITABLE), tr181NotWritable); + EXPECT_EQ(getErrorCode(WDMP_ERR_VALUE_IS_EMPTY), tr181ValueIsEmpty); + EXPECT_EQ(getErrorCode(WDMP_ERR_VALUE_IS_NULL), tr181ValueIsNull); + EXPECT_EQ(getErrorCode(WDMP_ERR_DEFAULT_VALUE), tr181DefaultValue); + EXPECT_EQ(getErrorCode(WDMP_ERR_INTERNAL_ERROR), tr181InternalError); +} + +TEST(tr181apiTest, getDefaultValue) { + const char* dirPath = "/etc/rfcdefaults/"; + int result = mkdir(dirPath, 0755); + EXPECT_EQ(result, 0); + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable", "false", "/etc/rfcdefaults/rfcdefaults.ini", Plain); + const char* pcParameterName ="Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable"; + char *pcCallerID = "rfcdefaults"; + TR181_ParamData_t pstParamData; + tr181ErrorCode_t status = getDefaultValue(pcCallerID,pcParameterName,&pstParamData); + EXPECT_EQ(status, tr181Success); + EXPECT_STREQ(pstParamData.value, "false"); +} + +TEST(tr181apiTest, getDefaultValue_callerIDNULL) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable"; + char *pcCallerID = NULL; + TR181_ParamData_t pstParamData; + tr181ErrorCode_t status = getDefaultValue(pcCallerID,pcParameterName,&pstParamData); + EXPECT_EQ(status, tr181Failure); +} + +TEST(tr181apiTest, getValue) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable", "true", TR181_LOCAL_STORE_FILE, Plain); + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.Enable"; + TR181_ParamData_t pstParam; + tr181ErrorCode_t status = getValue(TR181_LOCAL_STORE_FILE, pcParameterName, &pstParam); + EXPECT_EQ(status, tr181Success); + EXPECT_STREQ(pstParam.value, "true"); +} + +TEST(tr181apiTest, getEmptyValue) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.WebCfgData", "", TR181_LOCAL_STORE_FILE, Plain); + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.WebCfgData"; + TR181_ParamData_t pstParam; + tr181ErrorCode_t status = getValue(TR181_LOCAL_STORE_FILE, pcParameterName, &pstParam); + EXPECT_EQ(status, tr181ValueIsEmpty); +} + +TEST(tr181apiTest, getValueInvalidFile) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.IssueType"; + TR181_ParamData_t pstParam; + tr181ErrorCode_t status = getValue("/opt/secure/RFC/tr181LLOCALSTORE.ini", pcParameterName, &pstParam); + EXPECT_EQ(status, tr181Failure); +} + +TEST(tr181apiTest, setValue) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.PartnerName"; + const char* pcParamValue = "comcast"; + tr181ErrorCode_t status = setValue(pcParameterName, pcParamValue); + EXPECT_EQ(status, tr181Success); +} + +TEST(tr181apiTest, setLocalParam) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.PartnerProductName"; + char *pcCallerID = "rfcdefaults"; + const char* pcParamValue = "Xfinity"; + tr181ErrorCode_t status = setLocalParam(pcCallerID, pcParameterName, pcParamValue); + EXPECT_EQ(status, tr181Success); +} + +TEST(tr181apiTest, clearLocalParam) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.PartnerProductName"; + char *pcCallerID = "rfcdefaults"; + const char* pcParamValue = "Xfinity"; + tr181ErrorCode_t status = clearLocalParam(pcCallerID, pcParameterName); + EXPECT_EQ(status, tr181Success); +} + +TEST(tr181apiTest, clearLocalParamNotExist) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.FWUpdate.Enable"; + char *pcCallerID = "rfcdefaults"; + tr181ErrorCode_t status = clearLocalParam(pcCallerID, pcParameterName); + EXPECT_EQ(status, tr181Success); +} + +TEST(tr181apiTest, getLocalParam) { + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.PartnerName"; + char *pcCallerID = "rfcdefaults"; + TR181_ParamData_t pstParamData; + tr181ErrorCode_t status = getLocalParam(pcCallerID, pcParameterName, &pstParamData); + EXPECT_STREQ(pstParamData.value, "comcast"); + EXPECT_EQ(status, tr181Success); +} + +TEST(tr181apiTest, getLocalParamDefault) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.Enable", "true", "/etc/rfcdefaults/rfcdefaults.ini", Plain); + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.RDKRemoteDebugger.Enable"; + char *pcCallerID = "rfcdefaults"; + TR181_ParamData_t pstParamData; + tr181ErrorCode_t status = getLocalParam(pcCallerID, pcParameterName, &pstParamData); + EXPECT_STREQ(pstParamData.value, "true"); + EXPECT_EQ(status, tr181Success); +} + +TEST(tr181apiTest, getParam) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IncrementalCDL.Enable", "true", "/opt/secure/RFC/tr181store.ini", Plain); + const char* pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.IncrementalCDL.Enable"; + char *pcCallerID = "rfcdefaults"; + TR181_ParamData_t pstParamData; + tr181ErrorCode_t status = getParam(pcCallerID, pcParameterName, &pstParamData); + EXPECT_EQ(status, tr181Success); + EXPECT_STREQ(pstParamData.value, "true"); +} + +TEST(tr181apiTest, CallclearParam) { + char * const pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable"; + char *pcCallerID = "rfcdefaults"; + tr181ErrorCode_t status = clearParam(pcCallerID, pcParameterName); + EXPECT_EQ(status, tr181Success); +} + +TEST(tr181apiTest, CallsetParam) { + char * const pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SWDLSpLimit.TopSpeed"; + char *pcCallerID = "rfcdefaults"; + const char* pcParameterValue = "1280000"; + tr181ErrorCode_t status = setParam(pcCallerID, pcParameterName, pcParameterValue); + EXPECT_EQ(status, tr181Success); +} + +GTEST_API_ int main(int argc, char *argv[]){ + ::testing::InitGoogleTest(&argc, argv); + + cout << "Starting GTEST===========================>" << endl; + return RUN_ALL_TESTS(); +} diff --git a/rfcMgr/gtest/gtest_utils.cpp b/rfcMgr/gtest/gtest_utils.cpp new file mode 100644 index 00000000..a109f1f2 --- /dev/null +++ b/rfcMgr/gtest/gtest_utils.cpp @@ -0,0 +1,204 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2018 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tr181api.h" +#include +#include "rfcapi.h" +#include "jsonhandler.h" +#include "tr181_store_writer.h" + +using namespace std; + +#ifdef GTEST_ENABLE +extern bool (*getGetParamTypeFunc())(char * const, DATA_TYPE *); +extern DATA_TYPE (*getConvertTypeFunc())(char); +extern int (*getClearAttributeFunc())(char * const); +extern int (*getSetAttributeFunc())(char * const, char, char *); +extern int (*getGetAttributeFunc())(char * const); +extern size_t (*getWriteCurlResponse(void))(void *ptr, size_t size, size_t nmemb, std::string stream); +extern int (*getparseargsFunc())(int argc, char * argv[]); +#endif + +TEST(utilsTest, getParamType) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable", "true", "/opt/secure/RFC/tr181store.ini", Quoted); + char * const pcParameterName = const_cast("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable"); + DATA_TYPE paramType; + bool status = getGetParamTypeFunc()(pcParameterName, ¶mType); + EXPECT_EQ(status, true); +} + +TEST(utilsTest, CallconvertType) { + char itype = 'i'; + DATA_TYPE status = getConvertTypeFunc()(itype); + EXPECT_EQ(status, WDMP_INT); + + char stype = 's'; + status = getConvertTypeFunc()(stype); + EXPECT_EQ(status, WDMP_STRING); + + char btype = 'b'; + status = getConvertTypeFunc()(btype); + EXPECT_EQ(status, WDMP_BOOLEAN); + + char ftype = 'f'; + status = getConvertTypeFunc()(ftype); + EXPECT_EQ(status, WDMP_INT); +} + +TEST(utilsTest, CallgetAttribute) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable", "true", "/opt/secure/RFC/tr181store.ini", Quoted); + char * const pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable"; + int status = getGetAttributeFunc()(pcParameterName); + EXPECT_EQ(status, 0); +} + +TEST(utilsTest, CallsetAttribute) { + char * const pcParameterName = const_cast("Device.DeviceInfo.X_RDKCENTRAL-COM_xOpsDeviceMgmt.ForwardSSH.Enable"); + char * value = const_cast("false"); + int status = getSetAttributeFunc()(pcParameterName, 'b', value); + EXPECT_EQ(status, 0); +} + +TEST(utilsTest, CallclearAttribute) { + char * const pcParameterName = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable"; + int status = getClearAttributeFunc()(pcParameterName); + EXPECT_EQ(status, 0); +} + +TEST(utilsTest, Callparseargs) { + char* argv[] = { (char*)"tr181", (char*)"-n", (char*)"localOnly" }; + int argc = 3; + int status = getparseargsFunc()(argc, argv); + EXPECT_EQ(status, 0); +} + +TEST(utilsTest, CallsetAttribute_args) { + char * const pcParameterName = const_cast("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.MOCASSH.Enable"); + char * value = const_cast("false"); + char* argv[] = { (char*)"tr181", (char*)"-n", (char*)"localOnly" }; + int argc = 3; + int args_status = getparseargsFunc()(argc, argv); + int status = getSetAttributeFunc()(pcParameterName, 'b', value); + EXPECT_EQ(status, 0); +} + +TEST(utilsTest, CallgetAttribute_args) { + writeToTr181storeFile("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DHCPv6Client.Enable", "true", "/opt/secure/RFC/tr181localstore.ini", Quoted); + char * const pcParameterName = const_cast("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.DHCPv6Client.Enable"); + char *pcCallerID ="rfcdefaults"; + char * value = const_cast("false"); + char* argv[] = { (char*)"tr181", (char*)"-n", (char*)"localOnly" }; + int argc = 3; + int args_status = getparseargsFunc()(argc, argv); + int status = getGetAttributeFunc()(pcParameterName); + EXPECT_EQ(status, 0); +} + +TEST(utilsTest, CallreadFromFile) { + std::string jsonString = R"({"jsonrpc":"2.0","id":3,"result":{"experience":"X1","success":true}})"; + write_on_file("/tmp/test.json", jsonString); + char *result = readFromFile("/tmp/test.json"); + EXPECT_NE(result, nullptr); + + delete [] result; + std::remove("/tmp/test.json"); +} + +TEST(utilsTest, CallgetArrayNode) { + const char* jsonStr = R"({"jsonrpc":"2.0","id":3,"result":{"experience":"X1","success":true,"features":["A","B","C"]}})"; + cJSON* root = cJSON_Parse(jsonStr); + EXPECT_NE(root, nullptr); + + cJSON* arrayNode = getArrayNode(root); + EXPECT_NE(arrayNode, nullptr); + EXPECT_EQ(cJSON_GetArraySize(arrayNode), 3); + + cJSON_Delete(root); +} + +TEST(utilsTest, iterateAndSaveArrayNodes) { + + const char* jsonStr = R"({"featureControl":{"features":[{"name":"SNMP2WL","effectiveImmediate":false,"enable":true,"configData":{},"listType":"SNMPIPv4","listSize":2,"SNMP IP4 WL":["128.82.34.17","10.0.0.32/6"]}]}})"; + const char *absolutePath = "/opt/secure/RFC/.RFC_LIST_%s.ini"; + int count = iterateAndSaveArrayNodes(absolutePath, jsonStr); + EXPECT_EQ(count, 1); +} + +TEST(utilsTest, saveToFile) { + const char *format = "/opt/secure/RFC/.RFC_LIST_%s.ini"; + const char *name = "SNMP2WL"; + cJSON *array = cJSON_CreateArray(); + cJSON_AddItemToArray(array, cJSON_CreateString("128.82.34.17")); + cJSON_AddItemToArray(array, cJSON_CreateString("10.0.0.32/6")); + int status = saveToFile(array, format, name); + EXPECT_EQ(status, 1); + + cJSON_Delete(array); +} + +TEST(utilsTest, saveIfNodeContainsLists) { + const char *absolutePath = "/opt/secure/RFC/.RFC_LIST_%s.ini"; + const char *name = "SNMP2WL"; + cJSON *node = cJSON_CreateObject(); + cJSON_AddStringToObject(node, "name", "SNMP2WL"); + cJSON_AddStringToObject(node, "listType", "SNMPIPv4"); + cJSON *array = cJSON_CreateArray(); + cJSON_AddItemToArray(array, cJSON_CreateString("128.82.34.17")); + cJSON_AddItemToArray(array, cJSON_CreateString("10.0.0.32/6")); + cJSON_AddItemToObject(node, "SNMP IP4 WL", array); + int status = saveIfNodeContainsLists(node, absolutePath); + EXPECT_EQ(status, 1); + + cJSON_Delete(node); +} + +TEST(utilsTest, getFilePath) { + char *path = getFilePath(); + std::string expected = "/opt/secure/RFC/.RFC_LIST_%s.ini"; + EXPECT_STREQ(path, expected.c_str()); + + delete[] path; +} + +TEST(utilsTest, cleanAllFiles) { + std::remove("/opt/secure/RFC/tr181store.ini"); + std::remove("/opt/secure/RFC/tr181localstore.ini"); + std::remove("/opt/secure/RFC/bootstrap.ini"); + std::remove("/etc/rfcdefaults/rfcdefaults.ini"); + std::remove("/opt/secure/RFC/.RFC_LIST_SNMP2WL.ini"); +} + + +GTEST_API_ int main(int argc, char *argv[]){ + ::testing::InitGoogleTest(&argc, argv); + + cout << "Starting GTEST===========================>" << endl; + return RUN_ALL_TESTS(); +} diff --git a/rfcMgr/gtest/mocks/mock_curl.cpp b/rfcMgr/gtest/mocks/mock_curl.cpp new file mode 100644 index 00000000..fdbbcb2a --- /dev/null +++ b/rfcMgr/gtest/mocks/mock_curl.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +long simulated_http_code = 200; +CURLcode simulated_curl_result = CURLE_OK; +std::string simulated_response_body = R"({ + "parameters": [{ + "name": "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.Airplay.Enable", + "value": "true", + "dataType": 3, + "parameterCount": 1, + "message": "Success" + }], + "statusCode": 0 +})"; + +// Globals to store the user-provided write callback and userdata +static curl_write_callback g_write_callback = nullptr; +static void* g_write_data = nullptr; + +extern "C" { + +CURLcode curl_easy_setopt(CURL* curl, CURLoption option, ...) { + va_list args; + va_start(args, option); + + if (option == CURLOPT_WRITEFUNCTION) { + g_write_callback = va_arg(args, curl_write_callback); + } else if (option == CURLOPT_WRITEDATA) { + g_write_data = va_arg(args, void*); + } else { + // Ignore other options for now + (void)va_arg(args, void*); + } + + va_end(args); + return CURLE_OK; +} + +CURLcode curl_easy_perform(CURL* curl) { + if (g_write_callback && !simulated_response_body.empty()) { + // Call the write callback exactly like libcurl would: + // size=1, nmemb=length of data + g_write_callback(const_cast(simulated_response_body.c_str()), 1, simulated_response_body.size(), g_write_data); + } + return simulated_curl_result; +} + +CURLcode curl_easy_getinfo(CURL* curl, CURLINFO info, ...) { + va_list args; + va_start(args, info); + + if (info == CURLINFO_RESPONSE_CODE) { + long* p = va_arg(args, long*); + *p = simulated_http_code; + } + + va_end(args); + return CURLE_OK; +} + +} diff --git a/rfcMgr/gtest/mocks/tr181_store_writer.cpp b/rfcMgr/gtest/mocks/tr181_store_writer.cpp new file mode 100644 index 00000000..d9b7aac9 --- /dev/null +++ b/rfcMgr/gtest/mocks/tr181_store_writer.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include "tr181_store_writer.h" + +void writeToTr181storeFile(const std::string& key, const std::string& value, const std::string& filePath, ValueFormat format) { + // Check if the file exists and is openable in read mode + std::ifstream fileStream(filePath); + bool found = false; + std::string line; + std::vector lines; + + std::string formattedLine = (format == Quoted) + ? key + "=\"" + value + "\"" + : key + "=" + value; + + if (fileStream.is_open()) { + while (getline(fileStream, line)) { + // Check if the current line contains the key + if (line.find(key) != std::string::npos && line.substr(0, key.length()) == key) { + // Replace the line with the new key-value pair + line = formattedLine; + found = true; + } + lines.push_back(line); + } + fileStream.close(); + } else { + std::cout << "File does not exist or cannot be opened for reading. It will be created." << std::endl; + } + + // If the key was not found in an existing file or the file did not exist, add it to the vector + if (!found) { + lines.push_back(formattedLine); + } + + // Open the file in write mode to overwrite old content or create new file + std::ofstream outFileStream(filePath); + if (outFileStream.is_open()) { + for (const auto& outputLine : lines) { + outFileStream << outputLine << std::endl; + } + outFileStream.close(); + std::cout << "Configuration updated successfully." << std::endl; + } else { + std::cout << "Error opening file for writing." << std::endl; + } +} + +void write_on_file(const std::string& filePath, const std::string& data) +{ + std::ofstream outfile(filePath, std::ios::app); + if (outfile.is_open()) { + std::cout << "File Open" << std::endl; + outfile << data<< "\n" ; + std::cout << "Writing in file" << std::endl; + outfile.close(); + std::cout << "File written successfully." << std::endl; + } else { + std::cerr << "Unable to open file." << std::endl ; + } + +} + diff --git a/rfcMgr/gtest/mocks/tr181_store_writer.h b/rfcMgr/gtest/mocks/tr181_store_writer.h new file mode 100644 index 00000000..4cd1abaa --- /dev/null +++ b/rfcMgr/gtest/mocks/tr181_store_writer.h @@ -0,0 +1,22 @@ +#ifndef TR181_STORE_WRITER_H +#define TR181_STORE_WRITER_H + +#include + +enum ValueFormat { + Plain, // key=value + Quoted // key="value" +}; + +/** + * @brief Writes or updates a key="value" pair in a flat TR-181-style config file. + * + * @param key The TR-181 parameter name (e.g., "Device.DeviceInfo...") + * @param value The string value to be assigned (e.g., "true") + * @param filePath Path to the config file to read/update/create + */ +void writeToTr181storeFile(const std::string& key, const std::string& value, const std::string& filePath, ValueFormat format); + +void write_on_file(const std::string& filePath, const std::string& data); + +#endif // TR181_STORE_WRITER_H diff --git a/rfcMgr/mtlsUtils.h b/rfcMgr/mtlsUtils.h index 20618edb..dedf323a 100644 --- a/rfcMgr/mtlsUtils.h +++ b/rfcMgr/mtlsUtils.h @@ -51,6 +51,10 @@ extern "C" { #define STATE_RED_SPRT_FILE "" #define STATEREDFLAG "" +#if defined(GTEST_ENABLE) +int isStateRedSupported(void); +int isInStateRed(void); +#endif int getMtlscert(MtlsAuth_t *sec); #ifdef __cplusplus diff --git a/rfcMgr/rfc_main.cpp b/rfcMgr/rfc_main.cpp index cd542e04..16b8454f 100644 --- a/rfcMgr/rfc_main.cpp +++ b/rfcMgr/rfc_main.cpp @@ -30,6 +30,23 @@ extern "C" { #include "breakpad_wrapper.h" #endif +#include + +// Cleanup function +void cleanup_lock_file(void) +{ + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] RFC: Completed service, deleting lock\n", __FUNCTION__, __LINE__); + unlink(RFC_MGR_SERVICE_LOCK_FILE); +} + +// Signal handler for graceful shutdown +void signal_handler(int sig) +{ + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "RFC: Received signal %d, cleaning up lock file\n", sig); + cleanup_lock_file(); + exit(0); +} + int main() { pid_t pid; @@ -44,13 +61,20 @@ int main() { exit(EXIT_SUCCESS); } - + atexit(cleanup_lock_file); + + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + rfc::RFCManager* rfcMgr = new rfc::RFCManager(); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] RFC: Starting service, creating lock \n", __FUNCTION__, __LINE__); + /* Abort if another instance of rfcMgr is already running */ if (CurrentRunningInst(RFC_MGR_SERVICE_LOCK_FILE)) { rfcMgr->SendEventToMaintenanceManager("MaintenanceMGR", MAINT_RFC_INPROGRESS); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] RFC: rfcMgr process in progress, New instance not allowed as file %s is locked!\n", __FUNCTION__, __LINE__, RFC_MGR_SERVICE_LOCK_FILE); delete rfcMgr; return 1; } @@ -59,16 +83,16 @@ int main() if (isDeviceOnline == rfc::RFCMGR_DEVICE_ONLINE) { int status = FAILURE; - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] RFC:Device is Online\n", __FUNCTION__, __LINE__); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] RFC:Device is Online\n", __FUNCTION__, __LINE__); status = rfcMgr->RFCManagerProcessXconfRequest(); if(status == SUCCESS) { - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] RFC:Xconf Request Processed successfully\n", __FUNCTION__, __LINE__); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] RFC:Xconf Request Processed successfully\n", __FUNCTION__, __LINE__); } } else { - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] RFC:Device is Offline\n", __FUNCTION__, __LINE__); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] RFC:Device is Offline\n", __FUNCTION__, __LINE__); } #ifdef INCLUDE_BREAKPAD diff --git a/rfcMgr/rfc_manager.cpp b/rfcMgr/rfc_manager.cpp index 3472885f..1c8cadfa 100644 --- a/rfcMgr/rfc_manager.cpp +++ b/rfcMgr/rfc_manager.cpp @@ -344,7 +344,8 @@ namespace rfc { bool isRebootRequired = rfcObj->getRebootRequirement(); if(isRebootRequired == true) { - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR,"[%s][%d] RFC: Posting Reboot Required Event to MaintenanceMGR\n", __FUNCTION__,__LINE__); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR,"[%s][%d] RFC: Posting Reboot Required Event to MaintenanceMGR\n", __FUNCTION__,__LINE__); + rfcObj->NotifyTelemetry2Count("SYST_INFO_RFC_Reboot"); SendEventToMaintenanceManager("MaintenanceMGR", MAINT_CRITICAL_UPDATE); SendEventToMaintenanceManager("MaintenanceMGR", MAINT_REBOOT_REQUIRED); } @@ -353,6 +354,7 @@ namespace rfc { else { RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR,"[%s][%d] RFC: Posting RFC Error Event to MaintenanceMGR\n", __FUNCTION__,__LINE__); + rfcObj->NotifyTelemetry2Count("SYST_INFO_RFC_Error"); SendEventToMaintenanceManager("MaintenanceMGR", MAINT_RFC_ERROR); } @@ -360,6 +362,7 @@ namespace rfc { if(post_process_result == SUCCESS) { RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR,"[%s][%d] RFC:Post Processing Successfully Completed\n", __FUNCTION__,__LINE__); + rfcObj->NotifyTelemetry2Count("SYST_INFO_RFC_PostProcess_Success"); } else { diff --git a/rfcMgr/rfc_manager.h b/rfcMgr/rfc_manager.h index f9ce8fa0..d00466e7 100644 --- a/rfcMgr/rfc_manager.h +++ b/rfcMgr/rfc_manager.h @@ -41,6 +41,11 @@ #define ROUTE_FLAG_MAX_CHECK 5 #define RFC_MGR_INTERNET_CHECK_TIMEOUT 2000 +#if defined(GTEST_ENABLE) +#include +#endif + + /*----------------------------------------------------------------------------*/ /* Namespace */ /*----------------------------------------------------------------------------*/ @@ -64,6 +69,10 @@ enum DeviceStatus { #define RFC_MGR_SERVICE_LOCK_FILE "/tmp/.rfcServiceLock" +#if defined(GTEST_ENABLE) +bool isDnsResolve(const char *); +#endif + /*----------------------------------------------------------------------------*/ /* Class */ /*----------------------------------------------------------------------------*/ @@ -77,7 +86,11 @@ class RFCManager { rfc::DeviceStatus CheckDeviceIsOnline(void); void SendEventToMaintenanceManager(const char *, unsigned int); +#if defined(GTEST_ENABLE) + public: +#else private: +#endif void InitializeIARM(void); bool isConnectedToInternet(); bool CheckIProuteConnectivity(const char *); diff --git a/rfcMgr/rfc_xconf_handler.cpp b/rfcMgr/rfc_xconf_handler.cpp index e972d9ba..45c5c68f 100644 --- a/rfcMgr/rfc_xconf_handler.cpp +++ b/rfcMgr/rfc_xconf_handler.cpp @@ -90,31 +90,19 @@ int RuntimeFeatureControlProcessor:: InitializeRuntimeFeatureControlProcessor(vo return SUCCESS; } -bool RuntimeFeatureControlProcessor::checkWhoamiSupport( ) -{ - const std::string d_file = DEVICE_PROPERTIES_FILE; - std::ifstream devicepropFile; - bool found = false; - devicepropFile.open(d_file.c_str()); - if (!devicepropFile.is_open()) - { - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d]Failed to open file.\n", __FUNCTION__, __LINE__); - return false; - } - std::string line; - while (std::getline(devicepropFile, line)) - { - if (line == "WHOAMI_SUPPORT=true") - { - found = true; - break; - } +bool RuntimeFeatureControlProcessor::checkWhoamiSupport() +{ + char value[8] = {0}; + int ret = getDevicePropertyData("WHOAMI_SUPPORT", value, sizeof(value)); + if (ret != 1) { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Failed to get WHOAMI_SUPPORT property. Status: %d\n", __FUNCTION__, __LINE__, ret); + return false; } - devicepropFile.close(); - - return found; + bool enabled = (strcasecmp(value, "true") == 0); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] Whoami support is %s\n", __FUNCTION__, __LINE__, enabled ? "ENABLED" : "DISABLED"); + return enabled; } bool RuntimeFeatureControlProcessor::isDebugServicesEnabled(void) @@ -507,20 +495,112 @@ bool RuntimeFeatureControlProcessor::isXconfSelectorSlotProd() return result; } - void RuntimeFeatureControlProcessor::clearDB(void) { + + // Store permanent parameters before clearing (equivalent to rfcStashStoreParams) + rfcStashStoreParams(); + // clear RFC data store before storing new values + // this is required as sometime key value pairs will simply + // disappear from the config data, as mac is mostly removed + // to disable a feature rather than having different value + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Clearing DB\n", __FUNCTION__,__LINE__); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Resetting all rfc values in backing store\n", __FUNCTION__,__LINE__); + +#ifndef RDKC + std::string name = "rfc"; + const std::string clearValue = "true"; + std::string ClearDB = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ClearDB"; + std::string BootstrapClearDB = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.Control.ClearDB"; + std::string ConfigChangeTimeKey = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ConfigChangeTime"; + + std::time_t timestamp = std::time(nullptr); + std::string ConfigChangeTime = std::to_string(timestamp); + + std::ofstream touch_file(TR181STOREFILE); + touch_file.close(); + + set_RFCProperty(name, ClearDB, clearValue); + set_RFCProperty(name, BootstrapClearDB, clearValue); + set_RFCProperty(name, ConfigChangeTimeKey, ConfigChangeTime); + + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Clearing DB Value: %s\n", __FUNCTION__,__LINE__,ClearDB.c_str()); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Bootstrap Clearing DB Value: %s\n", __FUNCTION__,__LINE__,BootstrapClearDB.c_str()); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] ConfigChangeTime: %s\n", __FUNCTION__,__LINE__,ConfigChangeTime.c_str()); + +#else + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Clearing tr181 store\n", __FUNCTION__,__LINE__); + if (std::remove(TR181STOREFILE) == 0) + { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] File %s removed successfully\n",__FUNCTION__, __LINE__, TR181STOREFILE); + } +#endif + + // Now retrieve parameters that must persist + rfcStashRetrieveParams(); +} + +void RuntimeFeatureControlProcessor::rfcStashStoreParams(void) +{ + // Store parameters that should survive the DB clear + // Implementation depends on which parameters need to persist + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Storing permanent parameters\n", __FUNCTION__, __LINE__); + + // Call existing GetAccountID() to ensure _accountId is populated + GetAccountID(); + + // Store the current AccountID before clearing DB + stashAccountId = _accountId; + + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Stashed AccountID: %s\n", __FUNCTION__, __LINE__, stashAccountId.c_str()); +} + +void RuntimeFeatureControlProcessor::rfcStashRetrieveParams(void) +{ + // Restore the stored permanent parameters + // Implementation depends on which parameters need to persist + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Retrieving permanent parameters\n", __FUNCTION__, __LINE__); + + if (!stashAccountId.empty() && stashAccountId != "Unknown") + { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Restoring AccountID: %s\n", __FUNCTION__, __LINE__, stashAccountId.c_str()); + + std::string name = "rfc"; + + WDMP_STATUS status = set_RFCProperty(name, RFC_ACCOUNT_ID_KEY_STR, stashAccountId); + if (status != WDMP_SUCCESS) + { + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Failed to restore AccountID: %s\n", __FUNCTION__, __LINE__, getRFCErrorString(status)); + } + else + { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Successfully restored AccountID\n", __FUNCTION__, __LINE__); + // Update the in-memory copy as well + _accountId = stashAccountId; + } + } + else + { + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] No valid AccountID to restore\n", __FUNCTION__, __LINE__); + } +} + +void RuntimeFeatureControlProcessor::clearDBEnd(void){ RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Clearing DB\n", __FUNCTION__,__LINE__); std::string name = "rfc"; - std::string value = "true"; + const std::string clearValue = "true"; std::string ClearDBEndKey = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Control.ClearDBEnd"; std::string BootstrapClearDBEndKey = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Bootstrap.Control.ClearDBEnd"; std::string reloadCacheKey = "RFC_CONTROL_RELOADCACHE"; + + set_RFCProperty(name, ClearDBEndKey, clearValue); + set_RFCProperty(name, BootstrapClearDBEndKey, clearValue); + set_RFCProperty(name, reloadCacheKey, clearValue); - set_RFCProperty(name, ClearDBEndKey, value); - set_RFCProperty(name, BootstrapClearDBEndKey, value); - set_RFCProperty(name, reloadCacheKey, value); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Clearing DBEnd Key Value: %s\n", __FUNCTION__,__LINE__,ClearDBEndKey.c_str()); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Bootstrap Clearing DBEnd Key Value: %s\n", __FUNCTION__,__LINE__,BootstrapClearDBEndKey.c_str()); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] Reload Cache Key: %s\n", __FUNCTION__,__LINE__,reloadCacheKey.c_str()); } void RuntimeFeatureControlProcessor::updateHashInDB(std::string configSetHash) @@ -649,7 +729,8 @@ int RuntimeFeatureControlProcessor::ProcessRuntimeFeatureControlReq() { if((filePresentCheck(RFC_PROPERTIES_PERSISTENCE_FILE) == RDK_API_SUCCESS) && (_ebuild_type != ePROD || dbgServices == true)) { - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Setting URL to %s from local override\n", __FUNCTION__, __LINE__, _xconf_server_url.c_str()); + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Setting URL from local override to %s\n", __FUNCTION__, __LINE__, _xconf_server_url.c_str()); + NotifyTelemetry2Value("SYST_INFO_RFC_XconflocalURL", _xconf_server_url.c_str()); } else { @@ -657,7 +738,8 @@ int RuntimeFeatureControlProcessor::ProcessRuntimeFeatureControlReq() { _xconf_server_url.clear(); _xconf_server_url = _boot_strap_xconf_url + "/featureControl/getSettings"; - RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Setting URL to %s from Bootstrap config XCONF_BS_URL:%s\n", __FUNCTION__, __LINE__, _xconf_server_url.c_str(), _boot_strap_xconf_url.c_str()); + RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] Setting URL from Bootstrap config XCONF_BS_URL:%s to %s \n", __FUNCTION__, __LINE__, _boot_strap_xconf_url.c_str(), _xconf_server_url.c_str()); + NotifyTelemetry2Value("SYST_INFO_RFC_XconfBSURL", _xconf_server_url.c_str()); } } std::stringstream url = CreateXconfHTTPUrl(); @@ -711,6 +793,7 @@ int RuntimeFeatureControlProcessor::ProcessRuntimeFeatureControlReq() updateTimeInDB("0"); } RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] COMPLETED RFC PASS\n", __FUNCTION__, __LINE__); + NotifyTelemetry2Count("SYST_INFO_RFC_Complete"); set_RFCProperty(XCONF_SELECTOR_NAME, XCONF_SELECTOR_KEY_STR, rfcSelectOpt.c_str()); set_RFCProperty(XCONF_URL_TR181_NAME, XCONF_URL_KEY_STR, _xconf_server_url.c_str()); @@ -901,7 +984,7 @@ int RuntimeFeatureControlProcessor::DownloadRuntimeFeatutres(DownloadData *pDwnL { curl_ret_code = ExecuteRequest(&file_dwnl, &sec, &httpCode); } - RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] cURL Return : %d HTTP Code : %d\n",__FUNCTION__, __LINE__, curl_ret_code, httpCode); + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] RFC Xconf Connection Response cURL Return : %d HTTP Code : %d\n",__FUNCTION__, __LINE__, curl_ret_code, httpCode); CURLcode curl_code = (CURLcode)curl_ret_code; const char *error_msg = curl_easy_strerror(curl_code); RDK_LOG(RDK_LOG_DEBUG, LOG_RFCMGR, "[%s][%d] curl_easy_strerror =%s\n", __FUNCTION__, __LINE__, error_msg); @@ -928,6 +1011,9 @@ int RuntimeFeatureControlProcessor::DownloadRuntimeFeatutres(DownloadData *pDwnL switch(curl_ret_code) { + case 6: + case 18: + case 28: case 35: case 51: case 53: @@ -948,11 +1034,14 @@ int RuntimeFeatureControlProcessor::DownloadRuntimeFeatutres(DownloadData *pDwnL if((curl_ret_code == 0) && (httpCode == 404)) { + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] Received HTTP %d Response from Xconf Server. Retry logic not needed!!!\n",__FUNCTION__, __LINE__,httpCode); cleanAllFile(); RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[Features Enabled]-[NONE]:\n"); + NotifyTelemetry2Count("SYST_INFO_RFC_FeaturesNone"); } else if(httpCode == 304) { + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] HTTP request success. Response unchanged (%d). No processing\n",__FUNCTION__, __LINE__,httpCode); NotifyTelemetry2RemoteFeatures("/opt/secure/RFC/rfcFeature.list", "ACTIVE"); ret_value= NO_RFC_UPDATE_REQUIRED; } @@ -962,6 +1051,7 @@ int RuntimeFeatureControlProcessor::DownloadRuntimeFeatutres(DownloadData *pDwnL } else { + RDK_LOG(RDK_LOG_INFO, LOG_RFCMGR, "[%s][%d] HTTP request success, Processing updated (%d) response...\n",__FUNCTION__, __LINE__,httpCode); cleanAllFile(); if (std::remove(TR181LISTFILE) == 0) { @@ -1286,6 +1376,12 @@ void RuntimeFeatureControlProcessor::NotifyTelemetry2Count(std ::string markerNa v_secure_system("/usr/bin/telemetry2_0_client %s %d", markerName.c_str(), count); } + +void RuntimeFeatureControlProcessor::NotifyTelemetry2Value(std ::string markerName, std ::string value) +{ + v_secure_system("/usr/bin/telemetry2_0_client %s %s", markerName.c_str(), value.c_str()); +} + void RuntimeFeatureControlProcessor::processXconfResponseConfigDataPart(JSON *features) { CreateConfigDataValueMap(features); @@ -1363,6 +1459,7 @@ void RuntimeFeatureControlProcessor::processXconfResponseConfigDataPart(JSON *fe } updateTR181File(TR181_FILE_LIST, paramList); + clearDBEnd(); } void RuntimeFeatureControlProcessor::CreateConfigDataValueMap(JSON *features) @@ -1515,8 +1612,11 @@ void RuntimeFeatureControlProcessor::NotifyTelemetry2RemoteFeatures(const char * RDK_LOG(RDK_LOG_ERROR, LOG_RFCMGR, "[%s][%d] RFC Feature List is not found in the file.\n" , __FUNCTION__, __LINE__); return; } - v_secure_system("/usr/bin/telemetry2_0_client rfc_split %s", line.c_str()); - + if (rfcstatus == "STAGING") { + v_secure_system("/usr/bin/telemetry2_0_client rfc_staging_split %s", line.c_str()); + } else { + v_secure_system("/usr/bin/telemetry2_0_client rfc_split %s", line.c_str()); + } } void RuntimeFeatureControlProcessor::WriteFile(const std::string& filename, const std::string& data) diff --git a/rfcMgr/rfc_xconf_handler.h b/rfcMgr/rfc_xconf_handler.h index a5403569..17c01e29 100644 --- a/rfcMgr/rfc_xconf_handler.h +++ b/rfcMgr/rfc_xconf_handler.h @@ -59,6 +59,7 @@ extern "C" { #define RFC_LAST_VERSION "/opt/secure/RFC/.version" #define VARIABLEFILE "/opt/secure/RFC/rfcVariable.ini" #define TR181LISTFILE "/opt/secure/RFC/tr181.list" +#define TR181STOREFILE "/opt/secure/RFC/tr181store.ini" #define DIRECT_BLOCK_FILENAME "/tmp/.lastdirectfail_rfc" #define RFC_DEBUGSRV "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Identity.DbgServices.Enable" @@ -92,7 +93,9 @@ class RuntimeFeatureControlProcessor : public xconf::XconfHandler int InitializeRuntimeFeatureControlProcessor(void); int ProcessRuntimeFeatureControlReq(); bool getRebootRequirement(); - + void NotifyTelemetry2Count(std ::string markerName); + void NotifyTelemetry2Value(std ::string markerName, std ::string value); + private: typedef struct RuntimeFeatureControlObject { @@ -106,10 +109,11 @@ class RuntimeFeatureControlProcessor : public xconf::XconfHandler RfcState rfc_state; /* RFC State */ std::string _last_firmware; /* Last Firmware Version */ std::string _xconf_server_url; /* Xconf server URL */ - std::string _boot_strap_xconf_url; /* Bootstrap XConf URL */ + std::string _boot_strap_xconf_url; /* Bootstrap XConf URL */ std::string _valid_accountId; /* Valid Account ID*/ std::string _valid_partnerId; /* Valid Partner ID*/ std::string _accountId; /* Device Account ID */ + std::string stashAccountId; std::string _partnerId; /* Device Partner ID */ std::string _bkPartnerId; /* Device Partner ID */ std::string _experience; @@ -143,8 +147,12 @@ class RuntimeFeatureControlProcessor : public xconf::XconfHandler void updateTimeInDB(std::string timestampString); void updateHashAndTimeInDB(char *curlHeaderResp); bool IsDirectBlocked(); - void clearDB(); - + void clearDB(); + void clearDBEnd(); + void rfcStashStoreParams(void); + void rfcStashRetrieveParams(void); + + std::stringstream CreateXconfHTTPUrl(); void GetStoredHashAndTime( std ::string &valueHash, std::string &valueTime ); void RetrieveHashAndTimeFromPreviousDataSet(std ::string &valueHash, std::string &valueTime); @@ -169,7 +177,6 @@ class RuntimeFeatureControlProcessor : public xconf::XconfHandler int getJRPCTokenData( char *, char *, unsigned int ); void cleanAllFile(); int ProcessXconfUrl(const char *XconfUrl); - void NotifyTelemetry2Count(std ::string markerName); bool isDebugServicesEnabled(void); #if defined(GTEST_ENABLE) @@ -192,6 +199,35 @@ class RuntimeFeatureControlProcessor : public xconf::XconfHandler FRIEND_TEST(rfcMgrTest, writeRemoteFeatureCntrlFile); FRIEND_TEST(rfcMgrTest, getJsonRpc); FRIEND_TEST(rfcMgrTest, cleanAllFile); + FRIEND_TEST(rfcMgrTest, checkWhoamiSupport); + FRIEND_TEST(rfcMgrTest, isDebugServicesEnabled); + FRIEND_TEST(rfcMgrTest, isMaintenanceEnabled); + FRIEND_TEST(rfcMgrTest, GetOsClass); + FRIEND_TEST(rfcMgrTest, set_RFCProperty); + FRIEND_TEST(rfcMgrTest, GetValidPartnerId); + FRIEND_TEST(rfcMgrTest, GetValidAccountId); + FRIEND_TEST(rfcMgrTest, CreateXconfHTTPUrl); + FRIEND_TEST(rfcMgrTest, isConfigValueChange); + FRIEND_TEST(rfcMgrTest, IsDirectBlocked); + FRIEND_TEST(rfcMgrTest, CreateConfigDataValueMap); + FRIEND_TEST(rfcMgrTest, GetRuntimeFeatureControlJSON); + FRIEND_TEST(rfcMgrTest, InitDownloadData); + FRIEND_TEST(rfcMgrTest, getRFCName); + FRIEND_TEST(rfcMgrTest, getFeatureInstance); + FRIEND_TEST(rfcMgrTest, getRFCEnableParam); + FRIEND_TEST(rfcMgrTest, getEffectiveImmediateParam); + FRIEND_TEST(rfcMgrTest, GetXconfSelect); + FRIEND_TEST(rfcMgrTest, updateHashInDB); + FRIEND_TEST(rfcMgrTest, updateTimeInDB); + FRIEND_TEST(rfcMgrTest, getJRPCTokenData); + FRIEND_TEST(rfcMgrTest, ProcessXconfUrl); + FRIEND_TEST(rfcMgrTest, updateTR181File); + FRIEND_TEST(rfcMgrTest, processXconfResponseConfigDataPart); + FRIEND_TEST(rfcMgrTest, rfcStashStoreParams); + FRIEND_TEST(rfcMgrTest, rfcStashRetrieveParams); + FRIEND_TEST(rfcMgrTest, clearDBEnd); + FRIEND_TEST(rfcMgrTest, clearDB); + #endif }; diff --git a/rfcMgr/xconf_handler.h b/rfcMgr/xconf_handler.h index 1dabdb35..77c4b381 100644 --- a/rfcMgr/xconf_handler.h +++ b/rfcMgr/xconf_handler.h @@ -23,6 +23,10 @@ #include #include "mtlsUtils.h" +#if defined(GTEST_ENABLE) +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -39,7 +43,11 @@ namespace xconf { XconfHandler(const XconfHandler&) = delete; XconfHandler& operator=(const XconfHandler&) = delete; +#if defined(GTEST_ENABLE) + public: +#else protected : +#endif std::string _estb_mac_address; /* Device Mac Address*/ std::string _firmware_version; /* Device Frimware version */ BUILDTYPE _ebuild_type; /* Device Build Type */ diff --git a/rfcapi/rfcapi.cpp b/rfcapi/rfcapi.cpp index 7deedae3..de4634f3 100644 --- a/rfcapi/rfcapi.cpp +++ b/rfcapi/rfcapi.cpp @@ -347,7 +347,7 @@ WDMP_STATUS getRFCParameter(const char *pcCallerID, const char* pcParameterName, #ifdef TEMP_LOGGING logofs << prefix() << "curl response = " << res << "http response code = " << http_code << endl; #endif - RDK_LOG(RDK_LOG_INFO, LOG_RFCAPI,"curl response : %d http response code: %ld\n", res, http_code); + RDK_LOG(RDK_LOG_DEBUG, LOG_RFCAPI,"curl response : %d http response code: %ld\n", res, http_code); curl_easy_cleanup(curl_handle); curl_slist_free_all(customHeadersList); @@ -423,6 +423,7 @@ WDMP_STATUS getRFCParameter(const char *pcCallerID, const char* pcParameterName, #endif RDK_LOG(RDK_LOG_DEBUG, LOG_RFCAPI,"statusCode = %d\n", ret); } + cJSON_Delete(response_json); } } return ret; @@ -537,6 +538,7 @@ WDMP_STATUS setRFCParameter(const char *pcCallerID, const char* pcParameterName, #endif RDK_LOG(RDK_LOG_DEBUG, LOG_RFCAPI,"statusCode = %d\n", ret); } + cJSON_Delete(response_json); } } return ret; @@ -675,3 +677,10 @@ bool isRFCEnabled(const char *feature) } #endif + +// Define your write callback function +#ifdef GTEST_ENABLE +size_t (*getWriteCurlResponse(void))(void *ptr, size_t size, size_t nmemb, std::string stream) { + return &writeCurlResponse; +} +#endif diff --git a/rfcapi/rfcapi.h b/rfcapi/rfcapi.h index b4e79aa5..c1cb6642 100644 --- a/rfcapi/rfcapi.h +++ b/rfcapi/rfcapi.h @@ -67,6 +67,9 @@ WDMP_STATUS setRFCParameter(const char *pcCallerID, const char* pcParameterName, const char* getRFCErrorString(WDMP_STATUS code); bool isRFCEnabled(const char *); bool isFileInDirectory(const char *, const char *); +#if defined(GTEST_ENABLE) +bool init_rfcdefaults(); +#endif #endif #ifdef __cplusplus } diff --git a/run_ut.sh b/run_ut.sh index 44d61d29..af4154ea 100644 --- a/run_ut.sh +++ b/run_ut.sh @@ -41,9 +41,12 @@ cp ./rfcMgr/gtest/mocks/tr181store.ini /opt/secure/RFC/tr181store.ini export TOP_DIR=`pwd` -cd ./rfcMgr/ +cd ./rfcMgr/gtest rm ./gtest/rfcMgr_gtest +rm ./gtest/rfcapi_gtest +rm ./gtest/tr181api_gtest +rm ./gtest/utils_gtest automake --add-missing autoreconf --install @@ -52,6 +55,8 @@ autoreconf --install ./configure make clean +find . -name "*.gcda" -delete +find . -name "*.gcno" -delete echo "TOP_DIR = $TOP_DIR" @@ -59,13 +64,25 @@ echo "**** Compiling rfcMgr gtest ****" cd $TOP_DIR/rfcMgr/gtest make ./rfcMgr_gtest +./rfcapi_gtest +./tr181api_gtest +./utils_gtest + +if [ $? -ne 0 ]; then + echo "Unit tests failed" + exit 1 +fi echo "********************" +cd $TOP_DIR + if [ "$ENABLE_COV" = true ]; then echo "Generating coverage report" - lcov --capture --directory . --output-file coverage.info - lcov --remove coverage.info '/usr/*' --output-file coverage.info - lcov --list coverage.info + lcov --capture --directory . --base-directory . --output-file coverage.info + lcov --remove coverage.info '/usr/*' '*/gtest/*' '*/mocks/*' --output-file filtered.info + lcov --extract filtered.info '*/rfcMgr/*' '*/rfcapi/*' '*/tr181api/*' '*/utils/*' --output-file rfc_coverage.info + lcov --list rfc_coverage.info + cp rfc_coverage.info $TOP_DIR/rfcMgr/gtest/coverage.info fi cd $TOP_DIR diff --git a/tr181api/tr181api.h b/tr181api/tr181api.h index dfadf2de..4dda194e 100644 --- a/tr181api/tr181api.h +++ b/tr181api/tr181api.h @@ -23,6 +23,10 @@ #include #include +#if defined(GTEST_ENABLE) +#include +#endif + #ifdef __cplusplus extern "C" { @@ -84,6 +88,12 @@ tr181ErrorCode_t setLocalParam(char *pcCallerID, const char* pcParameterName, co tr181ErrorCode_t clearLocalParam(char *pcCallerID, const char* pcParameterName); tr181ErrorCode_t getDefaultValue(char *pcCallerID, const char* pcParameterName, TR181_ParamData_t *pstParamData); +#if defined(GTEST_ENABLE) +tr181ErrorCode_t setValue(const char* pcParameterName, const char* pcParamValue); +tr181ErrorCode_t getValue(const char* fileName, const char* pcParameterName, TR181_ParamData_t *pstParam); +TR181_PARAM_TYPE getType(DATA_TYPE type); +tr181ErrorCode_t getErrorCode(WDMP_STATUS status); +#endif #ifdef __cplusplus } diff --git a/utils/jsonhandler.cpp b/utils/jsonhandler.cpp index acd3319f..424ab84e 100644 --- a/utils/jsonhandler.cpp +++ b/utils/jsonhandler.cpp @@ -23,6 +23,10 @@ #include #include +#if defined(GTEST_ENABLE) +#include "jsonhandler.h" +#endif + #define JSON_ARRAY_IDENTIFIER "listType" #define JSON_NAME_IDENTIFIER "name" #define JSON_FEATURE_CONTROL_IDENTIFIER "featureControl" @@ -290,6 +294,7 @@ char * getFilePath(){ return path; } +#ifndef GTEST_ENABLE int main (int argc , char *argv []) { char * json_string = NULL; @@ -316,3 +321,4 @@ int main (int argc , char *argv []) } return 0; } +#endif diff --git a/utils/jsonhandler.h b/utils/jsonhandler.h new file mode 100644 index 00000000..9bf059ea --- /dev/null +++ b/utils/jsonhandler.h @@ -0,0 +1,46 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2018 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/** +* @defgroup rfc +* @{ +* @defgroup utils +* @{ +**/ + +#ifndef JSONHANDLER_H +#define JSONHANDLER_H + +#include +#include +#include +#include +#include + +#if defined(GTEST_ENABLE) +char * readFromFile(char * absolutePath); +cJSON * getArrayNode(cJSON *node); +int saveToFile(cJSON * arrayNode, const char * format,const char * name); +int saveIfNodeContainsLists(cJSON *node,const char * asbolutepath); +int iterateAndSaveArrayNodes(const char * absolutePath,const char * json_data); +char * getFilePath(); +#endif + +#endif // JSONHANDLER_H diff --git a/utils/tr181utils.cpp b/utils/tr181utils.cpp index e2a65198..37c4a1df 100644 --- a/utils/tr181utils.cpp +++ b/utils/tr181utils.cpp @@ -265,6 +265,7 @@ static int parseargs(int argc, char * argv[]) return 0; } +#ifndef GTEST_ENABLE int main(int argc, char *argv []) { if(legacyRfcEnabled() == true) @@ -316,6 +317,41 @@ int main(int argc, char *argv []) } return retcode; } +#endif /** @} */ /** @} */ +// Define your write callback function +#ifdef GTEST_ENABLE +bool (*getGetParamTypeFunc())(char * const, DATA_TYPE *) +{ + return &getParamType; +} + +DATA_TYPE (*getConvertTypeFunc())(char) +{ + return &convertType; +} + +int (*getClearAttributeFunc())(char * const) +{ + return &clearAttribute; +} + +int (*getSetAttributeFunc())(char * const, char, char *) +{ + return &setAttribute; +} + +int (*getGetAttributeFunc())(char * const) +{ + return &getAttribute; +} + +int (*getparseargsFunc())(int argc, char * argv[]) +{ + return &parseargs; +} + +#endif +