use luna_core::runtime::Value;
use luna_core::version::LuaVersion;
use luna_core::vm::Vm;
#[test]
fn vm_load_rejects_source_above_budget() {
let mut vm = Vm::new_minimal(LuaVersion::Lua55);
vm.set_loader_input_budget(1024); let src = b"local a = 1\n".repeat(200);
assert!(src.len() > 1024);
let err = vm.load(&src, b"=oversize").expect_err("must reject");
let msg = String::from_utf8_lossy(&err.msg);
assert!(
msg.contains("not enough memory"),
"expected 'not enough memory', got: {msg}"
);
}
#[test]
fn vm_load_accepts_source_at_or_below_budget() {
let mut vm = Vm::new_minimal(LuaVersion::Lua55);
vm.set_loader_input_budget(1 << 20); let src = b"return 1".to_vec();
vm.load(&src, b"=tiny").expect("tiny source should load");
}
#[test]
fn nat_load_feeder_loop_errors_at_budget() {
let mut vm = Vm::new(LuaVersion::Lua55);
vm.set_loader_input_budget(8 * 1024 * 1024); let driver = br#"
local p = 1 << 20
local s = string.rep("a", p)
local count = 0
local function f()
count = count + p
return s
end
local st, msg = load(f, "=big")
assert(st == nil, "expected load to fail at the budget cap")
assert(type(msg) == "string", "expected an error message string")
assert(string.find(msg, "not enough memory") ~= nil,
"expected 'not enough memory' in error, got: " .. tostring(msg))
return msg
"#;
let results = vm.eval(std::str::from_utf8(driver).unwrap()).unwrap();
match results.first() {
Some(Value::Str(s)) => {
let txt = String::from_utf8_lossy(s.as_bytes());
assert!(
txt.contains("not enough memory"),
"feeder loop hit unexpected error: {txt}"
);
}
other => panic!("expected error-msg string from driver, got {other:?}"),
}
}
#[test]
fn default_loader_input_budget_is_256_mib() {
let vm = Vm::new_minimal(LuaVersion::Lua55);
assert_eq!(vm.loader_input_budget(), Vm::DEFAULT_LOADER_INPUT_BUDGET);
assert_eq!(Vm::DEFAULT_LOADER_INPUT_BUDGET, 256 * 1024 * 1024);
}
#[test]
fn set_loader_input_budget_widens() {
let mut vm = Vm::new_minimal(LuaVersion::Lua55);
vm.set_loader_input_budget(usize::MAX);
assert_eq!(vm.loader_input_budget(), usize::MAX);
let mut src = b"return 1\n--[[\n".to_vec();
src.extend(std::iter::repeat_n(b'a', 16 * 1024));
src.extend_from_slice(b"\n]]\n");
vm.load(&src, b"=widened")
.expect("should load with widened cap");
}