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