4 * Tests suite for LTTng notification API
6 * Copyright (C) 2017 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
8 * SPDX-License-Identifier: MIT
20 #include <sys/types.h>
26 #include <common/compat/errno.h>
27 #include <lttng/action/action.h>
28 #include <lttng/action/notify.h>
29 #include <lttng/condition/buffer-usage.h>
30 #include <lttng/condition/condition.h>
31 #include <lttng/condition/evaluation.h>
32 #include <lttng/condition/event-rule.h>
33 #include <lttng/domain.h>
34 #include <lttng/endpoint.h>
35 #include <lttng/event-rule/kprobe.h>
36 #include <lttng/event-rule/syscall.h>
37 #include <lttng/event-rule/tracepoint.h>
38 #include <lttng/kernel-probe.h>
39 #include <lttng/lttng-error.h>
40 #include <lttng/lttng.h>
41 #include <lttng/notification/channel.h>
42 #include <lttng/notification/notification.h>
43 #include <lttng/trigger/trigger.h>
48 int named_pipe_args_start
= 0;
50 const char *app_state_file
= NULL
;
53 void wait_on_file(const char *path
, bool file_exist
)
62 ret
= stat(path
, &buf
);
63 if (ret
== -1 && errno
== ENOENT
) {
66 * The file does not exist. wait a bit and
67 * continue looping until it does.
69 (void) poll(NULL
, 0, 10);
74 * File does not exist and the exit condition we want.
75 * Break from the loop and return.
84 * stat() returned 0, so the file exists. break now only if
85 * that's the exit condition we want.
94 int write_pipe(const char *path
, uint8_t data
)
99 fd
= open(path
, O_WRONLY
| O_NONBLOCK
);
101 perror("Could not open consumer control named pipe");
105 ret
= write(fd
, &data
, sizeof(data
));
107 perror("Named pipe write failed");
109 perror("Named pipe close failed");
117 perror("Name pipe closing failed");
126 int stop_consumer(const char **argv
)
130 for (i
= named_pipe_args_start
; i
< nb_args
; i
++) {
131 ret
= write_pipe(argv
[i
], 49);
137 int resume_consumer(const char **argv
)
141 for (i
= named_pipe_args_start
; i
< nb_args
; i
++) {
142 ret
= write_pipe(argv
[i
], 0);
148 int suspend_application(void)
153 if (!stat(app_state_file
, &buf
)) {
154 fail("App is already in a suspended state.");
160 * Send SIGUSR1 to application instructing it to bypass tracepoint.
164 ret
= kill(app_pid
, SIGUSR1
);
166 fail("SIGUSR1 failed. errno %d", errno
);
171 wait_on_file(app_state_file
, true);
179 int resume_application(void)
184 ret
= stat(app_state_file
, &buf
);
185 if (ret
== -1 && errno
== ENOENT
) {
186 fail("State file does not exist");
196 ret
= kill(app_pid
, SIGUSR1
);
198 fail("SIGUSR1 failed. errno %d", errno
);
203 wait_on_file(app_state_file
, false);
212 void test_triggers_buffer_usage_condition(const char *session_name
,
213 const char *channel_name
,
214 enum lttng_domain_type domain_type
,
215 enum lttng_condition_type condition_type
)
217 unsigned int test_vector_size
= 5, i
;
218 enum lttng_condition_status condition_status
;
219 struct lttng_action
*action
;
222 action
= lttng_action_notify_create();
224 fail("Setup error on action creation");
228 /* Test lttng_register_trigger with null value */
229 ok(lttng_register_trigger(NULL
) == -LTTNG_ERR_INVALID
, "Registering a NULL trigger fails as expected");
231 /* Test: register a trigger */
233 for (i
= 0; i
< pow(2,test_vector_size
); i
++) {
235 char *test_tuple_string
= NULL
;
236 unsigned int mask_position
= 0;
237 bool session_name_set
= false;
238 bool channel_name_set
= false;
239 bool threshold_ratio_set
= false;
240 bool threshold_byte_set
= false;
241 bool domain_type_set
= false;
243 struct lttng_trigger
*trigger
= NULL
;
244 struct lttng_condition
*condition
= NULL
;
246 /* Create base condition */
247 switch (condition_type
) {
248 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
249 condition
= lttng_condition_buffer_usage_low_create();
251 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
252 condition
= lttng_condition_buffer_usage_high_create();
265 /* Prepare the condition for trigger registration test */
267 /* Set session name */
268 if ((1 << mask_position
) & i
) {
269 condition_status
= lttng_condition_buffer_usage_set_session_name(
270 condition
, session_name
);
271 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
275 session_name_set
= true;
279 /* Set channel name */
280 if ((1 << mask_position
) & i
) {
281 condition_status
= lttng_condition_buffer_usage_set_channel_name(
282 condition
, channel_name
);
283 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
287 channel_name_set
= true;
291 /* Set threshold ratio */
292 if ((1 << mask_position
) & i
) {
293 condition_status
= lttng_condition_buffer_usage_set_threshold_ratio(
295 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
299 threshold_ratio_set
= true;
303 /* Set threshold byte */
304 if ((1 << mask_position
) & i
) {
305 condition_status
= lttng_condition_buffer_usage_set_threshold(
307 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
311 threshold_byte_set
= true;
315 /* Set domain type */
316 if ((1 << mask_position
) & i
) {
317 condition_status
= lttng_condition_buffer_usage_set_domain_type(
318 condition
, LTTNG_DOMAIN_UST
);
319 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
323 domain_type_set
= true;
327 if (mask_position
!= test_vector_size
-1) {
328 assert("Logic error for test vector generation");
331 loop_ret
= asprintf(&test_tuple_string
, "session name %s, channel name %s, threshold ratio %s, threshold byte %s, domain type %s",
332 session_name_set
? "set" : "unset",
333 channel_name_set
? "set" : "unset",
334 threshold_ratio_set
? "set" : "unset",
335 threshold_byte_set
? "set" : "unset",
336 domain_type_set
? "set" : "unset");
337 if (!test_tuple_string
|| loop_ret
< 0) {
343 trigger
= lttng_trigger_create(condition
, action
);
349 loop_ret
= lttng_register_trigger(trigger
);
353 fail("Setup error occurred for tuple: %s", test_tuple_string
);
357 /* This combination happens three times */
358 if (session_name_set
&& channel_name_set
359 && (threshold_ratio_set
|| threshold_byte_set
)
360 && domain_type_set
) {
361 ok(loop_ret
== 0, "Trigger is registered: %s", test_tuple_string
);
364 * Test that a trigger cannot be registered
367 loop_ret
= lttng_register_trigger(trigger
);
368 ok(loop_ret
== -LTTNG_ERR_TRIGGER_EXISTS
, "Re-register trigger fails as expected: %s", test_tuple_string
);
370 /* Test that a trigger can be unregistered */
371 loop_ret
= lttng_unregister_trigger(trigger
);
372 ok(loop_ret
== 0, "Unregister trigger: %s", test_tuple_string
);
375 * Test that unregistration of a non-previously
376 * registered trigger fail.
378 loop_ret
= lttng_unregister_trigger(trigger
);
379 ok(loop_ret
== -LTTNG_ERR_TRIGGER_NOT_FOUND
, "Unregister of a non-registered trigger fails as expected: %s", test_tuple_string
);
381 ok(loop_ret
== -LTTNG_ERR_INVALID_TRIGGER
, "Trigger is invalid as expected and cannot be registered: %s", test_tuple_string
);
385 free(test_tuple_string
);
386 lttng_trigger_destroy(trigger
);
387 lttng_condition_destroy(condition
);
391 lttng_action_destroy(action
);
395 void wait_data_pending(const char *session_name
)
400 ret
= lttng_data_pending(session_name
);
406 int setup_buffer_usage_condition(struct lttng_condition
*condition
,
407 const char *condition_name
,
408 const char *session_name
,
409 const char *channel_name
,
410 const enum lttng_domain_type domain_type
)
412 enum lttng_condition_status condition_status
;
415 condition_status
= lttng_condition_buffer_usage_set_session_name(
416 condition
, session_name
);
417 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
418 fail("Failed to set session name on creation of condition `%s`",
424 condition_status
= lttng_condition_buffer_usage_set_channel_name(
425 condition
, channel_name
);
426 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
427 fail("Failed to set channel name on creation of condition `%s`",
433 condition_status
= lttng_condition_buffer_usage_set_domain_type(
434 condition
, domain_type
);
435 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
436 fail("Failed to set domain type on creation of condition `%s`",
447 void test_invalid_channel_subscription(
448 const enum lttng_domain_type domain_type
)
450 enum lttng_condition_status condition_status
;
451 enum lttng_notification_channel_status nc_status
;
452 struct lttng_condition
*dummy_condition
= NULL
;
453 struct lttng_condition
*dummy_invalid_condition
= NULL
;
454 struct lttng_notification_channel
*notification_channel
= NULL
;
457 notification_channel
= lttng_notification_channel_create(
458 lttng_session_daemon_notification_endpoint
);
459 ok(notification_channel
, "Notification channel object creation");
460 if (!notification_channel
) {
465 * Create a dummy, empty (thus invalid) condition to test error paths.
467 dummy_invalid_condition
= lttng_condition_buffer_usage_low_create();
468 if (!dummy_invalid_condition
) {
469 fail("Setup error on condition creation");
474 * Test subscription and unsubscription of an invalid condition to/from
477 nc_status
= lttng_notification_channel_subscribe(
478 notification_channel
, dummy_invalid_condition
);
479 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID
,
480 "Subscribing to an invalid condition");
482 nc_status
= lttng_notification_channel_unsubscribe(
483 notification_channel
, dummy_invalid_condition
);
484 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID
,
485 "Unsubscribing from an invalid condition");
487 /* Create a valid dummy condition with a ratio of 0.5 */
488 dummy_condition
= lttng_condition_buffer_usage_low_create();
489 if (!dummy_condition
) {
490 fail("Setup error on dummy_condition creation");
494 condition_status
= lttng_condition_buffer_usage_set_threshold_ratio(
495 dummy_condition
, 0.5);
496 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
497 fail("Setup error on condition creation");
501 ret
= setup_buffer_usage_condition(dummy_condition
, "dummy_condition",
502 "dummy_session", "dummy_channel", domain_type
);
504 fail("Setup error on dummy condition creation");
509 * Test subscription and unsubscription to/from a channel with invalid
512 nc_status
= lttng_notification_channel_subscribe(NULL
, NULL
);
513 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID
,
514 "Notification channel subscription is invalid: NULL, NULL");
516 nc_status
= lttng_notification_channel_subscribe(
517 notification_channel
, NULL
);
518 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID
,
519 "Notification channel subscription is invalid: NON-NULL, NULL");
521 nc_status
= lttng_notification_channel_subscribe(NULL
, dummy_condition
);
522 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID
,
523 "Notification channel subscription is invalid: NULL, NON-NULL");
525 nc_status
= lttng_notification_channel_unsubscribe(
526 notification_channel
, dummy_condition
);
527 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_UNKNOWN_CONDITION
,
528 "Unsubscribing from a valid unknown condition");
531 lttng_notification_channel_destroy(notification_channel
);
532 lttng_condition_destroy(dummy_invalid_condition
);
533 lttng_condition_destroy(dummy_condition
);
537 enum buffer_usage_type
{
538 BUFFER_USAGE_TYPE_LOW
,
539 BUFFER_USAGE_TYPE_HIGH
,
542 static int register_buffer_usage_notify_trigger(const char *session_name
,
543 const char *channel_name
,
544 const enum lttng_domain_type domain_type
,
545 enum buffer_usage_type buffer_usage_type
,
547 struct lttng_condition
**condition
,
548 struct lttng_action
**action
,
549 struct lttng_trigger
**trigger
)
551 enum lttng_condition_status condition_status
;
552 struct lttng_action
*tmp_action
= NULL
;
553 struct lttng_condition
*tmp_condition
= NULL
;
554 struct lttng_trigger
*tmp_trigger
= NULL
;
558 tmp_action
= lttng_action_notify_create();
560 fail("Setup error on action creation");
565 if (buffer_usage_type
== BUFFER_USAGE_TYPE_LOW
) {
566 tmp_condition
= lttng_condition_buffer_usage_low_create();
568 tmp_condition
= lttng_condition_buffer_usage_high_create();
571 if (!tmp_condition
) {
572 fail("Setup error on condition creation");
577 /* Set the buffer usage threashold */
578 condition_status
= lttng_condition_buffer_usage_set_threshold_ratio(
579 tmp_condition
, ratio
);
580 if (condition_status
!= LTTNG_CONDITION_STATUS_OK
) {
581 fail("Setup error on condition creation");
586 ret
= setup_buffer_usage_condition(tmp_condition
, "condition_name",
587 session_name
, channel_name
, domain_type
);
589 fail("Setup error on condition creation");
594 /* Register the trigger for condition. */
595 tmp_trigger
= lttng_trigger_create(tmp_condition
, tmp_action
);
597 fail("Setup error on trigger creation");
602 ret
= lttng_register_trigger(tmp_trigger
);
604 fail("Setup error on trigger registration");
609 *condition
= tmp_condition
;
610 *trigger
= tmp_trigger
;
611 *action
= tmp_action
;
615 lttng_action_destroy(tmp_action
);
616 lttng_condition_destroy(tmp_condition
);
617 lttng_trigger_destroy(tmp_trigger
);
623 static void test_subscription_twice(const char *session_name
,
624 const char *channel_name
,
625 const enum lttng_domain_type domain_type
)
628 enum lttng_notification_channel_status nc_status
;
630 struct lttng_action
*action
= NULL
;
631 struct lttng_notification_channel
*notification_channel
= NULL
;
632 struct lttng_trigger
*trigger
= NULL
;
634 struct lttng_condition
*condition
= NULL
;
636 ret
= register_buffer_usage_notify_trigger(session_name
, channel_name
,
637 domain_type
, BUFFER_USAGE_TYPE_LOW
, 0.99, &condition
,
640 fail("Setup error on trigger registration");
645 notification_channel
= lttng_notification_channel_create(
646 lttng_session_daemon_notification_endpoint
);
647 ok(notification_channel
, "Notification channel object creation");
648 if (!notification_channel
) {
652 /* Subscribe a valid condition. */
653 nc_status
= lttng_notification_channel_subscribe(
654 notification_channel
, condition
);
655 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
656 "Subscribe to condition");
658 /* Subscribing again should fail. */
659 nc_status
= lttng_notification_channel_subscribe(
660 notification_channel
, condition
);
661 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED
,
662 "Subscribe to a condition for which subscription was already done");
665 lttng_unregister_trigger(trigger
);
666 lttng_trigger_destroy(trigger
);
667 lttng_notification_channel_destroy(notification_channel
);
668 lttng_action_destroy(action
);
669 lttng_condition_destroy(condition
);
672 static void test_buffer_usage_notification_channel(const char *session_name
,
673 const char *channel_name
,
674 const enum lttng_domain_type domain_type
,
678 enum lttng_notification_channel_status nc_status
;
680 struct lttng_action
*low_action
= NULL
;
681 struct lttng_action
*high_action
= NULL
;
682 struct lttng_notification
*notification
= NULL
;
683 struct lttng_notification_channel
*notification_channel
= NULL
;
684 struct lttng_trigger
*low_trigger
= NULL
;
685 struct lttng_trigger
*high_trigger
= NULL
;
687 struct lttng_condition
*low_condition
= NULL
;
688 struct lttng_condition
*high_condition
= NULL
;
690 const double low_ratio
= 0.0;
691 const double high_ratio
= 0.90;
693 ret
= register_buffer_usage_notify_trigger(session_name
, channel_name
,
694 domain_type
, BUFFER_USAGE_TYPE_LOW
, low_ratio
,
695 &low_condition
, &low_action
, &low_trigger
);
697 fail("Setup error on low trigger registration");
701 ret
= register_buffer_usage_notify_trigger(session_name
, channel_name
,
702 domain_type
, BUFFER_USAGE_TYPE_HIGH
, high_ratio
,
703 &high_condition
, &high_action
, &high_trigger
);
705 fail("Setup error on high trigger registration");
710 notification_channel
= lttng_notification_channel_create(
711 lttng_session_daemon_notification_endpoint
);
712 ok(notification_channel
, "Notification channel object creation");
713 if (!notification_channel
) {
717 /* Subscribe a valid low condition */
718 nc_status
= lttng_notification_channel_subscribe(
719 notification_channel
, low_condition
);
720 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
721 "Subscribe to low condition");
723 /* Subscribe a valid high condition */
724 nc_status
= lttng_notification_channel_subscribe(
725 notification_channel
, high_condition
);
726 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
727 "Subscribe to high condition");
729 resume_application();
731 /* Wait for notification to happen */
733 lttng_start_tracing(session_name
);
735 /* Wait for high notification */
737 nc_status
= lttng_notification_channel_get_next_notification(
738 notification_channel
, ¬ification
);
739 } while (nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
);
740 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
&& notification
&&
741 lttng_condition_get_type(lttng_notification_get_condition(
743 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
,
744 "High notification received after intermediary communication");
745 lttng_notification_destroy(notification
);
748 suspend_application();
749 lttng_stop_tracing_no_wait(session_name
);
750 resume_consumer(argv
);
751 wait_data_pending(session_name
);
754 * Test that communication still work even if there is notification
755 * waiting for consumption.
758 nc_status
= lttng_notification_channel_unsubscribe(
759 notification_channel
, low_condition
);
760 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
761 "Unsubscribe with pending notification");
763 nc_status
= lttng_notification_channel_subscribe(
764 notification_channel
, low_condition
);
765 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
766 "Subscribe with pending notification");
769 nc_status
= lttng_notification_channel_get_next_notification(
770 notification_channel
, ¬ification
);
771 } while (nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
);
772 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
&& notification
&&
773 lttng_condition_get_type(lttng_notification_get_condition(
775 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
,
776 "Low notification received after intermediary communication");
777 lttng_notification_destroy(notification
);
780 /* Stop consumer to force a high notification */
782 resume_application();
783 lttng_start_tracing(session_name
);
786 nc_status
= lttng_notification_channel_get_next_notification(
787 notification_channel
, ¬ification
);
788 } while (nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
);
789 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
&& notification
&&
790 lttng_condition_get_type(lttng_notification_get_condition(
792 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
,
793 "High notification received after intermediary communication");
794 lttng_notification_destroy(notification
);
797 suspend_application();
798 lttng_stop_tracing_no_wait(session_name
);
799 resume_consumer(argv
);
800 wait_data_pending(session_name
);
803 nc_status
= lttng_notification_channel_get_next_notification(
804 notification_channel
, ¬ification
);
805 } while (nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
);
806 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
&& notification
&&
807 lttng_condition_get_type(lttng_notification_get_condition(
809 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
,
810 "Low notification received after re-subscription");
811 lttng_notification_destroy(notification
);
815 resume_application();
816 /* Stop consumer to force a high notification */
817 lttng_start_tracing(session_name
);
820 nc_status
= lttng_notification_channel_get_next_notification(
821 notification_channel
, ¬ification
);
822 } while (nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
);
823 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
&& notification
&&
824 lttng_condition_get_type(lttng_notification_get_condition(
826 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
,
827 "High notification");
828 lttng_notification_destroy(notification
);
831 suspend_application();
833 /* Resume consumer to allow event consumption */
834 lttng_stop_tracing_no_wait(session_name
);
835 resume_consumer(argv
);
836 wait_data_pending(session_name
);
838 nc_status
= lttng_notification_channel_unsubscribe(
839 notification_channel
, low_condition
);
840 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
841 "Unsubscribe low condition with pending notification");
843 nc_status
= lttng_notification_channel_unsubscribe(
844 notification_channel
, high_condition
);
845 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
846 "Unsubscribe high condition with pending notification");
849 lttng_notification_channel_destroy(notification_channel
);
850 lttng_trigger_destroy(low_trigger
);
851 lttng_trigger_destroy(high_trigger
);
852 lttng_action_destroy(low_action
);
853 lttng_action_destroy(high_action
);
854 lttng_condition_destroy(low_condition
);
855 lttng_condition_destroy(high_condition
);
858 static void create_tracepoint_event_rule_trigger(const char *event_pattern
,
859 const char *trigger_name
,
861 unsigned int exclusion_count
,
862 const char * const *exclusions
,
863 enum lttng_domain_type domain_type
,
864 struct lttng_condition
**condition
,
865 struct lttng_trigger
**trigger
)
867 enum lttng_event_rule_status event_rule_status
;
868 enum lttng_trigger_status trigger_status
;
870 struct lttng_action
*tmp_action
= NULL
;
871 struct lttng_event_rule
*event_rule
= NULL
;
872 struct lttng_condition
*tmp_condition
= NULL
;
873 struct lttng_trigger
*tmp_trigger
= NULL
;
876 assert(event_pattern
);
877 assert(trigger_name
);
881 event_rule
= lttng_event_rule_tracepoint_create(domain_type
);
882 ok(event_rule
, "Tracepoint event rule object creation");
884 event_rule_status
= lttng_event_rule_tracepoint_set_pattern(
885 event_rule
, event_pattern
);
886 ok(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
,
887 "Setting tracepoint event rule pattern: '%s'",
891 event_rule_status
= lttng_event_rule_tracepoint_set_filter(
893 ok(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
,
894 "Setting tracepoint event rule filter: '%s'",
902 assert(domain_type
== LTTNG_DOMAIN_UST
);
903 assert(exclusion_count
> 0);
905 for (i
= 0; i
< exclusion_count
; i
++) {
907 lttng_event_rule_tracepoint_add_exclusion(
910 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
911 fail("Setting tracepoint event rule exclusion '%s'.",
917 ok(success
, "Setting tracepoint event rule exclusions");
920 tmp_condition
= lttng_condition_event_rule_create(event_rule
);
921 ok(tmp_condition
, "Condition event rule object creation");
923 tmp_action
= lttng_action_notify_create();
924 ok(tmp_action
, "Action event rule object creation");
926 tmp_trigger
= lttng_trigger_create(tmp_condition
, tmp_action
);
927 ok(tmp_trigger
, "Trigger object creation %s", trigger_name
);
929 trigger_status
= lttng_trigger_set_name(tmp_trigger
, trigger_name
);
930 ok(trigger_status
== LTTNG_TRIGGER_STATUS_OK
,
931 "Setting name to trigger %s", trigger_name
);
933 ret
= lttng_register_trigger(tmp_trigger
);
934 ok(ret
== 0, "Trigger registration %s", trigger_name
);
936 lttng_event_rule_destroy(event_rule
);
938 *condition
= tmp_condition
;
939 *trigger
= tmp_trigger
;
944 static char *get_next_notification_trigger_name(
945 struct lttng_notification_channel
*notification_channel
)
947 struct lttng_notification
*notification
;
948 enum lttng_notification_channel_status status
;
949 const struct lttng_evaluation
*notification_evaluation
;
950 char *trigger_name
= NULL
;
952 enum lttng_condition_type notification_evaluation_type
;
954 /* Receive the next notification. */
955 status
= lttng_notification_channel_get_next_notification(
956 notification_channel
, ¬ification
);
959 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
962 /* Unhandled conditions / errors. */
963 fail("Failed to get next notification channel notification: status = %d",
968 notification_evaluation
=
969 lttng_notification_get_evaluation(notification
);
971 notification_evaluation_type
=
972 lttng_evaluation_get_type(notification_evaluation
);
973 switch (notification_evaluation_type
) {
974 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
:
975 lttng_evaluation_event_rule_get_trigger_name(
976 notification_evaluation
, &name
);
978 trigger_name
= strdup(name
);
981 fail("Unexpected notification evaluation type: notification type = %d",
982 notification_evaluation_type
);
986 lttng_notification_destroy(notification
);
992 static void test_tracepoint_event_rule_notification(
993 enum lttng_domain_type domain_type
)
996 const int notification_count
= 3;
997 enum lttng_notification_channel_status nc_status
;
998 struct lttng_action
*action
= NULL
;
999 struct lttng_condition
*condition
= NULL
;
1000 struct lttng_notification_channel
*notification_channel
= NULL
;
1001 struct lttng_trigger
*trigger
= NULL
;
1002 const char * const trigger_name
= "my_precious";
1003 const char *pattern
;
1005 if (domain_type
== LTTNG_DOMAIN_UST
) {
1006 pattern
= "tp:tptest";
1008 pattern
= "lttng_test_filter_event";
1011 create_tracepoint_event_rule_trigger(pattern
, trigger_name
, NULL
, 0,
1012 NULL
, domain_type
, &condition
, &trigger
);
1014 notification_channel
= lttng_notification_channel_create(
1015 lttng_session_daemon_notification_endpoint
);
1016 ok(notification_channel
, "Notification channel object creation");
1018 nc_status
= lttng_notification_channel_subscribe(
1019 notification_channel
, condition
);
1020 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
1021 "Subscribe to tracepoint event rule condition");
1023 resume_application();
1025 /* Get 3 notifications. */
1026 for (i
= 0; i
< notification_count
; i
++) {
1027 char *name
= get_next_notification_trigger_name(
1028 notification_channel
);
1030 ok(strcmp(trigger_name
, name
) == 0,
1031 "Received notification for the expected trigger name: '%s' (%d/%d)",
1032 trigger_name
, i
+ 1, notification_count
);
1036 suspend_application();
1037 lttng_notification_channel_destroy(notification_channel
);
1038 lttng_unregister_trigger(trigger
);
1039 lttng_trigger_destroy(trigger
);
1040 lttng_action_destroy(action
);
1041 lttng_condition_destroy(condition
);
1045 static void test_tracepoint_event_rule_notification_filter(
1046 enum lttng_domain_type domain_type
)
1049 enum lttng_notification_channel_status nc_status
;
1051 struct lttng_condition
*ctrl_condition
= NULL
, *condition
= NULL
;
1052 struct lttng_notification_channel
*notification_channel
= NULL
;
1053 struct lttng_trigger
*ctrl_trigger
= NULL
, *trigger
= NULL
;
1054 const char * const ctrl_trigger_name
= "control_trigger";
1055 const char * const trigger_name
= "trigger";
1056 const char *pattern
;
1057 int ctrl_count
= 0, count
= 0;
1059 if (domain_type
== LTTNG_DOMAIN_UST
) {
1060 pattern
= "tp:tptest";
1062 pattern
= "lttng_test_filter_event";
1065 notification_channel
= lttng_notification_channel_create(
1066 lttng_session_daemon_notification_endpoint
);
1067 ok(notification_channel
, "Notification channel object creation");
1069 create_tracepoint_event_rule_trigger(pattern
, ctrl_trigger_name
, NULL
,
1070 0, NULL
, domain_type
, &ctrl_condition
, &ctrl_trigger
);
1072 nc_status
= lttng_notification_channel_subscribe(
1073 notification_channel
, ctrl_condition
);
1074 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
1075 "Subscribe to tracepoint event rule condition");
1078 * Attach a filter expression to get notification only if the
1079 * `intfield` is even.
1081 create_tracepoint_event_rule_trigger(pattern
, trigger_name
,
1082 "(intfield & 1) == 0", 0, NULL
, domain_type
, &condition
,
1085 nc_status
= lttng_notification_channel_subscribe(
1086 notification_channel
, condition
);
1087 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
1088 "Subscribe to tracepoint event rule condition");
1091 * We registered 2 notifications triggers, one with a filter and one
1092 * without (control). The one with a filter will only fired when the
1093 * `intfield` is a multiple of 2. We should get two times as many
1094 * control notifications as filter notifications.
1096 resume_application();
1099 * Get 3 notifications. We should get 1 for the regular trigger (with
1100 * the filter) and 2 from the control trigger. This works whatever
1101 * the order we receive the notifications.
1103 for (i
= 0; i
< 3; i
++) {
1104 char *name
= get_next_notification_trigger_name(
1105 notification_channel
);
1107 if (strcmp(ctrl_trigger_name
, name
) == 0) {
1109 } else if (strcmp(trigger_name
, name
) == 0) {
1116 ok(ctrl_count
/ 2 == count
,
1117 "Get twice as many control notif as of regular notif");
1119 suspend_application();
1121 lttng_unregister_trigger(trigger
);
1122 lttng_unregister_trigger(ctrl_trigger
);
1123 lttng_notification_channel_destroy(notification_channel
);
1124 lttng_trigger_destroy(trigger
);
1125 lttng_trigger_destroy(ctrl_trigger
);
1126 lttng_condition_destroy(condition
);
1127 lttng_condition_destroy(ctrl_condition
);
1130 static void test_tracepoint_event_rule_notification_exclusion(
1131 enum lttng_domain_type domain_type
)
1133 enum lttng_notification_channel_status nc_status
;
1134 struct lttng_condition
*ctrl_condition
= NULL
, *condition
= NULL
;
1135 struct lttng_notification_channel
*notification_channel
= NULL
;
1136 struct lttng_trigger
*ctrl_trigger
= NULL
, *trigger
= NULL
;
1137 int ctrl_count
= 0, count
= 0, i
;
1138 const char * const ctrl_trigger_name
= "control_exclusion_trigger";
1139 const char * const trigger_name
= "exclusion_trigger";
1140 const char * const pattern
= "tp:tptest*";
1141 const char * const exclusions
[] = {
1148 notification_channel
= lttng_notification_channel_create(
1149 lttng_session_daemon_notification_endpoint
);
1150 ok(notification_channel
, "Notification channel object creation");
1152 create_tracepoint_event_rule_trigger(pattern
, ctrl_trigger_name
, NULL
,
1153 0, NULL
, domain_type
, &ctrl_condition
, &ctrl_trigger
);
1155 nc_status
= lttng_notification_channel_subscribe(
1156 notification_channel
, ctrl_condition
);
1157 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
1158 "Subscribe to tracepoint event rule condition");
1160 create_tracepoint_event_rule_trigger(pattern
, trigger_name
, NULL
, 4,
1161 exclusions
, domain_type
, &condition
, &trigger
);
1163 nc_status
= lttng_notification_channel_subscribe(
1164 notification_channel
, condition
);
1165 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
1166 "Subscribe to tracepoint event rule condition");
1169 * We registered 2 notifications triggers, one with an exclusion and
1170 * one without (control).
1171 * - The trigger with an exclusion will fire once every iteration.
1172 * - The trigger without an exclusion will fire 5 times every
1175 * We should get 5 times as many notifications from the control
1178 resume_application();
1181 * Get 6 notifications. We should get 1 for the regular trigger (with
1182 * the exclusion) and 5 from the control trigger. This works whatever
1183 * the order we receive the notifications.
1185 for (i
= 0; i
< 6; i
++) {
1186 char *name
= get_next_notification_trigger_name(
1187 notification_channel
);
1189 if (strcmp(ctrl_trigger_name
, name
) == 0) {
1191 } else if (strcmp(trigger_name
, name
) == 0) {
1198 ok(ctrl_count
/ 5 == count
,
1199 "Got 5 times as many control notif as of regular notif");
1201 suspend_application();
1203 lttng_unregister_trigger(trigger
);
1204 lttng_unregister_trigger(ctrl_trigger
);
1205 lttng_notification_channel_destroy(notification_channel
);
1206 lttng_trigger_destroy(trigger
);
1207 lttng_trigger_destroy(ctrl_trigger
);
1208 lttng_condition_destroy(condition
);
1209 lttng_condition_destroy(ctrl_condition
);
1213 static void test_kprobe_event_rule_notification(
1214 enum lttng_domain_type domain_type
)
1217 const int notification_count
= 3;
1218 enum lttng_notification_channel_status nc_status
;
1219 enum lttng_event_rule_status event_rule_status
;
1220 enum lttng_trigger_status trigger_status
;
1221 struct lttng_notification_channel
*notification_channel
= NULL
;
1222 struct lttng_condition
*condition
= NULL
;
1223 struct lttng_kernel_probe_location
*location
= NULL
;
1224 struct lttng_event_rule
*event_rule
= NULL
;
1225 struct lttng_action
*action
= NULL
;
1226 struct lttng_trigger
*trigger
= NULL
;
1227 const char * const trigger_name
= "kprobe_trigger";
1228 const char * const symbol_name
= "lttng_test_filter_event_write";
1230 action
= lttng_action_notify_create();
1232 fail("Failed to create notify action");
1236 location
= lttng_kernel_probe_location_symbol_create(symbol_name
, 0);
1238 fail("Failed to create kernel probe location");
1242 notification_channel
= lttng_notification_channel_create(
1243 lttng_session_daemon_notification_endpoint
);
1244 ok(notification_channel
, "Notification channel object creation");
1246 event_rule
= lttng_event_rule_kprobe_create();
1247 ok(event_rule
, "kprobe event rule object creation");
1249 event_rule_status
= lttng_event_rule_kprobe_set_location(
1250 event_rule
, location
);
1251 ok(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
,
1252 "Setting kprobe event rule location: '%s'", symbol_name
);
1254 event_rule_status
= lttng_event_rule_kprobe_set_name(
1255 event_rule
, trigger_name
);
1256 ok(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
,
1257 "Setting kprobe event rule name: '%s'", trigger_name
);
1259 condition
= lttng_condition_event_rule_create(event_rule
);
1260 ok(condition
, "Condition event rule object creation");
1262 /* Register the trigger for condition. */
1263 trigger
= lttng_trigger_create(condition
, action
);
1265 fail("Failed to create trigger with kernel probe event rule condition and notify action");
1269 trigger_status
= lttng_trigger_set_name(trigger
, trigger_name
);
1270 ok(trigger_status
== LTTNG_TRIGGER_STATUS_OK
,
1271 "Setting trigger name to '%s'", trigger_name
);
1273 ret
= lttng_register_trigger(trigger
);
1275 fail("Failed to register trigger with kernel probe event rule condition and notify action");
1279 nc_status
= lttng_notification_channel_subscribe(
1280 notification_channel
, condition
);
1281 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
1282 "Subscribe to tracepoint event rule condition");
1284 resume_application();
1286 for (i
= 0; i
< notification_count
; i
++) {
1287 char *name
= get_next_notification_trigger_name(
1288 notification_channel
);
1290 ok(strcmp(trigger_name
, name
) == 0,
1291 "Received notification for the expected trigger name: '%s' (%d/%d)",
1292 trigger_name
, i
+ 1, notification_count
);
1297 suspend_application();
1298 lttng_notification_channel_destroy(notification_channel
);
1299 lttng_unregister_trigger(trigger
);
1300 lttng_trigger_destroy(trigger
);
1301 lttng_action_destroy(action
);
1302 lttng_event_rule_destroy(event_rule
);
1303 lttng_condition_destroy(condition
);
1304 lttng_kernel_probe_location_destroy(location
);
1308 static void test_syscall_event_rule_notification(
1309 enum lttng_domain_type domain_type
)
1312 const int notification_count
= 3;
1313 enum lttng_notification_channel_status nc_status
;
1314 enum lttng_event_rule_status event_rule_status
;
1315 enum lttng_trigger_status trigger_status
;
1316 struct lttng_notification_channel
*notification_channel
= NULL
;
1317 struct lttng_condition
*condition
= NULL
;
1318 struct lttng_event_rule
*event_rule
= NULL
;
1319 struct lttng_action
*action
= NULL
;
1320 struct lttng_trigger
*trigger
= NULL
;
1321 const char * const trigger_name
= "syscall_trigger";
1322 const char * const syscall_name
= "openat";
1324 action
= lttng_action_notify_create();
1326 fail("Failed to create notify action");
1330 notification_channel
= lttng_notification_channel_create(
1331 lttng_session_daemon_notification_endpoint
);
1332 ok(notification_channel
, "Notification channel object creation");
1334 event_rule
= lttng_event_rule_syscall_create();
1335 ok(event_rule
, "syscall event rule object creation");
1337 event_rule_status
= lttng_event_rule_syscall_set_pattern(
1338 event_rule
, syscall_name
);
1339 ok(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
,
1340 "Setting syscall event rule pattern: '%s'", syscall_name
);
1342 condition
= lttng_condition_event_rule_create(event_rule
);
1343 ok(condition
, "Condition syscall event rule object creation");
1345 /* Register the trigger for condition. */
1346 trigger
= lttng_trigger_create(condition
, action
);
1348 fail("Failed to create trigger with syscall event rule condition and notify action");
1352 trigger_status
= lttng_trigger_set_name(trigger
, trigger_name
);
1353 ok(trigger_status
== LTTNG_TRIGGER_STATUS_OK
,
1354 "Setting name to trigger '%s'", trigger_name
);
1356 ret
= lttng_register_trigger(trigger
);
1358 fail("Failed to register trigger with syscall event rule condition and notify action");
1362 nc_status
= lttng_notification_channel_subscribe(
1363 notification_channel
, condition
);
1364 ok(nc_status
== LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
,
1365 "Subscribe to tracepoint event rule condition");
1367 resume_application();
1369 for (i
= 0; i
< notification_count
; i
++) {
1370 char *name
= get_next_notification_trigger_name(
1371 notification_channel
);
1373 ok(strcmp(trigger_name
, name
) == 0,
1374 "Received notification for the expected trigger name: '%s' (%d/%d)",
1375 trigger_name
, i
+ 1, notification_count
);
1379 suspend_application();
1380 lttng_notification_channel_destroy(notification_channel
);
1381 lttng_unregister_trigger(trigger
);
1382 lttng_trigger_destroy(trigger
);
1383 lttng_action_destroy(action
);
1384 lttng_condition_destroy(condition
);
1388 int main(int argc
, const char *argv
[])
1391 const char *session_name
= NULL
;
1392 const char *channel_name
= NULL
;
1393 const char *domain_type_string
= NULL
;
1394 enum lttng_domain_type domain_type
= LTTNG_DOMAIN_NONE
;
1397 fail("Missing test scenario, domain type, pid, or application state file argument(s)");
1401 test_scenario
= atoi(argv
[1]);
1402 domain_type_string
= argv
[2];
1403 app_pid
= (pid_t
) atoi(argv
[3]);
1404 app_state_file
= argv
[4];
1406 if (!strcmp("LTTNG_DOMAIN_UST", domain_type_string
)) {
1407 domain_type
= LTTNG_DOMAIN_UST
;
1409 if (!strcmp("LTTNG_DOMAIN_KERNEL", domain_type_string
)) {
1410 domain_type
= LTTNG_DOMAIN_KERNEL
;
1412 if (domain_type
== LTTNG_DOMAIN_NONE
) {
1413 fail("Unknown domain type");
1418 * Test cases are responsible for resuming the app when needed
1419 * and making sure it's suspended when returning.
1421 suspend_application();
1423 switch (test_scenario
) {
1428 /* Test cases that need gen-ust-event testapp. */
1429 diag("Test basic notification error paths for %s domain",
1430 domain_type_string
);
1431 test_invalid_channel_subscription(domain_type
);
1433 diag("Test tracepoint event rule notifications for domain %s",
1434 domain_type_string
);
1435 test_tracepoint_event_rule_notification(domain_type
);
1437 diag("Test tracepoint event rule notifications with filter for domain %s",
1438 domain_type_string
);
1439 test_tracepoint_event_rule_notification_filter(domain_type
);
1444 /* Test cases that need a tracing session enabled. */
1448 * Argument 7 and upward are named pipe location for consumerd
1451 named_pipe_args_start
= 7;
1454 fail("Missing parameter for tests to run %d", argc
);
1460 session_name
= argv
[5];
1461 channel_name
= argv
[6];
1463 test_subscription_twice(session_name
, channel_name
,
1466 diag("Test trigger for domain %s with buffer_usage_low condition",
1467 domain_type_string
);
1468 test_triggers_buffer_usage_condition(session_name
, channel_name
,
1470 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
);
1472 diag("Test trigger for domain %s with buffer_usage_high condition",
1473 domain_type_string
);
1474 test_triggers_buffer_usage_condition(session_name
, channel_name
,
1476 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
);
1478 diag("Test buffer usage notification channel api for domain %s",
1479 domain_type_string
);
1480 test_buffer_usage_notification_channel(session_name
, channel_name
,
1487 * Test cases that need a test app with more than one event
1493 * At the moment, the only test case of this scenario is
1494 * exclusion which is only supported by UST.
1496 assert(domain_type
== LTTNG_DOMAIN_UST
);
1497 diag("Test tracepoint event rule notifications with exclusion for domain %s",
1498 domain_type_string
);
1499 test_tracepoint_event_rule_notification_exclusion(domain_type
);
1507 /* Test cases that need the kernel tracer. */
1508 assert(domain_type
== LTTNG_DOMAIN_KERNEL
);
1510 diag("Test kprobe event rule notifications for domain %s",
1511 domain_type_string
);
1513 test_kprobe_event_rule_notification(domain_type
);
1520 /* Test cases that need the kernel tracer. */
1521 assert(domain_type
== LTTNG_DOMAIN_KERNEL
);
1523 diag("Test syscall event rule notifications for domain %s",
1524 domain_type_string
);
1526 test_syscall_event_rule_notification(domain_type
);
1535 return exit_status();