chiark / gitweb /
Prep v233.3: Add all possible coverage tests for elogind
[elogind.git] / src / test / test-util.c
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
21 #include <errno.h>
22 #include <string.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
25
26 #include "def.h"
27 #include "fileio.h"
28 #include "fs-util.h"
29 #include "parse-util.h"
30 //#include "raw-clone.h"
31 #include "rm-rf.h"
32 #include "string-util.h"
33 #include "util.h"
34
35 static 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
65 static 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));
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);
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));
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);
105 }
106
107 static 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
125 static 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
158 static void test_u64log2(void) {
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);
166 }
167
168 static void test_protect_errno(void) {
169         errno = 12;
170         {
171                 PROTECT_ERRNO;
172                 errno = 11;
173         }
174         assert_se(errno == 12);
175 }
176
177 static 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
187 static 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
198 #if 0 /// UNNEEDED by elogind
199 static void test_raw_clone(void) {
200         pid_t parent, pid, pid2;
201
202         parent = getpid();
203         log_info("before clone: getpid()→"PID_FMT, parent);
204         assert_se(raw_getpid() == parent);
205
206         pid = raw_clone(0);
207         assert_se(pid >= 0);
208
209         pid2 = raw_getpid();
210         log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
211                  pid, getpid(), pid2);
212         if (pid == 0) {
213                 assert_se(pid2 != parent);
214                 _exit(EXIT_SUCCESS);
215         } else {
216                 int status;
217
218                 assert_se(pid2 == parent);
219                 waitpid(pid, &status, __WCLONE);
220                 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
221         }
222 }
223 #endif // 0
224
225 static void test_physical_memory(void) {
226         uint64_t p;
227         char buf[FORMAT_BYTES_MAX];
228
229         p = physical_memory();
230         assert_se(p > 0);
231         assert_se(p < UINT64_MAX);
232         assert_se(p % page_size() == 0);
233
234         log_info("Memory: %s (%" PRIu64 ")", format_bytes(buf, sizeof(buf), p), p);
235 }
236
237 static void test_physical_memory_scale(void) {
238         uint64_t p;
239
240         p = physical_memory();
241
242         assert_se(physical_memory_scale(0, 100) == 0);
243         assert_se(physical_memory_scale(100, 100) == p);
244
245         log_info("Memory original: %" PRIu64, physical_memory());
246         log_info("Memory scaled by 50%%: %" PRIu64, physical_memory_scale(50, 100));
247         log_info("Memory divided by 2: %" PRIu64, physical_memory() / 2);
248         log_info("Page size: %zu", page_size());
249
250         /* There might be an uneven number of pages, hence permit these calculations to be half a page off... */
251         assert_se(page_size()/2 + physical_memory_scale(50, 100) - p/2 <= page_size());
252         assert_se(physical_memory_scale(200, 100) == p*2);
253
254         assert_se(physical_memory_scale(0, 1) == 0);
255         assert_se(physical_memory_scale(1, 1) == p);
256         assert_se(physical_memory_scale(2, 1) == p*2);
257
258         assert_se(physical_memory_scale(0, 2) == 0);
259
260         assert_se(page_size()/2 + physical_memory_scale(1, 2) - p/2 <= page_size());
261         assert_se(physical_memory_scale(2, 2) == p);
262         assert_se(physical_memory_scale(4, 2) == p*2);
263
264         assert_se(physical_memory_scale(0, UINT32_MAX) == 0);
265         assert_se(physical_memory_scale(UINT32_MAX, UINT32_MAX) == p);
266
267         /* overflow */
268         assert_se(physical_memory_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
269 }
270
271 static void test_system_tasks_max(void) {
272         uint64_t t;
273
274         t = system_tasks_max();
275         assert_se(t > 0);
276         assert_se(t < UINT64_MAX);
277
278         log_info("Max tasks: %" PRIu64, t);
279 }
280
281 static void test_system_tasks_max_scale(void) {
282         uint64_t t;
283
284         t = system_tasks_max();
285
286         assert_se(system_tasks_max_scale(0, 100) == 0);
287         assert_se(system_tasks_max_scale(100, 100) == t);
288
289         assert_se(system_tasks_max_scale(0, 1) == 0);
290         assert_se(system_tasks_max_scale(1, 1) == t);
291         assert_se(system_tasks_max_scale(2, 1) == 2*t);
292
293         assert_se(system_tasks_max_scale(0, 2) == 0);
294         assert_se(system_tasks_max_scale(1, 2) == t/2);
295         assert_se(system_tasks_max_scale(2, 2) == t);
296         assert_se(system_tasks_max_scale(3, 2) == (3*t)/2);
297         assert_se(system_tasks_max_scale(4, 2) == t*2);
298
299         assert_se(system_tasks_max_scale(0, UINT32_MAX) == 0);
300         assert_se(system_tasks_max_scale((UINT32_MAX-1)/2, UINT32_MAX-1) == t/2);
301         assert_se(system_tasks_max_scale(UINT32_MAX, UINT32_MAX) == t);
302
303         /* overflow */
304
305         assert_se(system_tasks_max_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
306 }
307
308 int main(int argc, char *argv[]) {
309         log_parse_environment();
310         log_open();
311
312         test_align_power2();
313         test_max();
314         test_container_of();
315         test_div_round_up();
316         test_u64log2();
317         test_protect_errno();
318         test_in_set();
319         test_log2i();
320 #if 0 /// UNNEEDED by elogind
321         test_raw_clone();
322 #endif // 0
323         test_physical_memory();
324         test_physical_memory_scale();
325         test_system_tasks_max();
326         test_system_tasks_max_scale();
327
328         return 0;
329 }