Skip to content
Merged
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ All notable changes to this project will be documented in this file. Dates are d

Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

#### [1.7.4](https://github.com/rdkcentral/telemetry/compare/1.7.3...1.7.4)

- DELIA-69767: Replace popen() to prevent FD closures and improve logging [`#225`](https://github.com/rdkcentral/telemetry/pull/225)
- RDK-60072: Adding L1 unit test cases to improve code coverage [`#234`](https://github.com/rdkcentral/telemetry/pull/234)
- RDK-60072: Adding L1 unit test cases to improve code coverage [`#219`](https://github.com/rdkcentral/telemetry/pull/219)

#### [1.7.3](https://github.com/rdkcentral/telemetry/compare/1.7.2...1.7.3)

> 11 December 2025

- Changelog update for release 1.7.3 [`8a5cbfb`](https://github.com/rdkcentral/telemetry/commit/8a5cbfbec59dfe97c64ffb0547e309c65e4abd84)
- RDKEMW-11275: Fix type conversion error in empty string fix [`893b4db`](https://github.com/rdkcentral/telemetry/commit/893b4dbc94bc5f6fcc1e8776edd6b6fb90ffc28e)
- RDKEMW-11275: Fix type conversion error in empty string fix [`ec2291e`](https://github.com/rdkcentral/telemetry/commit/ec2291e68bdc2d7f298919cbe7e36a0c25f3dbe0)

Expand Down
7 changes: 7 additions & 0 deletions source/ccspinterface/rbusInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -1953,3 +1953,10 @@ bool rbusCheckMethodExists(const char* rbusMethodName)
rbusObject_Release(outParams);
return true ;
}
#ifdef GTEST_ENABLE
typedef void (*rbusReloadConfFunc)(rbusHandle_t, rbusEvent_t const *, rbusEventSubscription_t *);
rbusReloadConfFunc rbusReloadConfFuncCallback(void)
{
return rbusReloadConf;
}
#endif
49 changes: 36 additions & 13 deletions source/commonlib/telemetry_busmessage_sender.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ static void *bus_handle = NULL;
static bool isRFCT2Enable = false ;
static bool isT2Ready = false;
static bool isRbusEnabled = false ;
static int count = 0;
static pthread_mutex_t initMtx = PTHREAD_MUTEX_INITIALIZER;
static bool isMutexInitialized = false ;

Expand Down Expand Up @@ -85,13 +84,23 @@ static void EVENT_DEBUG(char* format, ...)
logHandle = fopen(SENDER_LOG_FILE, "a+");
if(logHandle)
{
time_t rawtime;
struct tm* timeinfo;
struct timespec ts;
struct tm timeinfo;

time(&rawtime);
timeinfo = localtime(&rawtime);
static char timeBuffer[20] = { '\0' };
strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S", timeinfo);
if(clock_gettime(CLOCK_REALTIME, &ts) == -1)
{
fclose(logHandle);
pthread_mutex_unlock(&loggerMutex);
return;
}

char timeBuffer[24] = { '\0' };
long msecs;

localtime_r(&ts.tv_sec, &timeinfo);
msecs = ts.tv_nsec / 1000000;
strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S", &timeinfo);
snprintf(timeBuffer + strlen(timeBuffer), sizeof(timeBuffer) - strlen(timeBuffer), ".%03ld", msecs);
fprintf(logHandle, "%s : ", timeBuffer);
va_list argList;
va_start(argList, format);
Expand Down Expand Up @@ -316,8 +325,9 @@ void *cacheEventToFile(void *arg)
fl.l_len = 0;
fl.l_pid = 0;
FILE *fs = NULL;
char path[100];
pthread_detach(pthread_self());
int ch;
int count = 0;
EVENT_ERROR("%s:%d, Caching the event to File\n", __func__, __LINE__);
if(telemetry_data == NULL)
{
Expand Down Expand Up @@ -353,12 +363,25 @@ void *cacheEventToFile(void *arg)
EVENT_ERROR("%s: File open error %s\n", __FUNCTION__, T2_CACHE_FILE);
goto unlock;
}
fs = popen ("cat /tmp/t2_caching_file | wc -l", "r");
if(fs != NULL)

fs = fopen(T2_CACHE_FILE, "r");
if (fs != NULL)
{
fgets(path, 100, fs);
count = atoi ( path );
pclose(fs);
while ((ch = fgetc(fs)) != EOF)
{
if (ch == '\n')
{
count++;
}
}

//If the file is not empty and does not contain a newline, call it one line
if (count == 0 && ftell(fs) > 0)
{
count++;
}
fclose(fs);
fs = NULL;
}
if(count < MAX_EVENT_CACHE)
{
Expand Down
18 changes: 18 additions & 0 deletions source/dcautil/dca.c
Original file line number Diff line number Diff line change
Expand Up @@ -1385,3 +1385,21 @@ int getDCAResultsInVector(GrepSeekProfile *gSeekProfile, Vector * vecMarkerList,
T2Debug("%s --out \n", __FUNCTION__);
return rc;
}
#ifdef GTEST_ENABLE
typedef const char *(*strnstrFunc)(const char *, const char *, size_t);
strnstrFunc strnstrFuncCallback(void)
{
return strnstr;
}
typedef time_t (*extractUnixTimestampFunc)(const char*, size_t);
extractUnixTimestampFunc extractUnixTimestampFuncCallback(void)
{
return extractUnixTimestamp;
}

typedef T2ERROR (*updateLogSeekFunc)(hash_map_t *, const char *, const long);
updateLogSeekFunc updateLogSeekFuncCallback(void)
{
return updateLogSeek;
}
#endif
25 changes: 25 additions & 0 deletions source/protocol/http/curlinterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,3 +633,28 @@ T2ERROR sendCachedReportsOverHTTP(char *httpUrl, Vector *reportList)
}
return T2ERROR_SUCCESS;
}

#ifdef GTEST_ENABLE
typedef size_t (*WriteToFileFunc)(void *, size_t, size_t, void *);
typedef T2ERROR (*SetHeaderFunc)(CURL *, const char *, struct curl_slist **, childResponse *);
typedef T2ERROR (*SetMtlsHeadersFunc)(CURL *, const char *, const char *, childResponse *);
typedef T2ERROR (*SetPayloadFunc)(CURL *, const char *, childResponse *);
WriteToFileFunc getWriteToFileCallback()
{
return writeToFile;
}

SetHeaderFunc getSetHeaderCallback(void)
{
return setHeader;
}

SetMtlsHeadersFunc getSetMtlsHeadersCallback(void)
{
return setMtlsHeaders;
}
SetPayloadFunc getSetPayloadCallback(void)
{
return setPayload;
}
#endif
13 changes: 13 additions & 0 deletions source/reportgen/reportgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1341,4 +1341,17 @@ void tagReportAsCached(char **jsonReport)
destroyJSONReport(jsonReportObj);
}

#ifdef GTEST_ENABLE
typedef bool (*checkForEmptyStringFunc)(char *);
typedef T2ERROR (*applyRegexToValueFunc)(char **, const char *);

checkForEmptyStringFunc checkForEmptyStringCallback(void)
{
return checkForEmptyString;
}

applyRegexToValueFunc applyRegexToValueCallback(void)
{
return applyRegexToValue;
}
#endif
7 changes: 7 additions & 0 deletions source/scheduler/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,3 +679,10 @@ T2ERROR unregisterProfileFromScheduler(const char* profileName)
T2Info("profile: %s, not found in scheduler. Already removed\n", profileName);
return T2ERROR_FAILURE;
}
#ifdef GTEST_ENABLE
typedef unsigned int (*getSchdInSec_fn)(char*);
getSchdInSec_fn getSchdInSec_fnCallback(void)
{
return getSchdInSec;
}
#endif
124 changes: 122 additions & 2 deletions source/test/ccspinterface/ccspinterfaceTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,66 @@ TEST_F(CcspInterfaceTest, getProfileParameterValues_ReturnsVector_1) {
Vector_Destroy(profileValueList, freeProfileValues);
}

TEST_F(CcspInterfaceTest, getProfileParameterValues_ReturnsVector_WithRbusGetExtError) {
Vector* paramlist = NULL;
Vector_Create(&paramlist);
Param* p = (Param*) malloc(sizeof(Param));
p->name = strdup("Device.Dummy.Param");
p->alias = strdup("Device.Dummy.Alias");
p->paramType = strdup("dataModel");
p->reportEmptyParam = true;
p->regexParam = NULL;
p->skipFreq = 0;
Param* p1 = (Param*) malloc(sizeof(Param));
p1->name = strdup("Device.Dummy.Param");
p1->alias = strdup("Device.Dummy.Alias");
p1->paramType = strdup("dataModel");
p1->reportEmptyParam = true;
p1->regexParam = NULL;
p1->skipFreq = 0;
Vector_PushBack(paramlist, p);
Vector_PushBack(paramlist, p1);

EXPECT_CALL(*g_rbusMock, rbus_checkStatus())
.Times(::testing::AtMost(1)) // Could be called multiple times depending on bus state
.WillRepeatedly(Return(RBUS_ENABLED));
EXPECT_CALL(*g_rbusMock, rbus_registerLogHandler(_))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_SUCCESS));

EXPECT_CALL(*g_rbusMock, rbus_open(_, _))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_SUCCESS));

