refact: add test-coverage.sh and some docs
Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
parent
c4c1d72568
commit
de09f3dbc2
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
|||||||
build
|
build*
|
||||||
.vscode
|
.vscode
|
||||||
|
@ -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
6
docs/customVariables.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Environment Variable
|
||||||
|
|
||||||
|
本文档描述了 dde-application-manager 所用到的环境变量。
|
||||||
|
|
||||||
|
- `DEEPIN_APPLICATION_MANAGER_APP_LAUNCH_HELPER_BIN`
|
||||||
|
指定运行时app_launcher_helper_bin的绝对路径,便于调试.
|
@ -0,0 +1,9 @@
|
|||||||
|
# LaunchApp Example
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
这是 dde-application-manager 的一个拉起应用的例子。
|
||||||
|
|
||||||
|
本示例演示了如何使用 D-Bus 调用通过 dde-application-manager 启动 Google Chrome Stable 应用。
|
||||||
|
|
||||||
|
如需更改启动行为,请修改对应的 AppId 和启动参数。
|
@ -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}
|
||||||
|
@ -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
|
||||||
|
@ -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)};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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
24
tools/test-coverage.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user