Skip to content

RDKEMW-15248 : Fix L2 issue in systimemgr #74

Open
sindhu-krishnan wants to merge 68 commits into
developfrom
topic/RDKEMW-15246
Open

RDKEMW-15248 : Fix L2 issue in systimemgr #74
sindhu-krishnan wants to merge 68 commits into
developfrom
topic/RDKEMW-15246

Conversation

@sindhu-krishnan
Copy link
Copy Markdown
Contributor

No description provided.

sindhu-krishnan and others added 30 commits April 22, 2026 14:01
- Fix missing WPEFramework includes that caused 'not a namespace-name'
  and 'JsonObject does not name a type' errors
- Move WPEFramework includes exclusively to .cpp to avoid include path
  issues when header is included from other translation units
- Move internal state (controller, thunder_client, m_networkeventsubscribed)
  to file-scope statics with internal linkage
- Convert internal helper functions (subscribeToInternetEvent,
  unsubscribeFromInternetEvent, plugin_statechange) to static free
  functions - not part of the class interface
- Remove global thunder_ret, use local variable instead
- Remove explicit constructor declaration - compiler-generated default
  is sufficient; destructor handles RAII cleanup on process exit
Two bugs fixed:

1. Use versioned callsign for thunder_client
   NETWORK_MANAGER_CALLSIGN ('org.rdk.NetworkManager') was used to
   create the LinkType for subscribing to onInternetStatusChange, but
   the versioned callsign NETWORK_MANAGER_PLUGIN ('org.rdk.NetworkManager.1')
   is required for JSONRPC endpoint resolution. Using the unversioned
   callsign caused ERROR_TIMEDOUT (11) on every subscription attempt.

2. Attempt immediate subscription at startup
   After subscribing to the controller statechange event, try
   subscribeToInternetEvent() immediately. If NetworkManager is already
   active when systimemgr starts or restarts, no statechange event is
   fired, so the callback-driven subscription never happens. The
   immediate attempt handles this case; if it fails (plugin not up yet),
   the statechange callback will retry on the next activation.
…ents

Add consistent 'CHRONY:' prefix to all RDK_LOG statements in
networkstatussrc.cpp for easy log filtering with:
  grep CHRONY /opt/logs/systimemgr.log

Also remove stale debug log that printed internetStatus before it
was populated, which always printed an empty string.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.

Comment thread test/functional-tests/tests/test_systimemgr_nwstatus.py Outdated
Comment on lines +154 to +170
ok = inject_internet_status("NO_INTERNET", interface="eth0")
assert ok, "Failed to write NO_INTERNET inject file"

sleep(2) # Give sysTimeMgr time to process the event if it mistakenly does

# The code logs "no action needed" for non-connected states
no_action_log = "no action needed"
assert _wait_for_log(no_action_log, timeout_s=5), (
f"Expected 'no action needed' log not found for NO_INTERNET event"
)

# The processing path must NOT have been triggered by this event
processing_log = "CHRONY: Processing internet fully_connected event"
log_hits_before = grep_sysTimeMgrlogs(processing_log).count(processing_log)
sleep(1)
log_hits_after = grep_sysTimeMgrlogs(processing_log).count(processing_log)
assert log_hits_before == log_hits_after, (
Comment on lines +170 to +176
# --enable-chrony: build networkstatussrc.cpp against the real WPEFramework
# Thunder API (production builds).
# When NOT enabled (default for L1/L2 test builds), WPEFRAMEWORKCORE_CFLAGS/LIBS
# and WPEFRAMEWORKWEBSOCKET_CFLAGS/LIBS are empty strings so Makefile.am simply
# adds nothing. networkstatussrc.cpp then uses WPEFrameworkMock.h via the
# GTEST_ENABLE or __LOCAL_TEST_ guard, requiring no Thunder installation.
test -n "$WPEFRAMEWORKCORE_CFLAGS" || WPEFRAMEWORKCORE_CFLAGS=""
Comment thread systimerfactory/Makefile.am
Comment on lines +158 to +162
* Exit non-zero → Case C. */
int chronyActive = v_secure_system("/bin/systemctl is-active --quiet chronyd.service");
if (chronyActive != 0) {
/* Case A */
RDK_LOG(RDK_LOG_INFO, LOG_SYSTIME,
Comment on lines +190 to +196
RDK_LOG(RDK_LOG_ERROR, LOG_SYSTIME,
"[%s:%d]: CHRONY: chronyc online failed (ret=%d)."
" chronyd will sync on its own schedule.\n",
__FUNCTION__, __LINE__, ret);
}
}
}
Comment thread systimerfactory/unittest/mocks/Client_Mock.h
g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

@github-actions
Copy link
Copy Markdown

Code Coverage Summary

                                        Total:|75.5%   759|85.5%  62|    -    0

@github-actions
Copy link
Copy Markdown

Code Coverage Summary

                                        Total:|75.5%   759|85.5%  62|    -    0

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

Copilot AI review requested due to automatic review settings May 13, 2026 05:08
@github-actions
Copy link
Copy Markdown

Code Coverage Summary

                                        Total:|75.5%   759|85.5%  62|    -    0

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

test/functional-tests/tests/test_systimemgr_nwstatus.py:360

  • The file redefines the same tests and imports a second time. In Python the later definitions override the offset-based versions above, so the new stale-log protections and reset logic are never executed and the suite can still false-pass on old log lines. Remove the duplicate block or merge the intended changes into a single set of test functions.
