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