]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-cpu-set-util.c
6fc0ea0f49888c455c8fa96a304683a4d0ad4719
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "cpu-set-util.h"
7 #define ASSERT_CPUSET_EMPTY(c) \
9 ASSERT_EQ(c.allocated, 0u)
11 #define ASSERT_CPUSET_COUNT(c, n) \
12 ASSERT_NOT_NULL(c.set); \
13 ASSERT_GE(c.allocated, CPU_ALLOC_SIZE(n)); \
14 ASSERT_EQ(CPU_COUNT_S(c.allocated, c.set), (n))
16 #define ASSERT_CPUSET_ISSET(c, i) \
17 ASSERT_TRUE(CPU_ISSET_S(i, c.allocated, c.set));
19 #define ASSERT_CPUSET_STRING(c, str, range, mask) \
21 _cleanup_free_ char *s = NULL; \
22 ASSERT_NOT_NULL(s = cpu_set_to_string(&c)); \
23 log_info("cpu_set_to_string: %s", s); \
24 ASSERT_STREQ(s, str); \
26 ASSERT_NOT_NULL(s = cpu_set_to_range_string(&c)); \
27 log_info("cpu_set_to_range_string: %s", s); \
28 ASSERT_STREQ(s, range); \
30 ASSERT_NOT_NULL(s = cpu_set_to_mask_string(&c)); \
31 log_info("cpu_set_to_mask_string: %s", s); \
32 ASSERT_STREQ(s, mask); \
39 ASSERT_CPUSET_EMPTY(c
);
40 ASSERT_CPUSET_STRING(c
, "", "", "0");
44 ASSERT_OK(parse_cpu_set("0", &c
));
45 ASSERT_CPUSET_COUNT(c
, 1);
46 ASSERT_CPUSET_ISSET(c
, 0);
47 ASSERT_CPUSET_STRING(c
, "0", "0", "1");
50 /* Simple range (from CPUAffinity example) */
51 ASSERT_OK(parse_cpu_set("1 2 4", &c
));
52 ASSERT_CPUSET_COUNT(c
, 3);
53 ASSERT_CPUSET_ISSET(c
, 1);
54 ASSERT_CPUSET_ISSET(c
, 2);
55 ASSERT_CPUSET_ISSET(c
, 4);
56 ASSERT_CPUSET_STRING(c
, "1 2 4", "1-2 4", "16");
59 /* A more interesting range */
60 ASSERT_OK(parse_cpu_set("0 1 2 3 8 9 10 11", &c
));
61 ASSERT_CPUSET_COUNT(c
, 8);
62 for (unsigned i
= 0; i
< 4; i
++)
63 ASSERT_CPUSET_ISSET(c
, i
);
64 for (unsigned i
= 8; i
< 12; i
++)
65 ASSERT_CPUSET_ISSET(c
, i
);
66 ASSERT_CPUSET_STRING(c
, "0 1 2 3 8 9 10 11", "0-3 8-11", "f0f");
70 ASSERT_OK(parse_cpu_set("8 '9' 10 \"11\"", &c
));
71 ASSERT_CPUSET_COUNT(c
, 4);
72 for (unsigned i
= 8; i
< 12; i
++)
73 ASSERT_CPUSET_ISSET(c
, i
);
74 ASSERT_CPUSET_STRING(c
, "8 9 10 11", "8-11", "f00");
77 /* Use commas as separators */
78 ASSERT_OK(parse_cpu_set("0,1,2,3 8,9,10,11", &c
));
79 ASSERT_CPUSET_COUNT(c
, 8);
80 for (unsigned i
= 0; i
< 4; i
++)
81 ASSERT_CPUSET_ISSET(c
, i
);
82 for (unsigned i
= 8; i
< 12; i
++)
83 ASSERT_CPUSET_ISSET(c
, i
);
84 ASSERT_CPUSET_STRING(c
, "0 1 2 3 8 9 10 11", "0-3 8-11", "f0f");
87 /* Commas with spaces (and trailing comma, space) */
88 ASSERT_OK(parse_cpu_set("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c
));
89 ASSERT_CPUSET_COUNT(c
, 9);
90 for (unsigned i
= 0; i
< 8; i
++)
91 ASSERT_CPUSET_ISSET(c
, i
);
92 ASSERT_CPUSET_ISSET(c
, 63);
93 ASSERT_CPUSET_STRING(c
, "0 1 2 3 4 5 6 7 63", "0-7 63", "80000000,000000ff");
97 ASSERT_OK(parse_cpu_set("0-3,8-11", &c
));
98 ASSERT_CPUSET_COUNT(c
, 8);
99 for (unsigned i
= 0; i
< 4; i
++)
100 ASSERT_CPUSET_ISSET(c
, i
);
101 for (unsigned i
= 8; i
< 12; i
++)
102 ASSERT_CPUSET_ISSET(c
, i
);
103 ASSERT_CPUSET_STRING(c
, "0 1 2 3 8 9 10 11", "0-3 8-11", "f0f");
106 ASSERT_OK(parse_cpu_set("36-39,44-47", &c
));
107 ASSERT_CPUSET_COUNT(c
, 8);
108 for (unsigned i
= 36; i
< 40; i
++)
109 ASSERT_CPUSET_ISSET(c
, i
);
110 for (unsigned i
= 44; i
< 48; i
++)
111 ASSERT_CPUSET_ISSET(c
, i
);
112 ASSERT_CPUSET_STRING(c
, "36 37 38 39 44 45 46 47", "36-39 44-47", "f0f0,00000000");
115 ASSERT_OK(parse_cpu_set("64-71", &c
));
116 ASSERT_CPUSET_COUNT(c
, 8);
117 for (unsigned i
= 64; i
< 72; i
++)
118 ASSERT_CPUSET_ISSET(c
, i
);
119 ASSERT_CPUSET_STRING(c
, "64 65 66 67 68 69 70 71", "64-71", "ff,00000000,00000000");
122 /* Ranges with trailing comma, space */
123 ASSERT_OK(parse_cpu_set("0-3 8-11, ", &c
));
124 ASSERT_CPUSET_COUNT(c
, 8);
125 for (unsigned i
= 0; i
< 4; i
++)
126 ASSERT_CPUSET_ISSET(c
, i
);
127 for (unsigned i
= 8; i
< 12; i
++)
128 ASSERT_CPUSET_ISSET(c
, i
);
129 ASSERT_CPUSET_STRING(c
, "0 1 2 3 8 9 10 11", "0-3 8-11", "f0f");
132 /* Overlapping ranges */
133 ASSERT_OK(parse_cpu_set("0-7 4-11", &c
));
134 ASSERT_CPUSET_COUNT(c
, 12);
135 for (unsigned i
= 0; i
< 12; i
++)
136 ASSERT_CPUSET_ISSET(c
, i
);
137 ASSERT_CPUSET_STRING(c
, "0 1 2 3 4 5 6 7 8 9 10 11", "0-11", "fff");
140 /* Mix ranges and individual CPUs */
141 ASSERT_OK(parse_cpu_set("0,2 4-11", &c
));
142 ASSERT_CPUSET_COUNT(c
, 10);
143 ASSERT_CPUSET_ISSET(c
, 0);
144 ASSERT_CPUSET_ISSET(c
, 2);
145 for (unsigned i
= 4; i
< 12; i
++)
146 ASSERT_CPUSET_ISSET(c
, i
);
147 ASSERT_CPUSET_STRING(c
, "0 2 4 5 6 7 8 9 10 11", "0 2 4-11", "ff5");
151 ASSERT_ERROR(parse_cpu_set("3-0", &c
), EINVAL
);
152 ASSERT_CPUSET_EMPTY(c
);
155 ASSERT_ERROR(parse_cpu_set("0 1 2 3 garbage", &c
), EINVAL
);
156 ASSERT_CPUSET_EMPTY(c
);
158 /* Range with garbage */
159 ASSERT_ERROR(parse_cpu_set("0-3 8-garbage", &c
), EINVAL
);
160 ASSERT_CPUSET_EMPTY(c
);
163 ASSERT_OK(parse_cpu_set("", &c
));
164 ASSERT_CPUSET_EMPTY(c
); /* empty string returns NULL */
166 /* Runaway quoted string */
167 ASSERT_ERROR(parse_cpu_set("0 1 2 3 \"4 5 6 7 ", &c
), EINVAL
);
168 ASSERT_CPUSET_EMPTY(c
);
170 /* Maximum allocation */
171 ASSERT_OK(parse_cpu_set("8000-8191", &c
));
172 ASSERT_CPUSET_COUNT(c
, 192);
174 _cleanup_free_
char *expected_str
= NULL
;
175 for (size_t i
= 8000; i
< 8192; i
++)
176 ASSERT_OK(strextendf_with_separator(&expected_str
, " ", "%zu", i
));
178 _cleanup_free_
char *expected_mask
= NULL
;
179 for (size_t i
= 0; i
< 8192 / 32; i
++)
180 ASSERT_NOT_NULL(strextend_with_separator(&expected_mask
, ",", i
< 6 ? "ffffffff" : "00000000"));
182 ASSERT_CPUSET_STRING(c
, expected_str
, "8000-8191", expected_mask
);
186 #define parse(str, c) \
187 config_parse_cpu_set( \
192 /* section_line = */ 0, \
197 /* userdata = */ NULL)
199 TEST(config_parse_cpu_set
) {
202 ASSERT_OK_POSITIVE(parse("1 3", &c
));
203 ASSERT_CPUSET_COUNT(c
, 2);
204 ASSERT_CPUSET_STRING(c
, "1 3", "1 3", "a");
206 ASSERT_OK_POSITIVE(parse("4", &c
));
207 ASSERT_CPUSET_COUNT(c
, 3);
208 ASSERT_CPUSET_STRING(c
, "1 3 4", "1 3-4", "1a");
210 ASSERT_OK_POSITIVE(parse("", &c
));
211 ASSERT_CPUSET_EMPTY(c
);
214 TEST(cpu_set_to_from_dbus
) {
215 _cleanup_(cpu_set_done
) CPUSet c
= {}, c2
= {};
217 ASSERT_OK(parse_cpu_set("1 3 8 100-200", &c
));
218 ASSERT_CPUSET_COUNT(c
, 104);
220 _cleanup_free_
char *expected_str
= strdup("1 3 8");
221 ASSERT_NOT_NULL(expected_str
);
222 for (size_t i
= 100; i
<= 200; i
++)
223 ASSERT_OK(strextendf_with_separator(&expected_str
, " ", "%zu", i
));
225 ASSERT_CPUSET_STRING(c
, expected_str
, "1 3 8 100-200", "1ff,ffffffff,ffffffff,fffffff0,00000000,00000000,0000010a");
227 _cleanup_free_
uint8_t *array
= NULL
;
229 static const char expected
[32] =
230 "\x0A\x01\x00\x00\x00\x00\x00\x00"
231 "\x00\x00\x00\x00\xF0\xFF\xFF\xFF"
232 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
235 ASSERT_OK(cpu_set_to_dbus(&c
, &array
, &allocated
));
236 ASSERT_NOT_NULL(array
);
237 ASSERT_EQ(allocated
, c
.allocated
);
239 ASSERT_LE(allocated
, sizeof expected
);
240 ASSERT_GE(allocated
, DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */
241 ASSERT_EQ(memcmp(array
, expected
, allocated
), 0);
243 ASSERT_OK(cpu_set_from_dbus(array
, allocated
, &c2
));
244 ASSERT_CPUSET_COUNT(c2
, 104);
245 ASSERT_EQ(memcmp_nn(c
.set
, c
.allocated
, c2
.set
, c2
.allocated
), 0);
248 TEST(cpus_in_affinity_mask
) {
251 ASSERT_OK_POSITIVE(r
= cpus_in_affinity_mask());
252 log_info("cpus_in_affinity_mask: %d", r
);
255 TEST(print_cpu_alloc_size
) {
256 log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
257 log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
258 log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64));
259 log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65));
260 log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024));
261 log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025));
262 log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
265 DEFINE_TEST_MAIN(LOG_DEBUG
);