#include "network/HTTPDataSource.h" #include #include #include "utils/Logger.h" #include #include #include class HTTPDataSourceTest : public ::testing::Test { protected: void SetUp() override {} void TearDown() override {} }; TEST_F(HTTPDataSourceTest, BasicFunctionality) { DataSourceConfig config; config.position.host = "localhost"; config.position.port = 8081; config.position.aircraft_path = "/openApi/getCurrentFlightPositions"; config.position.vehicle_path = "/openApi/getCurrentVehiclePositions"; config.position.auth.auth_required = true; config.position.auth.auth_path = "/login"; config.position.auth.username = "dianxin"; config.position.auth.password = "dianxin@123"; config.position.timeout_ms = 5000; config.position.read_timeout_ms = 2000; config.position.refresh_interval_ms = 100; HTTPDataSource source(config); ASSERT_TRUE(source.connect()) << "连接失败"; std::vector aircraft; bool success = source.fetchPositionAircraftData(aircraft); ASSERT_TRUE(success) << "获取航空器数据失败"; ASSERT_FALSE(aircraft.empty()) << "航空器数据为空"; std::vector vehicles; ASSERT_TRUE(source.fetchPositionVehicleData(vehicles)) << "获取车辆数据失败"; ASSERT_FALSE(vehicles.empty()) << "车辆数据为空"; } TEST_F(HTTPDataSourceTest, AuthenticationFailure) { DataSourceConfig config; config.position.host = "localhost"; config.position.port = 8081; config.position.aircraft_path = "/openApi/getCurrentFlightPositions"; config.position.vehicle_path = "/openApi/getCurrentVehiclePositions"; config.position.refresh_interval_ms = 1000; config.position.timeout_ms = 1000; config.position.read_timeout_ms = 500; config.position.auth.auth_required = true; config.position.auth.username = "wrong_user"; config.position.auth.password = "wrong_pass"; config.position.auth.auth_path = "/login"; HTTPDataSource source(config); std::vector aircraft; EXPECT_FALSE(source.fetchPositionAircraftData(aircraft)); } TEST_F(HTTPDataSourceTest, Reconnection) { DataSourceConfig config; config.position.host = "localhost"; config.position.port = 8081; config.position.aircraft_path = "/openApi/getCurrentFlightPositions"; config.position.vehicle_path = "/openApi/getCurrentVehiclePositions"; config.position.refresh_interval_ms = 1000; config.position.timeout_ms = 1000; config.position.read_timeout_ms = 500; config.position.auth.auth_required = true; config.position.auth.username = "dianxin"; config.position.auth.password = "dianxin@123"; config.position.auth.auth_path = "/login"; HTTPDataSource source(config); EXPECT_TRUE(source.connect()); std::vector aircraft; EXPECT_TRUE(source.fetchPositionAircraftData(aircraft)); source.disconnect(); EXPECT_TRUE(source.connect()); aircraft.clear(); EXPECT_TRUE(source.fetchPositionAircraftData(aircraft)); } TEST_F(HTTPDataSourceTest, AuthenticationOnly) { DataSourceConfig config; config.position.host = "localhost"; config.position.port = 8081; config.position.aircraft_path = "/openApi/getCurrentFlightPositions"; config.position.vehicle_path = "/openApi/getCurrentVehiclePositions"; config.position.refresh_interval_ms = 1000; config.position.timeout_ms = 1000; config.position.read_timeout_ms = 500; config.position.auth.auth_required = true; config.position.auth.username = "dianxin"; config.position.auth.password = "dianxin@123"; config.position.auth.auth_path = "/login"; HTTPDataSource source(config); EXPECT_TRUE(source.connect()); std::vector aircraft; EXPECT_TRUE(source.fetchPositionAircraftData(aircraft)); } TEST_F(HTTPDataSourceTest, TrafficLightSignals) { DataSourceConfig config; config.position.host = "localhost"; config.position.port = 8081; config.position.aircraft_path = "/openApi/getCurrentFlightPositions"; config.position.vehicle_path = "/openApi/getCurrentVehiclePositions"; config.position.auth.auth_required = true; config.position.auth.auth_path = "/login"; config.position.auth.username = "dianxin"; config.position.auth.password = "dianxin@123"; config.position.timeout_ms = 5000; config.position.read_timeout_ms = 2000; config.position.refresh_interval_ms = 100; config.traffic_light.host = "localhost"; config.traffic_light.port = 8081; config.traffic_light.signal_path = "/api/VehicleCommandInfo"; config.vehicle.host = "localhost"; config.vehicle.port = 8081; config.vehicle.command_path = "/api/VehicleCommandInfo"; HTTPDataSource source(config); ASSERT_TRUE(source.connect()); // 先获取车辆状态来初始化车辆 std::vector vehicles; ASSERT_TRUE(source.fetchPositionVehicleData(vehicles)) << "获取车辆状态失败"; ASSERT_FALSE(vehicles.empty()) << "车辆数据为空"; // 发送绿灯指令(优先级 2) VehicleCommand green_command; green_command.vehicleId = "QN001"; green_command.type = CommandType::SIGNAL; green_command.reason = CommandReason::TRAFFIC_LIGHT; green_command.signalState = SignalState::GREEN; green_command.intersectionId = "INTERSECTION_001"; green_command.timestamp = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(source.sendUnmannedVehicleCommand(green_command.vehicleId, green_command)) << "发送绿灯指令失败"; // 等待绿灯指令生效 std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 发送红灯指令(优先级 4) VehicleCommand red_command; red_command.vehicleId = "QN001"; red_command.type = CommandType::SIGNAL; red_command.reason = CommandReason::TRAFFIC_LIGHT; red_command.signalState = SignalState::RED; red_command.intersectionId = "INTERSECTION_001"; red_command.latitude = 36.36; red_command.longitude = 120.08; red_command.timestamp = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(source.sendUnmannedVehicleCommand(red_command.vehicleId, red_command)) << "发送红灯指令失败"; // 等待红灯指令生效 std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 最后发送绿灯指令 green_command.timestamp = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(source.sendUnmannedVehicleCommand(green_command.vehicleId, green_command)) << "发送最终绿灯指令失败"; } TEST_F(HTTPDataSourceTest, UnmannedVehicleCommand) { DataSourceConfig config; config.position.host = "localhost"; config.position.port = 8081; config.position.aircraft_path = "/openApi/getCurrentFlightPositions"; config.position.vehicle_path = "/openApi/getCurrentVehiclePositions"; config.position.auth.auth_required = true; config.position.auth.auth_path = "/login"; config.position.auth.username = "dianxin"; config.position.auth.password = "dianxin@123"; config.position.timeout_ms = 5000; config.position.read_timeout_ms = 2000; config.position.refresh_interval_ms = 100; config.vehicle.host = "localhost"; config.vehicle.port = 8081; config.vehicle.command_path = "/api/VehicleCommandInfo"; config.vehicle.auth.auth_required = true; config.vehicle.auth.auth_path = "/login"; config.vehicle.auth.username = "dianxin"; config.vehicle.auth.password = "dianxin@123"; config.vehicle.timeout_ms = 5000; config.vehicle.read_timeout_ms = 2000; HTTPDataSource source(config); ASSERT_TRUE(source.connect()) << "连接失败"; // 先获取车辆状态来初始化车辆 std::vector vehicles; ASSERT_TRUE(source.fetchPositionVehicleData(vehicles)) << "获取车辆状态失败"; ASSERT_FALSE(vehicles.empty()) << "车辆数据为空"; // 先发送 RESUME 指令清除所有状态 VehicleCommand resume_command; resume_command.vehicleId = "QN001"; resume_command.type = CommandType::RESUME; resume_command.reason = CommandReason::RESUME_TRAFFIC; resume_command.timestamp = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(source.sendUnmannedVehicleCommand(resume_command.vehicleId, resume_command)) << "发送恢复指令失败"; // 等待 RESUME 指令生效 std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 发送 WARNING 指令(优先级 3) VehicleCommand warning_command; warning_command.vehicleId = "QN001"; warning_command.type = CommandType::WARNING; warning_command.reason = CommandReason::AIRCRAFT_CROSSING; warning_command.relativeSpeed = 50; warning_command.relativeMotionX = 50; warning_command.relativeMotionY = 50; warning_command.timestamp = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(source.sendUnmannedVehicleCommand(warning_command.vehicleId, warning_command)) << "发送预警指令失败"; // 等待 WARNING 指令生效 std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 发送 ALERT 指令(优先级 5) VehicleCommand alert_command; alert_command.vehicleId = "QN001"; alert_command.type = CommandType::ALERT; alert_command.reason = CommandReason::AIRCRAFT_CROSSING; alert_command.relativeSpeed = 100; alert_command.relativeMotionX = 100; alert_command.relativeMotionY = 100; alert_command.timestamp = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(source.sendUnmannedVehicleCommand(alert_command.vehicleId, alert_command)) << "发送告警指令失败"; // 等待 ALERT 指令生效 std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 最后发送 RESUME 指令清除状态 resume_command.timestamp = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); ASSERT_TRUE(source.sendUnmannedVehicleCommand(resume_command.vehicleId, resume_command)) << "发送最终恢复指令失败"; } TEST_F(HTTPDataSourceTest, TrafficLightAndUnmannedAuthFailure) { DataSourceConfig config; config.traffic_light.host = "localhost"; config.traffic_light.port = 8081; config.traffic_light.signal_path = "/api/VehicleCommandInfo"; config.traffic_light.auth.auth_required = true; config.traffic_light.auth.username = "wrong_user"; config.traffic_light.auth.password = "wrong_pass"; config.vehicle.host = "localhost"; config.vehicle.port = 8081; config.vehicle.command_path = "/api/VehicleCommandInfo"; config.vehicle.auth.auth_required = true; config.vehicle.auth.username = "wrong_user"; config.vehicle.auth.password = "wrong_pass"; HTTPDataSource source(config); std::vector signals; EXPECT_FALSE(source.fetchTrafficLightSignals(signals)); VehicleCommand command; command.vehicleId = "TEST_VEHICLE_001"; command.type = CommandType::SIGNAL; command.reason = CommandReason::RESUME_TRAFFIC; command.signalState = SignalState::GREEN; command.timestamp = 0; EXPECT_FALSE(source.sendUnmannedVehicleCommand(command.vehicleId, command)); }