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