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
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);
# 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}"
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)
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"
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"
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
--- /dev/null
+/*
+ * 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;
+}