sessiond: open_packets: use user_space_consumer_channel_keys util
[lttng-tools.git] / tests / unit / test_session.cpp
CommitLineData
63371d1e 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
63371d1e 3 *
9d16b343 4 * SPDX-License-Identifier: GPL-2.0-only
63371d1e 5 *
63371d1e
DG
6 */
7
28ab034a
JG
8#include <common/common.hpp>
9#include <common/compat/errno.hpp>
10#include <common/sessiond-comm/sessiond-comm.hpp>
11
12#include <bin/lttng-sessiond/health-sessiond.hpp>
13#include <bin/lttng-sessiond/session.hpp>
14#include <bin/lttng-sessiond/thread.hpp>
15#include <bin/lttng-sessiond/ust-app.hpp>
63371d1e
DG
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
6df2e2c9 19#include <sys/types.h>
28ab034a 20#include <tap/tap.h>
c9e313bc
SM
21#include <time.h>
22#include <unistd.h>
8273250b 23#include <urcu.h>
63371d1e 24
63371d1e
DG
25#define SESSION1 "test1"
26
28ab034a
JG
27#define MAX_SESSIONS 10000
28#define RANDOM_STRING_LEN 11
63371d1e 29
83c55082 30/* Number of TAP tests in this file */
dec56f6c 31#define NUM_TESTS 11
63371d1e
DG
32
33static struct ltt_session_list *session_list;
34
28ab034a
JG
35static const char alphanum[] = "0123456789"
36 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
37 "abcdefghijklmnopqrstuvwxyz";
98612240 38static char random_string[RANDOM_STRING_LEN];
63371d1e
DG
39
40/*
41 * Return random string of 10 characters.
98612240 42 * Not thread-safe.
63371d1e 43 */
cd9adb8b 44static char *get_random_string()
63371d1e
DG
45{
46 int i;
63371d1e 47
98612240
MD
48 for (i = 0; i < RANDOM_STRING_LEN - 1; i++) {
49 random_string[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
63371d1e
DG
50 }
51
98612240 52 random_string[RANDOM_STRING_LEN - 1] = '\0';
63371d1e 53
98612240 54 return random_string;
63371d1e
DG
55}
56
57/*
58 * Return 0 if session name is found, else -1
59 */
b53d4e59 60static int find_session_name(const char *name)
63371d1e
DG
61{
62 struct ltt_session *iter;
63
28ab034a 64 cds_list_for_each_entry (iter, &session_list->head, list) {
63371d1e
DG
65 if (strcmp(iter->name, name) == 0) {
66 return 0;
67 }
68 }
69
70 return -1;
71}
72
cd9adb8b 73static int session_list_count()
cc305a0b
MD
74{
75 int count = 0;
76 struct ltt_session *iter;
77
28ab034a 78 cds_list_for_each_entry (iter, &session_list->head, list) {
cc305a0b
MD
79 count++;
80 }
81 return count;
82}
83
63371d1e
DG
84/*
85 * Empty session list manually.
86 */
cd9adb8b 87static void empty_session_list()
63371d1e
DG
88{
89 struct ltt_session *iter, *tmp;
90
d9a970b7 91 const auto list_lock = lttng::sessiond::lock_session_list();
28ab034a 92 cds_list_for_each_entry_safe (iter, tmp, &session_list->head, list) {
23324029 93 session_destroy(iter);
63371d1e
DG
94 }
95
96 /* Session list must be 0 */
a0377dfe 97 LTTNG_ASSERT(!session_list_count());
63371d1e
DG
98}
99
100/*
101 * Test creation of 1 session
102 */
b53d4e59 103static int create_one_session(const char *name)
63371d1e
DG
104{
105 int ret;
b178f53e 106 enum lttng_error_code ret_code;
cd9adb8b 107 struct ltt_session *session = nullptr;
63371d1e 108
d9a970b7 109 const auto list_lock = lttng::sessiond::lock_session_list();
e3876bf0 110 ret_code = session_create(name, geteuid(), getegid(), &session);
b178f53e
JG
111 session_put(session);
112 if (ret_code == LTTNG_OK) {
63371d1e
DG
113 /* Validate */
114 ret = find_session_name(name);
115 if (ret < 0) {
116 /* Session not found by name */
117 printf("session not found after creation\n");
b178f53e 118 ret = -1;
63371d1e
DG
119 } else {
120 /* Success */
b178f53e 121 ret = 0;
63371d1e 122 }
54d01ffb 123 } else {
b178f53e 124 if (ret_code == LTTNG_ERR_EXIST_SESS) {
63371d1e
DG
125 printf("(session already exists) ");
126 }
b178f53e 127 ret = -1;
63371d1e 128 }
3517bb68 129
b178f53e 130 return ret;
63371d1e
DG
131}
132
133/*
134 * Test deletion of 1 session
135 */
a0a4f314 136static int destroy_one_session(ltt_session::ref session)
63371d1e
DG
137{
138 int ret;
59891c42 139 char session_name[NAME_MAX];
63371d1e 140
4cd95b52 141 strncpy(session_name, session->name, sizeof(session_name));
59891c42 142 session_name[sizeof(session_name) - 1] = '\0';
54d01ffb 143
a0a4f314
JG
144 /* Reference of the session list. */
145 ltt_session *weak_session_ptr = &session.get();
146 {
147 /* Drop the reference that stems from the look-up. */
148 const ltt_session::ref reference_to_drop = std::move(session);
149 }
150
151 session_destroy(weak_session_ptr);
63371d1e 152
e32d7f27
JG
153 ret = find_session_name(session_name);
154 if (ret < 0) {
155 /* Success, -1 means that the sesion is NOT found */
156 ret = 0;
157 } else {
158 /* Fail */
159 ret = -1;
160 }
d9a970b7 161
e32d7f27 162 return ret;
63371d1e
DG
163}
164
63371d1e
DG
165/*
166 * This test is supposed to fail at the second create call. If so, return 0 for
167 * test success, else -1.
168 */
cd9adb8b 169static int two_session_same_name()
63371d1e 170{
d9a970b7 171 const auto ret = create_one_session(SESSION1);
63371d1e
DG
172 if (ret < 0) {
173 /* Fail */
d9a970b7 174 return -1;
63371d1e
DG
175 }
176
d9a970b7
JG
177 /*
178 * Mind the order of the declaration of list_lock vs session:
179 * the session list lock must always be released _after_ the release of
180 * a session's reference (the destruction of a ref/locked_ref) to ensure
181 * since the reference's release may unpublish the session from the list of
182 * sessions.
183 */
184 const auto list_lock = lttng::sessiond::lock_session_list();
185 try {
186 const auto session = ltt_session::find_session(SESSION1);
63371d1e 187 /* Success */
d9a970b7
JG
188 return 0;
189 } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
e32d7f27 190 /* Fail */
d9a970b7 191 return -1;
63371d1e 192 }
63371d1e
DG
193}
194
cd9adb8b 195static void test_session_list()
63371d1e 196{
83c55082 197 session_list = session_get_list();
cd9adb8b 198 ok(session_list != nullptr, "Session list: not NULL");
83c55082 199}
63371d1e 200
cd9adb8b 201static void test_create_one_session()
83c55082 202{
28ab034a 203 ok(create_one_session(SESSION1) == 0, "Create session: %s", SESSION1);
83c55082 204}
63371d1e 205
cd9adb8b 206static void test_validate_session()
83c55082 207{
d9a970b7
JG
208 /*
209 * Mind the order of the declaration of list_lock vs session:
210 * the session list lock must always be released _after_ the release of
211 * a session's reference (the destruction of a ref/locked_ref) to ensure
212 * since the reference's release may unpublish the session from the list of
213 * sessions.
214 */
215 const auto list_lock = lttng::sessiond::lock_session_list();
d9a970b7
JG
216
217 try {
a0a4f314
JG
218 const auto session = ltt_session::find_session(SESSION1);
219 pass("Validating session: session found");
83c55082 220
d9a970b7 221 ok(session->kernel_session == nullptr && strlen(session->name),
d61d06f0 222 "Validating session: basic sanity check");
a0a4f314
JG
223
224 session->lock();
225 session->unlock();
226 } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
227 fail("Validating session: session found");
d61d06f0 228 skip(1, "Skipping session validation check as session was not found");
d61d06f0 229 }
83c55082 230}
63371d1e 231
cd9adb8b 232static void test_destroy_session()
83c55082 233{
d9a970b7
JG
234 /*
235 * Mind the order of the declaration of list_lock vs session:
236 * the session list lock must always be released _after_ the release of
237 * a session's reference (the destruction of a ref/locked_ref) to ensure
238 * since the reference's release may unpublish the session from the list of
239 * sessions.
240 */
241 const auto list_lock = lttng::sessiond::lock_session_list();
d9a970b7
JG
242
243 try {
a0a4f314 244 auto session = ltt_session::find_session(SESSION1);
63371d1e 245
a0a4f314 246 pass("Destroying session: session found");
63371d1e 247
a0a4f314 248 ok(destroy_one_session(std::move(session)) == 0,
d9a970b7
JG
249 "Destroying session: %s destroyed",
250 SESSION1);
a0a4f314
JG
251
252 } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
253 fail("Destroying session: session found");
acd4994e
JG
254 skip(1, "Skipping session destruction as it was not found");
255 }
83c55082 256}
63371d1e 257
cd9adb8b 258static void test_duplicate_session()
83c55082 259{
28ab034a 260 ok(two_session_same_name() == 0, "Duplicate session creation");
83c55082
CB
261}
262
cd9adb8b 263static void test_session_name_generation()
83c55082 264{
cd9adb8b 265 struct ltt_session *session = nullptr;
b178f53e
JG
266 enum lttng_error_code ret_code;
267 const char *expected_session_name_prefix = DEFAULT_SESSION_NAME;
83c55082 268
d9a970b7
JG
269 const auto list_lock = lttng::sessiond::lock_session_list();
270
cd9adb8b 271 ret_code = session_create(nullptr, geteuid(), getegid(), &session);
28ab034a 272 ok(ret_code == LTTNG_OK, "Create session with a NULL name (auto-generate a name)");
b178f53e
JG
273 if (!session) {
274 skip(1, "Skipping session name generation tests as session_create() failed.");
275 goto end;
276 }
28ab034a
JG
277 diag("Automatically-generated session name: %s", *session->name ? session->name : "ERROR");
278 ok(*session->name &&
279 !strncmp(expected_session_name_prefix,
280 session->name,
281 sizeof(DEFAULT_SESSION_NAME) - 1),
282 "Auto-generated session name starts with %s",
283 DEFAULT_SESSION_NAME);
b178f53e
JG
284end:
285 session_put(session);
83c55082
CB
286}
287
cd9adb8b 288static void test_large_session_number()
83c55082
CB
289{
290 int ret, i, failed = 0;
291 struct ltt_session *iter, *tmp;
63371d1e 292
63371d1e 293 for (i = 0; i < MAX_SESSIONS; i++) {
e6dd5671 294 char *tmp_name = get_random_string();
dec56f6c 295 ret = create_one_session(tmp_name);
63371d1e 296 if (ret < 0) {
83c55082
CB
297 diag("session %d (name: %s) creation failed", i, tmp_name);
298 ++failed;
db9b8b88 299 }
63371d1e 300 }
63371d1e 301
28ab034a 302 ok(failed == 0, "Large sessions number: created %u sessions", MAX_SESSIONS);
83c55082
CB
303
304 failed = 0;
305
d9a970b7 306 const auto list_lock = lttng::sessiond::lock_session_list();
63371d1e 307 for (i = 0; i < MAX_SESSIONS; i++) {
28ab034a 308 cds_list_for_each_entry_safe (iter, tmp, &session_list->head, list) {
a0a4f314
JG
309 ret = destroy_one_session([iter]() {
310 session_get(iter);
16d64977 311 return ltt_session::make_ref(*iter);
a0a4f314
JG
312 }());
313
63371d1e 314 if (ret < 0) {
59891c42 315 diag("session %d destroy failed", i);
83c55082 316 ++failed;
63371d1e
DG
317 }
318 }
319 }
63371d1e 320
83c55082
CB
321 ok(failed == 0 && session_list_count() == 0,
322 "Large sessions number: destroyed %u sessions",
323 MAX_SESSIONS);
324}
63371d1e 325
cd9adb8b 326int main()
83c55082 327{
83c55082
CB
328 plan_tests(NUM_TESTS);
329
412d7227 330 the_health_sessiond = health_app_create(NR_HEALTH_SESSIOND_TYPES);
5e97de00 331
e3bef725
CB
332 diag("Sessions unit tests");
333
8273250b
JR
334 rcu_register_thread();
335
83c55082
CB
336 test_session_list();
337
338 test_create_one_session();
339
340 test_validate_session();
341
342 test_destroy_session();
343
344 test_duplicate_session();
345
346 empty_session_list();
347
b178f53e 348 test_session_name_generation();
83c55082
CB
349
350 test_large_session_number();
351
8273250b 352 rcu_unregister_thread();
a3707772 353 lttng_thread_list_shutdown_orphans();
5e97de00 354
83c55082 355 return exit_status();
63371d1e 356}
This page took 0.083385 seconds and 4 git commands to generate.