#![allow(unused_imports)]
use crate::types::{ExecutionContext, ExecutionResult, SandboxConfig};
use crate::unified_sandbox::{BackendChoice, SandboxBackend, UnifiedSandbox};
use base64::Engine;
#[allow(dead_code)]
fn should_skip_sandbox_tests() -> bool {
std::env::var("CI").is_ok() || std::env::var("GITHUB_ACTIONS").is_ok()
}
#[tokio::test]
async fn test_unified_sandbox_nodejs_backend() -> Result<(), anyhow::Error> {
if should_skip_sandbox_tests() {
return Ok(());
}
let sandbox = UnifiedSandbox::new(SandboxConfig::restrictive(), SandboxBackend::NodeJs).await?;
let context = ExecutionContext::new("test".to_string(), serde_json::json!({}));
let result = sandbox.execute("console.log('test')", context).await?;
match &result {
ExecutionResult::Success { stdout, .. } => {
assert!(
stdout.contains("test") || !stdout.is_empty(),
"Expected non-empty stdout, got: {:?}",
stdout
);
}
_ => panic!("Expected success but got: {:?}", result),
}
let metrics = sandbox.get_metrics().await;
assert_eq!(metrics.total_executions, 1);
assert_eq!(metrics.node_executions, 1);
assert_eq!(metrics.wasm_executions, 0);
Ok(())
}
#[tokio::test]
async fn test_unified_sandbox_wasm_backend() -> Result<(), anyhow::Error> {
let sandbox = UnifiedSandbox::new(SandboxConfig::restrictive(), SandboxBackend::Wasm).await?;
let wasm_bytes = wat::parse_str(
r#"
(module
(func (export "main") (result i32)
i32.const 42
)
)
"#,
)?;
let context = ExecutionContext::new("test".to_string(), serde_json::json!({}));
let wasm_payload = format!(
"wasm_base64:{}",
base64::prelude::BASE64_STANDARD.encode(wasm_bytes)
);
let result = sandbox.execute(&wasm_payload, context).await?;
match &result {
ExecutionResult::Success { .. } => {} _ => panic!("Expected success but got: {:?}", result),
}
let metrics = sandbox.get_metrics().await;
assert_eq!(metrics.total_executions, 1);
assert_eq!(metrics.node_executions, 0);
assert_eq!(metrics.wasm_executions, 1);
Ok(())
}
#[tokio::test]
async fn test_unified_sandbox_hybrid_backend() -> Result<(), anyhow::Error> {
if should_skip_sandbox_tests() {
return Ok(());
}
let sandbox = UnifiedSandbox::new(
SandboxConfig::default(),
SandboxBackend::Hybrid {
wasm_ratio: 0.5,
intelligent_routing: true,
},
)
.await?;
let context = ExecutionContext::new("test".to_string(), serde_json::json!({}));
for i in 0..10 {
let code = format!("console.log('test{}')", i);
let result = sandbox.execute(&code, context.clone()).await?;
match &result {
ExecutionResult::Success { .. } => {} _ => panic!("Expected success for iteration {} but got: {:?}", i, result),
}
}
let metrics = sandbox.get_metrics().await;
assert_eq!(metrics.total_executions, 10);
assert!(metrics.node_executions > 0);
Ok(())
}
#[tokio::test]
async fn test_intelligent_routing() -> Result<(), anyhow::Error> {
if should_skip_sandbox_tests() {
return Ok(());
}
let sandbox = UnifiedSandbox::new(
SandboxConfig::default(),
SandboxBackend::Hybrid {
wasm_ratio: 0.1, intelligent_routing: true,
},
)
.await?;
let context = ExecutionContext::new("test".to_string(), serde_json::json!({}));
let simple_result = sandbox
.execute("console.log('simple')", context.clone())
.await?;
match &simple_result {
ExecutionResult::Success { .. } => {} _ => panic!(
"Expected success for simple code but got: {:?}",
simple_result
),
}
let complex_result = sandbox
.execute(
"function test() { return 'complex'; } console.log(test());",
context,
)
.await?;
match &complex_result {
ExecutionResult::Success { .. } => {} _ => panic!(
"Expected success for complex code but got: {:?}",
complex_result
),
}
let metrics = sandbox.get_metrics().await;
assert_eq!(metrics.total_executions, 2);
let routing_decisions = &metrics.routing_decisions;
assert_eq!(routing_decisions.len(), 2);
assert_eq!(routing_decisions[0].backend, "nodejs");
assert_eq!(routing_decisions[1].backend, "nodejs");
Ok(())
}
#[tokio::test]
async fn test_backend_health() -> Result<(), anyhow::Error> {
let sandbox = UnifiedSandbox::new(
SandboxConfig::restrictive(),
SandboxBackend::Hybrid {
wasm_ratio: 0.5,
intelligent_routing: true,
},
)
.await?;
let health = sandbox.get_health_status().await;
assert!(health.node_available);
assert!(health.wasm_available);
assert!(health.wasmtime_pool_stats.is_some());
Ok(())
}
#[tokio::test]
async fn test_backend_update() -> Result<(), anyhow::Error> {
let mut sandbox =
UnifiedSandbox::new(SandboxConfig::restrictive(), SandboxBackend::NodeJs).await?;
let context = ExecutionContext::new("test".to_string(), serde_json::json!({}));
let result1 = sandbox
.execute("console.log('nodejs')", context.clone())
.await?;
match &result1 {
ExecutionResult::Success { .. } => {} _ => panic!(
"Expected success for Node.js backend but got: {:?}",
result1
),
}
sandbox.update_backend(SandboxBackend::Wasm).await?;
let wasm_bytes = wat::parse_str(
r#"
(module
(func (export "main") (result i32)
i32.const 42
)
)
"#,
)?;
let wasm_payload = format!(
"wasm_base64:{}",
base64::prelude::BASE64_STANDARD.encode(wasm_bytes)
);
let result2 = sandbox.execute(&wasm_payload, context).await?;
match &result2 {
ExecutionResult::Success { .. } => {} _ => panic!("Expected success for WASM backend but got: {:?}", result2),
}
let metrics = sandbox.get_metrics().await;
assert!(
metrics.total_executions >= 1,
"Expected at least 1 execution, got {}",
metrics.total_executions
);
Ok(())
}