X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=tests%2Funit%2Ftest_session.cpp;h=f6e58c8cb48cae044539d0310a78814b58745c90;hb=HEAD;hp=5a549a593d51ff32df4973c154a1a3787de6b0d3;hpb=3c3390532736cfb5198f863d0d2b218e21fcf76d;p=lttng-tools.git diff --git a/tests/unit/test_session.cpp b/tests/unit/test_session.cpp index 5a549a593..eef160101 100644 --- a/tests/unit/test_session.cpp +++ b/tests/unit/test_session.cpp @@ -5,45 +5,44 @@ * */ +#include +#include +#include +#include + +#include +#include +#include +#include #include #include #include -#include -#include #include -#include - #include - -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #define SESSION1 "test1" -#define MAX_SESSIONS 10000 -#define RANDOM_STRING_LEN 11 +#define MAX_SESSIONS 1000 +#define RANDOM_STRING_LEN 11 /* Number of TAP tests in this file */ #define NUM_TESTS 11 static struct ltt_session_list *session_list; -static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; +static const char alphanum[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; static char random_string[RANDOM_STRING_LEN]; /* * Return random string of 10 characters. * Not thread-safe. */ -static char *get_random_string(void) +static char *get_random_string() { int i; @@ -61,10 +60,9 @@ static char *get_random_string(void) */ static int find_session_name(const char *name) { - struct ltt_session *iter; - - cds_list_for_each_entry(iter, &session_list->head, list) { - if (strcmp(iter->name, name) == 0) { + for (auto *session : lttng::urcu::list_iteration_adapter( + session_list->head)) { + if (strcmp(session->name, name) == 0) { return 0; } } @@ -72,29 +70,29 @@ static int find_session_name(const char *name) return -1; } -static int session_list_count(void) +static int session_list_count() { int count = 0; - struct ltt_session *iter; - cds_list_for_each_entry(iter, &session_list->head, list) { + for (auto *session [[maybe_unused]] : + lttng::urcu::list_iteration_adapter( + session_list->head)) { count++; } + return count; } /* * Empty session list manually. */ -static void empty_session_list(void) +static void empty_session_list() { - struct ltt_session *iter, *tmp; - - session_lock_list(); - cds_list_for_each_entry_safe(iter, tmp, &session_list->head, list) { - session_destroy(iter); + const auto list_lock = lttng::sessiond::lock_session_list(); + for (auto *session : lttng::urcu::list_iteration_adapter( + session_list->head)) { + session_destroy(session); } - session_unlock_list(); /* Session list must be 0 */ LTTNG_ASSERT(!session_list_count()); @@ -107,9 +105,9 @@ static int create_one_session(const char *name) { int ret; enum lttng_error_code ret_code; - struct ltt_session *session = NULL; + struct ltt_session *session = nullptr; - session_lock_list(); + const auto list_lock = lttng::sessiond::lock_session_list(); ret_code = session_create(name, geteuid(), getegid(), &session); session_put(session); if (ret_code == LTTNG_OK) { @@ -130,14 +128,13 @@ static int create_one_session(const char *name) ret = -1; } - session_unlock_list(); return ret; } /* * Test deletion of 1 session */ -static int destroy_one_session(struct ltt_session *session) +static int destroy_one_session(ltt_session::ref session) { int ret; char session_name[NAME_MAX]; @@ -145,8 +142,14 @@ static int destroy_one_session(struct ltt_session *session) strncpy(session_name, session->name, sizeof(session_name)); session_name[sizeof(session_name) - 1] = '\0'; - session_destroy(session); - session_put(session); + /* Reference of the session list. */ + ltt_session *weak_session_ptr = &session.get(); + { + /* Drop the reference that stems from the look-up. */ + const ltt_session::ref reference_to_drop = std::move(session); + } + + session_destroy(weak_session_ptr); ret = find_session_name(session_name); if (ret < 0) { @@ -156,6 +159,7 @@ static int destroy_one_session(struct ltt_session *session) /* Fail */ ret = -1; } + return ret; } @@ -163,131 +167,128 @@ static int destroy_one_session(struct ltt_session *session) * This test is supposed to fail at the second create call. If so, return 0 for * test success, else -1. */ -static int two_session_same_name(void) +static int two_session_same_name() { - int ret; - struct ltt_session *sess; - - ret = create_one_session(SESSION1); + const auto ret = create_one_session(SESSION1); if (ret < 0) { /* Fail */ - ret = -1; - goto end; + return -1; } - session_lock_list(); - sess = session_find_by_name(SESSION1); - if (sess) { + /* + * Mind the order of the declaration of list_lock vs session: + * the session list lock must always be released _after_ the release of + * a session's reference (the destruction of a ref/locked_ref) to ensure + * since the reference's release may unpublish the session from the list of + * sessions. + */ + const auto list_lock = lttng::sessiond::lock_session_list(); + try { + const auto session = ltt_session::find_session(SESSION1); /* Success */ - session_put(sess); - session_unlock_list(); - ret = 0; - goto end_unlock; - } else { + return 0; + } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) { /* Fail */ - ret = -1; - goto end_unlock; + return -1; } -end_unlock: - session_unlock_list(); -end: - return ret; } -static void test_session_list(void) +static void test_session_list() { session_list = session_get_list(); - ok(session_list != NULL, "Session list: not NULL"); + ok(session_list != nullptr, "Session list: not NULL"); } -static void test_create_one_session(void) +static void test_create_one_session() { - ok(create_one_session(SESSION1) == 0, - "Create session: %s", - SESSION1); + ok(create_one_session(SESSION1) == 0, "Create session: %s", SESSION1); } -static void test_validate_session(void) +static void test_validate_session() { - struct ltt_session *tmp; - - session_lock_list(); - tmp = session_find_by_name(SESSION1); - - ok(tmp != NULL, - "Validating session: session found"); - - if (tmp) { - ok(tmp->kernel_session == NULL && - strlen(tmp->name), + /* + * Mind the order of the declaration of list_lock vs session: + * the session list lock must always be released _after_ the release of + * a session's reference (the destruction of a ref/locked_ref) to ensure + * since the reference's release may unpublish the session from the list of + * sessions. + */ + const auto list_lock = lttng::sessiond::lock_session_list(); + + try { + const auto session = ltt_session::find_session(SESSION1); + pass("Validating session: session found"); + + ok(session->kernel_session == nullptr && strlen(session->name), "Validating session: basic sanity check"); - } else { + + session->lock(); + session->unlock(); + } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) { + fail("Validating session: session found"); skip(1, "Skipping session validation check as session was not found"); - goto end; } - - session_lock(tmp); - session_unlock(tmp); - session_put(tmp); -end: - session_unlock_list(); } -static void test_destroy_session(void) +static void test_destroy_session() { - struct ltt_session *tmp; + /* + * Mind the order of the declaration of list_lock vs session: + * the session list lock must always be released _after_ the release of + * a session's reference (the destruction of a ref/locked_ref) to ensure + * since the reference's release may unpublish the session from the list of + * sessions. + */ + const auto list_lock = lttng::sessiond::lock_session_list(); - session_lock_list(); - tmp = session_find_by_name(SESSION1); + try { + auto session = ltt_session::find_session(SESSION1); - ok(tmp != NULL, - "Destroying session: session found"); + pass("Destroying session: session found"); - if (tmp) { - ok(destroy_one_session(tmp) == 0, + ok(destroy_one_session(std::move(session)) == 0, "Destroying session: %s destroyed", SESSION1); - } else { + + } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) { + fail("Destroying session: session found"); skip(1, "Skipping session destruction as it was not found"); } - session_unlock_list(); } -static void test_duplicate_session(void) +static void test_duplicate_session() { - ok(two_session_same_name() == 0, - "Duplicate session creation"); + ok(two_session_same_name() == 0, "Duplicate session creation"); } -static void test_session_name_generation(void) +static void test_session_name_generation() { - struct ltt_session *session = NULL; + struct ltt_session *session = nullptr; enum lttng_error_code ret_code; const char *expected_session_name_prefix = DEFAULT_SESSION_NAME; - session_lock_list(); - ret_code = session_create(NULL, geteuid(), getegid(), &session); - ok(ret_code == LTTNG_OK, - "Create session with a NULL name (auto-generate a name)"); + const auto list_lock = lttng::sessiond::lock_session_list(); + + ret_code = session_create(nullptr, geteuid(), getegid(), &session); + ok(ret_code == LTTNG_OK, "Create session with a NULL name (auto-generate a name)"); if (!session) { skip(1, "Skipping session name generation tests as session_create() failed."); goto end; } - diag("Automatically-generated session name: %s", *session->name ? - session->name : "ERROR"); - ok(*session->name && !strncmp(expected_session_name_prefix, session->name, - sizeof(DEFAULT_SESSION_NAME) - 1), - "Auto-generated session name starts with %s", - DEFAULT_SESSION_NAME); + diag("Automatically-generated session name: %s", *session->name ? session->name : "ERROR"); + ok(*session->name && + !strncmp(expected_session_name_prefix, + session->name, + sizeof(DEFAULT_SESSION_NAME) - 1), + "Auto-generated session name starts with %s", + DEFAULT_SESSION_NAME); end: session_put(session); - session_unlock_list(); } -static void test_large_session_number(void) +static void test_large_session_number() { int ret, i, failed = 0; - struct ltt_session *iter, *tmp; for (i = 0; i < MAX_SESSIONS; i++) { char *tmp_name = get_random_string(); @@ -298,33 +299,34 @@ static void test_large_session_number(void) } } - ok(failed == 0, - "Large sessions number: created %u sessions", - MAX_SESSIONS); + ok(failed == 0, "Large sessions number: created %u sessions", MAX_SESSIONS); failed = 0; - session_lock_list(); + const auto list_lock = lttng::sessiond::lock_session_list(); for (i = 0; i < MAX_SESSIONS; i++) { - cds_list_for_each_entry_safe(iter, tmp, &session_list->head, list) { - LTTNG_ASSERT(session_get(iter)); - ret = destroy_one_session(iter); + for (auto *session : + lttng::urcu::list_iteration_adapter( + session_list->head)) { + ret = destroy_one_session([session]() { + session_get(session); + return ltt_session::make_ref(*session); + }()); + if (ret < 0) { diag("session %d destroy failed", i); ++failed; } } } - session_unlock_list(); ok(failed == 0 && session_list_count() == 0, "Large sessions number: destroyed %u sessions", MAX_SESSIONS); } -int main(int argc, char **argv) +int main() { - plan_tests(NUM_TESTS); the_health_sessiond = health_app_create(NR_HEALTH_SESSIOND_TYPES);