QDAirPortTestSystemBackend/tests/HTTPDataSourceTest.cpp
2026-01-27 15:24:05 +08:00

286 lines
12 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 "network/HTTPDataSource.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "utils/Logger.h"
#include <set>
#include <memory>
#include <thread>
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> aircraft;
bool success = source.fetchPositionAircraftData(aircraft);
ASSERT_TRUE(success) << "获取航空器数据失败";
ASSERT_FALSE(aircraft.empty()) << "航空器数据为空";
std::vector<Vehicle> 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> 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> 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> 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<Vehicle> 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::microseconds>(
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::microseconds>(
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::microseconds>(
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<Vehicle> 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::microseconds>(
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::microseconds>(
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::microseconds>(
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::microseconds>(
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<TrafficLightSignal> 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));
}