]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-cpu-set-util.c
core/scope: drop effectively unused unit_watch_pidref() calls (#38186)
[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"
4f7452a8 5#include "tests.h"
7ba365a9 6
079a135e
YW
7#define ASSERT_CPUSET_EMPTY(c) \
8 ASSERT_NULL(c.set); \
9 ASSERT_EQ(c.allocated, 0u)
10
079a135e
YW
11#define ASSERT_CPUSET_COUNT(c, n) \
12 ASSERT_NOT_NULL(c.set); \
274e2f4b
YW
13 ASSERT_GE(c.allocated, CPU_ALLOC_SIZE(n)); \
14 ASSERT_EQ(CPU_COUNT_S(c.allocated, c.set), (n))
079a135e
YW
15
16#define ASSERT_CPUSET_ISSET(c, i) \
17 ASSERT_TRUE(CPU_ISSET_S(i, c.allocated, c.set));
18
19#define ASSERT_CPUSET_STRING(c, str, range, mask) \
20 { \
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); \
25 s = mfree(s); \
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); \
29 s = mfree(s); \
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); \
33 }
34
4f7452a8 35TEST(parse_cpu_set) {
0985c7c4 36 CPUSet c = {};
079a135e
YW
37
38 /* empty */
39 ASSERT_CPUSET_EMPTY(c);
40 ASSERT_CPUSET_STRING(c, "", "", "0");
296fe3d5 41 cpu_set_done(&c);
7ba365a9 42
71b28519 43 /* Single value */
168351ee 44 ASSERT_OK(parse_cpu_set("0", &c));
079a135e
YW
45 ASSERT_CPUSET_COUNT(c, 1);
46 ASSERT_CPUSET_ISSET(c, 0);
47 ASSERT_CPUSET_STRING(c, "0", "0", "1");
296fe3d5 48 cpu_set_done(&c);
71b28519 49
7ba365a9 50 /* Simple range (from CPUAffinity example) */
168351ee 51 ASSERT_OK(parse_cpu_set("1 2 4", &c));
079a135e
YW
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");
296fe3d5 57 cpu_set_done(&c);
7ba365a9
RC
58
59 /* A more interesting range */
168351ee 60 ASSERT_OK(parse_cpu_set("0 1 2 3 8 9 10 11", &c));
079a135e
YW
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");
296fe3d5 67 cpu_set_done(&c);
7ba365a9
RC
68
69 /* Quoted strings */
168351ee 70 ASSERT_OK(parse_cpu_set("8 '9' 10 \"11\"", &c));
079a135e
YW
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");
296fe3d5 75 cpu_set_done(&c);
7ba365a9
RC
76
77 /* Use commas as separators */
168351ee 78 ASSERT_OK(parse_cpu_set("0,1,2,3 8,9,10,11", &c));
079a135e
YW
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");
296fe3d5 85 cpu_set_done(&c);
7ba365a9
RC
86
87 /* Commas with spaces (and trailing comma, space) */
168351ee 88 ASSERT_OK(parse_cpu_set("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c));
079a135e
YW
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");
296fe3d5 94 cpu_set_done(&c);
7ba365a9
RC
95
96 /* Ranges */
168351ee 97 ASSERT_OK(parse_cpu_set("0-3,8-11", &c));
079a135e
YW
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");
296fe3d5 104 cpu_set_done(&c);
079a135e 105
168351ee 106 ASSERT_OK(parse_cpu_set("36-39,44-47", &c));
079a135e
YW
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");
296fe3d5 113 cpu_set_done(&c);
079a135e 114
168351ee 115 ASSERT_OK(parse_cpu_set("64-71", &c));
079a135e
YW
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");
296fe3d5 120 cpu_set_done(&c);
7ba365a9
RC
121
122 /* Ranges with trailing comma, space */
168351ee 123 ASSERT_OK(parse_cpu_set("0-3 8-11, ", &c));
079a135e
YW
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");
296fe3d5 130 cpu_set_done(&c);
7ba365a9
RC
131
132 /* Overlapping ranges */
168351ee 133 ASSERT_OK(parse_cpu_set("0-7 4-11", &c));
079a135e
YW
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");
296fe3d5 138 cpu_set_done(&c);
7ba365a9
RC
139
140 /* Mix ranges and individual CPUs */
168351ee 141 ASSERT_OK(parse_cpu_set("0,2 4-11", &c));
079a135e
YW
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");
296fe3d5 148 cpu_set_done(&c);
7ba365a9 149
fe3ada07
YW
150 /* Negative range */
151 ASSERT_ERROR(parse_cpu_set("3-0", &c), EINVAL);
152 ASSERT_CPUSET_EMPTY(c);
7ba365a9
RC
153
154 /* Garbage */
168351ee 155 ASSERT_ERROR(parse_cpu_set("0 1 2 3 garbage", &c), EINVAL);
079a135e 156 ASSERT_CPUSET_EMPTY(c);
7ba365a9
RC
157
158 /* Range with garbage */
168351ee 159 ASSERT_ERROR(parse_cpu_set("0-3 8-garbage", &c), EINVAL);
079a135e 160 ASSERT_CPUSET_EMPTY(c);
7ba365a9
RC
161
162 /* Empty string */
168351ee 163 ASSERT_OK(parse_cpu_set("", &c));
079a135e 164 ASSERT_CPUSET_EMPTY(c); /* empty string returns NULL */
7ba365a9 165
efd08022 166 /* Runaway quoted string */
168351ee 167 ASSERT_ERROR(parse_cpu_set("0 1 2 3 \"4 5 6 7 ", &c), EINVAL);
079a135e 168 ASSERT_CPUSET_EMPTY(c);
0985c7c4
ZJS
169
170 /* Maximum allocation */
168351ee 171 ASSERT_OK(parse_cpu_set("8000-8191", &c));
079a135e
YW
172 ASSERT_CPUSET_COUNT(c, 192);
173
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));
177
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"));
181
182 ASSERT_CPUSET_STRING(c, expected_str, "8000-8191", expected_mask);
296fe3d5 183 cpu_set_done(&c);
7ba365a9
RC
184}
185
fe3ada07
YW
186#define parse(str, c) \
187 config_parse_cpu_set( \
188 "unit", \
189 "filename", \
190 /* line = */ 0, \
191 "[Section]", \
192 /* section_line = */ 0, \
193 "CPUAffinity", \
194 /* ltype = */ 0, \
195 str, \
196 c, \
197 /* userdata = */ NULL)
198
199TEST(config_parse_cpu_set) {
b54d7241 200 CPUSet c = {};
079a135e 201
fe3ada07 202 ASSERT_OK_POSITIVE(parse("1 3", &c));
079a135e
YW
203 ASSERT_CPUSET_COUNT(c, 2);
204 ASSERT_CPUSET_STRING(c, "1 3", "1 3", "a");
205
fe3ada07 206 ASSERT_OK_POSITIVE(parse("4", &c));
079a135e
YW
207 ASSERT_CPUSET_COUNT(c, 3);
208 ASSERT_CPUSET_STRING(c, "1 3 4", "1 3-4", "1a");
209
fe3ada07 210 ASSERT_OK_POSITIVE(parse("", &c));
079a135e 211 ASSERT_CPUSET_EMPTY(c);
b54d7241
ZJS
212}
213
4f7452a8 214TEST(cpu_set_to_from_dbus) {
296fe3d5 215 _cleanup_(cpu_set_done) CPUSet c = {}, c2 = {};
1bf0d6c2 216
168351ee 217 ASSERT_OK(parse_cpu_set("1 3 8 100-200", &c));
079a135e
YW
218 ASSERT_CPUSET_COUNT(c, 104);
219
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));
224
225 ASSERT_CPUSET_STRING(c, expected_str, "1 3 8 100-200", "1ff,ffffffff,ffffffff,fffffff0,00000000,00000000,0000010a");
1bf0d6c2
ZJS
226
227 _cleanup_free_ uint8_t *array = NULL;
228 size_t allocated;
229 static const char expected[32] =
079a135e
YW
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"
233 "\xFF\x01";
234
235 ASSERT_OK(cpu_set_to_dbus(&c, &array, &allocated));
236 ASSERT_NOT_NULL(array);
237 ASSERT_EQ(allocated, c.allocated);
238
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);
242
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);
1bf0d6c2
ZJS
246}
247
4f7452a8 248TEST(cpus_in_affinity_mask) {
9d1345f0
ZJS
249 int r;
250
079a135e 251 ASSERT_OK_POSITIVE(r = cpus_in_affinity_mask());
9d1345f0
ZJS
252 log_info("cpus_in_affinity_mask: %d", r);
253}
254
4f7452a8 255TEST(print_cpu_alloc_size) {
0985c7c4
ZJS
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));
7ba365a9 263}
4f7452a8 264
fe3ada07 265DEFINE_TEST_MAIN(LOG_DEBUG);