#[cfg(feature = "wasm-runtime")]
mod sdk_integration {
use agentzero_plugins::wasm::{
WasmIsolationPolicy, WasmPluginContainer, WasmPluginRuntime, WasmV2Options,
};
use std::path::PathBuf;
fn sample_wasm_path() -> PathBuf {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
PathBuf::from(manifest_dir)
.join("tests/fixtures/sample-plugin/target/wasm32-wasip1/release/sample_plugin.wasm")
}
fn default_policy() -> WasmIsolationPolicy {
WasmIsolationPolicy {
max_execution_ms: 5_000,
max_module_bytes: 5 * 1024 * 1024,
max_memory_mb: 64,
allow_network: false,
allow_fs_write: false,
allow_fs_read: false,
allowed_host_calls: vec!["az_log".to_string()],
}
}
#[test]
fn sdk_plugin_executes_successfully() {
let wasm_path = sample_wasm_path();
if !wasm_path.exists() {
eprintln!(
"SKIP: sample plugin not built at {}. Build with:\n\
cd crates/agentzero-plugins/tests/fixtures/sample-plugin\n\
RUSTC=$(rustup which rustc) cargo build --target wasm32-wasip1 --release",
wasm_path.display()
);
return;
}
let runtime = WasmPluginRuntime::new();
let container = WasmPluginContainer {
id: "sample_plugin".to_string(),
module_path: wasm_path,
entrypoint: "az_tool_execute".to_string(),
max_execution_ms: 5_000,
max_memory_mb: 64,
allow_network: false,
allow_fs_write: false,
};
let policy = default_policy();
let options = WasmV2Options {
workspace_root: "/tmp/test-workspace".to_string(),
capabilities: vec![],
};
let result = runtime
.execute_v2_with_policy(&container, r#"{"name":"AgentZero"}"#, &options, &policy)
.expect("SDK plugin execution should succeed");
assert!(
result.output.contains("Hello, AgentZero!"),
"output should contain greeting, got: {}",
result.output
);
assert!(
result.output.contains("workspace=/tmp/test-workspace"),
"output should contain workspace root, got: {}",
result.output
);
assert!(result.error.is_none(), "should have no error");
}
#[test]
fn sdk_plugin_handles_empty_input() {
let wasm_path = sample_wasm_path();
if !wasm_path.exists() {
return;
}
let runtime = WasmPluginRuntime::new();
let container = WasmPluginContainer {
id: "sample_plugin".to_string(),
module_path: wasm_path,
entrypoint: "az_tool_execute".to_string(),
max_execution_ms: 5_000,
max_memory_mb: 64,
allow_network: false,
allow_fs_write: false,
};
let policy = default_policy();
let options = WasmV2Options {
workspace_root: "/tmp".to_string(),
capabilities: vec![],
};
let result = runtime
.execute_v2_with_policy(&container, "{}", &options, &policy)
.expect("SDK plugin should handle empty input");
assert!(
result.output.contains("Hello, world!"),
"should use default name, got: {}",
result.output
);
}
#[test]
fn sdk_plugin_handles_invalid_json_input() {
let wasm_path = sample_wasm_path();
if !wasm_path.exists() {
return;
}
let runtime = WasmPluginRuntime::new();
let container = WasmPluginContainer {
id: "sample_plugin".to_string(),
module_path: wasm_path,
entrypoint: "az_tool_execute".to_string(),
max_execution_ms: 5_000,
max_memory_mb: 64,
allow_network: false,
allow_fs_write: false,
};
let policy = default_policy();
let options = WasmV2Options {
workspace_root: "/tmp".to_string(),
capabilities: vec![],
};
let result = runtime
.execute_v2_with_policy(&container, "not json at all", &options, &policy)
.expect("SDK plugin should not crash on invalid input");
assert!(
result.error.is_some(),
"should have error for invalid input, got output: {}",
result.output
);
}
}