feat: 插件自动挂载测试机制 — capabilities + self_test + 3阶段启动
- Plugin trait 增加 capabilities() 和 self_test() 方法 - PluginVTable 增加 get_capabilities 和 self_test FFI - ServiceManager 三阶段启动: init → self_test → start - SendCallback 改为 ctx 参数传递,消除 thread_local - export_plugin! 宏所有 FFI 函数包裹 catch_unwind - PluginManifest 增加 capabilities/required_capabilities/auto_test - 新增 3 个自测相关测试用例 (共 59 测试)
This commit is contained in:
@@ -29,12 +29,28 @@ pub struct PluginManifest {
|
||||
#[serde(default = "default_error_policy")]
|
||||
pub error_policy: ErrorPolicy,
|
||||
pub so_filename: String,
|
||||
/// 插件声明支持的功能列表
|
||||
#[serde(default)]
|
||||
pub capabilities: Vec<String>,
|
||||
/// 挂载时必须通过测试的功能(capabilities 的子集)
|
||||
#[serde(default)]
|
||||
pub required_capabilities: Vec<String>,
|
||||
/// 自测超时(毫秒),默认 5000
|
||||
#[serde(default = "default_test_timeout")]
|
||||
pub test_timeout_ms: u64,
|
||||
/// 是否在挂载时自动运行自测,默认 true
|
||||
#[serde(default = "default_true")]
|
||||
pub auto_test: bool,
|
||||
}
|
||||
|
||||
fn default_error_policy() -> ErrorPolicy {
|
||||
ErrorPolicy::AutoRollback
|
||||
}
|
||||
|
||||
fn default_test_timeout() -> u64 {
|
||||
5000
|
||||
}
|
||||
|
||||
/// 插件错误处理策略
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@@ -250,6 +266,10 @@ mod tests {
|
||||
dependencies: vec![],
|
||||
error_policy: ErrorPolicy::AutoRollback,
|
||||
so_filename: "libtest_plugin.so".to_string(),
|
||||
capabilities: vec![],
|
||||
required_capabilities: vec![],
|
||||
test_timeout_ms: 5000,
|
||||
auto_test: true,
|
||||
};
|
||||
|
||||
fs::write(
|
||||
@@ -333,4 +353,38 @@ mod tests {
|
||||
|
||||
let _ = fs::remove_dir_all(&tmp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn manifest_parses_capabilities() {
|
||||
let json = r#"{
|
||||
"id": "sensor",
|
||||
"version": "1.0.0",
|
||||
"sdk_version": "0.2.0",
|
||||
"so_filename": "libsensor.so",
|
||||
"capabilities": ["temperature", "humidity"],
|
||||
"required_capabilities": ["temperature"],
|
||||
"test_timeout_ms": 3000,
|
||||
"auto_test": true
|
||||
}"#;
|
||||
let manifest: PluginManifest = serde_json::from_str(json).unwrap();
|
||||
assert_eq!(manifest.capabilities, vec!["temperature", "humidity"]);
|
||||
assert_eq!(manifest.required_capabilities, vec!["temperature"]);
|
||||
assert_eq!(manifest.test_timeout_ms, 3000);
|
||||
assert!(manifest.auto_test);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn manifest_capabilities_default_empty() {
|
||||
let json = r#"{
|
||||
"id": "basic",
|
||||
"version": "1.0.0",
|
||||
"sdk_version": "0.2.0",
|
||||
"so_filename": "libbasic.so"
|
||||
}"#;
|
||||
let manifest: PluginManifest = serde_json::from_str(json).unwrap();
|
||||
assert!(manifest.capabilities.is_empty());
|
||||
assert!(manifest.required_capabilities.is_empty());
|
||||
assert_eq!(manifest.test_timeout_ms, 5000);
|
||||
assert!(manifest.auto_test);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user