"""
L2 tests for the NWStatusMonitor feature (topic/NWStatusMonitor).

Verifies that sysTimeMgr:
  1. Subscribes to onInternetStatusChange from org.rdk.NetworkManager.
  2. Processes a FULLY_CONNECTED event and triggers the appropriate
     chrony sync logic.
  3. Ignores non-connected status events (no chrony action logged).
  4. Does not re-process a duplicate FULLY_CONNECTED event while
     lastStatus is already fully_connected.

When compiled with -D__LOCAL_TEST_ (the default for test builds) sysTimeMgr
uses WPEFrameworkMock.h instead of the real Thunder library.  Events are
injected by writing JSON to a file that the mock SmartLinkType polls:
  /tmp/thunder_mock_org_rdk_NetworkManager_onInternetStatusChange.inject

No Thunder daemon, WebSocket server, or network-mock.js is required.
This mirrors the enservice entservices-testframework thunder mock approach.
"""

Comment on lines +180 to +190
AC_ARG_ENABLE([chrony],
AS_HELP_STRING([--enable-chrony],[enable NWStatus with real WPEFramework Thunder]),
[
case "${enableval}" in
yes) PKG_CHECK_MODULES([WPEFRAMEWORKCORE],[WPEFrameworkCore >= 1.0.0])
PKG_CHECK_MODULES([WPEFRAMEWORKWEBSOCKET],[WPEFrameworkWebSocket >= 1.0.0]);;
no) ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-chrony]) ;;
esac
],
[echo "chrony: WPEFramework disabled (using mocks for GTEST_ENABLE/__LOCAL_TEST_)"])
Comment on lines +170 to +180
offset = _log_offset()
subscribed = wait_for_nw_subscription(timeout_s=20)
assert subscribed, (
"sysTimeMgr did not call SmartLinkType::Subscribe() within timeout. "
"Ensure sysTimeMgr is compiled with -D__LOCAL_TEST_ and that "
"networkstatussrc.cpp is included (topic/NWStatusMonitor branch)."
)

expected_log = "Successfully subscribed to onInternetStatusChange"
assert _wait_for_new_log(expected_log, after_offset=offset, timeout_s=10), (
f"Expected log line not found after test start in {LOG_FILE}: '{expected_log}'"
lib_LTLIBRARIES = libsystimerfactory.la

libsystimerfactory_la_SOURCES = timerfactory.cpp pubsubfactory.cpp rdkdefaulttimesync.cpp drmtimersrc.cpp
libsystimerfactory_la_SOURCES = timerfactory.cpp pubsubfactory.cpp rdkdefaulttimesync.cpp drmtimersrc.cpp networkstatussrc.cpp
g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

@github-actions
Copy link
Copy Markdown

Code Coverage Summary

                                        Total:|75.5%   759|85.5%  62|    -    0

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

Copilot AI review requested due to automatic review settings May 13, 2026 07:28
@github-actions
Copy link
Copy Markdown

Code Coverage Summary

                                        Total:|75.5%   759|85.5%  62|    -    0

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.

Comment thread run_l2.sh
Comment on lines +69 to +71
# --enable-unittest) it uses WPEFrameworkMock.h instead of the real Thunder
# library. Events are injected by writing JSON to a file that the mock
# SmartLinkType polls — no Thunder daemon or WebSocket server is needed.
Comment on lines +272 to +276
auto entry = std::unique_ptr<EventEntry>(new EventEntry());
EventEntry* raw = entry.get();
entries_[eventName] = std::move(entry);

const std::string injectPath = injectFilePath(eventName);
2. The 'Successfully subscribed' line appears in log content written
after this test started (offset-based to avoid stale matches).
"""
offset = _log_offset()
Comment on lines +36 to +39
* L2 functional tests) use the lightweight header stubs from
* unittest/mocks/thunder/WPEFrameworkMock.h so no real Thunder/WPEFramework
* installation is required. irdklog.h is NOT included in test builds;
* WPEFrameworkMock.h provides its own RDK_LOG stubs.
Comment on lines +310 to +311
if (normalizedStatus != "fully_connected" || normalizedStatus == prev) {
RDK_LOG(RDK_LOG_INFO, LOG_SYSTIME,
Comment on lines +180 to +184
AC_ARG_ENABLE([chrony],
AS_HELP_STRING([--enable-chrony],[enable NWStatus with real WPEFramework Thunder]),
[
case "${enableval}" in
yes) PKG_CHECK_MODULES([WPEFRAMEWORKCORE],[WPEFrameworkCore >= 1.0.0])
lib_LTLIBRARIES = libsystimerfactory.la

libsystimerfactory_la_SOURCES = timerfactory.cpp pubsubfactory.cpp rdkdefaulttimesync.cpp drmtimersrc.cpp
libsystimerfactory_la_SOURCES = timerfactory.cpp pubsubfactory.cpp rdkdefaulttimesync.cpp drmtimersrc.cpp networkstatussrc.cpp
Comment on lines +128 to +133
static void processInternetOnline()
{
RDK_LOG(RDK_LOG_INFO,LOG_SYSTIME,"[%s:%d]: CHRONY: Processing internet fully_connected event\n",
__FUNCTION__,__LINE__);

bool firstSyncDone = (access("/tmp/clock-event", F_OK) == 0);
Comment on lines +347 to +353


expected_log = "Successfully subscribed to onInternetStatusChange"
assert _wait_for_new_log(expected_log, timeout_s=10), (
f"Expected log line not found in {LOG_FILE}: '{expected_log}'"
)

g_internetUpPending = false; /* clear — we are about to handle it */
lock.unlock();
processInternetOnline();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverity Issue - Double unlock

"~unique_lock" unlocks "lock" while it is unlocked. [Note: The source code implementation of the function has been overridden by a builtin model.]

Medium Impact, CWE-765
LOCK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants