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