]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-cpu-set-util.c
pe-binary: .initrd section is optional for UKI
[thirdparty/systemd.git] / src / test / test-cpu-set-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
7ba365a9
RC
2
3#include "alloc-util.h"
4#include "cpu-set-util.h"
71b28519 5#include "string-util.h"
4f7452a8 6#include "tests.h"
7ba365a9
RC
7#include "macro.h"
8
4f7452a8 9TEST(parse_cpu_set) {
0985c7c4 10 CPUSet c = {};
a832893f 11 _cleanup_free_ char *str = NULL;
7ba365a9
RC
12 int cpu;
13
71b28519
MS
14 /* Single value */
15 assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
16 assert_se(c.set);
a299ce05 17 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
71b28519
MS
18 assert_se(CPU_ISSET_S(0, c.allocated, c.set));
19 assert_se(CPU_COUNT_S(c.allocated, c.set) == 1);
20
21 assert_se(str = cpu_set_to_string(&c));
22 log_info("cpu_set_to_string: %s", str);
23 str = mfree(str);
24 assert_se(str = cpu_set_to_range_string(&c));
25 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 26 ASSERT_STREQ(str, "0");
71b28519 27 str = mfree(str);
0f30bf58
RRZ
28 assert_se(str = cpu_set_to_mask_string(&c));
29 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 30 ASSERT_STREQ(str, "1");
0f30bf58 31 str = mfree(str);
71b28519
MS
32 cpu_set_reset(&c);
33
7ba365a9 34 /* Simple range (from CPUAffinity example) */
1f57a176 35 assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
0985c7c4 36 assert_se(c.set);
a299ce05 37 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4
ZJS
38 assert_se(CPU_ISSET_S(1, c.allocated, c.set));
39 assert_se(CPU_ISSET_S(2, c.allocated, c.set));
1f57a176
ZJS
40 assert_se(CPU_ISSET_S(4, c.allocated, c.set));
41 assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
0985c7c4
ZJS
42
43 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
44 log_info("cpu_set_to_string: %s", str);
45 str = mfree(str);
71b28519
MS
46 assert_se(str = cpu_set_to_range_string(&c));
47 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 48 ASSERT_STREQ(str, "1-2 4");
71b28519 49 str = mfree(str);
0f30bf58
RRZ
50 assert_se(str = cpu_set_to_mask_string(&c));
51 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 52 ASSERT_STREQ(str, "16");
0f30bf58 53 str = mfree(str);
0985c7c4 54 cpu_set_reset(&c);
7ba365a9
RC
55
56 /* A more interesting range */
0985c7c4 57 assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 58 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4 59 assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
7ba365a9 60 for (cpu = 0; cpu < 4; cpu++)
0985c7c4 61 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
7ba365a9 62 for (cpu = 8; cpu < 12; cpu++)
0985c7c4 63 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
71b28519 64
0985c7c4 65 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
66 log_info("cpu_set_to_string: %s", str);
67 str = mfree(str);
71b28519
MS
68 assert_se(str = cpu_set_to_range_string(&c));
69 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 70 ASSERT_STREQ(str, "0-3 8-11");
71b28519 71 str = mfree(str);
0f30bf58
RRZ
72 assert_se(str = cpu_set_to_mask_string(&c));
73 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 74 ASSERT_STREQ(str, "f0f");
0f30bf58 75 str = mfree(str);
0985c7c4 76 cpu_set_reset(&c);
7ba365a9
RC
77
78 /* Quoted strings */
0985c7c4 79 assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 80 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4 81 assert_se(CPU_COUNT_S(c.allocated, c.set) == 4);
7ba365a9 82 for (cpu = 8; cpu < 12; cpu++)
0985c7c4
ZJS
83 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
84 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
85 log_info("cpu_set_to_string: %s", str);
86 str = mfree(str);
71b28519
MS
87 assert_se(str = cpu_set_to_range_string(&c));
88 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 89 ASSERT_STREQ(str, "8-11");
71b28519 90 str = mfree(str);
0f30bf58
RRZ
91 assert_se(str = cpu_set_to_mask_string(&c));
92 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 93 ASSERT_STREQ(str, "f00");
0f30bf58 94 str = mfree(str);
0985c7c4 95 cpu_set_reset(&c);
7ba365a9
RC
96
97 /* Use commas as separators */
0985c7c4 98 assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 99 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4 100 assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
7ba365a9 101 for (cpu = 0; cpu < 4; cpu++)
0985c7c4 102 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
7ba365a9 103 for (cpu = 8; cpu < 12; cpu++)
0985c7c4
ZJS
104 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
105 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
106 log_info("cpu_set_to_string: %s", str);
107 str = mfree(str);
0985c7c4 108 cpu_set_reset(&c);
7ba365a9
RC
109
110 /* Commas with spaces (and trailing comma, space) */
71923237 111 assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 112 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
71923237 113 assert_se(CPU_COUNT_S(c.allocated, c.set) == 9);
7ba365a9 114 for (cpu = 0; cpu < 8; cpu++)
0985c7c4 115 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
71923237
MS
116
117 assert_se(CPU_ISSET_S(63, c.allocated, c.set));
0985c7c4 118 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
119 log_info("cpu_set_to_string: %s", str);
120 str = mfree(str);
71b28519
MS
121 assert_se(str = cpu_set_to_range_string(&c));
122 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 123 ASSERT_STREQ(str, "0-7 63");
71b28519 124 str = mfree(str);
0f30bf58
RRZ
125 assert_se(str = cpu_set_to_mask_string(&c));
126 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 127 ASSERT_STREQ(str, "80000000,000000ff");
0f30bf58 128 str = mfree(str);
0985c7c4 129 cpu_set_reset(&c);
7ba365a9
RC
130
131 /* Ranges */
0985c7c4 132 assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 133 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4 134 assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
7ba365a9 135 for (cpu = 0; cpu < 4; cpu++)
0985c7c4 136 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
7ba365a9 137 for (cpu = 8; cpu < 12; cpu++)
0985c7c4
ZJS
138 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
139 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
140 log_info("cpu_set_to_string: %s", str);
141 str = mfree(str);
0985c7c4 142 cpu_set_reset(&c);
0f30bf58
RRZ
143 assert_se(parse_cpu_set_full("36-39,44-47", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
144 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
145 assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
146 for (cpu = 36; cpu < 40; cpu++)
147 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
148 for (cpu = 44; cpu < 48; cpu++)
149 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
150 assert_se(str = cpu_set_to_mask_string(&c));
151 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 152 ASSERT_STREQ(str, "f0f0,00000000");
0f30bf58
RRZ
153 str = mfree(str);
154 cpu_set_reset(&c);
155 assert_se(parse_cpu_set_full("64-71", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
156 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
157 assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
158 for (cpu = 64; cpu < 72; cpu++)
159 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
160 assert_se(str = cpu_set_to_mask_string(&c));
161 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 162 ASSERT_STREQ(str, "ff,00000000,00000000");
0f30bf58
RRZ
163 str = mfree(str);
164 cpu_set_reset(&c);
7ba365a9
RC
165
166 /* Ranges with trailing comma, space */
0985c7c4 167 assert_se(parse_cpu_set_full("0-3 8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 168 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4 169 assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
7ba365a9 170 for (cpu = 0; cpu < 4; cpu++)
0985c7c4 171 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
7ba365a9 172 for (cpu = 8; cpu < 12; cpu++)
0985c7c4
ZJS
173 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
174 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
175 log_info("cpu_set_to_string: %s", str);
176 str = mfree(str);
71b28519
MS
177 assert_se(str = cpu_set_to_range_string(&c));
178 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 179 ASSERT_STREQ(str, "0-3 8-11");
71b28519 180 str = mfree(str);
0f30bf58
RRZ
181 assert_se(str = cpu_set_to_mask_string(&c));
182 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 183 ASSERT_STREQ(str, "f0f");
0f30bf58 184 str = mfree(str);
0985c7c4 185 cpu_set_reset(&c);
7ba365a9
RC
186
187 /* Negative range (returns empty cpu_set) */
0985c7c4 188 assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 189 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4 190 assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
0f30bf58
RRZ
191 assert_se(str = cpu_set_to_mask_string(&c));
192 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 193 ASSERT_STREQ(str, "0");
0f30bf58 194 str = mfree(str);
0985c7c4 195 cpu_set_reset(&c);
7ba365a9
RC
196
197 /* Overlapping ranges */
0985c7c4 198 assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 199 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4 200 assert_se(CPU_COUNT_S(c.allocated, c.set) == 12);
7ba365a9 201 for (cpu = 0; cpu < 12; cpu++)
0985c7c4
ZJS
202 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
203 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
204 log_info("cpu_set_to_string: %s", str);
205 str = mfree(str);
71b28519
MS
206 assert_se(str = cpu_set_to_range_string(&c));
207 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 208 ASSERT_STREQ(str, "0-11");
71b28519 209 str = mfree(str);
0f30bf58
RRZ
210 assert_se(str = cpu_set_to_mask_string(&c));
211 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 212 ASSERT_STREQ(str, "fff");
0f30bf58 213 str = mfree(str);
0985c7c4 214 cpu_set_reset(&c);
7ba365a9
RC
215
216 /* Mix ranges and individual CPUs */
71923237 217 assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
a299ce05 218 assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
0985c7c4
ZJS
219 assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
220 assert_se(CPU_ISSET_S(0, c.allocated, c.set));
71923237 221 assert_se(CPU_ISSET_S(2, c.allocated, c.set));
7ba365a9 222 for (cpu = 4; cpu < 12; cpu++)
0985c7c4
ZJS
223 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
224 assert_se(str = cpu_set_to_string(&c));
a832893f
ZJS
225 log_info("cpu_set_to_string: %s", str);
226 str = mfree(str);
71b28519
MS
227 assert_se(str = cpu_set_to_range_string(&c));
228 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 229 ASSERT_STREQ(str, "0 2 4-11");
71b28519 230 str = mfree(str);
0f30bf58
RRZ
231 assert_se(str = cpu_set_to_mask_string(&c));
232 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 233 ASSERT_STREQ(str, "ff5");
0f30bf58 234 str = mfree(str);
0985c7c4 235 cpu_set_reset(&c);
7ba365a9
RC
236
237 /* Garbage */
0985c7c4
ZJS
238 assert_se(parse_cpu_set_full("0 1 2 3 garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
239 assert_se(!c.set);
240 assert_se(c.allocated == 0);
7ba365a9
RC
241
242 /* Range with garbage */
0985c7c4
ZJS
243 assert_se(parse_cpu_set_full("0-3 8-garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
244 assert_se(!c.set);
245 assert_se(c.allocated == 0);
7ba365a9
RC
246
247 /* Empty string */
0985c7c4
ZJS
248 assert_se(parse_cpu_set_full("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
249 assert_se(!c.set); /* empty string returns NULL */
250 assert_se(c.allocated == 0);
0f30bf58
RRZ
251 assert_se(str = cpu_set_to_mask_string(&c));
252 log_info("cpu_set_to_mask_string: %s", str);
c79e88b3 253 ASSERT_STREQ(str, "0");
0f30bf58 254 str = mfree(str);
7ba365a9 255
efd08022 256 /* Runaway quoted string */
0985c7c4
ZJS
257 assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
258 assert_se(!c.set);
259 assert_se(c.allocated == 0);
260
261 /* Maximum allocation */
262 assert_se(parse_cpu_set_full("8000-8191", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
263 assert_se(CPU_COUNT_S(c.allocated, c.set) == 192);
264 assert_se(str = cpu_set_to_string(&c));
265 log_info("cpu_set_to_string: %s", str);
266 str = mfree(str);
71b28519
MS
267 assert_se(str = cpu_set_to_range_string(&c));
268 log_info("cpu_set_to_range_string: %s", str);
c79e88b3 269 ASSERT_STREQ(str, "8000-8191");
71b28519 270 str = mfree(str);
0f30bf58
RRZ
271 assert_se(str = cpu_set_to_mask_string(&c));
272 log_info("cpu_set_to_mask_string: %s", str);
273 for (size_t i = 0; i < strlen(str); i++) {
274 if (i < 54) {
275 if (i >= 8 && (i + 1) % 9 == 0)
276 assert_se(str[i] == ',');
277 else
278 assert_se(str[i] == 'f');
279 }
280 else {
281 if (i >= 8 && (i + 1) % 9 == 0)
282 assert_se(str[i] == ',');
283 else
284 assert_se(str[i] == '0');
285 }
286 }
287 str = mfree(str);
0985c7c4 288 cpu_set_reset(&c);
7ba365a9
RC
289}
290
4f7452a8 291TEST(parse_cpu_set_extend) {
b54d7241
ZJS
292 CPUSet c = {};
293 _cleanup_free_ char *s1 = NULL, *s2 = NULL;
294
e2b2fb7f 295 assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 1);
b54d7241
ZJS
296 assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
297 assert_se(s1 = cpu_set_to_string(&c));
298 log_info("cpu_set_to_string: %s", s1);
299
e2b2fb7f 300 assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 1);
b54d7241
ZJS
301 assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
302 assert_se(s2 = cpu_set_to_string(&c));
303 log_info("cpu_set_to_string: %s", s2);
304
305 assert_se(parse_cpu_set_extend("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
306 assert_se(!c.set);
307 assert_se(c.allocated == 0);
308 log_info("cpu_set_to_string: (null)");
309}
310
4f7452a8 311TEST(cpu_set_to_from_dbus) {
1bf0d6c2
ZJS
312 _cleanup_(cpu_set_reset) CPUSet c = {}, c2 = {};
313 _cleanup_free_ char *s = NULL;
314
e2b2fb7f 315 assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 1);
1bf0d6c2
ZJS
316 assert_se(s = cpu_set_to_string(&c));
317 log_info("cpu_set_to_string: %s", s);
318 assert_se(CPU_COUNT_S(c.allocated, c.set) == 104);
319
320 _cleanup_free_ uint8_t *array = NULL;
321 size_t allocated;
322 static const char expected[32] =
323 "\x0A\x01\x00\x00\x00\x00\x00\x00\x00\x00"
324 "\x00\x00\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
325 "\xFF\xFF\xFF\xFF\xFF\x01";
326
327 assert_se(cpu_set_to_dbus(&c, &array, &allocated) == 0);
328 assert_se(array);
329 assert_se(allocated == c.allocated);
330
64412970
ZJS
331 assert_se(allocated <= sizeof expected);
332 assert_se(allocated >= DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */
f21b863e 333 assert_se(memcmp(array, expected, allocated) == 0);
1bf0d6c2
ZJS
334
335 assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0);
336 assert_se(c2.set);
337 assert_se(c2.allocated == c.allocated);
338 assert_se(memcmp(c.set, c2.set, c.allocated) == 0);
339}
340
4f7452a8 341TEST(cpus_in_affinity_mask) {
9d1345f0
ZJS
342 int r;
343
344 r = cpus_in_affinity_mask();
f21b863e 345 assert_se(r > 0);
9d1345f0
ZJS
346 log_info("cpus_in_affinity_mask: %d", r);
347}
348
4f7452a8 349TEST(print_cpu_alloc_size) {
0985c7c4
ZJS
350 log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
351 log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
352 log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64));
353 log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65));
354 log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024));
355 log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025));
356 log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
7ba365a9 357}
4f7452a8
JJ
358
359DEFINE_TEST_MAIN(LOG_INFO);