fix: relayd: unaligned access in trace_chunk_registry_ht_key_hash
[lttng-tools.git] / tests / regression / tools / notification / rotation.c
CommitLineData
88a5c0a9
JG
1/*
2 * rotation.c
3 *
4 * Tests suite for LTTng notification API (rotation notifications)
5 *
6 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
9d16b343 8 * SPDX-License-Identifier: MIT
88a5c0a9 9 *
88a5c0a9
JG
10 */
11
28f23191
JG
12#include <lttng/lttng.h>
13
88a5c0a9 14#include <stdint.h>
28f23191 15#include <stdio.h>
88a5c0a9 16#include <string.h>
28f23191
JG
17#include <tap/tap.h>
18#include <unistd.h>
88a5c0a9
JG
19
20#define TEST_COUNT 36
21
22struct session {
23 const char *name;
24 const char *output_path;
25};
26
27uint64_t expected_rotation_id = UINT64_MAX;
28
28f23191 29static int test_condition(struct lttng_condition *condition, const char *type_name)
88a5c0a9
JG
30{
31 int ret = 0;
32 const char *out_session_name;
28f23191 33 const char *const session_name = "test session name";
88a5c0a9
JG
34 enum lttng_condition_status status;
35
28f23191 36 status = lttng_condition_session_rotation_get_session_name(condition, &out_session_name);
88a5c0a9 37 ok(status == LTTNG_CONDITION_STATUS_UNSET,
28f23191
JG
38 "Getting unset name of %s condition fails with LTTNG_CONDITION_STATUS_UNSET",
39 type_name);
88a5c0a9 40
28f23191 41 status = lttng_condition_session_rotation_set_session_name(condition, session_name);
88a5c0a9 42 ok(status == LTTNG_CONDITION_STATUS_OK,
28f23191
JG
43 "Setting session name \"%s\" of %s condition succeeds",
44 session_name,
45 type_name);
88a5c0a9 46
28f23191
JG
47 status = lttng_condition_session_rotation_get_session_name(condition, &out_session_name);
48 ok(status == LTTNG_CONDITION_STATUS_OK, "Getting name of %s condition succeeds", type_name);
88a5c0a9
JG
49
50 ok(out_session_name && !strcmp(session_name, out_session_name),
28f23191
JG
51 "Session name returned by %s condition matches the expected name",
52 type_name);
88a5c0a9
JG
53 return ret;
54}
55
28f23191
JG
56static int setup_rotation_trigger(const struct session *session,
57 struct lttng_notification_channel *notification_channel)
88a5c0a9
JG
58{
59 int ret;
60 struct lttng_condition *rotation_ongoing_condition = NULL;
61 struct lttng_condition *rotation_completed_condition = NULL;
62 struct lttng_action *notify = NULL;
63 struct lttng_trigger *rotation_ongoing_trigger = NULL;
64 struct lttng_trigger *rotation_completed_trigger = NULL;
65 enum lttng_condition_status condition_status;
66 enum lttng_notification_channel_status notification_channel_status;
a5c2d2a7 67 enum lttng_error_code ret_code;
88a5c0a9
JG
68
69 notify = lttng_action_notify_create();
70 if (!notify) {
71 ret = -1;
72 goto end;
73 }
74
75 /* Create rotation ongoing and completed conditions. */
28f23191 76 rotation_ongoing_condition = lttng_condition_session_rotation_ongoing_create();
88a5c0a9
JG
77 ok(rotation_ongoing_condition, "Create session rotation ongoing condition");
78 if (!rotation_ongoing_condition) {
79 ret = -1;
80 goto end;
81 }
82 ret = test_condition(rotation_ongoing_condition, "rotation ongoing");
83 if (ret) {
84 goto end;
85 }
86 condition_status = lttng_condition_session_rotation_set_session_name(
28f23191 87 rotation_ongoing_condition, session->name);
88a5c0a9
JG
88 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
89 ret = -1;
90 diag("Failed to set session name on session rotation ongoing condition");
91 goto end;
92 }
93
28f23191 94 rotation_completed_condition = lttng_condition_session_rotation_completed_create();
88a5c0a9
JG
95 ok(rotation_completed_condition, "Create session rotation completed condition");
96 if (!rotation_completed_condition) {
97 ret = -1;
98 goto end;
99 }
100 ret = test_condition(rotation_completed_condition, "rotation completed");
101 if (ret) {
102 diag("Failed to set session name on session rotation completed condition");
103 goto end;
104 }
105 condition_status = lttng_condition_session_rotation_set_session_name(
28f23191 106 rotation_completed_condition, session->name);
88a5c0a9
JG
107 if (condition_status != LTTNG_CONDITION_STATUS_OK) {
108 ret = -1;
109 goto end;
110 }
111
112 notification_channel_status = lttng_notification_channel_subscribe(
28f23191 113 notification_channel, rotation_ongoing_condition);
88a5c0a9 114 ok(notification_channel_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
28f23191
JG
115 "Subscribe to session rotation ongoing notifications");
116 if (notification_channel_status != LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) {
88a5c0a9
JG
117 ret = -1;
118 goto end;
119 }
120 notification_channel_status = lttng_notification_channel_subscribe(
28f23191 121 notification_channel, rotation_completed_condition);
88a5c0a9 122 ok(notification_channel_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
28f23191
JG
123 "Subscribe to session rotation completed notifications");
124 if (notification_channel_status != LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) {
88a5c0a9
JG
125 ret = -1;
126 goto end;
127 }
128
129 /* Create rotation ongoing and completed triggers. */
28f23191 130 rotation_ongoing_trigger = lttng_trigger_create(rotation_ongoing_condition, notify);
88a5c0a9
JG
131 ok(rotation_ongoing_trigger, "Create a rotation ongoing notification trigger");
132 if (!rotation_ongoing_trigger) {
133 ret = -1;
134 goto end;
135 }
136
28f23191 137 rotation_completed_trigger = lttng_trigger_create(rotation_completed_condition, notify);
88a5c0a9
JG
138 ok(rotation_completed_trigger, "Create a rotation completed notification trigger");
139 if (!rotation_completed_trigger) {
140 ret = -1;
141 goto end;
142 }
143
144 /* Register rotation ongoing and completed triggers. */
28f23191 145 ret_code = lttng_register_trigger_with_automatic_name(rotation_ongoing_trigger);
a5c2d2a7
JG
146 ok(ret_code == LTTNG_OK, "Registered session rotation ongoing trigger");
147 if (ret_code != LTTNG_OK) {
148 ret = -ret_code;
88a5c0a9
JG
149 goto end;
150 }
151
28f23191
JG
152 ret_code = lttng_register_trigger_with_automatic_name(rotation_completed_trigger);
153 ok(ret_code == LTTNG_OK, "Registered session rotation completed trigger");
a5c2d2a7
JG
154 if (ret_code != LTTNG_OK) {
155 ret = -ret_code;
88a5c0a9
JG
156 goto end;
157 }
a5c2d2a7 158
88a5c0a9
JG
159end:
160 lttng_trigger_destroy(rotation_ongoing_trigger);
161 lttng_trigger_destroy(rotation_completed_trigger);
162 lttng_condition_destroy(rotation_ongoing_condition);
163 lttng_condition_destroy(rotation_completed_condition);
164 lttng_action_destroy(notify);
165 return ret;
166}
167
28f23191
JG
168static int test_notification(struct lttng_notification_channel *notification_channel,
169 const struct session *session,
170 const char *expected_notification_type_name,
171 enum lttng_condition_type expected_condition_type)
88a5c0a9
JG
172{
173 int ret = 0;
174 bool notification_pending;
175 enum lttng_notification_channel_status notification_channel_status;
176 enum lttng_condition_status condition_status;
177 enum lttng_evaluation_status evaluation_status;
178 enum lttng_trace_archive_location_status location_status;
179 enum lttng_condition_type condition_type;
180 struct lttng_notification *notification = NULL;
181 const struct lttng_condition *condition;
182 const struct lttng_evaluation *evaluation;
183 const char *session_name = NULL;
184 const struct lttng_trace_archive_location *location = NULL;
185 uint64_t rotation_id = UINT64_MAX;
186 const char *chunk_path = NULL;
187
188 notification_channel_status = lttng_notification_channel_has_pending_notification(
28f23191 189 notification_channel, &notification_pending);
88a5c0a9 190 ok(notification_channel_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK,
28f23191
JG
191 "Check for %s notification pending on notification channel",
192 expected_notification_type_name);
88a5c0a9
JG
193 if (notification_channel_status != LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) {
194 ret = -1;
195 goto end;
196 }
197
198 ok(notification_pending,
28f23191
JG
199 "Session %s notification is pending on notification channel",
200 expected_notification_type_name);
88a5c0a9
JG
201 if (!notification_pending) {
202 ret = -1;
203 goto end;
204 }
205
206 notification_channel_status = lttng_notification_channel_get_next_notification(
28f23191 207 notification_channel, &notification);
88a5c0a9 208 ok(notification_channel_status == LTTNG_NOTIFICATION_CHANNEL_STATUS_OK && notification,
28f23191
JG
209 "Get %s notification from notification channel",
210 expected_notification_type_name);
88a5c0a9
JG
211 if (notification_channel_status != LTTNG_NOTIFICATION_CHANNEL_STATUS_OK || !notification) {
212 ret = -1;
213 goto end;
214 }
215
216 condition = lttng_notification_get_condition(notification);
217 if (!condition) {
218 diag("Failed to get notification condition");
219 ret = -1;
220 goto end;
221 }
222
223 condition_type = lttng_condition_get_type(condition);
224 ok(condition_type == expected_condition_type,
28f23191
JG
225 "Notification condition obtained from notification channel is of type \"%s\"",
226 expected_notification_type_name);
88a5c0a9
JG
227 if (condition_type != expected_condition_type) {
228 ret = -1;
229 goto end;
230 }
231
28f23191
JG
232 condition_status =
233 lttng_condition_session_rotation_get_session_name(condition, &session_name);
88a5c0a9 234 ok(condition_status == LTTNG_CONDITION_STATUS_OK && session_name &&
28f23191
JG
235 !strcmp(session_name, session->name),
236 "Condition obtained from notification has the correct session name assigned");
88a5c0a9
JG
237 if (condition_status != LTTNG_CONDITION_STATUS_OK || !session_name) {
238 ret = -1;
239 goto end;
240 }
241
242 evaluation = lttng_notification_get_evaluation(notification);
243 if (!evaluation) {
244 diag("Failed to get notification evaluation");
245 ret = -1;
246 goto end;
247 }
248 condition_type = lttng_evaluation_get_type(evaluation);
249 ok(condition_type == expected_condition_type,
28f23191
JG
250 "Condition evaluation obtained from notification channel is of type \"%s\"",
251 expected_notification_type_name);
88a5c0a9
JG
252 if (condition_type != expected_condition_type) {
253 ret = -1;
254 goto end;
255 }
256
28f23191 257 evaluation_status = lttng_evaluation_session_rotation_get_id(evaluation, &rotation_id);
88a5c0a9 258 ok(evaluation_status == LTTNG_EVALUATION_STATUS_OK,
28f23191
JG
259 "Get %s id from notification evaluation",
260 expected_notification_type_name);
88a5c0a9
JG
261 if (evaluation_status != LTTNG_EVALUATION_STATUS_OK) {
262 ret = -1;
263 goto end;
264 }
265
266 if (expected_condition_type != LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED) {
267 /*
268 * Remaining tests only apply to "session rotation completed"
269 * notifications.
270 */
271 goto end;
272 }
273
28f23191
JG
274 evaluation_status =
275 lttng_evaluation_session_rotation_completed_get_location(evaluation, &location);
88a5c0a9 276 ok(evaluation_status == LTTNG_EVALUATION_STATUS_OK && location,
28f23191
JG
277 "Get session %s chunk location from evaluation",
278 expected_notification_type_name);
88a5c0a9
JG
279 if (evaluation_status != LTTNG_EVALUATION_STATUS_OK || !location) {
280 ret = -1;
281 goto end;
282 }
283
28f23191
JG
284 ok(lttng_trace_archive_location_get_type(location) ==
285 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL,
286 "Location returned from the session rotation completed notification is of type 'local'");
88a5c0a9 287
28f23191
JG
288 location_status =
289 lttng_trace_archive_location_local_get_absolute_path(location, &chunk_path);
c6795a46 290 ok(location_status == LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK && chunk_path,
28f23191 291 "Retrieved path from location returned by the session rotation completed notification");
88a5c0a9 292 diag("Chunk available at %s", chunk_path ? chunk_path : "NULL");
c6795a46
JG
293
294 ok(chunk_path && !strncmp(session->output_path, chunk_path, strlen(session->output_path)),
28f23191 295 "Returned path from location starts with the output path");
88a5c0a9
JG
296
297end:
298 lttng_notification_destroy(notification);
299 return ret;
300}
301
28f23191
JG
302static int
303test_rotation_ongoing_notification(struct lttng_notification_channel *notification_channel,
304 struct session *session)
88a5c0a9 305{
28f23191
JG
306 return test_notification(notification_channel,
307 session,
308 "rotation ongoing",
309 LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING);
88a5c0a9
JG
310}
311
28f23191
JG
312static int
313test_rotation_completed_notification(struct lttng_notification_channel *notification_channel,
314 struct session *session)
88a5c0a9 315{
28f23191
JG
316 return test_notification(notification_channel,
317 session,
318 "rotation completed",
319 LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED);
88a5c0a9
JG
320}
321
322int main(int argc, const char *argv[])
323{
324 int ret = 0;
325 struct session session = { 0 };
326 struct lttng_notification_channel *notification_channel = NULL;
327 struct lttng_rotation_handle *rotation_handle = NULL;
328 enum lttng_rotation_status rotation_status;
28f23191 329 enum lttng_rotation_state rotation_state = LTTNG_ROTATION_STATE_NO_ROTATION;
88a5c0a9
JG
330
331 if (argc != 3) {
332 puts("Usage: rotation SESSION_NAME SESSION_OUTPUT_PATH");
333 ret = 1;
334 goto error;
335 }
336
337 session.name = argv[1];
338 session.output_path = argv[2];
339
340 plan_tests(TEST_COUNT);
88a5c0a9 341
28f23191
JG
342 notification_channel =
343 lttng_notification_channel_create(lttng_session_daemon_notification_endpoint);
88a5c0a9
JG
344 if (!notification_channel) {
345 diag("Failed to create notification channel");
346 ret = -1;
347 goto error;
348 }
349
350 ret = setup_rotation_trigger(&session, notification_channel);
351 if (ret) {
352 goto error;
353 }
354
355 /* Start rotation and wait for its completion. */
356 ret = lttng_rotate_session(session.name, NULL, &rotation_handle);
28f23191 357 ok(ret >= 0 && rotation_handle, "Start rotation of session \"%s\"", session.name);
88a5c0a9
JG
358 if (ret < 0 || !rotation_handle) {
359 goto error;
360 }
361
362 do {
28f23191 363 rotation_status = lttng_rotation_handle_get_state(rotation_handle, &rotation_state);
88a5c0a9 364 } while (rotation_state == LTTNG_ROTATION_STATE_ONGOING &&
28f23191 365 rotation_status == LTTNG_ROTATION_STATUS_OK);
88a5c0a9 366 ok(rotation_status == LTTNG_ROTATION_STATUS_OK &&
28f23191
JG
367 rotation_state == LTTNG_ROTATION_STATE_COMPLETED,
368 "Complete rotation of session \"%s\"",
369 session.name);
88a5c0a9
JG
370
371 /*
372 * After a rotation has completed, we can expect two notifications to
373 * be queued:
374 * - Session rotation ongoing
375 * - Session rotation completed
376 */
28f23191 377 ret = test_rotation_ongoing_notification(notification_channel, &session);
88a5c0a9
JG
378 if (ret) {
379 goto error;
380 }
381
28f23191 382 ret = test_rotation_completed_notification(notification_channel, &session);
88a5c0a9
JG
383 if (ret) {
384 goto error;
385 }
386error:
387 lttng_notification_channel_destroy(notification_channel);
388 lttng_rotation_handle_destroy(rotation_handle);
674c3e2c 389 return exit_status();
88a5c0a9 390}
This page took 0.065907 seconds and 4 git commands to generate.