// ================================================================================================ // Audio Backend - 沙盒事件测试 // ================================================================================================ #include #include #include "plugin_host/sandbox/sandbox_interface.h" #include "tests/common/test_fixtures.h" #include #include #include using namespace audio_backend; using namespace audio_backend::plugin_host; using namespace std::chrono_literals; // 创建测试用的完整事件回调实现 class TestSandboxEventCallback : public ISandboxEventCallback { public: TestSandboxEventCallback() = default; ~TestSandboxEventCallback() override = default; // 实现回调接口 void on_process_started(ProcessId pid, const std::string& process_name) override { process_started_called_ = true; last_process_id_ = pid; last_process_name_ = process_name; } void on_process_exited(ProcessId pid, int exit_code) override { process_exited_called_ = true; last_process_id_ = pid; last_exit_code_ = exit_code; } void on_process_crashed(ProcessId pid, const std::string& reason) override { process_crashed_called_ = true; last_process_id_ = pid; last_crash_reason_ = reason; } void on_resource_limit_exceeded(ProcessId pid, const std::string& resource_name) override { resource_limit_exceeded_called_ = true; last_process_id_ = pid; last_resource_name_ = resource_name; } void on_security_violation(ProcessId pid, const std::string& violation_type) override { security_violation_called_ = true; last_process_id_ = pid; last_violation_type_ = violation_type; } void on_heartbeat_timeout(ProcessId pid) override { heartbeat_timeout_called_ = true; last_process_id_ = pid; } void on_performance_warning(ProcessId pid, const std::string& warning) override { performance_warning_called_ = true; last_process_id_ = pid; last_warning_ = warning; } // 重置状态 void reset() { process_started_called_ = false; process_exited_called_ = false; process_crashed_called_ = false; resource_limit_exceeded_called_ = false; security_violation_called_ = false; heartbeat_timeout_called_ = false; performance_warning_called_ = false; last_process_id_ = 0; last_process_name_ = ""; last_exit_code_ = 0; last_crash_reason_ = ""; last_resource_name_ = ""; last_violation_type_ = ""; last_warning_ = ""; } // 状态标志 bool process_started_called_ = false; bool process_exited_called_ = false; bool process_crashed_called_ = false; bool resource_limit_exceeded_called_ = false; bool security_violation_called_ = false; bool heartbeat_timeout_called_ = false; bool performance_warning_called_ = false; // 最后事件的详细信息 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 EventTestingSandbox : public SandboxBase { public: explicit EventTestingSandbox() : SandboxBase(SandboxType::ProcessLevelIsolation) {} ~EventTestingSandbox() override = default; // 模拟方法实现 common::ErrorCode do_initialize() override { return common::ErrorCode::Success; } common::ErrorCode do_shutdown() override { return common::ErrorCode::Success; } common::ErrorCode do_start_process( const std::string& executable_path, const std::vector& arguments, ProcessId& out_process_id) override { out_process_id = next_pid_++; register_process(out_process_id, executable_path); notify_process_started(out_process_id, executable_path); return common::ErrorCode::Success; } common::ErrorCode do_stop_process(ProcessId process_id, bool force) override { auto* process_info = find_process_info(process_id); if (process_info) { notify_process_exited(process_id, 0); unregister_process(process_id); return common::ErrorCode::Success; } return common::ErrorCode::InvalidArgument; } // 接口方法实现 common::ErrorCode start_process( const std::string& executable_path, const std::vector& arguments, ProcessId& out_process_id) override { return SandboxBase::start_process(executable_path, arguments, out_process_id); } common::ErrorCode suspend_process(ProcessId process_id) override { return common::ErrorCode::Success; } common::ErrorCode resume_process(ProcessId process_id) override { return common::ErrorCode::Success; } common::ErrorCode restart_process(ProcessId process_id) override { return common::ErrorCode::Success; } common::ErrorCode wait_for_process( ProcessId process_id, std::chrono::milliseconds timeout, int& exit_code) override { exit_code = 0; return common::ErrorCode::Success; } common::ErrorCode set_resource_limits( ProcessId process_id, const ResourceLimits& limits) override { auto* process_info = find_process_info(process_id); if (process_info) { resource_limits_[process_id] = limits; return common::ErrorCode::Success; } return common::ErrorCode::InvalidArgument; } common::ErrorCode get_resource_usage( ProcessId process_id, PerformanceMetrics& metrics) override { auto* process_info = find_process_info(process_id); if (process_info) { metrics = process_info->metrics; return common::ErrorCode::Success; } return common::ErrorCode::InvalidArgument; } common::ErrorCode enforce_resource_limits(ProcessId process_id) override { auto* process_info = find_process_info(process_id); if (process_info) { auto it = resource_limits_.find(process_id); if (it != resource_limits_.end()) { // 模拟超出内存限制 if (memory_limit_exceeded_) { notify_resource_limit_exceeded(process_id, "Memory"); } return common::ErrorCode::Success; } } return common::ErrorCode::InvalidArgument; } common::ErrorCode apply_security_settings( ProcessId process_id, const SecuritySettings& settings) override { auto* process_info = find_process_info(process_id); if (process_info) { security_settings_[process_id] = settings; return common::ErrorCode::Success; } return common::ErrorCode::InvalidArgument; } bool is_path_accessible( ProcessId process_id, const std::string& path) const override { auto* process_info = find_process_info(process_id); if (process_info) { auto it = security_settings_.find(process_id); if (it != security_settings_.end() && !it->second.allow_file_access) { notify_security_violation(process_id, "FileAccess"); return false; } return true; } return false; } bool is_network_accessible(ProcessId process_id) const override { auto* process_info = find_process_info(process_id); if (process_info) { auto it = security_settings_.find(process_id); if (it != security_settings_.end() && !it->second.allow_network_access) { notify_security_violation(process_id, "NetworkAccess"); return false; } return true; } return false; } common::ErrorCode execute_platform_specific_operation( const std::string& operation_name, const std::vector& parameters, std::string& result) override { return common::ErrorCode::Success; } // 模拟触发事件的方法 void simulate_process_crash(ProcessId process_id, const std::string& reason) { auto* process_info = find_process_info(process_id); if (process_info) { process_info->crash_count++; process_info->last_crash_reason = reason; process_info->last_crash_time = std::chrono::steady_clock::now(); notify_process_crashed(process_id, reason); } } void simulate_resource_limit_exceeded(ProcessId process_id, const std::string& resource) { auto* process_info = find_process_info(process_id); if (process_info) { notify_resource_limit_exceeded(process_id, resource); } } void simulate_security_violation(ProcessId process_id, const std::string& violation) { auto* process_info = find_process_info(process_id); if (process_info) { notify_security_violation(process_id, violation); } } void simulate_heartbeat_timeout(ProcessId process_id) { auto* process_info = find_process_info(process_id); if (process_info) { process_info->is_responsive = false; notify_heartbeat_timeout(process_id); } } void simulate_performance_warning(ProcessId process_id, const std::string& warning) { auto* process_info = find_process_info(process_id); if (process_info) { notify_performance_warning(process_id, warning); } } // 设置内存超限标志 void set_memory_limit_exceeded(bool value) { memory_limit_exceeded_ = value; } // 访问统计信息 const Statistics& get_stats() const { return stats_; } private: std::atomic next_pid_{1000}; std::map resource_limits_; std::map security_settings_; std::atomic memory_limit_exceeded_{false}; }; // 沙盒事件测试固定装置 class SandboxEventTest : public test::PluginSandboxTest { protected: void SetUp() override { test::PluginSandboxTest::SetUp(); // 创建沙盒 sandbox_ = std::make_unique(); // 创建事件回调 callback_ = std::make_shared(); // 初始化沙盒 SandboxConfig config; config.sandbox_type = SandboxType::ProcessLevelIsolation; config.process_creation_timeout = 5000; config.enable_heartbeat = true; config.heartbeat_interval_ms = 1000; config.heartbeat_timeout_ms = 5000; config.enable_resource_monitoring = true; config.resource_monitoring_interval_ms = 1000; ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success); } void TearDown() override { if (sandbox_->is_initialized()) { sandbox_->shutdown(); } sandbox_.reset(); callback_.reset(); test::PluginSandboxTest::TearDown(); } protected: std::unique_ptr sandbox_; std::shared_ptr callback_; }; // 测试进程事件 TEST_F(SandboxEventTest, ProcessLifecycleEvents) { // 设置事件回调 sandbox_->set_event_callback(callback_); // 启动进程 ProcessId pid = 0; auto result = sandbox_->start_process("test.exe", {"-arg1", "-arg2"}, pid); // 验证进程启动事件 ASSERT_EQ(result, common::ErrorCode::Success); EXPECT_TRUE(callback_->process_started_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_process_name_, "test.exe"); // 重置回调状态 callback_->reset(); // 停止进程 result = sandbox_->stop_process(pid); // 验证进程退出事件 ASSERT_EQ(result, common::ErrorCode::Success); EXPECT_TRUE(callback_->process_exited_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_exit_code_, 0); } // 测试进程崩溃事件 TEST_F(SandboxEventTest, ProcessCrashEvent) { // 设置事件回调 sandbox_->set_event_callback(callback_); // 启动进程 ProcessId pid = 0; sandbox_->start_process("test.exe", {}, pid); // 重置回调状态 callback_->reset(); // 模拟进程崩溃 sandbox_->simulate_process_crash(pid, "段错误"); // 验证崩溃事件 EXPECT_TRUE(callback_->process_crashed_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_crash_reason_, "段错误"); // 检查进程信息 auto process_info = sandbox_->get_process_info(pid); EXPECT_EQ(process_info.crash_count, 1); EXPECT_EQ(process_info.last_crash_reason, "段错误"); EXPECT_NE(process_info.last_crash_time, Timestamp()); // 检查统计信息 const auto& stats = sandbox_->get_stats(); EXPECT_EQ(stats.total_crashes.load(), 1); } // 测试资源限制事件 TEST_F(SandboxEventTest, ResourceLimitEvents) { // 设置事件回调 sandbox_->set_event_callback(callback_); // 启动进程 ProcessId pid = 0; sandbox_->start_process("test.exe", {}, pid); // 设置资源限制 ResourceLimits limits; limits.max_memory_mb = 100; limits.max_cpu_percent = 50.0; sandbox_->set_resource_limits(pid, limits); // 重置回调状态 callback_->reset(); // 方法1:直接模拟资源超限事件 sandbox_->simulate_resource_limit_exceeded(pid, "CPU"); // 验证资源超限事件 EXPECT_TRUE(callback_->resource_limit_exceeded_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_resource_name_, "CPU"); // 重置回调状态 callback_->reset(); // 方法2:通过强制执行资源限制触发事件 sandbox_->set_memory_limit_exceeded(true); sandbox_->enforce_resource_limits(pid); // 验证通过enforce触发的事件 EXPECT_TRUE(callback_->resource_limit_exceeded_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_resource_name_, "Memory"); // 检查统计信息 const auto& stats = sandbox_->get_stats(); EXPECT_EQ(stats.total_resource_violations.load(), 2); } // 测试安全违规事件 TEST_F(SandboxEventTest, SecurityViolationEvents) { // 设置事件回调 sandbox_->set_event_callback(callback_); // 启动进程 ProcessId pid = 0; sandbox_->start_process("test.exe", {}, pid); // 设置安全设置 - 禁用文件访问 SecuritySettings settings; settings.allow_file_access = false; settings.allow_network_access = true; sandbox_->apply_security_settings(pid, settings); // 重置回调状态 callback_->reset(); // 方法1:直接模拟安全违规事件 sandbox_->simulate_security_violation(pid, "Registry"); // 验证安全违规事件 EXPECT_TRUE(callback_->security_violation_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_violation_type_, "Registry"); // 重置回调状态 callback_->reset(); // 方法2:通过路径访问检查触发事件 bool is_accessible = sandbox_->is_path_accessible(pid, "/restricted/path"); // 验证通过访问检查触发的事件 EXPECT_FALSE(is_accessible); EXPECT_TRUE(callback_->security_violation_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_violation_type_, "FileAccess"); // 检查统计信息 const auto& stats = sandbox_->get_stats(); EXPECT_EQ(stats.total_security_violations.load(), 2); } // 测试心跳超时事件 TEST_F(SandboxEventTest, HeartbeatTimeoutEvent) { // 设置事件回调 sandbox_->set_event_callback(callback_); // 启动进程 ProcessId pid = 0; sandbox_->start_process("test.exe", {}, pid); // 重置回调状态 callback_->reset(); // 模拟心跳超时 sandbox_->simulate_heartbeat_timeout(pid); // 验证心跳超时事件 EXPECT_TRUE(callback_->heartbeat_timeout_called_); EXPECT_EQ(callback_->last_process_id_, pid); // 检查进程信息 auto process_info = sandbox_->get_process_info(pid); EXPECT_FALSE(process_info.is_responsive); // 检查统计信息 const auto& stats = sandbox_->get_stats(); EXPECT_EQ(stats.total_heartbeat_timeouts.load(), 1); } // 测试性能警告事件 TEST_F(SandboxEventTest, PerformanceWarningEvent) { // 设置事件回调 sandbox_->set_event_callback(callback_); // 启动进程 ProcessId pid = 0; sandbox_->start_process("test.exe", {}, pid); // 重置回调状态 callback_->reset(); // 模拟性能警告 sandbox_->simulate_performance_warning(pid, "高CPU占用"); // 验证性能警告事件 EXPECT_TRUE(callback_->performance_warning_called_); EXPECT_EQ(callback_->last_process_id_, pid); EXPECT_EQ(callback_->last_warning_, "高CPU占用"); } // 测试多进程事件处理 TEST_F(SandboxEventTest, MultiProcessEventHandling) { // 设置事件回调 sandbox_->set_event_callback(callback_); // 启动多个进程 ProcessId pid1 = 0, pid2 = 0, pid3 = 0; sandbox_->start_process("process1.exe", {}, pid1); sandbox_->start_process("process2.exe", {}, pid2); sandbox_->start_process("process3.exe", {}, pid3); // 重置回调状态 callback_->reset(); // 模拟不同进程的不同事件 sandbox_->simulate_process_crash(pid1, "段错误"); sandbox_->simulate_resource_limit_exceeded(pid2, "Memory"); sandbox_->simulate_security_violation(pid3, "NetworkAccess"); // 验证统计信息 const auto& stats = sandbox_->get_stats(); EXPECT_EQ(stats.total_crashes.load(), 1); EXPECT_EQ(stats.total_resource_violations.load(), 1); EXPECT_EQ(stats.total_security_violations.load(), 1); } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }