From 3ce4f61cf9253c6f746626a36e66501f94557523 Mon Sep 17 00:00:00 2001
From: "Sven M. Hallberg" <pesco@khjk.org>
Date: Tue, 1 Dec 2015 16:49:40 +0100
Subject: [PATCH] add test for out-of-memory handling

---
 src/t_misc.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/src/t_misc.c b/src/t_misc.c
index 92c2b326..47afbe4e 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);
 }
-- 
GitLab