Skip to content

Commit 508db69

Browse files
committed
feat(test): add unit tests for utils, parse threads and standalone entries (batch 4/8)
- new tests/src/ut_utils_extra.cpp, ut_cliapplicationhelper.cpp, ut_logtableview.cpp, ut_logviewer_auth_main.cpp - rewrite tests/src/ut_logtreeview.cpp with richer assertions - extend ut_logapplicationparsethread.cpp and ut_journalwork.cpp (7 files, +1295/-176 lines; batch 4/8 of the UT coverage series)
1 parent 48c53e0 commit 508db69

7 files changed

Lines changed: 1295 additions & 176 deletions
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
#include "cliapplicationhelper.h"
6+
7+
#include <gtest/gtest.h>
8+
9+
#include <QApplication>
10+
#include <QLocalServer>
11+
#include <QLocalSocket>
12+
#include <QTest>
13+
14+
// 单实例辅助类单元测试
15+
// 覆盖目标:application/cliapplicationhelper.cpp 中的全部可测函数
16+
// - CliApplicationHelper::instance()
17+
// - CliApplicationHelper::CliApplicationHelper() / ~CliApplicationHelper()
18+
// - CliApplicationHelper::setSingleInstance()(三种 SingleScope)
19+
// - CliApplicationHelper::staticCleanApplication()
20+
// - _CliApplicationHelper::helper() / clear() / defaultCreator()(通过公开接口间接覆盖)
21+
22+
// instance() 应返回非空指针,且重复调用返回同一实例(单例语义)
23+
TEST(CliApplicationHelper_Instance_UT, Instance_ReturnsNonNull)
24+
{
25+
CliApplicationHelper *p1 = CliApplicationHelper::instance();
26+
ASSERT_NE(p1, nullptr);
27+
28+
CliApplicationHelper *p2 = CliApplicationHelper::instance();
29+
EXPECT_EQ(p1, p2);
30+
}
31+
32+
// staticCleanApplication() 清理后再次 instance() 仍可正常获取实例,
33+
// 间接覆盖 clear()、~CliApplicationHelper()、defaultCreator()、helper()
34+
TEST(CliApplicationHelper_StaticCleanApplication_UT, StaticCleanApplication_ClearsAndRecreates)
35+
{
36+
CliApplicationHelper *p1 = CliApplicationHelper::instance();
37+
ASSERT_NE(p1, nullptr);
38+
39+
CliApplicationHelper::staticCleanApplication();
40+
41+
// 清理后再次获取,应得到新的有效实例
42+
CliApplicationHelper *p2 = CliApplicationHelper::instance();
43+
EXPECT_NE(p2, nullptr);
44+
}
45+
46+
// staticCleanApplication() 在未创建实例时也不应崩溃
47+
TEST(CliApplicationHelper_StaticCleanApplication_UT, StaticCleanApplication_NoCrashWhenEmpty)
48+
{
49+
// 先清理确保无残留
50+
CliApplicationHelper::staticCleanApplication();
51+
// 再次清理不应崩溃
52+
CliApplicationHelper::staticCleanApplication();
53+
EXPECT_TRUE(true);
54+
}
55+
56+
// 直接构造/析构对象,覆盖构造函数(qAddPostRoutine)与析构函数(m_helper = nullptr)
57+
TEST(CliApplicationHelper_Constructor_UT, Constructor_CreatesValidObject)
58+
{
59+
CliApplicationHelper *p = new CliApplicationHelper();
60+
EXPECT_NE(p, nullptr);
61+
delete p;
62+
}
63+
64+
// setSingleInstance —— UserScope 首次调用应成功(获取锁 + 监听)
65+
TEST(CliApplicationHelper_SetSingleInstance_UT, SetSingleInstance_UserScope_ReturnsTrue)
66+
{
67+
bool ret = CliApplicationHelper::setSingleInstance(
68+
QStringLiteral("ut_cli_helper_user"), CliApplicationHelper::UserScope);
69+
EXPECT_TRUE(ret);
70+
}
71+
72+
// setSingleInstance —— GroupScope
73+
TEST(CliApplicationHelper_SetSingleInstance_UT, SetSingleInstance_GroupScope_ReturnsTrue)
74+
{
75+
bool ret = CliApplicationHelper::setSingleInstance(
76+
QStringLiteral("ut_cli_helper_group"), CliApplicationHelper::GroupScope);
77+
EXPECT_TRUE(ret);
78+
}
79+
80+
// setSingleInstance —— WorldScope
81+
TEST(CliApplicationHelper_SetSingleInstance_UT, SetSingleInstance_WorldScope_ReturnsTrue)
82+
{
83+
bool ret = CliApplicationHelper::setSingleInstance(
84+
QStringLiteral("ut_cli_helper_world"), CliApplicationHelper::WorldScope);
85+
EXPECT_TRUE(ret);
86+
}
87+
88+
// setSingleInstance —— 同一 key 再次调用(同进程内复用锁),应返回 true
89+
TEST(CliApplicationHelper_SetSingleInstance_UT, SetSingleInstance_SameKeyTwice_ReturnsTrue)
90+
{
91+
QString key = QStringLiteral("ut_cli_helper_samekey");
92+
bool first = CliApplicationHelper::setSingleInstance(key, CliApplicationHelper::UserScope);
93+
EXPECT_TRUE(first);
94+
95+
bool second = CliApplicationHelper::setSingleInstance(key, CliApplicationHelper::UserScope);
96+
EXPECT_TRUE(second);
97+
}
98+
99+
// waitTime 静态成员可读写,验证默认值合理性
100+
TEST(CliApplicationHelper_Misc_UT, WaitTime_IsPositive)
101+
{
102+
EXPECT_GT(CliApplicationHelper::waitTime, 0);
103+
}
104+
105+
#include <QDataStream>
106+
#include <QIODevice>
107+
108+
// 触发 setSingleInstance 中 newConnection/readyRead 两个 lambda(line 159/168):
109+
// 使用事件循环驱动(QTest::qWait 轮询),而非阻塞式 waitForReadyRead,
110+
// 因为 server 端 QLocalSocket 的 flush() 需要事件循环才能将数据写入 socket。
111+
TEST(CliApplicationHelper_SetSingleInstance_UT, SetSingleInstance_NewConnectionHandlerFires)
112+
{
113+
QString key = QStringLiteral("ut_lambda_trigger");
114+
bool ret = CliApplicationHelper::setSingleInstance(key, CliApplicationHelper::UserScope);
115+
EXPECT_TRUE(ret);
116+
117+
// UserScope on Linux: prefix + "<uid>_" + key
118+
QString socketKey = QStringLiteral("_d_deepin_logger_single_instance_%1_%2")
119+
.arg(::getuid()).arg(key);
120+
121+
QLocalSocket client;
122+
client.connectToServer(socketKey);
123+
ASSERT_TRUE(client.waitForConnected(3000));
124+
125+
// 事件循环驱动:等待 server 端 newConnection lambda 触发并发送数据
126+
// QTest::qWait 运行事件循环,使 server 端 socket flush 生效
127+
for (int i = 0; i < 30 && client.bytesAvailable() < (int)sizeof(qint64); ++i) {
128+
QTest::qWait(100);
129+
}
130+
ASSERT_GT(client.bytesAvailable(), 0);
131+
132+
QDataStream in(&client);
133+
qint8 version = 0;
134+
qint64 pid = -1;
135+
QStringList arguments;
136+
in >> version >> pid >> arguments;
137+
EXPECT_GE(pid, 0);
138+
139+
// 回写数据触发 server 端 readyRead lambda(line 168)
140+
{
141+
QByteArray block;
142+
QDataStream out(&block, QIODevice::WriteOnly);
143+
out << (qint8)1 << (qint64)QCoreApplication::applicationPid()
144+
<< QStringList{QStringLiteral("ut_lambda_arg")};
145+
client.write(block);
146+
client.flush();
147+
}
148+
149+
// 事件循环驱动:等待 server 端 readyRead lambda 触发
150+
QTest::qWait(1000);
151+
152+
client.disconnectFromServer();
153+
if (client.state() != QLocalSocket::UnconnectedState) {
154+
client.waitForDisconnected(1000);
155+
}
156+
SUCCEED();
157+
}

‎tests/src/ut_journalwork.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ TEST(journalWork_doWork_UT, journalWork_doWork_UT)
9898
p->deleteLater();
9999
}
100100

101+
TEST(journalWork_run_UT, journalWork_run_UT)
102+
{
103+
journalWork *p = new journalWork(nullptr);
104+
EXPECT_NE(p, nullptr);
105+
Stub stub;
106+
stub.set(sd_journal_get_data, stub_sd_journal_get_data_work);
107+
stub.set(ADDR(journalWork, getReplaceColorStr), stub_getReplaceColorStr_work);
108+
p->run();
109+
p->deleteLater();
110+
}
111+
101112
TEST(journalWork_getReplaceColorStr_UT, journalWork_getReplaceColorStr_UT)
102113
{
103114
journalWork *p = new journalWork(nullptr);

0 commit comments

Comments
 (0)