Files
Alicho/tests/unit/plugin_host/sandbox_base_test.cpp
2025-10-28 10:27:49 +08:00

419 lines
14 KiB
C++

// ================================================================================================
// Audio Backend - 沙盒基类测试
// ================================================================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "plugin_host/sandbox/sandbox_interface.h"
#include "tests/common/test_fixtures.h"
#include <thread>
#include <chrono>
using namespace audio_backend;
using namespace audio_backend::plugin_host;
using namespace std::chrono_literals;
// 创建用于测试的模拟沙盒实现
class MockSandboxImpl : public SandboxBase {
public:
explicit MockSandboxImpl() : SandboxBase(SandboxType::ProcessLevelIsolation) {}
~MockSandboxImpl() override = default;
// 模拟方法实现
MOCK_METHOD(common::ErrorCode, do_initialize, (), (override));
MOCK_METHOD(common::ErrorCode, do_shutdown, (), (override));
MOCK_METHOD(common::ErrorCode, do_start_process,
(const std::string&, const std::vector<std::string>&, ProcessId&), (override));
MOCK_METHOD(common::ErrorCode, do_stop_process, (ProcessId, bool), (override));
// 接口方法实现
common::ErrorCode start_process(
const std::string& executable_path,
const std::vector<std::string>& 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 {
return common::ErrorCode::Success;
}
common::ErrorCode get_resource_usage(
ProcessId process_id,
PerformanceMetrics& metrics) override {
return common::ErrorCode::Success;
}
common::ErrorCode enforce_resource_limits(ProcessId process_id) override {
return common::ErrorCode::Success;
}
common::ErrorCode apply_security_settings(
ProcessId process_id,
const SecuritySettings& settings) override {
return common::ErrorCode::Success;
}
bool is_path_accessible(
ProcessId process_id,
const std::string& path) const override {
return true;
}
bool is_network_accessible(ProcessId process_id) const override {
return true;
}
common::ErrorCode execute_platform_specific_operation(
const std::string& operation_name,
const std::vector<std::string>& parameters,
std::string& result) override {
return common::ErrorCode::Success;
}
// 公开受保护方法以便测试
using SandboxBase::register_process;
using SandboxBase::unregister_process;
using SandboxBase::find_process_info;
using SandboxBase::notify_process_started;
using SandboxBase::notify_process_exited;
using SandboxBase::notify_process_crashed;
using SandboxBase::notify_resource_limit_exceeded;
using SandboxBase::notify_security_violation;
using SandboxBase::notify_heartbeat_timeout;
using SandboxBase::notify_performance_warning;
};
// 创建事件回调模拟类
class MockSandboxEventCallback : public ISandboxEventCallback {
public:
MOCK_METHOD(void, on_process_started, (ProcessId, const std::string&), (override));
MOCK_METHOD(void, on_process_exited, (ProcessId, int), (override));
MOCK_METHOD(void, on_process_crashed, (ProcessId, const std::string&), (override));
MOCK_METHOD(void, on_resource_limit_exceeded, (ProcessId, const std::string&), (override));
MOCK_METHOD(void, on_security_violation, (ProcessId, const std::string&), (override));
MOCK_METHOD(void, on_heartbeat_timeout, (ProcessId), (override));
MOCK_METHOD(void, on_performance_warning, (ProcessId, const std::string&), (override));
};
// 沙盒基类测试固定装置
class SandboxBaseTest : public test::PluginSandboxTest {
protected:
void SetUp() override {
test::PluginSandboxTest::SetUp();
// 创建模拟沙盒实现
sandbox_ = std::make_unique<::testing::NiceMock<MockSandboxImpl>>();
// 默认的成功返回
ON_CALL(*sandbox_, do_initialize())
.WillByDefault(::testing::Return(common::ErrorCode::Success));
ON_CALL(*sandbox_, do_shutdown())
.WillByDefault(::testing::Return(common::ErrorCode::Success));
ON_CALL(*sandbox_, do_start_process(::testing::_, ::testing::_, ::testing::_))
.WillByDefault([this](const std::string&, const std::vector<std::string>&, ProcessId& out_pid) {
out_pid = next_pid_++;
return common::ErrorCode::Success;
});
ON_CALL(*sandbox_, do_stop_process(::testing::_, ::testing::_))
.WillByDefault(::testing::Return(common::ErrorCode::Success));
// 创建模拟事件回调
callback_ = std::make_shared<::testing::NiceMock<MockSandboxEventCallback>>();
}
void TearDown() override {
sandbox_.reset();
callback_.reset();
test::PluginSandboxTest::TearDown();
}
// 创建基本沙盒配置
SandboxConfig create_basic_config() {
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;
return config;
}
// 生成一个有效的进程 ID
ProcessId generate_process_id() {
return next_pid_++;
}
protected:
std::unique_ptr<MockSandboxImpl> sandbox_;
std::shared_ptr<MockSandboxEventCallback> callback_;
ProcessId next_pid_ = 1000; // 起始进程ID
};
// 测试初始化和关闭
TEST_F(SandboxBaseTest, InitializeAndShutdown) {
// 准备
SandboxConfig config = create_basic_config();
// 设置期望
EXPECT_CALL(*sandbox_, do_initialize())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
// 执行初始化
auto result = sandbox_->initialize(config);
// 验证结果
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_TRUE(sandbox_->is_initialized());
EXPECT_EQ(sandbox_->get_sandbox_type(), SandboxType::ProcessLevelIsolation);
EXPECT_EQ(sandbox_->get_config().sandbox_type, SandboxType::ProcessLevelIsolation);
// 设置关闭期望
EXPECT_CALL(*sandbox_, do_shutdown())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
// 执行关闭
result = sandbox_->shutdown();
// 验证结果
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_FALSE(sandbox_->is_initialized());
}
// 测试初始化失败
TEST_F(SandboxBaseTest, InitializationFailure) {
// 准备
SandboxConfig config = create_basic_config();
// 设置期望 - 初始化失败
EXPECT_CALL(*sandbox_, do_initialize())
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::InitializationFailed));
// 执行初始化
auto result = sandbox_->initialize(config);
// 验证结果
EXPECT_EQ(result, common::ErrorCode::InitializationFailed);
EXPECT_FALSE(sandbox_->is_initialized());
}
// 测试重复初始化
TEST_F(SandboxBaseTest, DoubleInitialization) {
// 准备
SandboxConfig config = create_basic_config();
// 第一次初始化
ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success);
EXPECT_TRUE(sandbox_->is_initialized());
// 第二次初始化 - 不应该调用do_initialize
EXPECT_CALL(*sandbox_, do_initialize()).Times(0);
auto result = sandbox_->initialize(config);
// 验证重复初始化返回 Success
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_TRUE(sandbox_->is_initialized());
}
// 测试未初始化的关闭
TEST_F(SandboxBaseTest, ShutdownWithoutInitialization) {
// 未初始化时关闭 - 不应该调用do_shutdown
EXPECT_CALL(*sandbox_, do_shutdown()).Times(0);
auto result = sandbox_->shutdown();
// 验证结果
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_FALSE(sandbox_->is_initialized());
}
// 测试进程管理功能
TEST_F(SandboxBaseTest, ProcessManagement) {
// 初始化沙盒
SandboxConfig config = create_basic_config();
ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success);
// 启动进程的期望
ProcessId expected_pid = next_pid_;
EXPECT_CALL(*sandbox_, do_start_process(::testing::_, ::testing::_, ::testing::_))
.Times(1)
.WillOnce([expected_pid](const std::string&, const std::vector<std::string>&, ProcessId& out_pid) {
out_pid = expected_pid;
return common::ErrorCode::Success;
});
// 启动进程
ProcessId actual_pid = 0;
auto result = sandbox_->start_process("test.exe", {"arg1", "arg2"}, actual_pid);
// 验证进程启动
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_EQ(actual_pid, expected_pid);
EXPECT_TRUE(sandbox_->is_process_running(actual_pid));
// 获取进程信息
auto process_info = sandbox_->get_process_info(actual_pid);
EXPECT_EQ(process_info.process_id, actual_pid);
EXPECT_NE(process_info.start_time, Timestamp());
// 获取所有进程ID
auto process_ids = sandbox_->get_all_process_ids();
EXPECT_FALSE(process_ids.empty());
EXPECT_EQ(process_ids[0], actual_pid);
// 停止进程的期望
EXPECT_CALL(*sandbox_, do_stop_process(actual_pid, false))
.Times(1)
.WillOnce(::testing::Return(common::ErrorCode::Success));
// 停止进程
result = sandbox_->stop_process(actual_pid, false);
// 验证进程停止
EXPECT_EQ(result, common::ErrorCode::Success);
// SandboxBase 基类不会主动修改进程状态,这需要由派生类负责
}
// 测试事件回调
TEST_F(SandboxBaseTest, EventCallbacks) {
// 初始化沙盒
SandboxConfig config = create_basic_config();
ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success);
// 设置事件回调
sandbox_->set_event_callback(callback_);
// 进程启动事件
ProcessId pid = generate_process_id();
EXPECT_CALL(*callback_, on_process_started(pid, "test_process"))
.Times(1);
sandbox_->notify_process_started(pid, "test_process");
// 进程崩溃事件
EXPECT_CALL(*callback_, on_process_crashed(pid, "测试崩溃原因"))
.Times(1);
sandbox_->notify_process_crashed(pid, "测试崩溃原因");
// 资源超限事件
EXPECT_CALL(*callback_, on_resource_limit_exceeded(pid, "内存"))
.Times(1);
sandbox_->notify_resource_limit_exceeded(pid, "内存");
// 移除事件回调
sandbox_->remove_event_callback();
// 这应该不会调用任何回调方法
EXPECT_CALL(*callback_, on_process_exited(::testing::_, ::testing::_))
.Times(0);
sandbox_->notify_process_exited(pid, 0);
}
// 测试更新配置
TEST_F(SandboxBaseTest, UpdateConfig) {
// 初始化沙盒
SandboxConfig config = create_basic_config();
ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success);
// 初始配置
EXPECT_EQ(sandbox_->get_config().heartbeat_interval_ms, 1000);
// 更新配置
SandboxConfig new_config = create_basic_config();
new_config.heartbeat_interval_ms = 2000;
auto result = sandbox_->update_config(new_config);
// 验证配置更新
EXPECT_EQ(result, common::ErrorCode::Success);
EXPECT_EQ(sandbox_->get_config().heartbeat_interval_ms, 2000);
}
// 测试进程注册和注销
TEST_F(SandboxBaseTest, ProcessRegistration) {
// 初始化沙盒
SandboxConfig config = create_basic_config();
ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success);
// 注册进程
ProcessId pid = generate_process_id();
sandbox_->register_process(pid, "test_process");
// 验证进程信息
auto* process_info = sandbox_->find_process_info(pid);
ASSERT_NE(process_info, nullptr);
EXPECT_EQ(process_info->process_id, pid);
EXPECT_EQ(process_info->process_name, "test_process");
// 注销进程
sandbox_->unregister_process(pid);
// 验证进程已被注销
process_info = sandbox_->find_process_info(pid);
EXPECT_EQ(process_info, nullptr);
}
// 测试心跳机制
TEST_F(SandboxBaseTest, HeartbeatMechanism) {
// 初始化沙盒
SandboxConfig config = create_basic_config();
ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success);
// 注册进程
ProcessId pid = generate_process_id();
sandbox_->register_process(pid, "test_process");
// 发送心跳
auto result = sandbox_->send_heartbeat(pid);
EXPECT_EQ(result, common::ErrorCode::Success);
// 检查心跳
bool is_responsive = sandbox_->check_heartbeat(pid);
EXPECT_TRUE(is_responsive);
// 无效进程ID的心跳
result = sandbox_->send_heartbeat(999999);
EXPECT_NE(result, common::ErrorCode::Success);
is_responsive = sandbox_->check_heartbeat(999999);
EXPECT_FALSE(is_responsive);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}