1c9aae32c23afbba93b3f5b674380f08dea30caa
[lttng-tools.git] / tests / regression / tools / trigger / name / trigger_name.cpp
1 /*
2 * trigger_name.c
3 *
4 * Tests suite for anonymous, named, and automatic name triggers.
5 *
6 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * SPDX-License-Identifier: MIT
9 *
10 */
11
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <tap/tap.h>
15 #include <stdint.h>
16 #include <string.h>
17 #include <lttng/lttng.h>
18 #include <common/macros.h>
19
20 #define TEST_COUNT 70
21
22 enum unregistration_trigger_instance {
23 UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION,
24 UNREGISTRATION_TRIGGER_INSTANCE_FROM_LISTING,
25 };
26
27 typedef void (*test_function)(enum unregistration_trigger_instance);
28
29 static
30 const char *get_trigger_name(const struct lttng_trigger *trigger)
31 {
32 const char *trigger_name;
33 enum lttng_trigger_status trigger_status;
34
35 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
36 switch (trigger_status) {
37 case LTTNG_TRIGGER_STATUS_OK:
38 break;
39 case LTTNG_TRIGGER_STATUS_UNSET:
40 trigger_name = "(anonymous)";
41 break;
42 default:
43 trigger_name = "(failed to get name)";
44 break;
45 }
46
47 return trigger_name;
48 }
49
50 static
51 const char *unregistration_trigger_instance_name(
52 enum unregistration_trigger_instance unregistration_trigger)
53 {
54 const char *name;
55
56 switch (unregistration_trigger) {
57 case UNREGISTRATION_TRIGGER_INSTANCE_FROM_LISTING:
58 name = "from listing";
59 break;
60 case UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION:
61 name = "used for registration";
62 break;
63 default:
64 abort();
65 }
66
67 return name;
68 }
69
70 /*
71 * Returns a negative error code on error, else the number of unregistered
72 * triggers.
73 */
74 static
75 int unregister_all_triggers(void)
76 {
77 int ret;
78 enum lttng_error_code ret_code;
79 enum lttng_trigger_status trigger_status;
80 struct lttng_triggers *triggers = NULL;
81 unsigned int trigger_count, i, unregistered_trigger_count = 0;
82
83 ret_code = lttng_list_triggers(&triggers);
84 if (ret_code != LTTNG_OK) {
85 fail("Failed to list triggers");
86 ret = -1;
87 goto end;
88 }
89
90 trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
91 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
92 fail("Failed to get count of triggers returned by listing");
93 ret = -1;
94 goto end;
95 }
96
97 for (i = 0; i < trigger_count; i++) {
98 const struct lttng_trigger *trigger;
99
100 trigger = lttng_triggers_get_at_index(triggers, i);
101 LTTNG_ASSERT(trigger);
102
103 ret = lttng_unregister_trigger(trigger);
104 if (ret) {
105 const char *name;
106 enum lttng_trigger_status get_name_status =
107 lttng_trigger_get_name(trigger, &name);
108 if (get_name_status == LTTNG_TRIGGER_STATUS_OK) {
109 fail("Failed to unregister trigger: trigger name = '%s'", name);
110 } else {
111 fail("Failed to unregister trigger");
112 }
113 goto end;
114 }
115
116 unregistered_trigger_count++;
117 }
118
119 ret = (int) unregistered_trigger_count;
120
121 end:
122 lttng_triggers_destroy(triggers);
123 return ret;
124 }
125
126 static
127 int get_registered_triggers_count(void)
128 {
129 int ret;
130 enum lttng_error_code ret_code;
131 enum lttng_trigger_status trigger_status;
132 struct lttng_triggers *triggers = NULL;
133 unsigned int trigger_count;
134
135 ret_code = lttng_list_triggers(&triggers);
136 if (ret_code != LTTNG_OK) {
137 fail("Failed to list triggers");
138 ret = -1;
139 goto end;
140 }
141
142 trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
143 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
144 fail("Failed to get count of triggers returned by listing");
145 ret = -1;
146 goto end;
147 }
148
149 ret = (int) trigger_count;
150
151 end:
152 lttng_triggers_destroy(triggers);
153 return ret;
154 }
155
156 /*
157 * Create a generic trigger. The specifics of the condition and action are not
158 * important for the purposes of this test.
159 */
160 static
161 struct lttng_trigger *create_trigger(uint64_t threshold)
162 {
163 struct lttng_condition *condition = NULL;
164 struct lttng_action *action = NULL;
165 struct lttng_trigger *trigger = NULL;
166 enum lttng_condition_status condition_status;
167 const char * const session_name = "test session";
168
169 condition = lttng_condition_session_consumed_size_create();
170 if (!condition) {
171 fail("Failed to create 'session consumed size' condition");
172 goto end;
173 }
174
175 condition_status = lttng_condition_session_consumed_size_set_session_name(condition, session_name);
176 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
177 fail("Failed to set session name on 'session consumed size' condition");
178 goto end;
179 }
180
181 condition_status = lttng_condition_session_consumed_size_set_threshold(
182 condition, threshold);
183 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
184 fail("Failed to set threshold on 'session consumed size' condition");
185 goto end;
186 }
187
188 action = lttng_action_notify_create();
189 if (!action) {
190 fail("Failed to create 'notify' action");
191 goto end;
192 }
193
194 trigger = lttng_trigger_create(condition, action);
195 if (!trigger) {
196 fail("Failed to create trigger");
197 goto end;
198 }
199
200 end:
201 lttng_condition_destroy(condition);
202 lttng_action_destroy(action);
203 return trigger;
204 }
205
206 static
207 void register_anonymous_trigger(
208 enum unregistration_trigger_instance unregistration_trigger)
209 {
210 int ret;
211 struct lttng_trigger *trigger = create_trigger(0xbadc0ffee);
212 enum lttng_trigger_status trigger_status;
213 const char *trigger_name;
214 struct lttng_triggers *triggers = NULL;
215 unsigned int trigger_count, i;
216 enum lttng_error_code ret_code;
217
218 diag("Register an anonymous trigger (Unregistration performed with the trigger instance %s)",
219 unregistration_trigger_instance_name(
220 unregistration_trigger));
221
222 if (!trigger) {
223 fail("Failed to create trigger");
224 goto end;
225 }
226
227 ret = lttng_register_trigger(trigger);
228 ok(ret == 0, "Registered anonymous trigger");
229
230 trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
231 ok(trigger_status == LTTNG_TRIGGER_STATUS_UNSET,
232 "Anonymous trigger name remains unset after registration: trigger name = '%s'",
233 get_trigger_name(trigger));
234
235 ret_code = lttng_list_triggers(&triggers);
236 if (ret_code != LTTNG_OK) {
237 fail("Failed to list triggers");
238 ret = -1;
239 goto end;
240 }
241
242 trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
243 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
244 fail("Failed to get count of triggers returned by listing");
245 ret = -1;
246 goto end;
247 }
248
249 ok(trigger_count == 1, "Trigger listing returns 1 trigger");
250
251 for (i = 0; i < trigger_count; i++) {
252 const struct lttng_trigger *trigger_from_listing;
253
254 trigger_from_listing = lttng_triggers_get_at_index(triggers, i);
255 LTTNG_ASSERT(trigger_from_listing);
256
257 trigger_status = lttng_trigger_get_name(trigger_from_listing, &trigger_name);
258 ok(trigger_status == LTTNG_TRIGGER_STATUS_UNSET,
259 "Anonymous trigger returned by listing has an unset name: trigger name = '%s'",
260 get_trigger_name(trigger_from_listing));
261
262 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_FROM_LISTING) {
263 ret = lttng_unregister_trigger(trigger_from_listing);
264 ok(ret == 0, "Successfully unregistered anonymous trigger using the trigger instance returned by the listing");
265 }
266 }
267
268 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION) {
269 ret = lttng_unregister_trigger(trigger);
270 ok(ret == 0, "Successfully unregistered anonymous trigger using the trigger instance used on registration");
271 }
272
273 end:
274 lttng_triggers_destroy(triggers);
275 lttng_trigger_destroy(trigger);
276 }
277
278 static
279 void register_named_trigger(
280 enum unregistration_trigger_instance unregistration_trigger)
281 {
282 int ret;
283 struct lttng_trigger *trigger = create_trigger(0xbadc0ffee);
284 enum lttng_trigger_status trigger_status;
285 const char *returned_trigger_name;
286 struct lttng_triggers *triggers = NULL;
287 unsigned int trigger_count, i;
288 enum lttng_error_code ret_code;
289 const char * const trigger_name = "some name that is hopefully unique";
290
291 diag("Register a named trigger (Unregistration performed with the trigger instance %s)",
292 unregistration_trigger_instance_name(
293 unregistration_trigger));
294
295 if (!trigger) {
296 fail("Failed to create trigger");
297 goto end;
298 }
299
300 ret_code = lttng_register_trigger_with_name(trigger, trigger_name);
301 ok(ret_code == LTTNG_OK, "Registered trigger with name: trigger name = '%s'",
302 get_trigger_name(trigger));
303
304 trigger_status = lttng_trigger_get_name(trigger, &returned_trigger_name);
305 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
306 "Trigger name is set after registration: trigger name = '%s'",
307 get_trigger_name(trigger));
308
309 ok(!strcmp(get_trigger_name(trigger), trigger_name),
310 "Name set on trigger after registration is correct");
311
312 ret_code = lttng_list_triggers(&triggers);
313 if (ret_code != LTTNG_OK) {
314 fail("Failed to list triggers");
315 ret = -1;
316 goto end;
317 }
318
319 trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
320 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
321 fail("Failed to get count of triggers returned by listing");
322 ret = -1;
323 goto end;
324 }
325
326 ok(trigger_count == 1, "Trigger listing returns 1 trigger");
327
328 for (i = 0; i < trigger_count; i++) {
329 const struct lttng_trigger *trigger_from_listing;
330
331 trigger_from_listing = lttng_triggers_get_at_index(triggers, i);
332 LTTNG_ASSERT(trigger_from_listing);
333
334 trigger_status = lttng_trigger_get_name(trigger_from_listing, &returned_trigger_name);
335 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
336 "Trigger returned by listing has a name: trigger name = '%s'",
337 get_trigger_name(trigger_from_listing));
338
339 ok(!strcmp(get_trigger_name(trigger_from_listing),
340 trigger_name),
341 "Name set on trigger returned from listing is correct: name returned from listing = '%s', expected name = '%s'",
342 get_trigger_name(trigger_from_listing),
343 trigger_name);
344
345 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_FROM_LISTING) {
346 ret = lttng_unregister_trigger(trigger_from_listing);
347 ok(ret == 0, "Successfully unregistered named trigger using the trigger instance returned by the listing");
348 }
349 }
350
351 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION) {
352 ret = lttng_unregister_trigger(trigger);
353 ok(ret == 0, "Successfully unregistered named trigger using the trigger instance used on registration");
354 }
355
356 end:
357 lttng_triggers_destroy(triggers);
358 lttng_trigger_destroy(trigger);
359 }
360
361 static
362 void register_automatic_name_trigger(
363 enum unregistration_trigger_instance unregistration_trigger)
364 {
365 int ret;
366 struct lttng_trigger *trigger = create_trigger(0xbadc0ffee);
367 enum lttng_trigger_status trigger_status;
368 const char *returned_trigger_name;
369 struct lttng_triggers *triggers = NULL;
370 unsigned int trigger_count, i;
371 enum lttng_error_code ret_code;
372
373 diag("Register an automatic name trigger (Unregistration performed with the trigger instance %s)",
374 unregistration_trigger_instance_name(
375 unregistration_trigger));
376
377 if (!trigger) {
378 fail("Failed to create trigger");
379 goto end;
380 }
381
382 ret_code = lttng_register_trigger_with_automatic_name(trigger);
383 ok(ret_code == LTTNG_OK, "Registered trigger with automatic name");
384
385 trigger_status = lttng_trigger_get_name(trigger, &returned_trigger_name);
386 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
387 "Trigger name is set after registration: trigger name = '%s'",
388 get_trigger_name(trigger));
389
390 ok(returned_trigger_name && strlen(returned_trigger_name) > 0,
391 "Automatic name set on trigger after registration longer is not an empty string");
392
393 ret_code = lttng_list_triggers(&triggers);
394 if (ret_code != LTTNG_OK) {
395 fail("Failed to list triggers");
396 ret = -1;
397 goto end;
398 }
399
400 trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
401 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
402 fail("Failed to get count of triggers returned by listing");
403 ret = -1;
404 goto end;
405 }
406
407 ok(trigger_count == 1, "Trigger listing returns 1 trigger");
408
409 for (i = 0; i < trigger_count; i++) {
410 const struct lttng_trigger *trigger_from_listing;
411
412 trigger_from_listing = lttng_triggers_get_at_index(triggers, i);
413 LTTNG_ASSERT(trigger_from_listing);
414
415 trigger_status = lttng_trigger_get_name(trigger_from_listing, &returned_trigger_name);
416 ok(trigger_status == LTTNG_TRIGGER_STATUS_OK,
417 "Trigger returned by listing has a name: trigger name = '%s'",
418 get_trigger_name(trigger_from_listing));
419
420 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_FROM_LISTING) {
421 ret = lttng_unregister_trigger(trigger_from_listing);
422 ok(ret == 0, "Successfully unregistered automatic name trigger using the trigger instance returned by the listing");
423 }
424 }
425
426 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION) {
427 ret = lttng_unregister_trigger(trigger);
428 ok(ret == 0, "Successfully unregistered automatic trigger using the trigger instance used on registration");
429 }
430
431 end:
432 lttng_triggers_destroy(triggers);
433 lttng_trigger_destroy(trigger);
434 }
435
436 static
437 void double_register_anonymous_trigger(
438 enum unregistration_trigger_instance unregistration_trigger)
439 {
440 int ret;
441 struct lttng_trigger *trigger = create_trigger(0xbadc0ffee);
442 struct lttng_triggers *triggers = NULL;
443
444 diag("Register duplicate anonymous trigger (Unregistration performed with the trigger instance %s)",
445 unregistration_trigger_instance_name(
446 unregistration_trigger));
447
448 if (!trigger) {
449 fail("Failed to create trigger");
450 goto end;
451 }
452
453 ret = lttng_register_trigger(trigger);
454 ok(ret == 0, "Registered anonymous trigger");
455
456 ret = lttng_register_trigger(trigger);
457 ok(ret == -LTTNG_ERR_TRIGGER_EXISTS,
458 "Registering identical anonymous trigger fails with `LTTNG_ERR_TRIGGER_EXISTS`");
459
460
461 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION) {
462 ret = lttng_unregister_trigger(trigger);
463 ok(ret == 0, "Successfully unregistered anonymous trigger using the trigger instance used on registration");
464 } else {
465 ok(get_registered_triggers_count() == 1,
466 "Trigger listing returns 1 trigger");
467 ok(unregister_all_triggers() == 1,
468 "Successfully unregistered anonymous trigger using the trigger instance returned by the listing");
469 }
470
471 end:
472 lttng_triggers_destroy(triggers);
473 lttng_trigger_destroy(trigger);
474 }
475
476 static
477 void double_register_named_trigger(
478 enum unregistration_trigger_instance unregistration_trigger)
479 {
480 int ret;
481 struct lttng_trigger *trigger_a = create_trigger(0xbadc0ffee);
482 struct lttng_trigger *trigger_b = create_trigger(0xbadc0ffee);
483 struct lttng_triggers *triggers = NULL;
484 const char * const trigger_name = "a unique trigger name";
485 enum lttng_error_code ret_code;
486
487 diag("Register duplicate named trigger (Unregistration performed with the trigger instance %s)",
488 unregistration_trigger_instance_name(
489 unregistration_trigger));
490
491 if (!trigger_a || !trigger_b) {
492 fail("Failed to create triggers");
493 goto end;
494 }
495
496 ret_code = lttng_register_trigger_with_name(trigger_a, trigger_name);
497 ok(ret_code == LTTNG_OK, "Registered named trigger");
498
499 ret = lttng_register_trigger(trigger_a);
500 ok(ret == -LTTNG_ERR_INVALID,
501 "Registering a trigger instance already used for registration fails with `LTTNG_ERR_INVALID` (anonymous registration)");
502
503 ret_code = lttng_register_trigger_with_name(trigger_a, trigger_name);
504 ok(ret_code == LTTNG_ERR_INVALID,
505 "Registering a trigger instance already used for registration fails with `LTTNG_ERR_INVALID` (register with name)");
506
507 ret_code = lttng_register_trigger_with_automatic_name(trigger_a);
508 ok(ret_code == LTTNG_ERR_INVALID,
509 "Registering a trigger instance already used for registration fails with `LTTNG_ERR_INVALID` (register with automatic name)");
510
511 ret_code = lttng_register_trigger_with_name(trigger_b, trigger_name);
512 ok(ret_code == LTTNG_ERR_TRIGGER_EXISTS, "Registering trigger with an already used name fails with `LTTNG_ERR_TRIGGER_EXISTS`");
513
514 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION) {
515 ret = lttng_unregister_trigger(trigger_a);
516 ok(ret == 0, "Successfully unregistered named trigger using the trigger instance used on registration");
517 } else {
518 ok(get_registered_triggers_count() == 1,
519 "Trigger listing returns 1 trigger");
520 ok(unregister_all_triggers() == 1,
521 "Successfully unregistered named trigger using the trigger instance returned by the listing");
522 }
523
524 end:
525 lttng_triggers_destroy(triggers);
526 lttng_trigger_destroy(trigger_a);
527 lttng_trigger_destroy(trigger_b);
528 }
529
530 static
531 void double_register_automatic_name_trigger(
532 enum unregistration_trigger_instance unregistration_trigger)
533 {
534 int ret;
535 struct lttng_trigger *trigger_a = create_trigger(0xbadc0ffee);
536 struct lttng_trigger *trigger_b = create_trigger(0xbadc0ffee);
537 struct lttng_triggers *triggers = NULL;
538 enum lttng_error_code ret_code;
539
540 diag("Register duplicate automatic name trigger (Unregistration performed with the trigger instance %s)",
541 unregistration_trigger_instance_name(
542 unregistration_trigger));
543
544 if (!trigger_a || !trigger_b) {
545 fail("Failed to create triggers");
546 goto end;
547 }
548
549 ret_code = lttng_register_trigger_with_automatic_name(trigger_a);
550 ok(ret_code == LTTNG_OK, "Registered automatic name trigger: trigger name = '%s'", get_trigger_name(trigger_a));
551
552 ret = lttng_register_trigger_with_automatic_name(trigger_b);
553 ok(ret_code == LTTNG_OK, "Registering an identical trigger instance with an automatic name succeeds: trigger name = '%s'", get_trigger_name(trigger_b));
554
555 ok(strcmp(get_trigger_name(trigger_a), get_trigger_name(trigger_b)),
556 "Two identical triggers registered with an automatic name have different names");
557
558 if (unregistration_trigger == UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION) {
559 ret = lttng_unregister_trigger(trigger_a);
560 ok(ret == 0, "Successfully unregistered automatic trigger A using the trigger instance used on registration");
561
562 ret = lttng_unregister_trigger(trigger_b);
563 ok(ret == 0, "Successfully unregistered automatic trigger B using the trigger instance used on registration");
564 } else {
565 ok(get_registered_triggers_count() == 2,
566 "Trigger listing returns 2 trigger");
567 ok(unregister_all_triggers() == 2,
568 "Successfully unregistered automatic name triggers using the trigger instance returned by the listing");
569 }
570
571 end:
572 lttng_triggers_destroy(triggers);
573 lttng_trigger_destroy(trigger_a);
574 lttng_trigger_destroy(trigger_b);
575 }
576
577 static
578 void register_multiple_anonymous_triggers(void)
579 {
580 int ret;
581 struct lttng_trigger *trigger_a = create_trigger(0xbadc0ffee);
582 struct lttng_trigger *trigger_b = create_trigger(0xbadf00d);
583
584 diag("Register two different anonymous triggers");
585
586 if (!trigger_a || !trigger_b) {
587 fail("Failed to create triggers");
588 goto end;
589 }
590
591 ret = lttng_register_trigger(trigger_a);
592 ok(ret == 0, "Registered first anonymous trigger");
593
594 ret = lttng_register_trigger(trigger_b);
595 ok(ret == 0, "Registered second anonymous trigger");
596
597 ok(get_registered_triggers_count() == 2,
598 "Trigger listing returns 2 trigger");
599 ok(unregister_all_triggers() == 2,
600 "Successfully unregistered two anonymous triggers");
601
602 end:
603 lttng_trigger_destroy(trigger_a);
604 lttng_trigger_destroy(trigger_b);
605 }
606
607 const test_function test_functions[] = {
608 register_anonymous_trigger,
609 register_named_trigger,
610 register_automatic_name_trigger,
611 double_register_anonymous_trigger,
612 double_register_named_trigger,
613 double_register_automatic_name_trigger,
614 };
615
616 int main(int argc, const char **argv)
617 {
618 size_t i;
619
620 plan_tests(TEST_COUNT);
621
622 if (get_registered_triggers_count() != 0) {
623 fail("Session daemon already has registered triggers, bailing out");
624 goto end;
625 }
626
627 for (i = 0; i < ARRAY_SIZE(test_functions); i++) {
628 const test_function fn = test_functions[i];
629
630 fn(UNREGISTRATION_TRIGGER_INSTANCE_FROM_LISTING);
631 if (get_registered_triggers_count() != 0) {
632 fail("Previous test left registered triggers, bailing out");
633 goto end;
634 }
635 }
636
637 for (i = 0; i < ARRAY_SIZE(test_functions); i++) {
638 const test_function fn = test_functions[i];
639
640 fn(UNREGISTRATION_TRIGGER_INSTANCE_USED_FOR_REGISTRATION);
641 if (get_registered_triggers_count() != 0) {
642 fail("Previous test left registered triggers, bailing out");
643 goto end;
644 }
645 }
646
647 register_multiple_anonymous_triggers();
648 end:
649 return exit_status();
650 }
This page took 0.042776 seconds and 3 git commands to generate.