X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=tests%2Fregression%2Ftools%2Ftrigger%2Futils%2Fnotification-client.c;h=b656d726bdc5e88c425136d954e78814152ba789;hb=28f23191dcbf047429d51950a337a57d7a3f866a;hp=2c7c896d846a213038589f3580b6b6bb557d459d;hpb=e393070aaad23313daae844ff87043babaae69e7;p=lttng-tools.git diff --git a/tests/regression/tools/trigger/utils/notification-client.c b/tests/regression/tools/trigger/utils/notification-client.c index 2c7c896d8..b656d726b 100644 --- a/tests/regression/tools/trigger/utils/notification-client.c +++ b/tests/regression/tools/trigger/utils/notification-client.c @@ -5,6 +5,11 @@ * */ +#include "utils.h" + +#include +#include + #include #include #include @@ -14,37 +19,35 @@ #include #include -#include -#include - -#include "utils.h" - -static struct option long_options[] = -{ +static struct option long_options[] = { /* These options set a flag. */ - {"trigger", required_argument, 0, 'i'}, - {"sync-after-notif-register", required_argument, 0, 'a'}, - {0, 0, 0, 0} + { "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_group_contains_notify( - const struct lttng_action *action_group) +static bool action_list_contains_notify(const struct lttng_action *action_list) { unsigned int i, count; - enum lttng_action_status status = - lttng_action_group_get_count(action_group, &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 group\n"); + 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_group_get_at_index( - action_group, i); - const enum lttng_action_type action_type = - lttng_action_get_type(action); + 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; @@ -53,44 +56,38 @@ static bool action_group_contains_notify( return false; } -static bool is_expected_trigger_name(const char *expected_trigger_name, - struct lttng_notification *notification) +/* Only expects named triggers. */ +static bool is_trigger_name(const char *expected_trigger_name, + struct lttng_notification *notification) { - int ret = false; - const struct lttng_evaluation *evaluation = - lttng_notification_get_evaluation(notification); - const enum lttng_condition_type type = - lttng_evaluation_get_type(evaluation); - - switch (type) { - case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: - case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: - case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: - case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: - case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: - break; - case LTTNG_CONDITION_TYPE_ON_EVENT: - { - const char *trigger_name; - enum lttng_evaluation_status evaluation_status; - - evaluation_status = - lttng_evaluation_on_event_get_trigger_name( - evaluation, &trigger_name); - if (evaluation_status != LTTNG_EVALUATION_STATUS_OK) { - fprintf(stderr, "Failed to get trigger name of event rule notification\n"); - ret = -1; - break; - } + const char *trigger_name = NULL; + enum lttng_trigger_status trigger_status; + const struct lttng_trigger *trigger; + bool names_match; - ret = true; - break; + trigger = lttng_notification_get_trigger(notification); + if (!trigger) { + fprintf(stderr, "Failed to get trigger from notification\n"); + names_match = false; + goto end; } - default: - fprintf(stderr, "Unknown notification type (%d)\n", type); + + 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; } - return ret; + 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) @@ -98,19 +95,26 @@ int main(int argc, char **argv) int ret; int option; int option_index; - const char *expected_trigger_name = NULL; + 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:t:", - long_options, &option_index)) != -1) { + 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; @@ -127,9 +131,8 @@ int main(int argc, char **argv) goto end; } - - notification_channel = lttng_notification_channel_create( - lttng_session_daemon_notification_endpoint); + notification_channel = + lttng_notification_channel_create(lttng_session_daemon_notification_endpoint); if (!notification_channel) { fprintf(stderr, "Failed to create notification channel\n"); ret = -1; @@ -139,6 +142,7 @@ int main(int argc, char **argv) ret = lttng_list_triggers(&triggers); if (ret != LTTNG_OK) { fprintf(stderr, "Failed to list triggers\n"); + ret = -1; goto end; } @@ -149,35 +153,37 @@ int main(int argc, char **argv) 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_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); + 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)) { - continue; + 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_GROUP && - action_group_contains_notify(action)) || - action_type == LTTNG_ACTION_TYPE_NOTIFY)) { + 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); + 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); + fprintf(stderr, + "Failed to subscribe to notifications of trigger \"%s\"\n", + trigger_name); ret = -1; goto end; } @@ -186,11 +192,16 @@ int main(int argc, char **argv) } if (subcription_count == 0) { - printf("No matching trigger with a notify action found.\n"); - ret = 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 @@ -205,16 +216,15 @@ int main(int argc, char **argv) struct lttng_notification *notification; enum lttng_notification_channel_status channel_status; - channel_status = - lttng_notification_channel_get_next_notification( - notification_channel, - ¬ification); + 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"); - break; + ret = -1; + goto end; case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED: - ret = 0; + ret = -1; goto end; case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK: break; @@ -222,21 +232,59 @@ int main(int argc, char **argv) printf("Notification channel was closed by peer.\n"); break; default: - fprintf(stderr, "A communication error occurred on the notification channel.\n"); + fprintf(stderr, + "A communication error occurred on the notification channel.\n"); ret = -1; goto end; } - ret = is_expected_trigger_name(expected_trigger_name, - notification); + /* 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 = 0; + 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; }