use std::sync::Arc;
use luaur_rt::state::{GcIncParams, GcMode};
use luaur_rt::{Error, Lua, Result, UserData};
#[test]
fn test_memory_limit() -> Result<()> {
let lua = Lua::new();
let initial_memory = lua.used_memory();
assert!(
initial_memory > 0,
"used_memory reporting is wrong, lua uses memory for stdlib"
);
let f = lua
.load("local t = {}; for i = 1,10000 do t[i] = i end")
.into_function()?;
f.call::<()>(()).expect("should trigger no memory limit");
lua.set_memory_limit(initial_memory + 10000)?;
match f.call::<()>(()) {
Err(Error::MemoryError(_)) => {}
something_else => panic!("did not trigger memory error: {:?}", something_else),
};
lua.set_memory_limit(0)?;
f.call::<()>(()).expect("should trigger no memory limit");
lua.set_memory_limit(1024)?;
match lua
.load("local t = {}; for i = 1,10000 do t[i] = i end")
.into_function()
{
Err(Error::MemoryError(_)) => {}
_ => panic!("did not trigger memory error"),
};
Ok(())
}
#[test]
fn test_memory_limit_thread() -> Result<()> {
let lua = Lua::new();
let f = lua
.load("local t = {}; for i = 1,10000 do t[i] = i end")
.into_function()?;
let thread = lua.create_thread(f)?;
lua.set_memory_limit(lua.used_memory() + 10000)?;
match thread.resume::<()>(()) {
Err(Error::MemoryError(_)) => {}
something_else => panic!("did not trigger memory error: {:?}", something_else),
};
Ok(())
}
#[test]
fn test_gc_control() -> Result<()> {
let lua = Lua::new();
let globals = lua.globals();
assert!(lua.gc_is_running());
lua.gc_stop();
assert!(!lua.gc_is_running());
lua.gc_restart();
assert!(lua.gc_is_running());
assert!(matches!(
lua.gc_set_mode(GcMode::Incremental({
let p = GcIncParams::default().step_multiplier(100);
p.goal(200)
})),
GcMode::Incremental(_)
));
struct MyUserdata(#[allow(unused)] Arc<()>);
impl UserData for MyUserdata {}
let rc = Arc::new(());
globals.set("userdata", lua.create_userdata(MyUserdata(rc.clone()))?)?;
globals.raw_set("userdata", luaur_rt::Value::Nil)?;
assert_eq!(Arc::strong_count(&rc), 2);
lua.gc_collect()?;
lua.gc_collect()?;
assert_eq!(Arc::strong_count(&rc), 1);
Ok(())
}
#[test]
fn test_gc_step_and_count() -> Result<()> {
let lua = Lua::new();
assert!(lua.gc_count() > 0, "gc_count reports KB in use");
lua.load("local t = {}; for i = 1,1000 do t[i] = {} end")
.exec()?;
for _ in 0..100 {
if lua.gc_step()? {
break;
}
}
lua.gc_collect()?;
Ok(())
}