lttng list-triggers: handle all condition types
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 15 Apr 2021 13:07:31 +0000 (09:07 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 22 Apr 2021 05:36:13 +0000 (01:36 -0400)
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 <simon.marchi@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng/commands/list_triggers.c
tests/regression/tools/trigger/test_list_triggers_cli
tests/regression/tools/trigger/utils/Makefile.am
tests/regression/tools/trigger/utils/register-some-triggers.c [new file with mode: 0644]

index 91ff1c06850222584bcdb9b3d721bee5f7fd101d..bb118e56a217f48c70aeb78a309d28f8c84259ea 100644 (file)
@@ -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);
index 31ba7b366c114d4dd2c1febbf9da555233342302..89c77eb54d41b20c1405441c96229a9b16dad21c 100755 (executable)
@@ -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
 
index 4b716cadbe5ff76d053720d99ff77a1b11530309..21fb531122521e3e2ff079a14c8479eda017138b 100644 (file)
@@ -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 (file)
index 0000000..e462b9a
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+/* Utility to register some triggers, for test purposes. */
+
+#include <common/filter/filter-ast.h>
+#include <common/macros.h>
+#include <lttng/lttng.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+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 <test>\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;
+}
This page took 0.031844 seconds and 4 git commands to generate.