Skip to content

Feature/test l2#93

Open
Abhinavpv28 wants to merge 16 commits into
developfrom
feature/test_L2
Open

Feature/test l2#93
Abhinavpv28 wants to merge 16 commits into
developfrom
feature/test_L2

Conversation

@Abhinavpv28

Copy link
Copy Markdown
Contributor

No description provided.

Update test_uploadstblogs_normal_upload.py

Update test_uploadstblogs_normal_upload.py

L2

Update test_uploadLogsNow.py

Update test_uploadLogsNow.py

Fix command execution in run_uploadlogsnow function

Update test_uploadLogsNow.py

Update test_uploadLogsNow.py

Update test_uploadLogsNow.py

Update test_uploadLogsNow.py

Update test_uploadLogsNow.py

Update cov_build.sh

Update L2-tests.yml

Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Update run_uploadstblogs_l2.sh

L2

L2 failure

L2

Update cov_build.sh

Clone telemetry repo and copy header files

Update uploadstblogs_helper.py

Update uploadstblogs_helper.py

Update uploadstblogs_helper.py

Update test_uploadstblogs_upload_strategies.py

Update test_uploadstblogs_upload_strategies.py

Update uploadstblogs_helper.py

Create usblogupload.feature

Update test_log_upload_onreboot_false_case.py

Update test_log_upload_onreboot_true_case.py

Update L2-tests.yml

Update test_log_upload_onreboot_true_case.py

Update test_log_upload_onreboot_false_case.py

Update test_log_upload_onreboot_true_case.py

Update test_log_upload_onreboot_false_case.py

Update test_log_upload_onreboot_false_case.py

Update test_uploadstblogs_upload_strategies.py

Update L2-tests.yml

Update cov_build.sh

Update L2-tests.yml

Update test_uploadstblogs_upload_strategies.py
Update usb_log_validation_gtest.cpp

Add conditional compilation for GTEST_ENABLE

Update Makefile.am

Update Makefile.am

Update usb_log_file_manager_gtest.cpp

Update usb_log_main_gtest.cpp

Update unit_test.sh

Update unit_test.sh

Update unit_test.sh

Update unit_test.sh

Update unit_test.sh

Update unit_test.sh

Update directory path for unit tests

Update unit_test.sh

Update unit_test.sh

Update unit_test.sh

Create configure.ac

Update Makefile.am

Update Makefile.am

Update Makefile.am

Update Makefile.am

Update usb_log_file_manager_gtest.cpp

Update usb_log_main_gtest.cpp

Update usb_log_main_gtest.cpp

Update usb_log_file_manager_gtest.cpp

Update usb_log_main_gtest.cpp

Update usb_log_main_gtest.cpp

Update unit_test.sh

Update Makefile.am

Update unit_test.sh

Update unit_test.sh

Update usb_log_file_manager_gtest.cpp

Update unit_test.sh

Update usb_log_file_manager_gtest.cpp

Update Makefile.am

Update Makefile.am

Update Makefile.am

Update usb_log_file_manager_gtest.cpp

Update usb_log_file_manager_gtest.cpp

Update Makefile.am

Update usb_log_file_manager_gtest.cpp

Update usb_log_file_manager_gtest.cpp

Update usb_log_file_manager_gtest.cpp

Update unit_test.sh

Create usb_log_archive_gtest.cpp

Update Makefile.am

Update Makefile.am

Implement unit tests for usb_log_utils

Added unit tests for usb_log_utils functions including initialization, timestamp retrieval, filesystem sync, and file copy operations.

Update Makefile.am

Update unit_test.sh

Remove unnecessary empty line in unit_test.sh

Update unit_test.sh

Update unit_test.sh

Remove echo command from unit_test.sh

Remove unnecessary echo command from script

Update unit_test.sh to set RDK_PROFILE

Add RDK_PROFILE to device properties and update includes

Update usb_log_file_manager_gtest.cpp

Update usb_log_file_manager_gtest.cpp

Remove usb_log_main_gtest from unit tests

Removed usb_log_main_gtest from test execution.

Update usb_log_file_manager_gtest.cpp

Update usb_log_validation_gtest.cpp

Update usb_log_validation_gtest.cpp

Update usb_log_validation_gtest.cpp

Enable coverage options in unit_test.sh

Update usb_log_utils_gtest.cpp

Update copyright and license in usb_log_archive_gtest.cpp

Updated copyright information and license details in the test file.

Update usb_log_archive_gtest.cpp

Update unit_test.sh
Copilot AI review requested due to automatic review settings March 4, 2026 16:08
@Abhinavpv28
Abhinavpv28 requested a review from a team as a code owner March 4, 2026 16:08

Copilot AI left a comment

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.

Pull request overview

Adds unit- and L2-level coverage for the usbLogUpload component and wires it into existing CI/test runners alongside uploadstblogs.

Changes:

  • Introduces new GoogleTest suites for usbLogUpload modules (utils/archive) and updates existing ones (main/validation/file-manager).
  • Adds autotools build scaffolding for usbLogUpload/unittest and updates the repo unit-test runner to build/run the new test executables.
  • Extends L2 test scripts/workflow and adds a new functional test + feature file for usblogupload.

Reviewed changes

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

