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