Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include "alloc-util.h"
4 : : #include "cpu-set-util.h"
5 : : #include "string-util.h"
6 : : #include "macro.h"
7 : :
8 : 4 : static void test_parse_cpu_set(void) {
9 : 4 : CPUSet c = {};
10 : 4 : _cleanup_free_ char *str = NULL;
11 : : int cpu;
12 : :
13 [ + - ]: 4 : log_info("/* %s */", __func__);
14 : :
15 : : /* Single value */
16 [ - + ]: 4 : assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
17 [ - + ]: 4 : assert_se(c.set);
18 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
19 [ + - + - : 4 : assert_se(CPU_ISSET_S(0, c.allocated, c.set));
- + ]
20 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 1);
21 : :
22 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
23 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
24 : 4 : str = mfree(str);
25 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
26 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
27 [ - + ]: 4 : assert_se(streq(str, "0"));
28 : 4 : str = mfree(str);
29 : 4 : cpu_set_reset(&c);
30 : :
31 : : /* Simple range (from CPUAffinity example) */
32 [ - + ]: 4 : assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
33 [ - + ]: 4 : assert_se(c.set);
34 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
35 [ + - + - : 4 : assert_se(CPU_ISSET_S(1, c.allocated, c.set));
- + ]
36 [ + - + - : 4 : assert_se(CPU_ISSET_S(2, c.allocated, c.set));
- + ]
37 [ + - + - : 4 : assert_se(CPU_ISSET_S(4, c.allocated, c.set));
- + ]
38 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
39 : :
40 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
41 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
42 : 4 : str = mfree(str);
43 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
44 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
45 [ - + ]: 4 : assert_se(streq(str, "1-2 4"));
46 : 4 : str = mfree(str);
47 : 4 : cpu_set_reset(&c);
48 : :
49 : : /* A more interesting range */
50 [ - + ]: 4 : assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
51 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
52 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
53 [ + + ]: 20 : for (cpu = 0; cpu < 4; cpu++)
54 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
55 [ + + ]: 20 : for (cpu = 8; cpu < 12; cpu++)
56 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
57 : :
58 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
59 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
60 : 4 : str = mfree(str);
61 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
62 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
63 [ - + ]: 4 : assert_se(streq(str, "0-3 8-11"));
64 : 4 : str = mfree(str);
65 : 4 : cpu_set_reset(&c);
66 : :
67 : : /* Quoted strings */
68 [ - + ]: 4 : assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
69 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
70 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 4);
71 [ + + ]: 20 : for (cpu = 8; cpu < 12; cpu++)
72 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
73 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
74 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
75 : 4 : str = mfree(str);
76 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
77 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
78 [ - + ]: 4 : assert_se(streq(str, "8-11"));
79 : 4 : str = mfree(str);
80 : 4 : cpu_set_reset(&c);
81 : :
82 : : /* Use commas as separators */
83 [ - + ]: 4 : assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
84 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
85 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
86 [ + + ]: 20 : for (cpu = 0; cpu < 4; cpu++)
87 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
88 [ + + ]: 20 : for (cpu = 8; cpu < 12; cpu++)
89 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
90 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
91 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
92 : 4 : str = mfree(str);
93 : 4 : cpu_set_reset(&c);
94 : :
95 : : /* Commas with spaces (and trailing comma, space) */
96 [ - + ]: 4 : assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
97 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
98 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 9);
99 [ + + ]: 36 : for (cpu = 0; cpu < 8; cpu++)
100 [ + - + - : 32 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
101 : :
102 [ + - + - : 4 : assert_se(CPU_ISSET_S(63, c.allocated, c.set));
- + ]
103 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
104 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
105 : 4 : str = mfree(str);
106 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
107 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
108 [ - + ]: 4 : assert_se(streq(str, "0-7 63"));
109 : 4 : str = mfree(str);
110 : 4 : cpu_set_reset(&c);
111 : :
112 : : /* Ranges */
113 [ - + ]: 4 : assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
114 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
115 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
116 [ + + ]: 20 : for (cpu = 0; cpu < 4; cpu++)
117 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
118 [ + + ]: 20 : for (cpu = 8; cpu < 12; cpu++)
119 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
120 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
121 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
122 : 4 : str = mfree(str);
123 : 4 : cpu_set_reset(&c);
124 : :
125 : : /* Ranges with trailing comma, space */
126 [ - + ]: 4 : assert_se(parse_cpu_set_full("0-3 8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
127 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
128 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
129 [ + + ]: 20 : for (cpu = 0; cpu < 4; cpu++)
130 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
131 [ + + ]: 20 : for (cpu = 8; cpu < 12; cpu++)
132 [ + - + - : 16 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
133 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
134 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
135 : 4 : str = mfree(str);
136 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
137 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
138 [ - + ]: 4 : assert_se(streq(str, "0-3 8-11"));
139 : 4 : str = mfree(str);
140 : 4 : cpu_set_reset(&c);
141 : :
142 : : /* Negative range (returns empty cpu_set) */
143 [ - + ]: 4 : assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
144 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
145 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
146 : 4 : cpu_set_reset(&c);
147 : :
148 : : /* Overlapping ranges */
149 [ - + ]: 4 : assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
150 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
151 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 12);
152 [ + + ]: 52 : for (cpu = 0; cpu < 12; cpu++)
153 [ + - + - : 48 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
154 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
155 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
156 : 4 : str = mfree(str);
157 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
158 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
159 [ - + ]: 4 : assert_se(streq(str, "0-11"));
160 : 4 : str = mfree(str);
161 : 4 : cpu_set_reset(&c);
162 : :
163 : : /* Mix ranges and individual CPUs */
164 [ - + ]: 4 : assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
165 [ - + ]: 4 : assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
166 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
167 [ + - + - : 4 : assert_se(CPU_ISSET_S(0, c.allocated, c.set));
- + ]
168 [ + - + - : 4 : assert_se(CPU_ISSET_S(2, c.allocated, c.set));
- + ]
169 [ + + ]: 36 : for (cpu = 4; cpu < 12; cpu++)
170 [ + - + - : 32 : assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
- + ]
171 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
172 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
173 : 4 : str = mfree(str);
174 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
175 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
176 [ - + ]: 4 : assert_se(streq(str, "0 2 4-11"));
177 : 4 : str = mfree(str);
178 : 4 : cpu_set_reset(&c);
179 : :
180 : : /* Garbage */
181 [ - + ]: 4 : assert_se(parse_cpu_set_full("0 1 2 3 garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
182 [ - + ]: 4 : assert_se(!c.set);
183 [ - + ]: 4 : assert_se(c.allocated == 0);
184 : :
185 : : /* Range with garbage */
186 [ - + ]: 4 : assert_se(parse_cpu_set_full("0-3 8-garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
187 [ - + ]: 4 : assert_se(!c.set);
188 [ - + ]: 4 : assert_se(c.allocated == 0);
189 : :
190 : : /* Empty string */
191 [ - + ]: 4 : assert_se(parse_cpu_set_full("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
192 [ - + ]: 4 : assert_se(!c.set); /* empty string returns NULL */
193 [ - + ]: 4 : assert_se(c.allocated == 0);
194 : :
195 : : /* Runaway quoted string */
196 [ - + ]: 4 : assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
197 [ - + ]: 4 : assert_se(!c.set);
198 [ - + ]: 4 : assert_se(c.allocated == 0);
199 : :
200 : : /* Maximum allocation */
201 [ - + ]: 4 : assert_se(parse_cpu_set_full("8000-8191", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
202 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 192);
203 [ - + ]: 4 : assert_se(str = cpu_set_to_string(&c));
204 [ + - ]: 4 : log_info("cpu_set_to_string: %s", str);
205 : 4 : str = mfree(str);
206 [ - + ]: 4 : assert_se(str = cpu_set_to_range_string(&c));
207 [ + - ]: 4 : log_info("cpu_set_to_range_string: %s", str);
208 [ - + ]: 4 : assert_se(streq(str, "8000-8191"));
209 : 4 : str = mfree(str);
210 : 4 : cpu_set_reset(&c);
211 : 4 : }
212 : :
213 : 4 : static void test_parse_cpu_set_extend(void) {
214 : 4 : CPUSet c = {};
215 : 4 : _cleanup_free_ char *s1 = NULL, *s2 = NULL;
216 : :
217 [ + - ]: 4 : log_info("/* %s */", __func__);
218 : :
219 [ - + ]: 4 : assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
220 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
221 [ - + ]: 4 : assert_se(s1 = cpu_set_to_string(&c));
222 [ + - ]: 4 : log_info("cpu_set_to_string: %s", s1);
223 : :
224 [ - + ]: 4 : assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
225 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
226 [ - + ]: 4 : assert_se(s2 = cpu_set_to_string(&c));
227 [ + - ]: 4 : log_info("cpu_set_to_string: %s", s2);
228 : :
229 [ - + ]: 4 : assert_se(parse_cpu_set_extend("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
230 [ - + ]: 4 : assert_se(!c.set);
231 [ - + ]: 4 : assert_se(c.allocated == 0);
232 [ + - ]: 4 : log_info("cpu_set_to_string: (null)");
233 : 4 : }
234 : :
235 : 4 : static void test_cpu_set_to_from_dbus(void) {
236 : 4 : _cleanup_(cpu_set_reset) CPUSet c = {}, c2 = {};
237 : 4 : _cleanup_free_ char *s = NULL;
238 : :
239 [ + - ]: 4 : log_info("/* %s */", __func__);
240 : :
241 [ - + ]: 4 : assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
242 [ - + ]: 4 : assert_se(s = cpu_set_to_string(&c));
243 [ + - ]: 4 : log_info("cpu_set_to_string: %s", s);
244 [ - + ]: 4 : assert_se(CPU_COUNT_S(c.allocated, c.set) == 104);
245 : :
246 : 4 : _cleanup_free_ uint8_t *array = NULL;
247 : : size_t allocated;
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";
252 : :
253 [ - + ]: 4 : assert_se(cpu_set_to_dbus(&c, &array, &allocated) == 0);
254 [ - + ]: 4 : assert_se(array);
255 [ - + ]: 4 : assert_se(allocated == c.allocated);
256 : :
257 [ - + ]: 4 : assert_se(allocated <= sizeof expected);
258 [ - + ]: 4 : assert_se(allocated >= DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */
259 [ - + ]: 4 : assert(memcmp(array, expected, allocated) == 0);
260 : :
261 [ - + ]: 4 : assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0);
262 [ - + ]: 4 : assert_se(c2.set);
263 [ - + ]: 4 : assert_se(c2.allocated == c.allocated);
264 [ - + ]: 4 : assert_se(memcmp(c.set, c2.set, c.allocated) == 0);
265 : 4 : }
266 : :
267 : 4 : static void test_cpus_in_affinity_mask(void) {
268 : : int r;
269 : :
270 : 4 : r = cpus_in_affinity_mask();
271 [ - + ]: 4 : assert(r > 0);
272 [ + - ]: 4 : log_info("cpus_in_affinity_mask: %d", r);
273 : 4 : }
274 : :
275 : 4 : int main(int argc, char *argv[]) {
276 [ + - ]: 4 : log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
277 [ + - ]: 4 : log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
278 [ + - ]: 4 : log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64));
279 [ + - ]: 4 : log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65));
280 [ + - ]: 4 : log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024));
281 [ + - ]: 4 : log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025));
282 [ + - ]: 4 : log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
283 : :
284 : 4 : test_parse_cpu_set();
285 : 4 : test_parse_cpu_set_extend();
286 : 4 : test_cpus_in_affinity_mask();
287 : 4 : test_cpu_set_to_from_dbus();
288 : :
289 : 4 : return 0;
290 : : }
|