xref: /linux/tools/tracing/rtla/tests/unit/cli_opt_callback.c (revision 09005a63988521f74111fae344aecb3f63306168)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #define _GNU_SOURCE
4 #include <stdio.h>
5 #include <check.h>
6 
7 #define RTLA_ALLOW_CLI_P_H
8 #include "../../src/cli_p.h"
9 #include "cli_params_assert.h"
10 
11 #define TEST_CALLBACK(value, cb) OPT_CALLBACK('t', "test", value, "test value", "test help", cb)
12 #define TEST_LLONG_RANGE(value, lo, hi) \
13 	RTLA_OPT_CALLBACK_DATA('t', "test", value, "test value", "test help", \
14 	opt_llong_callback, LLONG_RANGE(lo, hi))
15 #define TEST_INT_RANGE(value, lo, hi) \
16 	RTLA_OPT_CALLBACK_DATA('t', "test", value, "test value", "test help", \
17 	opt_int_callback, INT_RANGE(lo, hi))
18 
19 START_TEST(test_opt_llong_callback_simple)
20 {
21 	long long test_value = 0;
22 	const struct option opt = TEST_CALLBACK(&test_value, opt_llong_callback);
23 
24 	ck_assert_int_eq(opt_llong_callback(&opt, "1234567890", 0), 0);
25 	ck_assert_int_eq(test_value, 1234567890);
26 }
27 END_TEST
28 
29 START_TEST(test_opt_llong_callback_max)
30 {
31 	long long test_value = 0;
32 	const struct option opt = TEST_CALLBACK(&test_value, opt_llong_callback);
33 
34 	ck_assert_int_eq(opt_llong_callback(&opt, "9223372036854775807", 0), 0);
35 	ck_assert_int_eq(test_value, 9223372036854775807LL);
36 }
37 END_TEST
38 
39 START_TEST(test_opt_llong_callback_min)
40 {
41 	long long test_value = 0;
42 	const struct option opt = TEST_CALLBACK(&test_value, opt_llong_callback);
43 
44 	ck_assert_int_eq(opt_llong_callback(&opt, "-9223372036854775808", 0), 0);
45 	ck_assert_int_eq(test_value, ~9223372036854775807LL);
46 }
47 END_TEST
48 
49 START_TEST(test_opt_llong_callback_non_numeric)
50 {
51 	long long test_value = 0;
52 	const struct option opt = TEST_CALLBACK(&test_value, opt_llong_callback);
53 
54 	assert(freopen("/dev/null", "w", stderr));
55 	ck_assert_int_eq(opt_llong_callback(&opt, "abc", 0), -1);
56 	ck_assert_int_eq(test_value, 0);
57 }
58 END_TEST
59 
60 START_TEST(test_opt_llong_callback_non_numeric_suffix)
61 {
62 	long long test_value = 0;
63 	const struct option opt = TEST_CALLBACK(&test_value, opt_llong_callback);
64 
65 	assert(freopen("/dev/null", "w", stderr));
66 	ck_assert_int_eq(opt_llong_callback(&opt, "1234567890abc", 0), -1);
67 	ck_assert_int_eq(test_value, 0);
68 }
69 END_TEST
70 
71 START_TEST(test_opt_llong_callback_unset)
72 {
73 	long long test_value = 0;
74 	const struct option opt = TEST_CALLBACK(&test_value, opt_llong_callback);
75 
76 	ck_assert_int_eq(opt_llong_callback(&opt, "1234567890", 0), 0);
77 	ck_assert_int_eq(opt_llong_callback(&opt, NULL, 1), 0);
78 	ck_assert_int_eq(test_value, 0);
79 }
80 END_TEST
81 
82 START_TEST(test_opt_llong_callback_unset_defval)
83 {
84 	long long test_value = 0;
85 	const long long default_value = 42;
86 	const struct option opt = RTLA_OPT_LLONG_DEFVAL('t', "test", &test_value, "test value",
87 							"test help", &default_value);
88 
89 	ck_assert_int_eq(opt_llong_callback(&opt, "1234567890", 0), 0);
90 	ck_assert_int_eq(opt_llong_callback(&opt, NULL, 1), 0);
91 	ck_assert_int_eq(test_value, default_value);
92 }
93 END_TEST
94 
95 START_TEST(test_opt_int_callback_simple)
96 {
97 	int test_value = 0;
98 	const struct option opt = TEST_CALLBACK(&test_value, opt_int_callback);
99 
100 	ck_assert_int_eq(opt_int_callback(&opt, "1234567890", 0), 0);
101 	ck_assert_int_eq(test_value, 1234567890);
102 }
103 END_TEST
104 
105 START_TEST(test_opt_int_callback_max)
106 {
107 	int test_value = 0;
108 	const struct option opt = TEST_CALLBACK(&test_value, opt_int_callback);
109 
110 	ck_assert_int_eq(opt_int_callback(&opt, "2147483647", 0), 0);
111 	ck_assert_int_eq(test_value, 2147483647);
112 }
113 END_TEST
114 
115 START_TEST(test_opt_int_callback_min)
116 {
117 	int test_value = 0;
118 	const struct option opt = TEST_CALLBACK(&test_value, opt_int_callback);
119 
120 	ck_assert_int_eq(opt_int_callback(&opt, "-2147483648", 0), 0);
121 	ck_assert_int_eq(test_value, -2147483648);
122 }
123 END_TEST
124 
125 START_TEST(test_opt_int_callback_non_numeric)
126 {
127 	int test_value = 0;
128 	const struct option opt = TEST_CALLBACK(&test_value, opt_int_callback);
129 
130 	assert(freopen("/dev/null", "w", stderr));
131 	ck_assert_int_eq(opt_int_callback(&opt, "abc", 0), -1);
132 	ck_assert_int_eq(test_value, 0);
133 }
134 END_TEST
135 
136 START_TEST(test_opt_int_callback_non_numeric_suffix)
137 {
138 	int test_value = 0;
139 	const struct option opt = TEST_CALLBACK(&test_value, opt_int_callback);
140 
141 	assert(freopen("/dev/null", "w", stderr));
142 	ck_assert_int_eq(opt_int_callback(&opt, "1234567890abc", 0), -1);
143 	ck_assert_int_eq(test_value, 0);
144 }
145 END_TEST
146 
147 START_TEST(test_opt_int_callback_unset)
148 {
149 	int test_value = 0;
150 	const struct option opt = TEST_CALLBACK(&test_value, opt_int_callback);
151 
152 	ck_assert_int_eq(opt_int_callback(&opt, "1234567890", 0), 0);
153 	ck_assert_int_eq(opt_int_callback(&opt, NULL, 1), 0);
154 	ck_assert_int_eq(test_value, 0);
155 }
156 END_TEST
157 
158 START_TEST(test_opt_int_callback_unset_defval)
159 {
160 	int test_value = 0;
161 	const struct option opt = RTLA_OPT_INT_DEFVAL('t', "test", &test_value, "test value",
162 						      "test help", 42);
163 
164 	ck_assert_int_eq(opt_int_callback(&opt, "1234567890", 0), 0);
165 	ck_assert_int_eq(opt_int_callback(&opt, NULL, 1), 0);
166 	ck_assert_int_eq(test_value, 42);
167 }
168 END_TEST
169 
170 START_TEST(test_opt_llong_callback_range_in)
171 {
172 	long long test_value = 0;
173 	const struct option opt = TEST_LLONG_RANGE(&test_value, 10, 100);
174 
175 	ck_assert_int_eq(opt_llong_callback(&opt, "50", 0), 0);
176 	ck_assert_int_eq(test_value, 50);
177 }
178 END_TEST
179 
180 START_TEST(test_opt_llong_callback_range_below)
181 {
182 	long long test_value = 0;
183 	const struct option opt = TEST_LLONG_RANGE(&test_value, 10, 100);
184 
185 	assert(freopen("/dev/null", "w", stderr));
186 	ck_assert_int_eq(opt_llong_callback(&opt, "9", 0), -1);
187 }
188 END_TEST
189 
190 START_TEST(test_opt_llong_callback_range_above)
191 {
192 	long long test_value = 0;
193 	const struct option opt = TEST_LLONG_RANGE(&test_value, 10, 100);
194 
195 	assert(freopen("/dev/null", "w", stderr));
196 	ck_assert_int_eq(opt_llong_callback(&opt, "101", 0), -1);
197 }
198 END_TEST
199 
200 START_TEST(test_opt_llong_callback_range_boundary)
201 {
202 	long long test_value = 0;
203 	const struct option opt = TEST_LLONG_RANGE(&test_value, 10, 100);
204 
205 	ck_assert_int_eq(opt_llong_callback(&opt, "10", 0), 0);
206 	ck_assert_int_eq(test_value, 10);
207 	ck_assert_int_eq(opt_llong_callback(&opt, "100", 0), 0);
208 	ck_assert_int_eq(test_value, 100);
209 }
210 END_TEST
211 
212 START_TEST(test_opt_int_callback_range_in)
213 {
214 	int test_value = 0;
215 	const struct option opt = TEST_INT_RANGE(&test_value, 0, 10000);
216 
217 	ck_assert_int_eq(opt_int_callback(&opt, "5000", 0), 0);
218 	ck_assert_int_eq(test_value, 5000);
219 }
220 END_TEST
221 
222 START_TEST(test_opt_int_callback_range_below)
223 {
224 	int test_value = 0;
225 	const struct option opt = TEST_INT_RANGE(&test_value, 0, 10000);
226 
227 	assert(freopen("/dev/null", "w", stderr));
228 	ck_assert_int_eq(opt_int_callback(&opt, "-1", 0), -1);
229 }
230 END_TEST
231 
232 START_TEST(test_opt_int_callback_range_above)
233 {
234 	int test_value = 0;
235 	const struct option opt = TEST_INT_RANGE(&test_value, 0, 10000);
236 
237 	assert(freopen("/dev/null", "w", stderr));
238 	ck_assert_int_eq(opt_int_callback(&opt, "10001", 0), -1);
239 }
240 END_TEST
241 
242 START_TEST(test_opt_int_callback_range_boundary)
243 {
244 	int test_value = 0;
245 	const struct option opt = TEST_INT_RANGE(&test_value, 0, 10000);
246 
247 	ck_assert_int_eq(opt_int_callback(&opt, "0", 0), 0);
248 	ck_assert_int_eq(test_value, 0);
249 	ck_assert_int_eq(opt_int_callback(&opt, "10000", 0), 0);
250 	ck_assert_int_eq(test_value, 10000);
251 }
252 END_TEST
253 
254 START_TEST(test_opt_cpus_cb)
255 {
256 	struct common_params params = {0};
257 	const struct option opt = TEST_CALLBACK(&params, opt_cpus_cb);
258 
259 	nr_cpus = 4;
260 	ck_assert_int_eq(opt_cpus_cb(&opt, "0-3", 0), 0);
261 	ck_assert_str_eq(params.cpus, "0-3");
262 }
263 END_TEST
264 
265 START_TEST(test_opt_cpus_cb_invalid)
266 {
267 	struct common_params params = {0};
268 	const struct option opt = TEST_CALLBACK(&params, opt_cpus_cb);
269 
270 	nr_cpus = 4;
271 	assert(freopen("/dev/null", "w", stderr));
272 	ck_assert_int_eq(opt_cpus_cb(&opt, "0-3,5", 0), -1);
273 }
274 END_TEST
275 
276 START_TEST(test_opt_cgroup_cb)
277 {
278 	struct common_params params = {0};
279 	const struct option opt = TEST_CALLBACK(&params, opt_cgroup_cb);
280 
281 	ck_assert_int_eq(opt_cgroup_cb(&opt, "cgroup", 0), 0);
282 	ck_assert_int_eq(params.cgroup, 1);
283 	ck_assert_str_eq(params.cgroup_name, "cgroup");
284 }
285 END_TEST
286 
287 START_TEST(test_opt_cgroup_cb_equals)
288 {
289 	struct common_params params = {0};
290 	const struct option opt = TEST_CALLBACK(&params, opt_cgroup_cb);
291 
292 	ck_assert_int_eq(opt_cgroup_cb(&opt, "=cgroup", 0), 0);
293 	ck_assert_int_eq(params.cgroup, 1);
294 	ck_assert_str_eq(params.cgroup_name, "cgroup");
295 }
296 END_TEST
297 
298 START_TEST(test_opt_cgroup_cb_unset)
299 {
300 	struct common_params params = {0};
301 	const struct option opt = TEST_CALLBACK(&params, opt_cgroup_cb);
302 
303 	ck_assert_int_eq(opt_cgroup_cb(&opt, "cgroup", 0), 0);
304 	ck_assert_int_eq(opt_cgroup_cb(&opt, NULL, 1), 0);
305 	ck_assert_int_eq(params.cgroup, 0);
306 	ck_assert_ptr_null(params.cgroup_name);
307 }
308 END_TEST
309 
310 START_TEST(test_opt_duration_cb)
311 {
312 	struct common_params params = {0};
313 	const struct option opt = TEST_CALLBACK(&params, opt_duration_cb);
314 
315 	ck_assert_int_eq(opt_duration_cb(&opt, "1m", 0), 0);
316 	ck_assert_int_eq(params.duration, 60);
317 }
318 END_TEST
319 
320 START_TEST(test_opt_duration_cb_invalid)
321 {
322 	struct common_params params = {0};
323 	const struct option opt = TEST_CALLBACK(&params, opt_duration_cb);
324 
325 	assert(freopen("/dev/null", "w", stderr));
326 	ck_assert_int_eq(opt_duration_cb(&opt, "abc", 0), -1);
327 }
328 END_TEST
329 
330 START_TEST(test_opt_duration_cb_unset)
331 {
332 	struct common_params params = {0};
333 	const struct option opt = TEST_CALLBACK(&params, opt_duration_cb);
334 
335 	ck_assert_int_eq(opt_duration_cb(&opt, "1m", 0), 0);
336 	ck_assert_int_eq(opt_duration_cb(&opt, NULL, 1), 0);
337 	ck_assert_int_eq(params.duration, 0);
338 }
339 END_TEST
340 
341 START_TEST(test_opt_event_cb)
342 {
343 	struct trace_events *events = NULL;
344 	const struct option opt = TEST_CALLBACK(&events, opt_event_cb);
345 
346 	ck_assert_int_eq(opt_event_cb(&opt, "sched:sched_switch", 0), 0);
347 	ck_assert_str_eq(events->system, "sched");
348 	ck_assert_str_eq(events->event, "sched_switch");
349 	ck_assert_ptr_eq(events->next, NULL);
350 }
351 END_TEST
352 
353 START_TEST(test_opt_event_cb_multiple)
354 {
355 	struct trace_events *events = NULL;
356 	const struct option opt = TEST_CALLBACK(&events, opt_event_cb);
357 
358 	ck_assert_int_eq(opt_event_cb(&opt, "sched:sched_switch", 0), 0);
359 	ck_assert_int_eq(opt_event_cb(&opt, "sched:sched_wakeup", 0), 0);
360 	ck_assert_str_eq(events->system, "sched");
361 	ck_assert_str_eq(events->event, "sched_wakeup");
362 	ck_assert_str_eq(events->next->system, "sched");
363 	ck_assert_str_eq(events->next->event, "sched_switch");
364 	ck_assert_ptr_eq(events->next->next, NULL);
365 }
366 END_TEST
367 
368 START_TEST(test_opt_housekeeping_cb)
369 {
370 	struct common_params __params = {0};
371 	struct common_params *params = &__params;
372 	const struct option opt = TEST_CALLBACK(params, opt_housekeeping_cb);
373 
374 	nr_cpus = 4;
375 	ck_assert_int_eq(opt_housekeeping_cb(&opt, "0-3", 0), 0);
376 	ck_assert_int_eq(params->hk_cpus, 1);
377 	CLI_ASSERT_CPUSET(hk_cpu_set, 0, 1, 2, 3);
378 }
379 END_TEST
380 
381 START_TEST(test_opt_housekeeping_cb_invalid)
382 {
383 	struct common_params params = {0};
384 	const struct option opt = TEST_CALLBACK(&params, opt_housekeeping_cb);
385 
386 	nr_cpus = 4;
387 	assert(freopen("/dev/null", "w", stderr));
388 	ck_assert_int_eq(opt_housekeeping_cb(&opt, "0-3,5", 0), -1);
389 }
390 END_TEST
391 
392 START_TEST(test_opt_housekeeping_cb_unset)
393 {
394 	struct common_params params = {0};
395 	const struct option opt = TEST_CALLBACK(&params, opt_housekeeping_cb);
396 
397 	nr_cpus = 4;
398 	ck_assert_int_eq(opt_housekeeping_cb(&opt, "0-3", 0), 0);
399 	ck_assert_int_eq(opt_housekeeping_cb(&opt, NULL, 1), 0);
400 	ck_assert_int_eq(params.hk_cpus, 0);
401 	ck_assert_int_eq(CPU_COUNT(&params.hk_cpu_set), 0);
402 }
403 END_TEST
404 
405 START_TEST(test_opt_priority_cb)
406 {
407 	struct common_params params = {0};
408 	const struct option opt = TEST_CALLBACK(&params, opt_priority_cb);
409 
410 	ck_assert_int_eq(opt_priority_cb(&opt, "f:95", 0), 0);
411 	ck_assert_int_eq(params.sched_param.sched_policy, SCHED_FIFO);
412 	ck_assert_int_eq(params.sched_param.sched_priority, 95);
413 }
414 END_TEST
415 
416 START_TEST(test_opt_priority_cb_invalid)
417 {
418 	struct common_params params = {0};
419 	const struct option opt = TEST_CALLBACK(&params, opt_priority_cb);
420 
421 	assert(freopen("/dev/null", "w", stderr));
422 	ck_assert_int_eq(opt_priority_cb(&opt, "abc", 0), -1);
423 }
424 END_TEST
425 
426 START_TEST(test_opt_priority_cb_unset)
427 {
428 	struct common_params params = {0};
429 	const struct option opt = TEST_CALLBACK(&params, opt_priority_cb);
430 
431 	ck_assert_int_eq(opt_priority_cb(&opt, "f:95", 0), 0);
432 	ck_assert_int_eq(opt_priority_cb(&opt, NULL, 1), 0);
433 	ck_assert_int_eq(params.sched_param.sched_policy, 0);
434 	ck_assert_int_eq(params.sched_param.sched_priority, 0);
435 }
436 END_TEST
437 
438 START_TEST(test_opt_trigger_cb)
439 {
440 	struct trace_events *events = trace_event_alloc("sched:sched_switch");
441 	const struct option opt = TEST_CALLBACK(&events, opt_trigger_cb);
442 
443 	ck_assert_int_eq(opt_trigger_cb(&opt, "stacktrace", 0), 0);
444 	ck_assert_str_eq(events->trigger, "stacktrace");
445 }
446 END_TEST
447 
448 START_TEST(test_opt_trigger_cb_no_event)
449 {
450 	struct trace_events *events = NULL;
451 	const struct option opt = TEST_CALLBACK(&events, opt_trigger_cb);
452 
453 	assert(freopen("/dev/null", "w", stderr));
454 	ck_assert_int_eq(opt_trigger_cb(&opt, "stacktrace", 0), -1);
455 }
456 END_TEST
457 
458 START_TEST(test_opt_filter_cb)
459 {
460 	struct trace_events *events = trace_event_alloc("sched:sched_switch");
461 	const struct option opt = TEST_CALLBACK(&events, opt_filter_cb);
462 
463 	ck_assert_int_eq(opt_filter_cb(&opt, "comm ~ \"rtla\"", 0), 0);
464 	ck_assert_str_eq(events->filter, "comm ~ \"rtla\"");
465 }
466 END_TEST
467 
468 START_TEST(test_opt_filter_cb_no_event)
469 {
470 	struct trace_events *events = NULL;
471 	const struct option opt = TEST_CALLBACK(&events, opt_filter_cb);
472 
473 	assert(freopen("/dev/null", "w", stderr));
474 	ck_assert_int_eq(opt_filter_cb(&opt, "comm ~ \"rtla\"", 0), -1);
475 }
476 END_TEST
477 
478 START_TEST(test_opt_osnoise_auto_cb)
479 {
480 	struct osnoise_params params = {0};
481 	struct osnoise_cb_data cb_data = {&params};
482 	const struct option opt = TEST_CALLBACK(&cb_data, opt_osnoise_auto_cb);
483 
484 	ck_assert_int_eq(opt_osnoise_auto_cb(&opt, "10", 0), 0);
485 	ck_assert_int_eq(params.common.stop_us, 10);
486 	ck_assert_int_eq(params.threshold, 1);
487 	ck_assert_str_eq(cb_data.trace_output, "osnoise_trace.txt");
488 }
489 END_TEST
490 
491 START_TEST(test_opt_osnoise_auto_cb_unset)
492 {
493 	struct osnoise_params params = {0};
494 	struct osnoise_cb_data cb_data = {&params};
495 	const struct option opt = TEST_CALLBACK(&cb_data, opt_osnoise_auto_cb);
496 
497 	ck_assert_int_eq(opt_osnoise_auto_cb(&opt, "10", 0), 0);
498 	ck_assert_int_eq(opt_osnoise_auto_cb(&opt, NULL, 1), 0);
499 	ck_assert_int_eq(params.common.stop_us, 0);
500 	ck_assert_int_eq(params.threshold, 0);
501 	ck_assert_ptr_null(cb_data.trace_output);
502 }
503 END_TEST
504 
505 
506 START_TEST(test_opt_osnoise_trace_output_cb)
507 {
508 	const char *trace_output = NULL;
509 	const struct option opt = TEST_CALLBACK(&trace_output, opt_osnoise_trace_output_cb);
510 
511 	ck_assert_int_eq(opt_osnoise_trace_output_cb(&opt, "trace.txt", 0), 0);
512 	ck_assert_str_eq(trace_output, "trace.txt");
513 }
514 END_TEST
515 
516 START_TEST(test_opt_osnoise_trace_output_cb_noarg)
517 {
518 	const char *trace_output = NULL;
519 	const struct option opt = TEST_CALLBACK(&trace_output, opt_osnoise_trace_output_cb);
520 
521 	ck_assert_int_eq(opt_osnoise_trace_output_cb(&opt, NULL, 0), 0);
522 	ck_assert_str_eq(trace_output, "osnoise_trace.txt");
523 }
524 END_TEST
525 
526 START_TEST(test_opt_osnoise_trace_output_cb_unset)
527 {
528 	const char *trace_output = NULL;
529 	const struct option opt = TEST_CALLBACK(&trace_output, opt_osnoise_trace_output_cb);
530 
531 	ck_assert_int_eq(opt_osnoise_trace_output_cb(&opt, "trace.txt", 0), 0);
532 	ck_assert_int_eq(opt_osnoise_trace_output_cb(&opt, NULL, 1), 0);
533 	ck_assert_ptr_null(trace_output);
534 }
535 END_TEST
536 
537 START_TEST(test_opt_osnoise_on_threshold_cb)
538 {
539 	struct actions actions = {0};
540 	const struct option opt = TEST_CALLBACK(&actions, opt_osnoise_on_threshold_cb);
541 
542 	ck_assert_int_eq(opt_osnoise_on_threshold_cb(&opt, "trace", 0), 0);
543 	ck_assert_int_eq(actions.len, 1);
544 	ck_assert_int_eq(actions.list[0].type, ACTION_TRACE_OUTPUT);
545 	ck_assert_str_eq(actions.list[0].trace_output, "osnoise_trace.txt");
546 }
547 END_TEST
548 
549 START_TEST(test_opt_osnoise_on_threshold_cb_invalid)
550 {
551 	struct actions actions = {0};
552 	const struct option opt = TEST_CALLBACK(&actions, opt_osnoise_on_threshold_cb);
553 
554 	assert(freopen("/dev/null", "w", stderr));
555 	ck_assert_int_eq(opt_osnoise_on_threshold_cb(&opt, "abc", 0), -1);
556 }
557 END_TEST
558 
559 START_TEST(test_opt_osnoise_on_end_cb)
560 {
561 	struct actions actions = {0};
562 	const struct option opt = TEST_CALLBACK(&actions, opt_osnoise_on_end_cb);
563 
564 	ck_assert_int_eq(opt_osnoise_on_end_cb(&opt, "trace", 0), 0);
565 	ck_assert_int_eq(actions.len, 1);
566 	ck_assert_int_eq(actions.list[0].type, ACTION_TRACE_OUTPUT);
567 	ck_assert_str_eq(actions.list[0].trace_output, "osnoise_trace.txt");
568 }
569 END_TEST
570 
571 START_TEST(test_opt_osnoise_on_end_cb_invalid)
572 {
573 	struct actions actions = {0};
574 	const struct option opt = TEST_CALLBACK(&actions, opt_osnoise_on_end_cb);
575 
576 	assert(freopen("/dev/null", "w", stderr));
577 	ck_assert_int_eq(opt_osnoise_on_end_cb(&opt, "abc", 0), -1);
578 }
579 END_TEST
580 
581 START_TEST(test_opt_timerlat_auto_cb)
582 {
583 	struct timerlat_params params = {0};
584 	struct timerlat_cb_data cb_data = {&params};
585 	const struct option opt = TEST_CALLBACK(&cb_data, opt_timerlat_auto_cb);
586 
587 	ck_assert_int_eq(opt_timerlat_auto_cb(&opt, "10", 0), 0);
588 	ck_assert_int_eq(params.common.stop_us, 10);
589 	ck_assert_int_eq(params.common.stop_total_us, 10);
590 	ck_assert_int_eq(params.print_stack, 10);
591 	ck_assert_str_eq(cb_data.trace_output, "timerlat_trace.txt");
592 }
593 END_TEST
594 
595 START_TEST(test_opt_timerlat_auto_cb_unset)
596 {
597 	struct timerlat_params params = {0};
598 	struct timerlat_cb_data cb_data = {&params};
599 	const struct option opt = TEST_CALLBACK(&cb_data, opt_timerlat_auto_cb);
600 
601 	ck_assert_int_eq(opt_timerlat_auto_cb(&opt, "10", 0), 0);
602 	ck_assert_int_eq(opt_timerlat_auto_cb(&opt, NULL, 1), 0);
603 	ck_assert_int_eq(params.common.stop_us, 0);
604 	ck_assert_int_eq(params.common.stop_total_us, 0);
605 	ck_assert_int_eq(params.print_stack, 0);
606 	ck_assert_ptr_null(cb_data.trace_output);
607 }
608 END_TEST
609 
610 
611 START_TEST(test_opt_aa_only_cb)
612 {
613 	struct timerlat_params params = {0};
614 	const struct option opt = TEST_CALLBACK(&params, opt_aa_only_cb);
615 
616 	ck_assert_int_eq(opt_aa_only_cb(&opt, "10", 0), 0);
617 	ck_assert_int_eq(params.common.stop_us, 10);
618 	ck_assert_int_eq(params.common.stop_total_us, 10);
619 	ck_assert_int_eq(params.print_stack, 10);
620 	ck_assert_int_eq(params.common.aa_only, 1);
621 }
622 END_TEST
623 
624 START_TEST(test_opt_aa_only_cb_unset)
625 {
626 	struct timerlat_params params = {0};
627 	const struct option opt = TEST_CALLBACK(&params, opt_aa_only_cb);
628 
629 	ck_assert_int_eq(opt_aa_only_cb(&opt, "10", 0), 0);
630 	ck_assert_int_eq(opt_aa_only_cb(&opt, NULL, 1), 0);
631 	ck_assert_int_eq(params.common.stop_us, 0);
632 	ck_assert_int_eq(params.common.stop_total_us, 0);
633 	ck_assert_int_eq(params.print_stack, 0);
634 	ck_assert_int_eq(params.common.aa_only, 0);
635 }
636 END_TEST
637 
638 START_TEST(test_opt_timerlat_trace_output_cb)
639 {
640 	const char *trace_output = NULL;
641 	const struct option opt = TEST_CALLBACK(&trace_output, opt_timerlat_trace_output_cb);
642 
643 	ck_assert_int_eq(opt_timerlat_trace_output_cb(&opt, "trace.txt", 0), 0);
644 	ck_assert_str_eq(trace_output, "trace.txt");
645 }
646 END_TEST
647 
648 START_TEST(test_opt_timerlat_trace_output_cb_noarg)
649 {
650 	const char *trace_output = NULL;
651 	const struct option opt = TEST_CALLBACK(&trace_output, opt_timerlat_trace_output_cb);
652 
653 	ck_assert_int_eq(opt_timerlat_trace_output_cb(&opt, NULL, 0), 0);
654 	ck_assert_str_eq(trace_output, "timerlat_trace.txt");
655 }
656 END_TEST
657 
658 START_TEST(test_opt_timerlat_trace_output_cb_unset)
659 {
660 	const char *trace_output = NULL;
661 	const struct option opt = TEST_CALLBACK(&trace_output, opt_timerlat_trace_output_cb);
662 
663 	ck_assert_int_eq(opt_timerlat_trace_output_cb(&opt, "trace.txt", 0), 0);
664 	ck_assert_int_eq(opt_timerlat_trace_output_cb(&opt, NULL, 1), 0);
665 	ck_assert_ptr_null(trace_output);
666 }
667 END_TEST
668 
669 START_TEST(test_opt_timerlat_on_threshold_cb)
670 {
671 	struct actions actions = {0};
672 	const struct option opt = TEST_CALLBACK(&actions, opt_timerlat_on_threshold_cb);
673 
674 	ck_assert_int_eq(opt_timerlat_on_threshold_cb(&opt, "trace", 0), 0);
675 	ck_assert_int_eq(actions.len, 1);
676 	ck_assert_int_eq(actions.list[0].type, ACTION_TRACE_OUTPUT);
677 	ck_assert_str_eq(actions.list[0].trace_output, "timerlat_trace.txt");
678 }
679 END_TEST
680 
681 START_TEST(test_opt_timerlat_on_threshold_cb_invalid)
682 {
683 	struct actions actions = {0};
684 	const struct option opt = TEST_CALLBACK(&actions, opt_timerlat_on_threshold_cb);
685 
686 	assert(freopen("/dev/null", "w", stderr));
687 	ck_assert_int_eq(opt_timerlat_on_threshold_cb(&opt, "abc", 0), -1);
688 }
689 END_TEST
690 
691 START_TEST(test_opt_timerlat_on_end_cb)
692 {
693 	struct actions actions = {0};
694 	const struct option opt = TEST_CALLBACK(&actions, opt_timerlat_on_end_cb);
695 
696 	ck_assert_int_eq(opt_timerlat_on_end_cb(&opt, "trace", 0), 0);
697 	ck_assert_int_eq(actions.len, 1);
698 	ck_assert_int_eq(actions.list[0].type, ACTION_TRACE_OUTPUT);
699 	ck_assert_str_eq(actions.list[0].trace_output, "timerlat_trace.txt");
700 }
701 END_TEST
702 
703 START_TEST(test_opt_timerlat_on_end_cb_invalid)
704 {
705 	struct actions actions = {0};
706 	const struct option opt = TEST_CALLBACK(&actions, opt_timerlat_on_end_cb);
707 
708 	assert(freopen("/dev/null", "w", stderr));
709 	ck_assert_int_eq(opt_timerlat_on_end_cb(&opt, "abc", 0), -1);
710 }
711 END_TEST
712 
713 START_TEST(test_opt_user_threads_cb)
714 {
715 	struct timerlat_params params = {0};
716 	const struct option opt = TEST_CALLBACK(&params, opt_user_threads_cb);
717 
718 	ck_assert_int_eq(opt_user_threads_cb(&opt, NULL, 0), 0);
719 	ck_assert_int_eq(params.common.user_workload, 1);
720 	ck_assert_int_eq(params.common.user_data, 1);
721 }
722 END_TEST
723 
724 START_TEST(test_opt_user_threads_cb_unset)
725 {
726 	struct timerlat_params params = {0};
727 	const struct option opt = TEST_CALLBACK(&params, opt_user_threads_cb);
728 
729 	ck_assert_int_eq(opt_user_threads_cb(&opt, NULL, 0), 0);
730 	ck_assert_int_eq(opt_user_threads_cb(&opt, NULL, 1), 0);
731 	ck_assert_int_eq(params.common.user_workload, 0);
732 	ck_assert_int_eq(params.common.user_data, 0);
733 }
734 END_TEST
735 
736 START_TEST(test_opt_nano_cb)
737 {
738 	struct timerlat_params params = {0};
739 	const struct option opt = TEST_CALLBACK(&params, opt_nano_cb);
740 
741 	ck_assert_int_eq(opt_nano_cb(&opt, NULL, 0), 0);
742 	ck_assert_int_eq(params.common.output_divisor, 1);
743 }
744 END_TEST
745 
746 START_TEST(test_opt_nano_cb_unset)
747 {
748 	struct timerlat_params params = {0};
749 	const struct option opt = TEST_CALLBACK(&params, opt_nano_cb);
750 
751 	ck_assert_int_eq(opt_nano_cb(&opt, NULL, 0), 0);
752 	ck_assert_int_eq(opt_nano_cb(&opt, NULL, 1), 0);
753 	ck_assert_int_eq(params.common.output_divisor, default_output_divisor);
754 }
755 END_TEST
756 
757 START_TEST(test_opt_timerlat_align_cb)
758 {
759 	struct timerlat_params params = {0};
760 	const struct option opt = RTLA_OPT_CALLBACK_DATA('A', "aligned", &params, "us",
761 		"test", opt_timerlat_align_cb, LLONG_RANGE(0, LLONG_MAX));
762 
763 	ck_assert_int_eq(opt_timerlat_align_cb(&opt, "500", 0), 0);
764 	ck_assert(params.timerlat_align);
765 	ck_assert_int_eq(params.timerlat_align_us, 500);
766 }
767 END_TEST
768 
769 START_TEST(test_opt_timerlat_align_cb_invalid)
770 {
771 	struct timerlat_params params = {0};
772 	const struct option opt = RTLA_OPT_CALLBACK_DATA('A', "aligned", &params, "us",
773 		"test", opt_timerlat_align_cb, LLONG_RANGE(0, LLONG_MAX));
774 
775 	assert(freopen("/dev/null", "w", stderr));
776 	ck_assert_int_eq(opt_timerlat_align_cb(&opt, "-1", 0), -1);
777 }
778 END_TEST
779 
780 START_TEST(test_opt_timerlat_align_cb_unset)
781 {
782 	struct timerlat_params params = {0};
783 	const struct option opt = RTLA_OPT_CALLBACK_DATA('A', "aligned", &params, "us",
784 		"test", opt_timerlat_align_cb, LLONG_RANGE(0, LLONG_MAX));
785 
786 	ck_assert_int_eq(opt_timerlat_align_cb(&opt, "500", 0), 0);
787 	ck_assert_int_eq(opt_timerlat_align_cb(&opt, NULL, 1), 0);
788 	ck_assert_int_eq(params.timerlat_align, 0);
789 	ck_assert_int_eq(params.timerlat_align_us, 0);
790 }
791 END_TEST
792 
793 START_TEST(test_opt_stack_format_cb)
794 {
795 	int stack_format = 0;
796 	const struct option opt = TEST_CALLBACK(&stack_format, opt_stack_format_cb);
797 
798 	ck_assert_int_eq(opt_stack_format_cb(&opt, "full", 0), 0);
799 	ck_assert_int_eq(stack_format, STACK_FORMAT_FULL);
800 }
801 END_TEST
802 
803 START_TEST(test_opt_stack_format_cb_invalid)
804 {
805 	int stack_format = 0;
806 	const struct option opt = TEST_CALLBACK(&stack_format, opt_stack_format_cb);
807 
808 	assert(freopen("/dev/null", "w", stderr));
809 	ck_assert_int_eq(opt_stack_format_cb(&opt, "abc", 0), -1);
810 }
811 END_TEST
812 
813 START_TEST(test_opt_stack_format_cb_unset)
814 {
815 	int stack_format = 0;
816 	const struct option opt = TEST_CALLBACK(&stack_format, opt_stack_format_cb);
817 
818 	ck_assert_int_eq(opt_stack_format_cb(&opt, "full", 0), 0);
819 	ck_assert_int_eq(opt_stack_format_cb(&opt, NULL, 1), 0);
820 	ck_assert_int_eq(stack_format, default_stack_format);
821 }
822 END_TEST
823 
824 
825 Suite *cli_opt_callback_suite(void)
826 {
827 	Suite *s = suite_create("cli_opt_callback");
828 	TCase *tc;
829 
830 	tc = tcase_create("common");
831 	tcase_add_test(tc, test_opt_llong_callback_simple);
832 	tcase_add_test(tc, test_opt_llong_callback_max);
833 	tcase_add_test(tc, test_opt_llong_callback_min);
834 	tcase_add_test(tc, test_opt_llong_callback_non_numeric);
835 	tcase_add_test(tc, test_opt_llong_callback_non_numeric_suffix);
836 	tcase_add_test(tc, test_opt_llong_callback_unset);
837 	tcase_add_test(tc, test_opt_llong_callback_unset_defval);
838 	tcase_add_test(tc, test_opt_llong_callback_range_in);
839 	tcase_add_test(tc, test_opt_llong_callback_range_below);
840 	tcase_add_test(tc, test_opt_llong_callback_range_above);
841 	tcase_add_test(tc, test_opt_llong_callback_range_boundary);
842 	tcase_add_test(tc, test_opt_int_callback_simple);
843 	tcase_add_test(tc, test_opt_int_callback_max);
844 	tcase_add_test(tc, test_opt_int_callback_min);
845 	tcase_add_test(tc, test_opt_int_callback_non_numeric);
846 	tcase_add_test(tc, test_opt_int_callback_non_numeric_suffix);
847 	tcase_add_test(tc, test_opt_int_callback_unset);
848 	tcase_add_test(tc, test_opt_int_callback_unset_defval);
849 	tcase_add_test(tc, test_opt_int_callback_range_in);
850 	tcase_add_test(tc, test_opt_int_callback_range_below);
851 	tcase_add_test(tc, test_opt_int_callback_range_above);
852 	tcase_add_test(tc, test_opt_int_callback_range_boundary);
853 	tcase_add_test(tc, test_opt_cpus_cb);
854 	tcase_add_test(tc, test_opt_cpus_cb_invalid);
855 	tcase_add_test(tc, test_opt_cgroup_cb);
856 	tcase_add_test(tc, test_opt_cgroup_cb_equals);
857 	tcase_add_test(tc, test_opt_cgroup_cb_unset);
858 	tcase_add_test(tc, test_opt_duration_cb);
859 	tcase_add_test(tc, test_opt_duration_cb_unset);
860 	tcase_add_test(tc, test_opt_duration_cb_invalid);
861 	tcase_add_test(tc, test_opt_event_cb);
862 	tcase_add_test(tc, test_opt_event_cb_multiple);
863 	tcase_add_test(tc, test_opt_housekeeping_cb);
864 	tcase_add_test(tc, test_opt_housekeeping_cb_invalid);
865 	tcase_add_test(tc, test_opt_housekeeping_cb_unset);
866 	tcase_add_test(tc, test_opt_priority_cb);
867 	tcase_add_test(tc, test_opt_priority_cb_invalid);
868 	tcase_add_test(tc, test_opt_priority_cb_unset);
869 	tcase_add_test(tc, test_opt_trigger_cb);
870 	tcase_add_test(tc, test_opt_trigger_cb_no_event);
871 	tcase_add_test(tc, test_opt_filter_cb);
872 	tcase_add_test(tc, test_opt_filter_cb_no_event);
873 	suite_add_tcase(s, tc);
874 
875 	tc = tcase_create("osnoise");
876 	tcase_add_test(tc, test_opt_osnoise_auto_cb);
877 	tcase_add_test(tc, test_opt_osnoise_auto_cb_unset);
878 	tcase_add_test(tc, test_opt_osnoise_trace_output_cb);
879 	tcase_add_test(tc, test_opt_osnoise_trace_output_cb_noarg);
880 	tcase_add_test(tc, test_opt_osnoise_trace_output_cb_unset);
881 	tcase_add_test(tc, test_opt_osnoise_on_threshold_cb);
882 	tcase_add_test(tc, test_opt_osnoise_on_threshold_cb_invalid);
883 	tcase_add_test(tc, test_opt_osnoise_on_end_cb);
884 	tcase_add_test(tc, test_opt_osnoise_on_end_cb_invalid);
885 	suite_add_tcase(s, tc);
886 
887 	tc = tcase_create("timerlat");
888 	tcase_add_test(tc, test_opt_timerlat_auto_cb);
889 	tcase_add_test(tc, test_opt_timerlat_auto_cb_unset);
890 	tcase_add_test(tc, test_opt_aa_only_cb);
891 	tcase_add_test(tc, test_opt_aa_only_cb_unset);
892 	tcase_add_test(tc, test_opt_timerlat_trace_output_cb);
893 	tcase_add_test(tc, test_opt_timerlat_trace_output_cb_noarg);
894 	tcase_add_test(tc, test_opt_timerlat_trace_output_cb_unset);
895 	tcase_add_test(tc, test_opt_timerlat_on_threshold_cb);
896 	tcase_add_test(tc, test_opt_timerlat_on_threshold_cb_invalid);
897 	tcase_add_test(tc, test_opt_timerlat_on_end_cb);
898 	tcase_add_test(tc, test_opt_timerlat_on_end_cb_invalid);
899 	tcase_add_test(tc, test_opt_user_threads_cb);
900 	tcase_add_test(tc, test_opt_user_threads_cb_unset);
901 	tcase_add_test(tc, test_opt_nano_cb);
902 	tcase_add_test(tc, test_opt_nano_cb_unset);
903 	tcase_add_test(tc, test_opt_stack_format_cb);
904 	tcase_add_test(tc, test_opt_stack_format_cb_invalid);
905 	tcase_add_test(tc, test_opt_stack_format_cb_unset);
906 	tcase_add_test(tc, test_opt_timerlat_align_cb);
907 	tcase_add_test(tc, test_opt_timerlat_align_cb_invalid);
908 	tcase_add_test(tc, test_opt_timerlat_align_cb_unset);
909 	suite_add_tcase(s, tc);
910 
911 	return s;
912 }
913