]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / test / test-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
539ad707
TA
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6 Copyright 2013 Thomas H.P. Andersen
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
618234a5 22#include <errno.h>
618234a5 23#include <string.h>
8852362b 24#include <sys/wait.h>
618234a5 25#include <unistd.h>
539ad707 26
65b3903f
ZJS
27#include "def.h"
28#include "fileio.h"
f4f15635 29#include "fs-util.h"
d9ab2bcf 30#include "parse-util.h"
8869a0b4 31#include "raw-clone.h"
618234a5 32#include "rm-rf.h"
07630cea 33#include "string-util.h"
618234a5 34#include "util.h"
539ad707 35
625e870b
DH
36static void test_align_power2(void) {
37 unsigned long i, p2;
38
39 assert_se(ALIGN_POWER2(0) == 0);
40 assert_se(ALIGN_POWER2(1) == 1);
41 assert_se(ALIGN_POWER2(2) == 2);
42 assert_se(ALIGN_POWER2(3) == 4);
43 assert_se(ALIGN_POWER2(12) == 16);
44
45 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
46 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
47 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
48 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
49 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
50
51 for (i = 1; i < 131071; ++i) {
52 for (p2 = 1; p2 < i; p2 <<= 1)
53 /* empty */ ;
54
55 assert_se(ALIGN_POWER2(i) == p2);
56 }
57
58 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
59 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
60 /* empty */ ;
61
62 assert_se(ALIGN_POWER2(i) == p2);
63 }
64}
65
7242d742
DH
66static void test_max(void) {
67 static const struct {
68 int a;
69 int b[CONST_MAX(10, 100)];
70 } val1 = {
71 .a = CONST_MAX(10, 100),
72 };
73 int d = 0;
74
75 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
76
77 /* CONST_MAX returns (void) instead of a value if the passed arguments
78 * are not of the same type or not constant expressions. */
79 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
7242d742
DH
80 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
81
82 assert_se(val1.a == 100);
83 assert_se(MAX(++d, 0) == 1);
84 assert_se(d == 1);
40a1eebd
DH
85
86 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
87 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
88 assert_cc(MAXSIZE(char, long) == sizeof(long));
667a0377
DH
89
90 assert_se(MAX(-5, 5) == 5);
91 assert_se(MAX(5, 5) == 5);
92 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
93 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
94 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
95 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
96 assert_se(LESS_BY(8, 4) == 4);
97 assert_se(LESS_BY(8, 8) == 0);
98 assert_se(LESS_BY(4, 8) == 0);
99 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
100 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
101 assert_se(CLAMP(-5, 0, 1) == 0);
102 assert_se(CLAMP(5, 0, 1) == 1);
103 assert_se(CLAMP(5, -10, 1) == 1);
104 assert_se(CLAMP(5, -10, 10) == 5);
105 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
7242d742
DH
106}
107
09571e3f
ZJS
108#pragma GCC diagnostic push
109#ifdef __clang__
110# pragma GCC diagnostic ignored "-Waddress-of-packed-member"
111#endif
112
fb835651
DH
113static void test_container_of(void) {
114 struct mytype {
115 uint8_t pad1[3];
116 uint64_t v1;
117 uint8_t pad2[2];
118 uint32_t v2;
119 } _packed_ myval = { };
120
121 assert_cc(sizeof(myval) == 17);
122 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
123 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
124 assert_se(container_of(&container_of(&myval.v2,
125 struct mytype,
126 v2)->v1,
127 struct mytype,
128 v1) == &myval);
129}
130
09571e3f
ZJS
131#pragma GCC diagnostic pop
132
180a60bc
DH
133static void test_div_round_up(void) {
134 int div;
135
136 /* basic tests */
137 assert_se(DIV_ROUND_UP(0, 8) == 0);
138 assert_se(DIV_ROUND_UP(1, 8) == 1);
139 assert_se(DIV_ROUND_UP(8, 8) == 1);
140 assert_se(DIV_ROUND_UP(12, 8) == 2);
141 assert_se(DIV_ROUND_UP(16, 8) == 2);
142
143 /* test multiple evaluation */
144 div = 0;
145 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
146 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
147 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
148 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
149
150 /* overflow test with exact division */
151 assert_se(sizeof(0U) == 4);
152 assert_se(0xfffffffaU % 10U == 0U);
153 assert_se(0xfffffffaU / 10U == 429496729U);
154 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
155 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
156 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
157
158 /* overflow test with rounded division */
159 assert_se(0xfffffffdU % 10U == 3U);
160 assert_se(0xfffffffdU / 10U == 429496729U);
161 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
162 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
163 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
164}
165
144e51ec 166static void test_u64log2(void) {
bdf7026e
TA
167 assert_se(u64log2(0) == 0);
168 assert_se(u64log2(8) == 3);
169 assert_se(u64log2(9) == 3);
170 assert_se(u64log2(15) == 3);
171 assert_se(u64log2(16) == 4);
172 assert_se(u64log2(1024*1024) == 20);
173 assert_se(u64log2(1024*1024+5) == 20);
144e51ec
CR
174}
175
2a371001
ZJS
176static void test_protect_errno(void) {
177 errno = 12;
178 {
179 PROTECT_ERRNO;
180 errno = 11;
181 }
bdf7026e 182 assert_se(errno == 12);
2a371001
ZJS
183}
184
cabb7806
LP
185static void test_in_set(void) {
186 assert_se(IN_SET(1, 1));
187 assert_se(IN_SET(1, 1, 2, 3, 4));
188 assert_se(IN_SET(2, 1, 2, 3, 4));
189 assert_se(IN_SET(3, 1, 2, 3, 4));
190 assert_se(IN_SET(4, 1, 2, 3, 4));
191 assert_se(!IN_SET(0, 1));
192 assert_se(!IN_SET(0, 1, 2, 3, 4));
193}
194
8fe90522
ZJS
195static void test_log2i(void) {
196 assert_se(log2i(1) == 0);
197 assert_se(log2i(2) == 1);
198 assert_se(log2i(3) == 1);
199 assert_se(log2i(4) == 2);
200 assert_se(log2i(32) == 5);
201 assert_se(log2i(33) == 5);
202 assert_se(log2i(63) == 5);
203 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
204}
205
ee05e779
ZJS
206static void test_raw_clone(void) {
207 pid_t parent, pid, pid2;
208
209 parent = getpid();
210 log_info("before clone: getpid()→"PID_FMT, parent);
211 assert_se(raw_getpid() == parent);
212
8869a0b4 213 pid = raw_clone(0);
e50221bf 214 assert_se(pid >= 0);
ee05e779
ZJS
215
216 pid2 = raw_getpid();
217 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
218 pid, getpid(), pid2);
0289a5bc 219 if (pid == 0) {
e50221bf 220 assert_se(pid2 != parent);
0289a5bc
FB
221 _exit(EXIT_SUCCESS);
222 } else {
223 int status;
224
e50221bf 225 assert_se(pid2 == parent);
0289a5bc
FB
226 waitpid(pid, &status, __WCLONE);
227 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
228 }
ee05e779
ZJS
229}
230
d9ab2bcf
LP
231static void test_physical_memory(void) {
232 uint64_t p;
233 char buf[FORMAT_BYTES_MAX];
234
235 p = physical_memory();
236 assert_se(p > 0);
237 assert_se(p < UINT64_MAX);
238 assert_se(p % page_size() == 0);
239
d8cf2ac7
LP
240 log_info("Memory: %s (%" PRIu64 ")", format_bytes(buf, sizeof(buf), p), p);
241}
242
243static void test_physical_memory_scale(void) {
244 uint64_t p;
245
246 p = physical_memory();
247
248 assert_se(physical_memory_scale(0, 100) == 0);
249 assert_se(physical_memory_scale(100, 100) == p);
250
251 log_info("Memory original: %" PRIu64, physical_memory());
252 log_info("Memory scaled by 50%%: %" PRIu64, physical_memory_scale(50, 100));
253 log_info("Memory divided by 2: %" PRIu64, physical_memory() / 2);
254 log_info("Page size: %zu", page_size());
255
256 /* There might be an uneven number of pages, hence permit these calculations to be half a page off... */
257 assert_se(page_size()/2 + physical_memory_scale(50, 100) - p/2 <= page_size());
258 assert_se(physical_memory_scale(200, 100) == p*2);
259
260 assert_se(physical_memory_scale(0, 1) == 0);
261 assert_se(physical_memory_scale(1, 1) == p);
262 assert_se(physical_memory_scale(2, 1) == p*2);
263
264 assert_se(physical_memory_scale(0, 2) == 0);
265
266 assert_se(page_size()/2 + physical_memory_scale(1, 2) - p/2 <= page_size());
267 assert_se(physical_memory_scale(2, 2) == p);
268 assert_se(physical_memory_scale(4, 2) == p*2);
269
270 assert_se(physical_memory_scale(0, UINT32_MAX) == 0);
271 assert_se(physical_memory_scale(UINT32_MAX, UINT32_MAX) == p);
272
273 /* overflow */
274 assert_se(physical_memory_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
83f8e808
LP
275}
276
277static void test_system_tasks_max(void) {
278 uint64_t t;
279
280 t = system_tasks_max();
281 assert_se(t > 0);
282 assert_se(t < UINT64_MAX);
283
284 log_info("Max tasks: %" PRIu64, t);
285}
286
287static void test_system_tasks_max_scale(void) {
288 uint64_t t;
289
290 t = system_tasks_max();
291
292 assert_se(system_tasks_max_scale(0, 100) == 0);
293 assert_se(system_tasks_max_scale(100, 100) == t);
294
295 assert_se(system_tasks_max_scale(0, 1) == 0);
296 assert_se(system_tasks_max_scale(1, 1) == t);
297 assert_se(system_tasks_max_scale(2, 1) == 2*t);
298
299 assert_se(system_tasks_max_scale(0, 2) == 0);
300 assert_se(system_tasks_max_scale(1, 2) == t/2);
301 assert_se(system_tasks_max_scale(2, 2) == t);
302 assert_se(system_tasks_max_scale(3, 2) == (3*t)/2);
303 assert_se(system_tasks_max_scale(4, 2) == t*2);
304
305 assert_se(system_tasks_max_scale(0, UINT32_MAX) == 0);
306 assert_se(system_tasks_max_scale((UINT32_MAX-1)/2, UINT32_MAX-1) == t/2);
307 assert_se(system_tasks_max_scale(UINT32_MAX, UINT32_MAX) == t);
308
309 /* overflow */
d8cf2ac7 310
83f8e808 311 assert_se(system_tasks_max_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
d9ab2bcf
LP
312}
313
539ad707 314int main(int argc, char *argv[]) {
9480794b
ZJS
315 log_parse_environment();
316 log_open();
317
625e870b 318 test_align_power2();
7242d742 319 test_max();
fb835651 320 test_container_of();
180a60bc 321 test_div_round_up();
144e51ec 322 test_u64log2();
2a371001 323 test_protect_errno();
cabb7806 324 test_in_set();
8fe90522 325 test_log2i();
ee05e779 326 test_raw_clone();
d9ab2bcf 327 test_physical_memory();
d8cf2ac7 328 test_physical_memory_scale();
83f8e808
LP
329 test_system_tasks_max();
330 test_system_tasks_max_scale();
539ad707
TA
331
332 return 0;
333}