]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
util-lib: Add sparc64 support for process creation (#3348)
[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"
8869a0b4 29#include "raw-clone.h"
618234a5 30#include "rm-rf.h"
07630cea 31#include "string-util.h"
618234a5 32#include "util.h"
539ad707 33
625e870b
DH
34static void test_align_power2(void) {
35 unsigned long i, p2;
36
37 assert_se(ALIGN_POWER2(0) == 0);
38 assert_se(ALIGN_POWER2(1) == 1);
39 assert_se(ALIGN_POWER2(2) == 2);
40 assert_se(ALIGN_POWER2(3) == 4);
41 assert_se(ALIGN_POWER2(12) == 16);
42
43 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
44 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
45 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
46 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
47 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
48
49 for (i = 1; i < 131071; ++i) {
50 for (p2 = 1; p2 < i; p2 <<= 1)
51 /* empty */ ;
52
53 assert_se(ALIGN_POWER2(i) == p2);
54 }
55
56 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
57 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
58 /* empty */ ;
59
60 assert_se(ALIGN_POWER2(i) == p2);
61 }
62}
63
7242d742
DH
64static void test_max(void) {
65 static const struct {
66 int a;
67 int b[CONST_MAX(10, 100)];
68 } val1 = {
69 .a = CONST_MAX(10, 100),
70 };
71 int d = 0;
72
73 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
74
75 /* CONST_MAX returns (void) instead of a value if the passed arguments
76 * are not of the same type or not constant expressions. */
77 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
7242d742
DH
78 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
79
80 assert_se(val1.a == 100);
81 assert_se(MAX(++d, 0) == 1);
82 assert_se(d == 1);
40a1eebd
DH
83
84 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
85 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
86 assert_cc(MAXSIZE(char, long) == sizeof(long));
667a0377
DH
87
88 assert_se(MAX(-5, 5) == 5);
89 assert_se(MAX(5, 5) == 5);
90 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
91 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
92 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
93 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
94 assert_se(LESS_BY(8, 4) == 4);
95 assert_se(LESS_BY(8, 8) == 0);
96 assert_se(LESS_BY(4, 8) == 0);
97 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
98 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
99 assert_se(CLAMP(-5, 0, 1) == 0);
100 assert_se(CLAMP(5, 0, 1) == 1);
101 assert_se(CLAMP(5, -10, 1) == 1);
102 assert_se(CLAMP(5, -10, 10) == 5);
103 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
7242d742
DH
104}
105
fb835651
DH
106static void test_container_of(void) {
107 struct mytype {
108 uint8_t pad1[3];
109 uint64_t v1;
110 uint8_t pad2[2];
111 uint32_t v2;
112 } _packed_ myval = { };
113
114 assert_cc(sizeof(myval) == 17);
115 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
116 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
117 assert_se(container_of(&container_of(&myval.v2,
118 struct mytype,
119 v2)->v1,
120 struct mytype,
121 v1) == &myval);
122}
123
180a60bc
DH
124static void test_div_round_up(void) {
125 int div;
126
127 /* basic tests */
128 assert_se(DIV_ROUND_UP(0, 8) == 0);
129 assert_se(DIV_ROUND_UP(1, 8) == 1);
130 assert_se(DIV_ROUND_UP(8, 8) == 1);
131 assert_se(DIV_ROUND_UP(12, 8) == 2);
132 assert_se(DIV_ROUND_UP(16, 8) == 2);
133
134 /* test multiple evaluation */
135 div = 0;
136 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
137 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
138 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
139 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
140
141 /* overflow test with exact division */
142 assert_se(sizeof(0U) == 4);
143 assert_se(0xfffffffaU % 10U == 0U);
144 assert_se(0xfffffffaU / 10U == 429496729U);
145 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
146 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
147 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
148
149 /* overflow test with rounded division */
150 assert_se(0xfffffffdU % 10U == 3U);
151 assert_se(0xfffffffdU / 10U == 429496729U);
152 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
153 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
154 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
155}
156
144e51ec 157static void test_u64log2(void) {
bdf7026e
TA
158 assert_se(u64log2(0) == 0);
159 assert_se(u64log2(8) == 3);
160 assert_se(u64log2(9) == 3);
161 assert_se(u64log2(15) == 3);
162 assert_se(u64log2(16) == 4);
163 assert_se(u64log2(1024*1024) == 20);
164 assert_se(u64log2(1024*1024+5) == 20);
144e51ec
CR
165}
166
2a371001
ZJS
167static void test_protect_errno(void) {
168 errno = 12;
169 {
170 PROTECT_ERRNO;
171 errno = 11;
172 }
bdf7026e 173 assert_se(errno == 12);
2a371001
ZJS
174}
175
cabb7806
LP
176static void test_in_set(void) {
177 assert_se(IN_SET(1, 1));
178 assert_se(IN_SET(1, 1, 2, 3, 4));
179 assert_se(IN_SET(2, 1, 2, 3, 4));
180 assert_se(IN_SET(3, 1, 2, 3, 4));
181 assert_se(IN_SET(4, 1, 2, 3, 4));
182 assert_se(!IN_SET(0, 1));
183 assert_se(!IN_SET(0, 1, 2, 3, 4));
184}
185
8fe90522
ZJS
186static void test_log2i(void) {
187 assert_se(log2i(1) == 0);
188 assert_se(log2i(2) == 1);
189 assert_se(log2i(3) == 1);
190 assert_se(log2i(4) == 2);
191 assert_se(log2i(32) == 5);
192 assert_se(log2i(33) == 5);
193 assert_se(log2i(63) == 5);
194 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
195}
196
8852362b 197static void test_execute_directory(void) {
aac7766c
ZJS
198 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
199 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
76f282c6 200 const char * dirs[] = {template_hi, template_lo, NULL};
aac7766c
ZJS
201 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
202
203 assert_se(mkdtemp(template_lo));
204 assert_se(mkdtemp(template_hi));
205
63c372cb
LP
206 name = strjoina(template_lo, "/script");
207 name2 = strjoina(template_hi, "/script2");
208 name3 = strjoina(template_lo, "/useless");
209 overridden = strjoina(template_lo, "/overridden");
210 override = strjoina(template_hi, "/overridden");
211 masked = strjoina(template_lo, "/masked");
212 mask = strjoina(template_hi, "/masked");
e801700e 213
4c1fc3e4
DM
214 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0);
215 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0);
216 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
217 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0);
218 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
aac7766c 219 assert_se(symlink("/dev/null", mask) == 0);
8852362b
RC
220 assert_se(chmod(name, 0755) == 0);
221 assert_se(chmod(name2, 0755) == 0);
aac7766c
ZJS
222 assert_se(chmod(overridden, 0755) == 0);
223 assert_se(chmod(override, 0755) == 0);
224 assert_se(chmod(masked, 0755) == 0);
8852362b
RC
225 assert_se(touch(name3) >= 0);
226
e801700e 227 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
aac7766c 228
0c0cdb06 229 assert_se(chdir(template_lo) == 0);
e801700e 230 assert_se(access("it_works", F_OK) >= 0);
aac7766c
ZJS
231 assert_se(access("failed", F_OK) < 0);
232
0c0cdb06 233 assert_se(chdir(template_hi) == 0);
e801700e 234 assert_se(access("it_works2", F_OK) >= 0);
aac7766c 235 assert_se(access("failed", F_OK) < 0);
8852362b 236
c6878637
LP
237 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
238 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
8852362b
RC
239}
240
ee05e779
ZJS
241static void test_raw_clone(void) {
242 pid_t parent, pid, pid2;
243
244 parent = getpid();
245 log_info("before clone: getpid()→"PID_FMT, parent);
246 assert_se(raw_getpid() == parent);
247
8869a0b4 248 pid = raw_clone(0);
e50221bf 249 assert_se(pid >= 0);
ee05e779
ZJS
250
251 pid2 = raw_getpid();
252 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
253 pid, getpid(), pid2);
0289a5bc 254 if (pid == 0) {
e50221bf 255 assert_se(pid2 != parent);
0289a5bc
FB
256 _exit(EXIT_SUCCESS);
257 } else {
258 int status;
259
e50221bf 260 assert_se(pid2 == parent);
0289a5bc
FB
261 waitpid(pid, &status, __WCLONE);
262 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
263 }
ee05e779
ZJS
264}
265
539ad707 266int main(int argc, char *argv[]) {
9480794b
ZJS
267 log_parse_environment();
268 log_open();
269
625e870b 270 test_align_power2();
7242d742 271 test_max();
fb835651 272 test_container_of();
180a60bc 273 test_div_round_up();
144e51ec 274 test_u64log2();
2a371001 275 test_protect_errno();
cabb7806 276 test_in_set();
8fe90522 277 test_log2i();
8852362b 278 test_execute_directory();
ee05e779 279 test_raw_clone();
539ad707
TA
280
281 return 0;
282}