This commit is contained in:
2025-10-28 10:27:49 +08:00
parent c98e7e61b3
commit 2003c5992f
122 changed files with 46814 additions and 249 deletions

View File

@@ -0,0 +1,576 @@
// ================================================================================================
// Audio Backend - 插件沙盒集成测试
// ================================================================================================
// 描述: 测试插件沙盒系统与插件加载、运行的集成
// ================================================================================================
#include "fixtures/integration_test_fixtures.h"
#include "plugin_host/sandbox/sandbox_interface.h"
#include "plugin_host/core/plugin_interface.h"
#include "plugin_host/manager/plugin_host_manager.h"
#include <thread>
#include <chrono>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <filesystem>
using namespace audio_backend;
using namespace audio_backend::test;
using namespace audio_backend::plugin_host;
using namespace std::chrono_literals;
// 沙盒事件监听器
class TestSandboxEventListener : public ISandboxEventCallback {
public:
void on_process_started(ProcessId pid, const std::string& process_name) override {
std::lock_guard<std::mutex> lock(mutex_);
process_started_count_++;
last_process_id_ = pid;
last_process_name_ = process_name;
events_.push_back("进程启动: " + process_name + " (PID: " + std::to_string(pid) + ")");
cv_.notify_all();
}
void on_process_exited(ProcessId pid, int exit_code) override {
std::lock_guard<std::mutex> lock(mutex_);
process_exited_count_++;
last_exit_code_ = exit_code;
events_.push_back("进程退出: PID " + std::to_string(pid) +
" (退出码: " + std::to_string(exit_code) + ")");
cv_.notify_all();
}
void on_process_crashed(ProcessId pid, const std::string& reason) override {
std::lock_guard<std::mutex> lock(mutex_);
process_crashed_count_++;
last_crash_reason_ = reason;
events_.push_back("进程崩溃: PID " + std::to_string(pid) +
" (原因: " + reason + ")");
cv_.notify_all();
}
void on_resource_limit_exceeded(ProcessId pid, const std::string& resource_name) override {
std::lock_guard<std::mutex> lock(mutex_);
resource_limit_exceeded_count_++;
last_resource_name_ = resource_name;
events_.push_back("资源超限: PID " + std::to_string(pid) +
" (资源: " + resource_name + ")");
cv_.notify_all();
}
void on_security_violation(ProcessId pid, const std::string& violation_type) override {
std::lock_guard<std::mutex> lock(mutex_);
security_violation_count_++;
last_violation_type_ = violation_type;
events_.push_back("安全违规: PID " + std::to_string(pid) +
" (类型: " + violation_type + ")");
cv_.notify_all();
}
void on_heartbeat_timeout(ProcessId pid) override {
std::lock_guard<std::mutex> lock(mutex_);
heartbeat_timeout_count_++;
events_.push_back("心跳超时: PID " + std::to_string(pid));
cv_.notify_all();
}
void on_performance_warning(ProcessId pid, const std::string& warning) override {
std::lock_guard<std::mutex> lock(mutex_);
performance_warning_count_++;
last_warning_ = warning;
events_.push_back("性能警告: PID " + std::to_string(pid) +
" (警告: " + warning + ")");
cv_.notify_all();
}
// 等待特定事件发生
bool wait_for_event(const std::string& event_type,
std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this, &event_type]() {
for (const auto& event : events_) {
if (event.find(event_type) != std::string::npos) {
return true;
}
}
return false;
});
}
// 等待事件计数达到指定值
template<typename CountGetter>
bool wait_for_count(CountGetter count_getter,
size_t target_count,
std::chrono::milliseconds timeout = 5s) {
std::unique_lock<std::mutex> lock(mutex_);
return cv_.wait_for(lock, timeout, [this, &count_getter, target_count]() {
return (this->*count_getter)() >= target_count;
});
}
// 获取统计信息
size_t process_started_count() const { return process_started_count_; }
size_t process_exited_count() const { return process_exited_count_; }
size_t process_crashed_count() const { return process_crashed_count_; }
size_t resource_limit_exceeded_count() const { return resource_limit_exceeded_count_; }
size_t security_violation_count() const { return security_violation_count_; }
size_t heartbeat_timeout_count() const { return heartbeat_timeout_count_; }
size_t performance_warning_count() const { return performance_warning_count_; }
// 获取最后事件信息
ProcessId last_process_id() const { return last_process_id_; }
const std::string& last_process_name() const { return last_process_name_; }
int last_exit_code() const { return last_exit_code_; }
const std::string& last_crash_reason() const { return last_crash_reason_; }
const std::string& last_resource_name() const { return last_resource_name_; }
const std::string& last_violation_type() const { return last_violation_type_; }
const std::string& last_warning() const { return last_warning_; }
// 清除事件历史
void clear_events() {
std::lock_guard<std::mutex> lock(mutex_);
events_.clear();
}
// 重置所有计数器
void reset_counters() {
std::lock_guard<std::mutex> lock(mutex_);
process_started_count_ = 0;
process_exited_count_ = 0;
process_crashed_count_ = 0;
resource_limit_exceeded_count_ = 0;
security_violation_count_ = 0;
heartbeat_timeout_count_ = 0;
performance_warning_count_ = 0;
}
private:
std::mutex mutex_;
std::condition_variable cv_;
std::vector<std::string> events_;
// 事件计数
size_t process_started_count_ = 0;
size_t process_exited_count_ = 0;
size_t process_crashed_count_ = 0;
size_t resource_limit_exceeded_count_ = 0;
size_t security_violation_count_ = 0;
size_t heartbeat_timeout_count_ = 0;
size_t performance_warning_count_ = 0;
// 最后事件信息
ProcessId last_process_id_ = 0;
std::string last_process_name_;
int last_exit_code_ = 0;
std::string last_crash_reason_;
std::string last_resource_name_;
std::string last_violation_type_;
std::string last_warning_;
};
// 插件沙盒测试类
class PluginSandboxIntegrationTestImpl : public PluginSandboxIntegrationTest {
protected:
void initialize_sandbox() override {
// 创建沙盒配置
SandboxConfig sandbox_config;
sandbox_config.sandbox_type = SandboxType::ProcessLevelIsolation;
sandbox_config.process_creation_timeout = 5000;
sandbox_config.enable_heartbeat = true;
sandbox_config.heartbeat_interval_ms = 1000;
sandbox_config.heartbeat_timeout_ms = 5000;
sandbox_config.enable_resource_monitoring = true;
sandbox_config.resource_monitoring_interval_ms = 1000;
// 使用工厂创建平台特定沙盒
sandbox_ = SandboxFactory::create_platform_sandbox(sandbox_config);
ASSERT_NE(sandbox_, nullptr);
// 初始化沙盒
ASSERT_EQ(sandbox_->initialize(sandbox_config), common::ErrorCode::Success);
// 添加事件监听器
sandbox_event_listener_ = std::make_shared<TestSandboxEventListener>();
sandbox_->set_event_callback(sandbox_event_listener_);
// 创建插件宿主管理器配置
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 shutdown_sandbox() override {
// 关闭插件宿主管理器
if (plugin_manager_) {
plugin_manager_->shutdown();
}
// 移除事件监听器
if (sandbox_) {
sandbox_->remove_event_callback();
// 关闭沙盒
sandbox_->shutdown();
}
}
void initialize_test_plugins() override {
// 确保测试插件目录存在
std::filesystem::create_directories(TEST_PLUGINS_DIR);
// 这里可以准备测试插件文件
// 在实际测试中我们假设测试插件已经在resources目录中
}
void shutdown_test_plugins() override {
// 卸载所有已加载的插件
for (auto id : loaded_plugins_) {
plugin_manager_->unload_plugin(id);
}
loaded_plugins_.clear();
}
PluginInstanceId load_test_plugin(const std::string& plugin_path) override {
// 构建完整插件路径
std::string full_path = test_plugins_dir_ + "/" + plugin_path;
// 创建插件加载配置
PluginLoadConfig config;
config.sample_rate = DEFAULT_SAMPLE_RATE;
config.block_size = DEFAULT_BUFFER_SIZE;
config.enable_sandbox = true;
// 加载插件
PluginInstanceId instance_id;
auto result = plugin_manager_->load_plugin(full_path, instance_id, config);
// 如果加载成功记录插件ID
if (result == common::ErrorCode::Success) {
loaded_plugins_.push_back(instance_id);
}
return instance_id;
}
// 创建资源限制
ResourceLimits create_resource_limits(bool strict = false) {
ResourceLimits limits;
if (strict) {
// 严格限制
limits.max_memory_mb = 10; // 只允许10MB内存
limits.max_cpu_percent = 10.0; // 最多10%的CPU
limits.max_threads = 2; // 最多2个线程
limits.max_file_handles = 5; // 最多5个文件句柄
limits.max_execution_time_ms = 5000; // 最多执行5秒
} else {
// 宽松限制
limits.max_memory_mb = 256; // 256MB内存
limits.max_cpu_percent = 50.0; // 最多50%的CPU
limits.max_threads = 8; // 最多8个线程
limits.max_file_handles = 100; // 最多100个文件句柄
limits.max_execution_time_ms = 60000; // 最多执行60秒
}
limits.kill_on_limit = strict; // 严格模式下超限直接终止
limits.throttle_on_limit = true; // 超限时限流
return limits;
}
// 创建安全设置
SecuritySettings create_security_settings(bool restrictive = false) {
SecuritySettings settings;
// 基本权限
settings.allow_file_access = true;
settings.allow_network_access = false;
settings.allow_process_creation = false;
settings.allow_system_operations = false;
if (restrictive) {
// 限制性设置
settings.allow_file_access = false;
settings.allowed_paths.clear();
settings.denied_paths = {"/*"}; // 禁止访问所有路径
} else {
// 普通设置
settings.allowed_paths = {
TEST_TEMP_DIR, // 允许访问临时目录
TEST_RESOURCES_DIR + "/data" // 允许访问数据目录
};
settings.denied_paths = {
"/system",
"/bin",
"/etc",
"C:\\Windows"
};
}
return settings;
}
protected:
std::shared_ptr<ISandbox> sandbox_;
std::shared_ptr<TestSandboxEventListener> sandbox_event_listener_;
};
// ================================================================================================
// 沙盒基本功能测试
// ================================================================================================
TEST_F(PluginSandboxIntegrationTestImpl, SandboxBasicFunctionality) {
// 验证沙盒已初始化
ASSERT_NE(sandbox_, nullptr);
EXPECT_TRUE(sandbox_->is_initialized());
// 获取沙盒类型
SandboxType type = sandbox_->get_sandbox_type();
EXPECT_NE(type, SandboxType::Unknown);
// 获取沙盒配置
const SandboxConfig& config = sandbox_->get_config();
EXPECT_EQ(config.sandbox_type, type);
EXPECT_TRUE(config.enable_heartbeat);
EXPECT_TRUE(config.enable_resource_monitoring);
// 检查平台支持的沙盒类型
auto supported_types = SandboxFactory::get_supported_sandbox_types();
EXPECT_FALSE(supported_types.empty());
// 验证当前使用的沙盒类型受支持
EXPECT_TRUE(SandboxFactory::is_sandbox_type_supported(type));
}
// ================================================================================================
// 插件加载和卸载测试
// ================================================================================================
TEST_F(PluginSandboxIntegrationTestImpl, PluginLoadingAndUnloading) {
// 这个测试需要实际的插件文件,在测试环境中可能需要跳过
if (!std::filesystem::exists(TEST_PLUGINS_DIR + "/test_plugin.dll") &&
!std::filesystem::exists(TEST_PLUGINS_DIR + "/test_plugin.so")) {
GTEST_SKIP() << "测试插件文件不存在,跳过测试";
}
// 设置事件监听器预期
sandbox_event_listener_->reset_counters();
// 加载测试插件
std::string plugin_path = "test_plugin.dll"; // Windows上使用.dll其他平台使用.so
#ifdef __linux__
plugin_path = "test_plugin.so";
#elif defined(__APPLE__)
plugin_path = "test_plugin.so";
#endif
PluginInstanceId plugin_id = load_test_plugin(plugin_path);
// 验证插件加载成功
EXPECT_NE(plugin_id, 0);
EXPECT_TRUE(plugin_manager_->is_plugin_loaded(plugin_id));
// 等待进程启动事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("进程启动"));
EXPECT_GE(sandbox_event_listener_->process_started_count(), 1);
// 获取插件信息
PluginInstanceInfo info;
EXPECT_EQ(plugin_manager_->get_plugin_info(plugin_id, info), common::ErrorCode::Success);
// 验证插件信息
EXPECT_EQ(info.instance_id, plugin_id);
EXPECT_EQ(info.plugin_id, TEST_PLUGINS_DIR + "/" + plugin_path);
EXPECT_EQ(info.state, PluginState::Initialized);
// 激活插件
EXPECT_EQ(plugin_manager_->activate_plugin(plugin_id), common::ErrorCode::Success);
// 验证插件状态
EXPECT_EQ(plugin_manager_->get_plugin_info(plugin_id, info), common::ErrorCode::Success);
EXPECT_EQ(info.state, PluginState::Active);
// 停用插件
EXPECT_EQ(plugin_manager_->deactivate_plugin(plugin_id), common::ErrorCode::Success);
// 验证插件状态
EXPECT_EQ(plugin_manager_->get_plugin_info(plugin_id, info), common::ErrorCode::Success);
EXPECT_EQ(info.state, PluginState::Initialized);
// 卸载插件
EXPECT_EQ(plugin_manager_->unload_plugin(plugin_id), common::ErrorCode::Success);
// 等待进程退出事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("进程退出"));
EXPECT_GE(sandbox_event_listener_->process_exited_count(), 1);
// 验证插件已卸载
EXPECT_FALSE(plugin_manager_->is_plugin_loaded(plugin_id));
}
// ================================================================================================
// 资源限制测试
// ================================================================================================
TEST_F(PluginSandboxIntegrationTestImpl, ResourceLimits) {
// 这个测试需要实际的插件文件,在测试环境中可能需要跳过
if (!std::filesystem::exists(TEST_PLUGINS_DIR + "/memory_intensive_plugin.dll") &&
!std::filesystem::exists(TEST_PLUGINS_DIR + "/memory_intensive_plugin.so")) {
GTEST_SKIP() << "内存密集型测试插件文件不存在,跳过测试";
}
// 设置事件监听器预期
sandbox_event_listener_->reset_counters();
// 加载内存密集型测试插件
std::string plugin_path = "memory_intensive_plugin.dll";
#ifdef __linux__
plugin_path = "memory_intensive_plugin.so";
#elif defined(__APPLE__)
plugin_path = "memory_intensive_plugin.so";
#endif
PluginInstanceId plugin_id = load_test_plugin(plugin_path);
// 验证插件加载成功
EXPECT_NE(plugin_id, 0);
EXPECT_TRUE(plugin_manager_->is_plugin_loaded(plugin_id));
// 等待进程启动事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("进程启动"));
// 获取插件进程信息
PluginInstanceInfo info;
EXPECT_EQ(plugin_manager_->get_plugin_info(plugin_id, info), common::ErrorCode::Success);
ProcessId pid = info.process_id;
// 获取沙盒进程信息
SandboxProcessInfo process_info = sandbox_->get_process_info(pid);
EXPECT_EQ(process_info.process_id, pid);
// 设置严格的资源限制
ResourceLimits strict_limits = create_resource_limits(true);
EXPECT_EQ(sandbox_->set_resource_limits(pid, strict_limits), common::ErrorCode::Success);
// 激活插件 - 这会触发内存密集型操作
EXPECT_EQ(plugin_manager_->activate_plugin(plugin_id), common::ErrorCode::Success);
// 等待资源超限事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("资源超限"));
EXPECT_GE(sandbox_event_listener_->resource_limit_exceeded_count(), 1);
// 验证进程状态(可能已被终止或限流)
process_info = sandbox_->get_process_info(pid);
// 卸载插件
plugin_manager_->unload_plugin(plugin_id);
}
// ================================================================================================
// 安全隔离测试
// ================================================================================================
TEST_F(PluginSandboxIntegrationTestImpl, SecurityIsolation) {
// 这个测试需要实际的插件文件,在测试环境中可能需要跳过
if (!std::filesystem::exists(TEST_PLUGINS_DIR + "/security_test_plugin.dll") &&
!std::filesystem::exists(TEST_PLUGINS_DIR + "/security_test_plugin.so")) {
GTEST_SKIP() << "安全测试插件文件不存在,跳过测试";
}
// 设置事件监听器预期
sandbox_event_listener_->reset_counters();
// 加载安全测试插件
std::string plugin_path = "security_test_plugin.dll";
#ifdef __linux__
plugin_path = "security_test_plugin.so";
#elif defined(__APPLE__)
plugin_path = "security_test_plugin.so";
#endif
PluginInstanceId plugin_id = load_test_plugin(plugin_path);
// 验证插件加载成功
EXPECT_NE(plugin_id, 0);
EXPECT_TRUE(plugin_manager_->is_plugin_loaded(plugin_id));
// 等待进程启动事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("进程启动"));
// 获取插件进程信息
PluginInstanceInfo info;
EXPECT_EQ(plugin_manager_->get_plugin_info(plugin_id, info), common::ErrorCode::Success);
ProcessId pid = info.process_id;
// 应用限制性安全设置
SecuritySettings restrictive_settings = create_security_settings(true);
EXPECT_EQ(sandbox_->apply_security_settings(pid, restrictive_settings), common::ErrorCode::Success);
// 激活插件 - 这会触发安全测试操作
EXPECT_EQ(plugin_manager_->activate_plugin(plugin_id), common::ErrorCode::Success);
// 等待安全违规事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("安全违规"));
EXPECT_GE(sandbox_event_listener_->security_violation_count(), 1);
// 卸载插件
plugin_manager_->unload_plugin(plugin_id);
}
// ================================================================================================
// 崩溃恢复测试
// ================================================================================================
TEST_F(PluginSandboxIntegrationTestImpl, CrashRecovery) {
// 这个测试需要实际的插件文件,在测试环境中可能需要跳过
if (!std::filesystem::exists(TEST_PLUGINS_DIR + "/crash_plugin.dll") &&
!std::filesystem::exists(TEST_PLUGINS_DIR + "/crash_plugin.so")) {
GTEST_SKIP() << "崩溃测试插件文件不存在,跳过测试";
}
// 设置事件监听器预期
sandbox_event_listener_->reset_counters();
// 加载崩溃测试插件
std::string plugin_path = "crash_plugin.dll";
#ifdef __linux__
plugin_path = "crash_plugin.so";
#elif defined(__APPLE__)
plugin_path = "crash_plugin.so";
#endif
PluginInstanceId plugin_id = load_test_plugin(plugin_path);
// 验证插件加载成功
EXPECT_NE(plugin_id, 0);
EXPECT_TRUE(plugin_manager_->is_plugin_loaded(plugin_id));
// 等待进程启动事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("进程启动"));
// 激活插件 - 这会触发崩溃
EXPECT_EQ(plugin_manager_->activate_plugin(plugin_id), common::ErrorCode::Success);
// 等待进程崩溃事件
EXPECT_TRUE(sandbox_event_listener_->wait_for_event("进程崩溃"));
EXPECT_GE(sandbox_event_listener_->process_crashed_count(), 1);
// 验证插件状态
PluginInstanceInfo info;
EXPECT_EQ(plugin_manager_->get_plugin_info(plugin_id, info), common::ErrorCode::Success);
EXPECT_EQ(info.state, PluginState::Error);
// 卸载插件
plugin_manager_->unload_plugin(plugin_id);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}