EXPECT_CALL(*g_rbusMock, rbus_getExt(_, _, _, _, _))
.Times(::testing::AtMost(2))
.WillRepeatedly(Return(RBUS_ERROR_BUS_ERROR));

Vector* profileValueList = getProfileParameterValues(paramlist, 2);

EXPECT_NE(profileValueList, nullptr);
Vector_Destroy(paramlist, freeParam);
Vector_Destroy(profileValueList, freeProfileValues);
}

TEST_F(CcspInterfaceTest, getProfileParameterValues_ReturnsFailure) {

EXPECT_CALL(*g_rbusMock, rbus_checkStatus())
.Times(::testing::AtMost(1)) // Could be called multiple times depending on bus state
.WillRepeatedly(Return(RBUS_ENABLED));
EXPECT_CALL(*g_rbusMock, rbus_registerLogHandler(_))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_SUCCESS));

EXPECT_CALL(*g_rbusMock, rbus_open(_, _))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_BUS_ERROR));

Vector* profileValueList = getProfileParameterValues(NULL, 0);

EXPECT_EQ(profileValueList, nullptr);
}

//Test the registerRbusT2EventListener function to register the rbus event listener
TEST_F(CcspInterfaceTest, RegisterRbusT2EventListener_Succeeds)
{
Expand Down Expand Up @@ -2079,7 +2139,22 @@ TEST_F(CcspInterfaceTest, RbusMethodCaller_ReturnsSuccessForDummyMethod) {


T2ERROR err = rbusMethodCaller((char*)"Dummy.Method", &inputParams, (char*)"payload", NULL);
EXPECT_TRUE(err == T2ERROR_SUCCESS || err == T2ERROR_FAILURE); // Accept either for stub
EXPECT_TRUE(err == T2ERROR_SUCCESS);
}

TEST_F(CcspInterfaceTest, RbusMethodCaller_ReturnsFailureForDummyMethod) {
// Prepare dummy input params object
rbusObject_t inputParams;
EXPECT_CALL(*g_rbusMock, rbus_registerLogHandler(_))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_SUCCESS));

