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