Tests: notification: use get_next_notification() and a validator
[lttng-tools.git] / tests / regression / tools / notification / notification.c
1 /*
2 * notification.c
3 *
4 * Tests suite for LTTng notification API
5 *
6 * Copyright (C) 2017 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
7 *
8 * SPDX-License-Identifier: MIT
9 *
10 */
11
12 #include <assert.h>
13 #include <math.h>
14 #include <stdbool.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <inttypes.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <signal.h>
24 #include <poll.h>
25
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/event-rule/uprobe.h>
39 #include <lttng/kernel-probe.h>
40 #include <lttng/lttng-error.h>
41 #include <lttng/lttng.h>
42 #include <lttng/notification/channel.h>
43 #include <lttng/notification/notification.h>
44 #include <lttng/condition/evaluation.h>
45 #include <lttng/trigger/trigger.h>
46 #include <lttng/userspace-probe.h>
47
48 #include <tap/tap.h>
49
50 int nb_args = 0;
51 int named_pipe_args_start = 0;
52 pid_t app_pid = 0;
53 const char *app_state_file = NULL;
54
55 static const char *get_notification_trigger_name(
56 struct lttng_notification *notification)
57 {
58 const char *name = NULL;
59 enum lttng_evaluation_status status;
60 const struct lttng_evaluation *evaluation;
61 evaluation = lttng_notification_get_evaluation(notification);
62 if (evaluation == NULL) {
63 fail("lttng_notification_get_evaluation");
64 goto end;
65 }
66
67 switch (lttng_evaluation_get_type(evaluation)) {
68 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT:
69 {
70 status = lttng_evaluation_event_rule_get_trigger_name(
71 evaluation, &name);
72 if (status != LTTNG_EVALUATION_STATUS_OK) {
73 fail("lttng_evaluation_event_rule_get_trigger_name");
74 name = NULL;
75 goto end;
76 }
77 break;
78 }
79 default:
80 fail("Wrong notification evaluation type \n");
81 goto end;
82 }
83 end:
84 return name;
85 }
86
87 static int validator_notification_trigger_name(
88 struct lttng_notification *notification,
89 const char *trigger_name)
90 {
91 int ret;
92 bool name_is_equal;
93 const char *name;
94
95 assert(notification);
96 assert(trigger_name);
97
98 name = get_notification_trigger_name(notification);
99 if (name == NULL) {
100 ret = 1;
101 goto end;
102 }
103
104 name_is_equal = (strcmp(trigger_name, name) == 0);
105 ok(name_is_equal, "Expected trigger name: %s got %s", trigger_name,
106 name);
107
108 ret = !name_is_equal;
109
110 end:
111 return ret;
112 }
113
114 static
115 void wait_on_file(const char *path, bool file_exist)
116 {
117 if (!path) {
118 return;
119 }
120 for (;;) {
121 int ret;
122 struct stat buf;
123
124 ret = stat(path, &buf);
125 if (ret == -1 && errno == ENOENT) {
126 if (file_exist) {
127 /*
128 * The file does not exist. wait a bit and
129 * continue looping until it does.
130 */
131 (void) poll(NULL, 0, 10);
132 continue;
133 }
134
135 /*
136 * File does not exist and the exit condition we want.
137 * Break from the loop and return.
138 */
139 break;
140 }
141 if (ret) {
142 perror("stat");
143 exit(EXIT_FAILURE);
144 }
145 /*
146 * stat() returned 0, so the file exists. break now only if
147 * that's the exit condition we want.
148 */
149 if (file_exist) {
150 break;
151 }
152 }
153 }
154
155 static
156 int write_pipe(const char *path, uint8_t data)
157 {
158 int ret = 0;
159 int fd = 0;
160
161 fd = open(path, O_WRONLY | O_NONBLOCK);
162 if (fd < 0) {
163 perror("Could not open consumer control named pipe");
164 goto end;
165 }
166
167 ret = write(fd, &data , sizeof(data));
168 if (ret < 1) {
169 perror("Named pipe write failed");
170 if (close(fd)) {
171 perror("Named pipe close failed");
172 }
173 ret = -1;
174 goto end;
175 }
176
177 ret = close(fd);
178 if (ret < 0) {
179 perror("Name pipe closing failed");
180 ret = -1;
181 goto end;
182 }
183 end:
184 return ret;
185 }
186
187 static
188 int stop_consumer(const char **argv)
189 {
190 int ret = 0, i;
191
192 for (i = named_pipe_args_start; i < nb_args; i++) {
193 ret = write_pipe(argv[i], 49);
194 }
195 return ret;
196 }
197
198 static
199 int resume_consumer(const char **argv)
200 {
201 int ret = 0, i;
202
203 for (i = named_pipe_args_start; i < nb_args; i++) {
204 ret = write_pipe(argv[i], 0);
205 }
206 return ret;
207 }
208
209 static
210 int suspend_application(void)
211 {
212 int ret;
213 struct stat buf;
214
215 if (!stat(app_state_file, &buf)) {
216 fail("App is already in a suspended state.");
217 ret = -1;
218 goto error;
219 }
220
221 /*
222 * Send SIGUSR1 to application instructing it to bypass tracepoint.
223 */
224 assert(app_pid > 1);
225
226 ret = kill(app_pid, SIGUSR1);
227 if (ret) {
228 fail("SIGUSR1 failed. errno %d", errno);
229 ret = -1;
230 goto error;
231 }
232
233 wait_on_file(app_state_file, true);
234
235 error:
236 return ret;
237
238 }
239
240 static
241 int resume_application(void)
242 {
243 int ret;
244 struct stat buf;
245
246 ret = stat(app_state_file, &buf);
247 if (ret == -1 && errno == ENOENT) {
248 fail("State file does not exist");
249 goto error;
250 }
251 if (ret) {
252 perror("stat");
253 goto error;
254 }
255
256 assert(app_pid > 1);
257
258 ret = kill(app_pid, SIGUSR1);
259 if (ret) {
260 fail("SIGUSR1 failed. errno %d", errno);
261 ret = -1;
262 goto error;
263 }
264
265 wait_on_file(app_state_file, false);
266
267 error:
268 return ret;
269
270 }
271
272
273 static
274 void test_triggers_buffer_usage_condition(const char *session_name,
275 const char *channel_name,
276 enum lttng_domain_type domain_type,
277 enum lttng_condition_type condition_type)
278 {
279 unsigned int test_vector_size = 5, i;
280 enum lttng_condition_status condition_status;
281 struct lttng_action *action;
282
283 /* Set-up */
284 action = lttng_action_notify_create();
285 if (!action) {
286 fail("Setup error on action creation");
287 goto end;
288 }
289
290 /* Test lttng_register_trigger with null value */
291 ok(lttng_register_trigger(NULL) == -LTTNG_ERR_INVALID, "Registering a NULL trigger fails as expected");
292
293 /* Test: register a trigger */
294
295 for (i = 0; i < pow(2,test_vector_size); i++) {
296 int loop_ret = 0;
297 char *test_tuple_string = NULL;
298 unsigned int mask_position = 0;
299 bool session_name_set = false;
300 bool channel_name_set = false;
301 bool threshold_ratio_set = false;
302 bool threshold_byte_set = false;
303 bool domain_type_set = false;
304
305 struct lttng_trigger *trigger = NULL;
306 struct lttng_condition *condition = NULL;
307
308 /* Create base condition */
309 switch (condition_type) {
310 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
311 condition = lttng_condition_buffer_usage_low_create();
312 break;
313 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
314 condition = lttng_condition_buffer_usage_high_create();
315 break;
316 default:
317 loop_ret = 1;
318 goto loop_end;
319 }
320
321 if (!condition) {
322 loop_ret = 1;
323 goto loop_end;
324
325 }
326
327 /* Prepare the condition for trigger registration test */
328
329 /* Set session name */
330 if ((1 << mask_position) & i) {
331 condition_status = lttng_condition_buffer_usage_set_session_name(
332 condition, session_name);
333 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
334 loop_ret = 1;
335 goto loop_end;
336 }
337 session_name_set = true;
338 }
339 mask_position++;
340
341 /* Set channel name */
342 if ((1 << mask_position) & i) {
343 condition_status = lttng_condition_buffer_usage_set_channel_name(
344 condition, channel_name);
345 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
346 loop_ret = 1;
347 goto loop_end;
348 }
349 channel_name_set = true;
350 }
351 mask_position++;
352
353 /* Set threshold ratio */
354 if ((1 << mask_position) & i) {
355 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
356 condition, 0.0);
357 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
358 loop_ret = 1;
359 goto loop_end;
360 }
361 threshold_ratio_set = true;
362 }
363 mask_position++;
364
365 /* Set threshold byte */
366 if ((1 << mask_position) & i) {
367 condition_status = lttng_condition_buffer_usage_set_threshold(
368 condition, 0);
369 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
370 loop_ret = 1;
371 goto loop_end;
372 }
373 threshold_byte_set = true;
374 }
375 mask_position++;
376
377 /* Set domain type */
378 if ((1 << mask_position) & i) {
379 condition_status = lttng_condition_buffer_usage_set_domain_type(
380 condition, LTTNG_DOMAIN_UST);
381 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
382 loop_ret = 1;
383 goto loop_end;
384 }
385 domain_type_set = true;
386 }
387
388 /* Safety check */
389 if (mask_position != test_vector_size -1) {
390 assert("Logic error for test vector generation");
391 }
392
393 loop_ret = asprintf(&test_tuple_string, "session name %s, channel name %s, threshold ratio %s, threshold byte %s, domain type %s",
394 session_name_set ? "set" : "unset",
395 channel_name_set ? "set" : "unset",
396 threshold_ratio_set ? "set" : "unset",
397 threshold_byte_set ? "set" : "unset",
398 domain_type_set? "set" : "unset");
399 if (!test_tuple_string || loop_ret < 0) {
400 loop_ret = 1;
401 goto loop_end;
402 }
403
404 /* Create trigger */
405 trigger = lttng_trigger_create(condition, action);
406 if (!trigger) {
407 loop_ret = 1;
408 goto loop_end;
409 }
410
411 loop_ret = lttng_register_trigger(trigger);
412
413 loop_end:
414 if (loop_ret == 1) {
415 fail("Setup error occurred for tuple: %s", test_tuple_string);
416 goto loop_cleanup;
417 }
418
419 /* This combination happens three times */
420 if (session_name_set && channel_name_set
421 && (threshold_ratio_set || threshold_byte_set)
422 && domain_type_set) {
423 ok(loop_ret == 0, "Trigger is registered: %s", test_tuple_string);
424
425 /*
426 * Test that a trigger cannot be registered
427 * multiple time.
428 */
429 loop_ret = lttng_register_trigger(trigger);
430 ok(loop_ret == -LTTNG_ERR_TRIGGER_EXISTS, "Re-register trigger fails as expected: %s", test_tuple_string);
431
432 /* Test that a trigger can be unregistered */
433 loop_ret = lttng_unregister_trigger(trigger);
434 ok(loop_ret == 0, "Unregister trigger: %s", test_tuple_string);
435
436 /*
437 * Test that unregistration of a non-previously
438 * registered trigger fail.
439 */
440 loop_ret = lttng_unregister_trigger(trigger);
441 ok(loop_ret == -LTTNG_ERR_TRIGGER_NOT_FOUND, "Unregister of a non-registered trigger fails as expected: %s", test_tuple_string);
442 } else {
443 ok(loop_ret == -LTTNG_ERR_INVALID_TRIGGER, "Trigger is invalid as expected and cannot be registered: %s", test_tuple_string);
444 }
445
446 loop_cleanup:
447 free(test_tuple_string);
448 lttng_trigger_destroy(trigger);
449 lttng_condition_destroy(condition);
450 }
451
452 end:
453 lttng_action_destroy(action);
454 }
455
456 static
457 void wait_data_pending(const char *session_name)
458 {
459 int ret;
460
461 do {
462 ret = lttng_data_pending(session_name);
463 assert(ret >= 0);
464 } while (ret != 0);
465 }
466
467 static
468 int setup_buffer_usage_condition(struct lttng_condition *condition,
469 const char *condition_name,
470 const char *session_name,
471 const char *channel_name,
472 const enum lttng_domain_type domain_type)
473 {
474 enum lttng_condition_status condition_status;
475 int ret = 0;
476
477 condition_status = lttng_condition_buffer_usage_set_session_name(
478 condition, session_name);
479 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
480 fail("Failed to set session name on creation of condition `%s`",
481 condition_name);
482 ret = -1;
483 goto end;
484 }
485
486 condition_status = lttng_condition_buffer_usage_set_channel_name(
487 condition, channel_name);
488 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
489 fail("Failed to set channel name on creation of condition `%s`",
490 condition_name);
491 ret = -1;
492 goto end;
493 }
494
495 condition_status = lttng_condition_buffer_usage_set_domain_type(
496 condition, domain_type);
497 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
498 fail("Failed to set domain type on creation of condition `%s`",
499 condition_name);
500 ret = -1;
501 goto end;
502 }
503
504 end:
505 return ret;
506 }
507
508 static
509 void test_invalid_channel_subscription(
510 const enum lttng_domain_type domain_type)
511 {
512 enum lttng_condition_status condition_status;
513 enum lttng_notification_channel_status nc_status;
514 struct lttng_condition *dummy_condition = NULL;
515 struct lttng_condition *dummy_invalid_condition = NULL;
516 struct lttng_notification_channel *notification_channel = NULL;
517 int ret = 0;
518
519 notification_channel = lttng_notification_channel_create(
520 lttng_session_daemon_notification_endpoint);
521 ok(notification_channel, "Notification channel object creation");
522 if (!notification_channel) {
523 goto end;
524 }
525
526 /*
527 * Create a dummy, empty (thus invalid) condition to test error paths.
528 */
529 dummy_invalid_condition = lttng_condition_buffer_usage_low_create();
530 if (!dummy_invalid_condition) {
531 fail("Setup error on condition creation");
532 goto end;
533 }
534
535 /*
536 * Test subscription and unsubscription of an invalid condition to/from
537 * a channel.
538 */
539 nc_status = lttng_notification_channel_subscribe(
540 notification_channel, dummy_invalid_condition);
541 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
542 "Subscribing to an invalid condition");
543
544 nc_status = lttng_notification_channel_unsubscribe(
545 notification_channel, dummy_invalid_condition);
546 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
547 "Unsubscribing from an invalid condition");
548
549 /* Create a valid dummy condition with a ratio of 0.5 */
550 dummy_condition = lttng_condition_buffer_usage_low_create();
551 if (!dummy_condition) {
552 fail("Setup error on dummy_condition creation");
553 goto end;
554 }
555
556 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
557 dummy_condition, 0.5);
558 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
559 fail("Setup error on condition creation");
560 goto end;
561 }
562
563 ret = setup_buffer_usage_condition(dummy_condition, "dummy_condition",
564 "dummy_session", "dummy_channel", domain_type);
565 if (ret) {
566 fail("Setup error on dummy condition creation");
567 goto end;
568 }
569
570 /*
571 * Test subscription and unsubscription to/from a channel with invalid
572 * parameters.
573 */
574 nc_status = lttng_notification_channel_subscribe(NULL, NULL);
575 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
576 "Notification channel subscription is invalid: NULL, NULL");
577
578 nc_status = lttng_notification_channel_subscribe(
579 notification_channel, NULL);
580 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
581 "Notification channel subscription is invalid: NON-NULL, NULL");
582
583 nc_status = lttng_notification_channel_subscribe(NULL, dummy_condition);
584 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
585 "Notification channel subscription is invalid: NULL, NON-NULL");
586
587 nc_status = lttng_notification_channel_unsubscribe(
588 notification_channel, dummy_condition);
589 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_UNKNOWN_CONDITION,
590 "Unsubscribing from a valid unknown condition");
591
592 end:
593 lttng_notification_channel_destroy(notification_channel);
594 lttng_condition_destroy(dummy_invalid_condition);
595 lttng_condition_destroy(dummy_condition);
596 return;
597 }
598
599 enum buffer_usage_type {
600 BUFFER_USAGE_TYPE_LOW,
601 BUFFER_USAGE_TYPE_HIGH,
602 };
603
604 static int register_buffer_usage_notify_trigger(const char *session_name,
605 const char *channel_name,
606 const enum lttng_domain_type domain_type,
607 enum buffer_usage_type buffer_usage_type,
608 double ratio,
609 struct lttng_condition **condition,
610 struct lttng_action **action,
611 struct lttng_trigger **trigger)
612 {
613 enum lttng_condition_status condition_status;
614 struct lttng_action *tmp_action = NULL;
615 struct lttng_condition *tmp_condition = NULL;
616 struct lttng_trigger *tmp_trigger = NULL;
617 int ret = 0;
618
619 /* Set-up */
620 tmp_action = lttng_action_notify_create();
621 if (!action) {
622 fail("Setup error on action creation");
623 ret = -1;
624 goto error;
625 }
626
627 if (buffer_usage_type == BUFFER_USAGE_TYPE_LOW) {
628 tmp_condition = lttng_condition_buffer_usage_low_create();
629 } else {
630 tmp_condition = lttng_condition_buffer_usage_high_create();
631 }
632
633 if (!tmp_condition) {
634 fail("Setup error on condition creation");
635 ret = -1;
636 goto error;
637 }
638
639 /* Set the buffer usage threashold */
640 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
641 tmp_condition, ratio);
642 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
643 fail("Setup error on condition creation");
644 ret = -1;
645 goto error;
646 }
647
648 ret = setup_buffer_usage_condition(tmp_condition, "condition_name",
649 session_name, channel_name, domain_type);
650 if (ret) {
651 fail("Setup error on condition creation");
652 ret = -1;
653 goto error;
654 }
655
656 /* Register the trigger for condition. */
657 tmp_trigger = lttng_trigger_create(tmp_condition, tmp_action);
658 if (!tmp_trigger) {
659 fail("Setup error on trigger creation");
660 ret = -1;
661 goto error;
662 }
663
664 ret = lttng_register_trigger(tmp_trigger);
665 if (ret) {
666 fail("Setup error on trigger registration");
667 ret = -1;
668 goto error;
669 }
670
671 *condition = tmp_condition;
672 *trigger = tmp_trigger;
673 *action = tmp_action;
674 goto end;
675
676 error:
677 lttng_action_destroy(tmp_action);
678 lttng_condition_destroy(tmp_condition);
679 lttng_trigger_destroy(tmp_trigger);
680
681 end:
682 return ret;
683 }
684
685 static void test_subscription_twice(const char *session_name,
686 const char *channel_name,
687 const enum lttng_domain_type domain_type)
688 {
689 int ret = 0;
690 enum lttng_notification_channel_status nc_status;
691
692 struct lttng_action *action = NULL;
693 struct lttng_notification_channel *notification_channel = NULL;
694 struct lttng_trigger *trigger = NULL;
695
696 struct lttng_condition *condition = NULL;
697
698 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
699 domain_type, BUFFER_USAGE_TYPE_LOW, 0.99, &condition,
700 &action, &trigger);
701 if (ret) {
702 fail("Setup error on trigger registration");
703 goto end;
704 }
705
706 /* Begin testing. */
707 notification_channel = lttng_notification_channel_create(
708 lttng_session_daemon_notification_endpoint);
709 ok(notification_channel, "Notification channel object creation");
710 if (!notification_channel) {
711 goto end;
712 }
713
714 /* Subscribe a valid condition. */
715 nc_status = lttng_notification_channel_subscribe(
716 notification_channel, condition);
717 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
718 "Subscribe to condition");
719
720 /* Subscribing again should fail. */
721 nc_status = lttng_notification_channel_subscribe(
722 notification_channel, condition);
723 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED,
724 "Subscribe to a condition for which subscription was already done");
725
726 end:
727 lttng_unregister_trigger(trigger);
728 lttng_trigger_destroy(trigger);
729 lttng_notification_channel_destroy(notification_channel);
730 lttng_action_destroy(action);
731 lttng_condition_destroy(condition);
732 }
733
734 static void test_buffer_usage_notification_channel(const char *session_name,
735 const char *channel_name,
736 const enum lttng_domain_type domain_type,
737 const char **argv)
738 {
739 int ret = 0;
740 enum lttng_notification_channel_status nc_status;
741
742 struct lttng_action *low_action = NULL;
743 struct lttng_action *high_action = NULL;
744 struct lttng_notification *notification = NULL;
745 struct lttng_notification_channel *notification_channel = NULL;
746 struct lttng_trigger *low_trigger = NULL;
747 struct lttng_trigger *high_trigger = NULL;
748
749 struct lttng_condition *low_condition = NULL;
750 struct lttng_condition *high_condition = NULL;
751
752 const double low_ratio = 0.0;
753 const double high_ratio = 0.90;
754
755 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
756 domain_type, BUFFER_USAGE_TYPE_LOW, low_ratio,
757 &low_condition, &low_action, &low_trigger);
758 if (ret) {
759 fail("Setup error on low trigger registration");
760 goto end;
761 }
762
763 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
764 domain_type, BUFFER_USAGE_TYPE_HIGH, high_ratio,
765 &high_condition, &high_action, &high_trigger);
766 if (ret) {
767 fail("Setup error on high trigger registration");
768 goto end;
769 }
770
771 /* Begin testing */
772 notification_channel = lttng_notification_channel_create(
773 lttng_session_daemon_notification_endpoint);
774 ok(notification_channel, "Notification channel object creation");
775 if (!notification_channel) {
776 goto end;
777 }
778
779 /* Subscribe a valid low condition */
780 nc_status = lttng_notification_channel_subscribe(
781 notification_channel, low_condition);
782 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
783 "Subscribe to low condition");
784
785 /* Subscribe a valid high condition */
786 nc_status = lttng_notification_channel_subscribe(
787 notification_channel, high_condition);
788 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
789 "Subscribe to high condition");
790
791 resume_application();
792
793 /* Wait for notification to happen */
794 stop_consumer(argv);
795 lttng_start_tracing(session_name);
796
797 /* Wait for high notification */
798 do {
799 nc_status = lttng_notification_channel_get_next_notification(
800 notification_channel, &notification);
801 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
802 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
803 lttng_condition_get_type(lttng_notification_get_condition(
804 notification)) ==
805 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
806 "High notification received after intermediary communication");
807 lttng_notification_destroy(notification);
808 notification = NULL;
809
810 suspend_application();
811 lttng_stop_tracing_no_wait(session_name);
812 resume_consumer(argv);
813 wait_data_pending(session_name);
814
815 /*
816 * Test that communication still work even if there is notification
817 * waiting for consumption.
818 */
819
820 nc_status = lttng_notification_channel_unsubscribe(
821 notification_channel, low_condition);
822 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
823 "Unsubscribe with pending notification");
824
825 nc_status = lttng_notification_channel_subscribe(
826 notification_channel, low_condition);
827 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
828 "Subscribe with pending notification");
829
830 do {
831 nc_status = lttng_notification_channel_get_next_notification(
832 notification_channel, &notification);
833 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
834 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
835 lttng_condition_get_type(lttng_notification_get_condition(
836 notification)) ==
837 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW,
838 "Low notification received after intermediary communication");
839 lttng_notification_destroy(notification);
840 notification = NULL;
841
842 /* Stop consumer to force a high notification */
843 stop_consumer(argv);
844 resume_application();
845 lttng_start_tracing(session_name);
846
847 do {
848 nc_status = lttng_notification_channel_get_next_notification(
849 notification_channel, &notification);
850 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
851 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
852 lttng_condition_get_type(lttng_notification_get_condition(
853 notification)) ==
854 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
855 "High notification received after intermediary communication");
856 lttng_notification_destroy(notification);
857 notification = NULL;
858
859 suspend_application();
860 lttng_stop_tracing_no_wait(session_name);
861 resume_consumer(argv);
862 wait_data_pending(session_name);
863
864 do {
865 nc_status = lttng_notification_channel_get_next_notification(
866 notification_channel, &notification);
867 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
868 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
869 lttng_condition_get_type(lttng_notification_get_condition(
870 notification)) ==
871 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW,
872 "Low notification received after re-subscription");
873 lttng_notification_destroy(notification);
874 notification = NULL;
875
876 stop_consumer(argv);
877 resume_application();
878 /* Stop consumer to force a high notification */
879 lttng_start_tracing(session_name);
880
881 do {
882 nc_status = lttng_notification_channel_get_next_notification(
883 notification_channel, &notification);
884 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
885 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
886 lttng_condition_get_type(lttng_notification_get_condition(
887 notification)) ==
888 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
889 "High notification");
890 lttng_notification_destroy(notification);
891 notification = NULL;
892
893 suspend_application();
894
895 /* Resume consumer to allow event consumption */
896 lttng_stop_tracing_no_wait(session_name);
897 resume_consumer(argv);
898 wait_data_pending(session_name);
899
900 nc_status = lttng_notification_channel_unsubscribe(
901 notification_channel, low_condition);
902 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
903 "Unsubscribe low condition with pending notification");
904
905 nc_status = lttng_notification_channel_unsubscribe(
906 notification_channel, high_condition);
907 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
908 "Unsubscribe high condition with pending notification");
909
910 end:
911 lttng_notification_channel_destroy(notification_channel);
912 lttng_trigger_destroy(low_trigger);
913 lttng_trigger_destroy(high_trigger);
914 lttng_action_destroy(low_action);
915 lttng_action_destroy(high_action);
916 lttng_condition_destroy(low_condition);
917 lttng_condition_destroy(high_condition);
918 }
919
920 static void create_tracepoint_event_rule_trigger(const char *event_pattern,
921 const char *trigger_name,
922 const char *filter,
923 unsigned int exclusion_count,
924 const char * const *exclusions,
925 enum lttng_domain_type domain_type,
926 struct lttng_condition **condition,
927 struct lttng_trigger **trigger)
928 {
929 enum lttng_event_rule_status event_rule_status;
930 enum lttng_trigger_status trigger_status;
931
932 struct lttng_action *tmp_action = NULL;
933 struct lttng_event_rule *event_rule = NULL;
934 struct lttng_condition *tmp_condition = NULL;
935 struct lttng_trigger *tmp_trigger = NULL;
936 int ret;
937
938 assert(event_pattern);
939 assert(trigger_name);
940 assert(condition);
941 assert(trigger);
942
943 event_rule = lttng_event_rule_tracepoint_create(domain_type);
944 ok(event_rule, "Tracepoint event rule object creation");
945
946 event_rule_status = lttng_event_rule_tracepoint_set_pattern(
947 event_rule, event_pattern);
948 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
949 "Setting tracepoint event rule pattern: '%s'",
950 event_pattern);
951
952 if (filter) {
953 event_rule_status = lttng_event_rule_tracepoint_set_filter(
954 event_rule, filter);
955 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
956 "Setting tracepoint event rule filter: '%s'",
957 filter);
958 }
959
960 if (exclusions) {
961 int i;
962 bool success = true;
963
964 assert(domain_type == LTTNG_DOMAIN_UST);
965 assert(exclusion_count > 0);
966
967 for (i = 0; i < exclusion_count; i++) {
968 event_rule_status =
969 lttng_event_rule_tracepoint_add_exclusion(
970 event_rule,
971 exclusions[i]);
972 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
973 fail("Setting tracepoint event rule exclusion '%s'.",
974 exclusions[i]);
975 success = false;
976 }
977 }
978
979 ok(success, "Setting tracepoint event rule exclusions");
980 }
981
982 tmp_condition = lttng_condition_event_rule_create(event_rule);
983 ok(tmp_condition, "Condition event rule object creation");
984
985 tmp_action = lttng_action_notify_create();
986 ok(tmp_action, "Action event rule object creation");
987
988 tmp_trigger = lttng_trigger_create(tmp_condition, tmp_action);
989 ok(tmp_trigger, "Trigger object creation %s", trigger_name);
990
991 trigger_status = lttng_trigger_set_name(tmp_trigger, trigger_name);
992 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
993 "Setting name to trigger %s", trigger_name);
994
995 ret = lttng_register_trigger(tmp_trigger);
996 ok(ret == 0, "Trigger registration %s", trigger_name);
997
998 lttng_event_rule_destroy(event_rule);
999
1000 *condition = tmp_condition;
1001 *trigger = tmp_trigger;
1002
1003 return;
1004 }
1005
1006 static struct lttng_notification *get_next_notification(
1007 struct lttng_notification_channel *notification_channel)
1008 {
1009 struct lttng_notification *local_notification = NULL;
1010 enum lttng_notification_channel_status status;
1011
1012 /* Receive the next notification. */
1013 status = lttng_notification_channel_get_next_notification(
1014 notification_channel, &local_notification);
1015
1016 switch (status) {
1017 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
1018 break;
1019 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
1020 fail("Notifications have been dropped");
1021 local_notification = NULL;
1022 break;
1023 default:
1024 /* Unhandled conditions / errors. */
1025 fail("Failed to get next notification (unknown notification channel status): status = %d",
1026 (int) status);
1027 local_notification = NULL;
1028 break;
1029 }
1030
1031 return local_notification;
1032 }
1033
1034 static void test_tracepoint_event_rule_notification(
1035 enum lttng_domain_type domain_type)
1036 {
1037 int i;
1038 int ret;
1039 const int notification_count = 3;
1040 enum lttng_notification_channel_status nc_status;
1041 struct lttng_action *action = NULL;
1042 struct lttng_condition *condition = NULL;
1043 struct lttng_notification_channel *notification_channel = NULL;
1044 struct lttng_trigger *trigger = NULL;
1045 const char * const trigger_name = "my_precious";
1046 const char *pattern;
1047
1048 if (domain_type == LTTNG_DOMAIN_UST) {
1049 pattern = "tp:tptest";
1050 } else {
1051 pattern = "lttng_test_filter_event";
1052 }
1053
1054 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 0,
1055 NULL, domain_type, &condition, &trigger);
1056
1057 notification_channel = lttng_notification_channel_create(
1058 lttng_session_daemon_notification_endpoint);
1059 ok(notification_channel, "Notification channel object creation");
1060
1061 nc_status = lttng_notification_channel_subscribe(
1062 notification_channel, condition);
1063 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1064 "Subscribe to tracepoint event rule condition");
1065
1066 resume_application();
1067
1068 /* Get notifications. */
1069 for (i = 0; i < notification_count; i++) {
1070 struct lttng_notification *notification = get_next_notification(
1071 notification_channel);
1072
1073 ok(notification, "Received notification (%d/%d)", i + 1,
1074 notification_count);
1075
1076 /* Error. */
1077 if (notification == NULL) {
1078 goto end;
1079 }
1080
1081 ret = validator_notification_trigger_name(notification, trigger_name);
1082 lttng_notification_destroy(notification);
1083 if (ret) {
1084 goto end;
1085 }
1086 }
1087
1088 end:
1089 suspend_application();
1090 lttng_notification_channel_destroy(notification_channel);
1091 lttng_unregister_trigger(trigger);
1092 lttng_trigger_destroy(trigger);
1093 lttng_action_destroy(action);
1094 lttng_condition_destroy(condition);
1095 return;
1096 }
1097
1098 static void test_tracepoint_event_rule_notification_filter(
1099 enum lttng_domain_type domain_type)
1100 {
1101 int i;
1102 const int notification_count = 3;
1103 enum lttng_notification_channel_status nc_status;
1104 struct lttng_condition *ctrl_condition = NULL, *condition = NULL;
1105 struct lttng_notification_channel *notification_channel = NULL;
1106 struct lttng_trigger *ctrl_trigger = NULL, *trigger = NULL;
1107 const char * const ctrl_trigger_name = "control_trigger";
1108 const char * const trigger_name = "trigger";
1109 const char *pattern;
1110 int ctrl_count = 0, count = 0;
1111
1112 if (domain_type == LTTNG_DOMAIN_UST) {
1113 pattern = "tp:tptest";
1114 } else {
1115 pattern = "lttng_test_filter_event";
1116 }
1117
1118 notification_channel = lttng_notification_channel_create(
1119 lttng_session_daemon_notification_endpoint);
1120 ok(notification_channel, "Notification channel object creation");
1121
1122 create_tracepoint_event_rule_trigger(pattern, ctrl_trigger_name, NULL,
1123 0, NULL, domain_type, &ctrl_condition, &ctrl_trigger);
1124
1125 nc_status = lttng_notification_channel_subscribe(
1126 notification_channel, ctrl_condition);
1127 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1128 "Subscribe to tracepoint event rule condition");
1129
1130 /*
1131 * Attach a filter expression to get notification only if the
1132 * `intfield` is even.
1133 */
1134 create_tracepoint_event_rule_trigger(pattern, trigger_name,
1135 "(intfield & 1) == 0", 0, NULL, domain_type, &condition,
1136 &trigger);
1137
1138 nc_status = lttng_notification_channel_subscribe(
1139 notification_channel, condition);
1140 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1141 "Subscribe to tracepoint event rule condition");
1142
1143 /*
1144 * We registered 2 notifications triggers, one with a filter and one
1145 * without (control). The one with a filter will only fired when the
1146 * `intfield` is a multiple of 2. We should get two times as many
1147 * control notifications as filter notifications.
1148 */
1149 resume_application();
1150
1151 /*
1152 * Get 3 notifications. We should get 1 for the regular trigger (with
1153 * the filter) and 2 from the control trigger. This works whatever
1154 * the order we receive the notifications.
1155 */
1156 for (i = 0; i < notification_count; i++) {
1157 const char *name;
1158 struct lttng_notification *notification = get_next_notification(
1159 notification_channel);
1160
1161 ok(notification, "Received notification (%d/%d)", i + 1,
1162 notification_count);
1163
1164 /* Error. */
1165 if (notification == NULL) {
1166 goto end;
1167 }
1168
1169 name = get_notification_trigger_name(notification);
1170 if (name == NULL) {
1171 lttng_notification_destroy(notification);
1172 goto end;
1173 }
1174
1175 if (strcmp(ctrl_trigger_name, name) == 0) {
1176 ctrl_count++;
1177 } else if (strcmp(trigger_name, name) == 0) {
1178 count++;
1179 }
1180
1181 lttng_notification_destroy(notification);
1182 }
1183
1184 ok(ctrl_count / 2 == count,
1185 "Get twice as many control notif as of regular notif");
1186
1187 end:
1188 suspend_application();
1189
1190 lttng_unregister_trigger(trigger);
1191 lttng_unregister_trigger(ctrl_trigger);
1192 lttng_notification_channel_destroy(notification_channel);
1193 lttng_trigger_destroy(trigger);
1194 lttng_trigger_destroy(ctrl_trigger);
1195 lttng_condition_destroy(condition);
1196 lttng_condition_destroy(ctrl_condition);
1197 }
1198
1199 static void test_tracepoint_event_rule_notification_exclusion(
1200 enum lttng_domain_type domain_type)
1201 {
1202 enum lttng_notification_channel_status nc_status;
1203 struct lttng_condition *ctrl_condition = NULL, *condition = NULL;
1204 struct lttng_notification_channel *notification_channel = NULL;
1205 struct lttng_trigger *ctrl_trigger = NULL, *trigger = NULL;
1206 int ctrl_count = 0, count = 0, i;
1207 const int notification_count = 6;
1208 const char * const ctrl_trigger_name = "control_exclusion_trigger";
1209 const char * const trigger_name = "exclusion_trigger";
1210 const char * const pattern = "tp:tptest*";
1211 const char * const exclusions[] = {
1212 "tp:tptest2",
1213 "tp:tptest3",
1214 "tp:tptest4",
1215 "tp:tptest5"
1216 };
1217
1218 notification_channel = lttng_notification_channel_create(
1219 lttng_session_daemon_notification_endpoint);
1220 ok(notification_channel, "Notification channel object creation");
1221
1222 create_tracepoint_event_rule_trigger(pattern, ctrl_trigger_name, NULL,
1223 0, NULL, domain_type, &ctrl_condition, &ctrl_trigger);
1224
1225 nc_status = lttng_notification_channel_subscribe(
1226 notification_channel, ctrl_condition);
1227 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1228 "Subscribe to tracepoint event rule condition");
1229
1230 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 4,
1231 exclusions, domain_type, &condition, &trigger);
1232
1233 nc_status = lttng_notification_channel_subscribe(
1234 notification_channel, condition);
1235 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1236 "Subscribe to tracepoint event rule condition");
1237
1238 /*
1239 * We registered 2 notifications triggers, one with an exclusion and
1240 * one without (control).
1241 * - The trigger with an exclusion will fire once every iteration.
1242 * - The trigger without an exclusion will fire 5 times every
1243 * iteration.
1244 *
1245 * We should get 5 times as many notifications from the control
1246 * trigger.
1247 */
1248 resume_application();
1249
1250 /*
1251 * Get 6 notifications. We should get 1 for the regular trigger (with
1252 * the exclusion) and 5 from the control trigger. This works whatever
1253 * the order we receive the notifications.
1254 */
1255 for (i = 0; i < notification_count; i++) {
1256 const char *name;
1257 struct lttng_notification *notification = get_next_notification(
1258 notification_channel);
1259
1260 ok(notification, "Received notification (%d/%d)", i + 1,
1261 notification_count);
1262
1263 /* Error. */
1264 if (notification == NULL) {
1265 goto end;
1266 }
1267
1268 name = get_notification_trigger_name(notification);
1269 if (name == NULL) {
1270 lttng_notification_destroy(notification);
1271 goto end;
1272 }
1273
1274 if (strcmp(ctrl_trigger_name, name) == 0) {
1275 ctrl_count++;
1276 } else if (strcmp(trigger_name, name) == 0) {
1277 count++;
1278 }
1279
1280 lttng_notification_destroy(notification);
1281 }
1282
1283 ok(ctrl_count / 5 == count,
1284 "Got 5 times as many control notif as of regular notif");
1285
1286 end:
1287 suspend_application();
1288
1289 lttng_unregister_trigger(trigger);
1290 lttng_unregister_trigger(ctrl_trigger);
1291 lttng_notification_channel_destroy(notification_channel);
1292 lttng_trigger_destroy(trigger);
1293 lttng_trigger_destroy(ctrl_trigger);
1294 lttng_condition_destroy(condition);
1295 lttng_condition_destroy(ctrl_condition);
1296 return;
1297 }
1298
1299 static void test_kprobe_event_rule_notification(
1300 enum lttng_domain_type domain_type)
1301 {
1302 int i, ret;
1303 const int notification_count = 3;
1304 enum lttng_notification_channel_status nc_status;
1305 enum lttng_event_rule_status event_rule_status;
1306 enum lttng_trigger_status trigger_status;
1307 struct lttng_notification_channel *notification_channel = NULL;
1308 struct lttng_condition *condition = NULL;
1309 struct lttng_kernel_probe_location *location = NULL;
1310 struct lttng_event_rule *event_rule = NULL;
1311 struct lttng_action *action = NULL;
1312 struct lttng_trigger *trigger = NULL;
1313 const char * const trigger_name = "kprobe_trigger";
1314 const char * const symbol_name = "lttng_test_filter_event_write";
1315
1316 action = lttng_action_notify_create();
1317 if (!action) {
1318 fail("Failed to create notify action");
1319 goto end;
1320 }
1321
1322 location = lttng_kernel_probe_location_symbol_create(symbol_name, 0);
1323 if (!location) {
1324 fail("Failed to create kernel probe location");
1325 goto end;
1326 }
1327
1328 notification_channel = lttng_notification_channel_create(
1329 lttng_session_daemon_notification_endpoint);
1330 ok(notification_channel, "Notification channel object creation");
1331
1332 event_rule = lttng_event_rule_kprobe_create();
1333 ok(event_rule, "kprobe event rule object creation");
1334
1335 event_rule_status = lttng_event_rule_kprobe_set_location(
1336 event_rule, location);
1337 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1338 "Setting kprobe event rule location: '%s'", symbol_name);
1339
1340 event_rule_status = lttng_event_rule_kprobe_set_name(
1341 event_rule, trigger_name);
1342 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1343 "Setting kprobe event rule name: '%s'", trigger_name);
1344
1345 condition = lttng_condition_event_rule_create(event_rule);
1346 ok(condition, "Condition event rule object creation");
1347
1348 /* Register the trigger for condition. */
1349 trigger = lttng_trigger_create(condition, action);
1350 if (!trigger) {
1351 fail("Failed to create trigger with kernel probe event rule condition and notify action");
1352 goto end;
1353 }
1354
1355 trigger_status = lttng_trigger_set_name(trigger, trigger_name);
1356 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
1357 "Setting trigger name to '%s'", trigger_name);
1358
1359 ret = lttng_register_trigger(trigger);
1360 if (ret) {
1361 fail("Failed to register trigger with kernel probe event rule condition and notify action");
1362 goto end;
1363 }
1364
1365 nc_status = lttng_notification_channel_subscribe(
1366 notification_channel, condition);
1367 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1368 "Subscribe to tracepoint event rule condition");
1369
1370 resume_application();
1371
1372 for (i = 0; i < notification_count; i++) {
1373 struct lttng_notification *notification = get_next_notification(
1374 notification_channel);
1375
1376 ok(notification, "Received notification (%d/%d)", i + 1,
1377 notification_count);
1378
1379 /* Error. */
1380 if (notification == NULL) {
1381 goto end;
1382 }
1383
1384 ret = validator_notification_trigger_name(notification, trigger_name);
1385 lttng_notification_destroy(notification);
1386 if (ret) {
1387 goto end;
1388 }
1389 }
1390
1391 end:
1392 suspend_application();
1393 lttng_notification_channel_destroy(notification_channel);
1394 lttng_unregister_trigger(trigger);
1395 lttng_trigger_destroy(trigger);
1396 lttng_action_destroy(action);
1397 lttng_event_rule_destroy(event_rule);
1398 lttng_condition_destroy(condition);
1399 lttng_kernel_probe_location_destroy(location);
1400 return;
1401 }
1402
1403 static void test_uprobe_event_rule_notification(
1404 enum lttng_domain_type domain_type,
1405 const char *testapp_path,
1406 const char *test_symbol_name)
1407 {
1408 int i, ret;
1409 const int notification_count = 3;
1410 enum lttng_notification_channel_status nc_status;
1411 enum lttng_event_rule_status event_rule_status;
1412 enum lttng_trigger_status trigger_status;
1413 struct lttng_notification_channel *notification_channel = NULL;
1414 struct lttng_userspace_probe_location *probe_location = NULL;
1415 struct lttng_userspace_probe_location_lookup_method *lookup_method =
1416 NULL;
1417 struct lttng_condition *condition = NULL;
1418 struct lttng_event_rule *event_rule = NULL;
1419 struct lttng_action *action = NULL;
1420 struct lttng_trigger *trigger = NULL;
1421 const char * const trigger_name = "uprobe_trigger";
1422
1423 action = lttng_action_notify_create();
1424 if (!action) {
1425 fail("Failed to create notify action");
1426 goto end;
1427 }
1428
1429 lookup_method = lttng_userspace_probe_location_lookup_method_function_elf_create();
1430 if (!lookup_method) {
1431 fail("Setup error on userspace probe lookup method creation");
1432 goto end;
1433 }
1434
1435 probe_location = lttng_userspace_probe_location_function_create(
1436 testapp_path, test_symbol_name, lookup_method);
1437 if (!probe_location) {
1438 fail("Failed to create userspace probe location");
1439 goto end;
1440 }
1441
1442 notification_channel = lttng_notification_channel_create(
1443 lttng_session_daemon_notification_endpoint);
1444 ok(notification_channel, "Notification channel object creation");
1445
1446 event_rule = lttng_event_rule_uprobe_create();
1447 ok(event_rule, "kprobe event rule object creation");
1448
1449 event_rule_status = lttng_event_rule_uprobe_set_location(
1450 event_rule, probe_location);
1451 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1452 "Setting uprobe event rule location");
1453
1454 event_rule_status = lttng_event_rule_uprobe_set_name(
1455 event_rule, trigger_name);
1456 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1457 "Setting uprobe event rule name: '%s'", trigger_name);
1458
1459 condition = lttng_condition_event_rule_create(event_rule);
1460 ok(condition, "Condition event rule object creation");
1461
1462 /* Register the trigger for condition. */
1463 trigger = lttng_trigger_create(condition, action);
1464 if (!trigger) {
1465 fail("Failed to create trigger with userspace probe event rule condition and notify action");
1466 goto end;
1467 }
1468
1469 trigger_status = lttng_trigger_set_name(trigger, trigger_name);
1470 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
1471 "Setting name to trigger '%s'", trigger_name);
1472
1473 ret = lttng_register_trigger(trigger);
1474 if (ret) {
1475 fail("Failed to register trigger with userspace probe event rule condition and notify action");
1476 goto end;
1477 }
1478
1479 nc_status = lttng_notification_channel_subscribe(
1480 notification_channel, condition);
1481 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1482 "Subscribe to tracepoint event rule condition");
1483
1484 resume_application();
1485
1486 for (i = 0; i < 3; i++) {
1487 struct lttng_notification *notification = get_next_notification(
1488 notification_channel);
1489
1490 ok(notification, "Received notification (%d/%d)", i + 1,
1491 notification_count);
1492
1493 /* Error. */
1494 if (notification == NULL) {
1495 goto end;
1496 }
1497
1498 ret = validator_notification_trigger_name(notification, trigger_name);
1499 lttng_notification_destroy(notification);
1500 if (ret) {
1501 goto end;
1502 }
1503 }
1504 end:
1505 suspend_application();
1506
1507 lttng_notification_channel_destroy(notification_channel);
1508 lttng_unregister_trigger(trigger);
1509 lttng_trigger_destroy(trigger);
1510 lttng_action_destroy(action);
1511 lttng_event_rule_destroy(event_rule);
1512 lttng_condition_destroy(condition);
1513 return;
1514 }
1515
1516 static void test_syscall_event_rule_notification(
1517 enum lttng_domain_type domain_type)
1518 {
1519 int i, ret;
1520 const int notification_count = 3;
1521 enum lttng_notification_channel_status nc_status;
1522 enum lttng_event_rule_status event_rule_status;
1523 enum lttng_trigger_status trigger_status;
1524 struct lttng_notification_channel *notification_channel = NULL;
1525 struct lttng_condition *condition = NULL;
1526 struct lttng_event_rule *event_rule = NULL;
1527 struct lttng_action *action = NULL;
1528 struct lttng_trigger *trigger = NULL;
1529 const char * const trigger_name = "syscall_trigger";
1530 const char * const syscall_name = "openat";
1531
1532 action = lttng_action_notify_create();
1533 if (!action) {
1534 fail("Failed to create notify action");
1535 goto end;
1536 }
1537
1538 notification_channel = lttng_notification_channel_create(
1539 lttng_session_daemon_notification_endpoint);
1540 ok(notification_channel, "Notification channel object creation");
1541
1542 event_rule = lttng_event_rule_syscall_create();
1543 ok(event_rule, "syscall event rule object creation");
1544
1545 event_rule_status = lttng_event_rule_syscall_set_pattern(
1546 event_rule, syscall_name);
1547 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1548 "Setting syscall event rule pattern: '%s'", syscall_name);
1549
1550 condition = lttng_condition_event_rule_create(event_rule);
1551 ok(condition, "Condition syscall event rule object creation");
1552
1553 /* Register the trigger for condition. */
1554 trigger = lttng_trigger_create(condition, action);
1555 if (!trigger) {
1556 fail("Failed to create trigger with syscall event rule condition and notify action");
1557 goto end;
1558 }
1559
1560 trigger_status = lttng_trigger_set_name(trigger, trigger_name);
1561 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
1562 "Setting name to trigger '%s'", trigger_name);
1563
1564 ret = lttng_register_trigger(trigger);
1565 if (ret) {
1566 fail("Failed to register trigger with syscall event rule condition and notify action");
1567 goto end;
1568 }
1569
1570 nc_status = lttng_notification_channel_subscribe(
1571 notification_channel, condition);
1572 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1573 "Subscribe to tracepoint event rule condition");
1574
1575 resume_application();
1576
1577 for (i = 0; i < notification_count; i++) {
1578 struct lttng_notification *notification = get_next_notification(
1579 notification_channel);
1580
1581 ok(notification, "Received notification (%d/%d)", i + 1,
1582 notification_count);
1583
1584 /* Error. */
1585 if (notification == NULL) {
1586 goto end;
1587 }
1588
1589 ret = validator_notification_trigger_name(notification, trigger_name);
1590 lttng_notification_destroy(notification);
1591 if (ret) {
1592 goto end;
1593 }
1594 }
1595 end:
1596 suspend_application();
1597 lttng_notification_channel_destroy(notification_channel);
1598 lttng_unregister_trigger(trigger);
1599 lttng_trigger_destroy(trigger);
1600 lttng_action_destroy(action);
1601 lttng_condition_destroy(condition);
1602 return;
1603 }
1604
1605 static void test_syscall_event_rule_notification_filter(
1606 enum lttng_domain_type domain_type)
1607 {
1608 int i, ret;
1609 const int notification_count = 3;
1610 enum lttng_notification_channel_status nc_status;
1611 enum lttng_event_rule_status event_rule_status;
1612 enum lttng_trigger_status trigger_status;
1613 struct lttng_notification_channel *notification_channel = NULL;
1614 struct lttng_condition *condition = NULL;
1615 struct lttng_event_rule *event_rule = NULL;
1616 struct lttng_action *action = NULL;
1617 struct lttng_trigger *trigger = NULL;
1618 const char * const trigger_name = "syscall_trigger";
1619 const char * const syscall_name = "openat";
1620 const char * const filter_pattern = "filename == \"/proc/cpuinfo\"";
1621
1622 action = lttng_action_notify_create();
1623 if (!action) {
1624 fail("Failed to create notify action");
1625 goto end;
1626 }
1627
1628 notification_channel = lttng_notification_channel_create(
1629 lttng_session_daemon_notification_endpoint);
1630 ok(notification_channel, "Notification channel object creation");
1631
1632 event_rule = lttng_event_rule_syscall_create();
1633 ok(event_rule, "syscall event rule object creation");
1634
1635 event_rule_status = lttng_event_rule_syscall_set_pattern(
1636 event_rule, syscall_name);
1637 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1638 "Setting syscall event rule pattern: '%s'", syscall_name);
1639
1640 event_rule_status = lttng_event_rule_syscall_set_filter(
1641 event_rule, filter_pattern);
1642 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1643 "Setting filter: '%s'", filter_pattern);
1644
1645 condition = lttng_condition_event_rule_create(event_rule);
1646 ok(condition, "Condition event rule object creation");
1647
1648 /* Register the triggers for condition */
1649 trigger = lttng_trigger_create(condition, action);
1650 if (!trigger) {
1651 fail("Failed to create trigger with syscall filtering event rule condition and notify action");
1652 goto end;
1653 }
1654
1655 trigger_status = lttng_trigger_set_name(trigger, trigger_name);
1656 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
1657 "Setting name to trigger '%s'", trigger_name);
1658
1659 ret = lttng_register_trigger(trigger);
1660 if (ret) {
1661 fail("Failed to register trigger with syscall filtering event rule condition and notify action");
1662 goto end;
1663 }
1664
1665 nc_status = lttng_notification_channel_subscribe(
1666 notification_channel, condition);
1667 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1668 "Subscribe to tracepoint event rule condition");
1669
1670 resume_application();
1671
1672 for (i = 0; i < notification_count; i++) {
1673 struct lttng_notification *notification = get_next_notification(
1674 notification_channel);
1675
1676 ok(notification, "Received notification (%d/%d)", i + 1,
1677 notification_count);
1678
1679 /* Error. */
1680 if (notification == NULL) {
1681 goto end;
1682 }
1683
1684 ret = validator_notification_trigger_name(notification, trigger_name);
1685 lttng_notification_destroy(notification);
1686 if (ret) {
1687 goto end;
1688 }
1689 }
1690
1691 end:
1692 suspend_application();
1693
1694 lttng_unregister_trigger(trigger);
1695 lttng_notification_channel_destroy(notification_channel);
1696 lttng_trigger_destroy(trigger);
1697 lttng_event_rule_destroy(event_rule);
1698 lttng_condition_destroy(condition);
1699 return;
1700 }
1701
1702 int main(int argc, const char *argv[])
1703 {
1704 int test_scenario;
1705 const char *domain_type_string = NULL;
1706 enum lttng_domain_type domain_type = LTTNG_DOMAIN_NONE;
1707
1708 if (argc < 5) {
1709 fail("Missing test scenario, domain type, pid, or application state file argument(s)");
1710 goto error;
1711 }
1712
1713 test_scenario = atoi(argv[1]);
1714 domain_type_string = argv[2];
1715 app_pid = (pid_t) atoi(argv[3]);
1716 app_state_file = argv[4];
1717
1718 if (!strcmp("LTTNG_DOMAIN_UST", domain_type_string)) {
1719 domain_type = LTTNG_DOMAIN_UST;
1720 }
1721 if (!strcmp("LTTNG_DOMAIN_KERNEL", domain_type_string)) {
1722 domain_type = LTTNG_DOMAIN_KERNEL;
1723 }
1724 if (domain_type == LTTNG_DOMAIN_NONE) {
1725 fail("Unknown domain type");
1726 goto error;
1727 }
1728
1729 /*
1730 * Test cases are responsible for resuming the app when needed
1731 * and making sure it's suspended when returning.
1732 */
1733 suspend_application();
1734
1735 switch (test_scenario) {
1736 case 1:
1737 {
1738 plan_tests(44);
1739
1740 /* Test cases that need gen-ust-event testapp. */
1741 diag("Test basic notification error paths for %s domain",
1742 domain_type_string);
1743 test_invalid_channel_subscription(domain_type);
1744
1745 diag("Test tracepoint event rule notifications for domain %s",
1746 domain_type_string);
1747 test_tracepoint_event_rule_notification(domain_type);
1748
1749 diag("Test tracepoint event rule notifications with filter for domain %s",
1750 domain_type_string);
1751 test_tracepoint_event_rule_notification_filter(domain_type);
1752 break;
1753 }
1754 case 2:
1755 {
1756 const char *session_name, *channel_name;
1757
1758 /* Test cases that need a tracing session enabled. */
1759 plan_tests(99);
1760
1761 /*
1762 * Argument 7 and upward are named pipe location for consumerd
1763 * control.
1764 */
1765 named_pipe_args_start = 7;
1766
1767 if (argc < 8) {
1768 fail("Missing parameter for tests to run %d", argc);
1769 goto error;
1770 }
1771
1772 nb_args = argc;
1773
1774 session_name = argv[5];
1775 channel_name = argv[6];
1776
1777 test_subscription_twice(session_name, channel_name,
1778 domain_type);
1779
1780 diag("Test trigger for domain %s with buffer_usage_low condition",
1781 domain_type_string);
1782 test_triggers_buffer_usage_condition(session_name, channel_name,
1783 domain_type,
1784 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
1785
1786 diag("Test trigger for domain %s with buffer_usage_high condition",
1787 domain_type_string);
1788 test_triggers_buffer_usage_condition(session_name, channel_name,
1789 domain_type,
1790 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
1791
1792 diag("Test buffer usage notification channel api for domain %s",
1793 domain_type_string);
1794 test_buffer_usage_notification_channel(session_name, channel_name,
1795 domain_type, argv);
1796 break;
1797 }
1798 case 3:
1799 {
1800 /*
1801 * Test cases that need a test app with more than one event
1802 * type.
1803 */
1804 plan_tests(25);
1805
1806 /*
1807 * At the moment, the only test case of this scenario is
1808 * exclusion which is only supported by UST.
1809 */
1810 assert(domain_type == LTTNG_DOMAIN_UST);
1811 diag("Test tracepoint event rule notifications with exclusion for domain %s",
1812 domain_type_string);
1813 test_tracepoint_event_rule_notification_exclusion(domain_type);
1814
1815 break;
1816 }
1817 case 4:
1818 {
1819 plan_tests(13);
1820 /* Test cases that need the kernel tracer. */
1821 assert(domain_type == LTTNG_DOMAIN_KERNEL);
1822
1823 diag("Test kprobe event rule notifications for domain %s",
1824 domain_type_string);
1825
1826 test_kprobe_event_rule_notification(domain_type);
1827
1828 break;
1829 }
1830 case 5:
1831 {
1832 plan_tests(25);
1833 /* Test cases that need the kernel tracer. */
1834 assert(domain_type == LTTNG_DOMAIN_KERNEL);
1835
1836 diag("Test syscall event rule notifications for domain %s",
1837 domain_type_string);
1838
1839 test_syscall_event_rule_notification(domain_type);
1840
1841 diag("Test syscall filtering event rule notifications for domain %s",
1842 domain_type_string);
1843
1844 test_syscall_event_rule_notification_filter(domain_type);
1845
1846 break;
1847 }
1848 case 6:
1849 {
1850 const char *testapp_path, *test_symbol_name;
1851
1852 plan_tests(13);
1853
1854 if (argc < 7) {
1855 fail("Missing parameter for tests to run %d", argc);
1856 goto error;
1857 }
1858
1859 testapp_path = argv[5];
1860 test_symbol_name = argv[6];
1861 /* Test cases that need the kernel tracer. */
1862 assert(domain_type == LTTNG_DOMAIN_KERNEL);
1863
1864 diag("Test userspace-probe event rule notifications for domain %s",
1865 domain_type_string);
1866
1867 test_uprobe_event_rule_notification(
1868 domain_type, testapp_path, test_symbol_name);
1869
1870 break;
1871 }
1872 default:
1873 abort();
1874 }
1875
1876 error:
1877 return exit_status();
1878 }
1879
This page took 0.104957 seconds and 4 git commands to generate.