- 'cds_lfht_for_each_duplicate'
- 'cds_list_for_each_entry'
- 'cds_list_for_each_entry_safe'
+ - 'for_each_action_mutable'
+ - 'for_each_action_const'
IncludeBlocks: Regroup
IncludeCategories:
#include <common/macros.hpp>
+#include <lttng/lttng-error.h>
+
+#include <assert.h>
#include <sys/types.h>
struct lttng_action;
const struct mi_lttng_error_query_callbacks *error_query_callbacks,
struct lttng_dynamic_array *action_path_indexes);
+#define for_each_action_const(__action_element, __action_list) \
+ assert(lttng_action_get_type(__action_list) == LTTNG_ACTION_TYPE_LIST); \
+ \
+ for (unsigned int __action_idx = 0; \
+ (__action_element = lttng_action_list_get_at_index(__action_list, __action_idx)); \
+ __action_idx++)
+
+#define for_each_action_mutable(__action_element, __action_list) \
+ assert(lttng_action_get_type(__action_list) == LTTNG_ACTION_TYPE_LIST); \
+ \
+ for (unsigned int __action_idx = 0; \
+ (__action_element = \
+ lttng_action_list_borrow_mutable_at_index(__action_list, __action_idx)); \
+ __action_idx++)
+
#endif /* LTTNG_ACTION_LIST_INTERNAL_H */
LTTNG_ASSERT(subitems);
if (type == LTTNG_ACTION_TYPE_LIST) {
- unsigned int count, i;
+ struct lttng_action *inner_action = NULL;
- status = lttng_action_list_get_count(action, &count);
- LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
-
- for (i = 0; i < count; i++) {
- struct lttng_action *inner_action = nullptr;
-
- inner_action = lttng_action_list_borrow_mutable_at_index(action, i);
+ for_each_action_mutable (inner_action, action) {
LTTNG_ASSERT(inner_action);
+
ret = add_action_to_subitem_array(inner_action, subitems);
if (ret) {
goto end;
static bool is_trigger_action_notify(const struct lttng_trigger *trigger)
{
bool is_notify = false;
- unsigned int i, count;
- enum lttng_action_status action_status;
const struct lttng_action *action = lttng_trigger_get_const_action(trigger);
+ const struct lttng_action *inner_action;
enum lttng_action_type action_type;
LTTNG_ASSERT(action);
goto end;
}
- action_status = lttng_action_list_get_count(action, &count);
- LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
-
- for (i = 0; i < count; i++) {
- const struct lttng_action *inner_action = lttng_action_list_get_at_index(action, i);
-
- action_type = lttng_action_get_type(inner_action);
- if (action_type == LTTNG_ACTION_TYPE_NOTIFY) {
+ for_each_action_const (inner_action, action) {
+ if (lttng_action_get_type(inner_action) == LTTNG_ACTION_TYPE_NOTIFY) {
is_notify = true;
goto end;
}
#include "common/argpar/argpar.h"
#include "common/dynamic-array.hpp"
#include "common/mi-lttng.hpp"
+#include "lttng/action/list-internal.hpp"
-#include <stdio.h>
/* For lttng_condition_type_str(). */
#include "lttng/condition/condition-internal.hpp"
#include "lttng/condition/event-rule-matches-internal.hpp"
#include "lttng/condition/event-rule-matches.h"
+
/* For lttng_domain_type_str(). */
#include "lttng/domain-internal.hpp"
+
/* For lttng_event_rule_kernel_syscall_emission_site_str() */
#include "../loglevel.hpp"
#include "lttng/event-rule/kernel-syscall-internal.hpp"
action = lttng_trigger_get_const_action(trigger);
action_type = lttng_action_get_type(action);
if (action_type == LTTNG_ACTION_TYPE_LIST) {
- unsigned int count, i;
- enum lttng_action_status action_status;
+ const struct lttng_action *subaction;
+ uint64_t action_path_index = 0;
MSG(" actions:");
-
- action_status = lttng_action_list_get_count(action, &count);
- LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
-
- for (i = 0; i < count; i++) {
- const uint64_t action_path_index = i;
- const struct lttng_action *subaction =
- lttng_action_list_get_at_index(action, i);
-
+ for_each_action_const (subaction, action) {
_MSG(" ");
print_one_action(trigger, subaction, &action_path_index, 1);
+ action_path_index++;
}
} else {
_MSG(" action:");
notification-client \
register-some-triggers
-notification_client_SOURCES = notification-client.c
+notification_client_SOURCES = notification-client.cpp
notification_client_LDADD = $(LIBLTTNG_CTL) \
$(top_builddir)/tests/utils/libtestutils.la
+++ /dev/null
-/*
- * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * SPDX-License-Identifier: MIT
- *
- */
-
-#include "utils.h"
-
-#include <lttng/condition/event-rule-matches.h>
-#include <lttng/lttng.h>
-
-#include <getopt.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-
-static struct option long_options[] = {
- /* These options set a flag. */
- { "trigger", required_argument, 0, 't' },
- { "sync-after-notif-register", required_argument, 0, 'a' },
- /* Default alue for count is 1 */
- { "count", required_argument, 0, 'b' },
- /*
- * When end-trigger is present the reception loop is exited only when a
- * notification matching the end trigger is received.
- * Otherwise the loop is exited when the count of notification received
- * for `trigger` math the `count` argument.
- */
- { "end-trigger", required_argument, 0, 'c' },
- { 0, 0, 0, 0 }
-};
-
-static bool action_list_contains_notify(const struct lttng_action *action_list)
-{
- unsigned int i, count;
- enum lttng_action_status status = lttng_action_list_get_count(action_list, &count);
-
- if (status != LTTNG_ACTION_STATUS_OK) {
- printf("Failed to get action count from action list\n");
- exit(1);
- }
-
- for (i = 0; i < count; i++) {
- const struct lttng_action *action = lttng_action_list_get_at_index(action_list, i);
- const enum lttng_action_type action_type = lttng_action_get_type(action);
-
- if (action_type == LTTNG_ACTION_TYPE_NOTIFY) {
- return true;
- }
- }
- return false;
-}
-
-/* Only expects named triggers. */
-static bool is_trigger_name(const char *expected_trigger_name,
- struct lttng_notification *notification)
-{
- const char *trigger_name = NULL;
- enum lttng_trigger_status trigger_status;
- const struct lttng_trigger *trigger;
- bool names_match;
-
- trigger = lttng_notification_get_trigger(notification);
- if (!trigger) {
- fprintf(stderr, "Failed to get trigger from notification\n");
- names_match = false;
- goto end;
- }
-
- trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
- if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
- fprintf(stderr, "Failed to get name from notification's trigger\n");
- names_match = false;
- goto end;
- }
-
- names_match = strcmp(expected_trigger_name, trigger_name) == 0;
- if (!names_match) {
- fprintf(stderr,
- "Got an unexpected trigger name: name = '%s', expected name = '%s'\n",
- trigger_name,
- expected_trigger_name);
- }
-end:
- return names_match;
-}
-
-int main(int argc, char **argv)
-{
- int ret;
- int option;
- int option_index;
- char *expected_trigger_name = NULL;
- char *end_trigger_name = NULL;
- struct lttng_triggers *triggers = NULL;
- unsigned int count, i, subcription_count = 0;
- enum lttng_trigger_status trigger_status;
- char *after_notif_register_file_path = NULL;
- struct lttng_notification_channel *notification_channel = NULL;
- int expected_notifications = 1, notification_count = 0;
-
- while ((option = getopt_long(argc, argv, "a:b:c:t:", long_options, &option_index)) != -1) {
- switch (option) {
- case 'a':
- after_notif_register_file_path = strdup(optarg);
- break;
- case 'b':
- expected_notifications = atoi(optarg);
- break;
- case 'c':
- end_trigger_name = strdup(optarg);
- break;
- case 't':
- expected_trigger_name = strdup(optarg);
- break;
- case '?':
- /* getopt_long already printed an error message. */
- default:
- ret = -1;
- goto end;
- }
- }
-
- if (optind != argc) {
- ret = -1;
- goto end;
- }
-
- notification_channel =
- lttng_notification_channel_create(lttng_session_daemon_notification_endpoint);
- if (!notification_channel) {
- fprintf(stderr, "Failed to create notification channel\n");
- ret = -1;
- goto end;
- }
-
- ret = lttng_list_triggers(&triggers);
- if (ret != LTTNG_OK) {
- fprintf(stderr, "Failed to list triggers\n");
- ret = -1;
- goto end;
- }
-
- trigger_status = lttng_triggers_get_count(triggers, &count);
- if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
- fprintf(stderr, "Failed to get trigger count\n");
- ret = -1;
- goto end;
- }
-
- /* Look for the trigger we want to subscribe to. */
- for (i = 0; i < count; i++) {
- const struct lttng_trigger *trigger = lttng_triggers_get_at_index(triggers, i);
- const struct lttng_condition *condition =
- lttng_trigger_get_const_condition(trigger);
- const struct lttng_action *action = lttng_trigger_get_const_action(trigger);
- const enum lttng_action_type action_type = lttng_action_get_type(action);
- enum lttng_notification_channel_status channel_status;
- const char *trigger_name = NULL;
-
- lttng_trigger_get_name(trigger, &trigger_name);
- if (strcmp(trigger_name, expected_trigger_name) != 0) {
- /* Might match the end event trigger */
- if (end_trigger_name != NULL &&
- strcmp(trigger_name, end_trigger_name) != 0) {
- continue;
- }
- }
- if (!((action_type == LTTNG_ACTION_TYPE_LIST &&
- action_list_contains_notify(action)) ||
- action_type == LTTNG_ACTION_TYPE_NOTIFY)) {
- /* "The action of trigger is not notify, skipping. */
- continue;
- }
-
- channel_status =
- lttng_notification_channel_subscribe(notification_channel, condition);
- if (channel_status) {
- fprintf(stderr,
- "Failed to subscribe to notifications of trigger \"%s\"\n",
- trigger_name);
- ret = -1;
- goto end;
- }
-
- subcription_count++;
- }
-
- if (subcription_count == 0) {
- fprintf(stderr, "No matching trigger with a notify action found.\n");
- ret = -1;
- goto end;
- }
-
- if (end_trigger_name != NULL && subcription_count != 2) {
- fprintf(stderr, "No matching end event trigger with a notify action found.\n");
- ret = -1;
- goto end;
- }
-
- /*
- * We registered to the notification of our target trigger. We can now
- * create the sync file to signify that we are ready.
- */
- ret = create_file(after_notif_register_file_path);
- if (ret != 0) {
- goto end;
- }
-
- for (;;) {
- struct lttng_notification *notification;
- enum lttng_notification_channel_status channel_status;
-
- channel_status = lttng_notification_channel_get_next_notification(
- notification_channel, ¬ification);
- switch (channel_status) {
- case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
- printf("Dropped notification\n");
- ret = -1;
- goto end;
- case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED:
- ret = -1;
- goto end;
- case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
- break;
- case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED:
- printf("Notification channel was closed by peer.\n");
- break;
- default:
- fprintf(stderr,
- "A communication error occurred on the notification channel.\n");
- ret = -1;
- goto end;
- }
-
- /* Early exit check. */
- if (end_trigger_name != NULL && is_trigger_name(end_trigger_name, notification)) {
- /* Exit the loop immediately. */
- printf("Received end event notification from trigger %s\n",
- end_trigger_name);
- lttng_notification_destroy(notification);
- goto evaluate_success;
- }
-
- ret = is_trigger_name(expected_trigger_name, notification);
- lttng_notification_destroy(notification);
- if (!ret) {
- ret = -1;
- goto end;
- }
-
- printf("Received event notification from trigger %s\n", expected_trigger_name);
- notification_count++;
- if (end_trigger_name == NULL && expected_notifications == notification_count) {
- /*
- * Here the loop exit is controlled by the number of
- * notification and not by the reception of the end
- * event trigger notification. This represent the
- * default behavior.
- *
- */
- goto evaluate_success;
- }
- }
-
-evaluate_success:
- if (expected_notifications == notification_count) {
- /* Success */
- ret = 0;
- } else {
- fprintf(stderr,
- "Expected %d notification got %d\n",
- expected_notifications,
- notification_count);
- ret = 1;
- }
-
-end:
- lttng_triggers_destroy(triggers);
- lttng_notification_channel_destroy(notification_channel);
- free(after_notif_register_file_path);
- free(end_trigger_name);
- free(expected_trigger_name);
- return !!ret;
-}
--- /dev/null
+/*
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ */
+
+#include "utils.h"
+
+#include <lttng/action/list-internal.hpp>
+#include <lttng/condition/event-rule-matches.h>
+#include <lttng/lttng.h>
+
+#include <getopt.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+
+static struct option long_options[] = {
+ /* These options set a flag. */
+ { "trigger", required_argument, 0, 't' },
+ { "sync-after-notif-register", required_argument, 0, 'a' },
+ /* Default alue for count is 1 */
+ { "count", required_argument, 0, 'b' },
+ /*
+ * When end-trigger is present the reception loop is exited only when a
+ * notification matching the end trigger is received.
+ * Otherwise the loop is exited when the count of notification received
+ * for `trigger` math the `count` argument.
+ */
+ { "end-trigger", required_argument, 0, 'c' },
+ { 0, 0, 0, 0 }
+};
+
+static bool action_list_contains_notify(const struct lttng_action *action_list)
+{
+ const struct lttng_action *sub_action;
+
+ for_each_action_const (sub_action, action_list) {
+ if (lttng_action_get_type(sub_action) == LTTNG_ACTION_TYPE_NOTIFY) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Only expects named triggers. */
+static bool is_trigger_name(const char *expected_trigger_name,
+ struct lttng_notification *notification)
+{
+ const char *trigger_name = NULL;
+ enum lttng_trigger_status trigger_status;
+ const struct lttng_trigger *trigger;
+ bool names_match;
+
+ trigger = lttng_notification_get_trigger(notification);
+ if (!trigger) {
+ fprintf(stderr, "Failed to get trigger from notification\n");
+ names_match = false;
+ goto end;
+ }
+
+ trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
+ if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
+ fprintf(stderr, "Failed to get name from notification's trigger\n");
+ names_match = false;
+ goto end;
+ }
+
+ names_match = strcmp(expected_trigger_name, trigger_name) == 0;
+ if (!names_match) {
+ fprintf(stderr,
+ "Got an unexpected trigger name: name = '%s', expected name = '%s'\n",
+ trigger_name,
+ expected_trigger_name);
+ }
+end:
+ return names_match;
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ int option;
+ int option_index;
+ char *expected_trigger_name = NULL;
+ char *end_trigger_name = NULL;
+ struct lttng_triggers *triggers = NULL;
+ unsigned int count, i, subcription_count = 0;
+ enum lttng_trigger_status trigger_status;
+ char *after_notif_register_file_path = NULL;
+ struct lttng_notification_channel *notification_channel = NULL;
+ int expected_notifications = 1, notification_count = 0;
+
+ while ((option = getopt_long(argc, argv, "a:b:c:t:", long_options, &option_index)) != -1) {
+ switch (option) {
+ case 'a':
+ after_notif_register_file_path = strdup(optarg);
+ break;
+ case 'b':
+ expected_notifications = atoi(optarg);
+ break;
+ case 'c':
+ end_trigger_name = strdup(optarg);
+ break;
+ case 't':
+ expected_trigger_name = strdup(optarg);
+ break;
+ case '?':
+ /* getopt_long already printed an error message. */
+ default:
+ ret = -1;
+ goto end;
+ }
+ }
+
+ if (optind != argc) {
+ ret = -1;
+ goto end;
+ }
+
+ notification_channel =
+ lttng_notification_channel_create(lttng_session_daemon_notification_endpoint);
+ if (!notification_channel) {
+ fprintf(stderr, "Failed to create notification channel\n");
+ ret = -1;
+ goto end;
+ }
+
+ ret = lttng_list_triggers(&triggers);
+ if (ret != LTTNG_OK) {
+ fprintf(stderr, "Failed to list triggers\n");
+ ret = -1;
+ goto end;
+ }
+
+ trigger_status = lttng_triggers_get_count(triggers, &count);
+ if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
+ fprintf(stderr, "Failed to get trigger count\n");
+ ret = -1;
+ goto end;
+ }
+
+ /* Look for the trigger we want to subscribe to. */
+ for (i = 0; i < count; i++) {
+ const struct lttng_trigger *trigger = lttng_triggers_get_at_index(triggers, i);
+ const struct lttng_condition *condition =
+ lttng_trigger_get_const_condition(trigger);
+ const struct lttng_action *action = lttng_trigger_get_const_action(trigger);
+ const enum lttng_action_type action_type = lttng_action_get_type(action);
+ enum lttng_notification_channel_status channel_status;
+ const char *trigger_name = NULL;
+
+ lttng_trigger_get_name(trigger, &trigger_name);
+ if (strcmp(trigger_name, expected_trigger_name) != 0) {
+ /* Might match the end event trigger */
+ if (end_trigger_name != NULL &&
+ strcmp(trigger_name, end_trigger_name) != 0) {
+ continue;
+ }
+ }
+ if (!((action_type == LTTNG_ACTION_TYPE_LIST &&
+ action_list_contains_notify(action)) ||
+ action_type == LTTNG_ACTION_TYPE_NOTIFY)) {
+ /* "The action of trigger is not notify, skipping. */
+ continue;
+ }
+
+ channel_status =
+ lttng_notification_channel_subscribe(notification_channel, condition);
+ if (channel_status) {
+ fprintf(stderr,
+ "Failed to subscribe to notifications of trigger \"%s\"\n",
+ trigger_name);
+ ret = -1;
+ goto end;
+ }
+
+ subcription_count++;
+ }
+
+ if (subcription_count == 0) {
+ fprintf(stderr, "No matching trigger with a notify action found.\n");
+ ret = -1;
+ goto end;
+ }
+
+ if (end_trigger_name != NULL && subcription_count != 2) {
+ fprintf(stderr, "No matching end event trigger with a notify action found.\n");
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * We registered to the notification of our target trigger. We can now
+ * create the sync file to signify that we are ready.
+ */
+ ret = create_file(after_notif_register_file_path);
+ if (ret != 0) {
+ goto end;
+ }
+
+ for (;;) {
+ struct lttng_notification *notification;
+ enum lttng_notification_channel_status channel_status;
+
+ channel_status = lttng_notification_channel_get_next_notification(
+ notification_channel, ¬ification);
+ switch (channel_status) {
+ case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
+ printf("Dropped notification\n");
+ ret = -1;
+ goto end;
+ case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED:
+ ret = -1;
+ goto end;
+ case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
+ break;
+ case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED:
+ printf("Notification channel was closed by peer.\n");
+ break;
+ default:
+ fprintf(stderr,
+ "A communication error occurred on the notification channel.\n");
+ ret = -1;
+ goto end;
+ }
+
+ /* Early exit check. */
+ if (end_trigger_name != NULL && is_trigger_name(end_trigger_name, notification)) {
+ /* Exit the loop immediately. */
+ printf("Received end event notification from trigger %s\n",
+ end_trigger_name);
+ lttng_notification_destroy(notification);
+ goto evaluate_success;
+ }
+
+ ret = is_trigger_name(expected_trigger_name, notification);
+ lttng_notification_destroy(notification);
+ if (!ret) {
+ ret = -1;
+ goto end;
+ }
+
+ printf("Received event notification from trigger %s\n", expected_trigger_name);
+ notification_count++;
+ if (end_trigger_name == NULL && expected_notifications == notification_count) {
+ /*
+ * Here the loop exit is controlled by the number of
+ * notification and not by the reception of the end
+ * event trigger notification. This represent the
+ * default behavior.
+ *
+ */
+ goto evaluate_success;
+ }
+ }
+
+evaluate_success:
+ if (expected_notifications == notification_count) {
+ /* Success */
+ ret = 0;
+ } else {
+ fprintf(stderr,
+ "Expected %d notification got %d\n",
+ expected_notifications,
+ notification_count);
+ ret = 1;
+ }
+
+end:
+ lttng_triggers_destroy(triggers);
+ lttng_notification_channel_destroy(notification_channel);
+ free(after_notif_register_file_path);
+ free(end_trigger_name);
+ free(expected_trigger_name);
+ return !!ret;
+}
#include <lttng/action/action-internal.hpp>
#include <lttng/action/action.h>
+#include <lttng/action/list-internal.hpp>
#include <lttng/action/notify.h>
#include <lttng/action/rate-policy-internal.hpp>
#include <lttng/action/rate-policy.h>
int lttng_opt_verbose;
int lttng_opt_mi;
-#define NUM_TESTS 60
+#define NUM_TESTS 71
static void test_action_notify()
{
lttng_payload_reset(&payload);
}
-static void test_action_rotate_session()
+static void test_action_list(void)
+{
+ int ret, action_idx;
+ struct lttng_action *list_action = NULL, *list_action_from_buffer = NULL,
+ *mut_inner_action = NULL, *stop_session_action = NULL,
+ *notify_action = NULL, *start_session_action = NULL;
+ const struct lttng_action *const_inner_action;
+ struct lttng_payload payload;
+
+ lttng_payload_init(&payload);
+
+ list_action = lttng_action_list_create();
+ ok(list_action, "Create list action");
+ ok(lttng_action_get_type(list_action) == LTTNG_ACTION_TYPE_LIST,
+ "Action has type LTTNG_ACTION_TYPE_LIST");
+
+ start_session_action = lttng_action_start_session_create();
+ (void) lttng_action_start_session_set_session_name(start_session_action, "une-session");
+
+ stop_session_action = lttng_action_stop_session_create();
+ (void) lttng_action_stop_session_set_session_name(stop_session_action, "une-autre-session");
+ notify_action = lttng_action_notify_create();
+
+ lttng_action_list_add_action(list_action, start_session_action);
+ lttng_action_list_add_action(list_action, stop_session_action);
+ lttng_action_list_add_action(list_action, notify_action);
+
+ ret = lttng_action_serialize(list_action, &payload);
+ ok(ret == 0, "Action list serialized");
+
+ {
+ struct lttng_payload_view view = lttng_payload_view_from_payload(&payload, 0, -1);
+ (void) lttng_action_create_from_payload(&view, &list_action_from_buffer);
+ }
+ ok(list_action_from_buffer, "Notify action created from payload is non-null");
+
+ ok(lttng_action_is_equal(list_action, list_action_from_buffer),
+ "Serialized and de-serialized list action are equal");
+
+ action_idx = 0;
+ for_each_action_const (const_inner_action, list_action) {
+ enum lttng_action_type inner_action_type =
+ lttng_action_get_type(const_inner_action);
+ switch (action_idx) {
+ case 0:
+ ok(inner_action_type == LTTNG_ACTION_TYPE_START_SESSION,
+ "First inner action of action list is `start-session` action");
+ break;
+ case 1:
+ ok(inner_action_type == LTTNG_ACTION_TYPE_STOP_SESSION,
+ "Second inner action of action list is `stop-session` action");
+ break;
+ case 2:
+ ok(inner_action_type == LTTNG_ACTION_TYPE_NOTIFY,
+ "Third inner action of action list is `notify` action");
+ break;
+ }
+ action_idx++;
+ }
+
+ action_idx = 0;
+ for_each_action_mutable (mut_inner_action, list_action) {
+ enum lttng_action_type inner_action_type = lttng_action_get_type(mut_inner_action);
+ switch (action_idx) {
+ case 0:
+ ok(inner_action_type == LTTNG_ACTION_TYPE_START_SESSION,
+ "First inner action of action list is `start-session` action");
+ break;
+ case 1:
+ ok(inner_action_type == LTTNG_ACTION_TYPE_STOP_SESSION,
+ "Second inner action of action list is `stop-session` action");
+ break;
+ case 2:
+ ok(inner_action_type == LTTNG_ACTION_TYPE_NOTIFY,
+ "Third inner action of action list is `notify` action");
+ break;
+ }
+ action_idx++;
+ }
+
+ lttng_action_destroy(list_action);
+ lttng_action_destroy(list_action_from_buffer);
+ lttng_action_destroy(start_session_action);
+ lttng_action_destroy(stop_session_action);
+ lttng_action_destroy(notify_action);
+ lttng_payload_reset(&payload);
+}
+
+static void test_action_rotate_session(void)
{
int ret;
enum lttng_action_status status;
{
plan_tests(NUM_TESTS);
test_action_notify();
+ test_action_list();
test_action_rotate_session();
test_action_start_session();
test_action_stop_session();