// ================================================================================================ // 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 #include #include #include #include #include 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 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 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 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 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 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 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 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 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 bool wait_for_count(CountGetter count_getter, size_t target_count, std::chrono::milliseconds timeout = 5s) { std::unique_lock 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 lock(mutex_); events_.clear(); } // 重置所有计数器 void reset_counters() { std::lock_guard 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 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(); 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(); 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 sandbox_; std::shared_ptr 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(); }