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_hist_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", "hist", "-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", "hist", "--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", "hist", "-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", "hist", "--period", "200"); 53 54 ck_assert_int_eq(tlat_params->timerlat_period_us, 200); 55 } 56 END_TEST 57 58 START_TEST(test_period_unset_short) 59 { 60 PARSE_ARGS("timerlat", "hist", "-p", "200", "--no-period"); 61 62 ck_assert_int_eq(tlat_params->timerlat_period_us, 0); 63 } 64 END_TEST 65 66 START_TEST(test_period_unset_long) 67 { 68 PARSE_ARGS("timerlat", "hist", "--period", "200", "--no-period"); 69 70 ck_assert_int_eq(tlat_params->timerlat_period_us, 0); 71 } 72 END_TEST 73 74 START_TEST(test_stack_short) 75 { 76 PARSE_ARGS("timerlat", "hist", "-s", "20"); 77 78 ck_assert_int_eq(tlat_params->print_stack, 20); 79 } 80 END_TEST 81 82 START_TEST(test_stack_long) 83 { 84 PARSE_ARGS("timerlat", "hist", "--stack", "20"); 85 86 ck_assert_int_eq(tlat_params->print_stack, 20); 87 } 88 END_TEST 89 90 START_TEST(test_thread_short) 91 { 92 PARSE_ARGS("timerlat", "hist", "-T", "20"); 93 94 ck_assert_int_eq(params->stop_total_us, 20); 95 } 96 END_TEST 97 98 START_TEST(test_thread_long) 99 { 100 PARSE_ARGS("timerlat", "hist", "--thread", "20"); 101 102 ck_assert_int_eq(params->stop_total_us, 20); 103 } 104 END_TEST 105 106 START_TEST(test_trace_short_noarg) 107 { 108 PARSE_ARGS("timerlat", "hist", "-t"); 109 110 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 111 "timerlat_trace.txt"); 112 } 113 END_TEST 114 115 START_TEST(test_trace_short_followarg) 116 { 117 PARSE_ARGS("timerlat", "hist", "-t", "-d", "20"); 118 119 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 120 "timerlat_trace.txt"); 121 ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */ 122 } 123 END_TEST 124 125 START_TEST(test_trace_short_space) 126 { 127 PARSE_ARGS("timerlat", "hist", "-t", "tracefile"); 128 129 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 130 "tracefile"); 131 } 132 END_TEST 133 134 START_TEST(test_trace_short_equals) 135 { 136 PARSE_ARGS("timerlat", "hist", "-t=tracefile"); 137 138 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 139 "tracefile"); 140 } 141 END_TEST 142 143 START_TEST(test_trace_long_noarg) 144 { 145 PARSE_ARGS("timerlat", "hist", "--trace"); 146 147 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 148 "timerlat_trace.txt"); 149 } 150 END_TEST 151 152 START_TEST(test_trace_long_followarg) 153 { 154 PARSE_ARGS("timerlat", "hist", "--trace", "-d", "20"); 155 156 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 157 "timerlat_trace.txt"); 158 ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */ 159 } 160 END_TEST 161 162 START_TEST(test_trace_long_space) 163 { 164 PARSE_ARGS("timerlat", "hist", "--trace", "tracefile"); 165 166 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 167 "tracefile"); 168 } 169 END_TEST 170 171 START_TEST(test_trace_long_equals) 172 { 173 PARSE_ARGS("timerlat", "hist", "--trace=tracefile"); 174 175 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 176 "tracefile"); 177 } 178 END_TEST 179 180 /* Event Configuration */ 181 182 START_TEST(test_event_short) 183 { 184 PARSE_ARGS("timerlat", "hist", "-e", "system:event"); 185 186 CLI_ASSERT_SINGLE_EVENT("system", "event"); 187 } 188 END_TEST 189 190 START_TEST(test_event_long) 191 { 192 PARSE_ARGS("timerlat", "hist", "--event", "system:event"); 193 194 CLI_ASSERT_SINGLE_EVENT("system", "event"); 195 } 196 END_TEST 197 198 START_TEST(test_filter) 199 { 200 PARSE_ARGS("timerlat", "hist", "-e", "system:event", "--filter", "filter"); 201 202 CLI_ASSERT_SINGLE_FILTER("filter"); 203 } 204 END_TEST 205 206 START_TEST(test_trigger) 207 { 208 PARSE_ARGS("timerlat", "hist", "-e", "system:event", "--trigger", "trigger"); 209 210 CLI_ASSERT_SINGLE_TRIGGER("trigger"); 211 } 212 END_TEST 213 214 /* CPU Configuration */ 215 216 START_TEST(test_cpus_short) 217 { 218 nr_cpus = 4; 219 220 PARSE_ARGS("timerlat", "hist", "-c", "0-1,3"); 221 222 ck_assert_str_eq(params->cpus, "0-1,3"); 223 CLI_ASSERT_CPUSET(monitored_cpus, 0, 1, 3); 224 } 225 END_TEST 226 227 START_TEST(test_cpus_long) 228 { 229 nr_cpus = 4; 230 231 PARSE_ARGS("timerlat", "hist", "--cpus", "0-1,3"); 232 233 ck_assert_str_eq(params->cpus, "0-1,3"); 234 CLI_ASSERT_CPUSET(monitored_cpus, 0, 1, 3); 235 } 236 END_TEST 237 238 START_TEST(test_housekeeping_short) 239 { 240 nr_cpus = 4; 241 242 PARSE_ARGS("timerlat", "hist", "-H", "0-1,3"); 243 244 CLI_ASSERT_CPUSET(hk_cpu_set, 0, 1, 3); 245 } 246 END_TEST 247 248 START_TEST(test_housekeeping_long) 249 { 250 nr_cpus = 4; 251 252 PARSE_ARGS("timerlat", "hist", "--house-keeping", "0-1,3"); 253 254 CLI_ASSERT_CPUSET(hk_cpu_set, 0, 1, 3); 255 } 256 END_TEST 257 258 /* Thread Configuration */ 259 260 START_TEST(test_cgroup_short_noarg) 261 { 262 PARSE_ARGS("timerlat", "hist", "-C"); 263 264 ck_assert(params->cgroup); 265 ck_assert_ptr_null(params->cgroup_name); 266 } 267 END_TEST 268 269 START_TEST(test_cgroup_short_space) 270 { 271 PARSE_ARGS("timerlat", "hist", "-C", "cgroup"); 272 273 ck_assert(params->cgroup); 274 ck_assert_str_eq(params->cgroup_name, "cgroup"); 275 } 276 END_TEST 277 278 START_TEST(test_cgroup_short_equals) 279 { 280 PARSE_ARGS("timerlat", "hist", "-C=cgroup"); 281 282 ck_assert(params->cgroup); 283 ck_assert_str_eq(params->cgroup_name, "cgroup"); 284 } 285 END_TEST 286 287 START_TEST(test_cgroup_long_noarg) 288 { 289 PARSE_ARGS("timerlat", "hist", "--cgroup"); 290 291 ck_assert(params->cgroup); 292 ck_assert_ptr_null(params->cgroup_name); 293 } 294 END_TEST 295 296 START_TEST(test_cgroup_long_space) 297 { 298 PARSE_ARGS("timerlat", "hist", "--cgroup", "cgroup"); 299 300 ck_assert(params->cgroup); 301 ck_assert_str_eq(params->cgroup_name, "cgroup"); 302 } 303 END_TEST 304 305 START_TEST(test_cgroup_long_equals) 306 { 307 PARSE_ARGS("timerlat", "hist", "--cgroup=cgroup"); 308 309 ck_assert(params->cgroup); 310 ck_assert_str_eq(params->cgroup_name, "cgroup"); 311 } 312 END_TEST 313 314 START_TEST(test_kernel_threads_short) 315 { 316 PARSE_ARGS("timerlat", "hist", "-k"); 317 318 ck_assert(params->kernel_workload); 319 ck_assert(!params->user_workload); 320 ck_assert(!params->user_data); 321 } 322 END_TEST 323 324 START_TEST(test_kernel_threads_long) 325 { 326 PARSE_ARGS("timerlat", "hist", "--kernel-threads"); 327 328 ck_assert(params->kernel_workload); 329 ck_assert(!params->user_workload); 330 ck_assert(!params->user_data); 331 } 332 END_TEST 333 334 START_TEST(test_priority_short) 335 { 336 PARSE_ARGS("timerlat", "hist", "-P", "f:95"); 337 338 ck_assert_int_eq(params->sched_param.sched_policy, SCHED_FIFO); 339 ck_assert_int_eq(params->sched_param.sched_priority, 95); 340 } 341 END_TEST 342 343 START_TEST(test_priority_long) 344 { 345 PARSE_ARGS("timerlat", "hist", "--priority", "f:95"); 346 347 ck_assert_int_eq(params->sched_param.sched_policy, SCHED_FIFO); 348 ck_assert_int_eq(params->sched_param.sched_priority, 95); 349 } 350 END_TEST 351 352 START_TEST(test_user_load_short) 353 { 354 PARSE_ARGS("timerlat", "hist", "-U"); 355 356 ck_assert(!params->kernel_workload); 357 ck_assert(!params->user_workload); 358 ck_assert(params->user_data); 359 } 360 END_TEST 361 362 START_TEST(test_user_load_long) 363 { 364 PARSE_ARGS("timerlat", "hist", "--user-load"); 365 366 ck_assert(!params->kernel_workload); 367 ck_assert(!params->user_workload); 368 ck_assert(params->user_data); 369 } 370 END_TEST 371 372 START_TEST(test_user_threads_short) 373 { 374 PARSE_ARGS("timerlat", "hist", "-u"); 375 376 ck_assert(!params->kernel_workload); 377 ck_assert(params->user_workload); 378 ck_assert(params->user_data); 379 } 380 END_TEST 381 382 START_TEST(test_user_threads_long) 383 { 384 PARSE_ARGS("timerlat", "hist", "--user-threads"); 385 386 ck_assert(!params->kernel_workload); 387 ck_assert(params->user_workload); 388 ck_assert(params->user_data); 389 } 390 END_TEST 391 392 START_TEST(test_aligned_short) 393 { 394 PARSE_ARGS("timerlat", "hist", "-A", "500"); 395 396 ck_assert(tlat_params->timerlat_align); 397 ck_assert_int_eq(tlat_params->timerlat_align_us, 500); 398 } 399 END_TEST 400 401 START_TEST(test_aligned_long) 402 { 403 PARSE_ARGS("timerlat", "hist", "--aligned", "500"); 404 405 ck_assert(tlat_params->timerlat_align); 406 ck_assert_int_eq(tlat_params->timerlat_align_us, 500); 407 } 408 END_TEST 409 410 /* Histogram Options */ 411 412 START_TEST(test_bucket_size_short) 413 { 414 PARSE_ARGS("timerlat", "hist", "-b", "2"); 415 416 ck_assert_int_eq(params->hist.bucket_size, 2); 417 } 418 END_TEST 419 420 START_TEST(test_bucket_size_long) 421 { 422 PARSE_ARGS("timerlat", "hist", "--bucket-size", "2"); 423 424 ck_assert_int_eq(params->hist.bucket_size, 2); 425 } 426 END_TEST 427 428 START_TEST(test_entries_short) 429 { 430 PARSE_ARGS("timerlat", "hist", "-E", "512"); 431 432 ck_assert_int_eq(params->hist.entries, 512); 433 } 434 END_TEST 435 436 START_TEST(test_entries_long) 437 { 438 PARSE_ARGS("timerlat", "hist", "--entries", "512"); 439 440 ck_assert_int_eq(params->hist.entries, 512); 441 } 442 END_TEST 443 444 START_TEST(test_no_header) 445 { 446 PARSE_ARGS("timerlat", "hist", "--no-header"); 447 448 ck_assert(params->hist.no_header); 449 } 450 END_TEST 451 452 START_TEST(test_no_index) 453 { 454 PARSE_ARGS("timerlat", "hist", "--with-zeros", "--no-index"); 455 456 ck_assert(params->hist.no_index); 457 } 458 END_TEST 459 460 START_TEST(test_no_irq) 461 { 462 PARSE_ARGS("timerlat", "hist", "--no-irq"); 463 464 ck_assert(params->hist.no_irq); 465 } 466 END_TEST 467 468 START_TEST(test_no_summary) 469 { 470 PARSE_ARGS("timerlat", "hist", "--no-summary"); 471 472 ck_assert(params->hist.no_summary); 473 } 474 END_TEST 475 476 START_TEST(test_no_thread) 477 { 478 PARSE_ARGS("timerlat", "hist", "--no-thread"); 479 480 ck_assert(params->hist.no_thread); 481 } 482 END_TEST 483 484 START_TEST(test_with_zeros) 485 { 486 PARSE_ARGS("timerlat", "hist", "--with-zeros"); 487 488 ck_assert(params->hist.with_zeros); 489 } 490 END_TEST 491 492 /* Output */ 493 494 START_TEST(test_nano_short) 495 { 496 PARSE_ARGS("timerlat", "hist", "-n"); 497 498 ck_assert_int_eq(params->output_divisor, 1); 499 } 500 END_TEST 501 502 START_TEST(test_nano_long) 503 { 504 PARSE_ARGS("timerlat", "hist", "--nano"); 505 506 ck_assert_int_eq(params->output_divisor, 1); 507 } 508 END_TEST 509 510 /* System Tuning */ 511 512 START_TEST(test_deepest_idle_state) 513 { 514 PARSE_ARGS("timerlat", "hist", "--deepest-idle-state", "1"); 515 516 ck_assert_int_eq(tlat_params->deepest_idle_state, 1); 517 } 518 END_TEST 519 520 START_TEST(test_dma_latency) 521 { 522 PARSE_ARGS("timerlat", "hist", "--dma-latency", "10"); 523 524 ck_assert_int_eq(tlat_params->dma_latency, 10); 525 } 526 END_TEST 527 528 START_TEST(test_trace_buffer_size) 529 { 530 PARSE_ARGS("timerlat", "hist", "--trace-buffer-size", "200"); 531 532 ck_assert_int_eq(params->buffer_size, 200); 533 } 534 END_TEST 535 536 START_TEST(test_warm_up) 537 { 538 PARSE_ARGS("timerlat", "hist", "--warm-up", "5"); 539 540 ck_assert_int_eq(params->warmup, 5); 541 } 542 END_TEST 543 544 /* Auto Analysis and Actions */ 545 546 START_TEST(test_auto) 547 { 548 PARSE_ARGS("timerlat", "hist", "-a", "20"); 549 550 CLI_TIMERLAT_ASSERT_AUTO(20); 551 } 552 END_TEST 553 554 START_TEST(test_bpf_action) 555 { 556 PARSE_ARGS("timerlat", "hist", "--bpf-action", "program"); 557 558 ck_assert_str_eq(tlat_params->bpf_action_program, "program"); 559 } 560 END_TEST 561 562 START_TEST(test_dump_tasks) 563 { 564 PARSE_ARGS("timerlat", "hist", "--dump-tasks"); 565 566 ck_assert(tlat_params->dump_tasks); 567 } 568 END_TEST 569 570 START_TEST(test_no_aa) 571 { 572 PARSE_ARGS("timerlat", "hist", "--no-aa"); 573 574 ck_assert(tlat_params->no_aa); 575 } 576 END_TEST 577 578 START_TEST(test_on_end) 579 { 580 PARSE_ARGS("timerlat", "hist", "--on-end", "trace"); 581 582 CLI_ASSERT_SINGLE_ACTION(end_actions, ACTION_TRACE_OUTPUT, trace_output, str, 583 "timerlat_trace.txt"); 584 } 585 END_TEST 586 587 START_TEST(test_on_threshold) 588 { 589 PARSE_ARGS("timerlat", "hist", "--on-threshold", "trace"); 590 591 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 592 "timerlat_trace.txt"); 593 } 594 END_TEST 595 596 START_TEST(test_stack_format) 597 { 598 PARSE_ARGS("timerlat", "hist", "--stack-format", "truncate"); 599 600 ck_assert_int_eq(tlat_params->stack_format, STACK_FORMAT_TRUNCATE); 601 } 602 END_TEST 603 604 /* General */ 605 606 START_TEST(test_debug_short) 607 { 608 PARSE_ARGS("timerlat", "hist", "-D"); 609 610 ck_assert(config_debug); 611 } 612 END_TEST 613 614 START_TEST(test_debug_long) 615 { 616 PARSE_ARGS("timerlat", "hist", "--debug"); 617 618 ck_assert(config_debug); 619 } 620 END_TEST 621 622 START_TEST(test_duration_short) 623 { 624 PARSE_ARGS("timerlat", "hist", "-d", "1m"); 625 626 ck_assert_int_eq(params->duration, 60); 627 } 628 END_TEST 629 630 START_TEST(test_duration_long) 631 { 632 PARSE_ARGS("timerlat", "hist", "--duration", "1m"); 633 634 ck_assert_int_eq(params->duration, 60); 635 } 636 END_TEST 637 638 Suite *timerlat_hist_cli_suite(void) 639 { 640 Suite *s = suite_create("timerlat_hist_cli"); 641 TCase *tc; 642 643 tc = tcase_create("tracing_options"); 644 tcase_add_test(tc, test_irq_short); 645 tcase_add_test(tc, test_irq_long); 646 tcase_add_test(tc, test_period_short); 647 tcase_add_test(tc, test_period_long); 648 tcase_add_test(tc, test_period_unset_short); 649 tcase_add_test(tc, test_period_unset_long); 650 tcase_add_test(tc, test_stack_short); 651 tcase_add_test(tc, test_stack_long); 652 tcase_add_test(tc, test_thread_short); 653 tcase_add_test(tc, test_thread_long); 654 tcase_add_test(tc, test_trace_short_noarg); 655 tcase_add_test(tc, test_trace_short_followarg); 656 tcase_add_test(tc, test_trace_short_space); 657 tcase_add_test(tc, test_trace_short_equals); 658 tcase_add_test(tc, test_trace_long_noarg); 659 tcase_add_test(tc, test_trace_long_followarg); 660 tcase_add_test(tc, test_trace_long_space); 661 tcase_add_test(tc, test_trace_long_equals); 662 suite_add_tcase(s, tc); 663 664 tc = tcase_create("event_configuration"); 665 tcase_add_test(tc, test_event_short); 666 tcase_add_test(tc, test_event_long); 667 tcase_add_test(tc, test_filter); 668 tcase_add_test(tc, test_trigger); 669 suite_add_tcase(s, tc); 670 671 tc = tcase_create("cpu_configuration"); 672 tcase_add_test(tc, test_cpus_short); 673 tcase_add_test(tc, test_cpus_long); 674 tcase_add_test(tc, test_housekeeping_short); 675 tcase_add_test(tc, test_housekeeping_long); 676 suite_add_tcase(s, tc); 677 678 tc = tcase_create("thread_configuration"); 679 tcase_add_test(tc, test_cgroup_short_noarg); 680 tcase_add_test(tc, test_cgroup_short_space); 681 tcase_add_test(tc, test_cgroup_short_equals); 682 tcase_add_test(tc, test_cgroup_long_noarg); 683 tcase_add_test(tc, test_cgroup_long_space); 684 tcase_add_test(tc, test_cgroup_long_equals); 685 tcase_add_test(tc, test_kernel_threads_short); 686 tcase_add_test(tc, test_kernel_threads_long); 687 tcase_add_test(tc, test_priority_short); 688 tcase_add_test(tc, test_priority_long); 689 tcase_add_test(tc, test_user_load_short); 690 tcase_add_test(tc, test_user_load_long); 691 tcase_add_test(tc, test_user_threads_short); 692 tcase_add_test(tc, test_user_threads_long); 693 tcase_add_test(tc, test_aligned_short); 694 tcase_add_test(tc, test_aligned_long); 695 suite_add_tcase(s, tc); 696 697 tc = tcase_create("histogram_options"); 698 tcase_add_test(tc, test_bucket_size_short); 699 tcase_add_test(tc, test_bucket_size_long); 700 tcase_add_test(tc, test_entries_short); 701 tcase_add_test(tc, test_entries_long); 702 tcase_add_test(tc, test_no_header); 703 tcase_add_test(tc, test_no_index); 704 tcase_add_test(tc, test_no_irq); 705 tcase_add_test(tc, test_no_summary); 706 tcase_add_test(tc, test_no_thread); 707 tcase_add_test(tc, test_with_zeros); 708 suite_add_tcase(s, tc); 709 710 tc = tcase_create("output"); 711 tcase_add_test(tc, test_nano_short); 712 tcase_add_test(tc, test_nano_long); 713 suite_add_tcase(s, tc); 714 715 tc = tcase_create("system_tuning"); 716 tcase_add_test(tc, test_deepest_idle_state); 717 tcase_add_test(tc, test_dma_latency); 718 tcase_add_test(tc, test_trace_buffer_size); 719 tcase_add_test(tc, test_warm_up); 720 suite_add_tcase(s, tc); 721 722 tc = tcase_create("aa_actions"); 723 tcase_add_test(tc, test_auto); 724 tcase_add_test(tc, test_bpf_action); 725 tcase_add_test(tc, test_dump_tasks); 726 tcase_add_test(tc, test_no_aa); 727 tcase_add_test(tc, test_on_end); 728 tcase_add_test(tc, test_on_threshold); 729 tcase_add_test(tc, test_stack_format); 730 suite_add_tcase(s, tc); 731 732 tc = tcase_create("general"); 733 tcase_add_test(tc, test_debug_short); 734 tcase_add_test(tc, test_debug_long); 735 tcase_add_test(tc, test_duration_short); 736 tcase_add_test(tc, test_duration_long); 737 suite_add_tcase(s, tc); 738 739 return s; 740 } 741