2 * Copyright (C) 2011 EfficiOS Inc.
4 * SPDX-License-Identifier: GPL-2.0-only
13 #include <sys/types.h>
18 #include <common/compat/errno.h>
19 #include <bin/lttng-sessiond/session.h>
20 #include <bin/lttng-sessiond/ust-app.h>
21 #include <bin/lttng-sessiond/health-sessiond.h>
22 #include <bin/lttng-sessiond/thread.h>
23 #include <common/sessiond-comm/sessiond-comm.h>
24 #include <common/common.h>
26 #define SESSION1 "test1"
28 #define MAX_SESSIONS 10000
29 #define RANDOM_STRING_LEN 11
31 /* Number of TAP tests in this file */
34 static struct ltt_session_list
*session_list
;
36 static const char alphanum
[] =
38 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
39 "abcdefghijklmnopqrstuvwxyz";
40 static char random_string
[RANDOM_STRING_LEN
];
43 * Return random string of 10 characters.
46 static char *get_random_string(void)
50 for (i
= 0; i
< RANDOM_STRING_LEN
- 1; i
++) {
51 random_string
[i
] = alphanum
[rand() % (sizeof(alphanum
) - 1)];
54 random_string
[RANDOM_STRING_LEN
- 1] = '\0';
60 * Return 0 if session name is found, else -1
62 static int find_session_name(const char *name
)
64 struct ltt_session
*iter
;
66 cds_list_for_each_entry(iter
, &session_list
->head
, list
) {
67 if (strcmp(iter
->name
, name
) == 0) {
75 static int session_list_count(void)
78 struct ltt_session
*iter
;
80 cds_list_for_each_entry(iter
, &session_list
->head
, list
) {
87 * Empty session list manually.
89 static void empty_session_list(void)
91 struct ltt_session
*iter
, *tmp
;
94 cds_list_for_each_entry_safe(iter
, tmp
, &session_list
->head
, list
) {
95 session_destroy(iter
);
97 session_unlock_list();
99 /* Session list must be 0 */
100 LTTNG_ASSERT(!session_list_count());
104 * Test creation of 1 session
106 static int create_one_session(const char *name
)
109 enum lttng_error_code ret_code
;
110 struct ltt_session
*session
= NULL
;
113 ret_code
= session_create(name
, geteuid(), getegid(), &session
);
114 session_put(session
);
115 if (ret_code
== LTTNG_OK
) {
117 ret
= find_session_name(name
);
119 /* Session not found by name */
120 printf("session not found after creation\n");
127 if (ret_code
== LTTNG_ERR_EXIST_SESS
) {
128 printf("(session already exists) ");
133 session_unlock_list();
138 * Test deletion of 1 session
140 static int destroy_one_session(struct ltt_session
*session
)
143 char session_name
[NAME_MAX
];
145 strncpy(session_name
, session
->name
, sizeof(session_name
));
146 session_name
[sizeof(session_name
) - 1] = '\0';
148 session_destroy(session
);
149 session_put(session
);
151 ret
= find_session_name(session_name
);
153 /* Success, -1 means that the sesion is NOT found */
163 * This test is supposed to fail at the second create call. If so, return 0 for
164 * test success, else -1.
166 static int two_session_same_name(void)
169 struct ltt_session
*sess
;
171 ret
= create_one_session(SESSION1
);
179 sess
= session_find_by_name(SESSION1
);
183 session_unlock_list();
192 session_unlock_list();
197 static void test_session_list(void)
199 session_list
= session_get_list();
200 ok(session_list
!= NULL
, "Session list: not NULL");
203 static void test_create_one_session(void)
205 ok(create_one_session(SESSION1
) == 0,
206 "Create session: %s",
210 static void test_validate_session(void)
212 struct ltt_session
*tmp
;
215 tmp
= session_find_by_name(SESSION1
);
218 "Validating session: session found");
221 ok(tmp
->kernel_session
== NULL
&&
223 "Validating session: basic sanity check");
225 skip(1, "Skipping session validation check as session was not found");
233 session_unlock_list();
236 static void test_destroy_session(void)
238 struct ltt_session
*tmp
;
241 tmp
= session_find_by_name(SESSION1
);
244 "Destroying session: session found");
247 ok(destroy_one_session(tmp
) == 0,
248 "Destroying session: %s destroyed",
251 skip(1, "Skipping session destruction as it was not found");
253 session_unlock_list();
256 static void test_duplicate_session(void)
258 ok(two_session_same_name() == 0,
259 "Duplicate session creation");
262 static void test_session_name_generation(void)
264 struct ltt_session
*session
= NULL
;
265 enum lttng_error_code ret_code
;
266 const char *expected_session_name_prefix
= DEFAULT_SESSION_NAME
;
269 ret_code
= session_create(NULL
, geteuid(), getegid(), &session
);
270 ok(ret_code
== LTTNG_OK
,
271 "Create session with a NULL name (auto-generate a name)");
273 skip(1, "Skipping session name generation tests as session_create() failed.");
276 diag("Automatically-generated session name: %s", *session
->name
?
277 session
->name
: "ERROR");
278 ok(*session
->name
&& !strncmp(expected_session_name_prefix
, session
->name
,
279 sizeof(DEFAULT_SESSION_NAME
) - 1),
280 "Auto-generated session name starts with %s",
281 DEFAULT_SESSION_NAME
);
283 session_put(session
);
284 session_unlock_list();
287 static void test_large_session_number(void)
289 int ret
, i
, failed
= 0;
290 struct ltt_session
*iter
, *tmp
;
292 for (i
= 0; i
< MAX_SESSIONS
; i
++) {
293 char *tmp_name
= get_random_string();
294 ret
= create_one_session(tmp_name
);
296 diag("session %d (name: %s) creation failed", i
, tmp_name
);
302 "Large sessions number: created %u sessions",
308 for (i
= 0; i
< MAX_SESSIONS
; i
++) {
309 cds_list_for_each_entry_safe(iter
, tmp
, &session_list
->head
, list
) {
310 LTTNG_ASSERT(session_get(iter
));
311 ret
= destroy_one_session(iter
);
313 diag("session %d destroy failed", i
);
318 session_unlock_list();
320 ok(failed
== 0 && session_list_count() == 0,
321 "Large sessions number: destroyed %u sessions",
325 int main(int argc
, char **argv
)
328 plan_tests(NUM_TESTS
);
330 the_health_sessiond
= health_app_create(NR_HEALTH_SESSIOND_TYPES
);
332 diag("Sessions unit tests");
334 rcu_register_thread();
338 test_create_one_session();
340 test_validate_session();
342 test_destroy_session();
344 test_duplicate_session();
346 empty_session_list();
348 test_session_name_generation();
350 test_large_session_number();
352 rcu_unregister_thread();
353 lttng_thread_list_shutdown_orphans();
355 return exit_status();