xref: /freebsd/contrib/pkgconf/tests/api/oom.h (revision 592efe252472a3385acf36b1f49ecf710a7f3d9c)
1*592efe25SPierre Pronchery /*
2*592efe25SPierre Pronchery  * oom.h
3*592efe25SPierre Pronchery  * Exhaustive allocation-failure test driver, built on the fuzzer/alloc-inject
4*592efe25SPierre Pronchery  * fault injector.
5*592efe25SPierre Pronchery  *
6*592efe25SPierre Pronchery  * SPDX-License-Identifier: pkgconf
7*592efe25SPierre Pronchery  *
8*592efe25SPierre Pronchery  * Copyright (c) 2026 pkgconf authors (see AUTHORS).
9*592efe25SPierre Pronchery  *
10*592efe25SPierre Pronchery  * Permission to use, copy, modify, and/or distribute this software for any
11*592efe25SPierre Pronchery  * purpose with or without fee is hereby granted, provided that the above
12*592efe25SPierre Pronchery  * copyright notice and this permission notice appear in all copies.
13*592efe25SPierre Pronchery  *
14*592efe25SPierre Pronchery  * This software is provided 'as is' and without any warranty, express or
15*592efe25SPierre Pronchery  * implied.  In no event shall the authors be liable for any damages arising
16*592efe25SPierre Pronchery  * from the use of this software.
17*592efe25SPierre Pronchery  */
18*592efe25SPierre Pronchery 
19*592efe25SPierre Pronchery #ifndef TEST_API_OOM_H
20*592efe25SPierre Pronchery #define TEST_API_OOM_H
21*592efe25SPierre Pronchery 
22*592efe25SPierre Pronchery #include "test-api.h"
23*592efe25SPierre Pronchery #include "alloc-inject.h"
24*592efe25SPierre Pronchery 
25*592efe25SPierre Pronchery /*
26*592efe25SPierre Pronchery  * Exhaustively fail each successive allocation an expression makes until it can
27*592efe25SPierre Pronchery  * complete with none failing.  Every injected failure must be reported
28*592efe25SPierre Pronchery  * gracefully (NULL for OOM_TEST_PTR, false for OOM_TEST_BOOL); on the run where
29*592efe25SPierre Pronchery  * no allocation fails the value succeeds and the loop ends.  Under ASAN this
30*592efe25SPierre Pronchery  * also asserts each partial-construction error path leaks nothing.
31*592efe25SPierre Pronchery  */
32*592efe25SPierre Pronchery #define OOM_TEST_PTR(objvar, make_expr, free_stmt)	\
33*592efe25SPierre Pronchery 	do {	\
34*592efe25SPierre Pronchery 		for (unsigned long _oom_n = 1; ; _oom_n++)	\
35*592efe25SPierre Pronchery 		{	\
36*592efe25SPierre Pronchery 			alloc_inject_arm(_oom_n);	\
37*592efe25SPierre Pronchery 			(objvar) = (make_expr);	\
38*592efe25SPierre Pronchery 			bool _oom_f = alloc_inject_fired();	\
39*592efe25SPierre Pronchery 			alloc_inject_disarm();	\
40*592efe25SPierre Pronchery 			if (!_oom_f) { free_stmt; break; }	\
41*592efe25SPierre Pronchery 			TEST_ASSERT_NULL(objvar);	\
42*592efe25SPierre Pronchery 			free_stmt;	\
43*592efe25SPierre Pronchery 		}	\
44*592efe25SPierre Pronchery 	} while (0)
45*592efe25SPierre Pronchery 
46*592efe25SPierre Pronchery #define OOM_TEST_BOOL(make_expr)	\
47*592efe25SPierre Pronchery 	do {	\
48*592efe25SPierre Pronchery 		for (unsigned long _oom_n = 1; ; _oom_n++)	\
49*592efe25SPierre Pronchery 		{	\
50*592efe25SPierre Pronchery 			alloc_inject_arm(_oom_n);	\
51*592efe25SPierre Pronchery 			bool _oom_ok = (make_expr);	\
52*592efe25SPierre Pronchery 			bool _oom_f = alloc_inject_fired();	\
53*592efe25SPierre Pronchery 			alloc_inject_disarm();	\
54*592efe25SPierre Pronchery 			if (!_oom_f) { TEST_ASSERT_TRUE(_oom_ok); break; }	\
55*592efe25SPierre Pronchery 			TEST_ASSERT_FALSE(_oom_ok);	\
56*592efe25SPierre Pronchery 		}	\
57*592efe25SPierre Pronchery 	} while (0)
58*592efe25SPierre Pronchery 
59*592efe25SPierre Pronchery #endif // TEST_API_OOM_H
60