refact: add test-coverage.sh and some docs

Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
ComixHe 2023-08-14 16:30:16 +08:00 committed by Comix
parent c4c1d72568
commit de09f3dbc2
12 changed files with 89 additions and 28 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
build build*
.vscode .vscode

View File

@ -14,12 +14,17 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
set(BUILD_EXAMPLES ON CACHE BOOL "Whether to build examples or not.") set(BUILD_EXAMPLES ON CACHE BOOL "Whether to build examples or not.")
set(DEBUG_MODE ON CACHE BOOL "start a dde-applicatiom-manager service for debug")
find_package(Qt6 REQUIRED COMPONENTS Core DBus Concurrent) find_package(Qt6 REQUIRED COMPONENTS Core DBus Concurrent)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
set(APP_LAUNCH_HELPER_BIN app-launch-helper) set(APP_LAUNCH_HELPER_BIN app-launch-helper)
if(DEBUG_MODE)
add_compile_definitions(-DDEBUG_MODE)
endif()
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(plugins) add_subdirectory(plugins)
add_subdirectory(apps) add_subdirectory(apps)
@ -27,7 +32,6 @@ add_subdirectory(apps)
include(CTest) include(CTest)
if(BUILD_TESTING) if(BUILD_TESTING)
enable_testing()
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()

6
docs/customVariables.md Normal file
View File

@ -0,0 +1,6 @@
# Environment Variable
本文档描述了 dde-application-manager 所用到的环境变量。
- `DEEPIN_APPLICATION_MANAGER_APP_LAUNCH_HELPER_BIN`
指定运行时app_launcher_helper_bin的绝对路径便于调试.

View File

@ -0,0 +1,9 @@
# LaunchApp Example
## Introduction
这是 dde-application-manager 的一个拉起应用的例子。
本示例演示了如何使用 D-Bus 调用通过 dde-application-manager 启动 Google Chrome Stable 应用。
如需更改启动行为,请修改对应的 AppId 和启动参数。

View File

