]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-cpu-set-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include "alloc-util.h"
4 #include "cpu-set-util.h"
5 #include "string-util.h"
8 static void test_parse_cpu_set(void) {
10 _cleanup_free_
char *str
= NULL
;
13 log_info("/* %s */", __func__
);
16 assert_se(parse_cpu_set_full("0", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
18 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
19 assert_se(CPU_ISSET_S(0, c
.allocated
, c
.set
));
20 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 1);
22 assert_se(str
= cpu_set_to_string(&c
));
23 log_info("cpu_set_to_string: %s", str
);
25 assert_se(str
= cpu_set_to_range_string(&c
));
26 log_info("cpu_set_to_range_string: %s", str
);
27 assert_se(streq(str
, "0"));
31 /* Simple range (from CPUAffinity example) */
32 assert_se(parse_cpu_set_full("1 2 4", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
34 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
35 assert_se(CPU_ISSET_S(1, c
.allocated
, c
.set
));
36 assert_se(CPU_ISSET_S(2, c
.allocated
, c
.set
));
37 assert_se(CPU_ISSET_S(4, c
.allocated
, c
.set
));
38 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 3);
40 assert_se(str
= cpu_set_to_string(&c
));
41 log_info("cpu_set_to_string: %s", str
);
43 assert_se(str
= cpu_set_to_range_string(&c
));
44 log_info("cpu_set_to_range_string: %s", str
);
45 assert_se(streq(str
, "1-2 4"));
49 /* A more interesting range */
50 assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
51 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
52 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 8);
53 for (cpu
= 0; cpu
< 4; cpu
++)
54 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
55 for (cpu
= 8; cpu
< 12; cpu
++)
56 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
58 assert_se(str
= cpu_set_to_string(&c
));
59 log_info("cpu_set_to_string: %s", str
);
61 assert_se(str
= cpu_set_to_range_string(&c
));
62 log_info("cpu_set_to_range_string: %s", str
);
63 assert_se(streq(str
, "0-3 8-11"));
68 assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
69 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
70 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 4);
71 for (cpu
= 8; cpu
< 12; cpu
++)
72 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
73 assert_se(str
= cpu_set_to_string(&c
));
74 log_info("cpu_set_to_string: %s", str
);
76 assert_se(str
= cpu_set_to_range_string(&c
));
77 log_info("cpu_set_to_range_string: %s", str
);
78 assert_se(streq(str
, "8-11"));
82 /* Use commas as separators */
83 assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
84 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
85 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 8);
86 for (cpu
= 0; cpu
< 4; cpu
++)
87 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
88 for (cpu
= 8; cpu
< 12; cpu
++)
89 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
90 assert_se(str
= cpu_set_to_string(&c
));
91 log_info("cpu_set_to_string: %s", str
);
95 /* Commas with spaces (and trailing comma, space) */
96 assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
97 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
98 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 9);
99 for (cpu
= 0; cpu
< 8; cpu
++)
100 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
102 assert_se(CPU_ISSET_S(63, c
.allocated
, c
.set
));
103 assert_se(str
= cpu_set_to_string(&c
));
104 log_info("cpu_set_to_string: %s", str
);
106 assert_se(str
= cpu_set_to_range_string(&c
));
107 log_info("cpu_set_to_range_string: %s", str
);
108 assert_se(streq(str
, "0-7 63"));
113 assert_se(parse_cpu_set_full("0-3,8-11", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
114 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
115 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 8);
116 for (cpu
= 0; cpu
< 4; cpu
++)
117 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
118 for (cpu
= 8; cpu
< 12; cpu
++)
119 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
120 assert_se(str
= cpu_set_to_string(&c
));
121 log_info("cpu_set_to_string: %s", str
);
125 /* Ranges with trailing comma, space */
126 assert_se(parse_cpu_set_full("0-3 8-11, ", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
127 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
128 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 8);
129 for (cpu
= 0; cpu
< 4; cpu
++)
130 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
131 for (cpu
= 8; cpu
< 12; cpu
++)
132 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
133 assert_se(str
= cpu_set_to_string(&c
));
134 log_info("cpu_set_to_string: %s", str
);
136 assert_se(str
= cpu_set_to_range_string(&c
));
137 log_info("cpu_set_to_range_string: %s", str
);
138 assert_se(streq(str
, "0-3 8-11"));
142 /* Negative range (returns empty cpu_set) */
143 assert_se(parse_cpu_set_full("3-0", &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
) == 0);
148 /* Overlapping ranges */
149 assert_se(parse_cpu_set_full("0-7 4-11", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
150 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
151 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 12);
152 for (cpu
= 0; cpu
< 12; cpu
++)
153 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
154 assert_se(str
= cpu_set_to_string(&c
));
155 log_info("cpu_set_to_string: %s", str
);
157 assert_se(str
= cpu_set_to_range_string(&c
));
158 log_info("cpu_set_to_range_string: %s", str
);
159 assert_se(streq(str
, "0-11"));
163 /* Mix ranges and individual CPUs */
164 assert_se(parse_cpu_set_full("0,2 4-11", &c
, true, NULL
, "fake", 1, "CPUAffinity") >= 0);
165 assert_se(c
.allocated
>= DIV_ROUND_UP(sizeof(__cpu_mask
), 8));
166 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 10);
167 assert_se(CPU_ISSET_S(0, c
.allocated
, c
.set
));
168 assert_se(CPU_ISSET_S(2, c
.allocated
, c
.set
));
169 for (cpu
= 4; cpu
< 12; cpu
++)
170 assert_se(CPU_ISSET_S(cpu
, c
.allocated
, c
.set
));
171 assert_se(str
= cpu_set_to_string(&c
));
172 log_info("cpu_set_to_string: %s", str
);
174 assert_se(str
= cpu_set_to_range_string(&c
));
175 log_info("cpu_set_to_range_string: %s", str
);
176 assert_se(streq(str
, "0 2 4-11"));
181 assert_se(parse_cpu_set_full("0 1 2 3 garbage", &c
, true, NULL
, "fake", 1, "CPUAffinity") == -EINVAL
);
183 assert_se(c
.allocated
== 0);
185 /* Range with garbage */
186 assert_se(parse_cpu_set_full("0-3 8-garbage", &c
, true, NULL
, "fake", 1, "CPUAffinity") == -EINVAL
);
188 assert_se(c
.allocated
== 0);
191 assert_se(parse_cpu_set_full("", &c
, true, NULL
, "fake", 1, "CPUAffinity") == 0);
192 assert_se(!c
.set
); /* empty string returns NULL */
193 assert_se(c
.allocated
== 0);
195 /* Runaway quoted string */
196 assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c
, true, NULL
, "fake", 1, "CPUAffinity") == -EINVAL
);
198 assert_se(c
.allocated
== 0);
200 /* Maximum allocation */
201 assert_se(parse_cpu_set_full("8000-8191", &c
, true, NULL
, "fake", 1, "CPUAffinity") == 0);
202 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 192);
203 assert_se(str
= cpu_set_to_string(&c
));
204 log_info("cpu_set_to_string: %s", str
);
206 assert_se(str
= cpu_set_to_range_string(&c
));
207 log_info("cpu_set_to_range_string: %s", str
);
208 assert_se(streq(str
, "8000-8191"));
213 static void test_parse_cpu_set_extend(void) {
215 _cleanup_free_
char *s1
= NULL
, *s2
= NULL
;
217 log_info("/* %s */", __func__
);
219 assert_se(parse_cpu_set_extend("1 3", &c
, true, NULL
, "fake", 1, "CPUAffinity") == 0);
220 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 2);
221 assert_se(s1
= cpu_set_to_string(&c
));
222 log_info("cpu_set_to_string: %s", s1
);
224 assert_se(parse_cpu_set_extend("4", &c
, true, NULL
, "fake", 1, "CPUAffinity") == 0);
225 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 3);
226 assert_se(s2
= cpu_set_to_string(&c
));
227 log_info("cpu_set_to_string: %s", s2
);
229 assert_se(parse_cpu_set_extend("", &c
, true, NULL
, "fake", 1, "CPUAffinity") == 0);
231 assert_se(c
.allocated
== 0);
232 log_info("cpu_set_to_string: (null)");
235 static void test_cpu_set_to_from_dbus(void) {
236 _cleanup_(cpu_set_reset
) CPUSet c
= {}, c2
= {};
237 _cleanup_free_
char *s
= NULL
;
239 log_info("/* %s */", __func__
);
241 assert_se(parse_cpu_set_extend("1 3 8 100-200", &c
, true, NULL
, "fake", 1, "CPUAffinity") == 0);
242 assert_se(s
= cpu_set_to_string(&c
));
243 log_info("cpu_set_to_string: %s", s
);
244 assert_se(CPU_COUNT_S(c
.allocated
, c
.set
) == 104);
246 _cleanup_free_
uint8_t *array
= NULL
;
248 static const char expected
[32] =
249 "\x0A\x01\x00\x00\x00\x00\x00\x00\x00\x00"
250 "\x00\x00\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
251 "\xFF\xFF\xFF\xFF\xFF\x01";
253 assert_se(cpu_set_to_dbus(&c
, &array
, &allocated
) == 0);
255 assert_se(allocated
== c
.allocated
);
257 assert_se(allocated
<= sizeof expected
);
258 assert_se(allocated
>= DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */
259 assert(memcmp(array
, expected
, allocated
) == 0);
261 assert_se(cpu_set_from_dbus(array
, allocated
, &c2
) == 0);
263 assert_se(c2
.allocated
== c
.allocated
);
264 assert_se(memcmp(c
.set
, c2
.set
, c
.allocated
) == 0);
267 static void test_cpus_in_affinity_mask(void) {
270 r
= cpus_in_affinity_mask();
272 log_info("cpus_in_affinity_mask: %d", r
);
275 int main(int argc
, char *argv
[]) {
276 log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
277 log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
278 log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64));
279 log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65));
280 log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024));
281 log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025));
282 log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
284 test_parse_cpu_set();
285 test_parse_cpu_set_extend();
286 test_cpus_in_affinity_mask();
287 test_cpu_set_to_from_dbus();