Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ set (BUILD_DOCS ON CACHE BOOL "Generate doxygen-based documentation")

project(dde-app-services)

include(CTest)

add_subdirectory("dconfig-center")
5 changes: 4 additions & 1 deletion dconfig-center/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ add_subdirectory("dde-dconfig-daemon")
add_subdirectory("dde-dconfig-editor")
add_subdirectory("dde-dconfig")
add_subdirectory("example")
add_subdirectory("tests")

if(BUILD_TESTING)
add_subdirectory("tests")
endif()

if (BUILD_DOCS)
add_subdirectory(docs)
Expand Down
49 changes: 46 additions & 3 deletions dconfig-center/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# SPDX-FileCopyrightText: 2022 Uniontech Software Technology Co.,Ltd.
# SPDX-FileCopyrightText: 2022 - 2026 Uniontech Software Technology Co.,Ltd.
#
# SPDX-License-Identifier: LGPL-3.0-only

find_package(Qt${QT_VERSION_MAJOR} ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS Core DBus Test)
find_package(Dtk${DTK_VERSION_MAJOR}Core REQUIRED)
find_package(GTest REQUIRED)

# generate moc_predefs.h
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(AUTOMOC_COMPILER_PREDEFINES ON)

set(DTK_HAS_UNIT_TEST ON)
option(ENABLE_COVERAGE "Enable coverage instrumentation" ON)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue: ENABLE_COVERAGE defaults to ON, so configuring with the default options instruments and links the test binary for coverage instead of leaving coverage disabled by default as the change description specifies.

Triggers: When the project is configured without explicitly setting ENABLE_COVERAGE.

Suggested fix: Change the option default to OFF.

Suggested change
option(ENABLE_COVERAGE "Enable coverage instrumentation" ON)
option(ENABLE_COVERAGE "Enable coverage instrumentation" OFF)

# for coverage
if (DTK_HAS_UNIT_TEST)
if(ENABLE_COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov --coverage")
endif()
Expand All @@ -23,10 +24,16 @@ list(APPEND SOURCES
ut_dconfigconn.cpp
ut_dconfigrefmanager.cpp
ut_dconfigserver.cpp
ut_dconfig_global.cpp
ut_helper.cpp
)

ADD_EXECUTABLE(dconfigtest main.cpp ${HEADERS} ${SOURCES} ${DCONFIG_DBUS_XML} data.qrc)

# Expose private/protected members for testing (equivalent to protected=public private=public
# but without breaking standard library headers)
target_compile_options(dconfigtest PRIVATE -fno-access-control)

target_include_directories(dconfigtest PUBLIC
../dde-dconfig-daemon
${CMAKE_CURRENT_BINARY_DIR}
Expand All @@ -43,3 +50,39 @@ target_link_libraries(dconfigtest PUBLIC ${COMMON_LIBS}
-lgtest
-lpthread
)

# Register each TEST() case with CTest (one entry per gtest case, not one
# per binary), so `ctest -R <case>` can run individual cases.
include(GoogleTest)
gtest_discover_tests(dconfigtest)

# ---- coverage: execute all tests and generate a coverage report ----
find_program(LCOV_PATH lcov)
find_program(GENHTML_PATH genhtml)
set(_run_test_coverage "")
if(LCOV_PATH AND GENHTML_PATH)
set(_run_test_coverage
COMMAND ${LCOV_PATH} --capture --directory ${CMAKE_BINARY_DIR}
--rc lcov_branch_coverage=1
--output-file ${CMAKE_BINARY_DIR}/coverage.info
COMMAND ${LCOV_PATH} --extract ${CMAKE_BINARY_DIR}/coverage.info
--rc lcov_branch_coverage=1
"${CMAKE_SOURCE_DIR}/dconfig-center/dde-dconfig-daemon/*"
"${CMAKE_SOURCE_DIR}/dconfig-center/common/*"
--output-file ${CMAKE_BINARY_DIR}/coverage_filtered.info
COMMAND ${GENHTML_PATH} ${CMAKE_BINARY_DIR}/coverage_filtered.info
--branch-coverage
--output-directory ${CMAKE_BINARY_DIR}/coverage_report
)
endif()
add_custom_target(coverage
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
${_run_test_coverage}
DEPENDS dconfigtest
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Run all tests and generate coverage report"
VERBATIM
)



51 changes: 49 additions & 2 deletions dconfig-center/tests/test_helper.hpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
// SPDX-FileCopyrightText: 2021 - 2022 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2021 - 2026 Uniontech Software Technology Co.,Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#pragma once

#include <QDir>
#include <QFile>

class EnvGuard {
public:
~EnvGuard()
{
if (m_name)
restore();
if (!m_createdDir.isEmpty())
QDir(m_createdDir).removeRecursively();
}
void set(const char *name, const QByteArray &value)
{
m_name = name;
m_wasSet = qEnvironmentVariableIsSet(m_name);
m_originValue = qgetenv(m_name);
qputenv(m_name, value);

if (!QDir(value).exists()) {
QDir().mkpath(value);
m_createdDir = QString::fromUtf8(value);
}
}
void restore()
{
qputenv(m_name, m_originValue);
if (!m_name)
return;
if (m_wasSet)
qputenv(m_name, m_originValue);
else
qunsetenv(m_name);
}
QString value()
{
Expand All @@ -29,6 +44,8 @@ class EnvGuard {
private:
QByteArray m_originValue;
const char* m_name = nullptr;
bool m_wasSet = false;
QString m_createdDir;
};


Expand All @@ -45,3 +62,33 @@ class FileCopyGuard {
private:
QString m_target;
};

// RAII guard for meta files modified during tests.
// Backs up original content on construction, restores on destruction —
// even if ASSERT_* causes early return, the file is always restored.
class MetaFileGuard {
public:
explicit MetaFileGuard(const QString &path) : m_path(path)
{
QFile file(path);
if (file.open(QIODevice::ReadOnly)) {
m_originalContent = file.readAll();
file.close();
m_hasOriginal = true;
}
}
~MetaFileGuard()
{
if (m_hasOriginal) {
QFile file(m_path);
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
file.write(m_originalContent);
file.close();
}
}
}
private:
QString m_path;
QByteArray m_originalContent;
bool m_hasOriginal = false;
};
Loading
Loading