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