From: Simon Marchi Date: Thu, 15 Apr 2021 13:07:31 +0000 (-0400) Subject: lttng list-triggers: handle all condition types X-Git-Tag: v2.13.0-rc1~37 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=19904669a9eb25cd4a0ccd3de82d3ac803dfe877 lttng list-triggers: handle all condition types At the moment, only the event-rule-matches condition is handled by the list-triggers commands. Change it to handle all existing condition types. Because these other condition types can't be created using the command-line interface, add a util program that creates and registers triggers for the purpose of the test. The test triggers with the event-rule-matches condition are kept as is, created using the command-line interface. Change-Id: I6a2b0442800c93f7e8815dce96d1cf1928d5725a Signed-off-by: Simon Marchi Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng/commands/list_triggers.c b/src/bin/lttng/commands/list_triggers.c index 91ff1c068..bb118e56a 100644 --- a/src/bin/lttng/commands/list_triggers.c +++ b/src/bin/lttng/commands/list_triggers.c @@ -39,6 +39,81 @@ struct argpar_opt_descr list_trigger_options[] = { ARGPAR_OPT_DESCR_SENTINEL, }; +static void print_condition_session_consumed_size( + const struct lttng_condition *condition) +{ + enum lttng_condition_status condition_status; + const char *session_name; + uint64_t threshold; + + condition_status = + lttng_condition_session_consumed_size_get_session_name( + condition, &session_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + lttng_condition_session_consumed_size_get_threshold( + condition, &threshold); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + MSG(" session name: %s", session_name); + MSG(" threshold: %" PRIu64 " bytes", threshold); +} + +static void print_condition_buffer_usage( + const struct lttng_condition *condition) +{ + enum lttng_condition_status condition_status; + const char *session_name, *channel_name; + enum lttng_domain_type domain_type; + uint64_t threshold; + + condition_status = lttng_condition_buffer_usage_get_session_name( + condition, &session_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + condition_status = lttng_condition_buffer_usage_get_channel_name( + condition, &channel_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + condition_status = lttng_condition_buffer_usage_get_domain_type( + condition, &domain_type); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + MSG(" session name: %s", session_name); + MSG(" channel name: %s", channel_name); + MSG(" domain: %s", lttng_domain_type_str(domain_type)); + + condition_status = lttng_condition_buffer_usage_get_threshold( + condition, &threshold); + if (condition_status == LTTNG_CONDITION_STATUS_OK) { + MSG(" threshold (bytes): %" PRIu64, threshold); + } else { + double threshold_ratio; + + assert(condition_status == LTTNG_CONDITION_STATUS_UNSET); + + condition_status = + lttng_condition_buffer_usage_get_threshold_ratio( + condition, &threshold_ratio); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + MSG(" threshold (ratio): %.2f", threshold_ratio); + } +} + +static void print_condition_session_rotation( + const struct lttng_condition *condition) +{ + enum lttng_condition_status condition_status; + const char *session_name; + + condition_status = lttng_condition_session_rotation_get_session_name( + condition, &session_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + MSG(" session name: %s", session_name); +} + /* * Returns the human-readable log level name associated with a numerical value * if there is one. The Log4j and JUL domains have discontinuous log level @@ -823,12 +898,22 @@ void print_one_trigger(const struct lttng_trigger *trigger) condition_type = lttng_condition_get_type(condition); MSG(" condition: %s", lttng_condition_type_str(condition_type)); switch (condition_type) { + case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: + print_condition_session_consumed_size(condition); + break; + case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: + case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: + print_condition_buffer_usage(condition); + break; + case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: + case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: + print_condition_session_rotation(condition); + break; case LTTNG_CONDITION_TYPE_ON_EVENT: print_condition_on_event(condition); break; default: - MSG(" (condition type not handled in %s)", __func__); - break; + abort(); } action = lttng_trigger_get_const_action(trigger); diff --git a/tests/regression/tools/trigger/test_list_triggers_cli b/tests/regression/tools/trigger/test_list_triggers_cli index 31ba7b366..89c77eb54 100755 --- a/tests/regression/tools/trigger/test_list_triggers_cli +++ b/tests/regression/tools/trigger/test_list_triggers_cli @@ -23,7 +23,7 @@ TESTDIR="$CURDIR/../../.." # shellcheck source=../../../utils/utils.sh source "$TESTDIR/utils/utils.sh" -NUM_TESTS=84 +NUM_TESTS=100 FULL_LTTNG_BIN="${TESTDIR}/../src/bin/lttng/${LTTNG_BIN}" @@ -32,6 +32,7 @@ tmp_stderr=$(mktemp -t test_list_triggers_cli_stderr.XXXXXX) tmp_expected_stdout=$(mktemp -t test_list_triggers_cli_expected_stdout.XXXXXX) uprobe_elf_binary=$(realpath "${TESTDIR}/utils/testapp/userspace-probe-elf-binary/.libs/userspace-probe-elf-binary") uprobe_sdt_binary=$(realpath "${TESTDIR}/utils/testapp/userspace-probe-sdt-binary/.libs/userspace-probe-sdt-binary") +register_some_triggers_bin=$(realpath "${CURDIR}/utils/register-some-triggers") uid=$(id --user) gid=$(id --group) @@ -350,6 +351,115 @@ test_on_event_syscall () lttng_remove_trigger_ok "T1" } +test_session_consumed_size_condition () +{ + ${register_some_triggers_bin} test_session_consumed_size_condition + + cat > "${tmp_expected_stdout}" <<- EOF + - name: trigger-with-session-consumed-size-condition + owner uid: ${uid} + condition: session consumed size + session name: the-session-name + threshold: 1234 bytes + actions: + notify + errors: none + errors: none + EOF + + list_triggers_matches_ok "session consumed size condition" "${tmp_expected_stdout}" + + lttng_remove_trigger_ok "trigger-with-session-consumed-size-condition" +} + +test_buffer_usage_conditions () +{ + ${register_some_triggers_bin} test_buffer_usage_conditions + + cat > "${tmp_expected_stdout}" <<- EOF + - name: trigger-with-buffer-usage-high-bytes-condition + owner uid: ${uid} + condition: buffer usage high + session name: the-session-name + channel name: the-channel-name + domain: ust + threshold (bytes): 1234 + actions: + notify + errors: none + errors: none + - name: trigger-with-buffer-usage-high-ratio-condition + owner uid: ${uid} + condition: buffer usage high + session name: the-session-name + channel name: the-channel-name + domain: ust + threshold (ratio): 0.25 + actions: + notify + errors: none + errors: none + - name: trigger-with-buffer-usage-low-bytes-condition + owner uid: ${uid} + condition: buffer usage low + session name: the-session-name + channel name: the-channel-name + domain: ust + threshold (bytes): 2345 + actions: + notify + errors: none + errors: none + - name: trigger-with-buffer-usage-low-ratio-condition + owner uid: ${uid} + condition: buffer usage low + session name: the-session-name + channel name: the-channel-name + domain: ust + threshold (ratio): 0.40 + actions: + notify + errors: none + errors: none + EOF + + list_triggers_matches_ok "buffer usage condition" "${tmp_expected_stdout}" + + lttng_remove_trigger_ok "trigger-with-buffer-usage-high-bytes-condition" + lttng_remove_trigger_ok "trigger-with-buffer-usage-high-ratio-condition" + lttng_remove_trigger_ok "trigger-with-buffer-usage-low-bytes-condition" + lttng_remove_trigger_ok "trigger-with-buffer-usage-low-ratio-condition" +} + +test_session_rotation_conditions () +{ + ${register_some_triggers_bin} test_session_rotation_conditions + + cat > "${tmp_expected_stdout}" <<- EOF + - name: trigger-with-session-rotation-completed-condition + owner uid: ${uid} + condition: session rotation completed + session name: the-session-name + actions: + notify + errors: none + errors: none + - name: trigger-with-session-rotation-ongoing-condition + owner uid: ${uid} + condition: session rotation ongoing + session name: the-session-name + actions: + notify + errors: none + errors: none + EOF + + list_triggers_matches_ok "session rotation conditions" "${tmp_expected_stdout}" + + lttng_remove_trigger_ok "trigger-with-session-rotation-completed-condition" + lttng_remove_trigger_ok "trigger-with-session-rotation-ongoing-condition" +} + test_snapshot_action () { diag "Listing snapshot actions" @@ -486,7 +596,7 @@ test_notify_action () errors: none EOF - list_triggers_matches_ok "snapshot action" "${tmp_expected_stdout}" + list_triggers_matches_ok "notify action" "${tmp_expected_stdout}" lttng_remove_trigger_ok "T0" lttng_remove_trigger_ok "T1" @@ -500,9 +610,12 @@ start_lttng_sessiond_notap test_top_level_options test_on_event_tracepoint skip $ist_root "non-root user: skipping kprobe tests" 9 || test_on_event_probe -skip $ist_root "non-root user: skipping userspace probe elf tests" 5 || test_on_event_userspace_probe_elf +skip $ist_root "non-root user: skipping uprobe tests" 5 || test_on_event_userspace_probe_elf skip $(($ist_root && $hast_sdt_binary)) "skipping userspace probe SDT tests" 5 || test_on_event_userspace_probe_sdt skip $ist_root "non-root user: skipping syscall tests" 7 || test_on_event_syscall +test_session_consumed_size_condition +test_buffer_usage_conditions +test_session_rotation_conditions test_snapshot_action test_notify_action diff --git a/tests/regression/tools/trigger/utils/Makefile.am b/tests/regression/tools/trigger/utils/Makefile.am index 4b716cadb..21fb53112 100644 --- a/tests/regression/tools/trigger/utils/Makefile.am +++ b/tests/regression/tools/trigger/utils/Makefile.am @@ -3,7 +3,15 @@ AM_CFLAGS += -I$(srcdir) -I$(top_srcdir)/tests/utils LIBLTTNG_CTL=$(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la -noinst_PROGRAMS = notification-client +noinst_PROGRAMS = \ + notification-client \ + register-some-triggers + notification_client_SOURCES = notification-client.c notification_client_LDADD = $(LIBLTTNG_CTL) \ - $(top_builddir)/tests/utils/libtestutils.la + $(top_builddir)/tests/utils/libtestutils.la + +register_some_triggers_SOURCES = register-some-triggers.c +register_some_triggers_LDADD = $(LIBLTTNG_CTL) \ + $(top_builddir)/src/common/filter/libfilter.la \ + $(top_builddir)/src/common/bytecode/libbytecode.la diff --git a/tests/regression/tools/trigger/utils/register-some-triggers.c b/tests/regression/tools/trigger/utils/register-some-triggers.c new file mode 100644 index 000000000..e462b9afc --- /dev/null +++ b/tests/regression/tools/trigger/utils/register-some-triggers.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2021 Simon Marchi + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +/* Utility to register some triggers, for test purposes. */ + +#include +#include +#include + +#include +#include +#include + +static void register_trigger(const char *trigger_name, + struct lttng_condition *condition, + struct lttng_action *action) +{ + struct lttng_trigger *trigger; + enum lttng_trigger_status trigger_status; + int ret; + + trigger = lttng_trigger_create(condition, action); + trigger_status = lttng_trigger_set_name(trigger, trigger_name); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + ret = lttng_register_trigger(trigger); + assert(ret == 0); +} + +/* + * Register a trigger with the given condition and an action group containing a + * single notify action. + */ +static void register_trigger_action_group_notify( + const char *trigger_name, struct lttng_condition *condition) +{ + struct lttng_action *action_notify; + struct lttng_action *action_group; + enum lttng_action_status action_status; + + action_group = lttng_action_group_create(); + action_notify = lttng_action_notify_create(); + action_status = lttng_action_group_add_action( + action_group, action_notify); + assert(action_status == LTTNG_ACTION_STATUS_OK); + + register_trigger(trigger_name, condition, action_group); +} + +static struct lttng_condition *create_session_consumed_size_condition( + const char *session_name, uint64_t threshold) +{ + struct lttng_condition *condition; + enum lttng_condition_status condition_status; + + condition = lttng_condition_session_consumed_size_create(); + condition_status = + lttng_condition_session_consumed_size_set_session_name( + condition, session_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + condition_status = lttng_condition_session_consumed_size_set_threshold( + condition, threshold); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + + return condition; +} + +static void test_session_consumed_size_condition(void) +{ + register_trigger_action_group_notify( + "trigger-with-session-consumed-size-condition", + create_session_consumed_size_condition( + "the-session-name", 1234)); +} + +static void fill_buffer_usage_condition(struct lttng_condition *condition, + const char *session_name, + const char *channel_name, + enum lttng_domain_type domain_type) +{ + enum lttng_condition_status condition_status; + + condition_status = lttng_condition_buffer_usage_set_session_name( + condition, session_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + condition_status = lttng_condition_buffer_usage_set_channel_name( + condition, channel_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); + condition_status = lttng_condition_buffer_usage_set_domain_type( + condition, domain_type); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); +} + +static void fill_buffer_usage_bytes_condition(struct lttng_condition *condition, + const char *session_name, + const char *channel_name, + enum lttng_domain_type domain_type, + uint64_t threshold) +{ + enum lttng_condition_status condition_status; + + fill_buffer_usage_condition( + condition, session_name, channel_name, domain_type); + condition_status = lttng_condition_buffer_usage_set_threshold( + condition, threshold); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); +} + +static void fill_buffer_usage_ratio_condition(struct lttng_condition *condition, + const char *session_name, + const char *channel_name, + enum lttng_domain_type domain_type, + double ratio) +{ + enum lttng_condition_status condition_status; + + fill_buffer_usage_condition( + condition, session_name, channel_name, domain_type); + condition_status = lttng_condition_buffer_usage_set_threshold_ratio( + condition, ratio); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); +} + +static struct lttng_condition *create_buffer_usage_high_bytes_condition( + const char *session_name, + const char *channel_name, + enum lttng_domain_type domain_type, + uint64_t threshold) +{ + struct lttng_condition *condition; + + condition = lttng_condition_buffer_usage_high_create(); + fill_buffer_usage_bytes_condition(condition, session_name, channel_name, + domain_type, threshold); + + return condition; +} + +static struct lttng_condition *create_buffer_usage_low_bytes_condition( + const char *session_name, + const char *channel_name, + enum lttng_domain_type domain_type, + uint64_t threshold) +{ + struct lttng_condition *condition; + + condition = lttng_condition_buffer_usage_low_create(); + fill_buffer_usage_bytes_condition(condition, session_name, channel_name, + domain_type, threshold); + + return condition; +} + +static struct lttng_condition *create_buffer_usage_high_ratio_condition( + const char *session_name, + const char *channel_name, + enum lttng_domain_type domain_type, + double ratio) +{ + struct lttng_condition *condition; + + condition = lttng_condition_buffer_usage_high_create(); + fill_buffer_usage_ratio_condition(condition, session_name, channel_name, + domain_type, ratio); + + return condition; +} + +static struct lttng_condition *create_buffer_usage_low_ratio_condition( + const char *session_name, + const char *channel_name, + enum lttng_domain_type domain_type, + double ratio) +{ + struct lttng_condition *condition; + + condition = lttng_condition_buffer_usage_low_create(); + fill_buffer_usage_ratio_condition(condition, session_name, channel_name, + domain_type, ratio); + + return condition; +} + +static void test_buffer_usage_conditions(void) +{ + register_trigger_action_group_notify( + "trigger-with-buffer-usage-high-bytes-condition", + create_buffer_usage_high_bytes_condition( + "the-session-name", "the-channel-name", + LTTNG_DOMAIN_UST, 1234)); + + register_trigger_action_group_notify( + "trigger-with-buffer-usage-low-bytes-condition", + create_buffer_usage_low_bytes_condition( + "the-session-name", "the-channel-name", + LTTNG_DOMAIN_UST, 2345)); + + register_trigger_action_group_notify( + "trigger-with-buffer-usage-high-ratio-condition", + create_buffer_usage_high_ratio_condition( + "the-session-name", "the-channel-name", + LTTNG_DOMAIN_UST, 0.25)); + + register_trigger_action_group_notify( + "trigger-with-buffer-usage-low-ratio-condition", + create_buffer_usage_low_ratio_condition( + "the-session-name", "the-channel-name", + LTTNG_DOMAIN_UST, 0.4)); +} + +static void fill_session_rotation_condition( + struct lttng_condition *condition, const char *session_name) +{ + enum lttng_condition_status condition_status; + + condition_status = lttng_condition_session_rotation_set_session_name( + condition, session_name); + assert(condition_status == LTTNG_CONDITION_STATUS_OK); +} + +static struct lttng_condition *create_session_rotation_ongoing_condition( + const char *session_name) +{ + struct lttng_condition *condition; + + condition = lttng_condition_session_rotation_ongoing_create(); + + fill_session_rotation_condition(condition, session_name); + + return condition; +} + +static struct lttng_condition *create_session_rotation_completed_condition( + const char *session_name) +{ + struct lttng_condition *condition; + + condition = lttng_condition_session_rotation_completed_create(); + + fill_session_rotation_condition(condition, session_name); + + return condition; +} + +static void test_session_rotation_conditions(void) +{ + register_trigger_action_group_notify( + "trigger-with-session-rotation-ongoing-condition", + create_session_rotation_ongoing_condition( + "the-session-name")); + + register_trigger_action_group_notify( + "trigger-with-session-rotation-completed-condition", + create_session_rotation_completed_condition( + "the-session-name")); +} + +static struct { + const char *name; + void (*callback)(void); +} tests[] = { + { + "test_session_consumed_size_condition", + test_session_consumed_size_condition, + }, + {"test_buffer_usage_conditions", test_buffer_usage_conditions}, + {"test_session_rotation_conditions", + test_session_rotation_conditions}, +}; + +static void show_known_tests(void) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + fprintf(stderr, " - %s\n", tests[i].name); + } +} + +int main(int argc, char **argv) +{ + const char *test; + size_t i; + int ret; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, "\n"); + fprintf(stderr, "Test must be one of:\n"); + show_known_tests(); + goto error; + } + + test = argv[1]; + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + if (strcmp(tests[i].name, test) == 0) { + break; + } + } + + if (i == ARRAY_SIZE(tests)) { + fprintf(stderr, "Unrecognized test `%s`\n", test); + fprintf(stderr, "\n"); + fprintf(stderr, "Known tests:\n"); + show_known_tests(); + goto error; + } + + tests[i].callback(); + + ret = 0; + goto end; + +error: + ret = 1; + +end: + return ret; +}