Skip to content

Conversation

@Abhinavpv28
Copy link
Contributor

No description provided.

@Abhinavpv28 Abhinavpv28 requested a review from a team as a code owner January 29, 2026 06:03
Copilot AI review requested due to automatic review settings January 29, 2026 06:03
Copy link
Contributor

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

This pull request implements an "UploadLogsNow" feature as a new mode in the logupload binary. This appears to be a C-based reimplementation of functionality previously handled by shell scripts, providing immediate on-demand log uploads.

Changes:

  • Adds new uploadlogsnow.c implementation with workflow for immediate log uploads
  • Integrates uploadlogsnow mode into the main logupload binary via command-line parameter detection
  • Adds comprehensive unit tests and functional tests for the new functionality
  • Updates build configuration to include new source files and dependencies
  • Adds snprintf truncation checks in file_operations.c for improved safety

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 19 comments.

Show a summary per file
File Description
uploadstblogs/src/uploadlogsnow.c New implementation of UploadLogsNow workflow including file copying, archiving, and upload
uploadstblogs/include/uploadlogsnow.h Header file declaring the execute_uploadlogsnow_workflow function
uploadstblogs/src/uploadstblogs.c Integration of uploadlogsnow mode with special parameter handling
uploadstblogs/src/file_operations.c Added add_timestamp_to_files_uploadlogsnow function and snprintf safety checks
uploadstblogs/src/event_manager.c Skip IARM events for uploadlogsnow mode
uploadstblogs/src/context_manager.c Added extended RDK logger initialization
uploadstblogs/include/uploadstblogs_types.h Added STATUS_FILE and DCM_TEMP_DIR constants, uploadlogsnow_mode field
uploadstblogs/unittest/uploadlogsnow_gtest.cpp Comprehensive unit tests for uploadlogsnow workflow
uploadstblogs/unittest/Makefile.am Added uploadlogsnow_gtest build target
uploadstblogs/src/Makefile.am Added uploadlogsnow.c to library sources
test/functional-tests/tests/test_uploadLogsNow.py New functional tests for uploadlogsnow feature
test/functional-tests/tests/uploadstblogs_helper.py Minor whitespace cleanup
test/functional-tests/tests/test_log_upload_onreboot_false_case.py Removed several test functions
test/run_uploadstblogs_l2.sh Added uploadLogsNow test execution (with incorrect test file reference)
unit_test.sh Added rdk_logger dependency and uploadlogsnow test execution
cov_build.sh Added rdk_logger dependency setup

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

####################################################################################

