Files
Tomas Glozar 05f4bcb2e2 rtla: Add unit tests for CLI with unset
Test parsing of command line that sets an option and then unsets it back
to the default value in all tools.

Only two CLI tests are added for each tool: short period option (-p ...
--no-period) and long period option (--period ... --no-period). The
logic specific for individual options is tested in opt callback tests
already.

Reviewed-by: Wander Lairson Costa <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Tomas Glozar <[email protected]>
2026-08-05 10:14:40 +02:00

741 lines
15 KiB
C

// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <check.h>
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <limits.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include <linux/container_of.h>
#include "cli_params_assert.h"
#include "../../src/cli.h"
#define PARSE_ARGS(...) char *argv[] = { __VA_ARGS__, NULL };\
int argc = sizeof(argv) / sizeof(char *) - 1;\
struct common_params *params =\
timerlat_hist_parse_args(argc, argv);\
struct timerlat_params *tlat_params __maybe_unused =\
to_timerlat_params(params)
/* Tracing Options */
START_TEST(test_irq_short)
{
PARSE_ARGS("timerlat", "hist", "-i", "20");
ck_assert_int_eq(params->stop_us, 20);
}
END_TEST
START_TEST(test_irq_long)
{
PARSE_ARGS("timerlat", "hist", "--irq", "20");
ck_assert_int_eq(params->stop_us, 20);
}
END_TEST
START_TEST(test_period_short)
{
PARSE_ARGS("timerlat", "hist", "-p", "200");
ck_assert_int_eq(tlat_params->timerlat_period_us, 200);
}
END_TEST
START_TEST(test_period_long)
{
PARSE_ARGS("timerlat", "hist", "--period", "200");
ck_assert_int_eq(tlat_params->timerlat_period_us, 200);
}
END_TEST
START_TEST(test_period_unset_short)
{
PARSE_ARGS("timerlat", "hist", "-p", "200", "--no-period");
ck_assert_int_eq(tlat_params->timerlat_period_us, 0);
}
END_TEST
START_TEST(test_period_unset_long)
{
PARSE_ARGS("timerlat", "hist", "--period", "200", "--no-period");
ck_assert_int_eq(tlat_params->timerlat_period_us, 0);
}
END_TEST
START_TEST(test_stack_short)
{
PARSE_ARGS("timerlat", "hist", "-s", "20");
ck_assert_int_eq(tlat_params->print_stack, 20);
}
END_TEST
START_TEST(test_stack_long)
{
PARSE_ARGS("timerlat", "hist", "--stack", "20");
ck_assert_int_eq(tlat_params->print_stack, 20);
}
END_TEST
START_TEST(test_thread_short)
{
PARSE_ARGS("timerlat", "hist", "-T", "20");
ck_assert_int_eq(params->stop_total_us, 20);
}
END_TEST
START_TEST(test_thread_long)
{
PARSE_ARGS("timerlat", "hist", "--thread", "20");
ck_assert_int_eq(params->stop_total_us, 20);
}
END_TEST
START_TEST(test_trace_short_noarg)
{
PARSE_ARGS("timerlat", "hist", "-t");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"timerlat_trace.txt");
}
END_TEST
START_TEST(test_trace_short_followarg)
{
PARSE_ARGS("timerlat", "hist", "-t", "-d", "20");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"timerlat_trace.txt");
ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */
}
END_TEST
START_TEST(test_trace_short_space)
{
PARSE_ARGS("timerlat", "hist", "-t", "tracefile");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"tracefile");
}
END_TEST
START_TEST(test_trace_short_equals)
{
PARSE_ARGS("timerlat", "hist", "-t=tracefile");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"tracefile");
}
END_TEST
START_TEST(test_trace_long_noarg)
{
PARSE_ARGS("timerlat", "hist", "--trace");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"timerlat_trace.txt");
}
END_TEST
START_TEST(test_trace_long_followarg)
{
PARSE_ARGS("timerlat", "hist", "--trace", "-d", "20");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"timerlat_trace.txt");
ck_assert_int_eq(params->duration, 20); /* check if next argument is read correctly */
}
END_TEST
START_TEST(test_trace_long_space)
{
PARSE_ARGS("timerlat", "hist", "--trace", "tracefile");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"tracefile");
}
END_TEST
START_TEST(test_trace_long_equals)
{
PARSE_ARGS("timerlat", "hist", "--trace=tracefile");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"tracefile");
}
END_TEST
/* Event Configuration */
START_TEST(test_event_short)
{
PARSE_ARGS("timerlat", "hist", "-e", "system:event");
CLI_ASSERT_SINGLE_EVENT("system", "event");
}
END_TEST
START_TEST(test_event_long)
{
PARSE_ARGS("timerlat", "hist", "--event", "system:event");
CLI_ASSERT_SINGLE_EVENT("system", "event");
}
END_TEST
START_TEST(test_filter)
{
PARSE_ARGS("timerlat", "hist", "-e", "system:event", "--filter", "filter");
CLI_ASSERT_SINGLE_FILTER("filter");
}
END_TEST
START_TEST(test_trigger)
{
PARSE_ARGS("timerlat", "hist", "-e", "system:event", "--trigger", "trigger");
CLI_ASSERT_SINGLE_TRIGGER("trigger");
}
END_TEST
/* CPU Configuration */
START_TEST(test_cpus_short)
{
nr_cpus = 4;
PARSE_ARGS("timerlat", "hist", "-c", "0-1,3");
ck_assert_str_eq(params->cpus, "0-1,3");
CLI_ASSERT_CPUSET(monitored_cpus, 0, 1, 3);
}
END_TEST
START_TEST(test_cpus_long)
{
nr_cpus = 4;
PARSE_ARGS("timerlat", "hist", "--cpus", "0-1,3");
ck_assert_str_eq(params->cpus, "0-1,3");
CLI_ASSERT_CPUSET(monitored_cpus, 0, 1, 3);
}
END_TEST
START_TEST(test_housekeeping_short)
{
nr_cpus = 4;
PARSE_ARGS("timerlat", "hist", "-H", "0-1,3");
CLI_ASSERT_CPUSET(hk_cpu_set, 0, 1, 3);
}
END_TEST
START_TEST(test_housekeeping_long)
{
nr_cpus = 4;
PARSE_ARGS("timerlat", "hist", "--house-keeping", "0-1,3");
CLI_ASSERT_CPUSET(hk_cpu_set, 0, 1, 3);
}
END_TEST
/* Thread Configuration */
START_TEST(test_cgroup_short_noarg)
{
PARSE_ARGS("timerlat", "hist", "-C");
ck_assert(params->cgroup);
ck_assert_ptr_null(params->cgroup_name);
}
END_TEST
START_TEST(test_cgroup_short_space)
{
PARSE_ARGS("timerlat", "hist", "-C", "cgroup");
ck_assert(params->cgroup);
ck_assert_str_eq(params->cgroup_name, "cgroup");
}
END_TEST
START_TEST(test_cgroup_short_equals)
{
PARSE_ARGS("timerlat", "hist", "-C=cgroup");
ck_assert(params->cgroup);
ck_assert_str_eq(params->cgroup_name, "cgroup");
}
END_TEST
START_TEST(test_cgroup_long_noarg)
{
PARSE_ARGS("timerlat", "hist", "--cgroup");
ck_assert(params->cgroup);
ck_assert_ptr_null(params->cgroup_name);
}
END_TEST
START_TEST(test_cgroup_long_space)
{
PARSE_ARGS("timerlat", "hist", "--cgroup", "cgroup");
ck_assert(params->cgroup);
ck_assert_str_eq(params->cgroup_name, "cgroup");
}
END_TEST
START_TEST(test_cgroup_long_equals)
{
PARSE_ARGS("timerlat", "hist", "--cgroup=cgroup");
ck_assert(params->cgroup);
ck_assert_str_eq(params->cgroup_name, "cgroup");
}
END_TEST
START_TEST(test_kernel_threads_short)
{
PARSE_ARGS("timerlat", "hist", "-k");
ck_assert(params->kernel_workload);
ck_assert(!params->user_workload);
ck_assert(!params->user_data);
}
END_TEST
START_TEST(test_kernel_threads_long)
{
PARSE_ARGS("timerlat", "hist", "--kernel-threads");
ck_assert(params->kernel_workload);
ck_assert(!params->user_workload);
ck_assert(!params->user_data);
}
END_TEST
START_TEST(test_priority_short)
{
PARSE_ARGS("timerlat", "hist", "-P", "f:95");
ck_assert_int_eq(params->sched_param.sched_policy, SCHED_FIFO);
ck_assert_int_eq(params->sched_param.sched_priority, 95);
}
END_TEST
START_TEST(test_priority_long)
{
PARSE_ARGS("timerlat", "hist", "--priority", "f:95");
ck_assert_int_eq(params->sched_param.sched_policy, SCHED_FIFO);
ck_assert_int_eq(params->sched_param.sched_priority, 95);
}
END_TEST
START_TEST(test_user_load_short)
{
PARSE_ARGS("timerlat", "hist", "-U");
ck_assert(!params->kernel_workload);
ck_assert(!params->user_workload);
ck_assert(params->user_data);
}
END_TEST
START_TEST(test_user_load_long)
{
PARSE_ARGS("timerlat", "hist", "--user-load");
ck_assert(!params->kernel_workload);
ck_assert(!params->user_workload);
ck_assert(params->user_data);
}
END_TEST
START_TEST(test_user_threads_short)
{
PARSE_ARGS("timerlat", "hist", "-u");
ck_assert(!params->kernel_workload);
ck_assert(params->user_workload);
ck_assert(params->user_data);
}
END_TEST
START_TEST(test_user_threads_long)
{
PARSE_ARGS("timerlat", "hist", "--user-threads");
ck_assert(!params->kernel_workload);
ck_assert(params->user_workload);
ck_assert(params->user_data);
}
END_TEST
START_TEST(test_aligned_short)
{
PARSE_ARGS("timerlat", "hist", "-A", "500");
ck_assert(tlat_params->timerlat_align);
ck_assert_int_eq(tlat_params->timerlat_align_us, 500);
}
END_TEST
START_TEST(test_aligned_long)
{
PARSE_ARGS("timerlat", "hist", "--aligned", "500");
ck_assert(tlat_params->timerlat_align);
ck_assert_int_eq(tlat_params->timerlat_align_us, 500);
}
END_TEST
/* Histogram Options */
START_TEST(test_bucket_size_short)
{
PARSE_ARGS("timerlat", "hist", "-b", "2");
ck_assert_int_eq(params->hist.bucket_size, 2);
}
END_TEST
START_TEST(test_bucket_size_long)
{
PARSE_ARGS("timerlat", "hist", "--bucket-size", "2");
ck_assert_int_eq(params->hist.bucket_size, 2);
}
END_TEST
START_TEST(test_entries_short)
{
PARSE_ARGS("timerlat", "hist", "-E", "512");
ck_assert_int_eq(params->hist.entries, 512);
}
END_TEST
START_TEST(test_entries_long)
{
PARSE_ARGS("timerlat", "hist", "--entries", "512");
ck_assert_int_eq(params->hist.entries, 512);
}
END_TEST
START_TEST(test_no_header)
{
PARSE_ARGS("timerlat", "hist", "--no-header");
ck_assert(params->hist.no_header);
}
END_TEST
START_TEST(test_no_index)
{
PARSE_ARGS("timerlat", "hist", "--with-zeros", "--no-index");
ck_assert(params->hist.no_index);
}
END_TEST
START_TEST(test_no_irq)
{
PARSE_ARGS("timerlat", "hist", "--no-irq");
ck_assert(params->hist.no_irq);
}
END_TEST
START_TEST(test_no_summary)
{
PARSE_ARGS("timerlat", "hist", "--no-summary");
ck_assert(params->hist.no_summary);
}
END_TEST
START_TEST(test_no_thread)
{
PARSE_ARGS("timerlat", "hist", "--no-thread");
ck_assert(params->hist.no_thread);
}
END_TEST
START_TEST(test_with_zeros)
{
PARSE_ARGS("timerlat", "hist", "--with-zeros");
ck_assert(params->hist.with_zeros);
}
END_TEST
/* Output */
START_TEST(test_nano_short)
{
PARSE_ARGS("timerlat", "hist", "-n");
ck_assert_int_eq(params->output_divisor, 1);
}
END_TEST
START_TEST(test_nano_long)
{
PARSE_ARGS("timerlat", "hist", "--nano");
ck_assert_int_eq(params->output_divisor, 1);
}
END_TEST
/* System Tuning */
START_TEST(test_deepest_idle_state)
{
PARSE_ARGS("timerlat", "hist", "--deepest-idle-state", "1");
ck_assert_int_eq(tlat_params->deepest_idle_state, 1);
}
END_TEST
START_TEST(test_dma_latency)
{
PARSE_ARGS("timerlat", "hist", "--dma-latency", "10");
ck_assert_int_eq(tlat_params->dma_latency, 10);
}
END_TEST
START_TEST(test_trace_buffer_size)
{
PARSE_ARGS("timerlat", "hist", "--trace-buffer-size", "200");
ck_assert_int_eq(params->buffer_size, 200);
}
END_TEST
START_TEST(test_warm_up)
{
PARSE_ARGS("timerlat", "hist", "--warm-up", "5");
ck_assert_int_eq(params->warmup, 5);
}
END_TEST
/* Auto Analysis and Actions */
START_TEST(test_auto)
{
PARSE_ARGS("timerlat", "hist", "-a", "20");
CLI_TIMERLAT_ASSERT_AUTO(20);
}
END_TEST
START_TEST(test_bpf_action)
{
PARSE_ARGS("timerlat", "hist", "--bpf-action", "program");
ck_assert_str_eq(tlat_params->bpf_action_program, "program");
}
END_TEST
START_TEST(test_dump_tasks)
{
PARSE_ARGS("timerlat", "hist", "--dump-tasks");
ck_assert(tlat_params->dump_tasks);
}
END_TEST
START_TEST(test_no_aa)
{
PARSE_ARGS("timerlat", "hist", "--no-aa");
ck_assert(tlat_params->no_aa);
}
END_TEST
START_TEST(test_on_end)
{
PARSE_ARGS("timerlat", "hist", "--on-end", "trace");
CLI_ASSERT_SINGLE_ACTION(end_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"timerlat_trace.txt");
}
END_TEST
START_TEST(test_on_threshold)
{
PARSE_ARGS("timerlat", "hist", "--on-threshold", "trace");
CLI_ASSERT_SINGLE_ACTION(threshold_actions, ACTION_TRACE_OUTPUT, trace_output, str,
"timerlat_trace.txt");
}
END_TEST
START_TEST(test_stack_format)
{
PARSE_ARGS("timerlat", "hist", "--stack-format", "truncate");
ck_assert_int_eq(tlat_params->stack_format, STACK_FORMAT_TRUNCATE);
}
END_TEST
/* General */
START_TEST(test_debug_short)
{
PARSE_ARGS("timerlat", "hist", "-D");
ck_assert(config_debug);
}
END_TEST
START_TEST(test_debug_long)
{
PARSE_ARGS("timerlat", "hist", "--debug");
ck_assert(config_debug);
}
END_TEST
START_TEST(test_duration_short)
{
PARSE_ARGS("timerlat", "hist", "-d", "1m");
ck_assert_int_eq(params->duration, 60);
}
END_TEST
START_TEST(test_duration_long)
{
PARSE_ARGS("timerlat", "hist", "--duration", "1m");
ck_assert_int_eq(params->duration, 60);
}
END_TEST
Suite *timerlat_hist_cli_suite(void)
{
Suite *s = suite_create("timerlat_hist_cli");
TCase *tc;
tc = tcase_create("tracing_options");
tcase_add_test(tc, test_irq_short);
tcase_add_test(tc, test_irq_long);
tcase_add_test(tc, test_period_short);
tcase_add_test(tc, test_period_long);
tcase_add_test(tc, test_period_unset_short);
tcase_add_test(tc, test_period_unset_long);
tcase_add_test(tc, test_stack_short);
tcase_add_test(tc, test_stack_long);
tcase_add_test(tc, test_thread_short);
tcase_add_test(tc, test_thread_long);
tcase_add_test(tc, test_trace_short_noarg);
tcase_add_test(tc, test_trace_short_followarg);
tcase_add_test(tc, test_trace_short_space);
tcase_add_test(tc, test_trace_short_equals);
tcase_add_test(tc, test_trace_long_noarg);
tcase_add_test(tc, test_trace_long_followarg);
tcase_add_test(tc, test_trace_long_space);
tcase_add_test(tc, test_trace_long_equals);
suite_add_tcase(s, tc);
tc = tcase_create("event_configuration");
tcase_add_test(tc, test_event_short);
tcase_add_test(tc, test_event_long);
tcase_add_test(tc, test_filter);
tcase_add_test(tc, test_trigger);
suite_add_tcase(s, tc);
tc = tcase_create("cpu_configuration");
tcase_add_test(tc, test_cpus_short);
tcase_add_test(tc, test_cpus_long);
tcase_add_test(tc, test_housekeeping_short);
tcase_add_test(tc, test_housekeeping_long);
suite_add_tcase(s, tc);
tc = tcase_create("thread_configuration");
tcase_add_test(tc, test_cgroup_short_noarg);
tcase_add_test(tc, test_cgroup_short_space);
tcase_add_test(tc, test_cgroup_short_equals);
tcase_add_test(tc, test_cgroup_long_noarg);
tcase_add_test(tc, test_cgroup_long_space);
tcase_add_test(tc, test_cgroup_long_equals);
tcase_add_test(tc, test_kernel_threads_short);
tcase_add_test(tc, test_kernel_threads_long);
tcase_add_test(tc, test_priority_short);
tcase_add_test(tc, test_priority_long);
tcase_add_test(tc, test_user_load_short);
tcase_add_test(tc, test_user_load_long);
tcase_add_test(tc, test_user_threads_short);
tcase_add_test(tc, test_user_threads_long);
tcase_add_test(tc, test_aligned_short);
tcase_add_test(tc, test_aligned_long);
suite_add_tcase(s, tc);
tc = tcase_create("histogram_options");
tcase_add_test(tc, test_bucket_size_short);
tcase_add_test(tc, test_bucket_size_long);
tcase_add_test(tc, test_entries_short);
tcase_add_test(tc, test_entries_long);
tcase_add_test(tc, test_no_header);
tcase_add_test(tc, test_no_index);
tcase_add_test(tc, test_no_irq);
tcase_add_test(tc, test_no_summary);
tcase_add_test(tc, test_no_thread);
tcase_add_test(tc, test_with_zeros);
suite_add_tcase(s, tc);
tc = tcase_create("output");
tcase_add_test(tc, test_nano_short);
tcase_add_test(tc, test_nano_long);
suite_add_tcase(s, tc);
tc = tcase_create("system_tuning");
tcase_add_test(tc, test_deepest_idle_state);
tcase_add_test(tc, test_dma_latency);
tcase_add_test(tc, test_trace_buffer_size);
tcase_add_test(tc, test_warm_up);
suite_add_tcase(s, tc);
tc = tcase_create("aa_actions");
tcase_add_test(tc, test_auto);
tcase_add_test(tc, test_bpf_action);
tcase_add_test(tc, test_dump_tasks);
tcase_add_test(tc, test_no_aa);
tcase_add_test(tc, test_on_end);
tcase_add_test(tc, test_on_threshold);
tcase_add_test(tc, test_stack_format);
suite_add_tcase(s, tc);
tc = tcase_create("general");
tcase_add_test(tc, test_debug_short);
tcase_add_test(tc, test_debug_long);
tcase_add_test(tc, test_duration_short);
tcase_add_test(tc, test_duration_long);
suite_add_tcase(s, tc);
return s;
}