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

607 lines
23 KiB
C++

// ================================================================================================
// Audio Backend - 系统端到端测试
// ================================================================================================
// 描述: 系统级别的端到端集成测试,测试完整音频处理流程
// ================================================================================================
#include "fixtures/integration_test_fixtures.h"
#include "fixtures/test_engine_server.h"
#include "fixtures/test_frontend.h"
#include "fixtures/test_plugin_host.h"
#include "frontend/manager/frontend_manager.h"
#include "plugin_host/manager/plugin_host_manager.h"
#include "frontend/device/device_manager.h"
#include <thread>
#include <chrono>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <fstream>
#include <filesystem>
using namespace audio_backend;
using namespace audio_backend::test;
using namespace audio_backend::frontend;
using namespace audio_backend::plugin_host;
using namespace std::chrono_literals;
// 系统端到端测试类
class SystemE2EIntegrationTest : public SystemE2ETest {
protected:
void initialize_test_system() override {
// 确保测试目录存在
std::filesystem::create_directories(TEST_TEMP_DIR);
std::filesystem::create_directories(TEST_PLUGINS_DIR);
// 创建系统配置文件
create_system_config_file();
// 初始化引擎服务器
initialize_engine_server();
// 初始化插件宿主
initialize_plugin_host();
// 初始化设备管理器
initialize_device_manager();
// 初始化前端管理器
initialize_frontend_manager();
// 连接各组件
connect_system_components();
// 准备测试资源
prepare_test_resources();
// 等待系统就绪
wait_for_system_ready();
}
void shutdown_test_system() override {
// 关闭前端管理器
if (frontend_manager_) {
frontend_manager_->shutdown();
}
// 关闭设备管理器
if (device_manager_) {
device_manager_->shutdown();
}
// 关闭插件宿主
if (plugin_manager_) {
plugin_manager_->shutdown();
}
// 关闭引擎服务器
if (engine_server_) {
engine_server_->stop();
engine_server_->shutdown();
}
// 清理测试资源
cleanup_test_resources();
}
// 创建系统配置文件
void create_system_config_file() {
// 确保配置目录存在
std::filesystem::create_directories(TEST_CONFIG_DIR);
// 创建一个简单的配置文件
std::ofstream config_file(system_config_path_);
config_file << "{\n";
config_file << " \"sample_rate\": 48000,\n";
config_file << " \"channels\": 2,\n";
config_file << " \"buffer_size\": 512,\n";
config_file << " \"enable_simd\": true,\n";
config_file << " \"plugin_paths\": [\"" << TEST_PLUGINS_DIR << "\"],\n";
config_file << " \"log_level\": \"debug\",\n";
config_file << " \"engine_endpoint\": \"tcp://127.0.0.1:5557\",\n";
config_file << " \"enable_auto_reconnect\": true\n";
config_file << "}\n";
config_file.close();
}
// 初始化引擎服务器
void initialize_engine_server() {
// 创建引擎服务器
engine_server_ = std::make_unique<TestEngineServer>("tcp://127.0.0.1:5557");
ASSERT_NE(engine_server_, nullptr);
// 配置引擎服务器
engine_server_->set_sample_rate(DEFAULT_SAMPLE_RATE);
engine_server_->set_channels(DEFAULT_CHANNELS);
engine_server_->set_buffer_size(DEFAULT_BUFFER_SIZE);
// 初始化引擎服务器
ASSERT_TRUE(engine_server_->initialize());
// 启动引擎服务器
ASSERT_TRUE(engine_server_->start());
}
// 初始化插件宿主
void initialize_plugin_host() {
// 创建插件宿主配置
PluginHostConfig host_config;
host_config.default_sample_rate = DEFAULT_SAMPLE_RATE;
host_config.default_block_size = DEFAULT_BUFFER_SIZE;
host_config.enable_sandbox = true;
host_config.plugin_search_paths = {TEST_PLUGINS_DIR};
host_config.cache_loaded_plugins = true;
// 创建插件宿主管理器
plugin_manager_ = std::make_unique<PluginHostManager>();
ASSERT_NE(plugin_manager_, nullptr);
// 初始化插件宿主管理器
ASSERT_EQ(plugin_manager_->initialize(host_config), common::ErrorCode::Success);
}
// 初始化设备管理器
void initialize_device_manager() {
// 创建设备管理器配置
DeviceManagerConfig device_config;
device_config.auto_detect_devices = true;
device_config.enable_hot_plug_detection = true;
device_config.device_scan_interval_ms = 1000;
device_config.default_buffer_size = DEFAULT_BUFFER_SIZE;
// 创建设备管理器
device_manager_ = device_factory::create_device_manager(device_config);
ASSERT_NE(device_manager_, nullptr);
// 初始化设备管理器
ASSERT_EQ(device_manager_->initialize(), common::ErrorCode::Success);
}
// 初始化前端管理器
void initialize_frontend_manager() {
// 创建前端配置
FrontendConfiguration frontend_config;
// 引擎代理配置
frontend_config.engine_proxy_config.engine_endpoint = "tcp://127.0.0.1:5557";
frontend_config.engine_proxy_config.connection_timeout = 5000ms;
frontend_config.engine_proxy_config.command_timeout = 3000ms;
frontend_config.engine_proxy_config.auto_reconnect = true;
// 设备管理器配置 - 使用已有设备管理器
frontend_config.use_existing_device_manager = true;
// 创建前端管理器
frontend_manager_ = std::make_unique<FrontendManager>(frontend_config);
ASSERT_NE(frontend_manager_, nullptr);
// 创建前端事件监听器
frontend_listener_ = std::make_shared<TestFrontendListener>();
ASSERT_NE(frontend_listener_, nullptr);
// 添加事件监听器
frontend_manager_->add_event_listener(frontend_listener_);
// 设置现有设备管理器
frontend_manager_->set_device_manager(device_manager_.get());
// 初始化前端管理器
ASSERT_EQ(frontend_manager_->initialize(), common::ErrorCode::Success);
}
// 连接系统组件
void connect_system_components() {
// 在实际系统中,这里会连接各组件
// 在测试中,我们通过引用关系已经连接了组件
}
// 准备测试资源
void prepare_test_resources() {
// 创建测试音频文件
test_audio_file_ = create_test_audio_file("wav", DEFAULT_SAMPLE_RATE, DEFAULT_CHANNELS, 5.0f);
// 创建测试设备
create_test_devices();
// 模拟加载测试插件
if (std::filesystem::exists(TEST_PLUGINS_DIR + "/test_plugin.dll") ||
std::filesystem::exists(TEST_PLUGINS_DIR + "/test_plugin.so")) {
std::string plugin_path = TEST_PLUGINS_DIR + "/test_plugin.dll";
#ifdef __linux__
plugin_path = TEST_PLUGINS_DIR + "/test_plugin.so";
#elif defined(__APPLE__)
plugin_path = TEST_PLUGINS_DIR + "/test_plugin.so";
#endif
// 加载插件
PluginLoadConfig config;
config.sample_rate = DEFAULT_SAMPLE_RATE;
config.block_size = DEFAULT_BUFFER_SIZE;
plugin_manager_->load_plugin(plugin_path, test_plugin_id_, config);
}
}
// 清理测试资源
void cleanup_test_resources() {
// 卸载测试插件
if (test_plugin_id_ != 0) {
plugin_manager_->unload_plugin(test_plugin_id_);
}
// 清理测试音频文件
if (!test_audio_file_.empty() && std::filesystem::exists(test_audio_file_)) {
std::filesystem::remove(test_audio_file_);
}
}
// 创建测试设备
void create_test_devices() {
// 创建输入设备
AudioDeviceInfo input_device;
input_device.id = "test-input-1";
input_device.name = "测试输入设备";
input_device.type = DeviceType::Input;
input_device.driver = DeviceDriver::WASAPI;
input_device.state = DeviceState::Available;
input_device.is_default_input = true;
input_device.current_sample_rate = DEFAULT_SAMPLE_RATE;
input_device.current_channels = DEFAULT_CHANNELS;
input_device.current_format = engine::AudioFormat::FLOAT32;
// 创建输出设备
AudioDeviceInfo output_device;
output_device.id = "test-output-1";
output_device.name = "测试输出设备";
output_device.type = DeviceType::Output;
output_device.driver = DeviceDriver::WASAPI;
output_device.state = DeviceState::Available;
output_device.is_default_output = true;
output_device.current_sample_rate = DEFAULT_SAMPLE_RATE;
output_device.current_channels = DEFAULT_CHANNELS;
output_device.current_format = engine::AudioFormat::FLOAT32;
// 注册测试设备
device_manager_->register_test_device(input_device);
device_manager_->register_test_device(output_device);
}
// 等待系统就绪
void wait_for_system_ready() {
// 等待前端初始化完成
ASSERT_TRUE(frontend_listener_->wait_for_initialization());
// 等待引擎连接
ASSERT_TRUE(frontend_listener_->wait_for_engine_connection());
// 等待设备检测完成
ASSERT_TRUE(frontend_listener_->wait_for_device_detection());
// 系统就绪延迟
std::this_thread::sleep_for(500ms);
}
// 模拟前端事件监听器
class TestFrontendListener : public IFrontendEventListener {
public:
void on_frontend_initialized() override {
std::lock_guard<std::mutex> lock(mutex_);
initialized_ = true;
cv_.notify_all();
}
void on_frontend_shutdown() override {
std::lock_guard<std::mutex> lock(mutex_);
shutdown_ = true;
cv_.notify_all();
}
void on_engine_status_changed(const EngineStatus& status) override {
std::lock_guard<std::mutex> lock(mutex_);
last_engine_status_ = status;
if (status.state == EngineState::Running) {
engine_connected_ = true;
} else if (status.state == EngineState::Unknown || status.state == EngineState::Error) {
engine_connected_ = false;
}
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;
if (device_status_changes_ >= 2) { // 假设至少需要检测到两个设备(输入和输出)
devices_detected_ = true;
}
cv_.notify_all();
}
void on_session_created(const SessionInfo& session) override {
std::lock_guard<std::mutex> lock(mutex_);
sessions_[session.id] = session;
cv_.notify_all();
}
void on_session_closed(const std::string& session_id) override {
std::lock_guard<std::mutex> lock(mutex_);
sessions_.erase(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_.push_back({error_type, message});
cv_.notify_all();
}
void on_log_message(LogLevel level, const std::string& message) override {
// 不需要同步,只记录日志
}
// 等待初始化完成
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 wait_for_engine_connection(std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this] { return engine_connected_; });
}
// 等待设备检测
bool wait_for_device_detection(std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this] { return devices_detected_; });
}
// 等待会话创建
bool wait_for_session(const std::string& session_id, std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this, &session_id] {
return sessions_.count(session_id) > 0;
});
}
// 等待特定引擎状态
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 is_initialized() const { return initialized_; }
bool is_engine_connected() const { return engine_connected_; }
bool are_devices_detected() const { return devices_detected_; }
size_t session_count() const { return sessions_.size(); }
size_t error_count() const { return errors_.size(); }
const EngineStatus& last_engine_status() const { return last_engine_status_; }
private:
std::mutex mutex_;
std::condition_variable cv_;
bool initialized_ = false;
bool shutdown_ = false;
bool engine_connected_ = false;
bool devices_detected_ = false;
EngineStatus last_engine_status_;
AudioDeviceInfo last_device_info_;
int device_status_changes_ = 0;
std::map<std::string, SessionInfo> sessions_;
std::vector<std::pair<FrontendErrorType, std::string>> errors_;
};
protected:
std::shared_ptr<TestFrontendListener> frontend_listener_;
PluginInstanceId test_plugin_id_ = 0;
std::string test_audio_file_;
};
// ================================================================================================
// 基本系统集成测试
// ================================================================================================
TEST_F(SystemE2EIntegrationTest, BasicSystemIntegration) {
// 验证系统各组件已初始化
ASSERT_TRUE(engine_server_->is_running());
ASSERT_TRUE(plugin_manager_->is_initialized());
ASSERT_TRUE(device_manager_->is_initialized());
ASSERT_TRUE(frontend_manager_->is_initialized());
ASSERT_TRUE(frontend_listener_->is_initialized());
ASSERT_TRUE(frontend_listener_->is_engine_connected());
ASSERT_TRUE(frontend_listener_->are_devices_detected());
// 获取设备列表
auto devices = device_manager_->get_all_devices();
EXPECT_GE(devices.size(), 2); // 至少应有输入和输出设备
// 验证引擎状态
EXPECT_EQ(frontend_listener_->last_engine_status().state, EngineState::Running);
}
// ================================================================================================
// 音频流程测试
// ================================================================================================
TEST_F(SystemE2EIntegrationTest, AudioProcessingFlow) {
// 配置输入设备
DeviceConfiguration input_config;
input_config.device_id = "test-input-1";
input_config.sample_rate = DEFAULT_SAMPLE_RATE;
input_config.channels = DEFAULT_CHANNELS;
input_config.format = engine::AudioFormat::FLOAT32;
input_config.buffer_size = DEFAULT_BUFFER_SIZE;
ASSERT_EQ(device_manager_->configure_device(input_config), common::ErrorCode::Success);
// 配置输出设备
DeviceConfiguration output_config;
output_config.device_id = "test-output-1";
output_config.sample_rate = DEFAULT_SAMPLE_RATE;
output_config.channels = DEFAULT_CHANNELS;
output_config.format = engine::AudioFormat::FLOAT32;
output_config.buffer_size = DEFAULT_BUFFER_SIZE;
ASSERT_EQ(device_manager_->configure_device(output_config), common::ErrorCode::Success);
// 启动输入流
ASSERT_EQ(device_manager_->start_input_stream(input_config.device_id), common::ErrorCode::Success);
// 启动输出流
ASSERT_EQ(device_manager_->start_output_stream(output_config.device_id), common::ErrorCode::Success);
// 如果测试插件已加载,则激活它
if (test_plugin_id_ != 0) {
ASSERT_EQ(plugin_manager_->activate_plugin(test_plugin_id_), common::ErrorCode::Success);
}
// 创建测试音频缓冲区
auto input_buffer = create_test_audio_buffer(DEFAULT_BUFFER_SIZE, DEFAULT_CHANNELS, engine::AudioFormat::FLOAT32, true);
// 模拟音频输入
device_manager_->simulate_audio_input(input_config.device_id, input_buffer);
// 验证引擎服务器收到了音频数据
EXPECT_TRUE(engine_server_->wait_for_audio_data(1, 2s));
// 引擎发送处理后的音频数据
engine::AudioBuffer processed_buffer = input_buffer;
// 模拟一些处理 - 例如增益
float gain = 0.7f;
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);
// 验证设备管理器接收到输出数据
EXPECT_TRUE(device_manager_->has_output_data(output_config.device_id));
// 停止音频流
ASSERT_EQ(device_manager_->stop_input_stream(input_config.device_id), common::ErrorCode::Success);
ASSERT_EQ(device_manager_->stop_output_stream(output_config.device_id), common::ErrorCode::Success);
// 如果测试插件已激活,则停用它
if (test_plugin_id_ != 0) {
ASSERT_EQ(plugin_manager_->deactivate_plugin(test_plugin_id_), common::ErrorCode::Success);
}
}
// ================================================================================================
// 会话创建和音频路由测试
// ================================================================================================
TEST_F(SystemE2EIntegrationTest, SessionCreationAndRouting) {
// 创建会话
SessionInfo session;
session.id = "test-session-1";
session.name = "测试会话";
session.status = SessionStatus::Active;
session.input_device_id = "test-input-1";
session.output_device_id = "test-output-1";
session.sample_rate = DEFAULT_SAMPLE_RATE;
session.channels = DEFAULT_CHANNELS;
session.format = engine::AudioFormat::FLOAT32;
// 创建会话
ASSERT_EQ(frontend_manager_->create_session(session), common::ErrorCode::Success);
// 等待会话创建事件
ASSERT_TRUE(frontend_listener_->wait_for_session(session.id));
// 配置会话设备
ASSERT_EQ(frontend_manager_->set_session_devices(
session.id, session.input_device_id, session.output_device_id),
common::ErrorCode::Success);
// 启动会话
ASSERT_EQ(frontend_manager_->start_session(session.id), common::ErrorCode::Success);
// 创建测试音频缓冲区
auto input_buffer = create_test_audio_buffer(DEFAULT_BUFFER_SIZE, DEFAULT_CHANNELS, engine::AudioFormat::FLOAT32, true);
// 发送音频数据到会话
ASSERT_EQ(frontend_manager_->send_audio_to_session(session.id, input_buffer), common::ErrorCode::Success);
// 验证引擎服务器收到了音频数据
EXPECT_TRUE(engine_server_->wait_for_audio_data(1, 2s));
// 模拟处理返回
engine::AudioBuffer processed_buffer = input_buffer;
engine_server_->send_audio_data(processed_buffer);
// 等待处理
std::this_thread::sleep_for(100ms);
// 停止会话
ASSERT_EQ(frontend_manager_->stop_session(session.id), common::ErrorCode::Success);
// 关闭会话
ASSERT_EQ(frontend_manager_->close_session(session.id), common::ErrorCode::Success);
}
// ================================================================================================
// 系统状态变更测试
// ================================================================================================
TEST_F(SystemE2EIntegrationTest, SystemStateChanges) {
// 测试停止引擎
engine_server_->expect_command(EngineCommand::Stop, "", common::ErrorCode::Success, "{}");
ASSERT_EQ(frontend_manager_->send_engine_command(EngineCommand::Stop), common::ErrorCode::Success);
// 模拟引擎状态变为Stopped
EngineStatus stopped_status;
stopped_status.state = EngineState::Stopped;
engine_server_->send_status_update(stopped_status);
// 等待引擎状态更新
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Stopped));
// 测试启动引擎
engine_server_->expect_command(EngineCommand::Start, "", common::ErrorCode::Success, "{}");
ASSERT_EQ(frontend_manager_->send_engine_command(EngineCommand::Start), common::ErrorCode::Success);
// 模拟引擎状态变为Running
EngineStatus running_status;
running_status.state = EngineState::Running;
engine_server_->send_status_update(running_status);
// 等待引擎状态更新
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
}
// ================================================================================================
// 系统错误恢复测试
// ================================================================================================
TEST_F(SystemE2EIntegrationTest, SystemErrorRecovery) {
// 模拟引擎错误
EngineStatus error_status;
error_status.state = EngineState::Error;
engine_server_->send_status_update(error_status);
// 等待引擎状态更新
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Error));
// 重启引擎
engine_server_->restart();
// 模拟引擎状态恢复
EngineStatus recovered_status;
recovered_status.state = EngineState::Running;
engine_server_->send_status_update(recovered_status);
// 等待引擎状态更新
ASSERT_TRUE(frontend_listener_->wait_for_engine_state(EngineState::Running));
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}