Line data Source code
1 : /** \file suite_oomtest.c
2 : * \brief Unit testing for oomtest helper
3 : * \author François Cerbelle (Fanfan), francois@cerbelle.net
4 : *
5 : * \internal
6 : * Created: 07/07/2024
7 : * Revision: none
8 : * Last modified: 2024-07-27 00:34
9 : * Compiler: gcc
10 : * Organization: Cerbelle.net
11 : * Copyright: Copyright (c) 2024, François Cerbelle
12 : *
13 : * This source code is released for free distribution under the terms of the
14 : * GNU General Public License as published by the Free Software Foundation.
15 : */
16 :
17 : #ifdef HAVE_CONFIG_H
18 : #include "config.h"
19 : #endif
20 :
21 : #include "debug/oom.h" /* OOM simulation */
22 : #include <check.h>
23 : #include <unistd.h> /* pid_t getpid() */
24 : #include <sys/stat.h> /* mkdir(), chdir(), mode_t */
25 : #include <stdio.h> /* fprintf */
26 : #include <stdlib.h> /* abort() */
27 : #include <sys/resource.h> /* setrlimit */
28 : #include <errno.h> /* errno */
29 : #include <string.h> /* strerror() */
30 : #include <limits.h> /* ULONG_MAX */
31 : #include "checktools.inc"
32 :
33 3 : START_TEST(oomtest_config_once_0)
34 : {
35 : struct rlimit limit;
36 : size_t l_result;
37 : size_t l_avail;
38 :
39 : /* Find installed physical RAM, 0 in case of failure */
40 3 : l_avail = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
41 :
42 : /* If pages were freed by the OS since a previous setrlimit, we need to use
43 : * the smallest value between previous rlimit value and available pages */
44 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
45 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
46 :
47 3 : l_result=oomtest_config(0);
48 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
49 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
50 3 : ck_assert(l_result==limit.rlim_max);
51 3 : ck_assert(l_result==l_avail);
52 3 : }
53 : END_TEST
54 :
55 3 : START_TEST(oomtest_config_once_max)
56 : {
57 : struct rlimit limit;
58 : size_t l_result;
59 : size_t l_avail;
60 :
61 : /* Find installed physical RAM, 0 in case of failure */
62 3 : l_avail = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
63 :
64 : /* If pages were freed by the OS since a previous setrlimit, we need to use
65 : * the smallest value between previous rlimit value and available pages */
66 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
67 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
68 :
69 3 : l_result=oomtest_config(l_avail);
70 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
71 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
72 3 : ck_assert(l_result==limit.rlim_max);
73 3 : ck_assert(l_result==l_avail);
74 3 : }
75 : END_TEST
76 :
77 3 : START_TEST(oomtest_config_once_over)
78 : {
79 : size_t l_avail;
80 :
81 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
82 : * whole testsuite if not caught or not in a child process */
83 3 : forktest_only;
84 :
85 : /* Find installed physical RAM, 0 in case of failure */
86 2 : l_avail = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
87 :
88 : /* SIGABRT(6) expected here */
89 2 : oomtest_config(l_avail+1);
90 : }
91 : END_TEST
92 :
93 3 : START_TEST(oomtest_config_once_value)
94 : {
95 : struct rlimit limit;
96 : size_t l_result;
97 : size_t l_avail;
98 :
99 : /* Find available physical RAM, 0 in case of failure */
100 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
101 :
102 : /* If pages were freed by the OS since a previous setrlimit, we need to use
103 : * the smallest value between previous rlimit value and available pages */
104 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
105 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
106 :
107 3 : l_avail /= 2;
108 3 : l_result=oomtest_config(l_avail);
109 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
110 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
111 3 : ck_assert(l_result==limit.rlim_max);
112 3 : ck_assert(l_result==l_avail);
113 3 : }
114 : END_TEST
115 :
116 3 : START_TEST(oomtest_config_twice_same)
117 : {
118 : struct rlimit limit;
119 : size_t l_result;
120 : size_t l_avail;
121 :
122 : /* Find available physical RAM, 0 in case of failure */
123 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
124 :
125 : /* If pages were freed by the OS since a previous setrlimit, we need to use
126 : * the smallest value between previous rlimit value and available pages */
127 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
128 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
129 :
130 3 : l_avail /= 2;
131 : /* First config, already tested */
132 3 : l_result=oomtest_config(l_avail);
133 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
134 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
135 3 : ck_assert(l_result==limit.rlim_max);
136 3 : ck_assert(l_result==l_avail);
137 :
138 : /* Second config, actuel current test */
139 3 : l_result=oomtest_config(l_avail);
140 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
141 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
142 3 : ck_assert(l_result==limit.rlim_max);
143 3 : ck_assert(l_result==l_avail);
144 3 : }
145 : END_TEST
146 :
147 3 : START_TEST(oomtest_config_twice_up)
148 : {
149 : struct rlimit limit;
150 : size_t l_result;
151 : size_t l_avail;
152 :
153 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
154 : * whole testsuite if not caught or not in a child process */
155 3 : forktest_only;
156 :
157 : /* Find available physical RAM, 0 in case of failure */
158 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
159 :
160 : /* If pages were freed by the OS since a previous setrlimit, we need to use
161 : * the smallest value between previous rlimit value and available pages */
162 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
163 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
164 :
165 : /* First configuration to half of the available RAM, already tested */
166 2 : l_result=oomtest_config(l_avail/3);
167 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
168 2 : ck_assert(l_result==limit.rlim_max);
169 2 : ck_assert(l_result==l_avail/3);
170 :
171 : /* Second config to set hard limit to the available RAM (higher) */
172 : /* SIGABRT(6) expected here */
173 2 : oomtest_config(l_avail/2);
174 : }
175 : END_TEST
176 :
177 3 : START_TEST(oomtest_config_twice_down)
178 : {
179 : struct rlimit limit;
180 : size_t l_result;
181 : size_t l_avail;
182 :
183 : /* Find available physical RAM, 0 in case of failure */
184 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
185 :
186 : /* If pages were freed by the OS since a previous setrlimit, we need to use
187 : * the smallest value between previous rlimit value and available pages */
188 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
189 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
190 :
191 3 : l_avail /= 2;
192 3 : l_result=oomtest_config(l_avail);
193 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
194 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
195 3 : ck_assert(l_result==limit.rlim_max);
196 3 : ck_assert(l_result==l_avail);
197 :
198 3 : l_avail /= 2;
199 3 : l_result=oomtest_config(l_avail);
200 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
201 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
202 3 : ck_assert(l_result==limit.rlim_max);
203 3 : ck_assert(l_result==l_avail);
204 3 : }
205 : END_TEST
206 :
207 3 : START_TEST(oomtest_noconfig_enable_0)
208 : {
209 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
210 : * whole testsuite if not caught or not in a child process */
211 : /* Furthermore, a previous test already configured the limit for the
212 : * process if not forked */
213 3 : forktest_only;
214 :
215 : /* SIG6 expected */
216 2 : oomtest_enable(0);
217 : }
218 : END_TEST
219 :
220 3 : START_TEST(oomtest_noconfig_enable_value)
221 : {
222 : struct rlimit limit;
223 : size_t l_avail;
224 :
225 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
226 : * whole testsuite if not caught or not in a child process */
227 : /* Furthermore, a previous test already configured the limit for the
228 : * process if not forked */
229 3 : forktest_only;
230 :
231 : /* Find available physical RAM, 0 in case of failure */
232 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
233 :
234 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
235 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
236 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
237 2 : l_avail /= 2;
238 :
239 : /* SIG6 expected */
240 2 : oomtest_enable(l_avail);
241 : }
242 : END_TEST
243 :
244 3 : START_TEST(oomtest_noconfig_enable_max)
245 : {
246 : struct rlimit limit;
247 : size_t l_avail;
248 :
249 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
250 : * whole testsuite if not caught or not in a child process */
251 : /* Furthermore, a previous test already configured the limit for the
252 : * process if not forked */
253 3 : forktest_only;
254 :
255 : /* Find installed physical RAM, 0 in case of failure */
256 2 : l_avail = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
257 :
258 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
259 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
260 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
261 :
262 : /* SIG6 expected */
263 2 : oomtest_enable(l_avail);
264 : }
265 : END_TEST
266 :
267 3 : START_TEST(oomtest_noconfig_enable_over)
268 : {
269 : struct rlimit limit;
270 : size_t l_avail;
271 :
272 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
273 : * whole testsuite if not caught or not in a child process */
274 : /* Furthermore, a previous test already configured the limit for the
275 : * process if not forked */
276 3 : forktest_only;
277 :
278 : /* Find installed physical RAM, 0 in case of failure */
279 2 : l_avail = (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
280 :
281 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
282 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
283 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
284 :
285 : /* SIG6 expected */
286 2 : oomtest_enable(l_avail+1);
287 : }
288 : END_TEST
289 :
290 3 : START_TEST(oomtest_config_enable_0)
291 : {
292 : struct rlimit limit;
293 : size_t l_result;
294 : size_t l_avail;
295 :
296 : /* Find available physical RAM, 0 in case of failure */
297 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
298 :
299 : /* Configure a hard limit only if not already configured by non-forked
300 : * previous tests */
301 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
302 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
303 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
304 3 : oomtest_config(l_avail);
305 :
306 : /* Soft limit to hard limit */
307 3 : l_result=oomtest_enable(0);
308 :
309 : /* Check */
310 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
311 3 : ck_assert(limit.rlim_cur==l_avail);
312 3 : ck_assert(limit.rlim_max==l_avail);
313 3 : ck_assert(l_result==limit.rlim_cur);
314 :
315 : /* Cleanup attempt in case of no fork */
316 3 : oomtest_disable();
317 3 : }
318 : END_TEST
319 :
320 3 : START_TEST(oomtest_config_enable_value)
321 : {
322 : struct rlimit limit;
323 : size_t l_result;
324 : size_t l_avail;
325 :
326 : /* Find available physical RAM, 0 in case of failure */
327 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
328 :
329 : /* Configure a hard limit only if not already configured by non-forked
330 : * previous tests */
331 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
332 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
333 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
334 3 : oomtest_config(l_avail);
335 :
336 : /* Update rlimit values */
337 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
338 3 : l_avail = limit.rlim_cur;
339 :
340 : /* Soft limit to half max */
341 3 : l_result=oomtest_enable(l_avail/2);
342 :
343 : /* Check */
344 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
345 3 : ck_assert(limit.rlim_cur==l_avail/2);
346 3 : ck_assert(limit.rlim_max==l_avail);
347 3 : ck_assert(l_result==limit.rlim_cur);
348 :
349 : /* Cleanup attempt in case of no fork */
350 3 : oomtest_disable();
351 3 : }
352 : END_TEST
353 :
354 3 : START_TEST(oomtest_config_enable_max)
355 : {
356 : struct rlimit limit;
357 : size_t l_result;
358 : size_t l_avail;
359 :
360 : /* Find available physical RAM, 0 in case of failure */
361 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
362 :
363 : /* Configure a hard limit only if not already configured by non-forked
364 : * previous tests */
365 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
366 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
367 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
368 3 : oomtest_config(l_avail);
369 :
370 : /* Update rlimit values */
371 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
372 3 : l_avail = limit.rlim_cur;
373 :
374 : /* Soft limit to hard limit */
375 3 : l_result=oomtest_enable(l_avail);
376 :
377 : /* Check */
378 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
379 3 : ck_assert(limit.rlim_cur==l_avail);
380 3 : ck_assert(limit.rlim_max==l_avail);
381 3 : ck_assert(l_result==limit.rlim_cur);
382 :
383 : /* Cleanup attempt in case of no fork */
384 3 : oomtest_disable();
385 3 : }
386 : END_TEST
387 :
388 3 : START_TEST(oomtest_config_enable_over)
389 : {
390 : struct rlimit limit;
391 : size_t l_avail;
392 :
393 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
394 : * whole testsuite if not caught or not in a child process */
395 3 : forktest_only;
396 :
397 : /* Find available physical RAM, 0 in case of failure */
398 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
399 :
400 : /* Configure a hard limit only if not already configured by non-forked
401 : * previous tests */
402 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
403 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
404 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
405 2 : oomtest_config(l_avail);
406 :
407 : /* Update rlimit values */
408 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
409 2 : l_avail = limit.rlim_cur;
410 :
411 : /* SIG6 expected */
412 2 : oomtest_enable(l_avail+1);
413 : }
414 : END_TEST
415 :
416 3 : START_TEST(oomtest_config_enable_twice_same)
417 : {
418 : struct rlimit limit;
419 : size_t l_result;
420 : size_t l_avail;
421 :
422 : /* Find available physical RAM, 0 in case of failure */
423 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
424 :
425 : /* Configure a hard limit only if not already configured by non-forked
426 : * previous tests */
427 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
428 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
429 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
430 3 : oomtest_config(l_avail);
431 :
432 : /* Update rlimit values */
433 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
434 3 : l_avail = limit.rlim_cur;
435 :
436 : /* Set soft limit */
437 3 : l_result=oomtest_enable(l_avail/2);
438 :
439 : /* Check */
440 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
441 3 : ck_assert(limit.rlim_cur==l_avail/2);
442 3 : ck_assert(limit.rlim_max==l_avail);
443 3 : ck_assert(l_result==limit.rlim_cur);
444 :
445 : /* Set soft limit */
446 3 : l_result=oomtest_enable(l_avail/2);
447 :
448 : /* Check */
449 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
450 3 : ck_assert(limit.rlim_cur==l_avail/2);
451 3 : ck_assert(limit.rlim_max==l_avail);
452 3 : ck_assert(l_result==limit.rlim_cur);
453 :
454 : /* Cleanup attempt in case of no fork */
455 3 : oomtest_disable();
456 3 : }
457 : END_TEST
458 :
459 3 : START_TEST(oomtest_config_enable_twice_up)
460 : {
461 : struct rlimit limit;
462 : size_t l_result;
463 : size_t l_avail;
464 :
465 : /* Find available physical RAM, 0 in case of failure */
466 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
467 :
468 : /* Configure a hard limit only if not already configured by non-forked
469 : * previous tests */
470 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
471 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
472 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
473 3 : oomtest_config(l_avail);
474 :
475 : /* Update rlimit values */
476 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
477 3 : l_avail = limit.rlim_cur;
478 :
479 : /* Set soft limit */
480 3 : l_result=oomtest_enable(l_avail/3);
481 :
482 : /* Check */
483 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
484 3 : ck_assert(limit.rlim_cur==l_avail/3);
485 3 : ck_assert(limit.rlim_max==l_avail);
486 3 : ck_assert(l_result==limit.rlim_cur);
487 :
488 : /* Set soft limit */
489 3 : l_result=oomtest_enable(l_avail/2);
490 :
491 : /* Check */
492 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
493 3 : ck_assert(limit.rlim_cur==l_avail/2);
494 3 : ck_assert(limit.rlim_max==l_avail);
495 3 : ck_assert(l_result==limit.rlim_cur);
496 :
497 : /* Cleanup attempt in case of no fork */
498 3 : oomtest_disable();
499 3 : }
500 : END_TEST
501 :
502 3 : START_TEST(oomtest_config_enable_twice_down)
503 : {
504 : struct rlimit limit;
505 : size_t l_result;
506 : size_t l_avail;
507 :
508 : /* Find available physical RAM, 0 in case of failure */
509 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
510 :
511 : /* Configure a hard limit only if not already configured by non-forked
512 : * previous tests */
513 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
514 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
515 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
516 3 : oomtest_config(l_avail);
517 :
518 : /* Update rlimit values */
519 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
520 3 : l_avail = limit.rlim_cur;
521 :
522 : /* Set soft limit */
523 3 : l_result=oomtest_enable(l_avail);
524 :
525 : /* Check */
526 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
527 3 : ck_assert(limit.rlim_cur==l_avail);
528 3 : ck_assert(limit.rlim_max==l_avail);
529 3 : ck_assert(l_result==limit.rlim_cur);
530 :
531 : /* Set soft limit */
532 3 : l_result=oomtest_enable(l_avail/2);
533 :
534 : /* Check */
535 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
536 3 : ck_assert(limit.rlim_cur==l_avail/2);
537 3 : ck_assert(limit.rlim_max==l_avail);
538 3 : ck_assert(l_result==limit.rlim_cur);
539 :
540 : /* Cleanup attempt in case of no fork */
541 3 : oomtest_disable();
542 3 : }
543 : END_TEST
544 :
545 3 : START_TEST(oomtest_noconfig_disable)
546 : {
547 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
548 : * whole testsuite if not caught or not in a child process */
549 : /* Furthermore, if not forked, the process might already be configured */
550 3 : forktest_only;
551 :
552 : /* SIG6 expected */
553 2 : oomtest_disable();
554 : }
555 : END_TEST
556 :
557 3 : START_TEST(oomtest_config_noenable_disable)
558 : {
559 : struct rlimit limit;
560 : size_t l_avail;
561 :
562 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
563 : * whole testsuite if not caught or not in a child process */
564 : /* Furthermore, a previous test already configured the limit for the
565 : * process if not forked */
566 3 : forktest_only;
567 :
568 : /* Find available physical RAM, 0 in case of failure */
569 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
570 :
571 : /* Configure a hard limit only if not already configured by non-forked
572 : * previous tests */
573 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
574 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
575 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
576 2 : oomtest_config(l_avail);
577 :
578 : /* Soft limit to hard limit */
579 : /* SIGABRT6 expected */
580 2 : oomtest_disable();
581 : }
582 : END_TEST
583 :
584 3 : START_TEST(oomtest_config_enable_disable)
585 : {
586 : struct rlimit limit;
587 : size_t l_result;
588 : size_t l_avail;
589 :
590 : /* Find available physical RAM, 0 in case of failure */
591 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
592 :
593 : /* Configure a hard limit only if not already configured by non-forked
594 : * previous tests */
595 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
596 3 : ck_assert(limit.rlim_cur==limit.rlim_max);
597 3 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
598 3 : oomtest_config(l_avail);
599 :
600 : /* Update rlimit values */
601 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
602 3 : l_avail = limit.rlim_cur;
603 :
604 : /* Set soft limit */
605 3 : l_result=oomtest_enable(l_avail/2);
606 :
607 : /* Check */
608 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
609 3 : ck_assert(limit.rlim_cur==l_avail/2);
610 3 : ck_assert(limit.rlim_max==l_avail);
611 3 : ck_assert(l_result==limit.rlim_cur);
612 :
613 : /* Test disable */
614 3 : l_result=oomtest_disable();
615 :
616 : /* Check */
617 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
618 3 : ck_assert(limit.rlim_cur==l_avail);
619 3 : ck_assert(limit.rlim_max==l_avail);
620 3 : ck_assert(l_result==limit.rlim_cur);
621 3 : }
622 : END_TEST
623 :
624 3 : START_TEST(oomtest_noconfig_noenable_fill)
625 : {
626 : /* Should be skipped while not enabled or not configured(would be stupid) */
627 3 : oomtest_fill(0,0);
628 3 : }
629 : END_TEST
630 :
631 300 : START_TEST(oomtest_config_enable_fill_minheap)
632 : {
633 : struct rlimit limit;
634 : size_t l_result;
635 : size_t l_avail;
636 : char* l_ptr;
637 300 : size_t i=0;
638 :
639 : /* Find available physical RAM, 0 in case of failure */
640 300 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
641 :
642 : /* Configure a hard limit only if not already configured by non-forked
643 : * previous tests */
644 300 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
645 300 : ck_assert(limit.rlim_cur==limit.rlim_max);
646 300 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
647 300 : oomtest_config(l_avail);
648 :
649 : /* Update rlimit values */
650 300 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
651 300 : l_avail = limit.rlim_cur;
652 :
653 : /* Set soft limit */
654 300 : l_result=oomtest_enable(l_avail/2);
655 :
656 : /* Check */
657 300 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
658 300 : ck_assert(limit.rlim_cur==l_avail/2);
659 300 : ck_assert(limit.rlim_max==l_avail);
660 300 : ck_assert(l_result==limit.rlim_cur);
661 :
662 : /* Test fill */
663 300 : l_result=oomtest_fill(_i*10,2);
664 :
665 : /* Check remaining RAM */
666 300 : i = (long)_i*10+50;
667 12061 : while ((NULL==(l_ptr=malloc(i--)))&&(i>0))
668 11761 : free(l_ptr);
669 :
670 300 : if (NULL!=l_ptr)
671 297 : free(l_ptr);
672 :
673 : /* Cleanup mess for next tests to succeed if not forked */
674 300 : oomtest_free();
675 300 : oomtest_disable();
676 :
677 : /* Check */
678 300 : ck_assert(l_result<=limit.rlim_cur);
679 300 : ck_assert((long)i>=(_i*10-4));
680 300 : ck_assert((long)i<=(_i*10+100));
681 300 : }
682 : END_TEST
683 :
684 45 : START_TEST(oomtest_config_enable_fill_twice)
685 : {
686 : struct rlimit limit;
687 : size_t l_avail;
688 :
689 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
690 : * whole testsuite if not caught or not in a child process */
691 45 : forktest_only;
692 :
693 : /* Find available physical RAM, 0 in case of failure */
694 30 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
695 :
696 : /* Configure a hard limit only if not already configured by non-forked
697 : * previous tests */
698 30 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
699 30 : ck_assert(limit.rlim_cur==limit.rlim_max);
700 30 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
701 30 : oomtest_config(l_avail);
702 :
703 : /* Update rlimit values */
704 30 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
705 30 : l_avail = limit.rlim_cur;
706 :
707 : /* Set soft limit */
708 30 : oomtest_enable(l_avail/2);
709 :
710 : /* Test fill */
711 30 : oomtest_fill(_i*10,2);
712 :
713 : /* SIGABRT6 expected */
714 30 : oomtest_fill(_i*10,2);
715 : }
716 : END_TEST
717 :
718 3 : START_TEST(oomtest_noconfig_noenable_free)
719 : {
720 : /* Should simply pass */
721 3 : oomtest_free();
722 3 : }
723 : END_TEST
724 :
725 3 : START_TEST(oomtest_config_noenable_free)
726 : {
727 : struct rlimit limit;
728 : size_t l_avail;
729 :
730 : /* Find available physical RAM, 0 in case of failure */
731 3 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
732 :
733 : /* Configure a hard limit only if not already configured by non-forked
734 : * previous tests */
735 3 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
736 3 : if (limit.rlim_max>l_avail)
737 2 : oomtest_config(l_avail);
738 :
739 : /* Should pass */
740 3 : oomtest_free();
741 3 : }
742 : END_TEST
743 :
744 3 : START_TEST(oomtest_config_enable_free)
745 : {
746 : struct rlimit limit;
747 : size_t l_avail;
748 :
749 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
750 : * whole testsuite if not caught or not in a child process */
751 3 : forktest_only;
752 :
753 : /* Find available physical RAM, 0 in case of failure */
754 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
755 :
756 : /* Configure a hard limit only if not already configured by non-forked
757 : * previous tests */
758 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
759 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
760 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
761 2 : oomtest_config(l_avail);
762 :
763 : /* Update rlimit values */
764 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
765 2 : l_avail = limit.rlim_cur;
766 :
767 : /* Set soft limit */
768 2 : oomtest_enable(l_avail/2);
769 :
770 : /* SIGABRT6 expected */
771 2 : oomtest_free();
772 : }
773 : END_TEST
774 :
775 3 : START_TEST(oomtest_config_enable_fill_free_twice)
776 : {
777 : struct rlimit limit;
778 : size_t l_avail;
779 :
780 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
781 : * whole testsuite if not caught or not in a child process */
782 3 : forktest_only;
783 :
784 : /* Find available physical RAM, 0 in case of failure */
785 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
786 :
787 : /* Configure a hard limit only if not already configured by non-forked
788 : * previous tests */
789 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
790 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
791 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
792 2 : oomtest_config(l_avail);
793 :
794 : /* Update rlimit values */
795 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
796 2 : l_avail = limit.rlim_cur;
797 :
798 : /* Set soft limit */
799 2 : oomtest_enable(l_avail/2);
800 :
801 : /* Fill RAM */
802 2 : oomtest_fill(_i*10,2);
803 :
804 : /* First cleanup */
805 2 : oomtest_free();
806 :
807 : /* SIGABRT6 expected */
808 2 : oomtest_free();
809 : }
810 : END_TEST
811 :
812 3 : START_TEST(oomtest_noconfig_noenable_disable)
813 : {
814 : struct rlimit limit;
815 : size_t l_avail;
816 :
817 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
818 : * whole testsuite if not caught or not in a child process */
819 3 : forktest_only;
820 :
821 : /* Find available physical RAM, 0 in case of failure */
822 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
823 :
824 : /* Configure a hard limit only if not already configured by non-forked
825 : * previous tests */
826 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
827 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
828 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
829 2 : oomtest_config(l_avail);
830 :
831 : /* Try to disable non enabled process, Should pass */
832 : /* SIGABRT6 expected */
833 2 : oomtest_disable();
834 : }
835 : END_TEST
836 :
837 3 : START_TEST(oomtest_config_enable_disable_twice)
838 : {
839 : struct rlimit limit;
840 : size_t l_avail;
841 :
842 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
843 : * whole testsuite if not caught or not in a child process */
844 3 : forktest_only;
845 :
846 : /* Find available physical RAM, 0 in case of failure */
847 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
848 :
849 : /* Configure a hard limit only if not already configured by non-forked
850 : * previous tests */
851 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
852 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
853 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
854 2 : oomtest_config(l_avail);
855 :
856 : /* Update rlimit values */
857 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
858 2 : l_avail = limit.rlim_cur;
859 :
860 : /* Set soft limit */
861 2 : oomtest_enable(l_avail/2);
862 :
863 : /* First disable, already tested */
864 2 : oomtest_disable();
865 :
866 : /* Second disable */
867 : /* SIGABRT6 expected */
868 2 : oomtest_disable();
869 : }
870 : END_TEST
871 :
872 45 : START_TEST(oomtest_config_enable_fill_disable)
873 : {
874 : struct rlimit limit;
875 : size_t l_avail;
876 :
877 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
878 : * whole testsuite if not caught or not in a child process */
879 45 : forktest_only;
880 :
881 : /* Find available physical RAM, 0 in case of failure */
882 30 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
883 :
884 : /* Configure a hard limit only if not already configured by non-forked
885 : * previous tests */
886 30 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
887 30 : ck_assert(limit.rlim_cur==limit.rlim_max);
888 30 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
889 30 : oomtest_config(l_avail);
890 :
891 : /* Update rlimit values */
892 30 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
893 30 : l_avail = limit.rlim_cur;
894 :
895 : /* Set soft limit */
896 30 : oomtest_enable(l_avail/2);
897 :
898 : #ifdef GCOV
899 : /* GCOV instrumentation will SIGSEGV otherwise under this RAM pressure */
900 30 : __gcov_dump();
901 : #endif
902 :
903 : /* Fill RAM */
904 0 : oomtest_fill(_i*10,2);
905 :
906 : /* SIGABRT6 expected */
907 0 : oomtest_disable();
908 : }
909 : END_TEST
910 :
911 45 : START_TEST(oomtest_config_enable_fill_config)
912 : {
913 : struct rlimit limit;
914 : size_t l_avail;
915 :
916 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
917 : * whole testsuite if not caught or not in a child process */
918 45 : forktest_only;
919 :
920 : /* Find available physical RAM, 0 in case of failure */
921 30 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
922 :
923 : /* Configure a hard limit only if not already configured by non-forked
924 : * previous tests */
925 30 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
926 30 : ck_assert(limit.rlim_cur==limit.rlim_max);
927 30 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
928 30 : oomtest_config(l_avail);
929 :
930 : /* Update rlimit values */
931 30 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
932 30 : l_avail = limit.rlim_cur;
933 :
934 : /* Set soft limit */
935 30 : oomtest_enable(l_avail/2);
936 :
937 : #ifdef GCOV
938 : /* GCOV instrumentation will SIGSEGV otherwise under this RAM pressure */
939 30 : __gcov_dump();
940 : #endif
941 :
942 : /* Fill RAM */
943 0 : oomtest_fill(_i*10,2);
944 :
945 : /* SIGABRT6 expected */
946 0 : oomtest_config(0);
947 : }
948 : END_TEST
949 :
950 3 : START_TEST(oomtest_config_enable_fill_hugeminheap)
951 : {
952 : struct rlimit limit;
953 : size_t l_avail;
954 :
955 : /* This test is supposed to trigger a SIGABRT(6) and will crash the
956 : * whole testsuite if not caught or not in a child process */
957 3 : forktest_only;
958 :
959 : /* Find available physical RAM, 0 in case of failure */
960 2 : l_avail = (sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
961 :
962 : /* Configure a hard limit only if not already configured by non-forked
963 : * previous tests */
964 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
965 2 : ck_assert(limit.rlim_cur==limit.rlim_max);
966 2 : l_avail=(limit.rlim_max<l_avail?limit.rlim_max:l_avail);
967 2 : oomtest_config(l_avail);
968 :
969 : /* Update rlimit values */
970 2 : ck_assert(0==getrlimit(RLIMIT_AS, &limit));
971 2 : l_avail = limit.rlim_cur;
972 :
973 : /* Set soft limit */
974 2 : oomtest_enable(l_avail/2);
975 :
976 : /* Test fill */
977 : /* SIGABRT6 expected */
978 2 : oomtest_fill(l_avail/2+1,2);
979 : }
980 : END_TEST
981 :
982 : /************************************************************************/
983 : /* Begining of test (potentially in child) */
984 522 : void oomtest_checked_uninitialized_setup()
985 : {
986 522 : signals_catch();
987 522 : forktest_gprofdir();
988 522 : }
989 :
990 : /* End of test (potentially in child) */
991 404 : void oomtest_checked_uninitialized_teardown()
992 : {
993 404 : signals_release();
994 404 : }
995 : /************************************************************************/
996 : /* Begining of test case */
997 351 : void oomtest_unchecked_setup()
998 : {
999 351 : forktest_init();
1000 351 : }
1001 : /* End of testcase */
1002 3 : void oomtest_unchecked_teardown()
1003 : {
1004 3 : }
1005 : /************************************************************************/
1006 355 : Suite* oomtest_suite()
1007 : {
1008 : Suite *s;
1009 : TCase *tc;
1010 :
1011 355 : s = suite_create("OOMTest");
1012 :
1013 355 : tc = tcase_create("Uninitialized");
1014 355 : tcase_set_tags(tc,"oom");
1015 : /* tcase_set_timeout(tc,5); */ /* seconds */
1016 355 : tcase_add_checked_fixture(tc, oomtest_checked_uninitialized_setup, oomtest_checked_uninitialized_teardown);
1017 355 : tcase_add_unchecked_fixture(tc, oomtest_unchecked_setup, oomtest_unchecked_teardown);
1018 355 : suite_add_tcase(s, tc);
1019 :
1020 355 : tcase_add_test(tc, oomtest_config_once_0);
1021 355 : tcase_add_test(tc, oomtest_config_once_max);
1022 355 : tcase_add_test_raise_signal(tc, oomtest_config_once_over,6);
1023 355 : tcase_add_test(tc, oomtest_config_once_value);
1024 355 : tcase_add_test(tc, oomtest_config_twice_same);
1025 355 : tcase_add_test_raise_signal(tc, oomtest_config_twice_up,6);
1026 355 : tcase_add_test(tc, oomtest_config_twice_down);
1027 355 : tcase_add_test_raise_signal(tc, oomtest_noconfig_enable_0,6);
1028 355 : tcase_add_test_raise_signal(tc, oomtest_noconfig_enable_value,6);
1029 355 : tcase_add_test_raise_signal(tc, oomtest_noconfig_enable_max,6);
1030 355 : tcase_add_test_raise_signal(tc, oomtest_noconfig_enable_over,6);
1031 355 : tcase_add_test(tc, oomtest_config_enable_0);
1032 355 : tcase_add_test(tc, oomtest_config_enable_value);
1033 355 : tcase_add_test(tc, oomtest_config_enable_max);
1034 355 : tcase_add_test_raise_signal(tc, oomtest_config_enable_over,6);
1035 355 : tcase_add_test(tc, oomtest_config_enable_twice_same);
1036 355 : tcase_add_test(tc, oomtest_config_enable_twice_up);
1037 355 : tcase_add_test(tc, oomtest_config_enable_twice_down);
1038 355 : tcase_add_test_raise_signal(tc, oomtest_noconfig_disable,6);
1039 355 : tcase_add_test_raise_signal(tc, oomtest_config_noenable_disable,6);
1040 355 : tcase_add_test(tc, oomtest_config_enable_disable);
1041 355 : tcase_add_test(tc, oomtest_noconfig_noenable_fill);
1042 355 : tcase_add_loop_test(tc, oomtest_config_enable_fill_minheap,0,100);
1043 355 : tcase_add_loop_test_raise_signal(tc, oomtest_config_enable_fill_twice,6,0,15);
1044 355 : tcase_add_test(tc, oomtest_noconfig_noenable_free);
1045 355 : tcase_add_test(tc, oomtest_config_noenable_free);
1046 355 : tcase_add_test_raise_signal(tc, oomtest_config_enable_free,6);
1047 355 : tcase_add_test_raise_signal(tc, oomtest_config_enable_fill_free_twice,6);
1048 355 : tcase_add_test_raise_signal(tc, oomtest_noconfig_noenable_disable,6);
1049 355 : tcase_add_test_raise_signal(tc, oomtest_config_enable_disable_twice,6);
1050 355 : tcase_add_loop_test_raise_signal(tc, oomtest_config_enable_fill_disable,6,0,15);
1051 355 : tcase_add_loop_test_raise_signal(tc, oomtest_config_enable_fill_config,6,0,15);
1052 355 : tcase_add_test_raise_signal(tc, oomtest_config_enable_fill_hugeminheap,6);
1053 355 : return s;
1054 : }
|