CppGenerate/tests/test_alert_manager.cpp

431 lines
14 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.

#include <gtest/gtest.h>
#include "alert_manager.hpp"
#include <sstream>
#include <iostream>
// 辅助类:用于捕获标准输出和标准错误输出
class StreamCapture {
public:
StreamCapture() : old_cout_(std::cout.rdbuf()), old_cerr_(std::cerr.rdbuf()) {
std::cout.rdbuf(ss_cout_.rdbuf());
std::cerr.rdbuf(ss_cerr_.rdbuf());
}
~StreamCapture() {
std::cout.rdbuf(old_cout_);
std::cerr.rdbuf(old_cerr_);
}
std::string getCout() const { return ss_cout_.str(); }
std::string getCerr() const { return ss_cerr_.str(); }
private:
std::stringstream ss_cout_;
std::stringstream ss_cerr_;
std::streambuf* old_cout_;
std::streambuf* old_cerr_;
};
// 测试夹具:为每个测试用例创建独立的 AlertManager 实例
class AlertManagerTest : public ::testing::Test {
protected:
void SetUp() override {
manager.initialize();
}
void TearDown() override {
manager.resetAllAlerts();
}
AlertManager manager;
};
// ==================== checkAltitudeAlert 测试 ====================
// 正常输入测试:高度在阈值范围内,不应触发任何预警
TEST_F(AlertManagerTest, testCheckAltitudeAlertNormalRange) {
StreamCapture capture;
// 默认阈值上限100.0,下限-50.0
// 测试正常高度 50.0
manager.checkAltitudeAlert(50.0f, 1000);
EXPECT_FALSE(manager.hasActiveAlerts());
EXPECT_FALSE(manager.hasUnacknowledgedAlerts());
// 测试接近上限但未超过
manager.checkAltitudeAlert(99.9f, 1001);
EXPECT_FALSE(manager.hasActiveAlerts());
// 测试接近下限但未低于
manager.checkAltitudeAlert(-49.9f, 1002);
EXPECT_FALSE(manager.hasActiveAlerts());
}
// 边界值测试:高度刚好等于阈值,不应触发预警
TEST_F(AlertManagerTest, testCheckAltitudeAlertAtThreshold) {
StreamCapture capture;
// 测试高度等于上限
manager.checkAltitudeAlert(100.0f, 2000);
EXPECT_FALSE(manager.hasActiveAlerts());
// 测试高度等于下限
manager.checkAltitudeAlert(-50.0f, 2001);
EXPECT_FALSE(manager.hasActiveAlerts());
}
// 边界值测试:高度超过上限,应触发 ALTITUDE_UPPER 预警
TEST_F(AlertManagerTest, testCheckAltitudeAlertExceedsUpper) {
StreamCapture capture;
// 高度超过上限
manager.checkAltitudeAlert(150.0f, 3000);
EXPECT_TRUE(manager.hasActiveAlerts());
EXPECT_TRUE(manager.hasUnacknowledgedAlerts());
auto activeAlerts = manager.getActiveAlerts();
ASSERT_EQ(1, activeAlerts.size());
EXPECT_EQ(AlertType::ALTITUDE_UPPER, activeAlerts[0].type);
EXPECT_EQ(AlertStatus::ACTIVE, activeAlerts[0].status);
EXPECT_EQ(3000, activeAlerts[0].trigger_time);
// 验证输出包含预警信息
std::string coutOutput = capture.getCout();
EXPECT_NE(std::string::npos, coutOutput.find("高度上限预警"));
EXPECT_NE(std::string::npos, coutOutput.find("150"));
}
// 边界值测试:高度低于下限,应触发 ALTITUDE_LOWER 预警
TEST_F(AlertManagerTest, testCheckAltitudeAlertBelowLower) {
StreamCapture capture;
// 高度低于下限
manager.checkAltitudeAlert(-100.0f, 4000);
EXPECT_TRUE(manager.hasActiveAlerts());
EXPECT_TRUE(manager.hasUnacknowledgedAlerts());
auto activeAlerts = manager.getActiveAlerts();
ASSERT_EQ(1, activeAlerts.size());
EXPECT_EQ(AlertType::ALTITUDE_LOWER, activeAlerts[0].type);
EXPECT_EQ(AlertStatus::ACTIVE, activeAlerts[0].status);
EXPECT_EQ(4000, activeAlerts[0].trigger_time);
// 验证输出包含预警信息
std::string coutOutput = capture.getCout();
EXPECT_NE(std::string::npos, coutOutput.find("高度下限预警"));
EXPECT_NE(std::string::npos, coutOutput.find("-100"));
}
// 特殊场景测试:高度超过上限后恢复正常,预警应解除
TEST_F(AlertManagerTest, testCheckAltitudeAlertUpperResolved) {
StreamCapture capture;
// 先触发上限预警
manager.checkAltitudeAlert(150.0f, 5000);
EXPECT_TRUE(manager.hasActiveAlerts());
// 高度恢复正常
manager.checkAltitudeAlert(80.0f, 5001);
// 预警应被解决
EXPECT_FALSE(manager.hasActiveAlerts());
EXPECT_FALSE(manager.hasUnacknowledgedAlerts());
// 验证历史记录中存在已解决的预警
auto history = manager.getAlertHistory(10);
bool foundResolved = false;
for (const auto& alert : history) {
if (alert.type == AlertType::ALTITUDE_UPPER &&
alert.status == AlertStatus::RESOLVED) {
foundResolved = true;
break;
}
}
EXPECT_TRUE(foundResolved);
}
// 特殊场景测试:高度低于下限后恢复正常,预警应解除
TEST_F(AlertManagerTest, testCheckAltitudeAlertLowerResolved) {
StreamCapture capture;
// 先触发下限预警
manager.checkAltitudeAlert(-100.0f, 6000);
EXPECT_TRUE(manager.hasActiveAlerts());
// 高度恢复正常
manager.checkAltitudeAlert(0.0f, 6001);
// 预警应被解决
EXPECT_FALSE(manager.hasActiveAlerts());
EXPECT_FALSE(manager.hasUnacknowledgedAlerts());
// 验证历史记录
auto history = manager.getAlertHistory(10);
bool foundResolved = false;
for (const auto& alert : history) {
if (alert.type == AlertType::ALTITUDE_LOWER &&
alert.status == AlertStatus::RESOLVED) {
foundResolved = true;
break;
}
}
EXPECT_TRUE(foundResolved);
}
// 特殊场景测试:同时超过上下限(理论上不可能,但测试逻辑完整性)
TEST_F(AlertManagerTest, testCheckAltitudeAlertBothThresholds) {
StreamCapture capture;
// 修改阈值使上下限重叠(通过 setAltitudeThresholds 会校验,这里直接测试逻辑)
// 注意:此测试仅验证 checkAltitudeAlert 的逻辑,不依赖阈值设置
// 先触发上限预警
manager.checkAltitudeAlert(150.0f, 7000);
EXPECT_TRUE(manager.hasActiveAlerts());
// 再触发下限预警(此时高度低于下限)
manager.checkAltitudeAlert(-100.0f, 7001);
// 应有 2 个活动预警
auto activeAlerts = manager.getActiveAlerts();
EXPECT_EQ(2, activeAlerts.size());
}
// 异常输入测试:高度为 NaN如果支持
TEST_F(AlertManagerTest, testCheckAltitudeAlertNaN) {
StreamCapture capture;
// 使用 NaN 值(如果编译器支持)
float nanValue = std::numeric_limits<float>::quiet_NaN();
// NaN 与任何值的比较结果都是 false因此不会触发预警
manager.checkAltitudeAlert(nanValue, 8000);
// 不应触发任何预警
EXPECT_FALSE(manager.hasActiveAlerts());
}
// 异常输入测试:高度为无穷大
TEST_F(AlertManagerTest, testCheckAltitudeAlertInfinity) {
StreamCapture capture;
float infValue = std::numeric_limits<float>::infinity();
// 正无穷应触发上限预警
manager.checkAltitudeAlert(infValue, 9000);
EXPECT_TRUE(manager.hasActiveAlerts());
auto activeAlerts = manager.getActiveAlerts();
ASSERT_EQ(1, activeAlerts.size());
EXPECT_EQ(AlertType::ALTITUDE_UPPER, activeAlerts[0].type);
}
// 异常输入测试:高度为负无穷
TEST_F(AlertManagerTest, testCheckAltitudeAlertNegativeInfinity) {
StreamCapture capture;
float negInfValue = -std::numeric_limits<float>::infinity();
// 负无穷应触下限预警
manager.checkAltitudeAlert(negInfValue, 10000);
EXPECT_TRUE(manager.hasActiveAlerts());
auto activeAlerts = manager.getActiveAlerts();
ASSERT_EQ(1, activeAlerts.size());
EXPECT_EQ(AlertType::ALTITUDE_LOWER, activeAlerts[0].type);
}
// 特殊场景测试:时间戳为 0
TEST_F(AlertManagerTest, testCheckAltitudeAlertTimestampZero) {
StreamCapture capture;
// 时间戳为 0 不应影响预警逻辑
manager.checkAltitudeAlert(150.0f, 0);
EXPECT_TRUE(manager.hasActiveAlerts());
auto activeAlerts = manager.getActiveAlerts();
ASSERT_EQ(1, activeAlerts.size());
EXPECT_EQ(0, activeAlerts[0].trigger_time);
}
// 特殊场景测试:连续多次触发同一预警,不应重复触发
TEST_F(AlertManagerTest, testCheckAltitudeAlertDuplicateTrigger) {
StreamCapture capture;
// 第一次触发
manager.checkAltitudeAlert(150.0f, 11000);
EXPECT_TRUE(manager.hasActiveAlerts());
// 第二次触发(高度仍然超过上限)
manager.checkAltitudeAlert(200.0f, 11001);
// 应仍只有 1 个活动预警
auto activeAlerts = manager.getActiveAlerts();
ASSERT_EQ(1, activeAlerts.size());
// 验证历史记录中只有 1 次触发
auto history = manager.getAlertHistory(10);
int triggerCount = 0;
for (const auto& alert : history) {
if (alert.type == AlertType::ALTITUDE_UPPER &&
alert.status == AlertStatus::ACTIVE) {
triggerCount++;
}
}
EXPECT_EQ(1, triggerCount);
}
// ==================== setAltitudeThresholds 测试 ====================
// 正常输入测试:设置有效的上下限阈值
TEST_F(AlertManagerTest, testSetAltitudeThresholdsValid) {
StreamCapture capture;
manager.setAltitudeThresholds(200.0f, -100.0f);
// 验证输出
std::string coutOutput = capture.getCout();
EXPECT_NE(std::string::npos, coutOutput.find("预警阈值已更新"));
EXPECT_NE(std::string::npos, coutOutput.find("200"));
EXPECT_NE(std::string::npos, coutOutput.find("-100"));
// 验证新阈值生效
manager.checkAltitudeAlert(150.0f, 12000);
EXPECT_FALSE(manager.hasActiveAlerts());
manager.checkAltitudeAlert(250.0f, 12001);
EXPECT_TRUE(manager.hasActiveAlerts());
}
// 边界值测试:设置上限等于下限(非法)
TEST_F(AlertManagerTest, testSetAltitudeThresholdsEqual) {
StreamCapture capture;
manager.setAltitudeThresholds(100.0f, 100.0f);
// 验证错误输出
std::string cerrOutput = capture.getCerr();
EXPECT_NE(std::string::npos, cerrOutput.find("上限阈值必须大于下限阈值"));
// 验证阈值未改变
manager.checkAltitudeAlert(150.0f, 13000);
EXPECT_TRUE(manager.hasActiveAlerts());
}
// 异常输入测试:设置上限小于下限(非法)
TEST_F(AlertManagerTest, testSetAltitudeThresholdsUpperLessThanLower) {
StreamCapture capture;
manager.setAltitudeThresholds(-50.0f, 100.0f);
// 验证错误输出
std::string cerrOutput = capture.getCerr();
EXPECT_NE(std::string::npos, cerrOutput.find("上限阈值必须大于下限阈值"));
// 验证阈值未改变
manager.checkAltitudeAlert(150.0f, 14000);
EXPECT_TRUE(manager.hasActiveAlerts());
}
// 边界值测试:设置非常大的阈值范围
TEST_F(AlertManagerTest, testSetAltitudeThresholdsLargeRange) {
StreamCapture capture;
float largeUpper = 1000000.0f;
float largeLower = -1000000.0f;
manager.setAltitudeThresholds(largeUpper, largeLower);
// 验证阈值设置成功
manager.checkAltitudeAlert(500000.0f, 15000);
EXPECT_FALSE(manager.hasActiveAlerts());
manager.checkAltitudeAlert(2000000.0f, 15001);
EXPECT_TRUE(manager.hasActiveAlerts());
}
// 边界值测试:设置非常小的阈值范围
TEST_F(AlertManagerTest, testSetAltitudeThresholdsSmallRange) {
StreamCapture capture;
float smallUpper = 0.001f;
float smallLower = -0.001f;
manager.setAltitudeThresholds(smallUpper, smallLower);
// 验证阈值设置成功
manager.checkAltitudeAlert(0.0005f, 16000);
EXPECT_FALSE(manager.hasActiveAlerts());
manager.checkAltitudeAlert(0.002f, 16001);
EXPECT_TRUE(manager.hasActiveAlerts());
}
// 特殊场景测试:设置阈值后,原有的活动预警应被重置
TEST_F(AlertManagerTest, testSetAltitudeThresholdsResetsAlerts) {
StreamCapture capture;
// 先触发一个预警
manager.checkAltitudeAlert(150.0f, 17000);
EXPECT_TRUE(manager.hasActiveAlerts());
// 修改阈值
manager.setAltitudeThresholds(200.0f, -100.0f);
// 原有的预警应被重置(解决)
EXPECT_FALSE(manager.hasActiveAlerts());
// 验证历史记录中存在已解决的预警
auto history = manager.getAlertHistory(10);
bool foundResolved = false;
for (const auto& alert : history) {
if (alert.type == AlertType::ALTITUDE_UPPER &&
alert.status == AlertStatus::RESOLVED) {
foundResolved = true;
break;
}
}
EXPECT_TRUE(foundResolved);
}
// 特殊场景测试:连续设置阈值,验证状态一致性
TEST_F(AlertManagerTest, testSetAltitudeThresholdsMultipleTimes) {
StreamCapture capture;
// 第一次设置
manager.setAltitudeThresholds(200.0f, -100.0f);
// 触发预警
manager.checkAltitudeAlert(250.0f, 18000);
EXPECT_TRUE(manager.hasActiveAlerts());
// 第二次设置
manager.setAltitudeThresholds(300.0f, -200.0f);
// 原有预警被重置
EXPECT_FALSE(manager.hasActiveAlerts());
// 新阈值下,原来的高度不再触发预警
manager.checkAltitudeAlert(250.0f, 18001);
EXPECT_FALSE(manager.hasActiveAlerts());
}
// 特殊场景测试:设置阈值后立即检查高度
TEST_F(AlertManagerTest, testSetAltitudeThresholdsImmediateCheck) {
StreamCapture capture;
// 设置新阈值
manager.setAltitudeThresholds(50.0f, -10.0f);
// 立即检查高度,应触发预警
manager.checkAltitudeAlert(60.0f, 19000);
EXPECT_TRUE(manager.hasActiveAlerts());
auto activeAlerts = manager.getActiveAlerts();
ASSERT_EQ(1, activeAlerts.size());
EXPECT_EQ(AlertType::ALTITUDE_UPPER, activeAlerts[0].type);
}