416 lines
15 KiB
C++
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();
|
|
} |