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