EXPECT_CALL(*g_rbusMock, rbus_open(_, _))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_BUS_ERROR));

T2ERROR err = rbusMethodCaller((char*)"Dummy.Method", &inputParams, (char*)"payload", NULL);
EXPECT_EQ(err, T2ERROR_FAILURE);
}

TEST_F(CcspInterfaceTest, RbusCheckMethodExists_ReturnsBool) {
Expand Down Expand Up @@ -2111,6 +2186,51 @@ TEST_F(CcspInterfaceTest, RbusCheckMethodExists_ReturnsBool) {

bool exists = rbusCheckMethodExists("Dummy.Method");
// Accept either true or false for stub
EXPECT_TRUE(exists == true || exists == false);
EXPECT_TRUE(exists);
}
TEST_F(CcspInterfaceTest, RbusCheckMethodExists_ReturnsBoolFalse){
EXPECT_CALL(*g_rbusMock, rbus_registerLogHandler(_))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_SUCCESS));

EXPECT_CALL(*g_rbusMock, rbus_open(_, _))
.Times(::testing::AtMost(1))
.WillRepeatedly(Return(RBUS_ERROR_BUS_ERROR));
bool exists = rbusCheckMethodExists("Dummy.Method");
// Accept either true or false for stub
EXPECT_FALSE(exists);
}
#ifdef GTEST_ENABLE
extern "C"
{
typedef void (*rbusReloadConfFunc)(rbusHandle_t, rbusEvent_t const *, rbusEventSubscription_t *);
rbusReloadConfFunc rbusReloadConfFuncCallback(void);
}

TEST_F(CcspInterfaceTest, rbusReloadConf_StaticFunction_Coverage) {
// Retrieve function pointer to static function under test
rbusReloadConfFunc callback = rbusReloadConfFuncCallback();
ASSERT_NE(callback, nullptr);

// Prepare dummy arguments
rbusHandle_t mockHandle = nullptr;

// Fill in the event and subscription structs according to your definition
rbusEvent_t event;
event.type = RBUS_EVENT_GENERAL;
event.name = "TestEvent";
event.data = nullptr;

rbusEventSubscription_t subscription;
subscription.eventName = "TestEvent";

// Normal call
callback(mockHandle, &event, &subscription);

// NULL event - covers event == NULL branch
callback(mockHandle, nullptr, &subscription);

// NULL subscription - covers subscription == NULL branch
callback(mockHandle, &event, nullptr);
}
#endif
Loading
Loading