xref: /linux/tools/tracing/rtla/tests/unit/timerlat_top_cli.c (revision 244d0cbff2efa13931115784e5dc4d1270a04ec7)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #define _GNU_SOURCE
4 #include <check.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <sched.h>
8 #include <limits.h>
9 #include <unistd.h>
10 #include <sys/sysinfo.h>
11 
12 #include <linux/container_of.h>
13 
14 #include "cli_params_assert.h"
15 #include "../../src/cli.h"
16 
17 #define PARSE_ARGS(...) char *argv[] = { __VA_ARGS__, NULL  };\
18 			int argc = sizeof(argv) / sizeof(char *) - 1;\
19 			struct common_params *params =\
20 				timerlat_top_parse_args(argc, argv);\
21 			struct timerlat_params *tlat_params __maybe_unused =\
22 				to_timerlat_params(params)
23 
24 /* Tracing Options */
25 
26 START_TEST(test_irq_short)
27 {
28 	PARSE_ARGS("timerlat", "top", "-i", "20");
29 
30 	ck_assert_int_eq(params->stop_us, 20);
31 }
32 END_TEST
33 
34 START_TEST(test_irq_long)
35 {
36 	PARSE_ARGS("timerlat", "top", "--irq", "20");
37 
38 	ck_assert_int_eq(params->stop_us, 20);
39 }
40 END_TEST
41 
42 START_TEST(test_period_short)
43 {
44 	PARSE_ARGS("timerlat", "top", "-p", "200");
45 
46 	ck_assert_int_eq(tlat_params->timerlat_period_us, 200);
47 }
48 END_TEST
49 
50 START_TEST(test_period_long)
51 {
52 	PARSE_ARGS("timerlat", "top", "--period", "200");
53 
54 	ck_assert_int_eq(tlat_params->timerlat_period_us, 200);
55 }
56 END_TEST
57 
58 START_TEST(test_stack_short)
59 {
60 	PARSE_ARGS("timerlat", "top", "-s", "20");
61 
62 	ck_assert_int_eq(tlat_params->print_stack, 20);
63 }
64 END_TEST
65 
66 START_TEST(test_stack_long)
67 {
68 	PARSE_ARGS("timerlat", "top", "--stack", "20");
69 
70 	ck_assert_int_eq(tlat_params->print_stack, 20);
71 }
72 END_TEST
73 
74 START_TEST(test_thread_short)
75 {
76 	PARSE_ARGS("timerlat", "top", "-T", "20");
77 
78 	ck_assert_int_eq(params->stop_total_us, 20);
79 }
80 END_TEST
81 
82 START_TEST(test_thread_long)
83 {
84 	PARSE_ARGS("timerlat", "top", "--thread", "20");
85 
86 	ck_assert_int_eq(params->stop_total_us, 20);
87 }
88 END_TEST
89 
90 /* Event Configuration */
91 
92 START_TEST(test_event_short)
93 {
94 	PARSE_ARGS("timerlat", "top", "-e", "system:event");
95 
96 	CLI_ASSERT_SINGLE_EVENT("system", "event");
97 }
98 END_TEST
99 
100 START_TEST(test_event_long)
101 {
102 	PARSE_ARGS("timerlat", "top", "--event", "system:event");
103 
104 	CLI_ASSERT_SINGLE_EVENT("system", "event");
105 }
106 END_TEST
107 
108 START_TEST(test_filter)
109 {
110 	PARSE_ARGS("timerlat", "top", "-e", "system:event", "--filter", "filter");
111 
112 	CLI_ASSERT_SINGLE_FILTER("filter");
113 }
114 END_TEST
115 
116 START_TEST(test_trigger)
117 {
118 	PARSE_ARGS("timerlat", "top", "-e", "system:event", "--trigger", "trigger");
119 
120 	CLI_ASSERT_SINGLE_TRIGGER("trigger");
121 }
122 END_TEST
123 
124 START_TEST(test_trace_short_noarg)
125 {
126 	PARSE_ARGS("timerlat", "top", "-t");
127 
128 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
129 				 "timerlat_trace.txt");
130 }
131 END_TEST
132 
133 START_TEST(test_trace_short_followarg)
134 {
135 	PARSE_ARGS("timerlat", "top", "-t", "-d", "20");
136 
137 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
138 				 "timerlat_trace.txt");
139 	ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */
140 }
141 END_TEST
142 
143 START_TEST(test_trace_short_space)
144 {
145 	PARSE_ARGS("timerlat", "top", "-t", "tracefile");
146 
147 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
148 				 "tracefile");
149 }
150 END_TEST
151 
152 START_TEST(test_trace_short_equals)
153 {
154 	PARSE_ARGS("timerlat", "top", "-t=tracefile");
155 
156 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
157 				 "tracefile");
158 }
159 END_TEST
160 
161 START_TEST(test_trace_long_noarg)
162 {
163 	PARSE_ARGS("timerlat", "top", "--trace");
164 
165 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
166 				 "timerlat_trace.txt");
167 }
168 END_TEST
169 
170 START_TEST(test_trace_long_followarg)
171 {
172 	PARSE_ARGS("timerlat", "top", "--trace", "-d", "20");
173 
174 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
175 				 "timerlat_trace.txt");
176 	ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */
177 }
178 END_TEST
179 
180 START_TEST(test_trace_long_space)
181 {
182 	PARSE_ARGS("timerlat", "top", "--trace", "tracefile");
183 
184 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
185 				 "tracefile");
186 }
187 END_TEST
188 
189 START_TEST(test_trace_long_equals)
190 {
191 	PARSE_ARGS("timerlat", "top", "--trace=tracefile");
192 
193 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
194 				 "tracefile");
195 }
196 END_TEST
197 
198 /* CPU Configuration */
199 
200 START_TEST(test_cpus_short)
201 {
202 	nr_cpus = 4;
203 
204 	PARSE_ARGS("timerlat", "top", "-c", "0-1,3");
205 
206 	ck_assert_str_eq(params->cpus, "0-1,3");
207 	CLI_ASSERT_CPUSET(monitored_cpus, 0, 1, 3);
208 }
209 END_TEST
210 
211 START_TEST(test_cpus_long)
212 {
213 	nr_cpus = 4;
214 
215 	PARSE_ARGS("timerlat", "top", "--cpus", "0-1,3");
216 
217 	ck_assert_str_eq(params->cpus, "0-1,3");
218 	CLI_ASSERT_CPUSET(monitored_cpus, 0, 1, 3);
219 }
220 END_TEST
221 
222 START_TEST(test_housekeeping_short)
223 {
224 	nr_cpus = 4;
225 
226 	PARSE_ARGS("timerlat", "top", "-H", "0-1,3");
227 
228 	CLI_ASSERT_CPUSET(hk_cpu_set, 0, 1, 3);
229 }
230 END_TEST
231 
232 START_TEST(test_housekeeping_long)
233 {
234 	nr_cpus = 4;
235 
236 	PARSE_ARGS("timerlat", "top", "--house-keeping", "0-1,3");
237 
238 	CLI_ASSERT_CPUSET(hk_cpu_set, 0, 1, 3);
239 }
240 END_TEST
241 
242 /* Thread Configuration */
243 
244 START_TEST(test_cgroup_short_noarg)
245 {
246 	PARSE_ARGS("timerlat", "top", "-C");
247 
248 	ck_assert(params->cgroup);
249 	ck_assert_ptr_null(params->cgroup_name);
250 }
251 END_TEST
252 
253 START_TEST(test_cgroup_short_space)
254 {
255 	PARSE_ARGS("timerlat", "top", "-C", "cgroup");
256 
257 	ck_assert(params->cgroup);
258 	ck_assert_str_eq(params->cgroup_name, "cgroup");
259 }
260 END_TEST
261 
262 START_TEST(test_cgroup_short_equals)
263 {
264 	PARSE_ARGS("timerlat", "top", "-C=cgroup");
265 
266 	ck_assert(params->cgroup);
267 	ck_assert_str_eq(params->cgroup_name, "cgroup");
268 }
269 END_TEST
270 
271 START_TEST(test_cgroup_long_noarg)
272 {
273 	PARSE_ARGS("timerlat", "top", "--cgroup");
274 
275 	ck_assert(params->cgroup);
276 	ck_assert_ptr_null(params->cgroup_name);
277 }
278 END_TEST
279 
280 START_TEST(test_cgroup_long_space)
281 {
282 	PARSE_ARGS("timerlat", "top", "--cgroup", "cgroup");
283 
284 	ck_assert(params->cgroup);
285 	ck_assert_str_eq(params->cgroup_name, "cgroup");
286 }
287 END_TEST
288 
289 START_TEST(test_cgroup_long_equals)
290 {
291 	PARSE_ARGS("timerlat", "top", "--cgroup=cgroup");
292 
293 	ck_assert(params->cgroup);
294 	ck_assert_str_eq(params->cgroup_name, "cgroup");
295 }
296 END_TEST
297 
298 START_TEST(test_kernel_threads_short)
299 {
300 	PARSE_ARGS("timerlat", "top", "-k");
301 
302 	ck_assert(params->kernel_workload);
303 	ck_assert(!params->user_workload);
304 	ck_assert(!params->user_data);
305 }
306 END_TEST
307 
308 START_TEST(test_kernel_threads_long)
309 {
310 	PARSE_ARGS("timerlat", "top", "--kernel-threads");
311 
312 	ck_assert(params->kernel_workload);
313 	ck_assert(!params->user_workload);
314 	ck_assert(!params->user_data);
315 }
316 END_TEST
317 
318 START_TEST(test_priority_short)
319 {
320 	PARSE_ARGS("timerlat", "top", "-P", "f:95");
321 
322 	ck_assert_int_eq(params->sched_param.sched_policy, SCHED_FIFO);
323 	ck_assert_int_eq(params->sched_param.sched_priority, 95);
324 }
325 END_TEST
326 
327 START_TEST(test_priority_long)
328 {
329 	PARSE_ARGS("timerlat", "top", "--priority", "f:95");
330 
331 	ck_assert_int_eq(params->sched_param.sched_policy, SCHED_FIFO);
332 	ck_assert_int_eq(params->sched_param.sched_priority, 95);
333 }
334 END_TEST
335 
336 START_TEST(test_user_load_short)
337 {
338 	PARSE_ARGS("timerlat", "top", "-U");
339 
340 	ck_assert(!params->kernel_workload);
341 	ck_assert(!params->user_workload);
342 	ck_assert(params->user_data);
343 }
344 END_TEST
345 
346 START_TEST(test_user_load_long)
347 {
348 	PARSE_ARGS("timerlat", "top", "--user-load");
349 
350 	ck_assert(!params->kernel_workload);
351 	ck_assert(!params->user_workload);
352 	ck_assert(params->user_data);
353 }
354 END_TEST
355 
356 START_TEST(test_user_threads_short)
357 {
358 	PARSE_ARGS("timerlat", "top", "-u");
359 
360 	ck_assert(!params->kernel_workload);
361 	ck_assert(params->user_workload);
362 	ck_assert(params->user_data);
363 }
364 END_TEST
365 
366 START_TEST(test_user_threads_long)
367 {
368 	PARSE_ARGS("timerlat", "top", "--user-threads");
369 
370 	ck_assert(!params->kernel_workload);
371 	ck_assert(params->user_workload);
372 	ck_assert(params->user_data);
373 }
374 END_TEST
375 
376 /* Output */
377 
378 START_TEST(test_nano_short)
379 {
380 	PARSE_ARGS("timerlat", "top", "-n");
381 
382 	ck_assert_int_eq(params->output_divisor, 1);
383 }
384 END_TEST
385 
386 START_TEST(test_nano_long)
387 {
388 	PARSE_ARGS("timerlat", "top", "--nano");
389 
390 	ck_assert_int_eq(params->output_divisor, 1);
391 }
392 END_TEST
393 
394 START_TEST(test_quiet_short)
395 {
396 	PARSE_ARGS("timerlat", "top", "-q");
397 
398 	ck_assert(params->quiet);
399 }
400 END_TEST
401 
402 START_TEST(test_quiet_long)
403 {
404 	PARSE_ARGS("timerlat", "top", "--quiet");
405 
406 	ck_assert(params->quiet);
407 }
408 END_TEST
409 
410 /* System Tuning */
411 
412 START_TEST(test_deepest_idle_state)
413 {
414 	PARSE_ARGS("timerlat", "top", "--deepest-idle-state", "1");
415 
416 	ck_assert_int_eq(tlat_params->deepest_idle_state, 1);
417 }
418 END_TEST
419 
420 START_TEST(test_dma_latency)
421 {
422 	PARSE_ARGS("timerlat", "top", "--dma-latency", "10");
423 
424 	ck_assert_int_eq(tlat_params->dma_latency, 10);
425 }
426 END_TEST
427 
428 START_TEST(test_trace_buffer_size)
429 {
430 	PARSE_ARGS("timerlat", "top", "--trace-buffer-size", "200");
431 
432 	ck_assert_int_eq(params->buffer_size, 200);
433 }
434 END_TEST
435 
436 START_TEST(test_warm_up)
437 {
438 	PARSE_ARGS("timerlat", "top", "--warm-up", "5");
439 
440 	ck_assert_int_eq(params->warmup, 5);
441 }
442 END_TEST
443 
444 /* Auto Analysis and Actions */
445 
446 START_TEST(test_auto)
447 {
448 	PARSE_ARGS("timerlat", "top", "-a", "20");
449 
450 	CLI_TIMERLAT_ASSERT_AUTO(20);
451 }
452 END_TEST
453 
454 START_TEST(test_aa_only)
455 {
456 	PARSE_ARGS("timerlat", "top", "--aa-only", "20");
457 
458 	CLI_TIMERLAT_ASSERT_AA_ONLY(20);
459 }
460 END_TEST
461 
462 START_TEST(test_bpf_action)
463 {
464 	PARSE_ARGS("timerlat", "top", "--bpf-action", "program");
465 
466 	ck_assert_str_eq(tlat_params->bpf_action_program, "program");
467 }
468 END_TEST
469 
470 START_TEST(test_dump_tasks)
471 {
472 	PARSE_ARGS("timerlat", "top", "--dump-tasks");
473 
474 	ck_assert(tlat_params->dump_tasks);
475 }
476 END_TEST
477 
478 START_TEST(test_no_aa)
479 {
480 	PARSE_ARGS("timerlat", "top", "--no-aa");
481 
482 	ck_assert(tlat_params->no_aa);
483 }
484 END_TEST
485 
486 START_TEST(test_on_end)
487 {
488 	PARSE_ARGS("timerlat", "top", "--on-end", "trace");
489 
490 	CLI_ASSERT_SINGLE_ACTION(end_actions, ACTION_TRACE_OUTPUT, trace_output, str,
491 				 "timerlat_trace.txt");
492 }
493 END_TEST
494 
495 START_TEST(test_on_threshold)
496 {
497 	PARSE_ARGS("timerlat", "top", "--on-threshold", "trace");
498 
499 	CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
500 				 "timerlat_trace.txt");
501 }
502 END_TEST
503 
504 START_TEST(test_stack_format)
505 {
506 	PARSE_ARGS("timerlat", "top", "--stack-format", "truncate");
507 
508 	ck_assert_int_eq(tlat_params->stack_format, STACK_FORMAT_TRUNCATE);
509 }
510 END_TEST
511 
512 /* General */
513 
514 START_TEST(test_debug_short)
515 {
516 	PARSE_ARGS("timerlat", "top", "-D");
517 
518 	ck_assert(config_debug);
519 }
520 END_TEST
521 
522 START_TEST(test_debug_long)
523 {
524 	PARSE_ARGS("timerlat", "top", "--debug");
525 
526 	ck_assert(config_debug);
527 }
528 END_TEST
529 
530 START_TEST(test_duration_short)
531 {
532 	PARSE_ARGS("timerlat", "top", "-d", "1m");
533 
534 	ck_assert_int_eq(params->duration, 60);
535 }
536 END_TEST
537 
538 START_TEST(test_duration_long)
539 {
540 	PARSE_ARGS("timerlat", "top", "--duration", "1m");
541 
542 	ck_assert_int_eq(params->duration, 60);
543 }
544 END_TEST
545 
546 Suite *timerlat_top_cli_suite(void)
547 {
548 	Suite *s = suite_create("timerlat_top_cli");
549 	TCase *tc;
550 
551 	tc = tcase_create("tracing_options");
552 	tcase_add_test(tc, test_irq_short);
553 	tcase_add_test(tc, test_irq_long);
554 	tcase_add_test(tc, test_period_short);
555 	tcase_add_test(tc, test_period_long);
556 	tcase_add_test(tc, test_stack_short);
557 	tcase_add_test(tc, test_stack_long);
558 	tcase_add_test(tc, test_thread_short);
559 	tcase_add_test(tc, test_thread_long);
560 	tcase_add_test(tc, test_trace_short_noarg);
561 	tcase_add_test(tc, test_trace_short_followarg);
562 	tcase_add_test(tc, test_trace_short_space);
563 	tcase_add_test(tc, test_trace_short_equals);
564 	tcase_add_test(tc, test_trace_long_noarg);
565 	tcase_add_test(tc, test_trace_long_followarg);
566 	tcase_add_test(tc, test_trace_long_space);
567 	tcase_add_test(tc, test_trace_long_equals);
568 	suite_add_tcase(s, tc);
569 
570 	tc = tcase_create("event_configuration");
571 	tcase_add_test(tc, test_event_short);
572 	tcase_add_test(tc, test_event_long);
573 	tcase_add_test(tc, test_filter);
574 	tcase_add_test(tc, test_trigger);
575 	suite_add_tcase(s, tc);
576 
577 	tc = tcase_create("cpu_configuration");
578 	tcase_add_test(tc, test_cpus_short);
579 	tcase_add_test(tc, test_cpus_long);
580 	tcase_add_test(tc, test_housekeeping_short);
581 	tcase_add_test(tc, test_housekeeping_long);
582 	suite_add_tcase(s, tc);
583 
584 	tc = tcase_create("thread_configuration");
585 	tcase_add_test(tc, test_cgroup_short_noarg);
586 	tcase_add_test(tc, test_cgroup_short_space);
587 	tcase_add_test(tc, test_cgroup_short_equals);
588 	tcase_add_test(tc, test_cgroup_long_noarg);
589 	tcase_add_test(tc, test_cgroup_long_space);
590 	tcase_add_test(tc, test_cgroup_long_equals);
591 	tcase_add_test(tc, test_kernel_threads_short);
592 	tcase_add_test(tc, test_kernel_threads_long);
593 	tcase_add_test(tc, test_priority_short);
594 	tcase_add_test(tc, test_priority_long);
595 	tcase_add_test(tc, test_user_load_short);
596 	tcase_add_test(tc, test_user_load_long);
597 	tcase_add_test(tc, test_user_threads_short);
598 	tcase_add_test(tc, test_user_threads_long);
599 	suite_add_tcase(s, tc);
600 
601 	tc = tcase_create("output");
602 	tcase_add_test(tc, test_nano_short);
603 	tcase_add_test(tc, test_nano_long);
604 	tcase_add_test(tc, test_quiet_short);
605 	tcase_add_test(tc, test_quiet_long);
606 	suite_add_tcase(s, tc);
607 
608 	tc = tcase_create("system_tuning");
609 	tcase_add_test(tc, test_deepest_idle_state);
610 	tcase_add_test(tc, test_dma_latency);
611 	tcase_add_test(tc, test_trace_buffer_size);
612 	tcase_add_test(tc, test_warm_up);
613 	suite_add_tcase(s, tc);
614 
615 	tc = tcase_create("aa_actions");
616 	tcase_add_test(tc, test_auto);
617 	tcase_add_test(tc, test_aa_only);
618 	tcase_add_test(tc, test_bpf_action);
619 	tcase_add_test(tc, test_dump_tasks);
620 	tcase_add_test(tc, test_no_aa);
621 	tcase_add_test(tc, test_on_end);
622 	tcase_add_test(tc, test_on_threshold);
623 	tcase_add_test(tc, test_stack_format);
624 	suite_add_tcase(s, tc);
625 
626 	tc = tcase_create("general");
627 	tcase_add_test(tc, test_debug_short);
628 	tcase_add_test(tc, test_debug_long);
629 	tcase_add_test(tc, test_duration_short);
630 	tcase_add_test(tc, test_duration_long);
631 	suite_add_tcase(s, tc);
632 
633 	return s;
634 }
635