557 lines
21 KiB
C++
557 lines
21 KiB
C++
// ================================================================================================
|
||
// 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();
|
||
} |