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