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

458 lines
16 KiB
C++

// ================================================================================================
// Audio Backend - 会话管理器测试
// ================================================================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "frontend/network/session_manager.h"
#include "tests/common/test_fixtures.h"
#include <thread>
#include <chrono>
#include <memory>
#include <string>
using namespace audio_backend;
using namespace audio_backend::frontend;
using namespace std::chrono_literals;
// 创建模拟会话事件监听器
class MockSessionEventListener : public ISessionEventListener {
public:
MOCK_METHOD(void, on_session_created, (const SessionInfo&), (override));
MOCK_METHOD(void, on_session_closed, (const std::string&), (override));
MOCK_METHOD(void, on_session_error, (const std::string&, SessionErrorType, const std::string&), (override));
MOCK_METHOD(void, on_session_status_changed, (const std::string&, SessionStatus, SessionStatus), (override));
MOCK_METHOD(void, on_client_joined, (const std::string&, const ClientInfo&), (override));
MOCK_METHOD(void, on_client_left, (const std::string&, const std::string&), (override));
MOCK_METHOD(void, on_session_config_changed, (const std::string&, const SessionConfig&), (override));
MOCK_METHOD(void, on_session_stats_updated, (const std::string&, const SessionStatistics&), (override));
};
// 创建模拟传输层
class MockTransportLayer {
public:
MOCK_METHOD(common::ErrorCode, initialize, ());
MOCK_METHOD(common::ErrorCode, shutdown, ());
MOCK_METHOD(bool, is_initialized, (), (const));
MOCK_METHOD(common::ErrorCode, connect, (const std::string&, uint16_t));
MOCK_METHOD(common::ErrorCode, disconnect, ());
MOCK_METHOD(bool, is_connected, (), (const));
MOCK_METHOD(common::ErrorCode, send_data, (const std::vector<uint8_t>&));
MOCK_METHOD(common::ErrorCode, receive_data, (std::vector<uint8_t>&, std::chrono::milliseconds));
MOCK_METHOD(common::ErrorCode, join_multicast_group, (const std::string&));
MOCK_METHOD(common::ErrorCode, leave_multicast_group, (const std::string&));
};
// 创建可测试会话管理器
class TestableSessionManager : public SessionManager {
public:
explicit TestableSessionManager(const SessionManagerConfig& config)
: SessionManager(config) {}
// 设置模拟传输层
void set_mock_transport_layer(std::shared_ptr<MockTransportLayer> transport) {
mock_transport_ = transport;
}
// 重载内部方法以使用模拟对象
common::ErrorCode initialize_transport() override {
if (mock_transport_) {
return mock_transport_->initialize();
}
return common::ErrorCode::InitializationFailed;
}
// 模拟会话操作
void simulate_session_created(const SessionInfo& session) {
sessions_[session.id] = session;
notify_session_created(session);
}
void simulate_session_closed(const std::string& session_id) {
auto it = sessions_.find(session_id);
if (it != sessions_.end()) {
sessions_.erase(it);
notify_session_closed(session_id);
}
}
void simulate_session_status_changed(const std::string& session_id, SessionStatus new_status) {
auto it = sessions_.find(session_id);
if (it != sessions_.end()) {
SessionStatus old_status = it->second.status;
it->second.status = new_status;
notify_session_status_changed(session_id, old_status, new_status);
}
}
void simulate_client_joined(const std::string& session_id, const ClientInfo& client) {
auto it = sessions_.find(session_id);
if (it != sessions_.end()) {
it->second.clients.push_back(client);
notify_client_joined(session_id, client);
}
}
void simulate_client_left(const std::string& session_id, const std::string& client_id) {
auto it = sessions_.find(session_id);
if (it != sessions_.end()) {
auto& clients = it->second.clients;
for (auto cit = clients.begin(); cit != clients.end(); ++cit) {
if (cit->id == client_id) {
clients.erase(cit);
break;
}
}
notify_client_left(session_id, client_id);
}
}
void simulate_session_error(const std::string& session_id, SessionErrorType error, const std::string& message) {
notify_session_error(session_id, error, message);
}
// 暴露内部函数和状态用于测试
using SessionManager::notify_session_created;
using SessionManager::notify_session_closed;
using SessionManager::notify_session_error;
using SessionManager::notify_session_status_changed;
using SessionManager::notify_client_joined;
using SessionManager::notify_client_left;
using SessionManager::notify_session_config_changed;
using SessionManager::notify_session_stats_updated;
std::map<std::string, SessionInfo> sessions_;
private:
std::shared_ptr<MockTransportLayer> mock_transport_;
};
// 会话管理器测试固定装置
class SessionManagerTest : public test::FrontendTest {
protected:
void SetUp() override {
test::FrontendTest::SetUp();
// 创建模拟传输层
mock_transport_ = std::make_shared<MockTransportLayer>();
// 创建会话管理器配置
SessionManagerConfig config;
config.max_sessions = 10;
config.enable_auto_reconnect = true;
config.reconnect_interval_ms = 1000;
config.session_timeout_ms = 30000;
config.default_port = 8000;
// 创建可测试会话管理器
session_manager_ = std::make_unique<TestableSessionManager>(config);
// 设置模拟传输层
session_manager_->set_mock_transport_layer(mock_transport_);
// 创建模拟事件监听器
listener_ = std::make_shared<::testing::NiceMock<MockSessionEventListener>>();
// 添加事件监听器
session_manager_->add_listener(listener_);
}
void TearDown() override {
// 移除事件监听器
if (listener_ && session_manager_) {
session_manager_->remove_listener(listener_);
}
// 关闭会话管理器
if (session_manager_ && session_manager_->is_initialized()) {
session_manager_->shutdown();
}
session_manager_.reset();
listener_.reset();
mock_transport_.reset();
test::FrontendTest::TearDown();
}
// 创建测试会话信息
SessionInfo create_test_session(const std::string& id = "session-1") {
SessionInfo session;
session.id = id;
session.name = "测试会话 " + id;
session.host = "192.168.1.100";
session.port = 8000;
session.status = SessionStatus::Active;
session.input_device_id = "input-device-1";
session.output_device_id = "output-device-1";
session.start_time = std::chrono::system_clock::now();
session.sample_rate = 48000;
session.channels = 2;
session.format = engine::AudioFormat::FLOAT32;
// 添加两个客户端
ClientInfo client1;
client1.id = "client-1";
client1.name = "客户端1";
client1.address = "192.168.1.101";
client1.join_time = std::chrono::system_clock::now();
client1.status = ClientStatus::Connected;
session.clients.push_back(client1);
ClientInfo client2;
client2.id = "client-2";
client2.name = "客户端2";
client2.address = "192.168.1.102";
client2.join_time = std::chrono::system_clock::now();
client2.status = ClientStatus::Connected;
session.clients.push_back(client2);
return session;
}
// 创建测试客户端信息
ClientInfo create_test_client(const std::string& id = "client-3") {
ClientInfo client;
client.id = id;
client.name = "客户端 " + id;
client.address = "192.168.1.103";
client.join_time = std::chrono::system_clock::now();
client.status = ClientStatus::Connected;
return client;
}
protected:
std::shared_ptr<MockTransportLayer> mock_transport_;
std::unique_ptr<TestableSessionManager> session_manager_;
std::shared_ptr<MockSessionEventListener> listener_;
};
// 测试初始化和关闭
TEST_F(SessionManagerTest, InitializeAndShutdown) {
// 设置模拟传输层期望
EXPECT_CALL(*mock_transport_, initialize())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
// 初始化会话管理器
auto result = session_manager_->initialize();
// 验证初始化成功
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_TRUE(session_manager_->is_initialized());
// 设置模拟传输层关闭期望
EXPECT_CALL(*mock_transport_, shutdown())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
// 关闭会话管理器
result = session_manager_->shutdown();
// 验证关闭成功
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_FALSE(session_manager_->is_initialized());
}
// 测试会话创建事件
TEST_F(SessionManagerTest, SessionCreationEvent) {
// 初始化会话管理器
EXPECT_CALL(*mock_transport_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(session_manager_->initialize(), common::ErrorCode::Success);
// 创建测试会话
SessionInfo session = create_test_session();
// 设置事件期望
EXPECT_CALL(*listener_, on_session_created(::testing::_))
.Times(1)
.WillOnce(::testing::Invoke([&session](const SessionInfo& info) {
EXPECT_EQ(info.id, session.id);
EXPECT_EQ(info.name, session.name);
EXPECT_EQ(info.host, session.host);
EXPECT_EQ(info.port, session.port);
EXPECT_EQ(info.status, session.status);
}));
// 模拟会话创建
session_manager_->simulate_session_created(session);
// 验证会话存在
EXPECT_EQ(session_manager_->sessions_.size(), 1);
EXPECT_TRUE(session_manager_->sessions_.count(session.id) > 0);
}
// 测试会话关闭事件
TEST_F(SessionManagerTest, SessionCloseEvent) {
// 初始化会话管理器
EXPECT_CALL(*mock_transport_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(session_manager_->initialize(), common::ErrorCode::Success);
// 创建测试会话
SessionInfo session = create_test_session();
session_manager_->simulate_session_created(session);
// 设置事件期望
EXPECT_CALL(*listener_, on_session_closed(session.id))
.Times(1);
// 模拟会话关闭
session_manager_->simulate_session_closed(session.id);
// 验证会话已关闭
EXPECT_EQ(session_manager_->sessions_.size(), 0);
}
// 测试会话状态变更事件
TEST_F(SessionManagerTest, SessionStatusChangeEvent) {
// 初始化会话管理器
EXPECT_CALL(*mock_transport_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(session_manager_->initialize(), common::ErrorCode::Success);
// 创建测试会话
SessionInfo session = create_test_session();
session_manager_->simulate_session_created(session);
// 设置事件期望
SessionStatus old_status = session.status;
SessionStatus new_status = SessionStatus::Paused;
EXPECT_CALL(*listener_, on_session_status_changed(session.id, old_status, new_status))
.Times(1);
// 模拟状态变更
session_manager_->simulate_session_status_changed(session.id, new_status);
// 验证状态已变更
EXPECT_EQ(session_manager_->sessions_[session.id].status, new_status);
}
// 测试客户端加入事件
TEST_F(SessionManagerTest, ClientJoinEvent) {
// 初始化会话管理器
EXPECT_CALL(*mock_transport_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(session_manager_->initialize(), common::ErrorCode::Success);
// 创建测试会话
SessionInfo session = create_test_session();
session_manager_->simulate_session_created(session);
// 创建新客户端
ClientInfo new_client = create_test_client();
// 设置事件期望
EXPECT_CALL(*listener_, on_client_joined(session.id, ::testing::_))
.Times(1)
.WillOnce(::testing::Invoke([&new_client](const std::string& session_id, const ClientInfo& client) {
EXPECT_EQ(client.id, new_client.id);
EXPECT_EQ(client.name, new_client.name);
EXPECT_EQ(client.address, new_client.address);
EXPECT_EQ(client.status, new_client.status);
}));
// 模拟客户端加入
session_manager_->simulate_client_joined(session.id, new_client);
// 验证客户端已加入
EXPECT_EQ(session_manager_->sessions_[session.id].clients.size(), 3);
}
// 测试客户端离开事件
TEST_F(SessionManagerTest, ClientLeaveEvent) {
// 初始化会话管理器
EXPECT_CALL(*mock_transport_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(session_manager_->initialize(), common::ErrorCode::Success);
// 创建测试会话
SessionInfo session = create_test_session();
session_manager_->simulate_session_created(session);
// 要离开的客户端ID
std::string client_id = session.clients[0].id;
// 设置事件期望
EXPECT_CALL(*listener_, on_client_left(session.id, client_id))
.Times(1);
// 模拟客户端离开
session_manager_->simulate_client_left(session.id, client_id);
// 验证客户端已离开
EXPECT_EQ(session_manager_->sessions_[session.id].clients.size(), 1);
}
// 测试会话错误事件
TEST_F(SessionManagerTest, SessionErrorEvent) {
// 初始化会话管理器
EXPECT_CALL(*mock_transport_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(session_manager_->initialize(), common::ErrorCode::Success);
// 创建测试会话
SessionInfo session = create_test_session();
session_manager_->simulate_session_created(session);
// 设置错误事件期望
SessionErrorType error_type = SessionErrorType::ConnectionError;
std::string error_message = "会话连接中断";
EXPECT_CALL(*listener_, on_session_error(session.id, error_type, error_message))
.Times(1);
// 模拟会话错误
session_manager_->simulate_session_error(session.id, error_type, error_message);
}
// 测试多个会话管理
TEST_F(SessionManagerTest, MultipleSessionManagement) {
// 初始化会话管理器
EXPECT_CALL(*mock_transport_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(session_manager_->initialize(), common::ErrorCode::Success);
// 创建多个测试会话
SessionInfo session1 = create_test_session("session-1");
SessionInfo session2 = create_test_session("session-2");
SessionInfo session3 = create_test_session("session-3");
// 设置事件期望
EXPECT_CALL(*listener_, on_session_created(::testing::_))
.Times(3);
// 模拟创建多个会话
session_manager_->simulate_session_created(session1);
session_manager_->simulate_session_created(session2);
session_manager_->simulate_session_created(session3);
// 验证会话已创建
EXPECT_EQ(session_manager_->sessions_.size(), 3);
// 设置会话关闭事件期望
EXPECT_CALL(*listener_, on_session_closed(::testing::_))
.Times(3);
// 模拟关闭所有会话
session_manager_->simulate_session_closed(session1.id);
session_manager_->simulate_session_closed(session2.id);
session_manager_->simulate_session_closed(session3.id);
// 验证会话已关闭
EXPECT_EQ(session_manager_->sessions_.size(), 0);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}