"""
Test cases for uploadLogsNOw functionality
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Typo in the docstring: "uploadLogsNOw" should be "uploadLogsNow" (lowercase 'w').

Suggested change
Test cases for uploadLogsNOw functionality
Test cases for uploadLogsNow functionality

Copilot uses AI. Check for mistakes.
echo "1. Running Error Handling Tests..."
echo "1. Running UploadLogsNow Tests..."
pytest -v --json-report --json-report-summary \
--json-report-file $RESULT_DIR/uploadLogsNow.json test/functional-tests/tests/test4.py
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The test file references 'test4.py' which does not exist in the test directory. This should be changed to 'test_uploadLogsNow.py' to match the actual test file name.

Suggested change
--json-report-file $RESULT_DIR/uploadLogsNow.json test/functional-tests/tests/test4.py
--json-report-file $RESULT_DIR/uploadLogsNow.json test/functional-tests/tests/test_uploadLogsNow.py

Copilot uses AI. Check for mistakes.

def check_upload_status_success(self):
"""Check upload status files for success indicators"""
status_files = [
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The STATUS_FILE is defined as "/opt/loguploadstatus.txt" in uploadstblogs_types.h, but the test checks for it in "/tmp/loguploadstatus.txt" first. The test should check the actual STATUS_FILE location ("/opt/loguploadstatus.txt") as the primary location, not "/tmp/loguploadstatus.txt".

Suggested change
status_files = [
status_files = [
"/opt/loguploadstatus.txt",

Copilot uses AI. Check for mistakes.
"""Clean up DCM temporary files and directories"""
temp_paths = [
"/tmp/DCM",
"/tmp/loguploadstatus.txt",
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The cleanup function is trying to delete "/tmp/loguploadstatus.txt", but based on the STATUS_FILE definition in uploadstblogs_types.h, the actual status file is located at "/opt/loguploadstatus.txt". This cleanup path should be corrected to match the actual status file location.

Suggested change
"/tmp/loguploadstatus.txt",
"/opt/loguploadstatus.txt",

Copilot uses AI. Check for mistakes.
@@ -34,29 +34,3 @@ def test_upload_cron_present():
sleep(20)
assert "urn:settings:LogUploadSettings:UploadSchedule:cron" in grep_dcmdlogs("is present setting cron jobs")

Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The removal of several test functions (test_upload_script_started_onboot_false, test_fw_cron_scheduled, test_upload_cron_scheduled, test_upload_script_started, test_fwupdate_script_started) reduces test coverage significantly. If these tests are no longer applicable due to architectural changes, this should be documented. Otherwise, consider whether equivalent test coverage is provided elsewhere to ensure no regression in functionality.

Copilot uses AI. Check for mistakes.
import subprocess as sp
import os
import tempfile
import shutil
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Import of 'shutil' is not used.

Suggested change
import shutil

Copilot uses AI. Check for mistakes.
for path in temp_paths:
try:
subprocess.run(f"rm -rf {path}", shell=True)
except:
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Except block directly handles BaseException.

Suggested change
except:
except Exception:

Copilot uses AI. Check for mistakes.
with open(filepath, 'w') as f:
f.write(content)
created_files.append(filepath)
except:
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Except block directly handles BaseException.

Copilot uses AI. Check for mistakes.
Comment on lines +124 to +125
except:
pass
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except:
pass
except Exception as e:
print(f"Warning: failed to remove temporary path '{path}': {e}")

Copilot uses AI. Check for mistakes.
if filename.endswith(('.tar.gz', '.tgz')):
print(f"Found archive file: {location}/{filename}")
return True
except Exception:
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except Exception:
except Exception:
# Directory scanning here is best-effort; ignore errors (e.g. permissions, races)

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings January 29, 2026 06:29
Copy link
Contributor

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 18 out of 18 changed files in this pull request and generated 14 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

#define MAX_FILENAME_LENGTH 256
#define MAX_CERT_PATH_LENGTH 256
#define LOG_UPLOADSTB "LOG.RDK.UPLOADSTB"
#define STATUS_FILE "/opt/loguploadstatus.txt"
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The STATUS_FILE path is defined as "/opt/loguploadstatus.txt", but in the test file it's also checked in "/tmp/loguploadstatus.txt". There's a discrepancy between the defined constant and the test expectations. Consider making the status file path configurable or ensuring consistency across the codebase.

Suggested change
#define STATUS_FILE "/opt/loguploadstatus.txt"
#define STATUS_FILE "/tmp/loguploadstatus.txt"

Copilot uses AI. Check for mistakes.
"""Set the RFC LogUploadEndpoint URL using rbuscli"""
try:
cmd = f"rbuscli set Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LogUploadEndpoint.URL string {url}"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Using subprocess.run with shell=True for rbuscli commands is a security risk. While rbuscli commands have controlled inputs here, consider using a list-based approach for better security: result = subprocess.run(["rbuscli", "set", "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.LogUploadEndpoint.URL", "string", url], capture_output=True, text=True, timeout=30)

Copilot uses AI. Check for mistakes.
Comment on lines +167 to 191
/* Extended initialization with programmatic configuration */
#ifndef L2_TEST_ENABLED
#ifndef GTEST_ENABLE
rdk_logger_ext_config_t config = {
.pModuleName = "LOG.RDK.UPLOADSTB", /* Module name */
.loglevel = RDK_LOG_INFO, /* Default log level */
.output = RDKLOG_OUTPUT_CONSOLE, /* Output to console (stdout/stderr) */
.format = RDKLOG_FORMAT_WITH_TS, /* Timestamped format */
.pFilePolicy = NULL /* Not using file output, so NULL */
};

if (rdk_logger_ext_init(&config) != RDK_SUCCESS) {
printf("UPLOADSTB : ERROR - Extended logger init failed\n");
}
#endif
#endif
if (0 == rdk_logger_init(DEBUG_INI_NAME)) {
g_rdk_logger_enabled = 1;
RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, "[%s:%d] RDK Logger initialized\n", __FUNCTION__, __LINE__);
} else {
fprintf(stderr, "WARNING: RDK Logger initialization failed, using fallback logging\n");
}

}
if (!ctx) {
RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, "[%s:%d] Context pointer is NULL\n", __FUNCTION__, __LINE__);
return false;
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The code initializes RDK logger first (lines 167-182) and then checks if ctx is NULL (line 189). However, if ctx is NULL, the function returns false after the logger has been initialized. This could lead to resource leaks or inconsistent state. The NULL check should be performed before any initialization logic.

Copilot uses AI. Check for mistakes.
Comment on lines +582 to +584
RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB,
"[%s:%d] Processing file...%s\n",
__FUNCTION__, __LINE__, filename);
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The log message "Processing file...%s" is misleading. When should_skip is set to 1, the file is being skipped, not processed. The message should be changed to something like "Skipping file (already has timestamp): %s" or "Excluding file from timestamp: %s" for clarity.

Copilot uses AI. Check for mistakes.
Comment on lines +593 to +595
RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB,
"[%s:%d] Processing file...%s\n",
__FUNCTION__, __LINE__, filename);
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The log message "Processing file...%s" is misleading. When should_skip is set to 1 for reboot.log, the file is being skipped, not processed. The message should be changed to something like "Skipping file (reboot.log): %s" or "Excluding file from timestamp: %s" for clarity.

Copilot uses AI. Check for mistakes.
// Initialize test context with safe paths
memset(&ctx, 0, sizeof(ctx));
strncpy(ctx.log_path, test_log_dir.c_str(), sizeof(ctx.log_path) - 1);
strcpy(ctx.dcm_log_path, "");
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Using strcpy() to set dcm_log_path to an empty string is less safe than using array initialization or strncpy. Consider using: ctx.dcm_log_path[0] = '\0'; which is clearer and safer.

Suggested change
strcpy(ctx.dcm_log_path, "");
ctx.dcm_log_path[0] = '\0';

Copilot uses AI. Check for mistakes.

// Get current timestamp in script format: MM-DD-YY-HH-MMAM/PM-
time_t now = time(NULL);
struct tm* tm_info = localtime(&now);
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Using localtime() is not thread-safe as it returns a pointer to a static buffer. In a multi-threaded environment, this could lead to race conditions. Use localtime_r() instead, which is the thread-safe version. Example: struct tm tm_info; localtime_r(&now, &tm_info);

Copilot uses AI. Check for mistakes.
def run_uploadlogsnow():
"""Execute uploadlogsnow using the specific binary command"""
cmd = "/usr/local/bin/logupload uploadlogsnow"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300)
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Using subprocess.run with shell=True is a security risk. The command string should be passed as a list to avoid shell injection vulnerabilities, especially if any part of the command could be influenced by user input. Change to: result = subprocess.run(["/usr/local/bin/logupload", "uploadlogsnow"], capture_output=True, text=True, timeout=300)

Copilot uses AI. Check for mistakes.
import tempfile
import shutil
from uploadstblogs_helper import *
from helper_functions import *
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

Import pollutes the enclosing namespace, as the imported module helper_functions does not define 'all'.

Copilot uses AI. Check for mistakes.
Comment on lines +362 to +363
except Exception:
pass
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except Exception:
pass
except (OSError, IOError) as e:
# Ignore filesystem access errors while checking for temporary archive files,
# but log them for debugging purposes.
print(f"Error accessing temporary location {location}: {e}")

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 3, 2026 09:27
Copy link
Contributor

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 18 out of 18 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

print(f"Checking {log_file} for success indicators")
for pattern in success_patterns:
# Use grep to search for pattern in the log file
cmd = f"grep -E '{pattern}' {log_file}"
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Using f-string with shell=True is unsafe. The 'pattern' variable contains user-controlled regex patterns that could potentially contain shell metacharacters. Use subprocess with shell=False and proper argument lists, or use shlex.quote() to sanitize the pattern. Better yet, use Python's built-in file reading and regex matching instead of calling grep.

Copilot uses AI. Check for mistakes.
Comment on lines +229 to +254
TEST_F(UploadLogsNowTest, IntegrationTest_CascadingFailures) {
// Test various failure scenarios one by one

// First test: directory creation fails (early failure)
g_create_directory_should_fail = true;
int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);

// Reset and test copy failure
SetUp(); // Reset all mocks
g_copy_file_should_fail = true;
result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);

// Reset and test archive creation failure
SetUp(); // Reset all mocks
g_create_archive_should_fail = true;
g_copy_files_return_count = 3; // Some files copied
result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);

// Reset and test upload failure
SetUp(); // Reset all mocks
g_execute_upload_cycle_return_value = false;
g_copy_files_return_count = 3; // Some files copied
result = execute_uploadlogsnow_workflow(&ctx);
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Calling SetUp() manually within a test is not a recommended practice in Google Test. The SetUp() method is automatically called before each test, so the state should already be reset. The multiple calls to execute_uploadlogsnow_workflow within the same test could lead to side effects. Consider splitting this into separate test cases instead of manually calling SetUp().

Suggested change
TEST_F(UploadLogsNowTest, IntegrationTest_CascadingFailures) {
// Test various failure scenarios one by one
// First test: directory creation fails (early failure)
g_create_directory_should_fail = true;
int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);
// Reset and test copy failure
SetUp(); // Reset all mocks
g_copy_file_should_fail = true;
result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);
// Reset and test archive creation failure
SetUp(); // Reset all mocks
g_create_archive_should_fail = true;
g_copy_files_return_count = 3; // Some files copied
result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);
// Reset and test upload failure
SetUp(); // Reset all mocks
g_execute_upload_cycle_return_value = false;
g_copy_files_return_count = 3; // Some files copied
result = execute_uploadlogsnow_workflow(&ctx);
TEST_F(UploadLogsNowTest, ExecuteWorkflow_DirectoryCreationFails) {
// Directory creation fails (early failure)
g_create_directory_should_fail = true;
int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);
}
TEST_F(UploadLogsNowTest, ExecuteWorkflow_CopyFileFails) {
// Copying files fails
g_copy_file_should_fail = true;
int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);
}
TEST_F(UploadLogsNowTest, ExecuteWorkflow_ArchiveCreationFails) {
// Archive creation fails after some files are copied
g_create_archive_should_fail = true;
g_copy_files_return_count = 3; // Some files copied
int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);
}
TEST_F(UploadLogsNowTest, ExecuteWorkflow_UploadCycleFails) {
// Upload cycle fails after some files are copied
g_execute_upload_cycle_return_value = false;
g_copy_files_return_count = 3; // Some files copied
int result = execute_uploadlogsnow_workflow(&ctx);

Copilot uses AI. Check for mistakes.
Comment on lines +540 to +543
time_t now = time(NULL);
struct tm* tm_info = localtime(&now);
char timestamp[32];
strftime(timestamp, sizeof(timestamp), "%m-%d-%y-%I-%M%p-", tm_info);
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The localtime() function is not thread-safe and returns a pointer to static storage that can be overwritten by subsequent calls. While the code immediately uses the result, in a multi-threaded environment this could be problematic. Other parts of the codebase also use localtime() without checking for NULL (e.g., archive_manager.c line 418 checks, but file_operations.c line 351 and 541 don't). Consider using localtime_r() for thread safety and add NULL checks consistently, as done in archive_manager.c.

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +256
// Test cases for execute_uploadlogsnow_workflow

TEST_F(UploadLogsNowTest, ExecuteWorkflow_NullContext) {
// Test null context parameter
int result = execute_uploadlogsnow_workflow(nullptr);
EXPECT_EQ(-1, result);
}

TEST_F(UploadLogsNowTest, ExecuteWorkflow_CreateDirectoryFails) {
g_create_directory_should_fail = true;

int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result); // Should fail due to directory creation failure
}

TEST_F(UploadLogsNowTest, ExecuteWorkflow_CopyFilesFails) {
g_copy_file_should_fail = true;

int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result); // Should fail due to file copy failure
}

TEST_F(UploadLogsNowTest, ExecuteWorkflow_CreateArchiveFails) {
g_create_archive_should_fail = true;
g_copy_files_return_count = 3; // Some files copied

int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result); // Should fail due to archive creation failure
}

TEST_F(UploadLogsNowTest, ExecuteWorkflow_ArchiveFileNotFound) {
g_file_exists_return_value = false;
g_copy_files_return_count = 3; // Some files copied

int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result); // Should fail when archive file doesn't exist after creation
}

TEST_F(UploadLogsNowTest, ExecuteWorkflow_UploadFails) {
g_execute_upload_cycle_return_value = false;
g_copy_files_return_count = 3; // Some files copied

int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result); // Should fail when upload fails
}

TEST_F(UploadLogsNowTest, IntegrationTest_CascadingFailures) {
// Test various failure scenarios one by one

// First test: directory creation fails (early failure)
g_create_directory_should_fail = true;
int result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);

// Reset and test copy failure
SetUp(); // Reset all mocks
g_copy_file_should_fail = true;
result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);

// Reset and test archive creation failure
SetUp(); // Reset all mocks
g_create_archive_should_fail = true;
g_copy_files_return_count = 3; // Some files copied
result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);

// Reset and test upload failure
SetUp(); // Reset all mocks
g_execute_upload_cycle_return_value = false;
g_copy_files_return_count = 3; // Some files copied
result = execute_uploadlogsnow_workflow(&ctx);
EXPECT_EQ(-1, result);
}
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The unit tests only cover failure scenarios but do not include a test for the successful execution path of execute_uploadlogsnow_workflow. There should be at least one test case that verifies the function succeeds when all dependencies return success values.

Copilot uses AI. Check for mistakes.
def run_uploadlogsnow():
"""Execute uploadlogsnow using the specific binary command"""
cmd = "/usr/local/bin/logupload uploadlogsnow"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300)
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The module is imported as 'sp' on line 27 but used as 'subprocess' throughout the file. This inconsistency should be resolved by either using 'sp' consistently or importing as 'subprocess' directly.

Copilot uses AI. Check for mistakes.
Comment on lines +312 to +313
"/tmp/loguploadstatus.txt",
"/opt/logs/loguploadstatus.txt"
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The STATUS_FILE is defined as "/opt/loguploadstatus.txt" in uploadstblogs_types.h, but the test checks for the file in both "/tmp/loguploadstatus.txt" and "/opt/logs/loguploadstatus.txt". This inconsistency could lead to test failures. The test should check the actual path defined by STATUS_FILE constant, which is "/opt/loguploadstatus.txt".

Suggested change
"/tmp/loguploadstatus.txt",
"/opt/logs/loguploadstatus.txt"
"/opt/loguploadstatus.txt"

Copilot uses AI. Check for mistakes.
// Initialize test context with safe paths
memset(&ctx, 0, sizeof(ctx));
strncpy(ctx.log_path, test_log_dir.c_str(), sizeof(ctx.log_path) - 1);
strcpy(ctx.dcm_log_path, "");
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Using strcpy without bounds checking is unsafe. While the code sets dcm_log_path to an empty string which is safe in this specific case, it's better to use a safer alternative like strncpy or memset for consistency with the rest of the code and to prevent potential security issues if this line is modified in the future.

Suggested change
strcpy(ctx.dcm_log_path, "");
memset(ctx.dcm_log_path, 0, sizeof(ctx.dcm_log_path));

Copilot uses AI. Check for mistakes.
Comment on lines +174 to +175
std::string cleanup_cmd = "rm -rf " + test_log_dir;
system(cleanup_cmd.c_str());
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Using system() to execute shell commands with user-controlled strings can be a security risk. While in this case the path is constructed from getpid() which is safe, it's better practice to use proper directory removal APIs like rmdir() or std::filesystem::remove_all() instead of system() to avoid potential command injection vulnerabilities and to have better error handling.

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +38
cmd = "/usr/local/bin/logupload uploadlogsnow"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300)
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Using subprocess.run with shell=True can be a security risk if the command contains user-controlled input. While in this specific case the command is hardcoded, it's better practice to use shell=False with a list of arguments for security and to avoid potential command injection issues. Consider changing to: subprocess.run(["/usr/local/bin/logupload", "uploadlogsnow"], capture_output=True, text=True, timeout=300)

Suggested change
cmd = "/usr/local/bin/logupload uploadlogsnow"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300)
cmd = ["/usr/local/bin/logupload", "uploadlogsnow"]
result = sp.run(cmd, capture_output=True, text=True, timeout=300)

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +34
from uploadstblogs_helper import *
from helper_functions import *


Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Import pollutes the enclosing namespace, as the imported module uploadstblogs_helper does not define 'all'.

Suggested change
from uploadstblogs_helper import *
from helper_functions import *
import uploadstblogs_helper as _uploadstblogs_helper
from helper_functions import *
# Explicitly expose only the helpers used from uploadstblogs_helper
remove_lock_file = _uploadstblogs_helper.remove_lock_file
cleanup_test_log_files = _uploadstblogs_helper.cleanup_test_log_files
kill_uploadstblogs = _uploadstblogs_helper.kill_uploadstblogs

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 3, 2026 09:49
Copy link
Contributor

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Update lcov command to include additional directory for coverage data.
Copilot AI review requested due to automatic review settings February 3, 2026 12:01
Copy link
Contributor

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 18 out of 18 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

result = run_uploadlogsnow()

# Verify basic execution success
#assert result.returncode == 0, f"Upload should succeed, got return code: {result.returncode}"
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The assertion checking the return code is commented out. This means the test won't actually validate whether the upload succeeded or failed. Either uncomment this assertion or provide an alternative validation mechanism. Commented-out assertions reduce test effectiveness.

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +173
// Skip IARM events for uploadLogNow case
if (ctx && ctx->uploadlogsnow_mode) {
RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB,
"[%s:%d] Skipping IARM events for uploadLogNow mode\n", __FUNCTION__, __LINE__);
return;
}
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The emit_upload_failure function checks ctx for null at line 169 but then at line 179 (outside the visible diff but part of the function) it may call is_device_broadband(ctx) without a null check. Review the full function to ensure all uses of ctx have appropriate null checks, similar to line 148 where ctx is checked before dereferencing.

Copilot uses AI. Check for mistakes.
Comment on lines +178 to +180
if (rdk_logger_ext_init(&config) != RDK_SUCCESS) {
printf("UPLOADSTB : ERROR - Extended logger init failed\n");
}
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The rdk_logger_ext_init() is called but its failure only prints a message without returning an error or affecting program flow. The function then continues to call rdk_logger_init() regardless of the extended init failure. Consider whether this dual initialization is intentional and if the failure of rdk_logger_ext_init() should be handled more explicitly.

Copilot uses AI. Check for mistakes.
#

ENABLE_COV=false
ENABLE_COV=true
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The ENABLE_COV flag has been changed from false to true. This enables code coverage by default, which is generally good for comprehensive testing. However, ensure this change is intentional and aligns with the project's CI/CD configuration, as it may affect build times and resource usage.

Suggested change
ENABLE_COV=true
ENABLE_COV=false

Copilot uses AI. Check for mistakes.
Comment on lines +393 to 394
// Rename directly without pre-check to avoid TOCTOU issue
if (rename(old_path, new_path) == 0) {
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The comment mentions "Rename directly without pre-check to avoid TOCTOU issue," but the original code had a stat check that verified the file was a regular file before renaming. While removing the TOCTOU vulnerability is good, this change now allows renaming of directories and other special files. If the original behavior was intentional (i.e., only rename regular files), you should consider using rename() with appropriate error handling to skip directories, or document this behavior change.

Copilot uses AI. Check for mistakes.
Comment on lines +167 to +179
assert len(init_logs) >= 0, "Should find context initialization evidence"

# Check for device properties loading
device_logs = grep_uploadstb_logs_regex(r"DEVICE_TYPE|device.*propert|loading.*propert")
assert len(device_logs) >= 0, "Should load device properties"

# Check for path validation/setup
path_logs = grep_uploadstb_logs_regex(r"LOG_PATH|DCM_LOG_PATH|path.*valid|directory.*creat")
assert len(path_logs) >= 0, "Should validate and setup paths"

# Check for RFC endpoint configuration reading
rfc_logs = grep_uploadstb_logs_regex(r"RFC|LogUploadEndpoint|endpoint.*config")
assert len(rfc_logs) >= 0, "Should read RFC configuration"
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

The assertions at lines 167, 171, 175, and 179 all check "len(init_logs) >= 0" which will always be true since len() always returns a non-negative integer. These assertions provide no actual validation. Consider changing them to check for a positive count: "assert len(init_logs) > 0" if you expect these patterns to be found, or remove the assertions if they're not meant to be strict requirements.

Suggested change
assert len(init_logs) >= 0, "Should find context initialization evidence"
# Check for device properties loading
device_logs = grep_uploadstb_logs_regex(r"DEVICE_TYPE|device.*propert|loading.*propert")
assert len(device_logs) >= 0, "Should load device properties"
# Check for path validation/setup
path_logs = grep_uploadstb_logs_regex(r"LOG_PATH|DCM_LOG_PATH|path.*valid|directory.*creat")
assert len(path_logs) >= 0, "Should validate and setup paths"
# Check for RFC endpoint configuration reading
rfc_logs = grep_uploadstb_logs_regex(r"RFC|LogUploadEndpoint|endpoint.*config")
assert len(rfc_logs) >= 0, "Should read RFC configuration"
assert len(init_logs) > 0, "Should find context initialization evidence"
# Check for device properties loading
device_logs = grep_uploadstb_logs_regex(r"DEVICE_TYPE|device.*propert|loading.*propert")
assert len(device_logs) > 0, "Should load device properties"
# Check for path validation/setup
path_logs = grep_uploadstb_logs_regex(r"LOG_PATH|DCM_LOG_PATH|path.*valid|directory.*creat")
assert len(path_logs) > 0, "Should validate and setup paths"
# Check for RFC endpoint configuration reading
rfc_logs = grep_uploadstb_logs_regex(r"RFC|LogUploadEndpoint|endpoint.*config")
assert len(rfc_logs) > 0, "Should read RFC configuration"

Copilot uses AI. Check for mistakes.
assert os.path.exists(filepath), f"Test file should exist: {filepath}"

# Execute uploadLogsNow
result = run_uploadlogsnow()
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Variable result is not used.

Suggested change
result = run_uploadlogsnow()
run_uploadlogsnow()

Copilot uses AI. Check for mistakes.

import pytest
import time
import subprocess as sp
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

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

Import of 'sp' is not used.

Copilot uses AI. Check for mistakes.
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.

1 participant