#include #include #include "collector/DataCollector.h" #include "utils/Logger.h" #include "network/MessageTypes.h" #include "core/System.h" // 创建一个 Mock DataSource 类 class MockDataSource : public DataSource { public: MOCK_METHOD0(connect, bool()); MOCK_METHOD0(disconnect, void()); MOCK_CONST_METHOD0(isAvailable, bool()); MOCK_METHOD1(fetchAircraftData, bool(std::vector&)); MOCK_METHOD1(fetchVehicleData, bool(std::vector&)); MOCK_METHOD1(fetchTrafficLightSignals, bool(std::vector&)); }; class DataCollectorTest : public ::testing::Test { protected: void SetUp() override { collector = std::make_unique(); mockSource = std::make_shared<::testing::NiceMock>(); collector->setDataSource(mockSource); } void TearDown() override { collector.reset(); } // 创建测试数据 Aircraft createTestAircraft(const std::string& id, double lat, double lon) { Aircraft a; a.id = id; a.flightNo = id; a.trackNumber = "TN" + id; a.geo.latitude = lat; a.geo.longitude = lon; a.altitude = 5.0; a.timestamp = std::chrono::system_clock::now().time_since_epoch().count(); return a; } Vehicle createTestVehicle(const std::string& id, double lat, double lon) { Vehicle v; v.id = id; v.vehicleNo = id; v.geo.latitude = lat; v.geo.longitude = lon; v.timestamp = std::chrono::system_clock::now().time_since_epoch().count(); return v; } // 创建测试用的红绿灯信号 TrafficLightSignal createTestTrafficLight(const std::string& id, int state) { TrafficLightSignal signal; signal.trafficLightId = id; signal.status = static_cast(state); signal.timestamp = std::chrono::system_clock::now().time_since_epoch().count(); return signal; } std::unique_ptr collector; std::shared_ptr mockSource; }; // 测试初始化 TEST_F(DataCollectorTest, Initialization) { DataSourceConfig dataSourceConfig; dataSourceConfig.host = "localhost"; dataSourceConfig.port = 8080; dataSourceConfig.aircraft_path = "/api/getCurrentFlightPositions"; WarnConfig warnConfig; warnConfig.warning_interval_ms = 1000; warnConfig.log_interval_ms = 2000; EXPECT_TRUE(collector->initialize(dataSourceConfig, warnConfig)); } // 测试刷新方法 TEST_F(DataCollectorTest, RefreshTest) { std::vector testAircraft = { createTestAircraft("TEST1", 36.36, 120.08), createTestAircraft("TEST2", 36.37, 120.09) }; std::vector testVehicles = { createTestVehicle("VEH1", 36.36, 120.08), createTestVehicle("VEH2", 36.37, 120.09) }; // 设置 Mock 数据返回 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillOnce(::testing::DoAll( ::testing::SetArgReferee<0>(testAircraft), ::testing::Return(true) )); EXPECT_CALL(*mockSource, fetchVehicleData(::testing::_)) .WillOnce(::testing::DoAll( ::testing::SetArgReferee<0>(testVehicles), ::testing::Return(true) )); // 执行刷新 collector->refresh(); // 验证数据 auto aircraft = collector->getAircraftData(); EXPECT_EQ(aircraft.size(), 2); if (!aircraft.empty()) { EXPECT_EQ(aircraft[0].flightNo, "TEST1"); EXPECT_EQ(aircraft[1].flightNo, "TEST2"); } auto vehicles = collector->getVehicleData(); EXPECT_EQ(vehicles.size(), 2); if (!vehicles.empty()) { EXPECT_EQ(vehicles[0].vehicleNo, "VEH1"); EXPECT_EQ(vehicles[1].vehicleNo, "VEH2"); } } // 测试数据采集循环 TEST_F(DataCollectorTest, DataCollectionLoop) { std::vector testAircraft = { createTestAircraft("TEST1", 36.36, 120.08) }; std::vector testVehicles = { createTestVehicle("VEH1", 36.36, 120.08) }; // 设置 Mock 数据返回 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillRepeatedly(::testing::DoAll( ::testing::SetArgReferee<0>(testAircraft), ::testing::Return(true) )); EXPECT_CALL(*mockSource, fetchVehicleData(::testing::_)) .WillRepeatedly(::testing::DoAll( ::testing::SetArgReferee<0>(testVehicles), ::testing::Return(true) )); // 启动采集 collector->start(); // 等待数据采集 std::this_thread::sleep_for(std::chrono::seconds(2)); // 停止采集 collector->stop(); // 验证数据 auto aircraft = collector->getAircraftData(); EXPECT_EQ(aircraft.size(), 1); auto vehicles = collector->getVehicleData(); EXPECT_EQ(vehicles.size(), 1); } // 测试错误处理 TEST_F(DataCollectorTest, ErrorHandling) { // 设置 Mock 返回错误 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillOnce(::testing::Return(false)); EXPECT_CALL(*mockSource, fetchVehicleData(::testing::_)) .WillOnce(::testing::Return(false)); // 执行刷新 collector->refresh(); // 验证数据为空 auto aircraft = collector->getAircraftData(); EXPECT_TRUE(aircraft.empty()); auto vehicles = collector->getVehicleData(); EXPECT_TRUE(vehicles.empty()); } // 测试红绿灯信号获取 TEST_F(DataCollectorTest, TrafficLightSignalsTest) { std::vector testSignals = { createTestTrafficLight("TL001", 0), // RED = 0 createTestTrafficLight("TL002", 1), // GREEN = 1 createTestTrafficLight("TL003", 2) // YELLOW = 2 }; // 设置 Mock 数据返回 EXPECT_CALL(*mockSource, fetchTrafficLightSignals(::testing::_)) .WillOnce(::testing::DoAll( ::testing::SetArgReferee<0>(testSignals), ::testing::Return(true) )); // 执行刷新 collector->refresh(); // 验证数据 auto signals = collector->getTrafficLightSignals(); EXPECT_EQ(signals.size(), 3); if (signals.size() >= 3) { EXPECT_EQ(signals[0].trafficLightId, "TL001"); EXPECT_EQ(signals[0].status, SignalStatus::RED); // RED = 0 EXPECT_EQ(signals[1].trafficLightId, "TL002"); EXPECT_EQ(signals[1].status, SignalStatus::GREEN); // GREEN = 1 } } // 测试红绿灯信号错误处理 TEST_F(DataCollectorTest, TrafficLightSignalsErrorTest) { // 设置 Mock 返回错误 EXPECT_CALL(*mockSource, fetchTrafficLightSignals(::testing::_)) .WillOnce(::testing::Return(false)); // 执行刷新 collector->refresh(); // 验证数据为空 auto signals = collector->getTrafficLightSignals(); EXPECT_TRUE(signals.empty()); } // 测试连接健康检查和超时告警 TEST_F(DataCollectorTest, ConnectionHealthAndTimeout) { DataSourceConfig dataSourceConfig; dataSourceConfig.host = "localhost"; dataSourceConfig.port = 8080; dataSourceConfig.timeout_ms = 1000; // 1秒超时 dataSourceConfig.refresh_interval_ms = 100; // 100ms刷新间隔 WarnConfig warnConfig; warnConfig.warning_interval_ms = 500; // 500ms告警间隔 collector->initialize(dataSourceConfig, warnConfig); // 模拟连接健康检查失败 EXPECT_CALL(*mockSource, isAvailable()) .WillRepeatedly(::testing::Return(false)); // 模拟数据获取失败 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillRepeatedly(::testing::Return(false)); EXPECT_CALL(*mockSource, fetchVehicleData(::testing::_)) .WillRepeatedly(::testing::Return(false)); // 启动采集 collector->start(); // 等待超过超时时间 std::this_thread::sleep_for(std::chrono::milliseconds(1500)); // 停止采集 collector->stop(); // 验证数据为空 auto aircraft = collector->getAircraftData(); EXPECT_TRUE(aircraft.empty()); auto vehicles = collector->getVehicleData(); EXPECT_TRUE(vehicles.empty()); } // 测试连接恢复 TEST_F(DataCollectorTest, ConnectionRecovery) { DataSourceConfig config; config.host = "localhost"; config.port = 8080; config.refresh_interval_ms = 10; WarnConfig warnConfig; warnConfig.warning_interval_ms = 20; collector->initialize(config, warnConfig); std::vector testAircraft = { createTestAircraft("TEST1", 36.36, 120.08) }; // 移除 InSequence,直接设置期望 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillOnce(::testing::Return(false)) .WillOnce(::testing::DoAll( ::testing::SetArgReferee<0>(testAircraft), ::testing::Return(true) )); // 行两次刷新 collector->refresh(); // 第一次失败 collector->refresh(); // 第二次成功 // 验证数据 auto aircraft = collector->getAircraftData(); EXPECT_EQ(aircraft.size(), 1); if (!aircraft.empty()) { EXPECT_EQ(aircraft[0].flightNo, "TEST1"); } } // 测试长连接下的数据获取 TEST_F(DataCollectorTest, LongConnectionDataFetch) { DataSourceConfig dataSourceConfig; dataSourceConfig.host = "localhost"; dataSourceConfig.port = 8080; dataSourceConfig.refresh_interval_ms = 100; collector->initialize(dataSourceConfig, WarnConfig{}); std::vector testAircraft = { createTestAircraft("TEST1", 36.36, 120.08) }; // 模拟连接保持可用 EXPECT_CALL(*mockSource, isAvailable()) .WillRepeatedly(::testing::Return(true)); // 模拟多次成功获取数据 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .Times(::testing::AtLeast(3)) .WillRepeatedly(::testing::DoAll( ::testing::SetArgReferee<0>(testAircraft), ::testing::Return(true) )); // 启动采集 collector->start(); // 等待多个刷新周期 std::this_thread::sleep_for(std::chrono::milliseconds(350)); // 应该执行至少3次获取 // 验证数据 auto aircraft = collector->getAircraftData(); EXPECT_FALSE(aircraft.empty()); if (!aircraft.empty()) { EXPECT_EQ(aircraft[0].flightNo, "TEST1"); } // 停止采集 collector->stop(); } TEST_F(DataCollectorTest, InitializeWithTimeoutConfig) { DataSourceConfig config; config.host = "localhost"; config.port = 8080; config.timeout_ms = 5000; // 连接超时 5 秒 config.read_timeout_ms = 2000; // 读取超时 2 秒 config.refresh_interval_ms = 100; WarnConfig warnConfig; warnConfig.warning_interval_ms = 500; EXPECT_NO_THROW(collector->initialize(config, warnConfig)); } TEST_F(DataCollectorTest, TimeoutWarningTest) { DataSourceConfig config; config.host = "localhost"; config.port = 8080; config.timeout_ms = 1000; // 连接超时 1 秒 config.read_timeout_ms = 500; // 读取超时 0.5 秒 config.refresh_interval_ms = 100; WarnConfig warnConfig; warnConfig.warning_interval_ms = 200; // 警告间隔 0.2 秒 collector->initialize(config, warnConfig); // 模拟连接成功但读取超时 EXPECT_CALL(*mockSource, isAvailable()) .WillRepeatedly(::testing::Return(true)); EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillRepeatedly(::testing::Return(false)); // 持续读取超时 // 启动采集 collector->start(); // 等待足够长的时间以触发多次警告 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 停止采集 collector->stop(); } // 测试超时警告机制 TEST_F(DataCollectorTest, TimeoutWarningMechanism) { DataSourceConfig config; config.host = "localhost"; config.port = 8080; config.timeout_ms = 200; // 连接超时 200ms config.read_timeout_ms = 100; // 读取超时 100ms config.refresh_interval_ms = 10; WarnConfig warnConfig; warnConfig.warning_interval_ms = 50; // 警告间隔 50ms // 创建一个计数器来记录收到的警告数量 int warningCount = 0; // 创建一个 mock System 来捕获警告 class MockSystem : public System { public: MOCK_METHOD1(broadcastTimeoutWarning, void(const network::TimeoutWarningMessage&)); }; auto mockSystem = std::make_shared(); // 设置期望接收到超时警告 EXPECT_CALL(*mockSystem, broadcastTimeoutWarning(::testing::_)) .WillRepeatedly(::testing::Invoke([&warningCount](const network::TimeoutWarningMessage& warning) { warningCount++; // 验证警告消息的内容 EXPECT_EQ(warning.source, "data_source"); EXPECT_GT(warning.elapsed_ms, 0); // 不检查具体的超时类型,因为这取决于实际的时间流逝 })); // 设置 mock system 到 collector collector->setSystem(mockSystem); collector->initialize(config, warnConfig); // 启动采集器 collector->start(); // 模拟数据获取失败 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillRepeatedly(::testing::Return(false)); // 等待足够长的时间以确保警告被发送 // 等待时间应该超过 refresh_interval_ms + timeout_ms + warning_interval_ms std::this_thread::sleep_for(std::chrono::milliseconds(300)); // 停止采集器 collector->stop(); // 验证是否收到了警告 EXPECT_GT(warningCount, 0); } // 测试读取超时机制 TEST_F(DataCollectorTest, ReadTimeoutMechanism) { DataSourceConfig config; config.host = "localhost"; config.port = 8080; config.timeout_ms = 100; // 连接超时 100ms config.read_timeout_ms = 50; // 读取超时 50ms config.refresh_interval_ms = 10; WarnConfig warnConfig; warnConfig.warning_interval_ms = 20; // 警告间隔 20ms // 创建一个计数器来记录收到的警告数量 int warningCount = 0; // 创建一个 mock System 来捕获警告 class MockSystem : public System { public: MOCK_METHOD1(broadcastTimeoutWarning, void(const network::TimeoutWarningMessage&)); }; auto mockSystem = std::make_shared(); // 设置期望接收到超时警告 EXPECT_CALL(*mockSystem, broadcastTimeoutWarning(::testing::_)) .WillRepeatedly(::testing::Invoke([&warningCount](const network::TimeoutWarningMessage& warning) { warningCount++; // 验证警告消息的内容 EXPECT_EQ(warning.source, "data_source"); EXPECT_GT(warning.elapsed_ms, 0); EXPECT_TRUE(warning.is_read_timeout); // 标记为读取超时 })); // 设置 mock system 到 collector collector->setSystem(mockSystem); collector->initialize(config, warnConfig); // 启动采集器 collector->start(); // 模拟读取超时 EXPECT_CALL(*mockSource, fetchAircraftData(::testing::_)) .WillRepeatedly(::testing::Invoke([](std::vector& aircraft) { std::this_thread::sleep_for(std::chrono::milliseconds(60)); // 睡眠超过读取超时时间但小于连���超时 return false; })); // 等待足够长的时间以确保警告被发送 // 等待时间应该超过 refresh_interval_ms + read_timeout_ms + warning_interval_ms std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 停止采集器 collector->stop(); // 验证是否收到了警告 EXPECT_GT(warningCount, 0); }