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