Files
Alicho/tests/unit/frontend/transport_layer_test.cpp
2025-10-28 10:27:49 +08:00

449 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.
// ================================================================================================
// Audio Backend - 网络传输层测试
// ================================================================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "frontend/network/transport_layer.h"
#include "tests/common/test_fixtures.h"
#include <thread>
#include <chrono>
#include <memory>
#include <string>
#include <vector>
using namespace audio_backend;
using namespace audio_backend::frontend;
using namespace std::chrono_literals;
// 创建模拟网络层
class MockNetworkLayer {
public:
MOCK_METHOD(bool, connect, (const std::string&, uint16_t));
MOCK_METHOD(bool, disconnect, ());
MOCK_METHOD(bool, is_connected, (), (const));
MOCK_METHOD(bool, send_data, (const std::vector<uint8_t>&));
MOCK_METHOD(bool, receive_data, (std::vector<uint8_t>&, std::chrono::milliseconds));
MOCK_METHOD(int, get_last_error, (), (const));
MOCK_METHOD(std::string, get_last_error_message, (), (const));
};
// 创建模拟传输层事件监听器
class MockTransportEventListener : public ITransportEventListener {
public:
MOCK_METHOD(void, on_connected, (const std::string&, uint16_t), (override));
MOCK_METHOD(void, on_disconnected, (), (override));
MOCK_METHOD(void, on_data_received, (const std::vector<uint8_t>&), (override));
MOCK_METHOD(void, on_error, (TransportError, const std::string&), (override));
MOCK_METHOD(void, on_stats_updated, (const TransportStatistics&), (override));
};
// 创建可测试传输层实现
class TestableTransportLayer : public TransportLayer {
public:
explicit TestableTransportLayer(const TransportConfig& config, MockNetworkLayer* network_layer)
: TransportLayer(config), network_layer_(network_layer) {
// 替换内部网络层为模拟实现
}
// 模拟网络层函数
bool override_connect(bool success) {
is_connected_ = success;
if (success) {
notify_connected(current_host_, current_port_);
}
return success;
}
bool override_disconnect(bool success) {
bool was_connected = is_connected_;
is_connected_ = !success;
if (success && was_connected) {
notify_disconnected();
}
return success;
}
bool override_send_data(const std::vector<uint8_t>& data, bool success) {
if (success) {
stats_.bytes_sent += data.size();
stats_.packets_sent++;
} else {
stats_.send_errors++;
}
return success;
}
void simulate_data_received(const std::vector<uint8_t>& data) {
stats_.bytes_received += data.size();
stats_.packets_received++;
notify_data_received(data);
}
void simulate_error(TransportError error, const std::string& message) {
stats_.errors++;
notify_error(error, message);
}
void simulate_network_outage() {
bool was_connected = is_connected_;
is_connected_ = false;
if (was_connected) {
notify_disconnected();
simulate_error(TransportError::ConnectionLost, "网络连接中断");
}
}
void simulate_network_recovery() {
bool was_disconnected = !is_connected_;
is_connected_ = true;
if (was_disconnected) {
notify_connected(current_host_, current_port_);
}
}
// 暴露内部函数和状态用于测试
using TransportLayer::notify_connected;
using TransportLayer::notify_disconnected;
using TransportLayer::notify_data_received;
using TransportLayer::notify_error;
using TransportLayer::notify_stats_updated;
bool is_connected_{false};
std::string current_host_{"localhost"};
uint16_t current_port_{8000};
TransportStatistics stats_{};
private:
MockNetworkLayer* network_layer_;
};
// 传输层测试固定装置
class TransportLayerTest : public test::FrontendTest {
protected:
void SetUp() override {
test::FrontendTest::SetUp();
// 创建模拟网络层
network_layer_ = std::make_unique<MockNetworkLayer>();
// 创建传输层配置
TransportConfig config;
config.host = "localhost";
config.port = 8000;
config.protocol = TransportProtocol::TCP;
config.buffer_size = 8192;
config.connect_timeout_ms = 1000;
config.auto_reconnect = true;
config.max_reconnect_attempts = 3;
config.reconnect_interval_ms = 500;
config.enable_encryption = true;
config.enable_compression = true;
// 创建可测试传输层
transport_ = std::make_unique<TestableTransportLayer>(config, network_layer_.get());
// 创建模拟事件监听器
listener_ = std::make_shared<::testing::NiceMock<MockTransportEventListener>>();
// 添加事件监听器
transport_->add_listener(listener_);
}
void TearDown() override {
// 移除事件监听器
if (listener_ && transport_) {
transport_->remove_listener(listener_);
}
// 关闭传输层
if (transport_ && transport_->is_initialized()) {
transport_->shutdown();
}
transport_.reset();
listener_.reset();
network_layer_.reset();
test::FrontendTest::TearDown();
}
// 创建测试数据包
std::vector<uint8_t> create_test_packet(size_t size, uint8_t value = 0) {
std::vector<uint8_t> packet(size, value);
return packet;
}
protected:
std::unique_ptr<MockNetworkLayer> network_layer_;
std::unique_ptr<TestableTransportLayer> transport_;
std::shared_ptr<MockTransportEventListener> listener_;
};
// 测试初始化和关闭
TEST_F(TransportLayerTest, InitializeAndShutdown) {
// 初始化传输层
auto result = transport_->initialize();
// 验证初始化成功
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_TRUE(transport_->is_initialized());
// 关闭传输层
result = transport_->shutdown();
// 验证关闭成功
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_FALSE(transport_->is_initialized());
}
// 测试连接管理
TEST_F(TransportLayerTest, ConnectionManagement) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 设置连接事件期望
EXPECT_CALL(*listener_, on_connected("localhost", 8000))
.Times(1);
// 模拟连接成功
bool connected = transport_->override_connect(true);
// 验证连接成功
EXPECT_TRUE(connected);
EXPECT_TRUE(transport_->is_connected_);
// 设置断开连接事件期望
EXPECT_CALL(*listener_, on_disconnected())
.Times(1);
// 模拟断开连接
bool disconnected = transport_->override_disconnect(true);
// 验证断开连接
EXPECT_TRUE(disconnected);
EXPECT_FALSE(transport_->is_connected_);
}
// 测试数据发送
TEST_F(TransportLayerTest, DataSending) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 模拟连接
transport_->override_connect(true);
// 创建测试数据包
auto packet = create_test_packet(1024, 0xAB);
// 模拟发送数据
bool sent = transport_->override_send_data(packet, true);
// 验证发送成功
EXPECT_TRUE(sent);
// 验证统计信息更新
EXPECT_EQ(transport_->stats_.packets_sent, 1);
EXPECT_EQ(transport_->stats_.bytes_sent, 1024);
}
// 测试数据接收
TEST_F(TransportLayerTest, DataReceiving) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 模拟连接
transport_->override_connect(true);
// 创建测试数据包
auto packet = create_test_packet(2048, 0xCD);
// 设置数据接收事件期望
EXPECT_CALL(*listener_, on_data_received(packet))
.Times(1);
// 模拟数据接收
transport_->simulate_data_received(packet);
// 验证统计信息更新
EXPECT_EQ(transport_->stats_.packets_received, 1);
EXPECT_EQ(transport_->stats_.bytes_received, 2048);
}
// 测试错误处理
TEST_F(TransportLayerTest, ErrorHandling) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 模拟连接
transport_->override_connect(true);
// 设置错误事件期望
TransportError expected_error = TransportError::ConnectionLost;
std::string error_message = "连接中断";
EXPECT_CALL(*listener_, on_error(expected_error, error_message))
.Times(1);
// 模拟错误
transport_->simulate_error(expected_error, error_message);
// 验证统计信息更新
EXPECT_EQ(transport_->stats_.errors, 1);
}
// 测试网络中断和恢复
TEST_F(TransportLayerTest, NetworkOutageAndRecovery) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 模拟连接
transport_->override_connect(true);
// 设置断开连接事件期望
EXPECT_CALL(*listener_, on_disconnected())
.Times(1);
// 设置错误事件期望
EXPECT_CALL(*listener_, on_error(TransportError::ConnectionLost, ::testing::_))
.Times(1);
// 模拟网络中断
transport_->simulate_network_outage();
// 验证连接状态
EXPECT_FALSE(transport_->is_connected_);
// 设置连接事件期望
EXPECT_CALL(*listener_, on_connected(transport_->current_host_, transport_->current_port_))
.Times(1);
// 模拟网络恢复
transport_->simulate_network_recovery();
// 验证连接状态
EXPECT_TRUE(transport_->is_connected_);
}
// 测试并发数据发送
TEST_F(TransportLayerTest, ConcurrentDataSending) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 模拟连接
transport_->override_connect(true);
// 发送多个数据包
const int num_packets = 10;
std::vector<std::thread> sender_threads;
for (int i = 0; i < num_packets; ++i) {
sender_threads.emplace_back([this, i]() {
// 创建测试数据包
auto packet = create_test_packet(512, static_cast<uint8_t>(i));
// 模拟发送数据
transport_->override_send_data(packet, true);
});
}
// 等待所有线程完成
for (auto& thread : sender_threads) {
thread.join();
}
// 验证统计信息更新
EXPECT_EQ(transport_->stats_.packets_sent, num_packets);
EXPECT_EQ(transport_->stats_.bytes_sent, num_packets * 512);
}
// 测试带QoS的数据发送
TEST_F(TransportLayerTest, QoSDataSending) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 模拟连接
transport_->override_connect(true);
// 创建测试数据包
auto packet = create_test_packet(1024, 0xAB);
// 测试不同的QoS级别
QoSLevel qos_levels[] = {
QoSLevel::BestEffort,
QoSLevel::Reliable,
QoSLevel::RealTime,
QoSLevel::Guaranteed
};
for (auto qos : qos_levels) {
// 模拟发送数据使用不同的QoS
transport_->set_default_qos(qos);
bool sent = transport_->override_send_data(packet, true);
// 验证发送成功
EXPECT_TRUE(sent);
}
// 验证统计信息更新
EXPECT_EQ(transport_->stats_.packets_sent, 4);
EXPECT_EQ(transport_->stats_.bytes_sent, 4 * 1024);
}
// 测试统计信息更新和通知
TEST_F(TransportLayerTest, StatisticsUpdateAndNotification) {
// 初始化传输层
ASSERT_EQ(transport_->initialize(), common::ErrorCode::Success);
// 设置统计信息更新事件期望
EXPECT_CALL(*listener_, on_stats_updated(::testing::_))
.Times(::testing::AtLeast(1));
// 模拟连接和数据传输
transport_->override_connect(true);
// 发送数据包
transport_->override_send_data(create_test_packet(1000), true);
// 接收数据包
transport_->simulate_data_received(create_test_packet(2000));
// 手动触发统计信息通知
transport_->notify_stats_updated(transport_->stats_);
// 验证统计信息
EXPECT_EQ(transport_->stats_.packets_sent, 1);
EXPECT_EQ(transport_->stats_.bytes_sent, 1000);
EXPECT_EQ(transport_->stats_.packets_received, 1);
EXPECT_EQ(transport_->stats_.bytes_received, 2000);
}
// 测试配置设置
TEST_F(TransportLayerTest, ConfigurationSettings) {
// 创建不同的传输层配置
TransportConfig config;
config.host = "example.com";
config.port = 9000;
config.protocol = TransportProtocol::UDP;
config.buffer_size = 16384;
config.connect_timeout_ms = 2000;
config.auto_reconnect = false;
// 创建使用新配置的传输层
auto custom_transport = std::make_unique<TestableTransportLayer>(config, network_layer_.get());
// 初始化
ASSERT_EQ(custom_transport->initialize(), common::ErrorCode::Success);
// 验证使用新配置
EXPECT_EQ(custom_transport->current_host_, "example.com");
EXPECT_EQ(custom_transport->current_port_, 9000);
// 清理
custom_transport->shutdown();
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}