Show a summary per file
File Description
usbLogUpload/unittest/usb_log_validation_gtest.cpp Updates validation unit tests; adds a custom main() for the gtest executable.
usbLogUpload/unittest/usb_log_utils_gtest.cpp New utils unit test suite with local stubs and a custom main().
usbLogUpload/unittest/usb_log_main_gtest.cpp Adds mock include and custom main() with global mock cleanup.
usbLogUpload/unittest/usb_log_file_manager_gtest.cpp Adds mock include, introduces a remove_directory stub, and adjusts assertions in filesystem tests.
usbLogUpload/unittest/usb_log_archive_gtest.cpp New archive unit test suite with dependency stubs and a custom main().
usbLogUpload/unittest/configure.ac New autotools configure script for usbLogUpload unit tests.
usbLogUpload/unittest/Makefile.am Adds new gtest binaries and link inputs for usbLogUpload unit tests.
usbLogUpload/src/usb_log_main.c Wraps production main() with #ifndef GTEST_ENABLE for unit-test linking.
usbLogUpload/include/usb_log_validation.h Removes the validate_system_prerequisites() declaration.
unit_test.sh Updates unit-test script to build/run usbLogUpload unit tests and adjusts env/properties setup.
test/run_uploadstblogs_l2.sh Improves device properties setup and adds MAC file preparation for L2 runs; adds a usbLogupload pytest run.
test/functional-tests/tests/test_usb_logupload.py New pytest functional test coverage for usblogupload.
test/functional-tests/tests/test_uploadstblogs_normal_upload.py Changes how logupload is invoked (shell + redirection).
test/functional-tests/tests/test_uploadLogsNow.py Changes how uploadlogsnow is invoked (shell + redirection).
test/functional-tests/tests/test_log_upload_onreboot_true_case.py Adjusts assertions to match “library API” logging behavior.
test/functional-tests/tests/test_log_upload_onreboot_false_case.py Adjusts assertions to match “library API” logging behavior.
test/functional-tests/features/usblogupload.feature New feature spec describing USB log upload scenarios.
.github/workflows/L2-tests.yml Enables mTLS in mock-xconf and native-platform containers via env var.

Comment on lines 95 to 99
"""Test: Service collects large log files within limits"""
# Create large test files (10MB each)
large_files = create_large_test_log_files(count=3, size_mb=10)

result = subprocess.run([
"/usr/local/bin/logupload",
"",
"1",
"1",
"true",
"HTTP",
"https://mockxconf:50058/"
])
result = subprocess.run("/usr/local/bin/logupload '' 1 1 true HTTP https://mockxconf:50058/ >> /opt/logs/logupload.log.0",shell=True)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

Same issue here: using shell=True without a timeout and redirecting output to a file reduces test observability and can cause CI hangs. Prefer subprocess.run([...], capture_output=True, text=True, timeout=...) (and write logs explicitly if needed).

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +18
AC_CHECK_LIB([gtest], [main])
AC_CHECK_LIB([gmock], [main])

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

AC_CHECK_LIB([gtest],[main]) / AC_CHECK_LIB([gmock],[main]) is checking for a main symbol inside the gtest/gmock libraries, which is typically only provided by gtest_main (and not by -lgtest/-lgmock). This can make ./configure fail even when gtest/gmock are installed. Update the checks to look for the correct libraries/symbols (e.g., check gtest_main if you want the library-provided main), or remove these AC_CHECK_LIB checks and rely on header/library discovery via your link flags.

Suggested change
AC_CHECK_LIB([gtest], [main])
AC_CHECK_LIB([gmock], [main])
AC_CHECK_LIB([gtest_main], [main])
AC_CHECK_LIB([gmock_main], [main])

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +60
bool remove_directory(const char* dirpath) {
if (!dirpath) return false;
struct stat st;
// Return false if directory does not exist
if (stat(dirpath, &st) != 0 || !S_ISDIR(st.st_mode)) return false;
// Otherwise, simulate success
return true;
}

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

remove_directory is declared with C linkage in this translation unit (because usb_log_file_manager.h is included inside an extern "C" { ... } block), but the definition here has default C++ linkage. That will either fail to compile (conflicting linkage) or fail to link (mangled symbol). Define it with extern "C" to match the declaration, or remove this stub and use the real implementation/mock instead.

Copilot uses AI. Check for mistakes.
Comment on lines 90 to 99
TEST_F(UsbLogFileManagerTest, CreateUsbLogDirectorySuccessTest) {
std::string usb_log_dir = test_usb_path + "/logs";

// Directory should not exist yet
EXPECT_FALSE(access(usb_log_dir.c_str(), F_OK) == 0);

// Create directory should succeed
EXPECT_EQ(create_usb_log_directory(usb_log_dir.c_str()), 0);

// Directory should now exist
EXPECT_TRUE(access(usb_log_dir.c_str(), F_OK) == 0);

}

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

CreateUsbLogDirectorySuccessTest no longer verifies that the directory was actually created (it only checks the return code). With the file-ops mocking in place, this test can pass even if create_usb_log_directory() becomes a no-op. Add an assertion that the directory exists after the call, or assert that the underlying directory-creation operation/mock was invoked with the expected path.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines 199 to 215
TEST_F(UsbLogFileManagerTest, CleanupTemporaryFilesSuccessTest) {
std::string temp_cleanup_dir = test_temp_path + "/cleanup_test";
mkdir(temp_cleanup_dir.c_str(), 0755);

// Create some test files
std::string test_file = temp_cleanup_dir + "/test.log";
FILE* f = fopen(test_file.c_str(), "w");
fprintf(f, "Test content");
fclose(f);

// Directory should exist
EXPECT_TRUE(access(temp_cleanup_dir.c_str(), F_OK) == 0);

// Cleanup should succeed
EXPECT_EQ(cleanup_temporary_files(temp_cleanup_dir.c_str()), 0);

// Directory should be removed
EXPECT_FALSE(access(temp_cleanup_dir.c_str(), F_OK) == 0);

}

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

CleanupTemporaryFilesSuccessTest no longer checks that the temporary directory was actually removed. As written, the test can pass even if cleanup_temporary_files() doesn't perform any cleanup (especially with the current remove_directory stub). Add a post-condition assertion (directory is gone) or verify the cleanup operation via the mock to ensure the behavior is really exercised.

Copilot generated this review using guidance from repository custom instructions.
Comment thread unit_test.sh
export top_srcdir=`pwd`

export LD_LIBRARY_PATH="/usr/local/lib:$TOP_DIR/uploadstblogs/src/.libs:$LD_LIBRARY_PATH"
echo "RDK_PROFILE=TV" >> /etc/device.properties

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

Appending RDK_PROFILE=TV to /etc/device.properties on every run (>>) can create multiple RDK_PROFILE entries, which may lead to ambiguous parsing depending on how properties are read. Prefer idempotent update logic (replace existing key if present, otherwise append) similar to what’s done in test/run_uploadstblogs_l2.sh.

