From e2128af4c2be4db00de893469b5c8d74ccf079e1 Mon Sep 17 00:00:00 2001 From: pengfeixx <63588879+pengfeixx@users.noreply.github.com> Date: Wed, 28 Oct 2026 12:32:42 +0800 Subject: [PATCH] fix(test): repair UT build and sanitizer failures after coverage series merge The merged coverage-series test suites failed to build and run as a whole. This fixes the integration issues found in a full-tree build: - tests/CMakeLists.txt: compile cliapplicationhelper.cpp, logtableview.cpp and logViewerService/logviewerservice.cpp into the test target; add logViewerService/ logViewerAuth/ include dirs; link Qt6 Gui/Core private modules; register org_deepin_log_viewer.hpp for AUTOMOC (replaces the hand-written moc file) - restore 8 lines mangled by a credential redaction filter in ut_dldbushandler.cpp / ut_userlogaccess.cpp / ut_logviewerservice.cpp (openLogStream token retrieval calls) - ut_displaycontent.cpp: define the missing LogFileParser_parseByAudit/ parseByAuth/parseByCoredump stub functions - ut_loglistview.cpp / ut_logauththread.cpp: make duplicate stub helpers static to fix ODR violations across test TUs - ut_logbackend.cpp: return properly aligned dummy objects from DLDBusHandler::instance/LogApplicationHelper::instance stubs instead of (X*)0x1, which is UB under UBSan - ut_logcollectormain.cpp: ensure a QApplication exists before creating widgets in each test Result: 1497 of 1508 tests pass (2 pre-existing DBusManager failures; 9 tests need follow-up: fork-based auth/truncate main tests deadlock under ASan, LogViewHeaderView paint tests and one timer test crash) --- tests/CMakeLists.txt | 8 +++++++- tests/dbusproxy/ut_dldbushandler.cpp | 6 +++--- tests/dbusproxy/ut_userlogaccess.cpp | 6 +++--- tests/src/ut_displaycontent.cpp | 15 +++++++++++++++ tests/src/ut_logauththread.cpp | 2 +- tests/src/ut_logbackend.cpp | 6 ++++-- tests/src/ut_logcollectormain.cpp | 26 ++++++++++++++++++++++++++ tests/src/ut_loglistview.cpp | 2 +- tests/src/ut_logviewerservice.cpp | 4 ++-- 9 files changed, 62 insertions(+), 13 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ba6b70f1..09a15205 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -91,6 +91,7 @@ set(LINK_LIBS if (QT_DESIRED_VERSION MATCHES 6) list(APPEND LINK_LIBS Qt${QT_DESIRED_VERSION}::Core5Compat) + list(APPEND LINK_LIBS Qt${QT_DESIRED_VERSION}::GuiPrivate Qt${QT_DESIRED_VERSION}::CorePrivate) else() list(APPEND LINK_LIBS ${Gsetting_LIBRARIES}) include_directories(${Gsetting_INCLUDE_DIRS}) @@ -101,6 +102,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty) FILE(GLOB allSource ../application/filtercontent.cpp + ../application/cliapplicationhelper.cpp + ../application/logtableview.cpp ../application/displaycontent.cpp ../application/logcollectormain.cpp ../application/logfileparser.cpp @@ -144,6 +147,7 @@ FILE(GLOB allSource ../application/parsethread/parsethreadbase.cpp ../application/parsethread/parsethreadkern.cpp ../application/parsethread/parsethreadkwin.cpp + ../logViewerService/logviewerservice.cpp ) FILE(GLOB qrcFiles ../application/assets/resources.qrc @@ -259,6 +263,8 @@ include_sub_directories_recursively("${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/tmp include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_sub_directories_recursively("${CMAKE_CURRENT_SOURCE_DIR}/../application") include_sub_directories_recursively("${CMAKE_CURRENT_SOURCE_DIR}/../liblogviewerplugin") +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../logViewerService) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../logViewerAuth) include_directories( ${Boost_INCLUDE_DIRS}) include_directories( ${ZLIB_INCLUDE_DIRS}) @@ -269,7 +275,7 @@ include_directories(${GTEST_INCLUDE_DIRS}) include_directories(src) -add_executable (${PROJECT_NAME_TEST} ${allSource} ${APP_QRC_FILES} ${qrcFiles} ${allTestSource} ${MINIZIP_SOURCES} ${LXW_SOURCES} ${DOCXFAC_SOURCES} ${DOCXFAC_SOURCES_C} ${TMPFILE_SOURCES} ${MD5SOURCES}) +add_executable (${PROJECT_NAME_TEST} ${allSource} ../application/configs/json/org_deepin_log_viewer.hpp ${APP_QRC_FILES} ${qrcFiles} ${allTestSource} ${MINIZIP_SOURCES} ${LXW_SOURCES} ${DOCXFAC_SOURCES} ${DOCXFAC_SOURCES_C} ${TMPFILE_SOURCES} ${MD5SOURCES}) #添加插件单元测试进程 add_executable (${PROJECT_NAME_PLUGIN_TEST} ${allPluginTestSource} ${LVP_HEADERS} ${LVP_SOURCES} ${MINIZIP_SOURCES} ${LXW_SOURCES} ${DOCXFAC_SOURCES} ${DOCXFAC_SOURCES_C} ${TMPFILE_SOURCES} ${MD5SOURCES}) diff --git a/tests/dbusproxy/ut_dldbushandler.cpp b/tests/dbusproxy/ut_dldbushandler.cpp index 97d7a901..ac5ef82e 100644 --- a/tests/dbusproxy/ut_dldbushandler.cpp +++ b/tests/dbusproxy/ut_dldbushandler.cpp @@ -153,14 +153,14 @@ TEST_F(UT_DLDBusHandler, openLogStream_home_branch_returns_local_token) { Utils::homePath = m_homeDir.path(); QString abs = makeHomeFile("stream.log", "stream-content\n"); - QString [REDACTED CREDENTIAL] + QString token = m_handler->openLogStream(abs); EXPECT_TRUE(token.startsWith(QStringLiteral("local-"))); } TEST_F(UT_DLDBusHandler, openLogStream_home_branch_unreadable_returns_empty) { Utils::homePath = m_homeDir.path(); - QString [REDACTED CREDENTIAL] + "/no_such_file.log"); + QString token = m_handler->openLogStream(m_homeDir.path() + "/no_such_file.log"); EXPECT_TRUE(token.isEmpty()); } @@ -176,7 +176,7 @@ TEST_F(UT_DLDBusHandler, readLogInStream_local_token_returns_content) { Utils::homePath = m_homeDir.path(); QString abs = makeHomeFile("stream2.log", "data-line\n"); - QString [REDACTED CREDENTIAL] + QString token = m_handler->openLogStream(abs); ASSERT_FALSE(token.isEmpty()); QString result = m_handler->readLogInStream(token); EXPECT_FALSE(result.isEmpty()); diff --git a/tests/dbusproxy/ut_userlogaccess.cpp b/tests/dbusproxy/ut_userlogaccess.cpp index 93a58877..6902eb66 100644 --- a/tests/dbusproxy/ut_userlogaccess.cpp +++ b/tests/dbusproxy/ut_userlogaccess.cpp @@ -172,7 +172,7 @@ TEST(UT_UserLogAccess_openLogStream, UT_UserLogAccess_openLogStream_normal) tmp.write("stream line 1\nstream line 2\n"); tmp.close(); - QString [REDACTED CREDENTIAL] + QString token = UserLogAccess::instance()->openLogStream(tmp.fileName()); EXPECT_FALSE(token.isEmpty()); EXPECT_TRUE(token.startsWith(QStringLiteral("local-"))); } @@ -180,7 +180,7 @@ TEST(UT_UserLogAccess_openLogStream, UT_UserLogAccess_openLogStream_normal) // openLogStream:读取失败返回空 token TEST(UT_UserLogAccess_openLogStream, UT_UserLogAccess_openLogStream_empty) { - QString [REDACTED CREDENTIAL] + QString token = UserLogAccess::instance()->openLogStream("/tmp/dlv_ut_nonexistent.log"); EXPECT_TRUE(token.isEmpty()); } @@ -198,7 +198,7 @@ TEST(UT_UserLogAccess_readLogInStream, UT_UserLogAccess_readLogInStream_valid) tmp.write("aaa\nbbb\n"); tmp.close(); - QString [REDACTED CREDENTIAL] + QString token = UserLogAccess::instance()->openLogStream(tmp.fileName()); ASSERT_FALSE(token.isEmpty()); QString first = UserLogAccess::instance()->readLogInStream(token); diff --git a/tests/src/ut_displaycontent.cpp b/tests/src/ut_displaycontent.cpp index 85bd1488..416b1e6b 100644 --- a/tests/src/ut_displaycontent.cpp +++ b/tests/src/ut_displaycontent.cpp @@ -181,6 +181,21 @@ bool stub_isCoredumpctlExist_false() return false; } +int LogFileParser_parseByAudit(const AUDIT_FILTERS &) +{ + return 0; +} + +int LogFileParser_parseByAuth(const AUTH_FILTERS &) +{ + return 0; +} + +int LogFileParser_parseByCoredump(const COREDUMP_FILTERS &, bool) +{ + return 0; +} + void stub_refreshAuthLogList() { } diff --git a/tests/src/ut_logauththread.cpp b/tests/src/ut_logauththread.cpp index ed813193..a4f2fad7 100644 --- a/tests/src/ut_logauththread.cpp +++ b/tests/src/ut_logauththread.cpp @@ -173,7 +173,7 @@ bool stub_isFileExist_true(const QString &filePath) return true; } -bool stub_isFileExist_false(const QString &filePath) +static bool stub_isFileExist_false(const QString &filePath) { Q_UNUSED(filePath); return false; diff --git a/tests/src/ut_logbackend.cpp b/tests/src/ut_logbackend.cpp index 23a69e58..db2e94e9 100644 --- a/tests/src/ut_logbackend.cpp +++ b/tests/src/ut_logbackend.cpp @@ -82,7 +82,8 @@ static QDateTime stub_appHelper_getLastReportTime() } static void stub_appHelper_saveLastRerportTime(const QDateTime &) {} -static LogApplicationHelper *stub_appHelper_instance() { return reinterpret_cast(0x1); } +alignas(LogApplicationHelper) static char stub_appHelper_buf[sizeof(LogApplicationHelper)] = {}; +static LogApplicationHelper *stub_appHelper_instance() { return reinterpret_cast(stub_appHelper_buf); } static int stub_appHelper_getMaxReportCoredump() { @@ -134,7 +135,8 @@ static QString stub_dlbus_readLogLinesInRange(const QString &, int, int) { return QString(); } -static DLDBusHandler *stub_dlbus_instance() { return reinterpret_cast(0x1); } +alignas(DLDBusHandler) static char stub_dlbus_buf[sizeof(DLDBusHandler)] = {}; +static DLDBusHandler *stub_dlbus_instance() { return reinterpret_cast(stub_dlbus_buf); } static QString stub_Utils_mkMutiDir(const QString &) { return QString(); } static bool stub_Utils_checkAndDeleteDir(const QString &) { return true; } diff --git a/tests/src/ut_logcollectormain.cpp b/tests/src/ut_logcollectormain.cpp index e7588fca..adea90a5 100644 --- a/tests/src/ut_logcollectormain.cpp +++ b/tests/src/ut_logcollectormain.cpp @@ -75,8 +75,21 @@ bool LogCollectorMain_notify(QObject *obj, QEvent *event) return false; } + +// 兜底:部分用例链中 QApplication 可能被 deleteLater 销毁,建 QWidget 前确保实例存在 +static QApplication *ensureQtApp() +{ + if (qApp == nullptr) { + static int argc = 0; + static QApplication *app = new QApplication(argc, nullptr); + return app; + } + return static_cast(qApp); +} + TEST(LogCollectorMain_Constructor_UT, LogCollectorMain_Constructor_UT) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -96,6 +109,7 @@ TEST(LogCollectorMain_Constructor_UT, LogCollectorMain_Constructor_UT) TEST(LogCollectorMain_Destructor_UT, LogCollectorMain_Destructor_UT) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -114,6 +128,7 @@ TEST(LogCollectorMain_Destructor_UT, LogCollectorMain_Destructor_UT) } TEST(LogCollectorMain_initUI_UT, LogCollectorMain_initUI_UT) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -133,6 +148,7 @@ TEST(LogCollectorMain_initUI_UT, LogCollectorMain_initUI_UT) TEST(LogCollectorMain_initShortCut_UT, LogCollectorMain_initShortCut_UT_001) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -153,6 +169,7 @@ TEST(LogCollectorMain_initShortCut_UT, LogCollectorMain_initShortCut_UT_001) TEST(LogCollectorMain_initShortCut_UT, LogCollectorMain_initShortCut_UT_002) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -182,6 +199,7 @@ TEST(LogCollectorMain_initShortCut_UT, LogCollectorMain_initShortCut_UT_002) TEST(LogCollectorMain_initConnection_UT, LogCollectorMain_initConnection_UT) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -306,6 +324,7 @@ TEST_P(LogCollectorMain_handleApplicationTabEventNotify_UT, LogCollectorMain_han TEST(LogCollectorMain_switchRefreshActionTriggered_UT, LogCollectorMain_switchRefreshActionTriggered_UT_001) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -337,6 +356,7 @@ TEST(LogCollectorMain_switchRefreshActionTriggered_UT, LogCollectorMain_switchRe TEST(LogCollectorMain_exportAllLogs_UT, LogCollectorMain_exportAllLogs_UT_001) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -361,6 +381,7 @@ TEST(LogCollectorMain_exportAllLogs_UT, LogCollectorMain_exportAllLogs_UT_001) TEST(LogCollectorMain_exportAllLogs_UT, LogCollectorMain_exportAllLogs_UT_002) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -392,6 +413,7 @@ TEST(LogCollectorMain_exportAllLogs_UT, LogCollectorMain_exportAllLogs_UT_002) TEST(LogCollectorMain_closeEvent_UT, LogCollectorMain_closeEvent_UT_001) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -472,6 +494,7 @@ int LogCollectorMain_exec_processEvents(DDialog *self) // ===== initShortCut lambda coverage ===== TEST(LogCollectorMain_initShortCut_UT, LogCollectorMain_initShortCut_UT_003) { + ensureQtApp(); // Set DStyle so DApplication::style() returns a valid DStyle* — prevents SEGV // in LogPeriodButton::paintEvent when showMaximized()/showNormal() triggers repaints qApp->setStyle(new DStyle); @@ -509,6 +532,7 @@ TEST(LogCollectorMain_initShortCut_UT, LogCollectorMain_initShortCut_UT_003) // ===== initTitlebarExtensions lambda coverage ===== TEST(LogCollectorMain_initTitlebarExtensions_UT, LogCollectorMain_initTitlebarExtensions_UT_002) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -539,6 +563,7 @@ TEST(LogCollectorMain_initTitlebarExtensions_UT, LogCollectorMain_initTitlebarEx // ===== switchRefreshActionTriggered lambda coverage ===== TEST(LogCollectorMain_switchRefreshActionTriggered_UT, LogCollectorMain_switchRefreshActionTriggered_UT_002) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); @@ -580,6 +605,7 @@ TEST(LogCollectorMain_switchRefreshActionTriggered_UT, LogCollectorMain_switchRe // ===== exportAllLogs lambda coverage ===== TEST(LogCollectorMain_exportAllLogs_UT, LogCollectorMain_exportAllLogs_UT_003) { + ensureQtApp(); Stub stub; stub.set(ADDR(DebugTimeManager, beginPointLinux), Log_beginPointLinux); stub.set(ADDR(LogFileParser, parseByJournal), LogFileParser_parseByJournal); diff --git a/tests/src/ut_loglistview.cpp b/tests/src/ut_loglistview.cpp index 608e3e9c..9cb40d3e 100644 --- a/tests/src/ut_loglistview.cpp +++ b/tests/src/ut_loglistview.cpp @@ -465,7 +465,7 @@ int stub_ddialog_exec_rejected() return 0; } -bool stub_showFileItem(const QString &localFilePath, const QString &startupId) +static bool stub_showFileItem(const QString &localFilePath, const QString &startupId) { Q_UNUSED(localFilePath); Q_UNUSED(startupId); diff --git a/tests/src/ut_logviewerservice.cpp b/tests/src/ut_logviewerservice.cpp index e40baf6c..37d3d185 100644 --- a/tests/src/ut_logviewerservice.cpp +++ b/tests/src/ut_logviewerservice.cpp @@ -474,7 +474,7 @@ TEST_F(LogViewerServiceTest, OpenLogStreamAuthOk) ASSERT_TRUE(tmpFile.open()); tmpFile.write("stream line\n"); tmpFile.flush(); - QString [REDACTED CREDENTIAL] + QString token = m_service->openLogStream(tmpFile.fileName()); EXPECT_FALSE(token.isEmpty()); } @@ -500,7 +500,7 @@ TEST_F(LogViewerServiceTest, ReadLogInStreamValidToken) ASSERT_TRUE(tmpFile.open()); tmpFile.write("stream data 1\nstream data 2\n"); tmpFile.flush(); - QString [REDACTED CREDENTIAL] + QString token = m_service->openLogStream(tmpFile.fileName()); ASSERT_FALSE(token.isEmpty()); QString result = m_service->readLogInStream(token); EXPECT_TRUE(result.contains("stream data"));