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