Suggested change
echo "RDK_PROFILE=TV" >> /etc/device.properties
if grep -q '^RDK_PROFILE=' /etc/device.properties 2>/dev/null; then
sed -i 's/^RDK_PROFILE=.*/RDK_PROFILE=TV/' /etc/device.properties
else
echo "RDK_PROFILE=TV" >> /etc/device.properties
fi

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +33
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$TOP_DIR/uploadstblogs/src/.libs:$LD_LIBRARY_PATH"

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

These export LD_LIBRARY_PATH=... lines are evaluated by make, so $TOP_DIR will be treated as a make variable (e.g., $T + OP_DIR...) and will not expand to the shell environment variable you set in unit_test.sh. This can result in an incorrect LD_LIBRARY_PATH during build/test runs. Prefer setting LD_LIBRARY_PATH in the test runner script/CI environment (or use AM_TESTS_ENVIRONMENT with $$TOP_DIR if you truly need a make-time export).

Suggested change
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$TOP_DIR/uploadstblogs/src/.libs:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH=/usr/local/lib:$$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$$TOP_DIR/uploadstblogs/src/.libs:$$LD_LIBRARY_PATH"

Copilot uses AI. Check for mistakes.
Comment thread unit_test.sh

make clean
make
echo "RDK_PROFILE=TV" >> /etc/device.properties

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

This second unconditional append of RDK_PROFILE=TV can further duplicate the key in /etc/device.properties, which can cause non-deterministic behavior if the reader takes the first/last occurrence. Consider making the update idempotent (replace if present) and do it only once per script run.

