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