]>
Commit | Line | Data |
---|---|---|
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 | 35 | TEST(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 | ||
199 | TEST(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 | 214 | TEST(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 | 248 | TEST(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 | 255 | TEST(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 | 265 | DEFINE_TEST_MAIN(LOG_DEBUG); |