tests: sync tests/utils/tap with Babeltrace repository
[lttng-tools.git] / tests / regression / tools / notification / notification.cpp
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 <math.h>
13 #include <stdbool.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <inttypes.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <signal.h>
23 #include <poll.h>
24
25 #include <common/compat/errno.h>
26 #include <common/macros.h>
27 #include <lttng/lttng.h>
28
29 #include <tap/tap.h>
30
31 #define FIELD_NAME_MAX_LEN 256
32
33 /* A callback to populate the condition capture descriptor. */
34 typedef int (*condition_capture_desc_cb)(struct lttng_condition *condition);
35
36 /* A callback for captured field validation. */
37 typedef int (*validate_cb)(const struct lttng_event_field_value *event_field, unsigned iteration);
38
39 int nb_args = 0;
40 int named_pipe_args_start = 0;
41 pid_t app_pid = 0;
42 const char *app_state_file = NULL;
43
44 enum field_type {
45 FIELD_TYPE_PAYLOAD,
46 FIELD_TYPE_CONTEXT,
47 FIELD_TYPE_APP_CONTEXT,
48 FIELD_TYPE_ARRAY_FIELD,
49 };
50
51 struct capture_base_field_tuple {
52 const char *field_name;
53 enum field_type field_type;
54 /* Do we expect a userspace capture? */
55 bool expected_ust;
56 /* Do we expect a kernel capture? */
57 bool expected_kernel;
58 validate_cb validate_ust;
59 validate_cb validate_kernel;
60 };
61
62 static
63 const char *field_value_type_to_str(enum lttng_event_field_value_type type)
64 {
65 switch (type) {
66 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNKNOWN:
67 return "UNKNOWN";
68 case LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID:
69 return "INVALID";
70 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT:
71 return "UNSIGNED INT";
72 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT:
73 return "SIGNED INT";
74 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
75 return "UNSIGNED ENUM";
76 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
77 return "SIGNED ENUM";
78 case LTTNG_EVENT_FIELD_VALUE_TYPE_REAL:
79 return "REAL";
80 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING:
81 return "STRING";
82 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY:
83 return "ARRAY";
84 default:
85 abort();
86 }
87 }
88
89 static int validate_type(const struct lttng_event_field_value *event_field,
90 enum lttng_event_field_value_type expect)
91 {
92 int ret;
93 enum lttng_event_field_value_type value;
94
95 value = lttng_event_field_value_get_type(event_field);
96 if (value == LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID) {
97 ret = 1;
98 goto end;
99 }
100
101 ok(expect == value, "Expected field type %s, got %s",
102 field_value_type_to_str(expect),
103 field_value_type_to_str(value));
104
105 ret = expect != value;
106
107 end:
108 return ret;
109 }
110
111 /*
112 * Validate unsigned captured field against the iteration number.
113 */
114 static int validate_unsigned_int_field(
115 const struct lttng_event_field_value *event_field,
116 unsigned int expected_value)
117 {
118 int ret;
119 uint64_t value;
120 enum lttng_event_field_value_status status;
121
122 ret = validate_type(
123 event_field, LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT);
124 if (ret) {
125 goto end;
126 }
127
128 status = lttng_event_field_value_unsigned_int_get_value(
129 event_field, &value);
130 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
131 fail("lttng_event_field_value_unsigned_int_get_value returned an error: status = %d",
132 (int) status);
133 ret = 1;
134 goto end;
135 }
136
137 ok(value == (uint64_t) expected_value,
138 "Expected unsigned integer value %u, got %" PRIu64,
139 expected_value, value);
140
141 ret = value != (uint64_t) expected_value;
142
143 end:
144 return ret;
145 }
146
147 /*
148 * Validate signed captured field.
149 */
150 static int validate_signed_int_field(
151 const struct lttng_event_field_value *event_field,
152 unsigned int iteration)
153 {
154 int ret;
155 const int64_t expected = -1;
156 int64_t value;
157 enum lttng_event_field_value_status status;
158
159 /* Unused. */
160 (void) iteration;
161
162 ret = validate_type(
163 event_field, LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT);
164 if (ret) {
165 goto end;
166 }
167
168 status = lttng_event_field_value_signed_int_get_value(
169 event_field, &value);
170 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
171 fail("lttng_event_field_value_signed_int_get_value returned an error: status = %d",
172 (int) status);
173 ret = 1;
174 goto end;
175 }
176
177 ok(value == expected,
178 "Expected signed integer value %" PRId64
179 ", got %" PRId64,
180 expected, value);
181
182 ret = value != expected;
183
184 end:
185
186 return ret;
187 }
188
189 /*
190 * Validate array of unsigned int.
191 */
192 static int validate_array_unsigned_int_field(
193 const struct lttng_event_field_value *event_field,
194 unsigned int iteration)
195 {
196 int ret;
197 enum lttng_event_field_value_status status;
198 const unsigned int expected = 3;
199 unsigned int i, count;
200
201 /* Unused. */
202 (void) iteration;
203
204 ret = validate_type(event_field, LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY);
205 if (ret) {
206 goto end;
207 }
208
209 status = lttng_event_field_value_array_get_length(event_field, &count);
210 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
211 fail("lttng_event_field_value_array_get_length");
212 ret = 1;
213 goto end;
214 }
215
216 ok(count == expected, "Expected %d subelements, got %d", expected,
217 count);
218 if (count != expected) {
219 ret = 1;
220 goto end;
221 }
222
223 for (i = 1; i < count + 1; i++) {
224 const struct lttng_event_field_value *value;
225
226 status = lttng_event_field_value_array_get_element_at_index(
227 event_field, i - 1, &value);
228 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
229 fail("lttng_event_field_value_array_get_element_at_index returned an error: status = %d",
230 (int) status);
231 ret = 1;
232 goto end;
233 }
234
235 ret = validate_unsigned_int_field(value, i);
236 if (ret) {
237 goto end;
238 }
239 }
240
241 ret = 0;
242 end:
243
244 return ret;
245 }
246
247 static int validate_array_unsigned_int_field_at_index(
248 const struct lttng_event_field_value *event_field,
249 unsigned int iteration)
250 {
251 int ret;
252 const uint64_t expected_value = 2;
253 enum lttng_event_field_value_status status;
254 uint64_t value;
255
256 /* Unused. */
257 (void) iteration;
258
259 ret = validate_type(
260 event_field, LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT);
261 if (ret) {
262 goto end;
263 }
264
265 status = lttng_event_field_value_unsigned_int_get_value(
266 event_field, &value);
267 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
268 fail("lttng_event_field_value_unsigned_int_get_value returned an error: status = %d",
269 (int) status);
270 ret = 1;
271 goto end;
272 }
273
274 ok(value == expected_value,
275 "Expected unsigned integer value %" PRIu64 ", got %" PRIu64,
276 expected_value, value);
277
278 ret = 0;
279 end:
280 return ret;
281 }
282
283 /*
284 * Validate sequence for a string (seqfield1):
285 *
286 * Value: "test" encoded in UTF-8: [116, 101, 115, 116]
287 */
288 static int validate_seqfield1(const struct lttng_event_field_value *event_field,
289 unsigned int iteration)
290 {
291 int ret;
292 enum lttng_event_field_value_status status;
293 unsigned int i, count;
294 const unsigned int expect[] = {116, 101, 115, 116};
295 const size_t array_count = sizeof(expect) / sizeof(*expect);
296
297 /* Unused. */
298 (void) iteration;
299
300 ret = validate_type(event_field, LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY);
301 if (ret) {
302 goto end;
303 }
304
305 status = lttng_event_field_value_array_get_length(event_field, &count);
306 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
307 fail("lttng_event_field_value_array_get_length returned an error: status = %d",
308 (int) status);
309 ret = 1;
310 goto end;
311 }
312
313 ok(count == array_count, "Expected %zu array sub-elements, got %d",
314 array_count, count);
315 if (count != array_count) {
316 ret = 1;
317 goto end;
318 }
319
320 for (i = 0; i < count; i++) {
321 const struct lttng_event_field_value *value;
322
323 status = lttng_event_field_value_array_get_element_at_index(
324 event_field, i, &value);
325 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
326 fail("lttng_event_field_value_array_get_element_at_index returned an error: status = %d",
327 (int) status);
328 ret = 1;
329 goto end;
330 }
331
332 ret = validate_unsigned_int_field(value, expect[i]);
333 if (ret) {
334 goto end;
335 }
336 }
337
338 ret = 0;
339 end:
340 return ret;
341 }
342
343 static int validate_string(
344 const struct lttng_event_field_value *event_field,
345 const char *expect)
346 {
347 int ret;
348 const char *value = NULL;
349 enum lttng_event_field_value_status status;
350
351 ret = validate_type(event_field, LTTNG_EVENT_FIELD_VALUE_TYPE_STRING);
352 if (ret) {
353 goto end;
354 }
355
356 status = lttng_event_field_value_string_get_value(event_field, &value);
357 if (!value) {
358 fail("lttng_event_field_value_array_get_length returned an error: status = %d",
359 (int) status);
360 ret = 1;
361 goto end;
362 }
363
364 ok(!strcmp(value, expect), "Expected string value \"%s\", got \"%s\"",
365 expect, value);
366
367 ret = 0;
368 end:
369
370 return ret;
371 }
372
373 /*
374 * Validate string. Expected value is "test".
375 */
376 static int validate_string_test(
377 const struct lttng_event_field_value *event_field,
378 unsigned int iteration)
379 {
380 const char * const expect = "test";
381
382 /* Unused. */
383 (void) iteration;
384
385 return validate_string(event_field, expect);
386 }
387
388 /*
389 * Validate escaped string. Expected value is "\*".
390 */
391 static int validate_string_escaped(
392 const struct lttng_event_field_value *event_field,
393 unsigned int iteration)
394 {
395 const char * const expect = "\\*";
396
397 /* Unused. */
398 (void) iteration;
399
400 return validate_string(event_field, expect);
401 }
402
403 /*
404 * Validate real field.
405 */
406 static int validate_real(
407 const struct lttng_event_field_value *event_field,
408 double expect)
409 {
410 int ret;
411 double value;
412 enum lttng_event_field_value_status status;
413
414 ret = validate_type(event_field, LTTNG_EVENT_FIELD_VALUE_TYPE_REAL);
415 if (ret) {
416 goto end;
417 }
418
419 status = lttng_event_field_value_real_get_value(event_field, &value);
420 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
421 fail("lttng_event_field_value_real_get_value returned an error: status = %d",
422 (int) status);
423 ret = 1;
424 goto end;
425 }
426
427 ok(value == expect, "Expected real value %f, got %f", expect, value);
428 ret = value != expect;
429 end:
430 return ret;
431 }
432
433 /*
434 * Validate floatfield.
435 */
436 static int validate_floatfield(
437 const struct lttng_event_field_value *event_field,
438 unsigned int iteration)
439 {
440 const double expect = 2222.0;
441
442 /* Unused. */
443 (void) iteration;
444
445 return validate_real(event_field, expect);
446 }
447
448 /*
449 * Validate doublefield.
450 */
451 static int validate_doublefield(
452 const struct lttng_event_field_value *event_field,
453 unsigned int iteration)
454 {
455 const double expect = 2.0;
456
457 /* Unused. */
458 (void) iteration;
459
460 return validate_real(event_field, expect);
461 }
462
463 /*
464 * Validate enum0: enum0 = ( "AUTO: EXPECT 0" : container = 0 )
465 */
466 static int validate_enum0(const struct lttng_event_field_value *event_field,
467 unsigned int iteration)
468 {
469 int ret;
470 enum lttng_event_field_value_status status;
471 uint64_t value;
472 const uint64_t expected_value = 0;
473
474 /* Unused. */
475 (void) iteration;
476
477 ret = validate_type(event_field,
478 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM);
479 if (ret) {
480 goto end;
481 }
482
483 status = lttng_event_field_value_unsigned_int_get_value(
484 event_field, &value);
485 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
486 fail("lttng_event_field_value_unsigned_int_get_value returned an error: status = %d",
487 (int) status);
488 ret = 1;
489 goto end;
490 }
491
492 ok(value == expected_value,
493 "Expected enum value %" PRIu64 ", got %" PRIu64,
494 expected_value, value);
495
496 end:
497 return ret;
498 }
499
500 /*
501 * Validate enumnegative: enumnegative = ( "AUTO: EXPECT 0" : container = 0 )
502 *
503 * We expect 2 labels here.
504 */
505 static int validate_enumnegative(
506 const struct lttng_event_field_value *event_field,
507 unsigned int iteration)
508 {
509 int ret;
510 enum lttng_event_field_value_status status;
511 int64_t value;
512 const int64_t expected_value = -1;
513
514 /* Unused. */
515 (void) iteration;
516
517 ret = validate_type(event_field,
518 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM);
519 if (ret) {
520 goto end;
521 }
522
523 status = lttng_event_field_value_signed_int_get_value(
524 event_field, &value);
525 if (status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
526 fail("lttng_event_field_value_unsigned_int_get_value");
527 ret = 1;
528 goto end;
529 }
530
531 ok(value == expected_value,
532 "Expected enum value %" PRId64 ", got %" PRId64,
533 expected_value, value);
534
535 end:
536 return ret;
537 }
538
539 static int validate_context_procname_ust(
540 const struct lttng_event_field_value *event_field,
541 unsigned int iteration)
542 {
543 /* Unused. */
544 (void) iteration;
545 return validate_string(event_field, "gen-ust-events");
546 }
547
548 static int validate_context_procname_kernel(
549 const struct lttng_event_field_value *event_field,
550 unsigned int iteration)
551 {
552 /* Unused. */
553 (void) iteration;
554 return validate_string(event_field, "echo");
555 }
556
557 struct capture_base_field_tuple test_capture_base_fields[] = {
558 { "DOESNOTEXIST", FIELD_TYPE_PAYLOAD, false, false, NULL, NULL },
559 { "intfield", FIELD_TYPE_PAYLOAD, true, true, validate_unsigned_int_field, validate_unsigned_int_field },
560 { "longfield", FIELD_TYPE_PAYLOAD, true, true, validate_unsigned_int_field, validate_unsigned_int_field },
561 { "signedfield", FIELD_TYPE_PAYLOAD, true, true, validate_signed_int_field, validate_signed_int_field },
562 { "arrfield1", FIELD_TYPE_PAYLOAD, true, true, validate_array_unsigned_int_field, validate_array_unsigned_int_field },
563 { "arrfield2", FIELD_TYPE_PAYLOAD, true, true, validate_string_test, validate_string_test },
564 { "arrfield3", FIELD_TYPE_PAYLOAD, true, true, validate_array_unsigned_int_field, validate_array_unsigned_int_field },
565 { "seqfield1", FIELD_TYPE_PAYLOAD, true, true, validate_seqfield1, validate_seqfield1 },
566 { "seqfield2", FIELD_TYPE_PAYLOAD, true, true, validate_string_test, validate_string_test },
567 { "seqfield3", FIELD_TYPE_PAYLOAD, true, true, validate_array_unsigned_int_field, validate_array_unsigned_int_field },
568 { "seqfield4", FIELD_TYPE_PAYLOAD, true, true, validate_array_unsigned_int_field, validate_array_unsigned_int_field },
569 { "arrfield1[1]", FIELD_TYPE_ARRAY_FIELD, true, true, validate_array_unsigned_int_field_at_index, validate_array_unsigned_int_field_at_index },
570 { "stringfield", FIELD_TYPE_PAYLOAD, true, true, validate_string_test, validate_string_test },
571 { "stringfield2", FIELD_TYPE_PAYLOAD, true, true, validate_string_escaped, validate_string_escaped },
572 { "floatfield", FIELD_TYPE_PAYLOAD, true, false, validate_floatfield, validate_floatfield },
573 { "doublefield", FIELD_TYPE_PAYLOAD, true, false, validate_doublefield, validate_doublefield },
574 { "enum0", FIELD_TYPE_PAYLOAD, true, true, validate_enum0, validate_enum0 },
575 { "enumnegative", FIELD_TYPE_PAYLOAD, true, true, validate_enumnegative, validate_enumnegative },
576 { "$ctx.procname", FIELD_TYPE_CONTEXT, true, true, validate_context_procname_ust, validate_context_procname_kernel },
577 };
578
579 static const char *get_notification_trigger_name(
580 struct lttng_notification *notification)
581 {
582 const char *trigger_name = NULL;
583 enum lttng_trigger_status trigger_status;
584 const struct lttng_trigger *trigger;
585
586 trigger = lttng_notification_get_trigger(notification);
587 if (!trigger) {
588 fail("Failed to get trigger from notification");
589 goto end;
590 }
591
592 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
593 switch (trigger_status) {
594 case LTTNG_TRIGGER_STATUS_OK:
595 break;
596 case LTTNG_TRIGGER_STATUS_UNSET:
597 trigger_name = "(anonymous)";
598 break;
599 default:
600 fail("Failed to get name from notification's trigger");
601 goto end;
602 }
603
604 end:
605 return trigger_name;
606 }
607
608 static int validator_notification_trigger_name(
609 struct lttng_notification *notification,
610 const char *trigger_name)
611 {
612 int ret;
613 bool name_is_equal;
614 const char *name;
615
616 LTTNG_ASSERT(notification);
617 LTTNG_ASSERT(trigger_name);
618
619 name = get_notification_trigger_name(notification);
620 if (name == NULL) {
621 ret = 1;
622 goto end;
623 }
624
625 name_is_equal = (strcmp(trigger_name, name) == 0);
626 ok(name_is_equal, "Expected trigger name: %s got %s", trigger_name,
627 name);
628
629 ret = !name_is_equal;
630
631 end:
632 return ret;
633 }
634
635 static
636 void wait_on_file(const char *path, bool file_exist)
637 {
638 if (!path) {
639 return;
640 }
641 for (;;) {
642 int ret;
643 struct stat buf;
644
645 ret = stat(path, &buf);
646 if (ret == -1 && errno == ENOENT) {
647 if (file_exist) {
648 /*
649 * The file does not exist. wait a bit and
650 * continue looping until it does.
651 */
652 (void) poll(NULL, 0, 10);
653 continue;
654 }
655
656 /*
657 * File does not exist and the exit condition we want.
658 * Break from the loop and return.
659 */
660 break;
661 }
662 if (ret) {
663 perror("stat");
664 exit(EXIT_FAILURE);
665 }
666 /*
667 * stat() returned 0, so the file exists. break now only if
668 * that's the exit condition we want.
669 */
670 if (file_exist) {
671 break;
672 }
673 }
674 }
675
676 static
677 int write_pipe(const char *path, uint8_t data)
678 {
679 int ret = 0;
680 int fd = 0;
681
682 fd = open(path, O_WRONLY | O_NONBLOCK);
683 if (fd < 0) {
684 perror("Could not open consumer control named pipe");
685 goto end;
686 }
687
688 ret = write(fd, &data , sizeof(data));
689 if (ret < 1) {
690 perror("Named pipe write failed");
691 if (close(fd)) {
692 perror("Named pipe close failed");
693 }
694 ret = -1;
695 goto end;
696 }
697
698 ret = close(fd);
699 if (ret < 0) {
700 perror("Name pipe closing failed");
701 ret = -1;
702 goto end;
703 }
704 end:
705 return ret;
706 }
707
708 static
709 int stop_consumer(const char **argv)
710 {
711 int ret = 0, i;
712
713 for (i = named_pipe_args_start; i < nb_args; i++) {
714 ret = write_pipe(argv[i], 49);
715 }
716 return ret;
717 }
718
719 static
720 int resume_consumer(const char **argv)
721 {
722 int ret = 0, i;
723
724 for (i = named_pipe_args_start; i < nb_args; i++) {
725 ret = write_pipe(argv[i], 0);
726 }
727 return ret;
728 }
729
730 static
731 int suspend_application(void)
732 {
733 int ret;
734 struct stat buf;
735
736 if (!stat(app_state_file, &buf)) {
737 fail("App is already in a suspended state.");
738 ret = -1;
739 goto error;
740 }
741
742 /*
743 * Send SIGUSR1 to application instructing it to bypass tracepoint.
744 */
745 LTTNG_ASSERT(app_pid > 1);
746
747 ret = kill(app_pid, SIGUSR1);
748 if (ret) {
749 fail("SIGUSR1 failed. errno %d", errno);
750 ret = -1;
751 goto error;
752 }
753
754 wait_on_file(app_state_file, true);
755
756 error:
757 return ret;
758
759 }
760
761 static
762 int resume_application(void)
763 {
764 int ret;
765 struct stat buf;
766
767 ret = stat(app_state_file, &buf);
768 if (ret == -1 && errno == ENOENT) {
769 fail("State file does not exist");
770 goto error;
771 }
772 if (ret) {
773 perror("stat");
774 goto error;
775 }
776
777 LTTNG_ASSERT(app_pid > 1);
778
779 ret = kill(app_pid, SIGUSR1);
780 if (ret) {
781 fail("SIGUSR1 failed. errno %d", errno);
782 ret = -1;
783 goto error;
784 }
785
786 wait_on_file(app_state_file, false);
787
788 error:
789 return ret;
790
791 }
792
793
794 static
795 void test_triggers_buffer_usage_condition(const char *session_name,
796 const char *channel_name,
797 enum lttng_domain_type domain_type,
798 enum lttng_condition_type condition_type)
799 {
800 unsigned int test_vector_size = 5, i;
801 enum lttng_condition_status condition_status;
802 struct lttng_action *action;
803
804 /* Set-up */
805 action = lttng_action_notify_create();
806 if (!action) {
807 fail("Setup error on action creation");
808 goto end;
809 }
810
811 /* Test lttng_register_trigger with null value */
812 ok(lttng_register_trigger(NULL) == -LTTNG_ERR_INVALID, "Registering a NULL trigger fails as expected");
813
814 /* Test: register a trigger */
815
816 for (i = 0; i < pow(2,test_vector_size); i++) {
817 int loop_ret = 0;
818 char *test_tuple_string = NULL;
819 unsigned int mask_position = 0;
820 bool session_name_set = false;
821 bool channel_name_set = false;
822 bool threshold_ratio_set = false;
823 bool threshold_byte_set = false;
824 bool domain_type_set = false;
825
826 struct lttng_trigger *trigger = NULL;
827 struct lttng_condition *condition = NULL;
828
829 /* Create base condition */
830 switch (condition_type) {
831 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
832 condition = lttng_condition_buffer_usage_low_create();
833 break;
834 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
835 condition = lttng_condition_buffer_usage_high_create();
836 break;
837 default:
838 loop_ret = 1;
839 goto loop_end;
840 }
841
842 if (!condition) {
843 loop_ret = 1;
844 goto loop_end;
845
846 }
847
848 /* Prepare the condition for trigger registration test */
849
850 /* Set session name */
851 if ((1 << mask_position) & i) {
852 condition_status = lttng_condition_buffer_usage_set_session_name(
853 condition, session_name);
854 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
855 loop_ret = 1;
856 goto loop_end;
857 }
858 session_name_set = true;
859 }
860 mask_position++;
861
862 /* Set channel name */
863 if ((1 << mask_position) & i) {
864 condition_status = lttng_condition_buffer_usage_set_channel_name(
865 condition, channel_name);
866 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
867 loop_ret = 1;
868 goto loop_end;
869 }
870 channel_name_set = true;
871 }
872 mask_position++;
873
874 /* Set threshold ratio */
875 if ((1 << mask_position) & i) {
876 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
877 condition, 0.0);
878 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
879 loop_ret = 1;
880 goto loop_end;
881 }
882 threshold_ratio_set = true;
883 }
884 mask_position++;
885
886 /* Set threshold byte */
887 if ((1 << mask_position) & i) {
888 condition_status = lttng_condition_buffer_usage_set_threshold(
889 condition, 0);
890 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
891 loop_ret = 1;
892 goto loop_end;
893 }
894 threshold_byte_set = true;
895 }
896 mask_position++;
897
898 /* Set domain type */
899 if ((1 << mask_position) & i) {
900 condition_status = lttng_condition_buffer_usage_set_domain_type(
901 condition, LTTNG_DOMAIN_UST);
902 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
903 loop_ret = 1;
904 goto loop_end;
905 }
906 domain_type_set = true;
907 }
908
909 /* Safety check */
910 if (mask_position != test_vector_size -1) {
911 LTTNG_ASSERT("Logic error for test vector generation");
912 }
913
914 loop_ret = asprintf(&test_tuple_string, "session name %s, channel name %s, threshold ratio %s, threshold byte %s, domain type %s",
915 session_name_set ? "set" : "unset",
916 channel_name_set ? "set" : "unset",
917 threshold_ratio_set ? "set" : "unset",
918 threshold_byte_set ? "set" : "unset",
919 domain_type_set? "set" : "unset");
920 if (!test_tuple_string || loop_ret < 0) {
921 loop_ret = 1;
922 goto loop_end;
923 }
924
925 /* Create trigger */
926 trigger = lttng_trigger_create(condition, action);
927 if (!trigger) {
928 loop_ret = 1;
929 goto loop_end;
930 }
931
932 loop_ret = lttng_register_trigger(trigger);
933
934 loop_end:
935 if (loop_ret == 1) {
936 fail("Setup error occurred for tuple: %s", test_tuple_string);
937 goto loop_cleanup;
938 }
939
940 /* This combination happens three times */
941 if (session_name_set && channel_name_set
942 && (threshold_ratio_set || threshold_byte_set)
943 && domain_type_set) {
944 ok(loop_ret == 0, "Trigger is registered: %s", test_tuple_string);
945
946 /*
947 * Test that a trigger cannot be registered
948 * multiple time.
949 */
950 loop_ret = lttng_register_trigger(trigger);
951 ok(loop_ret == -LTTNG_ERR_TRIGGER_EXISTS, "Re-register trigger fails as expected: %s", test_tuple_string);
952
953 /* Test that a trigger can be unregistered */
954 loop_ret = lttng_unregister_trigger(trigger);
955 ok(loop_ret == 0, "Unregister trigger: %s", test_tuple_string);
956
957 /*
958 * Test that unregistration of a non-previously
959 * registered trigger fail.
960 */
961 loop_ret = lttng_unregister_trigger(trigger);
962 ok(loop_ret == -LTTNG_ERR_TRIGGER_NOT_FOUND, "Unregister of a non-registered trigger fails as expected: %s", test_tuple_string);
963 } else {
964 ok(loop_ret == -LTTNG_ERR_INVALID_TRIGGER, "Trigger is invalid as expected and cannot be registered: %s", test_tuple_string);
965 }
966
967 loop_cleanup:
968 free(test_tuple_string);
969 lttng_trigger_destroy(trigger);
970 lttng_condition_destroy(condition);
971 }
972
973 end:
974 lttng_action_destroy(action);
975 }
976
977 static
978 void wait_data_pending(const char *session_name)
979 {
980 int ret;
981
982 do {
983 ret = lttng_data_pending(session_name);
984 LTTNG_ASSERT(ret >= 0);
985 } while (ret != 0);
986 }
987
988 static
989 int setup_buffer_usage_condition(struct lttng_condition *condition,
990 const char *condition_name,
991 const char *session_name,
992 const char *channel_name,
993 const enum lttng_domain_type domain_type)
994 {
995 enum lttng_condition_status condition_status;
996 int ret = 0;
997
998 condition_status = lttng_condition_buffer_usage_set_session_name(
999 condition, session_name);
1000 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1001 fail("Failed to set session name on creation of condition `%s`",
1002 condition_name);
1003 ret = -1;
1004 goto end;
1005 }
1006
1007 condition_status = lttng_condition_buffer_usage_set_channel_name(
1008 condition, channel_name);
1009 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1010 fail("Failed to set channel name on creation of condition `%s`",
1011 condition_name);
1012 ret = -1;
1013 goto end;
1014 }
1015
1016 condition_status = lttng_condition_buffer_usage_set_domain_type(
1017 condition, domain_type);
1018 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1019 fail("Failed to set domain type on creation of condition `%s`",
1020 condition_name);
1021 ret = -1;
1022 goto end;
1023 }
1024
1025 end:
1026 return ret;
1027 }
1028
1029 static
1030 void test_invalid_channel_subscription(
1031 const enum lttng_domain_type domain_type)
1032 {
1033 enum lttng_condition_status condition_status;
1034 enum lttng_notification_channel_status nc_status;
1035 struct lttng_condition *dummy_condition = NULL;
1036 struct lttng_condition *dummy_invalid_condition = NULL;
1037 struct lttng_notification_channel *notification_channel = NULL;
1038 int ret = 0;
1039
1040 notification_channel = lttng_notification_channel_create(
1041 lttng_session_daemon_notification_endpoint);
1042 ok(notification_channel, "Notification channel object creation");
1043 if (!notification_channel) {
1044 goto end;
1045 }
1046
1047 /*
1048 * Create a dummy, empty (thus invalid) condition to test error paths.
1049 */
1050 dummy_invalid_condition = lttng_condition_buffer_usage_low_create();
1051 if (!dummy_invalid_condition) {
1052 fail("Setup error on condition creation");
1053 goto end;
1054 }
1055
1056 /*
1057 * Test subscription and unsubscription of an invalid condition to/from
1058 * a channel.
1059 */
1060 nc_status = lttng_notification_channel_subscribe(
1061 notification_channel, dummy_invalid_condition);
1062 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1063 "Subscribing to an invalid condition");
1064
1065 nc_status = lttng_notification_channel_unsubscribe(
1066 notification_channel, dummy_invalid_condition);
1067 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1068 "Unsubscribing from an invalid condition");
1069
1070 /* Create a valid dummy condition with a ratio of 0.5 */
1071 dummy_condition = lttng_condition_buffer_usage_low_create();
1072 if (!dummy_condition) {
1073 fail("Setup error on dummy_condition creation");
1074 goto end;
1075 }
1076
1077 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
1078 dummy_condition, 0.5);
1079 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1080 fail("Setup error on condition creation");
1081 goto end;
1082 }
1083
1084 ret = setup_buffer_usage_condition(dummy_condition, "dummy_condition",
1085 "dummy_session", "dummy_channel", domain_type);
1086 if (ret) {
1087 fail("Setup error on dummy condition creation");
1088 goto end;
1089 }
1090
1091 /*
1092 * Test subscription and unsubscription to/from a channel with invalid
1093 * parameters.
1094 */
1095 nc_status = lttng_notification_channel_subscribe(NULL, NULL);
1096 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1097 "Notification channel subscription is invalid: NULL, NULL");
1098
1099 nc_status = lttng_notification_channel_subscribe(
1100 notification_channel, NULL);
1101 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1102 "Notification channel subscription is invalid: NON-NULL, NULL");
1103
1104 nc_status = lttng_notification_channel_subscribe(NULL, dummy_condition);
1105 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1106 "Notification channel subscription is invalid: NULL, NON-NULL");
1107
1108 nc_status = lttng_notification_channel_unsubscribe(
1109 notification_channel, dummy_condition);
1110 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_UNKNOWN_CONDITION,
1111 "Unsubscribing from a valid unknown condition");
1112
1113 end:
1114 lttng_notification_channel_destroy(notification_channel);
1115 lttng_condition_destroy(dummy_invalid_condition);
1116 lttng_condition_destroy(dummy_condition);
1117 return;
1118 }
1119
1120 enum buffer_usage_type {
1121 BUFFER_USAGE_TYPE_LOW,
1122 BUFFER_USAGE_TYPE_HIGH,
1123 };
1124
1125 static int register_buffer_usage_notify_trigger(const char *session_name,
1126 const char *channel_name,
1127 const enum lttng_domain_type domain_type,
1128 enum buffer_usage_type buffer_usage_type,
1129 double ratio,
1130 struct lttng_condition **condition,
1131 struct lttng_action **action,
1132 struct lttng_trigger **trigger)
1133 {
1134 enum lttng_condition_status condition_status;
1135 struct lttng_action *tmp_action = NULL;
1136 struct lttng_condition *tmp_condition = NULL;
1137 struct lttng_trigger *tmp_trigger = NULL;
1138 int ret = 0;
1139
1140 /* Set-up */
1141 tmp_action = lttng_action_notify_create();
1142 if (!action) {
1143 fail("Setup error on action creation");
1144 ret = -1;
1145 goto error;
1146 }
1147
1148 if (buffer_usage_type == BUFFER_USAGE_TYPE_LOW) {
1149 tmp_condition = lttng_condition_buffer_usage_low_create();
1150 } else {
1151 tmp_condition = lttng_condition_buffer_usage_high_create();
1152 }
1153
1154 if (!tmp_condition) {
1155 fail("Setup error on condition creation");
1156 ret = -1;
1157 goto error;
1158 }
1159
1160 /* Set the buffer usage threashold */
1161 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
1162 tmp_condition, ratio);
1163 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1164 fail("Setup error on condition creation");
1165 ret = -1;
1166 goto error;
1167 }
1168
1169 ret = setup_buffer_usage_condition(tmp_condition, "condition_name",
1170 session_name, channel_name, domain_type);
1171 if (ret) {
1172 fail("Setup error on condition creation");
1173 ret = -1;
1174 goto error;
1175 }
1176
1177 /* Register the trigger for condition. */
1178 tmp_trigger = lttng_trigger_create(tmp_condition, tmp_action);
1179 if (!tmp_trigger) {
1180 fail("Setup error on trigger creation");
1181 ret = -1;
1182 goto error;
1183 }
1184
1185 ret = lttng_register_trigger(tmp_trigger);
1186 if (ret) {
1187 fail("Setup error on trigger registration");
1188 ret = -1;
1189 goto error;
1190 }
1191
1192 *condition = tmp_condition;
1193 *trigger = tmp_trigger;
1194 *action = tmp_action;
1195 goto end;
1196
1197 error:
1198 lttng_action_destroy(tmp_action);
1199 lttng_condition_destroy(tmp_condition);
1200 lttng_trigger_destroy(tmp_trigger);
1201
1202 end:
1203 return ret;
1204 }
1205
1206 static void test_subscription_twice(const char *session_name,
1207 const char *channel_name,
1208 const enum lttng_domain_type domain_type)
1209 {
1210 int ret = 0;
1211 enum lttng_notification_channel_status nc_status;
1212
1213 struct lttng_action *action = NULL;
1214 struct lttng_notification_channel *notification_channel = NULL;
1215 struct lttng_trigger *trigger = NULL;
1216
1217 struct lttng_condition *condition = NULL;
1218
1219 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
1220 domain_type, BUFFER_USAGE_TYPE_LOW, 0.99, &condition,
1221 &action, &trigger);
1222 if (ret) {
1223 fail("Setup error on trigger registration in %s()",
1224 __FUNCTION__);
1225 goto end;
1226 }
1227
1228 /* Begin testing. */
1229 notification_channel = lttng_notification_channel_create(
1230 lttng_session_daemon_notification_endpoint);
1231 ok(notification_channel, "Notification channel object creation");
1232 if (!notification_channel) {
1233 goto end;
1234 }
1235
1236 /* Subscribe a valid condition. */
1237 nc_status = lttng_notification_channel_subscribe(
1238 notification_channel, condition);
1239 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1240 "Subscribe to condition");
1241
1242 /* Subscribing again should fail. */
1243 nc_status = lttng_notification_channel_subscribe(
1244 notification_channel, condition);
1245 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED,
1246 "Subscribe to a condition for which subscription was already done");
1247
1248 end:
1249 ret = lttng_unregister_trigger(trigger);
1250 if (ret) {
1251 fail("Failed to unregister trigger in %s()", __FUNCTION__);
1252 }
1253
1254 lttng_trigger_destroy(trigger);
1255 lttng_notification_channel_destroy(notification_channel);
1256 lttng_action_destroy(action);
1257 lttng_condition_destroy(condition);
1258 }
1259
1260 static void test_buffer_usage_notification_channel(const char *session_name,
1261 const char *channel_name,
1262 const enum lttng_domain_type domain_type,
1263 const char **argv)
1264 {
1265 int ret = 0;
1266 enum lttng_notification_channel_status nc_status;
1267
1268 struct lttng_action *low_action = NULL;
1269 struct lttng_action *high_action = NULL;
1270 struct lttng_notification *notification = NULL;
1271 struct lttng_notification_channel *notification_channel = NULL;
1272 struct lttng_trigger *low_trigger = NULL;
1273 struct lttng_trigger *high_trigger = NULL;
1274
1275 struct lttng_condition *low_condition = NULL;
1276 struct lttng_condition *high_condition = NULL;
1277
1278 const double low_ratio = 0.0;
1279 const double high_ratio = 0.90;
1280
1281 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
1282 domain_type, BUFFER_USAGE_TYPE_LOW, low_ratio,
1283 &low_condition, &low_action, &low_trigger);
1284 if (ret) {
1285 fail("Setup error on low trigger registration");
1286 goto end;
1287 }
1288
1289 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
1290 domain_type, BUFFER_USAGE_TYPE_HIGH, high_ratio,
1291 &high_condition, &high_action, &high_trigger);
1292 if (ret) {
1293 fail("Setup error on high trigger registration");
1294 goto end;
1295 }
1296
1297 /* Begin testing */
1298 notification_channel = lttng_notification_channel_create(
1299 lttng_session_daemon_notification_endpoint);
1300 ok(notification_channel, "Notification channel object creation");
1301 if (!notification_channel) {
1302 goto end;
1303 }
1304
1305 /* Subscribe a valid low condition */
1306 nc_status = lttng_notification_channel_subscribe(
1307 notification_channel, low_condition);
1308 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1309 "Subscribe to low condition");
1310
1311 /* Subscribe a valid high condition */
1312 nc_status = lttng_notification_channel_subscribe(
1313 notification_channel, high_condition);
1314 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1315 "Subscribe to high condition");
1316
1317 resume_application();
1318
1319 /* Wait for notification to happen */
1320 stop_consumer(argv);
1321 lttng_start_tracing(session_name);
1322
1323 /* Wait for high notification */
1324 do {
1325 nc_status = lttng_notification_channel_get_next_notification(
1326 notification_channel, &notification);
1327 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
1328 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
1329 lttng_condition_get_type(lttng_notification_get_condition(
1330 notification)) ==
1331 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
1332 "High notification received after intermediary communication");
1333 lttng_notification_destroy(notification);
1334 notification = NULL;
1335
1336 suspend_application();
1337 lttng_stop_tracing_no_wait(session_name);
1338 resume_consumer(argv);
1339 wait_data_pending(session_name);
1340
1341 /*
1342 * Test that communication still work even if there is notification
1343 * waiting for consumption.
1344 */
1345
1346 nc_status = lttng_notification_channel_unsubscribe(
1347 notification_channel, low_condition);
1348 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1349 "Unsubscribe with pending notification");
1350
1351 nc_status = lttng_notification_channel_subscribe(
1352 notification_channel, low_condition);
1353 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1354 "Subscribe with pending notification");
1355
1356 do {
1357 nc_status = lttng_notification_channel_get_next_notification(
1358 notification_channel, &notification);
1359 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
1360 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
1361 lttng_condition_get_type(lttng_notification_get_condition(
1362 notification)) ==
1363 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW,
1364 "Low notification received after intermediary communication");
1365 lttng_notification_destroy(notification);
1366 notification = NULL;
1367
1368 /* Stop consumer to force a high notification */
1369 stop_consumer(argv);
1370 resume_application();
1371 lttng_start_tracing(session_name);
1372
1373 do {
1374 nc_status = lttng_notification_channel_get_next_notification(
1375 notification_channel, &notification);
1376 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
1377 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
1378 lttng_condition_get_type(lttng_notification_get_condition(
1379 notification)) ==
1380 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
1381 "High notification received after intermediary communication");
1382 lttng_notification_destroy(notification);
1383 notification = NULL;
1384
1385 suspend_application();
1386 lttng_stop_tracing_no_wait(session_name);
1387 resume_consumer(argv);
1388 wait_data_pending(session_name);
1389
1390 do {
1391 nc_status = lttng_notification_channel_get_next_notification(
1392 notification_channel, &notification);
1393 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
1394 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
1395 lttng_condition_get_type(lttng_notification_get_condition(
1396 notification)) ==
1397 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW,
1398 "Low notification received after re-subscription");
1399 lttng_notification_destroy(notification);
1400 notification = NULL;
1401
1402 stop_consumer(argv);
1403 resume_application();
1404 /* Stop consumer to force a high notification */
1405 lttng_start_tracing(session_name);
1406
1407 do {
1408 nc_status = lttng_notification_channel_get_next_notification(
1409 notification_channel, &notification);
1410 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
1411 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
1412 lttng_condition_get_type(lttng_notification_get_condition(
1413 notification)) ==
1414 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
1415 "High notification");
1416 lttng_notification_destroy(notification);
1417 notification = NULL;
1418
1419 suspend_application();
1420
1421 /* Resume consumer to allow event consumption */
1422 lttng_stop_tracing_no_wait(session_name);
1423 resume_consumer(argv);
1424 wait_data_pending(session_name);
1425
1426 nc_status = lttng_notification_channel_unsubscribe(
1427 notification_channel, low_condition);
1428 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1429 "Unsubscribe low condition with pending notification");
1430
1431 nc_status = lttng_notification_channel_unsubscribe(
1432 notification_channel, high_condition);
1433 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1434 "Unsubscribe high condition with pending notification");
1435
1436 end:
1437 lttng_notification_channel_destroy(notification_channel);
1438 lttng_trigger_destroy(low_trigger);
1439 lttng_trigger_destroy(high_trigger);
1440 lttng_action_destroy(low_action);
1441 lttng_action_destroy(high_action);
1442 lttng_condition_destroy(low_condition);
1443 lttng_condition_destroy(high_condition);
1444 }
1445
1446 static void create_tracepoint_event_rule_trigger(const char *event_pattern,
1447 const char *trigger_name,
1448 const char *filter,
1449 unsigned int exclusion_count,
1450 const char * const *exclusions,
1451 enum lttng_domain_type domain_type,
1452 condition_capture_desc_cb capture_desc_cb,
1453 struct lttng_condition **condition,
1454 struct lttng_trigger **trigger)
1455 {
1456 typedef struct lttng_event_rule *(*event_rule_create)(void);
1457 typedef enum lttng_event_rule_status (
1458 *event_rule_set_name_pattern)(
1459 struct lttng_event_rule *rule,
1460 const char *pattern);
1461 typedef enum lttng_event_rule_status (*event_rule_set_filter)(
1462 struct lttng_event_rule *rule,
1463 const char *expression);
1464 typedef enum lttng_event_rule_status (
1465 *event_rule_add_name_pattern_exclusion)(
1466 struct lttng_event_rule * rule, const char *exclusion);
1467
1468 enum lttng_event_rule_status event_rule_status;
1469 struct lttng_action *tmp_action = NULL;
1470 struct lttng_event_rule *event_rule = NULL;
1471 struct lttng_condition *tmp_condition = NULL;
1472 struct lttng_trigger *tmp_trigger = NULL;
1473 int ret;
1474 enum lttng_error_code ret_code;
1475 event_rule_create create;
1476 event_rule_set_name_pattern set_name_pattern;
1477 event_rule_set_filter set_filter;
1478 event_rule_add_name_pattern_exclusion add_name_pattern_exclusion;
1479
1480 LTTNG_ASSERT(event_pattern);
1481 LTTNG_ASSERT(trigger_name);
1482 LTTNG_ASSERT(condition);
1483 LTTNG_ASSERT(trigger);
1484
1485 /* Set the function pointers based on the domain type. */
1486 switch (domain_type) {
1487 case LTTNG_DOMAIN_UST:
1488 create = lttng_event_rule_user_tracepoint_create;
1489 set_name_pattern = lttng_event_rule_user_tracepoint_set_name_pattern;
1490 set_filter = lttng_event_rule_user_tracepoint_set_filter;
1491 add_name_pattern_exclusion = lttng_event_rule_user_tracepoint_add_name_pattern_exclusion;
1492 break;
1493 case LTTNG_DOMAIN_KERNEL:
1494 create = lttng_event_rule_kernel_tracepoint_create;
1495 set_name_pattern = lttng_event_rule_kernel_tracepoint_set_name_pattern;
1496 set_filter = lttng_event_rule_kernel_tracepoint_set_filter;
1497 add_name_pattern_exclusion = NULL;
1498 break;
1499 default:
1500 abort();
1501 break;
1502 }
1503
1504 event_rule = create();
1505 ok(event_rule, "Tracepoint event rule object creation");
1506
1507 event_rule_status = set_name_pattern(event_rule, event_pattern);
1508 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1509 "Setting tracepoint event rule pattern: '%s'",
1510 event_pattern);
1511
1512 if (filter) {
1513 event_rule_status = set_filter(event_rule, filter);
1514 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1515 "Setting tracepoint event rule filter: '%s'",
1516 filter);
1517 }
1518
1519 if (exclusions) {
1520 int i;
1521 bool success = true;
1522
1523 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_UST);
1524 LTTNG_ASSERT(add_name_pattern_exclusion != NULL);
1525 LTTNG_ASSERT(exclusion_count > 0);
1526
1527 for (i = 0; i < exclusion_count; i++) {
1528 event_rule_status = add_name_pattern_exclusion(
1529 event_rule, exclusions[i]);
1530 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
1531 fail("Setting tracepoint event rule exclusion '%s'.",
1532 exclusions[i]);
1533 success = false;
1534 }
1535 }
1536
1537 ok(success, "Setting tracepoint event rule exclusions");
1538 }
1539
1540 tmp_condition = lttng_condition_event_rule_matches_create(event_rule);
1541 ok(tmp_condition, "Condition event rule object creation");
1542
1543 if (capture_desc_cb) {
1544 ret = capture_desc_cb(tmp_condition);
1545 if (ret) {
1546 fail("Failed to generate the condition capture descriptor");
1547 abort();
1548 }
1549 }
1550
1551 tmp_action = lttng_action_notify_create();
1552 ok(tmp_action, "Action event rule object creation");
1553
1554 tmp_trigger = lttng_trigger_create(tmp_condition, tmp_action);
1555 ok(tmp_trigger, "Trigger object creation %s", trigger_name);
1556
1557 ret_code = lttng_register_trigger_with_name(tmp_trigger, trigger_name);
1558 ok(ret_code == LTTNG_OK, "Trigger registration %s", trigger_name);
1559
1560 lttng_event_rule_destroy(event_rule);
1561
1562 *condition = tmp_condition;
1563 *trigger = tmp_trigger;
1564
1565 return;
1566 }
1567
1568 static struct lttng_notification *get_next_notification(
1569 struct lttng_notification_channel *notification_channel)
1570 {
1571 struct lttng_notification *local_notification = NULL;
1572 enum lttng_notification_channel_status status;
1573
1574 /* Receive the next notification. */
1575 status = lttng_notification_channel_get_next_notification(
1576 notification_channel, &local_notification);
1577
1578 switch (status) {
1579 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
1580 break;
1581 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
1582 fail("Notifications have been dropped");
1583 local_notification = NULL;
1584 break;
1585 default:
1586 /* Unhandled conditions / errors. */
1587 fail("Failed to get next notification (unknown notification channel status): status = %d",
1588 (int) status);
1589 local_notification = NULL;
1590 break;
1591 }
1592
1593 return local_notification;
1594 }
1595
1596 static void test_tracepoint_event_rule_notification(
1597 enum lttng_domain_type domain_type)
1598 {
1599 int i;
1600 int ret;
1601 const int notification_count = 3;
1602 enum lttng_notification_channel_status nc_status;
1603 struct lttng_action *action = NULL;
1604 struct lttng_condition *condition = NULL;
1605 struct lttng_notification_channel *notification_channel = NULL;
1606 struct lttng_trigger *trigger = NULL;
1607 const char * const trigger_name = "my_precious";
1608 const char *pattern;
1609
1610 if (domain_type == LTTNG_DOMAIN_UST) {
1611 pattern = "tp:tptest";
1612 } else {
1613 pattern = "lttng_test_filter_event";
1614 }
1615
1616 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 0,
1617 NULL, domain_type, NULL, &condition, &trigger);
1618
1619 notification_channel = lttng_notification_channel_create(
1620 lttng_session_daemon_notification_endpoint);
1621 ok(notification_channel, "Notification channel object creation");
1622
1623 nc_status = lttng_notification_channel_subscribe(
1624 notification_channel, condition);
1625 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1626 "Subscribe to tracepoint event rule condition");
1627
1628 resume_application();
1629
1630 /* Get notifications. */
1631 for (i = 0; i < notification_count; i++) {
1632 struct lttng_notification *notification = get_next_notification(
1633 notification_channel);
1634
1635 ok(notification, "Received notification (%d/%d)", i + 1,
1636 notification_count);
1637
1638 /* Error. */
1639 if (notification == NULL) {
1640 goto end;
1641 }
1642
1643 ret = validator_notification_trigger_name(notification, trigger_name);
1644 lttng_notification_destroy(notification);
1645 if (ret) {
1646 goto end;
1647 }
1648 }
1649
1650 end:
1651 suspend_application();
1652 lttng_notification_channel_destroy(notification_channel);
1653 lttng_unregister_trigger(trigger);
1654 lttng_trigger_destroy(trigger);
1655 lttng_action_destroy(action);
1656 lttng_condition_destroy(condition);
1657 return;
1658 }
1659
1660 static void test_tracepoint_event_rule_notification_filter(
1661 enum lttng_domain_type domain_type)
1662 {
1663 int i;
1664 const int notification_count = 3;
1665 enum lttng_notification_channel_status nc_status;
1666 struct lttng_condition *ctrl_condition = NULL, *condition = NULL;
1667 struct lttng_notification_channel *notification_channel = NULL;
1668 struct lttng_trigger *ctrl_trigger = NULL, *trigger = NULL;
1669 const char * const ctrl_trigger_name = "control_trigger";
1670 const char * const trigger_name = "trigger";
1671 const char *pattern;
1672 int ctrl_count = 0, count = 0;
1673
1674 if (domain_type == LTTNG_DOMAIN_UST) {
1675 pattern = "tp:tptest";
1676 } else {
1677 pattern = "lttng_test_filter_event";
1678 }
1679
1680 notification_channel = lttng_notification_channel_create(
1681 lttng_session_daemon_notification_endpoint);
1682 ok(notification_channel, "Notification channel object creation");
1683
1684 create_tracepoint_event_rule_trigger(pattern, ctrl_trigger_name, NULL,
1685 0, NULL, domain_type, NULL, &ctrl_condition, &ctrl_trigger);
1686
1687 nc_status = lttng_notification_channel_subscribe(
1688 notification_channel, ctrl_condition);
1689 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1690 "Subscribe to tracepoint event rule condition");
1691
1692 /*
1693 * Attach a filter expression to get notification only if the
1694 * `intfield` is even.
1695 */
1696 create_tracepoint_event_rule_trigger(pattern, trigger_name,
1697 "(intfield & 1) == 0", 0, NULL, domain_type, NULL, &condition,
1698 &trigger);
1699
1700 nc_status = lttng_notification_channel_subscribe(
1701 notification_channel, condition);
1702 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1703 "Subscribe to tracepoint event rule condition");
1704
1705 /*
1706 * We registered 2 notifications triggers, one with a filter and one
1707 * without (control). The one with a filter will only fired when the
1708 * `intfield` is a multiple of 2. We should get two times as many
1709 * control notifications as filter notifications.
1710 */
1711 resume_application();
1712
1713 /*
1714 * Get 3 notifications. We should get 1 for the regular trigger (with
1715 * the filter) and 2 from the control trigger. This works whatever
1716 * the order we receive the notifications.
1717 */
1718 for (i = 0; i < notification_count; i++) {
1719 const char *name;
1720 struct lttng_notification *notification = get_next_notification(
1721 notification_channel);
1722
1723 ok(notification, "Received notification (%d/%d)", i + 1,
1724 notification_count);
1725
1726 /* Error. */
1727 if (notification == NULL) {
1728 goto end;
1729 }
1730
1731 name = get_notification_trigger_name(notification);
1732 if (name == NULL) {
1733 lttng_notification_destroy(notification);
1734 goto end;
1735 }
1736
1737 if (strcmp(ctrl_trigger_name, name) == 0) {
1738 ctrl_count++;
1739 } else if (strcmp(trigger_name, name) == 0) {
1740 count++;
1741 }
1742
1743 lttng_notification_destroy(notification);
1744 }
1745
1746 ok(ctrl_count / 2 == count,
1747 "Get twice as many control notif as of regular notif");
1748
1749 end:
1750 suspend_application();
1751
1752 lttng_unregister_trigger(trigger);
1753 lttng_unregister_trigger(ctrl_trigger);
1754 lttng_notification_channel_destroy(notification_channel);
1755 lttng_trigger_destroy(trigger);
1756 lttng_trigger_destroy(ctrl_trigger);
1757 lttng_condition_destroy(condition);
1758 lttng_condition_destroy(ctrl_condition);
1759 }
1760
1761 static void test_tracepoint_event_rule_notification_exclusion(
1762 enum lttng_domain_type domain_type)
1763 {
1764 enum lttng_notification_channel_status nc_status;
1765 struct lttng_condition *ctrl_condition = NULL, *condition = NULL;
1766 struct lttng_notification_channel *notification_channel = NULL;
1767 struct lttng_trigger *ctrl_trigger = NULL, *trigger = NULL;
1768 int ctrl_count = 0, count = 0, i;
1769 const int notification_count = 6;
1770 const char * const ctrl_trigger_name = "control_exclusion_trigger";
1771 const char * const trigger_name = "exclusion_trigger";
1772 const char * const pattern = "tp:tptest*";
1773 const char * const exclusions[] = {
1774 "tp:tptest2",
1775 "tp:tptest3",
1776 "tp:tptest4",
1777 "tp:tptest5"
1778 };
1779
1780 notification_channel = lttng_notification_channel_create(
1781 lttng_session_daemon_notification_endpoint);
1782 ok(notification_channel, "Notification channel object creation");
1783
1784 create_tracepoint_event_rule_trigger(pattern, ctrl_trigger_name, NULL,
1785 0, NULL, domain_type, NULL, &ctrl_condition,
1786 &ctrl_trigger);
1787
1788 nc_status = lttng_notification_channel_subscribe(
1789 notification_channel, ctrl_condition);
1790 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1791 "Subscribe to tracepoint event rule condition");
1792
1793 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 4,
1794 exclusions, domain_type, NULL, &condition,
1795 &trigger);
1796
1797 nc_status = lttng_notification_channel_subscribe(
1798 notification_channel, condition);
1799 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1800 "Subscribe to tracepoint event rule condition");
1801
1802 /*
1803 * We registered 2 notifications triggers, one with an exclusion and
1804 * one without (control).
1805 * - The trigger with an exclusion will fire once every iteration.
1806 * - The trigger without an exclusion will fire 5 times every
1807 * iteration.
1808 *
1809 * We should get 5 times as many notifications from the control
1810 * trigger.
1811 */
1812 resume_application();
1813
1814 /*
1815 * Get 6 notifications. We should get 1 for the regular trigger (with
1816 * the exclusion) and 5 from the control trigger. This works whatever
1817 * the order we receive the notifications.
1818 */
1819 for (i = 0; i < notification_count; i++) {
1820 const char *name;
1821 struct lttng_notification *notification = get_next_notification(
1822 notification_channel);
1823
1824 ok(notification, "Received notification (%d/%d)", i + 1,
1825 notification_count);
1826
1827 /* Error. */
1828 if (notification == NULL) {
1829 goto end;
1830 }
1831
1832 name = get_notification_trigger_name(notification);
1833 if (name == NULL) {
1834 lttng_notification_destroy(notification);
1835 goto end;
1836 }
1837
1838 if (strcmp(ctrl_trigger_name, name) == 0) {
1839 ctrl_count++;
1840 } else if (strcmp(trigger_name, name) == 0) {
1841 count++;
1842 }
1843
1844 lttng_notification_destroy(notification);
1845 }
1846
1847 ok(ctrl_count / 5 == count,
1848 "Got 5 times as many control notif as of regular notif");
1849
1850 end:
1851 suspend_application();
1852
1853 lttng_unregister_trigger(trigger);
1854 lttng_unregister_trigger(ctrl_trigger);
1855 lttng_notification_channel_destroy(notification_channel);
1856 lttng_trigger_destroy(trigger);
1857 lttng_trigger_destroy(ctrl_trigger);
1858 lttng_condition_destroy(condition);
1859 lttng_condition_destroy(ctrl_condition);
1860 return;
1861 }
1862
1863 static void test_kprobe_event_rule_notification(
1864 enum lttng_domain_type domain_type)
1865 {
1866 int i, ret;
1867 enum lttng_error_code ret_code;
1868 const int notification_count = 3;
1869 enum lttng_notification_channel_status nc_status;
1870 enum lttng_event_rule_status event_rule_status;
1871 struct lttng_notification_channel *notification_channel = NULL;
1872 struct lttng_condition *condition = NULL;
1873 struct lttng_kernel_probe_location *location = NULL;
1874 struct lttng_event_rule *event_rule = NULL;
1875 struct lttng_action *action = NULL;
1876 struct lttng_trigger *trigger = NULL;
1877 const char * const trigger_name = "kprobe_trigger";
1878 const char * const symbol_name = "lttng_test_filter_event_write";
1879
1880 action = lttng_action_notify_create();
1881 if (!action) {
1882 fail("Failed to create notify action");
1883 goto end;
1884 }
1885
1886 location = lttng_kernel_probe_location_symbol_create(symbol_name, 0);
1887 if (!location) {
1888 fail("Failed to create kernel probe location");
1889 goto end;
1890 }
1891
1892 notification_channel = lttng_notification_channel_create(
1893 lttng_session_daemon_notification_endpoint);
1894 ok(notification_channel, "Notification channel object creation");
1895
1896 event_rule = lttng_event_rule_kernel_kprobe_create(location);
1897 ok(event_rule, "kprobe event rule object creation");
1898
1899 event_rule_status = lttng_event_rule_kernel_kprobe_set_event_name(
1900 event_rule, trigger_name);
1901 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1902 "Setting kprobe event rule name: '%s'", trigger_name);
1903
1904 condition = lttng_condition_event_rule_matches_create(event_rule);
1905 ok(condition, "Condition event rule object creation");
1906
1907 /* Register the trigger for condition. */
1908 trigger = lttng_trigger_create(condition, action);
1909 if (!trigger) {
1910 fail("Failed to create trigger with kernel probe event rule condition and notify action");
1911 goto end;
1912 }
1913
1914 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
1915 if (ret_code != LTTNG_OK) {
1916 fail("Failed to register trigger with kernel probe event rule condition and notify action");
1917 goto end;
1918 }
1919
1920 nc_status = lttng_notification_channel_subscribe(
1921 notification_channel, condition);
1922 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1923 "Subscribe to tracepoint event rule condition");
1924
1925 resume_application();
1926
1927 for (i = 0; i < notification_count; i++) {
1928 struct lttng_notification *notification = get_next_notification(
1929 notification_channel);
1930
1931 ok(notification, "Received notification (%d/%d)", i + 1,
1932 notification_count);
1933
1934 /* Error. */
1935 if (notification == NULL) {
1936 goto end;
1937 }
1938
1939 ret = validator_notification_trigger_name(notification, trigger_name);
1940 lttng_notification_destroy(notification);
1941 if (ret) {
1942 goto end;
1943 }
1944 }
1945
1946 end:
1947 suspend_application();
1948 lttng_notification_channel_destroy(notification_channel);
1949 lttng_unregister_trigger(trigger);
1950 lttng_trigger_destroy(trigger);
1951 lttng_action_destroy(action);
1952 lttng_event_rule_destroy(event_rule);
1953 lttng_condition_destroy(condition);
1954 lttng_kernel_probe_location_destroy(location);
1955 return;
1956 }
1957
1958 static void test_uprobe_event_rule_notification(
1959 enum lttng_domain_type domain_type,
1960 const char *testapp_path,
1961 const char *test_symbol_name)
1962 {
1963 int i, ret;
1964 enum lttng_error_code ret_code;
1965 const int notification_count = 3;
1966 enum lttng_notification_channel_status nc_status;
1967 enum lttng_event_rule_status event_rule_status;
1968 struct lttng_notification_channel *notification_channel = NULL;
1969 struct lttng_userspace_probe_location *probe_location = NULL;
1970 struct lttng_userspace_probe_location_lookup_method *lookup_method =
1971 NULL;
1972 struct lttng_condition *condition = NULL;
1973 struct lttng_event_rule *event_rule = NULL;
1974 struct lttng_action *action = NULL;
1975 struct lttng_trigger *trigger = NULL;
1976 const char * const trigger_name = "uprobe_trigger";
1977
1978 action = lttng_action_notify_create();
1979 if (!action) {
1980 fail("Failed to create notify action");
1981 goto end;
1982 }
1983
1984 lookup_method = lttng_userspace_probe_location_lookup_method_function_elf_create();
1985 if (!lookup_method) {
1986 fail("Setup error on userspace probe lookup method creation");
1987 goto end;
1988 }
1989
1990 probe_location = lttng_userspace_probe_location_function_create(
1991 testapp_path, test_symbol_name, lookup_method);
1992 if (!probe_location) {
1993 fail("Failed to create userspace probe location");
1994 goto end;
1995 }
1996
1997 notification_channel = lttng_notification_channel_create(
1998 lttng_session_daemon_notification_endpoint);
1999 ok(notification_channel, "Notification channel object creation");
2000
2001 event_rule = lttng_event_rule_kernel_uprobe_create(probe_location);
2002 ok(event_rule, "kprobe event rule object creation");
2003
2004 event_rule_status = lttng_event_rule_kernel_uprobe_set_event_name(
2005 event_rule, trigger_name);
2006 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2007 "Setting uprobe event rule name: '%s'", trigger_name);
2008
2009 condition = lttng_condition_event_rule_matches_create(event_rule);
2010 ok(condition, "Condition event rule object creation");
2011
2012 /* Register the trigger for condition. */
2013 trigger = lttng_trigger_create(condition, action);
2014 if (!trigger) {
2015 fail("Failed to create trigger with userspace probe event rule condition and notify action");
2016 goto end;
2017 }
2018
2019 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
2020 if (ret_code != LTTNG_OK) {
2021 fail("Failed to register trigger with userspace probe event rule condition and notify action");
2022 goto end;
2023 }
2024
2025 nc_status = lttng_notification_channel_subscribe(
2026 notification_channel, condition);
2027 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2028 "Subscribe to tracepoint event rule condition");
2029
2030 resume_application();
2031
2032 for (i = 0; i < 3; i++) {
2033 struct lttng_notification *notification = get_next_notification(
2034 notification_channel);
2035
2036 ok(notification, "Received notification (%d/%d)", i + 1,
2037 notification_count);
2038
2039 /* Error. */
2040 if (notification == NULL) {
2041 goto end;
2042 }
2043
2044 ret = validator_notification_trigger_name(notification, trigger_name);
2045 lttng_notification_destroy(notification);
2046 if (ret) {
2047 goto end;
2048 }
2049 }
2050 end:
2051 suspend_application();
2052
2053 lttng_notification_channel_destroy(notification_channel);
2054 lttng_unregister_trigger(trigger);
2055 lttng_trigger_destroy(trigger);
2056 lttng_action_destroy(action);
2057 lttng_userspace_probe_location_destroy(probe_location);
2058 lttng_event_rule_destroy(event_rule);
2059 lttng_condition_destroy(condition);
2060 return;
2061 }
2062
2063 static void test_syscall_event_rule_notification(
2064 enum lttng_domain_type domain_type)
2065 {
2066 int i, ret;
2067 enum lttng_error_code ret_code;
2068 const int notification_count = 3;
2069 enum lttng_notification_channel_status nc_status;
2070 enum lttng_event_rule_status event_rule_status;
2071 struct lttng_notification_channel *notification_channel = NULL;
2072 struct lttng_condition *condition = NULL;
2073 struct lttng_event_rule *event_rule = NULL;
2074 struct lttng_action *action = NULL;
2075 struct lttng_trigger *trigger = NULL;
2076 const char * const trigger_name = "syscall_trigger";
2077 const char * const syscall_name = "openat";
2078
2079 action = lttng_action_notify_create();
2080 if (!action) {
2081 fail("Failed to create notify action");
2082 goto end;
2083 }
2084
2085 notification_channel = lttng_notification_channel_create(
2086 lttng_session_daemon_notification_endpoint);
2087 ok(notification_channel, "Notification channel object creation");
2088
2089 event_rule = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY);
2090 ok(event_rule, "syscall event rule object creation");
2091
2092 event_rule_status = lttng_event_rule_kernel_syscall_set_name_pattern(
2093 event_rule, syscall_name);
2094 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2095 "Setting syscall event rule pattern: '%s'", syscall_name);
2096
2097 condition = lttng_condition_event_rule_matches_create(event_rule);
2098 ok(condition, "Condition syscall event rule object creation");
2099
2100 /* Register the trigger for condition. */
2101 trigger = lttng_trigger_create(condition, action);
2102 if (!trigger) {
2103 fail("Failed to create trigger with syscall event rule condition and notify action");
2104 goto end;
2105 }
2106
2107 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
2108 if (ret_code != LTTNG_OK) {
2109 fail("Failed to register trigger with syscall event rule condition and notify action");
2110 goto end;
2111 }
2112
2113 nc_status = lttng_notification_channel_subscribe(
2114 notification_channel, condition);
2115 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2116 "Subscribe to tracepoint event rule condition");
2117
2118 resume_application();
2119
2120 for (i = 0; i < notification_count; i++) {
2121 struct lttng_notification *notification = get_next_notification(
2122 notification_channel);
2123
2124 ok(notification, "Received notification (%d/%d)", i + 1,
2125 notification_count);
2126
2127 /* Error. */
2128 if (notification == NULL) {
2129 goto end;
2130 }
2131
2132 ret = validator_notification_trigger_name(notification, trigger_name);
2133 lttng_notification_destroy(notification);
2134 if (ret) {
2135 goto end;
2136 }
2137 }
2138 end:
2139 suspend_application();
2140 lttng_notification_channel_destroy(notification_channel);
2141 lttng_unregister_trigger(trigger);
2142 lttng_trigger_destroy(trigger);
2143 lttng_action_destroy(action);
2144 lttng_condition_destroy(condition);
2145 return;
2146 }
2147
2148 static void test_syscall_event_rule_notification_filter(
2149 enum lttng_domain_type domain_type)
2150 {
2151 int i, ret;
2152 enum lttng_error_code ret_code;
2153 const int notification_count = 3;
2154 enum lttng_notification_channel_status nc_status;
2155 enum lttng_event_rule_status event_rule_status;
2156 struct lttng_notification_channel *notification_channel = NULL;
2157 struct lttng_condition *condition = NULL;
2158 struct lttng_event_rule *event_rule = NULL;
2159 struct lttng_action *action = NULL;
2160 struct lttng_trigger *trigger = NULL;
2161 const char * const trigger_name = "syscall_trigger";
2162 const char * const syscall_name = "openat";
2163 const char * const filter_pattern = "filename == \"/proc/cpuinfo\"";
2164
2165 action = lttng_action_notify_create();
2166 if (!action) {
2167 fail("Failed to create notify action");
2168 goto end;
2169 }
2170
2171 notification_channel = lttng_notification_channel_create(
2172 lttng_session_daemon_notification_endpoint);
2173 ok(notification_channel, "Notification channel object creation");
2174
2175 event_rule = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY);
2176 ok(event_rule, "syscall event rule object creation");
2177
2178 event_rule_status = lttng_event_rule_kernel_syscall_set_name_pattern(
2179 event_rule, syscall_name);
2180 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2181 "Setting syscall event rule pattern: '%s'", syscall_name);
2182
2183 event_rule_status = lttng_event_rule_kernel_syscall_set_filter(
2184 event_rule, filter_pattern);
2185 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2186 "Setting filter: '%s'", filter_pattern);
2187
2188 condition = lttng_condition_event_rule_matches_create(event_rule);
2189 ok(condition, "Condition event rule object creation");
2190
2191 /* Register the triggers for condition */
2192 trigger = lttng_trigger_create(condition, action);
2193 if (!trigger) {
2194 fail("Failed to create trigger with syscall filtering event rule condition and notify action");
2195 goto end;
2196 }
2197
2198 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
2199 if (ret_code != LTTNG_OK) {
2200 fail("Failed to register trigger with syscall filtering event rule condition and notify action");
2201 goto end;
2202 }
2203
2204 nc_status = lttng_notification_channel_subscribe(
2205 notification_channel, condition);
2206 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2207 "Subscribe to tracepoint event rule condition");
2208
2209 resume_application();
2210
2211 for (i = 0; i < notification_count; i++) {
2212 struct lttng_notification *notification = get_next_notification(
2213 notification_channel);
2214
2215 ok(notification, "Received notification (%d/%d)", i + 1,
2216 notification_count);
2217
2218 /* Error. */
2219 if (notification == NULL) {
2220 goto end;
2221 }
2222
2223 ret = validator_notification_trigger_name(notification, trigger_name);
2224 lttng_notification_destroy(notification);
2225 if (ret) {
2226 goto end;
2227 }
2228 }
2229
2230 end:
2231 suspend_application();
2232
2233 lttng_unregister_trigger(trigger);
2234 lttng_notification_channel_destroy(notification_channel);
2235 lttng_trigger_destroy(trigger);
2236 lttng_event_rule_destroy(event_rule);
2237 lttng_condition_destroy(condition);
2238 return;
2239 }
2240
2241 static int generate_capture_descr(struct lttng_condition *condition)
2242 {
2243 int ret, i;
2244 struct lttng_event_expr *expr = NULL;
2245 const unsigned int basic_field_count = sizeof(test_capture_base_fields) /
2246 sizeof(*test_capture_base_fields);
2247 enum lttng_condition_status cond_status;
2248
2249 for (i = 0; i < basic_field_count; i++) {
2250 diag("Adding capture descriptor '%s'",
2251 test_capture_base_fields[i].field_name);
2252
2253 switch (test_capture_base_fields[i].field_type) {
2254 case FIELD_TYPE_PAYLOAD:
2255 expr = lttng_event_expr_event_payload_field_create(
2256 test_capture_base_fields[i].field_name);
2257 break;
2258 case FIELD_TYPE_CONTEXT:
2259 expr = lttng_event_expr_channel_context_field_create(
2260 test_capture_base_fields[i].field_name);
2261 break;
2262 case FIELD_TYPE_ARRAY_FIELD:
2263 {
2264 int nb_matches;
2265 unsigned int index;
2266 char field_name[FIELD_NAME_MAX_LEN];
2267 struct lttng_event_expr *array_expr = NULL;
2268
2269 nb_matches = sscanf(test_capture_base_fields[i].field_name,
2270 "%[^[][%u]", field_name, &index);
2271 if (nb_matches != 2) {
2272 fail("Unexpected array field name format: field name = '%s'",
2273 test_capture_base_fields[i].field_name);
2274 ret = 1;
2275 goto end;
2276 }
2277
2278 array_expr = lttng_event_expr_event_payload_field_create(
2279 field_name);
2280
2281 expr = lttng_event_expr_array_field_element_create(
2282 array_expr, index);
2283 break;
2284 }
2285 case FIELD_TYPE_APP_CONTEXT:
2286 fail("Application context tests are not implemented yet.");
2287 /* fallthrough. */
2288 default:
2289 ret = 1;
2290 goto end;
2291 }
2292
2293 if (expr == NULL) {
2294 fail("Failed to create capture expression");
2295 ret = -1;
2296 goto end;
2297 }
2298
2299 cond_status = lttng_condition_event_rule_matches_append_capture_descriptor(
2300 condition, expr);
2301 if (cond_status != LTTNG_CONDITION_STATUS_OK) {
2302 fail("Failed to append capture descriptor");
2303 ret = -1;
2304 lttng_event_expr_destroy(expr);
2305 goto end;
2306 }
2307 }
2308
2309 ret = 0;
2310
2311 end:
2312 return ret;
2313 }
2314
2315 static int validator_notification_trigger_capture(
2316 enum lttng_domain_type domain,
2317 struct lttng_notification *notification,
2318 const int iteration)
2319 {
2320 int ret;
2321 unsigned int capture_count, i;
2322 enum lttng_evaluation_event_rule_matches_status
2323 event_rule_matches_evaluation_status;
2324 enum lttng_event_field_value_status event_field_value_status;
2325 const struct lttng_evaluation *evaluation;
2326 const struct lttng_event_field_value *captured_fields;
2327 bool at_least_one_error = false;
2328
2329 evaluation = lttng_notification_get_evaluation(notification);
2330 if (evaluation == NULL) {
2331 fail("Failed to get evaluation from notification during trigger capture test");
2332 ret = 1;
2333 goto end;
2334 }
2335
2336 event_rule_matches_evaluation_status =
2337 lttng_evaluation_event_rule_matches_get_captured_values(
2338 evaluation, &captured_fields);
2339 if (event_rule_matches_evaluation_status !=
2340 LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_OK) {
2341 diag("Failed to get event rule evaluation captured values: status = %d",
2342 (int) event_rule_matches_evaluation_status);
2343 ret = 1;
2344 goto end;
2345 }
2346
2347 event_field_value_status =
2348 lttng_event_field_value_array_get_length(captured_fields,
2349 &capture_count);
2350 if (event_field_value_status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
2351 fail("Failed to get count of captured value field array");
2352 ret = 1;
2353 goto end;
2354 }
2355
2356 for (i = 0; i < capture_count; i++) {
2357 const struct lttng_event_field_value *captured_field = NULL;
2358 validate_cb validate;
2359 bool expected;
2360
2361 diag("Validating capture of field '%s'",
2362 test_capture_base_fields[i].field_name);
2363 event_field_value_status =
2364 lttng_event_field_value_array_get_element_at_index(
2365 captured_fields, i,
2366 &captured_field);
2367
2368 switch(domain) {
2369 case LTTNG_DOMAIN_UST:
2370 expected = test_capture_base_fields[i].expected_ust;
2371 break;
2372 case LTTNG_DOMAIN_KERNEL:
2373 expected = test_capture_base_fields[i].expected_kernel;
2374 break;
2375 default:
2376 fail("Unexpected domain encountered: domain = %d",
2377 (int) domain);
2378 ret = 1;
2379 goto end;
2380 }
2381
2382 if (domain == LTTNG_DOMAIN_UST) {
2383 validate = test_capture_base_fields[i].validate_ust;
2384 } else {
2385 validate = test_capture_base_fields[i].validate_kernel;
2386 }
2387
2388 if (!expected) {
2389 ok(event_field_value_status == LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE,
2390 "No payload captured");
2391 continue;
2392 }
2393
2394 if (event_field_value_status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
2395 if (event_field_value_status ==
2396 LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE) {
2397 fail("Expected a capture but it is unavailable");
2398 } else {
2399 fail("lttng_event_field_value_array_get_element_at_index returned an error: status = %d",
2400 (int) event_field_value_status);
2401 }
2402
2403 ret = 1;
2404 goto end;
2405 }
2406
2407 diag("Captured field of type %s",
2408 field_value_type_to_str(
2409 lttng_event_field_value_get_type(captured_field)));
2410
2411 LTTNG_ASSERT(validate);
2412 ret = validate(captured_field, iteration);
2413 if (ret) {
2414 at_least_one_error = true;
2415 }
2416 }
2417
2418 ret = at_least_one_error;
2419
2420 end:
2421 return ret;
2422 }
2423
2424 static void test_tracepoint_event_rule_notification_capture(
2425 enum lttng_domain_type domain_type)
2426 {
2427 enum lttng_notification_channel_status nc_status;
2428
2429 int i, ret;
2430 struct lttng_condition *condition = NULL;
2431 struct lttng_notification_channel *notification_channel = NULL;
2432 struct lttng_trigger *trigger = NULL;
2433 const char *trigger_name = "my_precious";
2434 const char *pattern;
2435
2436 if (domain_type == LTTNG_DOMAIN_UST) {
2437 pattern = "tp:tptest";
2438 } else {
2439 pattern = "lttng_test_filter_event";
2440 }
2441
2442 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 0,
2443 NULL, domain_type, generate_capture_descr, &condition,
2444 &trigger);
2445
2446 notification_channel = lttng_notification_channel_create(
2447 lttng_session_daemon_notification_endpoint);
2448 ok(notification_channel, "Notification channel object creation");
2449
2450 nc_status = lttng_notification_channel_subscribe(
2451 notification_channel, condition);
2452 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2453 "Subscribe to tracepoint event rule condition");
2454
2455 resume_application();
2456
2457 /* Get 3 notifications */
2458 for (i = 0; i < 3; i++) {
2459 struct lttng_notification *notification = get_next_notification(
2460 notification_channel);
2461 ok(notification, "Received notification");
2462
2463 /* Error */
2464 if (notification == NULL) {
2465 goto end;
2466 }
2467
2468 ret = validator_notification_trigger_name(notification, trigger_name);
2469 if (ret) {
2470 lttng_notification_destroy(notification);
2471 goto end;
2472 }
2473
2474 ret = validator_notification_trigger_capture(domain_type, notification, i);
2475 if (ret) {
2476 lttng_notification_destroy(notification);
2477 goto end;
2478 }
2479
2480 lttng_notification_destroy(notification);
2481 }
2482
2483 end:
2484 suspend_application();
2485 lttng_notification_channel_destroy(notification_channel);
2486 lttng_unregister_trigger(trigger);
2487 lttng_trigger_destroy(trigger);
2488 lttng_condition_destroy(condition);
2489 return;
2490 }
2491
2492 int main(int argc, const char *argv[])
2493 {
2494 int test_scenario;
2495 const char *domain_type_string = NULL;
2496 enum lttng_domain_type domain_type = LTTNG_DOMAIN_NONE;
2497
2498 if (argc < 5) {
2499 fail("Missing test scenario, domain type, pid, or application state file argument(s)");
2500 goto error;
2501 }
2502
2503 test_scenario = atoi(argv[1]);
2504 domain_type_string = argv[2];
2505 app_pid = (pid_t) atoi(argv[3]);
2506 app_state_file = argv[4];
2507
2508 if (!strcmp("LTTNG_DOMAIN_UST", domain_type_string)) {
2509 domain_type = LTTNG_DOMAIN_UST;
2510 }
2511 if (!strcmp("LTTNG_DOMAIN_KERNEL", domain_type_string)) {
2512 domain_type = LTTNG_DOMAIN_KERNEL;
2513 }
2514 if (domain_type == LTTNG_DOMAIN_NONE) {
2515 fail("Unknown domain type");
2516 goto error;
2517 }
2518
2519 /*
2520 * Test cases are responsible for resuming the app when needed
2521 * and making sure it's suspended when returning.
2522 */
2523 suspend_application();
2524
2525 switch (test_scenario) {
2526 case 1:
2527 {
2528 plan_tests(41);
2529
2530 /* Test cases that need gen-ust-event testapp. */
2531 diag("Test basic notification error paths for %s domain",
2532 domain_type_string);
2533 test_invalid_channel_subscription(domain_type);
2534
2535 diag("Test tracepoint event rule notifications for domain %s",
2536 domain_type_string);
2537 test_tracepoint_event_rule_notification(domain_type);
2538
2539 diag("Test tracepoint event rule notifications with filter for domain %s",
2540 domain_type_string);
2541 test_tracepoint_event_rule_notification_filter(domain_type);
2542 break;
2543 }
2544 case 2:
2545 {
2546 const char *session_name, *channel_name;
2547
2548 /* Test cases that need a tracing session enabled. */
2549 plan_tests(99);
2550
2551 /*
2552 * Argument 7 and upward are named pipe location for consumerd
2553 * control.
2554 */
2555 named_pipe_args_start = 7;
2556
2557 if (argc < 8) {
2558 fail("Missing parameter for tests to run %d", argc);
2559 goto error;
2560 }
2561
2562 nb_args = argc;
2563
2564 session_name = argv[5];
2565 channel_name = argv[6];
2566
2567 test_subscription_twice(session_name, channel_name,
2568 domain_type);
2569
2570 diag("Test trigger for domain %s with buffer_usage_low condition",
2571 domain_type_string);
2572 test_triggers_buffer_usage_condition(session_name, channel_name,
2573 domain_type,
2574 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
2575
2576 diag("Test trigger for domain %s with buffer_usage_high condition",
2577 domain_type_string);
2578 test_triggers_buffer_usage_condition(session_name, channel_name,
2579 domain_type,
2580 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
2581
2582 diag("Test buffer usage notification channel api for domain %s",
2583 domain_type_string);
2584 test_buffer_usage_notification_channel(session_name, channel_name,
2585 domain_type, argv);
2586 break;
2587 }
2588 case 3:
2589 {
2590 /*
2591 * Test cases that need a test app with more than one event
2592 * type.
2593 */
2594 plan_tests(23);
2595
2596 /*
2597 * At the moment, the only test case of this scenario is
2598 * exclusion which is only supported by UST.
2599 */
2600 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_UST);
2601 diag("Test tracepoint event rule notifications with exclusion for domain %s",
2602 domain_type_string);
2603 test_tracepoint_event_rule_notification_exclusion(domain_type);
2604
2605 break;
2606 }
2607 case 4:
2608 {
2609 plan_tests(11);
2610 /* Test cases that need the kernel tracer. */
2611 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_KERNEL);
2612
2613 diag("Test kprobe event rule notifications for domain %s",
2614 domain_type_string);
2615
2616 test_kprobe_event_rule_notification(domain_type);
2617
2618 break;
2619 }
2620 case 5:
2621 {
2622 plan_tests(23);
2623 /* Test cases that need the kernel tracer. */
2624 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_KERNEL);
2625
2626 diag("Test syscall event rule notifications for domain %s",
2627 domain_type_string);
2628
2629 test_syscall_event_rule_notification(domain_type);
2630
2631 diag("Test syscall filtering event rule notifications for domain %s",
2632 domain_type_string);
2633
2634 test_syscall_event_rule_notification_filter(domain_type);
2635
2636 break;
2637 }
2638 case 6:
2639 {
2640 const char *testapp_path, *test_symbol_name;
2641
2642 plan_tests(11);
2643
2644 if (argc < 7) {
2645 fail("Missing parameter for tests to run %d", argc);
2646 goto error;
2647 }
2648
2649 testapp_path = argv[5];
2650 test_symbol_name = argv[6];
2651 /* Test cases that need the kernel tracer. */
2652 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_KERNEL);
2653
2654 diag("Test userspace-probe event rule notifications for domain %s",
2655 domain_type_string);
2656
2657 test_uprobe_event_rule_notification(
2658 domain_type, testapp_path, test_symbol_name);
2659
2660 break;
2661 }
2662 case 7:
2663 {
2664 switch(domain_type) {
2665 case LTTNG_DOMAIN_UST:
2666 plan_tests(221);
2667 break;
2668 case LTTNG_DOMAIN_KERNEL:
2669 plan_tests(215);
2670 break;
2671 default:
2672 abort();
2673 }
2674
2675 diag("Test tracepoint event rule notification captures for domain %s",
2676 domain_type_string);
2677 test_tracepoint_event_rule_notification_capture(domain_type);
2678
2679 break;
2680 }
2681
2682 default:
2683 abort();
2684 }
2685
2686 error:
2687 return exit_status();
2688 }
2689
This page took 0.088024 seconds and 4 git commands to generate.