diff --git a/src/t_misc.c b/src/t_misc.c index 92c2b326471d48a82fcae8f110d1febad58c6fe3..47afbe4e87b7a94db2fe46cf7a0da839f5f29c37 100644 --- a/src/t_misc.c +++ b/src/t_misc.c @@ -1,5 +1,6 @@ #include <glib.h> #include <string.h> +#include <sys/resource.h> #include "test_suite.h" #include "hammer.h" @@ -29,7 +30,43 @@ static void test_tt_registry(void) { g_check_cmp_int32(h_get_token_type_number("com.upstandinghackers.test.unkown_token_type"), ==, 0); } +// perform a big allocation during parsing to trigger out-of-memory handling +static HParsedToken *act_big_alloc(const HParseResult *r, void *user) { + void *buf = h_arena_malloc(r->arena, 1024*1024*1024); + assert(buf != NULL); + return NULL; +} +static void test_oom(void) { + HParser *p = h_action(h_ch('x'), act_big_alloc, NULL); + // this should always fail, but never crash + + struct rlimit bak, lim; + int i; + i = getrlimit(RLIMIT_DATA, &bak); + assert(i == 0); + lim.rlim_cur = 1000*1024*1024; // never enough + if(lim.rlim_cur > bak.rlim_max) + lim.rlim_cur = bak.rlim_max; + lim.rlim_max = bak.rlim_max; + i = setrlimit(RLIMIT_DATA, &lim); + assert(i == 0); + + g_check_parse_failed(p, PB_PACKRAT, "x",1); + g_check_parse_failed(p, PB_REGULAR, "x",1); + g_check_parse_failed(p, PB_LLk, "x",1); + g_check_parse_failed(p, PB_LALR, "x",1); + g_check_parse_failed(p, PB_GLR, "x",1); + + g_check_parse_chunks_failed(p, PB_LLk, "",0, "x",1); + //g_check_parse_chunks_failed(p, PB_LALR, "",0, "x",1); + //g_check_parse_chunks_failed(p, PB_GLR, "",0, "x",1); + + i = setrlimit(RLIMIT_DATA, &bak); + assert(i == 0); +} + void register_misc_tests(void) { g_test_add_func("/core/misc/tt_user", test_tt_user); g_test_add_func("/core/misc/tt_registry", test_tt_registry); + g_test_add_func("/core/misc/oom", test_oom); }