use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicIsize, Ordering::Relaxed};
use aura_lang::Script;
struct Counting;
static LIVE: AtomicIsize = AtomicIsize::new(0);
unsafe impl GlobalAlloc for Counting {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
LIVE.fetch_add(layout.size() as isize, Relaxed);
System.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
LIVE.fetch_sub(layout.size() as isize, Relaxed);
System.dealloc(ptr, layout)
}
}
#[global_allocator]
static ALLOCATOR: Counting = Counting;
#[test]
fn memory_does_not_grow_with_the_number_of_calls() {
let rules = Script::builder()
.source(
"t.aura",
concat!(
"pub def route(path)\n",
" backend: path.starts_with(\"/api\") ? \"api\" : \"static\"\n",
" tags: [1, 2, 3, 4, 5].map (x, i) -> \"#{path}-#{x}\" end\n",
"end\n",
),
)
.load()
.expect("loads");
let route = rules
.function::<(&str,), serde_json::Value>("route")
.expect("binds");
for _ in 0..1_000 {
route.call(("/api/x",)).expect("call");
}
let before = LIVE.load(Relaxed);
for _ in 0..100_000 {
route.call(("/api/x",)).expect("call");
}
let grew = LIVE.load(Relaxed) - before;
assert!(
grew < 64 * 1024,
"live memory grew by {grew} bytes over 100,000 calls — {} bytes per call",
grew / 100_000
);
}