]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-util.c
2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Thomas H.P. Andersen
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.
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.
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/>.
24 #include <sys/types.h>
26 #include <sys/xattr.h>
29 #include "alloc-util.h"
34 #include "glob-util.h"
36 #include "parse-util.h"
37 #include "path-util.h"
38 #include "process-util.h"
41 #include "string-util.h"
45 #include "xattr-util.h"
47 static void test_align_power2(void) {
50 assert_se(ALIGN_POWER2(0) == 0);
51 assert_se(ALIGN_POWER2(1) == 1);
52 assert_se(ALIGN_POWER2(2) == 2);
53 assert_se(ALIGN_POWER2(3) == 4);
54 assert_se(ALIGN_POWER2(12) == 16);
56 assert_se(ALIGN_POWER2(ULONG_MAX
) == 0);
57 assert_se(ALIGN_POWER2(ULONG_MAX
- 1) == 0);
58 assert_se(ALIGN_POWER2(ULONG_MAX
- 1024) == 0);
59 assert_se(ALIGN_POWER2(ULONG_MAX
/ 2) == ULONG_MAX
/ 2 + 1);
60 assert_se(ALIGN_POWER2(ULONG_MAX
+ 1) == 0);
62 for (i
= 1; i
< 131071; ++i
) {
63 for (p2
= 1; p2
< i
; p2
<<= 1)
66 assert_se(ALIGN_POWER2(i
) == p2
);
69 for (i
= ULONG_MAX
- 1024; i
< ULONG_MAX
; ++i
) {
70 for (p2
= 1; p2
&& p2
< i
; p2
<<= 1)
73 assert_se(ALIGN_POWER2(i
) == p2
);
77 static void test_max(void) {
80 int b
[CONST_MAX(10, 100)];
82 .a
= CONST_MAX(10, 100),
86 assert_cc(sizeof(val1
.b
) == sizeof(int) * 100);
88 /* CONST_MAX returns (void) instead of a value if the passed arguments
89 * are not of the same type or not constant expressions. */
90 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
91 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
93 assert_se(val1
.a
== 100);
94 assert_se(MAX(++d
, 0) == 1);
97 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
98 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
99 assert_cc(MAXSIZE(char, long) == sizeof(long));
101 assert_se(MAX(-5, 5) == 5);
102 assert_se(MAX(5, 5) == 5);
103 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
104 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
105 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
106 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
107 assert_se(LESS_BY(8, 4) == 4);
108 assert_se(LESS_BY(8, 8) == 0);
109 assert_se(LESS_BY(4, 8) == 0);
110 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
111 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
112 assert_se(CLAMP(-5, 0, 1) == 0);
113 assert_se(CLAMP(5, 0, 1) == 1);
114 assert_se(CLAMP(5, -10, 1) == 1);
115 assert_se(CLAMP(5, -10, 10) == 5);
116 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
119 static void test_container_of(void) {
125 } _packed_ myval
= { };
127 assert_cc(sizeof(myval
) == 17);
128 assert_se(container_of(&myval
.v1
, struct mytype
, v1
) == &myval
);
129 assert_se(container_of(&myval
.v2
, struct mytype
, v2
) == &myval
);
130 assert_se(container_of(&container_of(&myval
.v2
,
137 static void test_div_round_up(void) {
141 assert_se(DIV_ROUND_UP(0, 8) == 0);
142 assert_se(DIV_ROUND_UP(1, 8) == 1);
143 assert_se(DIV_ROUND_UP(8, 8) == 1);
144 assert_se(DIV_ROUND_UP(12, 8) == 2);
145 assert_se(DIV_ROUND_UP(16, 8) == 2);
147 /* test multiple evaluation */
149 assert_se(DIV_ROUND_UP(div
++, 8) == 0 && div
== 1);
150 assert_se(DIV_ROUND_UP(++div
, 8) == 1 && div
== 2);
151 assert_se(DIV_ROUND_UP(8, div
++) == 4 && div
== 3);
152 assert_se(DIV_ROUND_UP(8, ++div
) == 2 && div
== 4);
154 /* overflow test with exact division */
155 assert_se(sizeof(0U) == 4);
156 assert_se(0xfffffffaU
% 10U == 0U);
157 assert_se(0xfffffffaU
/ 10U == 429496729U);
158 assert_se(DIV_ROUND_UP(0xfffffffaU
, 10U) == 429496729U);
159 assert_se((0xfffffffaU
+ 10U - 1U) / 10U == 0U);
160 assert_se(0xfffffffaU
/ 10U + !!(0xfffffffaU
% 10U) == 429496729U);
162 /* overflow test with rounded division */
163 assert_se(0xfffffffdU
% 10U == 3U);
164 assert_se(0xfffffffdU
/ 10U == 429496729U);
165 assert_se(DIV_ROUND_UP(0xfffffffdU
, 10U) == 429496730U);
166 assert_se((0xfffffffdU
+ 10U - 1U) / 10U == 0U);
167 assert_se(0xfffffffdU
/ 10U + !!(0xfffffffdU
% 10U) == 429496730U);
170 static void test_u64log2(void) {
171 assert_se(u64log2(0) == 0);
172 assert_se(u64log2(8) == 3);
173 assert_se(u64log2(9) == 3);
174 assert_se(u64log2(15) == 3);
175 assert_se(u64log2(16) == 4);
176 assert_se(u64log2(1024*1024) == 20);
177 assert_se(u64log2(1024*1024+5) == 20);
180 static void test_protect_errno(void) {
186 assert_se(errno
== 12);
189 static void test_in_set(void) {
190 assert_se(IN_SET(1, 1));
191 assert_se(IN_SET(1, 1, 2, 3, 4));
192 assert_se(IN_SET(2, 1, 2, 3, 4));
193 assert_se(IN_SET(3, 1, 2, 3, 4));
194 assert_se(IN_SET(4, 1, 2, 3, 4));
195 assert_se(!IN_SET(0, 1));
196 assert_se(!IN_SET(0, 1, 2, 3, 4));
199 static void test_log2i(void) {
200 assert_se(log2i(1) == 0);
201 assert_se(log2i(2) == 1);
202 assert_se(log2i(3) == 1);
203 assert_se(log2i(4) == 2);
204 assert_se(log2i(32) == 5);
205 assert_se(log2i(33) == 5);
206 assert_se(log2i(63) == 5);
207 assert_se(log2i(INT_MAX
) == sizeof(int)*8-2);
210 static void test_glob_exists(void) {
211 char name
[] = "/tmp/test-glob_exists.XXXXXX";
215 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
219 r
= glob_exists("/tmp/test-glob_exists*");
224 r
= glob_exists("/tmp/test-glob_exists*");
228 static void test_execute_directory(void) {
229 char template_lo
[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
230 char template_hi
[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
231 const char * dirs
[] = {template_hi
, template_lo
, NULL
};
232 const char *name
, *name2
, *name3
, *overridden
, *override
, *masked
, *mask
;
234 assert_se(mkdtemp(template_lo
));
235 assert_se(mkdtemp(template_hi
));
237 name
= strjoina(template_lo
, "/script");
238 name2
= strjoina(template_hi
, "/script2");
239 name3
= strjoina(template_lo
, "/useless");
240 overridden
= strjoina(template_lo
, "/overridden");
241 override
= strjoina(template_hi
, "/overridden");
242 masked
= strjoina(template_lo
, "/masked");
243 mask
= strjoina(template_hi
, "/masked");
245 assert_se(write_string_file(name
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE
) == 0);
246 assert_se(write_string_file(name2
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE
) == 0);
247 assert_se(write_string_file(overridden
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE
) == 0);
248 assert_se(write_string_file(override
, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE
) == 0);
249 assert_se(write_string_file(masked
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE
) == 0);
250 assert_se(symlink("/dev/null", mask
) == 0);
251 assert_se(chmod(name
, 0755) == 0);
252 assert_se(chmod(name2
, 0755) == 0);
253 assert_se(chmod(overridden
, 0755) == 0);
254 assert_se(chmod(override
, 0755) == 0);
255 assert_se(chmod(masked
, 0755) == 0);
256 assert_se(touch(name3
) >= 0);
258 execute_directories(dirs
, DEFAULT_TIMEOUT_USEC
, NULL
);
260 assert_se(chdir(template_lo
) == 0);
261 assert_se(access("it_works", F_OK
) >= 0);
262 assert_se(access("failed", F_OK
) < 0);
264 assert_se(chdir(template_hi
) == 0);
265 assert_se(access("it_works2", F_OK
) >= 0);
266 assert_se(access("failed", F_OK
) < 0);
268 (void) rm_rf(template_lo
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
269 (void) rm_rf(template_hi
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
272 static void test_raw_clone(void) {
273 pid_t parent
, pid
, pid2
;
276 log_info("before clone: getpid()→"PID_FMT
, parent
);
277 assert_se(raw_getpid() == parent
);
279 pid
= raw_clone(0, NULL
);
283 log_info("raw_clone: "PID_FMT
" getpid()→"PID_FMT
" raw_getpid()→"PID_FMT
,
284 pid
, getpid(), pid2
);
286 assert_se(pid2
!= parent
);
291 assert_se(pid2
== parent
);
292 waitpid(pid
, &status
, __WCLONE
);
293 assert_se(WIFEXITED(status
) && WEXITSTATUS(status
) == EXIT_SUCCESS
);
297 static void test_fgetxattrat_fake(void) {
298 char t
[] = "/var/tmp/xattrtestXXXXXX";
299 _cleanup_close_
int fd
= -1;
304 assert_se(mkdtemp(t
));
305 x
= strjoina(t
, "/test");
306 assert_se(touch(x
) >= 0);
308 r
= setxattr(x
, "user.foo", "bar", 3, 0);
309 if (r
< 0 && errno
== EOPNOTSUPP
) /* no xattrs supported on /var/tmp... */
313 fd
= open(t
, O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
|O_NOCTTY
);
316 assert_se(fgetxattrat_fake(fd
, "test", "user.foo", v
, 3, 0) >= 0);
317 assert_se(memcmp(v
, "bar", 3) == 0);
320 fd
= open("/", O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
|O_NOCTTY
);
322 assert_se(fgetxattrat_fake(fd
, "usr", "user.idontexist", v
, 3, 0) == -ENODATA
);
325 assert_se(unlink(x
) >= 0);
326 assert_se(rmdir(t
) >= 0);
329 int main(int argc
, char *argv
[]) {
330 log_parse_environment();
338 test_protect_errno();
342 test_execute_directory();
344 test_fgetxattrat_fake();