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

416 lines
15 KiB
C++

// ================================================================================================
// Audio Backend - 前端管理器测试
// ================================================================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "frontend/manager/frontend_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 MockFrontendEventListener : public IFrontendEventListener {
public:
MOCK_METHOD(void, on_frontend_initialized, (), (override));
MOCK_METHOD(void, on_frontend_shutdown, (), (override));
MOCK_METHOD(void, on_engine_status_changed, (const EngineStatus&), (override));
MOCK_METHOD(void, on_device_status_changed, (const AudioDeviceInfo&), (override));
MOCK_METHOD(void, on_session_created, (const SessionInfo&), (override));
MOCK_METHOD(void, on_session_closed, (const std::string&), (override));
MOCK_METHOD(void, on_error_occurred, (FrontendErrorType, const std::string&), (override));
MOCK_METHOD(void, on_log_message, (LogLevel, const std::string&), (override));
};
// 创建模拟设备管理器
class MockDeviceManager {
public:
MOCK_METHOD(common::ErrorCode, initialize, ());
MOCK_METHOD(common::ErrorCode, shutdown, ());
MOCK_METHOD(bool, is_initialized, (), (const));
MOCK_METHOD(std::vector<AudioDeviceInfo>, get_all_devices, (), (const));
MOCK_METHOD(std::vector<AudioDeviceInfo>, get_input_devices, (), (const));
MOCK_METHOD(std::vector<AudioDeviceInfo>, get_output_devices, (), (const));
MOCK_METHOD(std::optional<AudioDeviceInfo>, get_device_info, (const std::string&), (const));
MOCK_METHOD(common::ErrorCode, configure_device, (const DeviceConfiguration&));
MOCK_METHOD(common::ErrorCode, start_input_stream, (const std::string&));
MOCK_METHOD(common::ErrorCode, stop_input_stream, (const std::string&));
MOCK_METHOD(common::ErrorCode, start_output_stream, (const std::string&));
MOCK_METHOD(common::ErrorCode, stop_output_stream, (const std::string&));
};
// 创建模拟引擎代理
class MockEngineProxy {
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&));
MOCK_METHOD(common::ErrorCode, disconnect, ());
MOCK_METHOD(bool, is_connected, (), (const));
MOCK_METHOD(common::ErrorCode, send_command, (EngineCommand, const std::string&));
MOCK_METHOD(common::ErrorCode, get_engine_status, (EngineStatus&));
MOCK_METHOD(EngineState, get_current_state, (), (const));
MOCK_METHOD(common::ErrorCode, send_audio_data, (const engine::AudioBuffer&));
};
// 创建可测试前端管理器
class TestableFrontendManager : public FrontendManager {
public:
TestableFrontendManager(const FrontendConfiguration& config)
: FrontendManager(config) {}
// 设置模拟设备管理器和引擎代理
void set_mock_device_manager(std::shared_ptr<MockDeviceManager> mock_device_manager) {
mock_device_manager_ = mock_device_manager;
}
void set_mock_engine_proxy(std::shared_ptr<MockEngineProxy> mock_engine_proxy) {
mock_engine_proxy_ = mock_engine_proxy;
}
// 重载内部方法以使用模拟对象
common::ErrorCode initialize_device_manager() override {
if (mock_device_manager_) {
return mock_device_manager_->initialize();
}
return common::ErrorCode::InitializationFailed;
}
common::ErrorCode initialize_engine_proxy() override {
if (mock_engine_proxy_) {
return mock_engine_proxy_->initialize();
}
return common::ErrorCode::InitializationFailed;
}
// 允许直接触发事件
using FrontendManager::notify_engine_status_changed;
using FrontendManager::notify_device_status_changed;
using FrontendManager::notify_session_created;
using FrontendManager::notify_session_closed;
using FrontendManager::notify_error_occurred;
using FrontendManager::notify_log_message;
private:
std::shared_ptr<MockDeviceManager> mock_device_manager_;
std::shared_ptr<MockEngineProxy> mock_engine_proxy_;
};
// 前端管理器测试固定装置
class FrontendManagerTest : public test::FrontendTest {
protected:
void SetUp() override {
test::FrontendTest::SetUp();
// 创建模拟组件
mock_device_manager_ = std::make_shared<MockDeviceManager>();
mock_engine_proxy_ = std::make_shared<MockEngineProxy>();
// 创建前端配置
FrontendConfiguration config;
config.device_manager_config.auto_detect_devices = true;
config.engine_proxy_config.engine_endpoint = "tcp://localhost:5555";
config.session_manager_config.enable_auto_reconnect = true;
config.service_discovery_config.enable_mdns = true;
config.log_level = LogLevel::Debug;
// 创建可测试前端管理器
frontend_manager_ = std::make_unique<TestableFrontendManager>(config);
// 设置模拟组件
frontend_manager_->set_mock_device_manager(mock_device_manager_);
frontend_manager_->set_mock_engine_proxy(mock_engine_proxy_);
// 创建模拟事件监听器
listener_ = std::make_shared<::testing::NiceMock<MockFrontendEventListener>>();
// 添加事件监听器
frontend_manager_->add_event_listener(listener_);
}
void TearDown() override {
// 移除事件监听器
if (listener_ && frontend_manager_) {
frontend_manager_->remove_event_listener(listener_);
}
// 关闭前端管理器
if (frontend_manager_ && frontend_manager_->is_initialized()) {
frontend_manager_->shutdown();
}
frontend_manager_.reset();
listener_.reset();
mock_device_manager_.reset();
mock_engine_proxy_.reset();
test::FrontendTest::TearDown();
}
// 创建测试设备信息
AudioDeviceInfo create_test_device(DeviceType type) {
AudioDeviceInfo device;
if (type == DeviceType::Input) {
device.id = "input-device-1";
device.name = "测试输入设备";
device.type = DeviceType::Input;
device.is_default_input = true;
} else {
device.id = "output-device-1";
device.name = "测试输出设备";
device.type = DeviceType::Output;
device.is_default_output = true;
}
device.driver = DeviceDriver::WASAPI;
device.state = DeviceState::Available;
device.current_sample_rate = 48000;
device.current_channels = 2;
device.current_format = engine::AudioFormat::FLOAT32;
return device;
}
// 创建测试会话信息
SessionInfo create_test_session() {
SessionInfo session;
session.id = "session-1";
session.name = "测试会话";
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;
return session;
}
// 创建测试引擎状态
EngineStatus create_test_engine_status() {
EngineStatus status;
status.state = EngineState::Running;
status.config.sample_rate = 48000;
status.config.channels = 2;
status.config.format = engine::AudioFormat::FLOAT32;
status.cpu_usage = 15.0;
status.memory_usage_mb = 128.0;
status.frames_processed = 10000;
status.current_latency_ms = 10.0;
status.last_update = std::chrono::system_clock::now();
return status;
}
protected:
std::shared_ptr<MockDeviceManager> mock_device_manager_;
std::shared_ptr<MockEngineProxy> mock_engine_proxy_;
std::unique_ptr<TestableFrontendManager> frontend_manager_;
std::shared_ptr<MockFrontendEventListener> listener_;
};
// 测试初始化和关闭
TEST_F(FrontendManagerTest, InitializeAndShutdown) {
// 设置模拟组件期望
EXPECT_CALL(*mock_device_manager_, initialize())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
EXPECT_CALL(*mock_engine_proxy_, initialize())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
// 设置事件期望
EXPECT_CALL(*listener_, on_frontend_initialized())
.Times(1);
// 初始化前端管理器
auto result = frontend_manager_->initialize();
// 验证初始化成功
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_TRUE(frontend_manager_->is_initialized());
// 设置模拟组件关闭期望
EXPECT_CALL(*mock_device_manager_, shutdown())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
EXPECT_CALL(*mock_engine_proxy_, shutdown())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
// 设置事件期望
EXPECT_CALL(*listener_, on_frontend_shutdown())
.Times(1);
// 关闭前端管理器
result = frontend_manager_->shutdown();
// 验证关闭成功
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_FALSE(frontend_manager_->is_initialized());
}
// 测试引擎状态变更事件
TEST_F(FrontendManagerTest, EngineStatusChangedEvent) {
// 初始化前端管理器
EXPECT_CALL(*mock_device_manager_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
EXPECT_CALL(*mock_engine_proxy_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(frontend_manager_->initialize(), common::ErrorCode::Success);
// 创建引擎状态
auto engine_status = create_test_engine_status();
// 设置事件期望
EXPECT_CALL(*listener_, on_engine_status_changed(::testing::_))
.Times(1)
.WillOnce(::testing::Invoke([&engine_status](const EngineStatus& status) {
EXPECT_EQ(status.state, engine_status.state);
EXPECT_EQ(status.config.sample_rate, engine_status.config.sample_rate);
EXPECT_DOUBLE_EQ(status.cpu_usage, engine_status.cpu_usage);
}));
// 触发事件
frontend_manager_->notify_engine_status_changed(engine_status);
}
// 测试设备状态变更事件
TEST_F(FrontendManagerTest, DeviceStatusChangedEvent) {
// 初始化前端管理器
EXPECT_CALL(*mock_device_manager_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
EXPECT_CALL(*mock_engine_proxy_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(frontend_manager_->initialize(), common::ErrorCode::Success);
// 创建设备信息
auto device_info = create_test_device(DeviceType::Output);
// 设置事件期望
EXPECT_CALL(*listener_, on_device_status_changed(::testing::_))
.Times(1)
.WillOnce(::testing::Invoke([&device_info](const AudioDeviceInfo& device) {
EXPECT_EQ(device.id, device_info.id);
EXPECT_EQ(device.name, device_info.name);
EXPECT_EQ(device.type, device_info.type);
}));
// 触发事件
frontend_manager_->notify_device_status_changed(device_info);
}
// 测试会话创建和关闭事件
TEST_F(FrontendManagerTest, SessionEvents) {
// 初始化前端管理器
EXPECT_CALL(*mock_device_manager_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
EXPECT_CALL(*mock_engine_proxy_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(frontend_manager_->initialize(), common::ErrorCode::Success);
// 创建会话信息
auto session_info = create_test_session();
// 设置会话创建事件期望
EXPECT_CALL(*listener_, on_session_created(::testing::_))
.Times(1)
.WillOnce(::testing::Invoke([&session_info](const SessionInfo& session) {
EXPECT_EQ(session.id, session_info.id);
EXPECT_EQ(session.name, session_info.name);
EXPECT_EQ(session.status, session_info.status);
}));
// 触发会话创建事件
frontend_manager_->notify_session_created(session_info);
// 设置会话关闭事件期望
EXPECT_CALL(*listener_, on_session_closed(session_info.id))
.Times(1);
// 触发会话关闭事件
frontend_manager_->notify_session_closed(session_info.id);
}
// 测试错误事件
TEST_F(FrontendManagerTest, ErrorEvent) {
// 初始化前端管理器
EXPECT_CALL(*mock_device_manager_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
EXPECT_CALL(*mock_engine_proxy_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(frontend_manager_->initialize(), common::ErrorCode::Success);
// 设置错误事件期望
FrontendErrorType error_type = FrontendErrorType::DeviceError;
std::string error_message = "设备初始化失败";
EXPECT_CALL(*listener_, on_error_occurred(error_type, error_message))
.Times(1);
// 触发错误事件
frontend_manager_->notify_error_occurred(error_type, error_message);
}
// 测试日志事件
TEST_F(FrontendManagerTest, LogEvent) {
// 初始化前端管理器
EXPECT_CALL(*mock_device_manager_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
EXPECT_CALL(*mock_engine_proxy_, initialize())
.WillOnce(::testing::Return(common::ErrorCode::Success));
ASSERT_EQ(frontend_manager_->initialize(), common::ErrorCode::Success);
// 设置日志事件期望
LogLevel log_level = LogLevel::Info;
std::string log_message = "前端管理器初始化成功";
EXPECT_CALL(*listener_, on_log_message(log_level, log_message))
.Times(1);
// 触发日志事件
frontend_manager_->notify_log_message(log_level, log_message);
}
// 测试初始化失败
TEST_F(FrontendManagerTest, InitializationFailure) {
// 设置设备管理器初始化失败
EXPECT_CALL(*mock_device_manager_, initialize())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::InitializationFailed));
// 设置错误事件期望
EXPECT_CALL(*listener_, on_error_occurred(FrontendErrorType::InitializationError, ::testing::_))
.Times(::testing::AtLeast(0));
// 初始化前端管理器
auto result = frontend_manager_->initialize();
// 验证初始化失败
EXPECT_NE(result, common::ErrorCode::Success);
EXPECT_FALSE(frontend_manager_->is_initialized());
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}