@ -8,7 +8,7 @@ set(LIB_NAME dde_am_static)
file(GLOB SRCS ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/*.h) file(GLOB SRCS ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/*.h)
add_library(${LIB_NAME} ${SRCS}) add_library(${LIB_NAME} STATIC ${SRCS})
target_include_directories(${LIB_NAME} PRIVATE target_include_directories(${LIB_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}

View File

@ -8,7 +8,13 @@
constexpr auto SystemdService = u8"org.freedesktop.systemd1"; constexpr auto SystemdService = u8"org.freedesktop.systemd1";
constexpr auto SystemdObjectPath = u8"/org/freedesktop/systemd1"; constexpr auto SystemdObjectPath = u8"/org/freedesktop/systemd1";
constexpr auto SystemdInterfaceName = u8"org.freedesktop.systemd1.Manager"; constexpr auto SystemdInterfaceName = u8"org.freedesktop.systemd1.Manager";
constexpr auto DDEApplicationManager1ServiceName = u8"org.deepin.dde.ApplicationManager1"; constexpr auto DDEApplicationManager1ServiceName =
#ifdef DEBUG_MODE
u8"org.deepin.dde.debug.ApplicationManager1";
#else
u8"org.deepin.dde.ApplicationManager1";
#endif
constexpr auto DDEApplicationManager1ObjectPath = u8"/org/deepin/dde/ApplicationManager1"; constexpr auto DDEApplicationManager1ObjectPath = u8"/org/deepin/dde/ApplicationManager1";
constexpr auto DDEApplicationManager1ApplicationObjectPath = u8"/org/deepin/dde/ApplicationManager1/Application/"; constexpr auto DDEApplicationManager1ApplicationObjectPath = u8"/org/deepin/dde/ApplicationManager1/Application/";
constexpr auto DDEApplicationManager1InstanceObjectPath = u8"/org/deepin/dde/ApplicationManager1/Instance/"; constexpr auto DDEApplicationManager1InstanceObjectPath = u8"/org/deepin/dde/ApplicationManager1/Instance/";
@ -16,7 +22,19 @@ constexpr auto DDEApplicationManager1JobManagerObjectPath = u8"/org/deepin/dde/A
constexpr auto DDEApplicationManager1JobObjectPath = u8"/org/deepin/dde/ApplicationManager1/JobManager1/Job/"; constexpr auto DDEApplicationManager1JobObjectPath = u8"/org/deepin/dde/ApplicationManager1/JobManager1/Job/";
constexpr auto DesktopFileEntryKey = u8"Desktop Entry"; constexpr auto DesktopFileEntryKey = u8"Desktop Entry";
constexpr auto DesktopFileActionKey = u8"Desktop Action "; constexpr auto DesktopFileActionKey = u8"Desktop Action ";
constexpr auto ApplicationManagerServerDBusName = u8"deepin_application_manager_server_bus";
constexpr auto ApplicationManagerDestDBusName = "deepin_application_manager_dest_bus"; constexpr auto ApplicationManagerServerDBusName =
#ifdef DEBUG_MODE
u8"deepin_application_manager_debug_server_bus";
#else
u8"deepin_application_manager_server_bus";
#endif
constexpr auto ApplicationManagerDestDBusName =
#ifdef DEBUG_MODE
u8"deepin_application_manager_debug_dest_bus";
#else
u8"deepin_application_manager_dest_bus";
#endif
#endif #endif

View File

@ -76,7 +76,7 @@ private:
if constexpr (std::is_same_v<T, DesktopFile>) { if constexpr (std::is_same_v<T, DesktopFile>) {
m_applicationPath = m_applicationPath =
#ifdef QT_DEBUG #ifdef DEBUG_MODE
QDBusObjectPath{objectPath + escapeToObjectPath(dbusAppid)}; QDBusObjectPath{objectPath + escapeToObjectPath(dbusAppid)};
#else #else
QDBusObjectPath{objectPath + QUuid::createUuid().toString(QUuid::Id128)}; QDBusObjectPath{objectPath + QUuid::createUuid().toString(QUuid::Id128)};

View File

@ -87,9 +87,9 @@ DesktopErrorCode DesktopEntry::parseEntry(const QString &str, decltype(m_entryMa
std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &desktopFile, DesktopErrorCode &err) noexcept std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &desktopFile, DesktopErrorCode &err) noexcept
{ {
constexpr decltype(auto) desktopPostfix = ".desktop"; constexpr decltype(auto) desktopSuffix = ".desktop";
if (!desktopFile.endsWith(desktopPostfix)) { if (!desktopFile.endsWith(desktopSuffix)) {
qWarning() << "file isn't a desktop file:" << desktopFile; qWarning() << "file isn't a desktop file:" << desktopFile;
err = DesktopErrorCode::MismatchedFile; err = DesktopErrorCode::MismatchedFile;
return std::nullopt; return std::nullopt;
@ -111,7 +111,7 @@ std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &d
}); });
if (idGen) { if (idGen) {
auto tmp = path.chopped(sizeof(desktopPostfix) - 1); auto tmp = path.chopped(sizeof(desktopSuffix) - 1);
auto components = tmp.split(QDir::separator()).toList(); auto components = tmp.split(QDir::separator()).toList();
auto it = std::find(components.cbegin(), components.cend(), "applications"); auto it = std::find(components.cbegin(), components.cend(), "applications");
QString FileId; QString FileId;
@ -138,9 +138,10 @@ std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &d
std::optional<DesktopFile> DesktopFile::searchDesktopFileById(const QString &appId, DesktopErrorCode &err) noexcept std::optional<DesktopFile> DesktopFile::searchDesktopFileById(const QString &appId, DesktopErrorCode &err) noexcept
{ {
auto XDGDataDirs = getXDGDataDirs(); auto XDGDataDirs = getXDGDataDirs();
constexpr auto desktopSuffix = u8".desktop";
for (const auto &dir : XDGDataDirs) { for (const auto &dir : XDGDataDirs) {
auto app = QFileInfo{dir + QDir::separator() + appId}; auto app = QFileInfo{dir + QDir::separator() + appId + desktopSuffix};
while (!app.exists()) { while (!app.exists()) {
auto filePath = app.absoluteFilePath(); auto filePath = app.absoluteFilePath();
auto hyphenIndex = filePath.indexOf('-'); auto hyphenIndex = filePath.indexOf('-');
@ -155,6 +156,8 @@ std::optional<DesktopFile> DesktopFile::searchDesktopFileById(const QString &app
return searchDesktopFileByPath(app.absoluteFilePath(), err); return searchDesktopFileByPath(app.absoluteFilePath(), err);
} }
} }
err = DesktopErrorCode::NotFound;
return std::nullopt; return std::nullopt;
} }

View File

@ -18,19 +18,10 @@ target_link_libraries(${BIN_NAME} PRIVATE
dde_am_static dde_am_static
) )
target_compile_options(${BIN_NAME} PRIVATE target_compile_options(${BIN_NAME} PRIVATE "-fno-access-control")
-fno-access-control
-fsanitize=undefined
-fsanitize=address
)
target_link_options(${BIN_NAME} PRIVATE
-fsanitize=undefined
-fsanitize=address
)
add_test( add_test(
NAME UnitTest NAME UnitTest
COMMAND ${BIN_NAME} COMMAND ${BIN_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests
) )

View File

@ -15,22 +15,28 @@ class TestDesktopEntry : public testing::Test
public: public:
static void SetUpTestCase() static void SetUpTestCase()
{ {
env = qgetenv("XDG_DATA_DIRS");
auto curDir = QDir::current(); auto curDir = QDir::current();
QString path{curDir.absolutePath() + "/data/desktopExample.desktop"}; QByteArray fakeXDG = (curDir.absolutePath() + QDir::separator() + "data").toLocal8Bit();
qputenv("XDG_DATA_DIRS", fakeXDG);
DesktopErrorCode err; DesktopErrorCode err;
auto file = DesktopFile::searchDesktopFileByPath(path, err); auto file = DesktopFile::searchDesktopFileById("deepin-editor", err);
if (!file.has_value()) { if (!file.has_value()) {
qWarning() << "search " << path << "failed:" << err; qWarning() << "search failed:" << err;
return; return;
} }
m_file.reset(new DesktopFile{std::move(file).value()}); m_file.reset(new DesktopFile{std::move(file).value()});
} }
static void TearDownTestCase() { qputenv("XDG_DATA_DIRS", env); }
void SetUp() override {} void SetUp() override {}
void TearDown() override {} void TearDown() override {}
QSharedPointer<DesktopFile> file() { return m_file; } QSharedPointer<DesktopFile> file() { return m_file; }
private: private:
static inline QSharedPointer<DesktopFile> m_file; static inline QSharedPointer<DesktopFile> m_file;
static inline QByteArray env;
}; };
TEST_F(TestDesktopEntry, desktopFile) TEST_F(TestDesktopEntry, desktopFile)
@ -39,16 +45,16 @@ TEST_F(TestDesktopEntry, desktopFile)
ASSERT_FALSE(fileptr.isNull()); ASSERT_FALSE(fileptr.isNull());
const auto &exampleFile = file(); const auto &exampleFile = file();
auto curDir = QDir::current(); auto curDir = QDir::current();
QString path{curDir.absolutePath() + "/data/desktopExample.desktop"}; QString path{curDir.absolutePath() + QDir::separator() + "data" + QDir::separator() + "applications" + QDir::separator() +
"deepin-editor.desktop"};
EXPECT_EQ(exampleFile->filePath().toStdString(), path.toStdString()); EXPECT_EQ(exampleFile->filePath().toStdString(), path.toStdString());
EXPECT_EQ(exampleFile->desktopId().toStdString(), ""); EXPECT_EQ(exampleFile->desktopId().toStdString(), "deepin-editor");
} }
TEST_F(TestDesktopEntry, prase) TEST_F(TestDesktopEntry, prase)
{ {
const auto &exampleFile = file(); const auto &exampleFile = file();
ASSERT_FALSE(exampleFile.isNull()); ASSERT_FALSE(exampleFile.isNull());
;
DesktopEntry entry; DesktopEntry entry;
QFile in{exampleFile->filePath()}; QFile in{exampleFile->filePath()};
ASSERT_TRUE(in.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text)); ASSERT_TRUE(in.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text));

24
tools/test-coverage.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
# SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: LGPL-3.0-or-later
cd "$(git rev-parse --show-toplevel)" || exit 255
BUILD_DIR=${BUILD_DIR:="build-cov"}
HTML_DIR=${BUILD_DIR}/html
export ASAN_OPTIONS="halt_on_error=0"
cmake -B "$BUILD_DIR" \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="--coverage -fsanitize=address -fsanitize-recover=address " \
-DCMAKE_CXX_LINK_FLAGS="-lasan"
cmake --build "$BUILD_DIR" -j$(nproc)
cmake --build "$BUILD_DIR" -j$(nproc) -t test
gcovr -f "src/*" --html-details "$BUILD_DIR"/coverage.html