Copilot uses AI. Check for mistakes.
"""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)
result = subprocess.run("/usr/local/bin/logupload uploadlogsnow >> /opt/logs/logupload.log.0",shell=True)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

subprocess.run(...) was changed to a shell command with output redirection and no timeout/capture_output. This makes the test less debuggable (stdout/stderr are lost to the test runner) and can cause CI hangs if the command blocks. Prefer passing args as a list (no shell), keep a timeout, and capture output so failures are actionable.

Suggested change
result = subprocess.run("/usr/local/bin/logupload uploadlogsnow >> /opt/logs/logupload.log.0",shell=True)
cmd = ["/usr/local/bin/logupload", "uploadlogsnow"]
result = sp.run(cmd, capture_output=True, text=True, timeout=60)

Copilot uses AI. Check for mistakes.
Comment on lines +57 to +58
result = subprocess.run("/usr/local/bin/logupload '' 1 1 true HTTP https://mockxconf:50058/ >> /opt/logs/logupload.log.0",shell=True)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

Switching to shell=True with output redirection removes any timeout/capture of stdout/stderr and can hide failures or hang CI if logupload blocks. Prefer invoking the binary with an argument list (no shell), adding a timeout, and capturing output so assertions and failure logs remain reliable.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings March 4, 2026 17:04

Copilot AI left a comment

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.

Pull request overview

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

Comment on lines +23 to +28
// Mocks and stubs for dependencies
extern "C" {
int get_current_timestamp(char *buf, size_t len) {
strncpy(buf, "01/01/26-12:00:00", len-1);
buf[len-1] = '\0';
return 0;

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

This file uses strncpy but doesn’t include <cstring>/<string.h>. Depending on transitive includes this can fail to compile. Add the appropriate header explicitly.

Copilot uses AI. Check for mistakes.
Comment on lines 35 to 38
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)
result = subprocess.run("/usr/local/bin/logupload uploadlogsnow >> /opt/logs/logupload.log.0",shell=True)
return result

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

run_uploadlogsnow() no longer sets a timeout or captures stdout/stderr. If logupload hangs in CI, this test suite can block indefinitely, and failures become harder to diagnose. Consider restoring a bounded timeout and capturing output (or at least enabling it on failure) instead of relying on shell redirection.

Copilot uses AI. Check for mistakes.
Comment on lines 55 to 60
# Run uploadSTBLogs
#result = run_uploadstblogs()

result = subprocess.run([
"/usr/local/bin/logupload",
"",
"1",
"1",
"true",
"HTTP",
"https://mockxconf:50058/"
])


result = subprocess.run("/usr/local/bin/logupload '' 1 1 true HTTP https://mockxconf:50058/ >> /opt/logs/logupload.log.0",shell=True)

# Verify initialization
assert result.returncode == 0 or result.returncode == 1, "Upload process should complete"

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

These calls switched to shell=True without any timeout or captured output. That makes the tests vulnerable to hanging indefinitely in CI and reduces debuggability when failures occur. Prefer subprocess.run([...], timeout=..., capture_output=True, text=True) (or reuse run_uploadstblogs() from uploadstblogs_helper.py) and write logs conditionally on failure.

Copilot uses AI. Check for mistakes.
Comment thread test/run_l2.sh

pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py

cat /opt/logs/dcmd.log.0

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

cat /opt/logs/dcmd.log.0 will dump the entire log into CI output, which can be very large and may contain sensitive data. Consider tailing a small number of lines, gating it behind a failure condition, or removing it entirely.

Suggested change
cat /opt/logs/dcmd.log.0
tail -n 200 /opt/logs/dcmd.log.0

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +57
bool remove_directory(const char* dirpath) {
if (!dirpath) return false;
struct stat st;
// Return false if directory does not exist
if (stat(dirpath, &st) != 0 || !S_ISDIR(st.st_mode)) return false;

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

remove_directory is declared with C linkage via file_operations.h (included through the surrounding extern "C"), but it’s defined here with C++ linkage. This will typically fail to compile due to conflicting language linkage. Define it inside an extern "C" block (matching the header) or rename it to avoid clashing with the production symbol.

Copilot uses AI. Check for mistakes.
Comment thread unit_test.sh
Comment on lines +69 to 72
make clean
make
echo "RDK_PROFILE=TV" >> /etc/device.properties
fail=0

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

RDK_PROFILE=TV is appended a second time later in the script, which further increases the chance of duplicated keys in /etc/device.properties. If the profile must be enforced, do it once using an idempotent replace-or-add approach.

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +40
# Path to device.properties for test
device_properties_path = os.path.join(os.path.dirname(__file__), "device.properties")
backup_path = device_properties_path + ".bak"
# Backup original if exists
if os.path.exists(device_properties_path):
os.rename(device_properties_path, backup_path)
# Ensure RDK_PROFILE=TV is present
with open(device_properties_path, "w", encoding="utf-8") as f:
f.write("RDK_PROFILE=TV\n")
yield
# Restore original after test
if os.path.exists(backup_path):
os.remove(device_properties_path)
os.rename(backup_path, device_properties_path)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

This fixture writes device.properties next to the test file, but the code under test reads properties via getDevicePropertyData (typically backed by /etc/device.properties). As-is, the fixture likely has no effect on usblogupload behavior and can give false confidence. Consider updating /etc/device.properties in an idempotent way (or mocking getDevicePropertyData) instead of creating a local file.

Suggested change
# Path to device.properties for test
device_properties_path = os.path.join(os.path.dirname(__file__), "device.properties")
backup_path = device_properties_path + ".bak"
# Backup original if exists
if os.path.exists(device_properties_path):
os.rename(device_properties_path, backup_path)
# Ensure RDK_PROFILE=TV is present
with open(device_properties_path, "w", encoding="utf-8") as f:
f.write("RDK_PROFILE=TV\n")
yield
# Restore original after test
if os.path.exists(backup_path):
os.remove(device_properties_path)
os.rename(backup_path, device_properties_path)
# Path to device.properties used by getDevicePropertyData (typically /etc/device.properties)
device_properties_path = "/etc/device.properties"
file_existed_before = os.path.exists(device_properties_path)
original_content = ""
modified = False
if file_existed_before:
# Read existing content so we can restore it after the test, if we modify it
try:
with open(device_properties_path, "r", encoding="utf-8", errors="ignore") as f:
original_content = f.read()
except OSError:
# If we cannot read the file, do not attempt to modify or restore it
original_content = ""
file_existed_before = False
# Ensure RDK_PROFILE=TV is present during the test
needs_write = True
if file_existed_before and original_content:
if "RDK_PROFILE=TV" in original_content:
needs_write = False
if needs_write:
try:
mode = "a" if file_existed_before else "w"
with open(device_properties_path, mode, encoding="utf-8") as f:
f.write("RDK_PROFILE=TV\n")
modified = True
except OSError:
# If we cannot write, proceed with the test; it may fail appropriately
modified = False
yield
# Restore original state after test if we modified the file
if modified:
try:
if file_existed_before:
with open(device_properties_path, "w", encoding="utf-8") as f:
f.write(original_content)
else:
# File was created by this fixture; remove it
if os.path.exists(device_properties_path):
os.remove(device_properties_path)
except OSError:
# Best-effort restore; ignore errors during cleanup
pass

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings March 4, 2026 17:47

Copilot AI left a comment

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.

Pull request overview

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

Comments suppressed due to low confidence (1)

test/run_uploadstblogs_l2.sh:67

  • This script edits source code in /usr/common_utilities to disable SSL verification and comment out auth logic. That can mask real security behavior and may affect other test suites running in the same environment. Consider limiting these changes to a controlled mock/test configuration (or revert the edits after the tests complete).
cd /usr/common_utilities
sed -i '/file_upload\.sslverify/s/= 1;/= 0;/' uploadutils/mtls_upload.c
sed -i 's/\(ret_code = setCommonCurlOpt(curl, s3url, NULL, \)true\()\)/\1false\2/g' uploadutils/uploadUtil.c
sed -i '/if (auth) {/,/}/s/^/\/\/ /' uploadutils/uploadUtil.c

#include "usb_log_archive.h"
#include <string>
#include <cstdio>
#include <sys/stat.h>

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

This file uses strncpy and rmdir but does not include the headers that declare them (<cstring>/<string.h> for strncpy, <unistd.h> for rmdir). This is likely to fail compilation with stricter toolchains.

Suggested change
#include <sys/stat.h>
#include <sys/stat.h>
#include <cstring>
#include <unistd.h>

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +27
strncpy(buf, "01/01/26-12:00:00", len-1);
buf[len-1] = '\0';

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

get_current_timestamp stub writes to buf[len-1] and passes len-1 to strncpy without guarding len == 0. If the production code ever calls this with a zero-length buffer, this becomes an out-of-bounds write in the test binary. Consider returning an error when len == 0 (or ensuring the stub matches production validation).

Suggested change
strncpy(buf, "01/01/26-12:00:00", len-1);
buf[len-1] = '\0';
if (buf == NULL || len == 0) {
return -1;
}
strncpy(buf, "01/01/26-12:00:00", len - 1);
buf[len - 1] = '\0';

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +86
logs = grep_usblogupload_logs(":.*File:")
# This checks for the log line with MAC address and file name
# (Regex match, may need adjustment based on actual log format)
assert result.returncode in (0, 3), "Should exit with success or write error code"

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

grep_usblogupload_logs escapes the search string, so patterns like ":.*File:" are treated literally (not as regex). In test_usblogupload_mac_address_log this likely never matches. If a regex match is intended, either add a separate helper that does regex matching or avoid re.escape for that call site.

Copilot uses AI. Check for mistakes.
Comment on lines +42 to +67
def test_usblogupload_missing_log_path(self, tmp_path):
# Simulate missing log path by passing a non-existent mount point
usb_mount = str(tmp_path / "not_a_mount")
result = subprocess.run([USBLOGUPLOAD_BIN, usb_mount], capture_output=True, text=True)
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(result.stdout)
f.write(result.stderr)
assert result.returncode == 2 or result.returncode == 3, "Should fail with USB not mounted or write error"
logs = grep_usblogupload_logs("Failed")
# Accept log file or process output containing 'fail', 'error', or 'not mounted'
output = (result.stdout + result.stderr).lower()
assert (
logs or
"fail" in output or
"error" in output or
"not mounted" in output
), (
f"Should log a failure message. Got stdout: {result.stdout}, stderr: {result.stderr}"
)

def test_usblogupload_archive_creation(self, tmp_path):
# Simulate a valid mount and check for archive creation log
usb_mount = tmp_path / "usb"
usb_mount.mkdir()
result = subprocess.run([USBLOGUPLOAD_BIN, str(usb_mount)], capture_output=True, text=True)
with open(LOG_FILE, "a", encoding="utf-8") as f:

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

All subprocess.run(...) calls here lack a timeout. If usblogupload blocks (e.g., waiting on I/O), these tests can hang the entire suite. Consider adding a reasonable timeout per invocation and reporting stdout/stderr on timeout to aid debugging.

Copilot uses AI. Check for mistakes.
Comment thread unit_test.sh

make clean
make
pwd

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

pwd at this point looks like leftover debug output and will add noise to CI logs. Consider removing it (or use it consistently with a label if it’s needed for debugging).

Suggested change
pwd

Copilot uses AI. Check for mistakes.
Comment on lines 55 to +58
# Run uploadSTBLogs
#result = run_uploadstblogs()

result = subprocess.run([
"/usr/local/bin/logupload",
"",
"1",
"1",
"true",
"HTTP",
"https://mockxconf:50058/"
])


result = subprocess.run("/usr/local/bin/logupload '' 1 1 true HTTP https://mockxconf:50058/ >> /opt/logs/logupload.log.0",shell=True)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

This test file uses subprocess.run(...) but does not import subprocess. Unless subprocess is injected via one of the star-imported helpers (unlikely and non-obvious), this will raise NameError and fail the test.

Copilot uses AI. Check for mistakes.
Comment on lines 44 to 46
usb_log_file_manager_gtest_SOURCES = usb_log_file_manager_gtest.cpp \
../src/usb_log_file_manager.c
../src/usb_log_file_manager.c ../src/usb_log_utils.c ../../uploadstblogs/unittest/mocks/mock_file_operations.cpp

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

mock_file_operations.cpp is added to the test sources, but COMMON_CPPFLAGS does not include ../../uploadstblogs/unittest/mocks. Since mock_file_operations.cpp includes "mock_file_operations.h" (no relative path), this will fail to compile unless the mocks directory is added to the include path (or the include in that file is changed).

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +48
USBLOGUPLOAD_BIN = "/usr/local/bin/usblogupload"
LOG_FILE = "/opt/logs/logupload.log" # Adjust if needed

# Helper to grep logs

def grep_usblogupload_logs(search: str):
search_result = []
search_pattern = re.compile(re.escape(search), re.IGNORECASE)
try:
with open(LOG_FILE, 'r', encoding='utf-8', errors='ignore') as file:
for line in file:
if search_pattern.search(line):
search_result.append(line)
except Exception as e:
print(f"Could not read file {LOG_FILE}: {e}")
return search_result


@pytest.fixture(autouse=True)
def setup_device_properties(tmp_path):
# Path to device.properties for test
device_properties_path = os.path.join(os.path.dirname(__file__), "device.properties")
backup_path = device_properties_path + ".bak"
# Backup original if exists
if os.path.exists(device_properties_path):
os.rename(device_properties_path, backup_path)
# Ensure RDK_PROFILE=TV is present
with open(device_properties_path, "w", encoding="utf-8") as f:
f.write("RDK_PROFILE=TV\n")
yield
# Restore original after test
if os.path.exists(backup_path):
os.remove(device_properties_path)
os.rename(backup_path, device_properties_path)

class TestUSBLogUpload:
def test_usblogupload_missing_log_path(self, tmp_path):
# Simulate missing log path by passing a non-existent mount point
usb_mount = str(tmp_path / "not_a_mount")
result = subprocess.run([USBLOGUPLOAD_BIN, usb_mount], capture_output=True, text=True)
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(result.stdout)
f.write(result.stderr)

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

LOG_FILE is under /opt/logs, but the tests append to it without ensuring the directory exists. If /opt/logs is missing in the environment, open(LOG_FILE, "a") will raise and fail the test before any assertions. Consider creating the directory/file in a fixture (or using tmp_path for per-test logs).

Copilot uses AI. Check for mistakes.
echo "BUILD_TYPE=dev" >> /etc/device.properties
fi

echo "AA:BB:CC:dd:EE:FF" >> /tmp/.estb_mac

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

echo "AA:BB:CC:dd:EE:FF" >> /tmp/.estb_mac appends a new MAC each run, which can change behavior if the consumer reads the first/last line. Prefer overwriting (>), or ensure the file is cleaned before writing to keep tests deterministic.

Suggested change
echo "AA:BB:CC:dd:EE:FF" >> /tmp/.estb_mac
echo "AA:BB:CC:dd:EE:FF" > /tmp/.estb_mac

Copilot uses AI. Check for mistakes.
Comment thread test/run_l2.sh

pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py

cat /opt/logs/dcmd.log.0

Copilot AI Mar 4, 2026

Copy link

Choose a reason for hiding this comment

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

Unconditionally cat-ing /opt/logs/dcmd.log.0 can flood CI logs and may fail if the file doesn’t exist yet. Consider guarding it (e.g., only print on failure, or check existence and tail a limited number of lines).

Suggested change
cat /opt/logs/dcmd.log.0
if [ -f /opt/logs/dcmd.log.0 ]; then
echo "Last 200 lines of /opt/logs/dcmd.log.0:"
tail -n 200 /opt/logs/dcmd.log.0
fi

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings March 5, 2026 00:46
Removed the execution of 'run_l2.sh' from the test command in the native-platform container.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 11 comments.

Comments suppressed due to low confidence (1)

unit_test.sh:53

  • unit_test.sh clones external GitHub repositories (iarmmgrs, rdk_logger) and invokes cov_build.sh, which itself clones and builds additional external code, all from mutable branch heads. This makes every test run execute remote code with the privileges and secrets of the CI/device environment if any of those repositories or the network path are compromised. Pin each git clone to an immutable commit or vetted release tag (or vendor the dependencies) so the test runner no longer fetches and executes unverified code at runtime.
cd ../..
sh cov_build.sh
cd -
git clone https://github.com/rdkcentral/iarmmgrs.git
cp iarmmgrs/sysmgr/include/sysMgr.h /usr/local/include
cp iarmmgrs/maintenance/include/maintenanceMGR.h /usr/local/include
git clone https://github.com/rdkcentral/rdk_logger.git
cp rdk_logger/include/rdk_logger.h /usr/local/include

Comment on lines +17 to +19
AC_CHECK_LIB([gtest], [main])
AC_CHECK_LIB([gmock], [main])

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

AC_CHECK_LIB([gtest], [main]) / AC_CHECK_LIB([gmock], [main]) is brittle: many installations provide main() in libgtest_main instead of libgtest, and these unit tests now provide their own main() anyway. Consider checking for a gtest symbol other than main (or linking -lgtest_main and removing per-test main()), to avoid configure failures on standard gtest packages.

Suggested change
AC_CHECK_LIB([gtest], [main])
AC_CHECK_LIB([gmock], [main])
dnl Use a C++ link test for Google Test and Google Mock instead of checking for main().
AC_LANG_PUSH([C++])
dnl Check for Google Test library
AC_CACHE_CHECK([for Google Test library], [ac_cv_lib_gtest], [
save_LIBS="$LIBS"
LIBS="$LIBS -lgtest"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <gtest/gtest.h>]],
[[int argc = 0;
char **argv = 0;
::testing::InitGoogleTest(&argc, argv);
return 0;]])],
[ac_cv_lib_gtest=yes],
[ac_cv_lib_gtest=no])
LIBS="$save_LIBS"
])
if test "x$ac_cv_lib_gtest" = xyes; then
LIBS="$LIBS -lgtest"
AC_DEFINE([HAVE_LIBGTEST], [1],
[Define to 1 if you have the Google Test library.])
fi
dnl Check for Google Mock library (typically depends on gtest)
AC_CACHE_CHECK([for Google Mock library], [ac_cv_lib_gmock], [
save_LIBS="$LIBS"
LIBS="$LIBS -lgmock -lgtest"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <gmock/gmock.h>]],
[[int argc = 0;
char **argv = 0;
::testing::InitGoogleMock(&argc, argv);
return 0;]])],
[ac_cv_lib_gmock=yes],
[ac_cv_lib_gmock=no])
LIBS="$save_LIBS"
])
if test "x$ac_cv_lib_gmock" = xyes; then
LIBS="$LIBS -lgmock -lgtest"
AC_DEFINE([HAVE_LIBGMOCK], [1],
[Define to 1 if you have the Google Mock library.])
fi
AC_LANG_POP([C++])

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +35
@pytest.fixture(autouse=True)
def setup_device_properties(tmp_path):
# Path to device.properties for test
device_properties_path = os.path.join(os.path.dirname(__file__), "device.properties")
backup_path = device_properties_path + ".bak"
# Backup original if exists
if os.path.exists(device_properties_path):
os.rename(device_properties_path, backup_path)
# Ensure RDK_PROFILE=TV is present
with open(device_properties_path, "w", encoding="utf-8") as f:
f.write("RDK_PROFILE=TV\n")
yield

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

The fixture writes RDK_PROFILE=TV to a device.properties file in the test directory, but usblogupload reads device properties via getDevicePropertyData() (typically backed by /etc/device.properties). As written, this setup likely has no effect on the binary under test. Consider updating /etc/device.properties (with proper backup/restore) or stubbing getDevicePropertyData() for this test environment.

Copilot uses AI. Check for mistakes.

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "../../uploadstblogs/unittest/mocks/mock_file_operations.h"

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

ExecuteWithValidInputTest in this file expects usb_log_upload_execute("/tmp/test_usb") to return USB_LOG_SUCCESS, but the test never creates that mount-point directory. Because validate_usb_mount_point() uses access() directly, the call will fail on a clean system. Create the directory in the test (and clean it up) or adjust the expectation/mocking so the test matches real behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +28
int getDevicePropertyData(const char*, char* buf, size_t) { strcpy(buf, "false"); return UTILS_SUCCESS; }
int getIncludePropertyData(const char*, char* buf, size_t) { strcpy(buf, "/opt/logs"); return UTILS_SUCCESS; }

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

The getDevicePropertyData() / getIncludePropertyData() stubs ignore the provided buffer length and use strcpy(). Even in tests, it’s better to respect the size_t parameter (e.g., bounded copy + explicit NUL termination) to avoid accidental overflows if the production code calls these with smaller buffers in the future.

Suggested change
int getDevicePropertyData(const char*, char* buf, size_t) { strcpy(buf, "false"); return UTILS_SUCCESS; }
int getIncludePropertyData(const char*, char* buf, size_t) { strcpy(buf, "/opt/logs"); return UTILS_SUCCESS; }
int getDevicePropertyData(const char*, char* buf, size_t bufSize)
{
if (buf == nullptr || bufSize == 0U) {
return UTILS_SUCCESS;
}
std::snprintf(buf, bufSize, "false");
return UTILS_SUCCESS;
}
int getIncludePropertyData(const char*, char* buf, size_t bufSize)
{
if (buf == nullptr || bufSize == 0U) {
return UTILS_SUCCESS;
}
std::snprintf(buf, bufSize, "/opt/logs");
return UTILS_SUCCESS;
}

Copilot uses AI. Check for mistakes.
Comment thread cov_build.sh
Comment on lines 57 to 59
cd ${ROOT}
git clone https://github.com/rdkcentral/common_utilities.git -b feature/upload_L2
git clone https://github.com/rdkcentral/common_utilities.git
cd common_utilities

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

cov_build.sh now clones common_utilities without pinning a branch/tag/commit. This makes CI non-deterministic and can break builds when upstream changes. Prefer pinning to a known-good branch or commit SHA (and documenting it) to keep L2/Coverage runs reproducible.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +46
int copy_file_and_delete(const char *src, const char *dst) {
// Simulate successful copy
return 0;
}
void RDK_LOG(int level, int module, const char *fmt, ...) {}
}

class UsbLogArchiveTest : public ::testing::Test {
protected:
std::string temp_dir;
void SetUp() override {
temp_dir = "./test_usb_log_dir";
mkdir(temp_dir.c_str(), 0777);
}
void TearDown() override {
rmdir(temp_dir.c_str());
}

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

The copy_file_and_delete() stub always returns success without creating the destination file or deleting the source. Since create_usb_log_archive() (via create_archive()) will likely generate a real .tgz inside temp_dir, TearDown()'s rmdir(temp_dir) can fail because the directory is not empty. Make the stub simulate the expected copy+delete (or update teardown to remove the directory contents) so the test is self-cleaning and accurately validates behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +39
if grep -q '^RDK_PROFILE=' /etc/device.properties; then
sed -i 's/^RDK_PROFILE=.*/RDK_PROFILE=TV/' /etc/device.properties
else
echo 'RDK_PROFILE=TV' >> /etc/device.properties
fi

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

grep -q '^RDK_PROFILE=' /etc/device.properties is run before ensuring /etc/device.properties exists. If the file is missing, grep will emit an error to stderr (even though the script continues). Consider touching/creating /etc/device.properties before this block to keep the script clean and predictable.

Copilot uses AI. Check for mistakes.
Comment on lines 40 to 50
static int remove_directory_recursive(const char *path) {
if (ftw(path, [](const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
if (typeflag == FTW_DP)
rmdir(fpath);
else if (typeflag == FTW_F || typeflag == FTW_SL)
unlink(fpath);
return 0;
}, 20) != 0) {
return -1;
}
return rmdir(path);

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

remove_directory_recursive() calls ftw() but checks for FTW_DP/FTW_SL typeflags. Those constants are used with nftw() (post-order traversal) and won’t be produced by ftw(), which means subdirectories won’t get removed and the final rmdir(path) can fail. Consider switching to nftw(..., FTW_DEPTH | FTW_PHYS) or handling FTW_D properly so the test cleanup actually deletes nested directories.

Copilot uses AI. Check for mistakes.
Comment on lines 90 to +98
TEST_F(UsbLogFileManagerTest, CreateUsbLogDirectorySuccessTest) {
std::string usb_log_dir = test_usb_path + "/logs";

// Directory should not exist yet
EXPECT_FALSE(access(usb_log_dir.c_str(), F_OK) == 0);

// Create directory should succeed
EXPECT_EQ(create_usb_log_directory(usb_log_dir.c_str()), 0);

// Directory should now exist
EXPECT_TRUE(access(usb_log_dir.c_str(), F_OK) == 0);

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

CreateUsbLogDirectorySuccessTest only asserts the return code and no longer verifies the observable behavior (that the directory was actually created). Adding an assertion that the directory exists after create_usb_log_directory() will make the test meaningful and help prevent regressions.

Copilot generated this review using guidance from repository custom instructions.
Comment thread cov_build.sh
Comment on lines 41 to +61
git clone https://github.com/rdkcentral/iarmmgrs.git
cp iarmmgrs/sysmgr/include/sysMgr.h /usr/local/include
cp iarmmgrs/maintenance/include/maintenanceMGR.h /usr/local/include

cd ${ROOT}
rm -rf rdk_logger
git clone https://github.com/rdkcentral/rdk_logger.git
cp rdk_logger/include/* /usr/local/include

cd ${ROOT}
rm -rf telemetry
git clone https://github.com/rdkcentral/telemetry.git
cd telemetry
cp include/*.h /usr/local/include
sh build_inside_container.sh

cd ${ROOT}
git clone https://github.com/rdkcentral/common_utilities.git -b feature/upload_L2
git clone https://github.com/rdkcentral/common_utilities.git
cd common_utilities
autoreconf -i
./configure --enable-rdkcertselector --prefix=${INSTALL_DIR} CFLAGS="-Wno-stringop-truncation -DL2_TEST_ENABLED -DRDK_LOGGER"
./configure --enable-rdkcertselector --enable-mountutils --prefix=${INSTALL_DIR} CFLAGS="-Wno-stringop-truncation -DL2_TEST_ENABLED -DRDK_LOGGER"

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

This script git clones several external repositories (iarmmgrs, rdk_logger, telemetry, common_utilities) from GitHub using mutable branch heads, then builds/installs them, which is a classic supply-chain risk. If any of these repos or the network path is compromised, an attacker can execute arbitrary code in your build/test environment with access to secrets and build artifacts. Pin these dependencies to immutable commit hashes or vetted release tags (or vendor the sources locally) so CI does not fetch and run unverified remote code on each run.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings March 5, 2026 01:04

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.

Comment on lines +60 to +66
fputs("testdata", f);
fclose(f);

EXPECT_EQ(copy_file_and_delete(src, dst), 0);

FILE* f2 = fopen(dst, "r");
ASSERT_NE(f2, nullptr);

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

fopen() isn’t checked for failure before writing; if the test runs in an environment where the working directory is not writable, this will segfault. Add assertions that f/f2 are non-null (and handle cleanup) so failures are reported cleanly.

Suggested change
fputs("testdata", f);
fclose(f);
EXPECT_EQ(copy_file_and_delete(src, dst), 0);
FILE* f2 = fopen(dst, "r");
ASSERT_NE(f2, nullptr);
ASSERT_NE(f, nullptr) << "Failed to open source file for writing";
if (f == nullptr) {
return;
}
fputs("testdata", f);
fclose(f);
EXPECT_EQ(copy_file_and_delete(src, dst), 0);
FILE* f2 = fopen(dst, "r");
ASSERT_NE(f2, nullptr) << "Failed to open destination file for reading";
if (f2 == nullptr) {
unlink(dst);
return;
}

Copilot uses AI. Check for mistakes.
Comment on lines +32 to 34
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$TOP_DIR/uploadstblogs/src/.libs:$LD_LIBRARY_PATH"

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

The two export LD_LIBRARY_PATH=... lines are fragile in Automake: the second assignment overwrites the first, uses an undefined TOP_DIR make variable (expands to empty), and includes quotes that will become part of the value. This can result in an incorrect LD_LIBRARY_PATH during builds/runs. Prefer setting LD_LIBRARY_PATH in the test runner scripts (as you already do in unit_test.sh) or use an rpath (-Wl,-rpath,...) / AM_LDFLAGS for test binaries instead of exporting it here.

Suggested change
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$TOP_DIR/uploadstblogs/src/.libs:$LD_LIBRARY_PATH"

Copilot uses AI. Check for mistakes.
- name: Enter Inside Platform native container and run L2 Test
run: |
docker exec -i native-platform /bin/bash -c "cd /mnt/L2_CONTAINER_SHARED_VOLUME/ && sh cov_build.sh && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu:/lib/aarch64-linux-gnu:/usr/local/lib: && sh test/run_l2.sh && sh test/run_uploadstblogs_l2.sh"
docker exec -i native-platform /bin/bash -c "cd /mnt/L2_CONTAINER_SHARED_VOLUME/ && sh cov_build.sh && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu:/lib/aarch64-linux-gnu:/usr/local/lib: && sh test/run_uploadstblogs_l2.sh"

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

The workflow no longer runs test/run_l2.sh, so the DCM/L2 suites executed there (boot sequence, cron cases, etc.) won’t run in CI anymore. If the intent is to narrow coverage to uploadstblogs/usblogupload only, consider either adding those checks into run_uploadstblogs_l2.sh or running both scripts to avoid silently dropping coverage.

Suggested change
docker exec -i native-platform /bin/bash -c "cd /mnt/L2_CONTAINER_SHARED_VOLUME/ && sh cov_build.sh && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu:/lib/aarch64-linux-gnu:/usr/local/lib: && sh test/run_uploadstblogs_l2.sh"
docker exec -i native-platform /bin/bash -c "cd /mnt/L2_CONTAINER_SHARED_VOLUME/ && sh cov_build.sh && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu:/lib/aarch64-linux-gnu:/usr/local/lib: && sh test/run_l2.sh && sh test/run_uploadstblogs_l2.sh"

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +61
bool remove_directory(const char* dirpath) {
if (!dirpath) return false;
struct stat st;
// Return false if directory does not exist
if (stat(dirpath, &st) != 0 || !S_ISDIR(st.st_mode)) return false;
// Otherwise, simulate success
return true;
}

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

This remove_directory definition is unused (no references in this test file) and, because it lacks extern "C", it will not override the C remove_directory() symbol that usb_log_file_manager.c calls. If the intent is to mock remove_directory for cleanup_temporary_files(), add it to the existing mock_file_operations shim (with C linkage) and drive it via g_mockFileOperations, or remove this function to avoid confusion.

Suggested change
bool remove_directory(const char* dirpath) {
if (!dirpath) return false;
struct stat st;
// Return false if directory does not exist
if (stat(dirpath, &st) != 0 || !S_ISDIR(st.st_mode)) return false;
// Otherwise, simulate success
return true;
}

Copilot uses AI. Check for mistakes.
Comment thread test/run_l2.sh
pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_true_test.json test/functional-tests/tests/test_log_upload_onreboot_true_case.py

pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py
#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

This script now skips the test_log_upload_onreboot_false_case.py suite entirely. If this is intended, it should be documented and/or replaced with an equivalent assertion elsewhere; otherwise it reduces L2 coverage and can hide regressions for the "onreboot=false" path.

Suggested change
#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py
pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py

Copilot uses AI. Check for mistakes.
Comment on lines +98 to 99
result = subprocess.run("/usr/local/bin/logupload '' 1 1 true HTTP https://mockxconf:50058/ >> /opt/logs/logupload.log.0",shell=True)

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

Same issue here: using shell=True with a single command string (and '') changes argv compared to the previous list-form invocation, and removes the ability to easily capture stdout/stderr for assertions. Prefer passing an argv list (including an explicit empty-string argument if needed) and adding a timeout/capture for reliability.

Copilot uses AI. Check for mistakes.
Abhinav P V added 2 commits March 5, 2026 02:13
Copilot AI review requested due to automatic review settings March 5, 2026 02:19

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 4 comments.

Comment thread test/run_l2.sh
Comment on lines +45 to +47
#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py

cat /opt/logs/dcmd.log.0

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

Commenting out the log_upload_onreboot_false_case pytest invocation reduces L2 coverage, and cat /opt/logs/dcmd.log.0 can produce very large CI logs (and is noisy even on success). If this is temporary debugging, consider reverting it or gating the cat behind a failure condition / debug flag.

Suggested change
#pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py
cat /opt/logs/dcmd.log.0
pytest -v --json-report --json-report-summary --json-report-file $RESULT_DIR/log_upload_reboot_false_test.json test/functional-tests/tests/test_log_upload_onreboot_false_case.py
if [ "${DCM_SHOW_LOGS:-0}" -ne 0 ] && [ -f /opt/logs/dcmd.log.0 ]; then
cat /opt/logs/dcmd.log.0
fi

Copilot uses AI. Check for mistakes.
Comment on lines +24 to 25
#include "../../uploadstblogs/unittest/mocks/mock_file_operations.h"

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

Including mock_file_operations.h implies this test binary is now linking against the mocked create_directory() implementation (from mock_file_operations.cpp), whose default behavior returns success without actually creating directories. With that default, usb_log_upload_execute() can fail later (e.g., create_temporary_directory() checks access() on the created path). Consider either initializing g_mockFileOperations to perform realistic directory creation / expectations, or updating the test expectations to match the mocked behavior.

Copilot uses AI. Check for mistakes.

def grep_usblogupload_logs(search: str):
search_result = []
search_pattern = re.compile(re.escape(search), re.IGNORECASE)

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

grep_usblogupload_logs() uses re.escape(search), so callers cannot pass regex patterns. Tests later pass strings like ":.*File:" expecting regex matching, which will never work with this helper. Add a regex-based grep helper (no escaping) or change the tests to search for a literal substring.

Suggested change
search_pattern = re.compile(re.escape(search), re.IGNORECASE)
search_pattern = re.compile(search, re.IGNORECASE)

Copilot uses AI. Check for mistakes.
return 0;
}
int copy_file_and_delete(const char *src, const char *dst) {
// Simulate successful copy

Copilot AI Mar 5, 2026

Copy link

Choose a reason for hiding this comment

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

copy_file_and_delete() is stubbed to return success but it doesn’t delete the source archive created by create_archive(). That leaves files inside ./test_usb_log_dir, so TearDown()’s rmdir() will fail (directory not empty) and can make the suite flaky. Either have the stub simulate deletion of the source path, or explicitly remove the generated archive(s) in TearDown() (e.g., unlink + rmdir).

Suggested change
// Simulate successful copy
(void)dst; /* Destination is not used in this stub */
if (src != NULL) {
/* Simulate deletion of the source archive so temp_dir can be removed */
(void)remove(src);
}
/* Always report success to match stub semantics */

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.

2 participants