Files
JNetApplet/tests/tst_networkmonitorapplet.cpp
T
Jokul 2e615df2ff test: 新增C++后端单元测试,标记#17完成并更新审查清单
新建 tests/tst_networkmonitorapplet.cpp(Qt Test),5个测试用例覆盖
isPhysicalInterface、速度计算、负值钳制、总量累加、接口校验。

同时更新审查清单:#17标记完成,推荐开发中#19/#20/#21/#23/#30/#33
标记为随缺陷修复一并完成。
2026-07-24 19:03:52 +08:00

203 lines
6.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// SPDX-FileCopyrightText: 2026 Jokul
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// NetworkMonitorApplet 单元测试
// 覆盖核心纯逻辑函数:isPhysicalInterface、速度计算(含真实间隔/负值钳制/总量累加)、
// setActiveInterface 接口校验
// 用 #define private public 技巧访问私有成员(friend 声明因 DS_BEGIN_NAMESPACE
// 命名空间与 Q_OBJECT 宏交互而无法正确解析,此为 C++ 测试常用替代方案)
// 必须在 include 头文件之前定义,使 private 成员在测试编译单元中可访问
#define private public
#include "networkmonitorapplet.h"
#undef private
#include <QtTest/QtTest>
#include <QDateTime>
// dde-shell 的 DS 命名空间(DS_BEGIN_NAMESPACE = namespace ds {
DS_USE_NAMESPACE
class NetworkMonitorAppletTest : public QObject
{
Q_OBJECT
private:
// 创建 applet 实例的辅助方法
// 构造时不调用 init()(会启动定时器),仅用于测试纯逻辑方法
NetworkMonitorApplet *createApplet()
{
return new NetworkMonitorApplet();
}
private slots:
// isPhysicalInterface:物理网卡前缀匹配
void testIsPhysicalInterface_data();
void testIsPhysicalInterface();
// 速度计算:按真实时间间隔计算
void testCalculateSpeed();
// 计数器回绕时负值钳制为 0
void testNegativeDeltaClamped();
// 总量累加而非取计数器值
void testTotalAccumulation();
// setActiveInterface 拒绝无效接口名
void testSetActiveInterfaceValidation();
};
void NetworkMonitorAppletTest::testIsPhysicalInterface_data()
{
QTest::addColumn<QString>("name");
QTest::addColumn<bool>("expected");
// 物理网卡
QTest::newRow("wlp3s0") << "wlp3s0" << true;
QTest::newRow("wlan0") << "wlan0" << true;
QTest::newRow("enp3s0") << "enp3s0" << true;
QTest::newRow("eth0") << "eth0" << true;
// 非物理接口
QTest::newRow("lo") << "lo" << false;
QTest::newRow("docker0") << "docker0" << false;
QTest::newRow("veth0") << "veth0" << false;
QTest::newRow("br-xxx") << "br-xxx" << false;
QTest::newRow("tun0") << "tun0" << false;
QTest::newRow("Meta") << "Meta" << false;
QTest::newRow("empty") << "" << false;
}
void NetworkMonitorAppletTest::testIsPhysicalInterface()
{
NetworkMonitorApplet *applet = createApplet();
QFETCH(QString, name);
QFETCH(bool, expected);
QCOMPARE(applet->isPhysicalInterface(name), expected);
delete applet;
}
void NetworkMonitorAppletTest::testCalculateSpeed()
{
NetworkMonitorApplet *applet = createApplet();
// 设置活动接口和接口数据
applet->m_interfaceList = QStringList() << "eth0";
NetworkInterface iface;
iface.name = "eth0";
iface.rxBytes = 1000;
iface.txBytes = 500;
applet->m_interfaces["eth0"] = iface;
applet->m_activeInterface = "eth0";
// 模拟首次更新:记录基线
applet->m_firstUpdate = true;
applet->calculateSpeed();
QVERIFY(!applet->m_firstUpdate);
// 第二次更新:字节增加了 1000 rx / 500 tx,间隔约 1 秒
iface.rxBytes = 2000;
iface.txBytes = 1000;
applet->m_interfaces["eth0"] = iface;
applet->m_lastTimestampMs = QDateTime::currentMSecsSinceEpoch() - 1000;
applet->calculateSpeed();
// 速度应约为 1000 bytes/sec(允许误差因真实时间戳)
QVERIFY(applet->m_downloadSpeed > 900 && applet->m_downloadSpeed < 1100);
QVERIFY(applet->m_uploadSpeed > 450 && applet->m_uploadSpeed < 550);
delete applet;
}
void NetworkMonitorAppletTest::testNegativeDeltaClamped()
{
NetworkMonitorApplet *applet = createApplet();
applet->m_interfaceList = QStringList() << "eth0";
NetworkInterface iface;
iface.name = "eth0";
iface.rxBytes = 2000;
iface.txBytes = 1000;
applet->m_interfaces["eth0"] = iface;
applet->m_activeInterface = "eth0";
// 首次更新记录基线
applet->m_firstUpdate = true;
applet->calculateSpeed();
// 模拟计数器回绕:当前值小于上次值
iface.rxBytes = 500; // 回绕!
iface.txBytes = 200; // 回绕!
applet->m_interfaces["eth0"] = iface;
applet->m_lastTimestampMs = QDateTime::currentMSecsSinceEpoch() - 1000;
applet->calculateSpeed();
// 速度应为 0,不应为负
QVERIFY(applet->m_downloadSpeed >= 0);
QVERIFY(applet->m_uploadSpeed >= 0);
delete applet;
}
void NetworkMonitorAppletTest::testTotalAccumulation()
{
NetworkMonitorApplet *applet = createApplet();
applet->m_interfaceList = QStringList() << "eth0";
NetworkInterface iface;
iface.name = "eth0";
iface.rxBytes = 0;
iface.txBytes = 0;
applet->m_interfaces["eth0"] = iface;
applet->m_activeInterface = "eth0";
applet->m_totalDownload = 0;
applet->m_totalUpload = 0;
// 首次更新记录基线
applet->m_firstUpdate = true;
applet->calculateSpeed();
// 第一次增量:rx +1000, tx +500
iface.rxBytes = 1000;
iface.txBytes = 500;
applet->m_interfaces["eth0"] = iface;
applet->m_lastTimestampMs = QDateTime::currentMSecsSinceEpoch() - 1000;
applet->calculateSpeed();
QCOMPARE(applet->m_totalDownload, qint64(1000));
QCOMPARE(applet->m_totalUpload, qint64(500));
// 第二次增量:rx +2000, tx +1000
iface.rxBytes = 3000;
iface.txBytes = 1500;
applet->m_interfaces["eth0"] = iface;
applet->m_lastTimestampMs = QDateTime::currentMSecsSinceEpoch() - 1000;
applet->calculateSpeed();
// 总量应累加,而非取计数器值
QCOMPARE(applet->m_totalDownload, qint64(3000));
QCOMPARE(applet->m_totalUpload, qint64(1500));
delete applet;
}
void NetworkMonitorAppletTest::testSetActiveInterfaceValidation()
{
NetworkMonitorApplet *applet = createApplet();
applet->m_interfaceList = QStringList() << "eth0" << "wlan0";
applet->m_activeInterface = "eth0";
// 无效接口名应被忽略
applet->setActiveInterface("nonexistent");
QCOMPARE(applet->m_activeInterface, QString("eth0"));
// 有效接口名应被设置
applet->setActiveInterface("wlan0");
QCOMPARE(applet->m_activeInterface, QString("wlan0"));
delete applet;
}
QTEST_MAIN(NetworkMonitorAppletTest)
#include "tst_networkmonitorapplet.moc"