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_stack_short) 59 { 60 PARSE_ARGS("timerlat", "hist", "-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", "hist", "--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", "hist", "-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", "hist", "--thread", "20"); 85 86 ck_assert_int_eq(params->stop_total_us, 20); 87 } 88 END_TEST 89 90 START_TEST(test_trace_short_noarg) 91 { 92 PARSE_ARGS("timerlat", "hist", "-t"); 93 94 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 95 "timerlat_trace.txt"); 96 } 97 END_TEST 98 99 START_TEST(test_trace_short_followarg) 100 { 101 PARSE_ARGS("timerlat", "hist", "-t", "-d", "20"); 102 103 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 104 "timerlat_trace.txt"); 105 ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */ 106 } 107 END_TEST 108 109 START_TEST(test_trace_short_space) 110 { 111 PARSE_ARGS("timerlat", "hist", "-t", "tracefile"); 112 113 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 114 "tracefile"); 115 } 116 END_TEST 117 118 START_TEST(test_trace_short_equals) 119 { 120 PARSE_ARGS("timerlat", "hist", "-t=tracefile"); 121 122 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 123 "tracefile"); 124 } 125 END_TEST 126 127 START_TEST(test_trace_long_noarg) 128 { 129 PARSE_ARGS("timerlat", "hist", "--trace"); 130 131 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 132 "timerlat_trace.txt"); 133 } 134 END_TEST 135 136 START_TEST(test_trace_long_followarg) 137 { 138 PARSE_ARGS("timerlat", "hist", "--trace", "-d", "20"); 139 140 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 141 "timerlat_trace.txt"); 142 ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */ 143 } 144 END_TEST 145 146 START_TEST(test_trace_long_space) 147 { 148 PARSE_ARGS("timerlat", "hist", "--trace", "tracefile"); 149 150 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 151 "tracefile"); 152 } 153 END_TEST 154 155 START_TEST(test_trace_long_equals) 156 { 157 PARSE_ARGS("timerlat", "hist", "--trace=tracefile"); 158 159 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 160 "tracefile"); 161 } 162 END_TEST 163 164 /* Event Configuration */ 165 166 START_TEST(test_event_short) 167 { 168 PARSE_ARGS("timerlat", "hist", "-e", "system:event"); 169 170 CLI_ASSERT_SINGLE_EVENT("system", "event"); 171 } 172 END_TEST 173 174 START_TEST(test_event_long) 175 { 176 PARSE_ARGS("timerlat", "hist", "--event", "system:event"); 177 178 CLI_ASSERT_SINGLE_EVENT("system", "event"); 179 } 180 END_TEST 181 182 START_TEST(test_filter) 183 { 184 PARSE_ARGS("timerlat", "hist", "-e", "system:event", "--filter", "filter"); 185 186 CLI_ASSERT_SINGLE_FILTER("filter"); 187 } 188 END_TEST 189 190 START_TEST(test_trigger) 191 { 192 PARSE_ARGS("timerlat", "hist", "-e", "system:event", "--trigger", "trigger"); 193 194 CLI_ASSERT_SINGLE_TRIGGER("trigger"); 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", "hist", "-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", "hist", "--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", "hist", "-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", "hist", "--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", "hist", "-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", "hist", "-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", "hist", "-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", "hist", "--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", "hist", "--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", "hist", "--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", "hist", "-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", "hist", "--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", "hist", "-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", "hist", "--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", "hist", "-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", "hist", "--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", "hist", "-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", "hist", "--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 START_TEST(test_aligned_short) 377 { 378 PARSE_ARGS("timerlat", "hist", "-A", "500"); 379 380 ck_assert(tlat_params->timerlat_align); 381 ck_assert_int_eq(tlat_params->timerlat_align_us, 500); 382 } 383 END_TEST 384 385 START_TEST(test_aligned_long) 386 { 387 PARSE_ARGS("timerlat", "hist", "--aligned", "500"); 388 389 ck_assert(tlat_params->timerlat_align); 390 ck_assert_int_eq(tlat_params->timerlat_align_us, 500); 391 } 392 END_TEST 393 394 /* Histogram Options */ 395 396 START_TEST(test_bucket_size_short) 397 { 398 PARSE_ARGS("timerlat", "hist", "-b", "2"); 399 400 ck_assert_int_eq(params->hist.bucket_size, 2); 401 } 402 END_TEST 403 404 START_TEST(test_bucket_size_long) 405 { 406 PARSE_ARGS("timerlat", "hist", "--bucket-size", "2"); 407 408 ck_assert_int_eq(params->hist.bucket_size, 2); 409 } 410 END_TEST 411 412 START_TEST(test_entries_short) 413 { 414 PARSE_ARGS("timerlat", "hist", "-E", "512"); 415 416 ck_assert_int_eq(params->hist.entries, 512); 417 } 418 END_TEST 419 420 START_TEST(test_entries_long) 421 { 422 PARSE_ARGS("timerlat", "hist", "--entries", "512"); 423 424 ck_assert_int_eq(params->hist.entries, 512); 425 } 426 END_TEST 427 428 START_TEST(test_no_header) 429 { 430 PARSE_ARGS("timerlat", "hist", "--no-header"); 431 432 ck_assert(params->hist.no_header); 433 } 434 END_TEST 435 436 START_TEST(test_no_index) 437 { 438 PARSE_ARGS("timerlat", "hist", "--with-zeros", "--no-index"); 439 440 ck_assert(params->hist.no_index); 441 } 442 END_TEST 443 444 START_TEST(test_no_irq) 445 { 446 PARSE_ARGS("timerlat", "hist", "--no-irq"); 447 448 ck_assert(params->hist.no_irq); 449 } 450 END_TEST 451 452 START_TEST(test_no_summary) 453 { 454 PARSE_ARGS("timerlat", "hist", "--no-summary"); 455 456 ck_assert(params->hist.no_summary); 457 } 458 END_TEST 459 460 START_TEST(test_no_thread) 461 { 462 PARSE_ARGS("timerlat", "hist", "--no-thread"); 463 464 ck_assert(params->hist.no_thread); 465 } 466 END_TEST 467 468 START_TEST(test_with_zeros) 469 { 470 PARSE_ARGS("timerlat", "hist", "--with-zeros"); 471 472 ck_assert(params->hist.with_zeros); 473 } 474 END_TEST 475 476 /* Output */ 477 478 START_TEST(test_nano_short) 479 { 480 PARSE_ARGS("timerlat", "hist", "-n"); 481 482 ck_assert_int_eq(params->output_divisor, 1); 483 } 484 END_TEST 485 486 START_TEST(test_nano_long) 487 { 488 PARSE_ARGS("timerlat", "hist", "--nano"); 489 490 ck_assert_int_eq(params->output_divisor, 1); 491 } 492 END_TEST 493 494 /* System Tuning */ 495 496 START_TEST(test_deepest_idle_state) 497 { 498 PARSE_ARGS("timerlat", "hist", "--deepest-idle-state", "1"); 499 500 ck_assert_int_eq(tlat_params->deepest_idle_state, 1); 501 } 502 END_TEST 503 504 START_TEST(test_dma_latency) 505 { 506 PARSE_ARGS("timerlat", "hist", "--dma-latency", "10"); 507 508 ck_assert_int_eq(tlat_params->dma_latency, 10); 509 } 510 END_TEST 511 512 START_TEST(test_trace_buffer_size) 513 { 514 PARSE_ARGS("timerlat", "hist", "--trace-buffer-size", "200"); 515 516 ck_assert_int_eq(params->buffer_size, 200); 517 } 518 END_TEST 519 520 START_TEST(test_warm_up) 521 { 522 PARSE_ARGS("timerlat", "hist", "--warm-up", "5"); 523 524 ck_assert_int_eq(params->warmup, 5); 525 } 526 END_TEST 527 528 /* Auto Analysis and Actions */ 529 530 START_TEST(test_auto) 531 { 532 PARSE_ARGS("timerlat", "hist", "-a", "20"); 533 534 CLI_TIMERLAT_ASSERT_AUTO(20); 535 } 536 END_TEST 537 538 START_TEST(test_bpf_action) 539 { 540 PARSE_ARGS("timerlat", "hist", "--bpf-action", "program"); 541 542 ck_assert_str_eq(tlat_params->bpf_action_program, "program"); 543 } 544 END_TEST 545 546 START_TEST(test_dump_tasks) 547 { 548 PARSE_ARGS("timerlat", "hist", "--dump-tasks"); 549 550 ck_assert(tlat_params->dump_tasks); 551 } 552 END_TEST 553 554 START_TEST(test_no_aa) 555 { 556 PARSE_ARGS("timerlat", "hist", "--no-aa"); 557 558 ck_assert(tlat_params->no_aa); 559 } 560 END_TEST 561 562 START_TEST(test_on_end) 563 { 564 PARSE_ARGS("timerlat", "hist", "--on-end", "trace"); 565 566 CLI_ASSERT_SINGLE_ACTION(end_actions, ACTION_TRACE_OUTPUT, trace_output, str, 567 "timerlat_trace.txt"); 568 } 569 END_TEST 570 571 START_TEST(test_on_threshold) 572 { 573 PARSE_ARGS("timerlat", "hist", "--on-threshold", "trace"); 574 575 CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str, 576 "timerlat_trace.txt"); 577 } 578 END_TEST 579 580 START_TEST(test_stack_format) 581 { 582 PARSE_ARGS("timerlat", "hist", "--stack-format", "truncate"); 583 584 ck_assert_int_eq(tlat_params->stack_format, STACK_FORMAT_TRUNCATE); 585 } 586 END_TEST 587 588 /* General */ 589 590 START_TEST(test_debug_short) 591 { 592 PARSE_ARGS("timerlat", "hist", "-D"); 593 594 ck_assert(config_debug); 595 } 596 END_TEST 597 598 START_TEST(test_debug_long) 599 { 600 PARSE_ARGS("timerlat", "hist", "--debug"); 601 602 ck_assert(config_debug); 603 } 604 END_TEST 605 606 START_TEST(test_duration_short) 607 { 608 PARSE_ARGS("timerlat", "hist", "-d", "1m"); 609 610 ck_assert_int_eq(params->duration, 60); 611 } 612 END_TEST 613 614 START_TEST(test_duration_long) 615 { 616 PARSE_ARGS("timerlat", "hist", "--duration", "1m"); 617 618 ck_assert_int_eq(params->duration, 60); 619 } 620 END_TEST 621 622 Suite *timerlat_hist_cli_suite(void) 623 { 624 Suite *s = suite_create("timerlat_hist_cli"); 625 TCase *tc; 626 627 tc = tcase_create("tracing_options"); 628 tcase_add_test(tc, test_irq_short); 629 tcase_add_test(tc, test_irq_long); 630 tcase_add_test(tc, test_period_short); 631 tcase_add_test(tc, test_period_long); 632 tcase_add_test(tc, test_stack_short); 633 tcase_add_test(tc, test_stack_long); 634 tcase_add_test(tc, test_thread_short); 635 tcase_add_test(tc, test_thread_long); 636 tcase_add_test(tc, test_trace_short_noarg); 637 tcase_add_test(tc, test_trace_short_followarg); 638 tcase_add_test(tc, test_trace_short_space); 639 tcase_add_test(tc, test_trace_short_equals); 640 tcase_add_test(tc, test_trace_long_noarg); 641 tcase_add_test(tc, test_trace_long_followarg); 642 tcase_add_test(tc, test_trace_long_space); 643 tcase_add_test(tc, test_trace_long_equals); 644 suite_add_tcase(s, tc); 645 646 tc = tcase_create("event_configuration"); 647 tcase_add_test(tc, test_event_short); 648 tcase_add_test(tc, test_event_long); 649 tcase_add_test(tc, test_filter); 650 tcase_add_test(tc, test_trigger); 651 suite_add_tcase(s, tc); 652 653 tc = tcase_create("cpu_configuration"); 654 tcase_add_test(tc, test_cpus_short); 655 tcase_add_test(tc, test_cpus_long); 656 tcase_add_test(tc, test_housekeeping_short); 657 tcase_add_test(tc, test_housekeeping_long); 658 suite_add_tcase(s, tc); 659 660 tc = tcase_create("thread_configuration"); 661 tcase_add_test(tc, test_cgroup_short_noarg); 662 tcase_add_test(tc, test_cgroup_short_space); 663 tcase_add_test(tc, test_cgroup_short_equals); 664 tcase_add_test(tc, test_cgroup_long_noarg); 665 tcase_add_test(tc, test_cgroup_long_space); 666 tcase_add_test(tc, test_cgroup_long_equals); 667 tcase_add_test(tc, test_kernel_threads_short); 668 tcase_add_test(tc, test_kernel_threads_long); 669 tcase_add_test(tc, test_priority_short); 670 tcase_add_test(tc, test_priority_long); 671 tcase_add_test(tc, test_user_load_short); 672 tcase_add_test(tc, test_user_load_long); 673 tcase_add_test(tc, test_user_threads_short); 674 tcase_add_test(tc, test_user_threads_long); 675 tcase_add_test(tc, test_aligned_short); 676 tcase_add_test(tc, test_aligned_long); 677 suite_add_tcase(s, tc); 678 679 tc = tcase_create("histogram_options"); 680 tcase_add_test(tc, test_bucket_size_short); 681 tcase_add_test(tc, test_bucket_size_long); 682 tcase_add_test(tc, test_entries_short); 683 tcase_add_test(tc, test_entries_long); 684 tcase_add_test(tc, test_no_header); 685 tcase_add_test(tc, test_no_index); 686 tcase_add_test(tc, test_no_irq); 687 tcase_add_test(tc, test_no_summary); 688 tcase_add_test(tc, test_no_thread); 689 tcase_add_test(tc, test_with_zeros); 690 suite_add_tcase(s, tc); 691 692 tc = tcase_create("output"); 693 tcase_add_test(tc, test_nano_short); 694 tcase_add_test(tc, test_nano_long); 695 suite_add_tcase(s, tc); 696 697 tc = tcase_create("system_tuning"); 698 tcase_add_test(tc, test_deepest_idle_state); 699 tcase_add_test(tc, test_dma_latency); 700 tcase_add_test(tc, test_trace_buffer_size); 701 tcase_add_test(tc, test_warm_up); 702 suite_add_tcase(s, tc); 703 704 tc = tcase_create("aa_actions"); 705 tcase_add_test(tc, test_auto); 706 tcase_add_test(tc, test_bpf_action); 707 tcase_add_test(tc, test_dump_tasks); 708 tcase_add_test(tc, test_no_aa); 709 tcase_add_test(tc, test_on_end); 710 tcase_add_test(tc, test_on_threshold); 711 tcase_add_test(tc, test_stack_format); 712 suite_add_tcase(s, tc); 713 714 tc = tcase_create("general"); 715 tcase_add_test(tc, test_debug_short); 716 tcase_add_test(tc, test_debug_long); 717 tcase_add_test(tc, test_duration_short); 718 tcase_add_test(tc, test_duration_long); 719 suite_add_tcase(s, tc); 720 721 return s; 722 } 723