Rename C++ header files to .hpp
[lttng-tools.git] / tests / regression / tools / notification / notification.cpp
CommitLineData
434f8068
JR
1/*
2 * notification.c
3 *
4 * Tests suite for LTTng notification API
5 *
6 * Copyright (C) 2017 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
7 *
9d16b343 8 * SPDX-License-Identifier: MIT
434f8068 9 *
434f8068
JR
10 */
11
434f8068
JR
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>
854382b8 22#include <signal.h>
854382b8 23#include <poll.h>
434f8068 24
c9e313bc
SM
25#include <common/compat/errno.hpp>
26#include <common/macros.hpp>
7948461b 27#include <lttng/lttng.h>
434f8068
JR
28
29#include <tap/tap.h>
30
26e2f47b
JR
31#define FIELD_NAME_MAX_LEN 256
32
33/* A callback to populate the condition capture descriptor. */
34typedef int (*condition_capture_desc_cb)(struct lttng_condition *condition);
35
36/* A callback for captured field validation. */
37typedef int (*validate_cb)(const struct lttng_event_field_value *event_field, unsigned iteration);
38
434f8068
JR
39int nb_args = 0;
40int named_pipe_args_start = 0;
7344b6a3 41pid_t app_pid = 0;
854382b8
JR
42const char *app_state_file = NULL;
43
26e2f47b
JR
44enum field_type {
45 FIELD_TYPE_PAYLOAD,
46 FIELD_TYPE_CONTEXT,
47 FIELD_TYPE_APP_CONTEXT,
48 FIELD_TYPE_ARRAY_FIELD,
49};
50
51struct capture_base_field_tuple {
729c1fec 52 const char *field_name;
26e2f47b
JR
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
62static
63const 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
89static 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
107end:
108 return ret;
109}
110
111/*
112 * Validate unsigned captured field against the iteration number.
113 */
114static 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
143end:
144 return ret;
145}
146
147/*
148 * Validate signed captured field.
149 */
150static 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
184end:
185
186 return ret;
187}
188
189/*
190 * Validate array of unsigned int.
191 */
192static 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;
242end:
243
244 return ret;
245}
246
247static 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,
9f4a25d3 275 "Expected unsigned integer value %" PRIu64 ", got %" PRIu64,
26e2f47b
JR
276 expected_value, value);
277
278 ret = 0;
279end:
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 */
288static 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;
339end:
340 return ret;
341}
342
343static 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;
368end:
369
370 return ret;
371}
372
373/*
374 * Validate string. Expected value is "test".
375 */
376static 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 */
391static 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 */
406static 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;
429end:
430 return ret;
431}
432
433/*
434 * Validate floatfield.
435 */
436static 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 */
451static 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 */
466static 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
496end:
497 return ret;
498}
499
500/*
501 * Validate enumnegative: enumnegative = ( "AUTO: EXPECT 0" : container = 0 )
502 *
503 * We expect 2 labels here.
504 */
505static 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
535end:
536 return ret;
537}
538
539static 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
548static 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
557struct 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
d150e7e5
JR
579static const char *get_notification_trigger_name(
580 struct lttng_notification *notification)
581{
65f64978
JG
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");
d150e7e5
JR
589 goto end;
590 }
591
65f64978 592 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
0efb2ad7
JG
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:
65f64978 600 fail("Failed to get name from notification's trigger");
d150e7e5
JR
601 goto end;
602 }
65f64978 603
d150e7e5 604end:
65f64978 605 return trigger_name;
d150e7e5
JR
606}
607
608static 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
a0377dfe
FD
616 LTTNG_ASSERT(notification);
617 LTTNG_ASSERT(trigger_name);
d150e7e5
JR
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
631end:
632 return ret;
633}
634
854382b8
JR
635static
636void 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) {
f0784451
FD
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;
854382b8 654 }
f0784451
FD
655
656 /*
657 * File does not exist and the exit condition we want.
658 * Break from the loop and return.
659 */
660 break;
854382b8
JR
661 }
662 if (ret) {
663 perror("stat");
664 exit(EXIT_FAILURE);
665 }
f0784451
FD
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 }
854382b8
JR
673 }
674}
434f8068 675
f12eb9c1 676static
434f8068
JR
677int 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");
eff748d0
JR
691 if (close(fd)) {
692 perror("Named pipe close failed");
693 }
434f8068
JR
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 }
704end:
705 return ret;
706}
707
f12eb9c1 708static
434f8068
JR
709int stop_consumer(const char **argv)
710{
9df6c82a
JG
711 int ret = 0, i;
712
713 for (i = named_pipe_args_start; i < nb_args; i++) {
434f8068
JR
714 ret = write_pipe(argv[i], 49);
715 }
716 return ret;
717}
718
f12eb9c1 719static
434f8068
JR
720int resume_consumer(const char **argv)
721{
9df6c82a
JG
722 int ret = 0, i;
723
724 for (i = named_pipe_args_start; i < nb_args; i++) {
434f8068
JR
725 ret = write_pipe(argv[i], 0);
726 }
727 return ret;
728}
729
f12eb9c1
SM
730static
731int suspend_application(void)
854382b8
JR
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 */
a0377dfe 745 LTTNG_ASSERT(app_pid > 1);
7344b6a3 746
854382b8
JR
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
756error:
757 return ret;
758
759}
760
f12eb9c1 761static
a3ecaea8 762int resume_application(void)
854382b8
JR
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
a0377dfe 777 LTTNG_ASSERT(app_pid > 1);
7344b6a3 778
854382b8
JR
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
788error:
789 return ret;
790
791}
792
793
f12eb9c1 794static
434f8068
JR
795void test_triggers_buffer_usage_condition(const char *session_name,
796 const char *channel_name,
434f8068
JR
797 enum lttng_condition_type condition_type)
798{
9df6c82a 799 unsigned int test_vector_size = 5, i;
434f8068
JR
800 enum lttng_condition_status condition_status;
801 struct lttng_action *action;
802
803 /* Set-up */
804 action = lttng_action_notify_create();
805 if (!action) {
806 fail("Setup error on action creation");
807 goto end;
808 }
809
810 /* Test lttng_register_trigger with null value */
811 ok(lttng_register_trigger(NULL) == -LTTNG_ERR_INVALID, "Registering a NULL trigger fails as expected");
812
813 /* Test: register a trigger */
9df6c82a
JG
814
815 for (i = 0; i < pow(2,test_vector_size); i++) {
434f8068
JR
816 int loop_ret = 0;
817 char *test_tuple_string = NULL;
818 unsigned int mask_position = 0;
819 bool session_name_set = false;
820 bool channel_name_set = false;
821 bool threshold_ratio_set = false;
822 bool threshold_byte_set = false;
823 bool domain_type_set = false;
824
825 struct lttng_trigger *trigger = NULL;
826 struct lttng_condition *condition = NULL;
827
828 /* Create base condition */
829 switch (condition_type) {
830 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
831 condition = lttng_condition_buffer_usage_low_create();
832 break;
833 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
834 condition = lttng_condition_buffer_usage_high_create();
835 break;
836 default:
837 loop_ret = 1;
838 goto loop_end;
839 }
840
841 if (!condition) {
842 loop_ret = 1;
843 goto loop_end;
844
845 }
846
847 /* Prepare the condition for trigger registration test */
848
849 /* Set session name */
850 if ((1 << mask_position) & i) {
851 condition_status = lttng_condition_buffer_usage_set_session_name(
852 condition, session_name);
853 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
854 loop_ret = 1;
855 goto loop_end;
856 }
857 session_name_set = true;
858 }
859 mask_position++;
860
861 /* Set channel name */
862 if ((1 << mask_position) & i) {
863 condition_status = lttng_condition_buffer_usage_set_channel_name(
864 condition, channel_name);
865 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
866 loop_ret = 1;
867 goto loop_end;
868 }
869 channel_name_set = true;
870 }
871 mask_position++;
872
873 /* Set threshold ratio */
874 if ((1 << mask_position) & i) {
875 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
876 condition, 0.0);
877 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
878 loop_ret = 1;
879 goto loop_end;
880 }
881 threshold_ratio_set = true;
882 }
883 mask_position++;
884
885 /* Set threshold byte */
886 if ((1 << mask_position) & i) {
887 condition_status = lttng_condition_buffer_usage_set_threshold(
888 condition, 0);
889 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
890 loop_ret = 1;
891 goto loop_end;
892 }
893 threshold_byte_set = true;
894 }
895 mask_position++;
896
897 /* Set domain type */
898 if ((1 << mask_position) & i) {
899 condition_status = lttng_condition_buffer_usage_set_domain_type(
900 condition, LTTNG_DOMAIN_UST);
901 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
902 loop_ret = 1;
903 goto loop_end;
904 }
905 domain_type_set = true;
906 }
907
908 /* Safety check */
909 if (mask_position != test_vector_size -1) {
a0377dfe 910 LTTNG_ASSERT("Logic error for test vector generation");
434f8068
JR
911 }
912
9479b7a7 913 loop_ret = asprintf(&test_tuple_string, "session name %s, channel name %s, threshold ratio %s, threshold byte %s, domain type %s",
434f8068
JR
914 session_name_set ? "set" : "unset",
915 channel_name_set ? "set" : "unset",
916 threshold_ratio_set ? "set" : "unset",
917 threshold_byte_set ? "set" : "unset",
918 domain_type_set? "set" : "unset");
919 if (!test_tuple_string || loop_ret < 0) {
920 loop_ret = 1;
921 goto loop_end;
922 }
923
924 /* Create trigger */
925 trigger = lttng_trigger_create(condition, action);
926 if (!trigger) {
927 loop_ret = 1;
928 goto loop_end;
929 }
930
931 loop_ret = lttng_register_trigger(trigger);
932
933loop_end:
934 if (loop_ret == 1) {
935 fail("Setup error occurred for tuple: %s", test_tuple_string);
936 goto loop_cleanup;
937 }
938
939 /* This combination happens three times */
940 if (session_name_set && channel_name_set
941 && (threshold_ratio_set || threshold_byte_set)
942 && domain_type_set) {
943 ok(loop_ret == 0, "Trigger is registered: %s", test_tuple_string);
944
945 /*
946 * Test that a trigger cannot be registered
947 * multiple time.
948 */
949 loop_ret = lttng_register_trigger(trigger);
950 ok(loop_ret == -LTTNG_ERR_TRIGGER_EXISTS, "Re-register trigger fails as expected: %s", test_tuple_string);
951
952 /* Test that a trigger can be unregistered */
953 loop_ret = lttng_unregister_trigger(trigger);
954 ok(loop_ret == 0, "Unregister trigger: %s", test_tuple_string);
955
956 /*
957 * Test that unregistration of a non-previously
958 * registered trigger fail.
959 */
960 loop_ret = lttng_unregister_trigger(trigger);
43e0c204 961 ok(loop_ret == -LTTNG_ERR_TRIGGER_NOT_FOUND, "Unregister of a non-registered trigger fails as expected: %s", test_tuple_string);
434f8068
JR
962 } else {
963 ok(loop_ret == -LTTNG_ERR_INVALID_TRIGGER, "Trigger is invalid as expected and cannot be registered: %s", test_tuple_string);
964 }
965
966loop_cleanup:
967 free(test_tuple_string);
968 lttng_trigger_destroy(trigger);
969 lttng_condition_destroy(condition);
970 }
971
972end:
973 lttng_action_destroy(action);
974}
975
ff2b03c8
JG
976static
977void wait_data_pending(const char *session_name)
978{
979 int ret;
980
981 do {
982 ret = lttng_data_pending(session_name);
a0377dfe 983 LTTNG_ASSERT(ret >= 0);
ff2b03c8
JG
984 } while (ret != 0);
985}
986
f12eb9c1 987static
17423302
FD
988int setup_buffer_usage_condition(struct lttng_condition *condition,
989 const char *condition_name,
990 const char *session_name,
991 const char *channel_name,
992 const enum lttng_domain_type domain_type)
993{
994 enum lttng_condition_status condition_status;
995 int ret = 0;
996
997 condition_status = lttng_condition_buffer_usage_set_session_name(
998 condition, session_name);
999 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1000 fail("Failed to set session name on creation of condition `%s`",
1001 condition_name);
1002 ret = -1;
1003 goto end;
1004 }
1005
1006 condition_status = lttng_condition_buffer_usage_set_channel_name(
1007 condition, channel_name);
1008 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1009 fail("Failed to set channel name on creation of condition `%s`",
1010 condition_name);
1011 ret = -1;
1012 goto end;
1013 }
1014
1015 condition_status = lttng_condition_buffer_usage_set_domain_type(
1016 condition, domain_type);
1017 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1018 fail("Failed to set domain type on creation of condition `%s`",
1019 condition_name);
1020 ret = -1;
1021 goto end;
1022 }
1023
1024end:
1025 return ret;
1026}
1027
1028static
90fcb2ec
FD
1029void test_invalid_channel_subscription(
1030 const enum lttng_domain_type domain_type)
434f8068 1031{
434f8068
JR
1032 enum lttng_condition_status condition_status;
1033 enum lttng_notification_channel_status nc_status;
434f8068 1034 struct lttng_condition *dummy_condition = NULL;
90fcb2ec
FD
1035 struct lttng_condition *dummy_invalid_condition = NULL;
1036 struct lttng_notification_channel *notification_channel = NULL;
1037 int ret = 0;
434f8068 1038
90fcb2ec
FD
1039 notification_channel = lttng_notification_channel_create(
1040 lttng_session_daemon_notification_endpoint);
1041 ok(notification_channel, "Notification channel object creation");
1042 if (!notification_channel) {
434f8068
JR
1043 goto end;
1044 }
1045
90fcb2ec
FD
1046 /*
1047 * Create a dummy, empty (thus invalid) condition to test error paths.
1048 */
434f8068
JR
1049 dummy_invalid_condition = lttng_condition_buffer_usage_low_create();
1050 if (!dummy_invalid_condition) {
1051 fail("Setup error on condition creation");
1052 goto end;
1053 }
1054
90fcb2ec
FD
1055 /*
1056 * Test subscription and unsubscription of an invalid condition to/from
1057 * a channel.
1058 */
1059 nc_status = lttng_notification_channel_subscribe(
1060 notification_channel, dummy_invalid_condition);
1061 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1062 "Subscribing to an invalid condition");
1063
1064 nc_status = lttng_notification_channel_unsubscribe(
1065 notification_channel, dummy_invalid_condition);
1066 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1067 "Unsubscribing from an invalid condition");
1068
434f8068
JR
1069 /* Create a valid dummy condition with a ratio of 0.5 */
1070 dummy_condition = lttng_condition_buffer_usage_low_create();
1071 if (!dummy_condition) {
1072 fail("Setup error on dummy_condition creation");
1073 goto end;
434f8068 1074 }
90fcb2ec 1075
434f8068
JR
1076 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
1077 dummy_condition, 0.5);
1078 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
1079 fail("Setup error on condition creation");
1080 goto end;
1081 }
1082
17423302 1083 ret = setup_buffer_usage_condition(dummy_condition, "dummy_condition",
90fcb2ec 1084 "dummy_session", "dummy_channel", domain_type);
17423302
FD
1085 if (ret) {
1086 fail("Setup error on dummy condition creation");
434f8068
JR
1087 goto end;
1088 }
1089
90fcb2ec
FD
1090 /*
1091 * Test subscription and unsubscription to/from a channel with invalid
1092 * parameters.
1093 */
1094 nc_status = lttng_notification_channel_subscribe(NULL, NULL);
1095 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1096 "Notification channel subscription is invalid: NULL, NULL");
1097
1098 nc_status = lttng_notification_channel_subscribe(
1099 notification_channel, NULL);
1100 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1101 "Notification channel subscription is invalid: NON-NULL, NULL");
1102
1103 nc_status = lttng_notification_channel_subscribe(NULL, dummy_condition);
1104 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID,
1105 "Notification channel subscription is invalid: NULL, NON-NULL");
1106
1107 nc_status = lttng_notification_channel_unsubscribe(
1108 notification_channel, dummy_condition);
1109 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_UNKNOWN_CONDITION,
1110 "Unsubscribing from a valid unknown condition");
1111
1112end:
1113 lttng_notification_channel_destroy(notification_channel);
1114 lttng_condition_destroy(dummy_invalid_condition);
1115 lttng_condition_destroy(dummy_condition);
1116 return;
1117}
1118
3780613c
FD
1119enum buffer_usage_type {
1120 BUFFER_USAGE_TYPE_LOW,
1121 BUFFER_USAGE_TYPE_HIGH,
1122};
1123
1124static int register_buffer_usage_notify_trigger(const char *session_name,
90fcb2ec
FD
1125 const char *channel_name,
1126 const enum lttng_domain_type domain_type,
3780613c
FD
1127 enum buffer_usage_type buffer_usage_type,
1128 double ratio,
1129 struct lttng_condition **condition,
1130 struct lttng_action **action,
1131 struct lttng_trigger **trigger)
90fcb2ec 1132{
90fcb2ec 1133 enum lttng_condition_status condition_status;
3780613c
FD
1134 struct lttng_action *tmp_action = NULL;
1135 struct lttng_condition *tmp_condition = NULL;
1136 struct lttng_trigger *tmp_trigger = NULL;
1137 int ret = 0;
90fcb2ec
FD
1138
1139 /* Set-up */
3780613c 1140 tmp_action = lttng_action_notify_create();
90fcb2ec
FD
1141 if (!action) {
1142 fail("Setup error on action creation");
3780613c
FD
1143 ret = -1;
1144 goto error;
434f8068
JR
1145 }
1146
3780613c
FD
1147 if (buffer_usage_type == BUFFER_USAGE_TYPE_LOW) {
1148 tmp_condition = lttng_condition_buffer_usage_low_create();
1149 } else {
1150 tmp_condition = lttng_condition_buffer_usage_high_create();
434f8068
JR
1151 }
1152
3780613c
FD
1153 if (!tmp_condition) {
1154 fail("Setup error on condition creation");
1155 ret = -1;
1156 goto error;
434f8068
JR
1157 }
1158
3780613c 1159 /* Set the buffer usage threashold */
434f8068 1160 condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
3780613c 1161 tmp_condition, ratio);
434f8068 1162 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
3780613c
FD
1163 fail("Setup error on condition creation");
1164 ret = -1;
1165 goto error;
434f8068
JR
1166 }
1167
3780613c 1168 ret = setup_buffer_usage_condition(tmp_condition, "condition_name",
17423302
FD
1169 session_name, channel_name, domain_type);
1170 if (ret) {
3780613c
FD
1171 fail("Setup error on condition creation");
1172 ret = -1;
1173 goto error;
434f8068
JR
1174 }
1175
3780613c
FD
1176 /* Register the trigger for condition. */
1177 tmp_trigger = lttng_trigger_create(tmp_condition, tmp_action);
1178 if (!tmp_trigger) {
1179 fail("Setup error on trigger creation");
1180 ret = -1;
1181 goto error;
434f8068
JR
1182 }
1183
3780613c 1184 ret = lttng_register_trigger(tmp_trigger);
434f8068 1185 if (ret) {
3780613c
FD
1186 fail("Setup error on trigger registration");
1187 ret = -1;
1188 goto error;
434f8068
JR
1189 }
1190
3780613c
FD
1191 *condition = tmp_condition;
1192 *trigger = tmp_trigger;
1193 *action = tmp_action;
1194 goto end;
434f8068 1195
3780613c
FD
1196error:
1197 lttng_action_destroy(tmp_action);
1198 lttng_condition_destroy(tmp_condition);
1199 lttng_trigger_destroy(tmp_trigger);
1200
1201end:
1202 return ret;
1203}
1204
fa448dbe
FD
1205static void test_subscription_twice(const char *session_name,
1206 const char *channel_name,
1207 const enum lttng_domain_type domain_type)
1208{
1209 int ret = 0;
1210 enum lttng_notification_channel_status nc_status;
1211
1212 struct lttng_action *action = NULL;
1213 struct lttng_notification_channel *notification_channel = NULL;
1214 struct lttng_trigger *trigger = NULL;
1215
1216 struct lttng_condition *condition = NULL;
1217
1218 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
1219 domain_type, BUFFER_USAGE_TYPE_LOW, 0.99, &condition,
1220 &action, &trigger);
1221 if (ret) {
b7d7800d
JG
1222 fail("Setup error on trigger registration in %s()",
1223 __FUNCTION__);
fa448dbe
FD
1224 goto end;
1225 }
1226
1227 /* Begin testing. */
1228 notification_channel = lttng_notification_channel_create(
1229 lttng_session_daemon_notification_endpoint);
1230 ok(notification_channel, "Notification channel object creation");
1231 if (!notification_channel) {
1232 goto end;
1233 }
1234
1235 /* Subscribe a valid condition. */
1236 nc_status = lttng_notification_channel_subscribe(
1237 notification_channel, condition);
1238 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1239 "Subscribe to condition");
1240
1241 /* Subscribing again should fail. */
1242 nc_status = lttng_notification_channel_subscribe(
1243 notification_channel, condition);
1244 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_ALREADY_SUBSCRIBED,
1245 "Subscribe to a condition for which subscription was already done");
1246
1247end:
b7d7800d
JG
1248 ret = lttng_unregister_trigger(trigger);
1249 if (ret) {
1250 fail("Failed to unregister trigger in %s()", __FUNCTION__);
1251 }
1252
fa448dbe
FD
1253 lttng_trigger_destroy(trigger);
1254 lttng_notification_channel_destroy(notification_channel);
1255 lttng_action_destroy(action);
1256 lttng_condition_destroy(condition);
1257}
1258
40ac6709 1259static void test_buffer_usage_notification_channel(const char *session_name,
3780613c
FD
1260 const char *channel_name,
1261 const enum lttng_domain_type domain_type,
1262 const char **argv)
1263{
1264 int ret = 0;
1265 enum lttng_notification_channel_status nc_status;
1266
1267 struct lttng_action *low_action = NULL;
1268 struct lttng_action *high_action = NULL;
1269 struct lttng_notification *notification = NULL;
1270 struct lttng_notification_channel *notification_channel = NULL;
1271 struct lttng_trigger *low_trigger = NULL;
1272 struct lttng_trigger *high_trigger = NULL;
1273
1274 struct lttng_condition *low_condition = NULL;
1275 struct lttng_condition *high_condition = NULL;
1276
1277 const double low_ratio = 0.0;
1278 const double high_ratio = 0.90;
1279
1280 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
1281 domain_type, BUFFER_USAGE_TYPE_LOW, low_ratio,
1282 &low_condition, &low_action, &low_trigger);
1283 if (ret) {
1284 fail("Setup error on low trigger registration");
434f8068
JR
1285 goto end;
1286 }
1287
3780613c
FD
1288 ret = register_buffer_usage_notify_trigger(session_name, channel_name,
1289 domain_type, BUFFER_USAGE_TYPE_HIGH, high_ratio,
1290 &high_condition, &high_action, &high_trigger);
434f8068
JR
1291 if (ret) {
1292 fail("Setup error on high trigger registration");
1293 goto end;
1294 }
1295
1296 /* Begin testing */
a6ae2480
FD
1297 notification_channel = lttng_notification_channel_create(
1298 lttng_session_daemon_notification_endpoint);
434f8068
JR
1299 ok(notification_channel, "Notification channel object creation");
1300 if (!notification_channel) {
1301 goto end;
1302 }
1303
434f8068 1304 /* Subscribe a valid low condition */
a6ae2480
FD
1305 nc_status = lttng_notification_channel_subscribe(
1306 notification_channel, low_condition);
1307 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
40ac6709 1308 "Subscribe to low condition");
434f8068
JR
1309
1310 /* Subscribe a valid high condition */
a6ae2480
FD
1311 nc_status = lttng_notification_channel_subscribe(
1312 notification_channel, high_condition);
1313 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
40ac6709 1314 "Subscribe to high condition");
434f8068 1315
7676e0d2
FD
1316 resume_application();
1317
434f8068 1318 /* Wait for notification to happen */
434f8068 1319 stop_consumer(argv);
ff2b03c8 1320 lttng_start_tracing(session_name);
434f8068
JR
1321
1322 /* Wait for high notification */
67c93c15 1323 do {
a6ae2480
FD
1324 nc_status = lttng_notification_channel_get_next_notification(
1325 notification_channel, &notification);
67c93c15 1326 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
a6ae2480
FD
1327 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
1328 lttng_condition_get_type(lttng_notification_get_condition(
1329 notification)) ==
1330 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
434f8068
JR
1331 "High notification received after intermediary communication");
1332 lttng_notification_destroy(notification);
1333 notification = NULL;
1334
854382b8 1335 suspend_application();
ff2b03c8 1336 lttng_stop_tracing_no_wait(session_name);
434f8068 1337 resume_consumer(argv);
ff2b03c8 1338 wait_data_pending(session_name);
434f8068
JR
1339
1340 /*
1341 * Test that communication still work even if there is notification
1342 * waiting for consumption.
1343 */
1344
a6ae2480
FD
1345 nc_status = lttng_notification_channel_unsubscribe(
1346 notification_channel, low_condition);
1347 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1348 "Unsubscribe with pending notification");
434f8068 1349
a6ae2480
FD
1350 nc_status = lttng_notification_channel_subscribe(
1351 notification_channel, low_condition);
1352 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1353 "Subscribe with pending notification");
434f8068 1354
67c93c15 1355 do {
a6ae2480
FD
1356 nc_status = lttng_notification_channel_get_next_notification(
1357 notification_channel, &notification);
67c93c15 1358 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
a6ae2480
FD
1359 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
1360 lttng_condition_get_type(lttng_notification_get_condition(
1361 notification)) ==
1362 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW,
434f8068
JR
1363 "Low notification received after intermediary communication");
1364 lttng_notification_destroy(notification);
1365 notification = NULL;
1366
1367 /* Stop consumer to force a high notification */
ff2b03c8 1368 stop_consumer(argv);
854382b8 1369 resume_application();
434f8068 1370 lttng_start_tracing(session_name);
434f8068 1371
67c93c15 1372 do {
a6ae2480
FD
1373 nc_status = lttng_notification_channel_get_next_notification(
1374 notification_channel, &notification);
67c93c15 1375 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
434f8068 1376 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
a6ae2480
FD
1377 lttng_condition_get_type(lttng_notification_get_condition(
1378 notification)) ==
1379 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
434f8068
JR
1380 "High notification received after intermediary communication");
1381 lttng_notification_destroy(notification);
1382 notification = NULL;
1383
854382b8 1384 suspend_application();
ff2b03c8 1385 lttng_stop_tracing_no_wait(session_name);
434f8068 1386 resume_consumer(argv);
ff2b03c8 1387 wait_data_pending(session_name);
434f8068 1388
67c93c15 1389 do {
a6ae2480
FD
1390 nc_status = lttng_notification_channel_get_next_notification(
1391 notification_channel, &notification);
67c93c15 1392 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
434f8068 1393 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
a6ae2480
FD
1394 lttng_condition_get_type(lttng_notification_get_condition(
1395 notification)) ==
1396 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW,
434f8068
JR
1397 "Low notification received after re-subscription");
1398 lttng_notification_destroy(notification);
1399 notification = NULL;
1400
ff2b03c8 1401 stop_consumer(argv);
854382b8 1402 resume_application();
434f8068
JR
1403 /* Stop consumer to force a high notification */
1404 lttng_start_tracing(session_name);
434f8068 1405
67c93c15 1406 do {
a6ae2480
FD
1407 nc_status = lttng_notification_channel_get_next_notification(
1408 notification_channel, &notification);
67c93c15 1409 } while (nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED);
434f8068 1410 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification &&
a6ae2480
FD
1411 lttng_condition_get_type(lttng_notification_get_condition(
1412 notification)) ==
1413 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH,
434f8068
JR
1414 "High notification");
1415 lttng_notification_destroy(notification);
1416 notification = NULL;
1417
ff2b03c8 1418 suspend_application();
7676e0d2
FD
1419
1420 /* Resume consumer to allow event consumption */
ff2b03c8 1421 lttng_stop_tracing_no_wait(session_name);
434f8068 1422 resume_consumer(argv);
ff2b03c8 1423 wait_data_pending(session_name);
434f8068 1424
a6ae2480
FD
1425 nc_status = lttng_notification_channel_unsubscribe(
1426 notification_channel, low_condition);
1427 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1428 "Unsubscribe low condition with pending notification");
1429
1430 nc_status = lttng_notification_channel_unsubscribe(
1431 notification_channel, high_condition);
1432 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1433 "Unsubscribe high condition with pending notification");
434f8068
JR
1434
1435end:
1436 lttng_notification_channel_destroy(notification_channel);
3780613c
FD
1437 lttng_trigger_destroy(low_trigger);
1438 lttng_trigger_destroy(high_trigger);
1439 lttng_action_destroy(low_action);
1440 lttng_action_destroy(high_action);
434f8068 1441 lttng_condition_destroy(low_condition);
eff748d0 1442 lttng_condition_destroy(high_condition);
434f8068
JR
1443}
1444
7948461b
FD
1445static void create_tracepoint_event_rule_trigger(const char *event_pattern,
1446 const char *trigger_name,
1447 const char *filter,
1448 unsigned int exclusion_count,
3e4ee3b3 1449 const char * const *exclusions,
7948461b 1450 enum lttng_domain_type domain_type,
26e2f47b 1451 condition_capture_desc_cb capture_desc_cb,
7948461b
FD
1452 struct lttng_condition **condition,
1453 struct lttng_trigger **trigger)
1454{
695f7044
JR
1455 typedef struct lttng_event_rule *(*event_rule_create)(void);
1456 typedef enum lttng_event_rule_status (
1457 *event_rule_set_name_pattern)(
1458 struct lttng_event_rule *rule,
1459 const char *pattern);
1460 typedef enum lttng_event_rule_status (*event_rule_set_filter)(
1461 struct lttng_event_rule *rule,
1462 const char *expression);
1463 typedef enum lttng_event_rule_status (
1464 *event_rule_add_name_pattern_exclusion)(
1465 struct lttng_event_rule * rule, const char *exclusion);
1466
7948461b 1467 enum lttng_event_rule_status event_rule_status;
7948461b
FD
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;
a5c2d2a7 1473 enum lttng_error_code ret_code;
695f7044
JR
1474 event_rule_create create;
1475 event_rule_set_name_pattern set_name_pattern;
1476 event_rule_set_filter set_filter;
1477 event_rule_add_name_pattern_exclusion add_name_pattern_exclusion;
7948461b 1478
a0377dfe
FD
1479 LTTNG_ASSERT(event_pattern);
1480 LTTNG_ASSERT(trigger_name);
1481 LTTNG_ASSERT(condition);
1482 LTTNG_ASSERT(trigger);
7948461b 1483
695f7044
JR
1484 /* Set the function pointers based on the domain type. */
1485 switch (domain_type) {
1486 case LTTNG_DOMAIN_UST:
1487 create = lttng_event_rule_user_tracepoint_create;
1488 set_name_pattern = lttng_event_rule_user_tracepoint_set_name_pattern;
1489 set_filter = lttng_event_rule_user_tracepoint_set_filter;
1490 add_name_pattern_exclusion = lttng_event_rule_user_tracepoint_add_name_pattern_exclusion;
1491 break;
1492 case LTTNG_DOMAIN_KERNEL:
1493 create = lttng_event_rule_kernel_tracepoint_create;
1494 set_name_pattern = lttng_event_rule_kernel_tracepoint_set_name_pattern;
1495 set_filter = lttng_event_rule_kernel_tracepoint_set_filter;
1496 add_name_pattern_exclusion = NULL;
1497 break;
1498 default:
1499 abort();
1500 break;
1501 }
1502
1503 event_rule = create();
7948461b
FD
1504 ok(event_rule, "Tracepoint event rule object creation");
1505
695f7044 1506 event_rule_status = set_name_pattern(event_rule, event_pattern);
7948461b
FD
1507 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1508 "Setting tracepoint event rule pattern: '%s'",
1509 event_pattern);
1510
1511 if (filter) {
695f7044 1512 event_rule_status = set_filter(event_rule, filter);
7948461b
FD
1513 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1514 "Setting tracepoint event rule filter: '%s'",
1515 filter);
1516 }
1517
1518 if (exclusions) {
1519 int i;
1520 bool success = true;
1521
a0377dfe
FD
1522 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_UST);
1523 LTTNG_ASSERT(add_name_pattern_exclusion != NULL);
1524 LTTNG_ASSERT(exclusion_count > 0);
7948461b
FD
1525
1526 for (i = 0; i < exclusion_count; i++) {
695f7044
JR
1527 event_rule_status = add_name_pattern_exclusion(
1528 event_rule, exclusions[i]);
7948461b
FD
1529 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
1530 fail("Setting tracepoint event rule exclusion '%s'.",
1531 exclusions[i]);
1532 success = false;
1533 }
1534 }
1535
1536 ok(success, "Setting tracepoint event rule exclusions");
1537 }
1538
8dbb86b8 1539 tmp_condition = lttng_condition_event_rule_matches_create(event_rule);
7948461b
FD
1540 ok(tmp_condition, "Condition event rule object creation");
1541
26e2f47b
JR
1542 if (capture_desc_cb) {
1543 ret = capture_desc_cb(tmp_condition);
1544 if (ret) {
1545 fail("Failed to generate the condition capture descriptor");
1546 abort();
1547 }
1548 }
1549
7948461b
FD
1550 tmp_action = lttng_action_notify_create();
1551 ok(tmp_action, "Action event rule object creation");
1552
1553 tmp_trigger = lttng_trigger_create(tmp_condition, tmp_action);
1554 ok(tmp_trigger, "Trigger object creation %s", trigger_name);
1555
a5c2d2a7
JG
1556 ret_code = lttng_register_trigger_with_name(tmp_trigger, trigger_name);
1557 ok(ret_code == LTTNG_OK, "Trigger registration %s", trigger_name);
7948461b
FD
1558
1559 lttng_event_rule_destroy(event_rule);
1560
1561 *condition = tmp_condition;
1562 *trigger = tmp_trigger;
1563
1564 return;
1565}
1566
d150e7e5 1567static struct lttng_notification *get_next_notification(
7948461b
FD
1568 struct lttng_notification_channel *notification_channel)
1569{
d150e7e5 1570 struct lttng_notification *local_notification = NULL;
7948461b 1571 enum lttng_notification_channel_status status;
7948461b
FD
1572
1573 /* Receive the next notification. */
1574 status = lttng_notification_channel_get_next_notification(
d150e7e5 1575 notification_channel, &local_notification);
7948461b
FD
1576
1577 switch (status) {
1578 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
1579 break;
d150e7e5
JR
1580 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
1581 fail("Notifications have been dropped");
1582 local_notification = NULL;
7948461b
FD
1583 break;
1584 default:
d150e7e5
JR
1585 /* Unhandled conditions / errors. */
1586 fail("Failed to get next notification (unknown notification channel status): status = %d",
1587 (int) status);
1588 local_notification = NULL;
7948461b
FD
1589 break;
1590 }
1591
d150e7e5 1592 return local_notification;
7948461b
FD
1593}
1594
1595static void test_tracepoint_event_rule_notification(
1596 enum lttng_domain_type domain_type)
1597{
1598 int i;
d150e7e5 1599 int ret;
7948461b
FD
1600 const int notification_count = 3;
1601 enum lttng_notification_channel_status nc_status;
1602 struct lttng_action *action = NULL;
1603 struct lttng_condition *condition = NULL;
1604 struct lttng_notification_channel *notification_channel = NULL;
1605 struct lttng_trigger *trigger = NULL;
1606 const char * const trigger_name = "my_precious";
1607 const char *pattern;
1608
1609 if (domain_type == LTTNG_DOMAIN_UST) {
1610 pattern = "tp:tptest";
1611 } else {
1612 pattern = "lttng_test_filter_event";
1613 }
1614
1615 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 0,
26e2f47b 1616 NULL, domain_type, NULL, &condition, &trigger);
7948461b
FD
1617
1618 notification_channel = lttng_notification_channel_create(
1619 lttng_session_daemon_notification_endpoint);
1620 ok(notification_channel, "Notification channel object creation");
1621
1622 nc_status = lttng_notification_channel_subscribe(
1623 notification_channel, condition);
1624 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1625 "Subscribe to tracepoint event rule condition");
1626
1627 resume_application();
1628
d150e7e5 1629 /* Get notifications. */
7948461b 1630 for (i = 0; i < notification_count; i++) {
d150e7e5 1631 struct lttng_notification *notification = get_next_notification(
7948461b
FD
1632 notification_channel);
1633
d150e7e5
JR
1634 ok(notification, "Received notification (%d/%d)", i + 1,
1635 notification_count);
1636
1637 /* Error. */
1638 if (notification == NULL) {
1639 goto end;
1640 }
1641
1642 ret = validator_notification_trigger_name(notification, trigger_name);
1643 lttng_notification_destroy(notification);
1644 if (ret) {
1645 goto end;
1646 }
7948461b
FD
1647 }
1648
d150e7e5 1649end:
7948461b
FD
1650 suspend_application();
1651 lttng_notification_channel_destroy(notification_channel);
1652 lttng_unregister_trigger(trigger);
1653 lttng_trigger_destroy(trigger);
1654 lttng_action_destroy(action);
1655 lttng_condition_destroy(condition);
1656 return;
1657}
1658
a740a242
FD
1659static void test_tracepoint_event_rule_notification_filter(
1660 enum lttng_domain_type domain_type)
1661{
1662 int i;
d150e7e5 1663 const int notification_count = 3;
a740a242 1664 enum lttng_notification_channel_status nc_status;
a740a242
FD
1665 struct lttng_condition *ctrl_condition = NULL, *condition = NULL;
1666 struct lttng_notification_channel *notification_channel = NULL;
1667 struct lttng_trigger *ctrl_trigger = NULL, *trigger = NULL;
1668 const char * const ctrl_trigger_name = "control_trigger";
1669 const char * const trigger_name = "trigger";
1670 const char *pattern;
1671 int ctrl_count = 0, count = 0;
1672
1673 if (domain_type == LTTNG_DOMAIN_UST) {
1674 pattern = "tp:tptest";
1675 } else {
1676 pattern = "lttng_test_filter_event";
1677 }
1678
1679 notification_channel = lttng_notification_channel_create(
1680 lttng_session_daemon_notification_endpoint);
1681 ok(notification_channel, "Notification channel object creation");
1682
1683 create_tracepoint_event_rule_trigger(pattern, ctrl_trigger_name, NULL,
26e2f47b 1684 0, NULL, domain_type, NULL, &ctrl_condition, &ctrl_trigger);
a740a242
FD
1685
1686 nc_status = lttng_notification_channel_subscribe(
1687 notification_channel, ctrl_condition);
1688 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1689 "Subscribe to tracepoint event rule condition");
1690
1691 /*
1692 * Attach a filter expression to get notification only if the
1693 * `intfield` is even.
1694 */
1695 create_tracepoint_event_rule_trigger(pattern, trigger_name,
26e2f47b 1696 "(intfield & 1) == 0", 0, NULL, domain_type, NULL, &condition,
a740a242
FD
1697 &trigger);
1698
1699 nc_status = lttng_notification_channel_subscribe(
1700 notification_channel, condition);
1701 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1702 "Subscribe to tracepoint event rule condition");
1703
1704 /*
1705 * We registered 2 notifications triggers, one with a filter and one
1706 * without (control). The one with a filter will only fired when the
1707 * `intfield` is a multiple of 2. We should get two times as many
1708 * control notifications as filter notifications.
1709 */
1710 resume_application();
1711
1712 /*
1713 * Get 3 notifications. We should get 1 for the regular trigger (with
1714 * the filter) and 2 from the control trigger. This works whatever
1715 * the order we receive the notifications.
1716 */
d150e7e5
JR
1717 for (i = 0; i < notification_count; i++) {
1718 const char *name;
1719 struct lttng_notification *notification = get_next_notification(
a740a242
FD
1720 notification_channel);
1721
d150e7e5
JR
1722 ok(notification, "Received notification (%d/%d)", i + 1,
1723 notification_count);
1724
1725 /* Error. */
1726 if (notification == NULL) {
1727 goto end;
1728 }
1729
1730 name = get_notification_trigger_name(notification);
1731 if (name == NULL) {
1732 lttng_notification_destroy(notification);
1733 goto end;
1734 }
1735
a740a242
FD
1736 if (strcmp(ctrl_trigger_name, name) == 0) {
1737 ctrl_count++;
1738 } else if (strcmp(trigger_name, name) == 0) {
1739 count++;
1740 }
1741
d150e7e5 1742 lttng_notification_destroy(notification);
a740a242
FD
1743 }
1744
1745 ok(ctrl_count / 2 == count,
1746 "Get twice as many control notif as of regular notif");
1747
d150e7e5 1748end:
a740a242
FD
1749 suspend_application();
1750
1751 lttng_unregister_trigger(trigger);
1752 lttng_unregister_trigger(ctrl_trigger);
1753 lttng_notification_channel_destroy(notification_channel);
1754 lttng_trigger_destroy(trigger);
1755 lttng_trigger_destroy(ctrl_trigger);
1756 lttng_condition_destroy(condition);
1757 lttng_condition_destroy(ctrl_condition);
1758}
1759
3e4ee3b3
FD
1760static void test_tracepoint_event_rule_notification_exclusion(
1761 enum lttng_domain_type domain_type)
1762{
1763 enum lttng_notification_channel_status nc_status;
1764 struct lttng_condition *ctrl_condition = NULL, *condition = NULL;
1765 struct lttng_notification_channel *notification_channel = NULL;
1766 struct lttng_trigger *ctrl_trigger = NULL, *trigger = NULL;
1767 int ctrl_count = 0, count = 0, i;
d150e7e5 1768 const int notification_count = 6;
3e4ee3b3
FD
1769 const char * const ctrl_trigger_name = "control_exclusion_trigger";
1770 const char * const trigger_name = "exclusion_trigger";
1771 const char * const pattern = "tp:tptest*";
1772 const char * const exclusions[] = {
1773 "tp:tptest2",
1774 "tp:tptest3",
1775 "tp:tptest4",
1776 "tp:tptest5"
1777 };
1778
1779 notification_channel = lttng_notification_channel_create(
1780 lttng_session_daemon_notification_endpoint);
1781 ok(notification_channel, "Notification channel object creation");
1782
1783 create_tracepoint_event_rule_trigger(pattern, ctrl_trigger_name, NULL,
26e2f47b
JR
1784 0, NULL, domain_type, NULL, &ctrl_condition,
1785 &ctrl_trigger);
3e4ee3b3
FD
1786
1787 nc_status = lttng_notification_channel_subscribe(
1788 notification_channel, ctrl_condition);
1789 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1790 "Subscribe to tracepoint event rule condition");
1791
1792 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 4,
26e2f47b
JR
1793 exclusions, domain_type, NULL, &condition,
1794 &trigger);
3e4ee3b3
FD
1795
1796 nc_status = lttng_notification_channel_subscribe(
1797 notification_channel, condition);
1798 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1799 "Subscribe to tracepoint event rule condition");
1800
1801 /*
1802 * We registered 2 notifications triggers, one with an exclusion and
1803 * one without (control).
1804 * - The trigger with an exclusion will fire once every iteration.
1805 * - The trigger without an exclusion will fire 5 times every
1806 * iteration.
1807 *
1808 * We should get 5 times as many notifications from the control
1809 * trigger.
1810 */
1811 resume_application();
1812
1813 /*
1814 * Get 6 notifications. We should get 1 for the regular trigger (with
1815 * the exclusion) and 5 from the control trigger. This works whatever
1816 * the order we receive the notifications.
1817 */
d150e7e5
JR
1818 for (i = 0; i < notification_count; i++) {
1819 const char *name;
1820 struct lttng_notification *notification = get_next_notification(
3e4ee3b3
FD
1821 notification_channel);
1822
d150e7e5
JR
1823 ok(notification, "Received notification (%d/%d)", i + 1,
1824 notification_count);
1825
1826 /* Error. */
1827 if (notification == NULL) {
1828 goto end;
1829 }
1830
1831 name = get_notification_trigger_name(notification);
1832 if (name == NULL) {
1833 lttng_notification_destroy(notification);
1834 goto end;
1835 }
1836
3e4ee3b3
FD
1837 if (strcmp(ctrl_trigger_name, name) == 0) {
1838 ctrl_count++;
1839 } else if (strcmp(trigger_name, name) == 0) {
1840 count++;
1841 }
1842
d150e7e5 1843 lttng_notification_destroy(notification);
3e4ee3b3
FD
1844 }
1845
1846 ok(ctrl_count / 5 == count,
1847 "Got 5 times as many control notif as of regular notif");
1848
d150e7e5 1849end:
3e4ee3b3
FD
1850 suspend_application();
1851
1852 lttng_unregister_trigger(trigger);
1853 lttng_unregister_trigger(ctrl_trigger);
1854 lttng_notification_channel_destroy(notification_channel);
1855 lttng_trigger_destroy(trigger);
1856 lttng_trigger_destroy(ctrl_trigger);
1857 lttng_condition_destroy(condition);
1858 lttng_condition_destroy(ctrl_condition);
1859 return;
1860}
1861
f46376a1 1862static void test_kprobe_event_rule_notification(void)
51704c8e
FD
1863{
1864 int i, ret;
a5c2d2a7 1865 enum lttng_error_code ret_code;
51704c8e
FD
1866 const int notification_count = 3;
1867 enum lttng_notification_channel_status nc_status;
1868 enum lttng_event_rule_status event_rule_status;
51704c8e
FD
1869 struct lttng_notification_channel *notification_channel = NULL;
1870 struct lttng_condition *condition = NULL;
1871 struct lttng_kernel_probe_location *location = NULL;
1872 struct lttng_event_rule *event_rule = NULL;
1873 struct lttng_action *action = NULL;
1874 struct lttng_trigger *trigger = NULL;
1875 const char * const trigger_name = "kprobe_trigger";
1876 const char * const symbol_name = "lttng_test_filter_event_write";
1877
1878 action = lttng_action_notify_create();
1879 if (!action) {
1880 fail("Failed to create notify action");
1881 goto end;
1882 }
1883
1884 location = lttng_kernel_probe_location_symbol_create(symbol_name, 0);
1885 if (!location) {
1886 fail("Failed to create kernel probe location");
1887 goto end;
1888 }
1889
1890 notification_channel = lttng_notification_channel_create(
1891 lttng_session_daemon_notification_endpoint);
1892 ok(notification_channel, "Notification channel object creation");
1893
85522de5 1894 event_rule = lttng_event_rule_kernel_kprobe_create(location);
51704c8e
FD
1895 ok(event_rule, "kprobe event rule object creation");
1896
85522de5 1897 event_rule_status = lttng_event_rule_kernel_kprobe_set_event_name(
51704c8e
FD
1898 event_rule, trigger_name);
1899 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
1900 "Setting kprobe event rule name: '%s'", trigger_name);
1901
8dbb86b8 1902 condition = lttng_condition_event_rule_matches_create(event_rule);
51704c8e
FD
1903 ok(condition, "Condition event rule object creation");
1904
1905 /* Register the trigger for condition. */
1906 trigger = lttng_trigger_create(condition, action);
1907 if (!trigger) {
1908 fail("Failed to create trigger with kernel probe event rule condition and notify action");
1909 goto end;
1910 }
1911
a5c2d2a7
JG
1912 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
1913 if (ret_code != LTTNG_OK) {
51704c8e
FD
1914 fail("Failed to register trigger with kernel probe event rule condition and notify action");
1915 goto end;
1916 }
1917
1918 nc_status = lttng_notification_channel_subscribe(
1919 notification_channel, condition);
1920 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
1921 "Subscribe to tracepoint event rule condition");
1922
1923 resume_application();
1924
1925 for (i = 0; i < notification_count; i++) {
d150e7e5 1926 struct lttng_notification *notification = get_next_notification(
51704c8e
FD
1927 notification_channel);
1928
d150e7e5
JR
1929 ok(notification, "Received notification (%d/%d)", i + 1,
1930 notification_count);
1931
1932 /* Error. */
1933 if (notification == NULL) {
1934 goto end;
1935 }
1936
1937 ret = validator_notification_trigger_name(notification, trigger_name);
1938 lttng_notification_destroy(notification);
1939 if (ret) {
1940 goto end;
1941 }
51704c8e
FD
1942 }
1943
1944end:
1945 suspend_application();
1946 lttng_notification_channel_destroy(notification_channel);
1947 lttng_unregister_trigger(trigger);
1948 lttng_trigger_destroy(trigger);
1949 lttng_action_destroy(action);
aab0598f 1950 lttng_event_rule_destroy(event_rule);
51704c8e
FD
1951 lttng_condition_destroy(condition);
1952 lttng_kernel_probe_location_destroy(location);
1953 return;
1954}
1955
45294d8a 1956static void test_uprobe_event_rule_notification(
45294d8a
FD
1957 const char *testapp_path,
1958 const char *test_symbol_name)
1959{
1960 int i, ret;
a5c2d2a7 1961 enum lttng_error_code ret_code;
45294d8a
FD
1962 const int notification_count = 3;
1963 enum lttng_notification_channel_status nc_status;
1964 enum lttng_event_rule_status event_rule_status;
45294d8a
FD
1965 struct lttng_notification_channel *notification_channel = NULL;
1966 struct lttng_userspace_probe_location *probe_location = NULL;
1967 struct lttng_userspace_probe_location_lookup_method *lookup_method =
1968 NULL;
1969 struct lttng_condition *condition = NULL;
1970 struct lttng_event_rule *event_rule = NULL;
1971 struct lttng_action *action = NULL;
1972 struct lttng_trigger *trigger = NULL;
1973 const char * const trigger_name = "uprobe_trigger";
1974
1975 action = lttng_action_notify_create();
1976 if (!action) {
1977 fail("Failed to create notify action");
1978 goto end;
1979 }
1980
1981 lookup_method = lttng_userspace_probe_location_lookup_method_function_elf_create();
1982 if (!lookup_method) {
1983 fail("Setup error on userspace probe lookup method creation");
1984 goto end;
1985 }
1986
1987 probe_location = lttng_userspace_probe_location_function_create(
1988 testapp_path, test_symbol_name, lookup_method);
1989 if (!probe_location) {
1990 fail("Failed to create userspace probe location");
1991 goto end;
1992 }
1993
1994 notification_channel = lttng_notification_channel_create(
1995 lttng_session_daemon_notification_endpoint);
1996 ok(notification_channel, "Notification channel object creation");
1997
46fd07ac 1998 event_rule = lttng_event_rule_kernel_uprobe_create(probe_location);
45294d8a
FD
1999 ok(event_rule, "kprobe event rule object creation");
2000
46fd07ac 2001 event_rule_status = lttng_event_rule_kernel_uprobe_set_event_name(
45294d8a
FD
2002 event_rule, trigger_name);
2003 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2004 "Setting uprobe event rule name: '%s'", trigger_name);
2005
8dbb86b8 2006 condition = lttng_condition_event_rule_matches_create(event_rule);
45294d8a
FD
2007 ok(condition, "Condition event rule object creation");
2008
2009 /* Register the trigger for condition. */
2010 trigger = lttng_trigger_create(condition, action);
2011 if (!trigger) {
2012 fail("Failed to create trigger with userspace probe event rule condition and notify action");
2013 goto end;
2014 }
2015
a5c2d2a7
JG
2016 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
2017 if (ret_code != LTTNG_OK) {
45294d8a
FD
2018 fail("Failed to register trigger with userspace probe event rule condition and notify action");
2019 goto end;
2020 }
2021
2022 nc_status = lttng_notification_channel_subscribe(
2023 notification_channel, condition);
2024 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2025 "Subscribe to tracepoint event rule condition");
2026
2027 resume_application();
2028
d150e7e5
JR
2029 for (i = 0; i < 3; i++) {
2030 struct lttng_notification *notification = get_next_notification(
45294d8a
FD
2031 notification_channel);
2032
d150e7e5
JR
2033 ok(notification, "Received notification (%d/%d)", i + 1,
2034 notification_count);
2035
2036 /* Error. */
2037 if (notification == NULL) {
2038 goto end;
2039 }
2040
2041 ret = validator_notification_trigger_name(notification, trigger_name);
2042 lttng_notification_destroy(notification);
2043 if (ret) {
2044 goto end;
2045 }
45294d8a
FD
2046 }
2047end:
2048 suspend_application();
2049
2050 lttng_notification_channel_destroy(notification_channel);
2051 lttng_unregister_trigger(trigger);
2052 lttng_trigger_destroy(trigger);
2053 lttng_action_destroy(action);
a877d1b5 2054 lttng_userspace_probe_location_destroy(probe_location);
45294d8a
FD
2055 lttng_event_rule_destroy(event_rule);
2056 lttng_condition_destroy(condition);
2057 return;
2058}
2059
f46376a1 2060static void test_syscall_event_rule_notification(void)
aab0598f
FD
2061{
2062 int i, ret;
a5c2d2a7 2063 enum lttng_error_code ret_code;
aab0598f
FD
2064 const int notification_count = 3;
2065 enum lttng_notification_channel_status nc_status;
2066 enum lttng_event_rule_status event_rule_status;
aab0598f
FD
2067 struct lttng_notification_channel *notification_channel = NULL;
2068 struct lttng_condition *condition = NULL;
2069 struct lttng_event_rule *event_rule = NULL;
2070 struct lttng_action *action = NULL;
2071 struct lttng_trigger *trigger = NULL;
2072 const char * const trigger_name = "syscall_trigger";
2073 const char * const syscall_name = "openat";
2074
2075 action = lttng_action_notify_create();
2076 if (!action) {
2077 fail("Failed to create notify action");
2078 goto end;
2079 }
2080
2081 notification_channel = lttng_notification_channel_create(
2082 lttng_session_daemon_notification_endpoint);
2083 ok(notification_channel, "Notification channel object creation");
2084
4f7da553 2085 event_rule = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY);
aab0598f
FD
2086 ok(event_rule, "syscall event rule object creation");
2087
4f7da553 2088 event_rule_status = lttng_event_rule_kernel_syscall_set_name_pattern(
aab0598f
FD
2089 event_rule, syscall_name);
2090 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2091 "Setting syscall event rule pattern: '%s'", syscall_name);
2092
8dbb86b8 2093 condition = lttng_condition_event_rule_matches_create(event_rule);
aab0598f
FD
2094 ok(condition, "Condition syscall event rule object creation");
2095
2096 /* Register the trigger for condition. */
2097 trigger = lttng_trigger_create(condition, action);
2098 if (!trigger) {
2099 fail("Failed to create trigger with syscall event rule condition and notify action");
2100 goto end;
2101 }
2102
a5c2d2a7
JG
2103 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
2104 if (ret_code != LTTNG_OK) {
aab0598f
FD
2105 fail("Failed to register trigger with syscall event rule condition and notify action");
2106 goto end;
2107 }
2108
2109 nc_status = lttng_notification_channel_subscribe(
2110 notification_channel, condition);
2111 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2112 "Subscribe to tracepoint event rule condition");
2113
2114 resume_application();
2115
2116 for (i = 0; i < notification_count; i++) {
d150e7e5 2117 struct lttng_notification *notification = get_next_notification(
aab0598f
FD
2118 notification_channel);
2119
d150e7e5
JR
2120 ok(notification, "Received notification (%d/%d)", i + 1,
2121 notification_count);
2122
2123 /* Error. */
2124 if (notification == NULL) {
2125 goto end;
2126 }
2127
2128 ret = validator_notification_trigger_name(notification, trigger_name);
2129 lttng_notification_destroy(notification);
2130 if (ret) {
2131 goto end;
2132 }
aab0598f
FD
2133 }
2134end:
2135 suspend_application();
2136 lttng_notification_channel_destroy(notification_channel);
2137 lttng_unregister_trigger(trigger);
2138 lttng_trigger_destroy(trigger);
2139 lttng_action_destroy(action);
2140 lttng_condition_destroy(condition);
2141 return;
2142}
2143
f46376a1 2144static void test_syscall_event_rule_notification_filter(void)
acb98866
FD
2145{
2146 int i, ret;
a5c2d2a7 2147 enum lttng_error_code ret_code;
acb98866
FD
2148 const int notification_count = 3;
2149 enum lttng_notification_channel_status nc_status;
2150 enum lttng_event_rule_status event_rule_status;
acb98866
FD
2151 struct lttng_notification_channel *notification_channel = NULL;
2152 struct lttng_condition *condition = NULL;
2153 struct lttng_event_rule *event_rule = NULL;
2154 struct lttng_action *action = NULL;
2155 struct lttng_trigger *trigger = NULL;
2156 const char * const trigger_name = "syscall_trigger";
2157 const char * const syscall_name = "openat";
2158 const char * const filter_pattern = "filename == \"/proc/cpuinfo\"";
2159
2160 action = lttng_action_notify_create();
2161 if (!action) {
2162 fail("Failed to create notify action");
2163 goto end;
2164 }
2165
2166 notification_channel = lttng_notification_channel_create(
2167 lttng_session_daemon_notification_endpoint);
2168 ok(notification_channel, "Notification channel object creation");
2169
4f7da553 2170 event_rule = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY);
acb98866
FD
2171 ok(event_rule, "syscall event rule object creation");
2172
4f7da553 2173 event_rule_status = lttng_event_rule_kernel_syscall_set_name_pattern(
acb98866
FD
2174 event_rule, syscall_name);
2175 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2176 "Setting syscall event rule pattern: '%s'", syscall_name);
2177
4f7da553 2178 event_rule_status = lttng_event_rule_kernel_syscall_set_filter(
acb98866
FD
2179 event_rule, filter_pattern);
2180 ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK,
2181 "Setting filter: '%s'", filter_pattern);
2182
8dbb86b8 2183 condition = lttng_condition_event_rule_matches_create(event_rule);
acb98866
FD
2184 ok(condition, "Condition event rule object creation");
2185
2186 /* Register the triggers for condition */
2187 trigger = lttng_trigger_create(condition, action);
2188 if (!trigger) {
2189 fail("Failed to create trigger with syscall filtering event rule condition and notify action");
2190 goto end;
2191 }
2192
a5c2d2a7
JG
2193 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
2194 if (ret_code != LTTNG_OK) {
acb98866
FD
2195 fail("Failed to register trigger with syscall filtering event rule condition and notify action");
2196 goto end;
2197 }
2198
2199 nc_status = lttng_notification_channel_subscribe(
2200 notification_channel, condition);
2201 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2202 "Subscribe to tracepoint event rule condition");
2203
2204 resume_application();
2205
d150e7e5
JR
2206 for (i = 0; i < notification_count; i++) {
2207 struct lttng_notification *notification = get_next_notification(
acb98866
FD
2208 notification_channel);
2209
d150e7e5
JR
2210 ok(notification, "Received notification (%d/%d)", i + 1,
2211 notification_count);
2212
2213 /* Error. */
2214 if (notification == NULL) {
2215 goto end;
2216 }
2217
2218 ret = validator_notification_trigger_name(notification, trigger_name);
2219 lttng_notification_destroy(notification);
2220 if (ret) {
2221 goto end;
2222 }
acb98866
FD
2223 }
2224
2225end:
2226 suspend_application();
2227
2228 lttng_unregister_trigger(trigger);
2229 lttng_notification_channel_destroy(notification_channel);
2230 lttng_trigger_destroy(trigger);
2231 lttng_event_rule_destroy(event_rule);
2232 lttng_condition_destroy(condition);
2233 return;
2234}
2235
26e2f47b
JR
2236static int generate_capture_descr(struct lttng_condition *condition)
2237{
2238 int ret, i;
2239 struct lttng_event_expr *expr = NULL;
2240 const unsigned int basic_field_count = sizeof(test_capture_base_fields) /
2241 sizeof(*test_capture_base_fields);
2242 enum lttng_condition_status cond_status;
2243
2244 for (i = 0; i < basic_field_count; i++) {
2245 diag("Adding capture descriptor '%s'",
2246 test_capture_base_fields[i].field_name);
2247
2248 switch (test_capture_base_fields[i].field_type) {
2249 case FIELD_TYPE_PAYLOAD:
2250 expr = lttng_event_expr_event_payload_field_create(
2251 test_capture_base_fields[i].field_name);
2252 break;
2253 case FIELD_TYPE_CONTEXT:
2254 expr = lttng_event_expr_channel_context_field_create(
2255 test_capture_base_fields[i].field_name);
2256 break;
2257 case FIELD_TYPE_ARRAY_FIELD:
2258 {
2259 int nb_matches;
2260 unsigned int index;
2261 char field_name[FIELD_NAME_MAX_LEN];
2262 struct lttng_event_expr *array_expr = NULL;
2263
2264 nb_matches = sscanf(test_capture_base_fields[i].field_name,
2265 "%[^[][%u]", field_name, &index);
2266 if (nb_matches != 2) {
2267 fail("Unexpected array field name format: field name = '%s'",
2268 test_capture_base_fields[i].field_name);
2269 ret = 1;
2270 goto end;
2271 }
2272
2273 array_expr = lttng_event_expr_event_payload_field_create(
2274 field_name);
2275
2276 expr = lttng_event_expr_array_field_element_create(
2277 array_expr, index);
2278 break;
2279 }
2280 case FIELD_TYPE_APP_CONTEXT:
2281 fail("Application context tests are not implemented yet.");
2282 /* fallthrough. */
2283 default:
2284 ret = 1;
2285 goto end;
2286 }
2287
2288 if (expr == NULL) {
2289 fail("Failed to create capture expression");
2290 ret = -1;
2291 goto end;
2292 }
2293
8dbb86b8 2294 cond_status = lttng_condition_event_rule_matches_append_capture_descriptor(
26e2f47b
JR
2295 condition, expr);
2296 if (cond_status != LTTNG_CONDITION_STATUS_OK) {
2297 fail("Failed to append capture descriptor");
2298 ret = -1;
2299 lttng_event_expr_destroy(expr);
2300 goto end;
2301 }
2302 }
2303
2304 ret = 0;
2305
2306end:
2307 return ret;
2308}
2309
2310static int validator_notification_trigger_capture(
2311 enum lttng_domain_type domain,
2312 struct lttng_notification *notification,
2313 const int iteration)
2314{
2315 int ret;
2316 unsigned int capture_count, i;
8dbb86b8
JR
2317 enum lttng_evaluation_event_rule_matches_status
2318 event_rule_matches_evaluation_status;
26e2f47b
JR
2319 enum lttng_event_field_value_status event_field_value_status;
2320 const struct lttng_evaluation *evaluation;
2321 const struct lttng_event_field_value *captured_fields;
2322 bool at_least_one_error = false;
2323
2324 evaluation = lttng_notification_get_evaluation(notification);
2325 if (evaluation == NULL) {
2326 fail("Failed to get evaluation from notification during trigger capture test");
2327 ret = 1;
2328 goto end;
2329 }
2330
8dbb86b8
JR
2331 event_rule_matches_evaluation_status =
2332 lttng_evaluation_event_rule_matches_get_captured_values(
3ce811ee 2333 evaluation, &captured_fields);
8dbb86b8
JR
2334 if (event_rule_matches_evaluation_status !=
2335 LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_OK) {
26e2f47b 2336 diag("Failed to get event rule evaluation captured values: status = %d",
8dbb86b8 2337 (int) event_rule_matches_evaluation_status);
26e2f47b
JR
2338 ret = 1;
2339 goto end;
2340 }
2341
2342 event_field_value_status =
2343 lttng_event_field_value_array_get_length(captured_fields,
2344 &capture_count);
2345 if (event_field_value_status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
2346 fail("Failed to get count of captured value field array");
2347 ret = 1;
2348 goto end;
2349 }
2350
2351 for (i = 0; i < capture_count; i++) {
2352 const struct lttng_event_field_value *captured_field = NULL;
2353 validate_cb validate;
2354 bool expected;
2355
2356 diag("Validating capture of field '%s'",
2357 test_capture_base_fields[i].field_name);
2358 event_field_value_status =
2359 lttng_event_field_value_array_get_element_at_index(
2360 captured_fields, i,
2361 &captured_field);
2362
2363 switch(domain) {
2364 case LTTNG_DOMAIN_UST:
2365 expected = test_capture_base_fields[i].expected_ust;
2366 break;
2367 case LTTNG_DOMAIN_KERNEL:
2368 expected = test_capture_base_fields[i].expected_kernel;
2369 break;
2370 default:
2371 fail("Unexpected domain encountered: domain = %d",
2372 (int) domain);
2373 ret = 1;
2374 goto end;
2375 }
2376
2377 if (domain == LTTNG_DOMAIN_UST) {
2378 validate = test_capture_base_fields[i].validate_ust;
2379 } else {
2380 validate = test_capture_base_fields[i].validate_kernel;
2381 }
2382
2383 if (!expected) {
2384 ok(event_field_value_status == LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE,
2385 "No payload captured");
2386 continue;
2387 }
2388
2389 if (event_field_value_status != LTTNG_EVENT_FIELD_VALUE_STATUS_OK) {
2390 if (event_field_value_status ==
2391 LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE) {
2392 fail("Expected a capture but it is unavailable");
2393 } else {
2394 fail("lttng_event_field_value_array_get_element_at_index returned an error: status = %d",
2395 (int) event_field_value_status);
2396 }
2397
2398 ret = 1;
2399 goto end;
2400 }
2401
2402 diag("Captured field of type %s",
2403 field_value_type_to_str(
2404 lttng_event_field_value_get_type(captured_field)));
2405
a0377dfe 2406 LTTNG_ASSERT(validate);
26e2f47b
JR
2407 ret = validate(captured_field, iteration);
2408 if (ret) {
2409 at_least_one_error = true;
2410 }
2411 }
2412
2413 ret = at_least_one_error;
2414
2415end:
2416 return ret;
2417}
2418
2419static void test_tracepoint_event_rule_notification_capture(
2420 enum lttng_domain_type domain_type)
2421{
2422 enum lttng_notification_channel_status nc_status;
2423
2424 int i, ret;
2425 struct lttng_condition *condition = NULL;
2426 struct lttng_notification_channel *notification_channel = NULL;
2427 struct lttng_trigger *trigger = NULL;
2428 const char *trigger_name = "my_precious";
2429 const char *pattern;
2430
2431 if (domain_type == LTTNG_DOMAIN_UST) {
2432 pattern = "tp:tptest";
2433 } else {
2434 pattern = "lttng_test_filter_event";
2435 }
2436
2437 create_tracepoint_event_rule_trigger(pattern, trigger_name, NULL, 0,
2438 NULL, domain_type, generate_capture_descr, &condition,
2439 &trigger);
2440
2441 notification_channel = lttng_notification_channel_create(
2442 lttng_session_daemon_notification_endpoint);
2443 ok(notification_channel, "Notification channel object creation");
2444
2445 nc_status = lttng_notification_channel_subscribe(
2446 notification_channel, condition);
2447 ok(nc_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
2448 "Subscribe to tracepoint event rule condition");
2449
2450 resume_application();
2451
2452 /* Get 3 notifications */
2453 for (i = 0; i < 3; i++) {
2454 struct lttng_notification *notification = get_next_notification(
2455 notification_channel);
2456 ok(notification, "Received notification");
2457
2458 /* Error */
2459 if (notification == NULL) {
2460 goto end;
2461 }
2462
2463 ret = validator_notification_trigger_name(notification, trigger_name);
2464 if (ret) {
2465 lttng_notification_destroy(notification);
2466 goto end;
2467 }
2468
2469 ret = validator_notification_trigger_capture(domain_type, notification, i);
2470 if (ret) {
2471 lttng_notification_destroy(notification);
2472 goto end;
2473 }
2474
2475 lttng_notification_destroy(notification);
2476 }
2477
2478end:
2479 suspend_application();
2480 lttng_notification_channel_destroy(notification_channel);
2481 lttng_unregister_trigger(trigger);
2482 lttng_trigger_destroy(trigger);
2483 lttng_condition_destroy(condition);
2484 return;
2485}
2486
434f8068
JR
2487int main(int argc, const char *argv[])
2488{
069fc1c5 2489 int test_scenario;
434f8068
JR
2490 const char *domain_type_string = NULL;
2491 enum lttng_domain_type domain_type = LTTNG_DOMAIN_NONE;
2492
a740a242
FD
2493 if (argc < 5) {
2494 fail("Missing test scenario, domain type, pid, or application state file argument(s)");
434f8068
JR
2495 goto error;
2496 }
2497
069fc1c5
FD
2498 test_scenario = atoi(argv[1]);
2499 domain_type_string = argv[2];
a740a242
FD
2500 app_pid = (pid_t) atoi(argv[3]);
2501 app_state_file = argv[4];
434f8068
JR
2502
2503 if (!strcmp("LTTNG_DOMAIN_UST", domain_type_string)) {
2504 domain_type = LTTNG_DOMAIN_UST;
2505 }
2506 if (!strcmp("LTTNG_DOMAIN_KERNEL", domain_type_string)) {
2507 domain_type = LTTNG_DOMAIN_KERNEL;
2508 }
2509 if (domain_type == LTTNG_DOMAIN_NONE) {
2510 fail("Unknown domain type");
2511 goto error;
2512 }
2513
a740a242
FD
2514 /*
2515 * Test cases are responsible for resuming the app when needed
2516 * and making sure it's suspended when returning.
2517 */
2518 suspend_application();
2519
069fc1c5
FD
2520 switch (test_scenario) {
2521 case 1:
2522 {
a5c2d2a7 2523 plan_tests(41);
7948461b 2524
069fc1c5 2525 /* Test cases that need gen-ust-event testapp. */
a740a242 2526 diag("Test basic notification error paths for %s domain",
069fc1c5
FD
2527 domain_type_string);
2528 test_invalid_channel_subscription(domain_type);
7948461b
FD
2529
2530 diag("Test tracepoint event rule notifications for domain %s",
2531 domain_type_string);
2532 test_tracepoint_event_rule_notification(domain_type);
2533
a740a242
FD
2534 diag("Test tracepoint event rule notifications with filter for domain %s",
2535 domain_type_string);
2536 test_tracepoint_event_rule_notification_filter(domain_type);
069fc1c5
FD
2537 break;
2538 }
2539 case 2:
2540 {
45294d8a 2541 const char *session_name, *channel_name;
d150e7e5 2542
069fc1c5
FD
2543 /* Test cases that need a tracing session enabled. */
2544 plan_tests(99);
7676e0d2 2545
069fc1c5
FD
2546 /*
2547 * Argument 7 and upward are named pipe location for consumerd
2548 * control.
2549 */
2550 named_pipe_args_start = 7;
2551
2552 if (argc < 8) {
2553 fail("Missing parameter for tests to run %d", argc);
2554 goto error;
2555 }
434f8068 2556
069fc1c5
FD
2557 nb_args = argc;
2558
a740a242
FD
2559 session_name = argv[5];
2560 channel_name = argv[6];
069fc1c5
FD
2561
2562 test_subscription_twice(session_name, channel_name,
2563 domain_type);
2564
2565 diag("Test trigger for domain %s with buffer_usage_low condition",
2566 domain_type_string);
2567 test_triggers_buffer_usage_condition(session_name, channel_name,
069fc1c5
FD
2568 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
2569
2570 diag("Test trigger for domain %s with buffer_usage_high condition",
2571 domain_type_string);
2572 test_triggers_buffer_usage_condition(session_name, channel_name,
069fc1c5
FD
2573 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
2574
2575 diag("Test buffer usage notification channel api for domain %s",
2576 domain_type_string);
2577 test_buffer_usage_notification_channel(session_name, channel_name,
2578 domain_type, argv);
2579 break;
2580 }
3e4ee3b3
FD
2581 case 3:
2582 {
2583 /*
2584 * Test cases that need a test app with more than one event
2585 * type.
2586 */
a5c2d2a7 2587 plan_tests(23);
3e4ee3b3
FD
2588
2589 /*
2590 * At the moment, the only test case of this scenario is
2591 * exclusion which is only supported by UST.
2592 */
a0377dfe 2593 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_UST);
3e4ee3b3
FD
2594 diag("Test tracepoint event rule notifications with exclusion for domain %s",
2595 domain_type_string);
2596 test_tracepoint_event_rule_notification_exclusion(domain_type);
2597
2598 break;
2599 }
51704c8e
FD
2600 case 4:
2601 {
a3ea2340 2602 plan_tests(11);
51704c8e 2603 /* Test cases that need the kernel tracer. */
a0377dfe 2604 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_KERNEL);
aab0598f 2605
51704c8e
FD
2606 diag("Test kprobe event rule notifications for domain %s",
2607 domain_type_string);
2608
f46376a1 2609 test_kprobe_event_rule_notification();
51704c8e
FD
2610
2611 break;
2612 }
aab0598f
FD
2613 case 5:
2614 {
a3ea2340 2615 plan_tests(23);
aab0598f 2616 /* Test cases that need the kernel tracer. */
a0377dfe 2617 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_KERNEL);
aab0598f
FD
2618
2619 diag("Test syscall event rule notifications for domain %s",
2620 domain_type_string);
2621
f46376a1 2622 test_syscall_event_rule_notification();
aab0598f 2623
acb98866
FD
2624 diag("Test syscall filtering event rule notifications for domain %s",
2625 domain_type_string);
2626
f46376a1 2627 test_syscall_event_rule_notification_filter();
acb98866 2628
aab0598f
FD
2629 break;
2630 }
45294d8a
FD
2631 case 6:
2632 {
2633 const char *testapp_path, *test_symbol_name;
2634
a3ea2340 2635 plan_tests(11);
45294d8a
FD
2636
2637 if (argc < 7) {
2638 fail("Missing parameter for tests to run %d", argc);
2639 goto error;
2640 }
2641
2642 testapp_path = argv[5];
2643 test_symbol_name = argv[6];
2644 /* Test cases that need the kernel tracer. */
a0377dfe 2645 LTTNG_ASSERT(domain_type == LTTNG_DOMAIN_KERNEL);
45294d8a
FD
2646
2647 diag("Test userspace-probe event rule notifications for domain %s",
2648 domain_type_string);
2649
2650 test_uprobe_event_rule_notification(
f46376a1 2651 testapp_path, test_symbol_name);
45294d8a
FD
2652
2653 break;
2654 }
26e2f47b
JR
2655 case 7:
2656 {
2657 switch(domain_type) {
2658 case LTTNG_DOMAIN_UST:
a5c2d2a7 2659 plan_tests(221);
26e2f47b
JR
2660 break;
2661 case LTTNG_DOMAIN_KERNEL:
a3ea2340 2662 plan_tests(215);
26e2f47b
JR
2663 break;
2664 default:
a0377dfe 2665 abort();
26e2f47b
JR
2666 }
2667
2668 diag("Test tracepoint event rule notification captures for domain %s",
2669 domain_type_string);
2670 test_tracepoint_event_rule_notification_capture(domain_type);
2671
2672 break;
2673 }
2674
069fc1c5
FD
2675 default:
2676 abort();
2677 }
90fcb2ec 2678
434f8068
JR
2679error:
2680 return exit_status();
2681}
2682
This page took 0.159417 seconds and 4 git commands to generate.