Files
Alicho/tests/integration/frontend_engine_test.cpp
2025-10-28 10:27:49 +08:00

557 lines
21 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 "fixtures/integration_test_fixtures.h"
#include "fixtures/test_engine_server.h"
#include "fixtures/test_frontend.h"
#include "frontend/manager/frontend_manager.h"
#include "frontend/proxy/engine_proxy.h"
#include "frontend/device/device_manager.h"
#include <thread>
#include <chrono>
#include <atomic>
#include <mutex>
#include <condition_variable>
using namespace audio_backend;
using namespace audio_backend::test;
using namespace audio_backend::frontend;
using namespace std::chrono_literals;
// 前端事件监听器
class TestFrontendEventListener : public IFrontendEventListener {
public:
void on_frontend_initialized() override {
std::lock_guard<std::mutex> lock(mutex_);
initialized_ = true;
events_.push_back("前端初始化");
cv_.notify_all();
}
void on_frontend_shutdown() override {
std::lock_guard<std::mutex> lock(mutex_);
shutdown_ = true;
events_.push_back("前端关闭");
cv_.notify_all();
}
void on_engine_status_changed(const EngineStatus& status) override {
std::lock_guard<std::mutex> lock(mutex_);
engine_status_changes_++;
last_engine_status_ = status;
events_.push_back("引擎状态变更: " + engine_state_to_string(status.state));
cv_.notify_all();
}
void on_device_status_changed(const AudioDeviceInfo& device) override {
std::lock_guard<std::mutex> lock(mutex_);
device_status_changes_++;
last_device_info_ = device;
events_.push_back("设备状态变更: " + device.name);
cv_.notify_all();
}
void on_session_created(const SessionInfo& session) override {
std::lock_guard<std::mutex> lock(mutex_);
sessions_created_++;
last_session_info_ = session;
events_.push_back("会话创建: " + session.name);
cv_.notify_all();
}
void on_session_closed(const std::string& session_id) override {
std::lock_guard<std::mutex> lock(mutex_);
sessions_closed_++;
last_closed_session_id_ = session_id;
events_.push_back("会话关闭: " + session_id);
cv_.notify_all();
}
void on_error_occurred(FrontendErrorType error_type, const std::string& message) override {
std::lock_guard<std::mutex> lock(mutex_);
errors_++;
last_error_type_ = error_type;
last_error_message_ = message;
events_.push_back("错误发生: " + message);
cv_.notify_all();
}
void on_log_message(LogLevel level, const std::string& message) override {
std::lock_guard<std::mutex> lock(mutex_);
log_messages_++;
last_log_level_ = level;
last_log_message_ = message;
}
// 等待特定事件发生
bool wait_for_event(const std::string& event_prefix,
std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this, &event_prefix]() {
for (const auto& event : events_) {
if (event.find(event_prefix) == 0) {
return true;
}
}
return false;
});
}
// 等待特定引擎状态
bool wait_for_engine_state(EngineState state,
std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this, state]() {
return last_engine_status_.state == state;
});
}
// 等待前端初始化完成
bool wait_for_initialization(std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this]() {
return initialized_;
});
}
// 状态查询
bool is_initialized() const { return initialized_; }
bool is_shutdown() const { return shutdown_; }
int engine_status_changes() const { return engine_status_changes_; }
int device_status_changes() const { return device_status_changes_; }
int sessions_created() const { return sessions_created_; }
int sessions_closed() const { return sessions_closed_; }
int errors() const { return errors_; }
int log_messages() const { return log_messages_; }
// 最后事件信息
const EngineStatus& last_engine_status() const { return last_engine_status_; }
const AudioDeviceInfo& last_device_info() const { return last_device_info_; }
const SessionInfo& last_session_info() const { return last_session_info_; }
const std::string& last_closed_session_id() const { return last_closed_session_id_; }
FrontendErrorType last_error_type() const { return last_error_type_; }
const std::string& last_error_message() const { return last_error_message_; }
LogLevel last_log_level() const { return last_log_level_; }
const std::string& last_log_message() const { return last_log_message_; }
// 清除事件历史
void clear_events() {
std::lock_guard<std::mutex> lock(mutex_);
events_.clear();
}
// 重置计数器
void reset_counters() {
std::lock_guard<std::mutex> lock(mutex_);
engine_status_changes_ = 0;
device_status_changes_ = 0;
sessions_created_ = 0;
sessions_closed_ = 0;
errors_ = 0;
log_messages_ = 0;
}
private:
// 引擎状态转换为字符串
std::string engine_state_to_string(EngineState state) {
switch (state) {
case EngineState::Unknown: return "Unknown";
case EngineState::Stopped: return "Stopped";
case EngineState::Starting: return "Starting";
case EngineState::Running: return "Running";
case EngineState::Paused: return "Paused";
case EngineState::Stopping: return "Stopping";
case EngineState::Error: return "Error";
default: return "未知状态";
}
}
std::mutex mutex_;
std::condition_variable cv_;
std::vector<std::string> events_;
// 状态标志
bool initialized_ = false;
bool shutdown_ = false;
// 事件计数
int engine_status_changes_ = 0;
int device_status_changes_ = 0;
int sessions_created_ = 0;
int sessions_closed_ = 0;
int errors_ = 0;
int log_messages_ = 0;
// 最后事件信息
EngineStatus last_engine_status_;
AudioDeviceInfo last_device_info_;
SessionInfo last_session_info_;
std::string last_closed_session_id_;
FrontendErrorType last_error_type_ = FrontendErrorType::Unknown;
std::string last_error_message_;
LogLevel last_log_level_ = LogLevel::Info;
std::string last_log_message_;
};
// 前端引擎集成测试类
class FrontendEngineIntegrationTest : public FrontendEngineTest {
protected:
void initialize_engine_server() override {
// 创建测试引擎服务器
engine_server_ = std::make_unique<TestEngineServer>(engine_endpoint_);
ASSERT_NE(engine_server_, nullptr);
// 初始化引擎服务器
ASSERT_TRUE(engine_server_->initialize());
// 启动引擎服务器
ASSERT_TRUE(engine_server_->start());
}
void shutdown_engine_server() override {
if (engine_server_) {
// 停止引擎服务器
engine_server_->stop();
// 关闭引擎服务器
engine_server_->shutdown();
}
}
void initialize_frontend_client() override {
// 创建前端配置
FrontendConfiguration frontend_config;
// 引擎代理配置
frontend_config.engine_proxy_config.engine_endpoint = engine_endpoint_;
frontend_config.engine_proxy_config.connection_timeout = 5000ms;
frontend_config.engine_proxy_config.command_timeout = 3000ms;
frontend_config.engine_proxy_config.status_poll_interval = 1000ms;
frontend_config.engine_proxy_config.auto_reconnect = true;
// 设备管理器配置
frontend_config.device_manager_config.auto_detect_devices = true;
frontend_config.device_manager_config.enable_hot_plug_detection = true;
frontend_config.device_manager_config.device_scan_interval_ms = 1000;
frontend_config.device_manager_config.default_buffer_size = DEFAULT_BUFFER_SIZE;
// 会话管理器配置
frontend_config.session_manager_config.max_sessions = 5;
frontend_config.session_manager_config.enable_auto_reconnect = true;
frontend_config.session_manager_config.reconnect_interval_ms = 1000;
// 创建前端管理器
frontend_manager_ = std::make_unique<FrontendManager>(frontend_config);
ASSERT_NE(frontend_manager_, nullptr);
// 创建前端事件监听器
frontend_listener_ = std::make_shared<TestFrontendEventListener>();
ASSERT_NE(frontend_listener_, nullptr);
// 添加事件监听器
frontend_manager_->add_event_listener(frontend_listener_);
// 初始化前端管理器
ASSERT_EQ(frontend_manager_->initialize(), common::ErrorCode::Success);
// 等待初始化完成事件
ASSERT_TRUE(frontend_listener_->wait_for_initialization());
}
void shutdown_frontend_client() override {
if (frontend_manager_) {
// 移除事件监听器
if (frontend_listener_) {
frontend_manager_->remove_event_listener(frontend_listener_);
}
// 关闭前端管理器
frontend_manager_->shutdown();
}
}
// 创建测试音频会话
SessionInfo create_test_session() {
SessionInfo session;
session.id = "test-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 = DEFAULT_SAMPLE_RATE;
session.channels = DEFAULT_CHANNELS;
session.format = engine::AudioFormat::FLOAT32;
return session;
}
protected:
std::shared_ptr<TestFrontendEventListener> frontend_listener_;
};
// ================================================================================================
// 基本连接测试
// ================================================================================================
TEST_F(FrontendEngineIntegrationTest, BasicConnection) {
// 验证前端已初始化
EXPECT_TRUE(frontend_manager_->is_initialized());
EXPECT_TRUE(frontend_listener_->is_initialized());
// 验证引擎连接
// 等待引擎状态变为Running表示前端已成功连接到引擎
EXPECT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 验证引擎状态
EXPECT_GE(frontend_listener_->engine_status_changes(), 1);
EXPECT_EQ(frontend_listener_->last_engine_status().state, EngineState::Running);
}
// ================================================================================================
// 引擎命令测试
// ================================================================================================
TEST_F(FrontendEngineIntegrationTest, EngineCommands) {
// 等待引擎连接
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 重置事件计数
frontend_listener_->reset_counters();
// 发送暂停命令
engine_server_->expect_command(EngineCommand::Pause, "", common::ErrorCode::Success, "{}");
EXPECT_EQ(frontend_manager_->send_engine_command(EngineCommand::Pause), common::ErrorCode::Success);
// 模拟引擎状态变为Paused
EngineStatus paused_status;
paused_status.state = EngineState::Paused;
paused_status.config.sample_rate = DEFAULT_SAMPLE_RATE;
paused_status.config.channels = DEFAULT_CHANNELS;
engine_server_->send_status_update(paused_status);
// 等待引擎状态更新
EXPECT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Paused));
// 发送恢复命令
engine_server_->expect_command(EngineCommand::Resume, "", common::ErrorCode::Success, "{}");
EXPECT_EQ(frontend_manager_->send_engine_command(EngineCommand::Resume), common::ErrorCode::Success);
// 模拟引擎状态变为Running
EngineStatus running_status;
running_status.state = EngineState::Running;
running_status.config.sample_rate = DEFAULT_SAMPLE_RATE;
running_status.config.channels = DEFAULT_CHANNELS;
engine_server_->send_status_update(running_status);
// 等待引擎状态更新
EXPECT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 验证状态变更次数
EXPECT_EQ(frontend_listener_->engine_status_changes(), 2);
}
// ================================================================================================
// 音频数据传输测试
// ================================================================================================
TEST_F(FrontendEngineIntegrationTest, AudioDataTransfer) {
// 等待引擎连接
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 创建测试音频缓冲区
auto test_buffer = create_test_audio_buffer(1024, 2, engine::AudioFormat::FLOAT32, true);
// 发送音频数据到引擎
EXPECT_EQ(frontend_manager_->send_audio_data(test_buffer), common::ErrorCode::Success);
// 验证引擎服务器是否收到数据
EXPECT_TRUE(engine_server_->wait_for_audio_data(1, 2s));
EXPECT_EQ(engine_server_->received_audio_buffer_count(), 1);
// 验证接收到的数据
const auto& received_buffer = engine_server_->last_received_audio_buffer();
EXPECT_EQ(received_buffer.num_frames(), test_buffer.num_frames());
EXPECT_EQ(received_buffer.num_channels(), test_buffer.num_channels());
EXPECT_EQ(received_buffer.format(), test_buffer.format());
// 模拟引擎发送处理后的音频数据
engine::AudioBuffer processed_buffer = test_buffer;
// 应用一些处理 - 例如增益
float gain = 0.8f;
float* data = processed_buffer.interleaved_data<float>();
for (size_t i = 0; i < processed_buffer.num_frames() * processed_buffer.num_channels(); ++i) {
data[i] *= gain;
}
// 发送处理后的数据
engine_server_->send_audio_data(processed_buffer);
// 等待前端接收音频数据
std::this_thread::sleep_for(100ms);
// 从前端读取处理后的数据
engine::AudioBuffer output_buffer(1024, 2, engine::AudioFormat::FLOAT32);
EXPECT_EQ(frontend_manager_->receive_audio_data(output_buffer, 100ms), common::ErrorCode::Success);
// 验证处理后的数据
EXPECT_EQ(output_buffer.num_frames(), processed_buffer.num_frames());
EXPECT_EQ(output_buffer.num_channels(), processed_buffer.num_channels());
EXPECT_EQ(output_buffer.format(), processed_buffer.format());
// 抽查几个样本点
const float* output_data = output_buffer.interleaved_data<float>();
const float* processed_data = processed_buffer.interleaved_data<float>();
for (size_t i = 0; i < output_buffer.num_frames() * output_buffer.num_channels(); i += 100) {
EXPECT_NEAR(output_data[i], processed_data[i], 0.0001f);
}
}
// ================================================================================================
// 设备检测测试
// ================================================================================================
TEST_F(FrontendEngineIntegrationTest, DeviceDetection) {
// 等待引擎连接
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 重置事件计数
frontend_listener_->reset_counters();
// 创建测试设备信息
AudioDeviceInfo test_device;
test_device.id = "test-device-1";
test_device.name = "测试音频设备";
test_device.type = DeviceType::Duplex;
test_device.driver = DeviceDriver::WASAPI;
test_device.state = DeviceState::Available;
test_device.is_default_input = true;
test_device.is_default_output = true;
test_device.current_sample_rate = DEFAULT_SAMPLE_RATE;
test_device.current_channels = DEFAULT_CHANNELS;
test_device.current_format = engine::AudioFormat::FLOAT32;
// 模拟设备管理器发现设备
frontend_manager_->notify_device_added(test_device);
// 等待设备状态变更事件
EXPECT_TRUE(frontend_listener_->wait_for_event("设备状态变更"));
// 验证设备事件
EXPECT_EQ(frontend_listener_->device_status_changes(), 1);
EXPECT_EQ(frontend_listener_->last_device_info().id, test_device.id);
EXPECT_EQ(frontend_listener_->last_device_info().name, test_device.name);
// 获取设备列表
auto devices = frontend_manager_->get_all_devices();
EXPECT_GE(devices.size(), 1);
// 查找测试设备
bool found = false;
for (const auto& device : devices) {
if (device.id == test_device.id) {
found = true;
break;
}
}
EXPECT_TRUE(found);
}
// ================================================================================================
// 会话管理测试
// ================================================================================================
TEST_F(FrontendEngineIntegrationTest, SessionManagement) {
// 等待引擎连接
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 重置事件计数
frontend_listener_->reset_counters();
// 创建测试会话
SessionInfo test_session = create_test_session();
// 模拟创建会话
frontend_manager_->notify_session_created(test_session);
// 等待会话创建事件
EXPECT_TRUE(frontend_listener_->wait_for_event("会话创建"));
// 验证会话事件
EXPECT_EQ(frontend_listener_->sessions_created(), 1);
EXPECT_EQ(frontend_listener_->last_session_info().id, test_session.id);
EXPECT_EQ(frontend_listener_->last_session_info().name, test_session.name);
// 模拟关闭会话
frontend_manager_->notify_session_closed(test_session.id);
// 等待会话关闭事件
EXPECT_TRUE(frontend_listener_->wait_for_event("会话关闭"));
// 验证会话关闭事件
EXPECT_EQ(frontend_listener_->sessions_closed(), 1);
EXPECT_EQ(frontend_listener_->last_closed_session_id(), test_session.id);
}
// ================================================================================================
// 错误处理测试
// ================================================================================================
TEST_F(FrontendEngineIntegrationTest, ErrorHandling) {
// 等待引擎连接
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 重置事件计数
frontend_listener_->reset_counters();
// 模拟错误
frontend_manager_->notify_error_occurred(
FrontendErrorType::EngineError,
"引擎命令执行失败"
);
// 等待错误事件
EXPECT_TRUE(frontend_listener_->wait_for_event("错误发生"));
// 验证错误事件
EXPECT_EQ(frontend_listener_->errors(), 1);
EXPECT_EQ(frontend_listener_->last_error_type(), FrontendErrorType::EngineError);
EXPECT_EQ(frontend_listener_->last_error_message(), "引擎命令执行失败");
// 模拟引擎发送错误状态
EngineStatus error_status;
error_status.state = EngineState::Error;
error_status.config.sample_rate = DEFAULT_SAMPLE_RATE;
error_status.config.channels = DEFAULT_CHANNELS;
engine_server_->send_status_update(error_status);
// 等待引擎错误状态
EXPECT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Error));
}
// ================================================================================================
// 断线重连测试
// ================================================================================================
TEST_F(FrontendEngineIntegrationTest, ConnectionResilience) {
// 等待引擎连接
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 重置事件计数
frontend_listener_->reset_counters();
// 模拟引擎服务器断开连接
engine_server_->stop();
// 等待引擎状态变为Unknown断开连接
EXPECT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Unknown));
// 模拟引擎服务器重新启动
engine_server_->start();
// 等待重新连接状态变为Running
EXPECT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
// 验证状态变更
EXPECT_GE(frontend_listener_->engine_status_changes(), 2);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}