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