From ed9f1fb24a21b222c23684cdf8e77b4d21c21895 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 7 Aug 2018 14:33:27 -0400 Subject: [PATCH] Test: session rotation schedule API MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- .gitignore | 1 + src/lib/lttng-ctl/rotate.c | 18 +- tests/regression/Makefile.am | 3 +- tests/regression/tools/rotation/Makefile.am | 13 +- .../regression/tools/rotation/schedule_api.c | 313 ++++++++++++++++++ .../tools/rotation/test_schedule_api | 40 +++ 6 files changed, 381 insertions(+), 7 deletions(-) create mode 100644 tests/regression/tools/rotation/schedule_api.c create mode 100755 tests/regression/tools/rotation/test_schedule_api diff --git a/.gitignore b/.gitignore index 1ad59422b..f8d11834b 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,7 @@ health_check /tests/regression/tools/mi/validate_xml /tests/regression/tools/notification/base_client /tests/regression/tools/notification/notification +/tests/regression/tools/rotation/schedule_api /tests/regression/ust/overlap/demo/demo /tests/regression/ust/linking/demo_builtin /tests/regression/ust/linking/demo_static diff --git a/src/lib/lttng-ctl/rotate.c b/src/lib/lttng-ctl/rotate.c index 5c5b1b70c..d9871dc9d 100644 --- a/src/lib/lttng-ctl/rotate.c +++ b/src/lib/lttng-ctl/rotate.c @@ -302,6 +302,9 @@ enum lttng_rotation_status lttng_rotation_update_schedule( status = lttng_rotation_schedule_size_threshold_get_threshold( schedule, &lsm.u.rotation_set_schedule.value); if (status != LTTNG_ROTATION_STATUS_OK) { + if (status == LTTNG_ROTATION_STATUS_UNAVAILABLE) { + status = LTTNG_ROTATION_STATUS_INVALID; + } goto end; } @@ -313,6 +316,9 @@ enum lttng_rotation_status lttng_rotation_update_schedule( status = lttng_rotation_schedule_periodic_get_period( schedule, &lsm.u.rotation_set_schedule.value); if (status != LTTNG_ROTATION_STATUS_OK) { + if (status == LTTNG_ROTATION_STATUS_UNAVAILABLE) { + status = LTTNG_ROTATION_STATUS_INVALID; + } goto end; } @@ -468,7 +474,8 @@ lttng_rotation_schedule_size_threshold_get_threshold( enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; struct lttng_rotation_schedule_size_threshold *size_schedule; - if (!schedule || !size_threshold_bytes) { + if (!schedule || !size_threshold_bytes || + schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD) { status = LTTNG_ROTATION_STATUS_INVALID; goto end; } @@ -495,7 +502,8 @@ lttng_rotation_schedule_size_threshold_set_threshold( struct lttng_rotation_schedule_size_threshold *size_schedule; if (!schedule || size_threshold_bytes == 0 || - size_threshold_bytes == -1ULL) { + size_threshold_bytes == -1ULL || + schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD) { status = LTTNG_ROTATION_STATUS_INVALID; goto end; } @@ -532,7 +540,8 @@ lttng_rotation_schedule_periodic_get_period( enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; struct lttng_rotation_schedule_periodic *periodic_schedule; - if (!schedule || !period_us) { + if (!schedule || !period_us || + schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC) { status = LTTNG_ROTATION_STATUS_INVALID; goto end; } @@ -558,7 +567,8 @@ lttng_rotation_schedule_periodic_set_period( enum lttng_rotation_status status = LTTNG_ROTATION_STATUS_OK; struct lttng_rotation_schedule_periodic *periodic_schedule; - if (!schedule || period_us == 0 || period_us == -1ULL) { + if (!schedule || period_us == 0 || period_us == -1ULL || + schedule->type != LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC) { status = LTTNG_ROTATION_STATUS_INVALID; goto end; } diff --git a/tests/regression/Makefile.am b/tests/regression/Makefile.am index 50e89e4c5..4d306d42d 100644 --- a/tests/regression/Makefile.am +++ b/tests/regression/Makefile.am @@ -29,7 +29,8 @@ TESTS = tools/filtering/test_invalid_filter \ tools/notification/test_notification_multi_app \ tools/rotation/test_ust \ tools/rotation/test_kernel \ - tools/rotation/test_save_load_mi + tools/rotation/test_save_load_mi \ + tools/rotation/test_schedule_api if HAVE_LIBLTTNG_UST_CTL SUBDIRS += ust diff --git a/tests/regression/tools/rotation/Makefile.am b/tests/regression/tools/rotation/Makefile.am index 2fbb54e04..c063a8036 100644 --- a/tests/regression/tools/rotation/Makefile.am +++ b/tests/regression/tools/rotation/Makefile.am @@ -1,5 +1,14 @@ -noinst_SCRIPTS = test_kernel test_ust test_save_load_mi rotate_utils.sh -EXTRA_DIST = test_kernel test_ust test_save_load_mi rotate_utils.sh +AM_CPPFLAGS += -I$(top_srcdir)/tests/utils/ -I$(srcdir) + +LIBTAP=$(top_builddir)/tests/utils/tap/libtap.la +LIBLTTNG_CTL=$(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la + +noinst_PROGRAMS = schedule_api +schedule_api_SOURCES = schedule_api.c +schedule_api_LDADD = $(LIBTAP) $(LIBLTTNG_CTL) + +noinst_SCRIPTS = test_kernel test_ust test_save_load_mi test_schedule_api rotate_utils.sh +EXTRA_DIST = test_kernel test_ust test_save_load_mi test_schedule_api rotate_utils.sh all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/regression/tools/rotation/schedule_api.c b/tests/regression/tools/rotation/schedule_api.c new file mode 100644 index 000000000..0ab367152 --- /dev/null +++ b/tests/regression/tools/rotation/schedule_api.c @@ -0,0 +1,313 @@ +/* + * schedule_api.c + * + * Unit tests for the session rotation schedule API + * + * Copyright (C) 2018 Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include + +#define NUM_TESTS 26 + +#define SIZE_THRESHOLD_BYTES 1024 +#define PERIODIC_TIME_US 1000000 + +const char *session_name; + +bool schedules_equal(const struct lttng_rotation_schedule *a, + const struct lttng_rotation_schedule *b) +{ + bool equal = false; + enum lttng_rotation_schedule_type a_type, b_type; + uint64_t a_value, b_value; + enum lttng_rotation_status status; + + a_type = lttng_rotation_schedule_get_type(a); + b_type = lttng_rotation_schedule_get_type(b); + if (a_type != b_type) { + diag("Schedules are not of the same type (%i != %i)", + a_type, b_type); + goto end; + } + + switch (a_type) { + case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD: + { + status = lttng_rotation_schedule_size_threshold_get_threshold(a, + &a_value); + if (status != LTTNG_ROTATION_STATUS_OK) { + diag("Failed to retrieve size threshold of schedule 'a'"); + goto end; + } + status = lttng_rotation_schedule_size_threshold_get_threshold(b, + &b_value); + if (status != LTTNG_ROTATION_STATUS_OK) { + diag("Failed to retrieve size threshold of schedule 'b'"); + goto end; + } + break; + } + case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC: + { + status = lttng_rotation_schedule_periodic_get_period(a, + &a_value); + if (status != LTTNG_ROTATION_STATUS_OK) { + diag("Failed to retrieve period of schedule 'a'"); + goto end; + } + status = lttng_rotation_schedule_periodic_get_period(b, + &b_value); + if (status != LTTNG_ROTATION_STATUS_OK) { + diag("Failed to retrieve period of schedule 'b'"); + goto end; + } + break; + } + default: + diag("Unexpected schedule type: %i", a_type); + goto end; + } + + equal = a_value == b_value; + if (!equal) { + diag("Schedules have different values"); + } +end: + return equal; +} + +void test_add_null_session(void) +{ + enum lttng_rotation_status status; + struct lttng_rotation_schedule *size_schedule = NULL; + + size_schedule = lttng_rotation_schedule_size_threshold_create(); + + status = lttng_session_add_rotation_schedule(NULL, size_schedule); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "NULL session name rejected by lttng_session_add_rotation_schedule()"); +} + +void test_add_null_schedule(void) +{ + enum lttng_rotation_status status; + + status = lttng_session_add_rotation_schedule(session_name, NULL); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "NULL schedule rejected by lttng_session_add_rotation_schedule()"); +} + +void test_add_uninitialized_schedule(void) +{ + enum lttng_rotation_status status; + struct lttng_rotation_schedule *size_schedule = NULL, + *periodic_schedule = NULL; + + size_schedule = lttng_rotation_schedule_size_threshold_create(); + ok(size_schedule, "Created a size threshold session rotation schedule"); + + status = lttng_session_add_rotation_schedule(session_name, + size_schedule); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "Uninitialized size schedule rejected by lttng_session_add_rotation_schedule()"); + + periodic_schedule = lttng_rotation_schedule_periodic_create(); + ok(periodic_schedule, "Created a periodic session rotation schedule"); + + status = lttng_session_add_rotation_schedule(session_name, + periodic_schedule); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "Uninitialized periodic schedule rejected by lttng_session_add_rotation_schedule()"); + + lttng_rotation_schedule_destroy(size_schedule); + lttng_rotation_schedule_destroy(periodic_schedule); +} + +void test_remove_null_session(void) +{ + enum lttng_rotation_status status; + struct lttng_rotation_schedule *size_schedule = NULL; + + size_schedule = lttng_rotation_schedule_size_threshold_create(); + + status = lttng_session_remove_rotation_schedule(NULL, size_schedule); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "NULL session name rejected by lttng_session_remove_rotation_schedule()"); +} + +void test_remove_null_schedule(void) +{ + enum lttng_rotation_status status; + + status = lttng_session_remove_rotation_schedule(session_name, NULL); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "NULL schedule rejected by lttng_session_remove_rotation_schedule()"); +} + +void test_remove_uninitialized_schedule(void) +{ + enum lttng_rotation_status status; + struct lttng_rotation_schedule *size_schedule = NULL, + *periodic_schedule = NULL; + + size_schedule = lttng_rotation_schedule_size_threshold_create(); + status = lttng_session_remove_rotation_schedule(session_name, + size_schedule); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "Uninitialized size schedule rejected by lttng_session_remove_rotation_schedule()"); + + periodic_schedule = lttng_rotation_schedule_periodic_create(); + status = lttng_session_remove_rotation_schedule(session_name, + periodic_schedule); + ok(status == LTTNG_ROTATION_STATUS_INVALID, + "Uninitialized periodic schedule rejected by lttng_session_remove_rotation_schedule()"); + + lttng_rotation_schedule_destroy(size_schedule); + lttng_rotation_schedule_destroy(periodic_schedule); +} + +void test_uninitialized_schedule_get(void) +{ + uint64_t value; + enum lttng_rotation_status status; + struct lttng_rotation_schedule *size_schedule = NULL, + *periodic_schedule = NULL; + + size_schedule = lttng_rotation_schedule_size_threshold_create(); + periodic_schedule = lttng_rotation_schedule_periodic_create(); + + status = lttng_rotation_schedule_size_threshold_get_threshold( + size_schedule, &value); + ok(status == LTTNG_ROTATION_STATUS_UNAVAILABLE, + "Getter on size threshold rotation schedule returns LTTNG_ROTATION_STATUS_UNAVAILABLE by default"); + status = lttng_rotation_schedule_periodic_get_period(periodic_schedule, + &value); + ok(status == LTTNG_ROTATION_STATUS_UNAVAILABLE, + "Getter on periodic rotation schedule returns LTTNG_ROTATION_STATUS_UNAVAILABLE by default"); + + lttng_rotation_schedule_destroy(size_schedule); + lttng_rotation_schedule_destroy(periodic_schedule); + +} + +void test_add_list_remove_schedule( + const struct lttng_rotation_schedule *original_schedule) +{ + int ret; + unsigned int schedules_count = 0; + enum lttng_rotation_status status; + const struct lttng_rotation_schedule *list_schedule; + struct lttng_rotation_schedules *list_schedules; + + status = lttng_session_add_rotation_schedule(session_name, + original_schedule); + ok(status == LTTNG_ROTATION_STATUS_OK, + "Add a rotation schedule to session \'%s\'", + session_name); + + ret = lttng_session_list_rotation_schedules(session_name, + &list_schedules); + ok(ret == LTTNG_OK && list_schedules, + "List rotation schedules of session \'%s\'", + session_name); + + status = lttng_rotation_schedules_get_count(list_schedules, + &schedules_count); + ok(status == LTTNG_ROTATION_STATUS_OK && schedules_count == 1, + "Listing returned 1 rotation schedule"); + + list_schedule = lttng_rotation_schedules_get_at_index(list_schedules, + 0); + ok(list_schedule, + "Obtain the first schedule of a schedules list"); + + ok(schedules_equal(original_schedule, list_schedule), + "Schedule returned by the listing is equal to the reference schedule that was added"); + + status = lttng_session_remove_rotation_schedule(session_name, + list_schedule); + ok(status == LTTNG_ROTATION_STATUS_OK, + "Remove rotation schedule returned by the schedules listing"); + lttng_rotation_schedules_destroy(list_schedules); + + (void) lttng_session_list_rotation_schedules(session_name, + &list_schedules); + status = lttng_rotation_schedules_get_count(list_schedules, + &schedules_count); + ok(status == LTTNG_ROTATION_STATUS_OK && schedules_count == 0, + "Listing returned 0 rotation schedules after removal"); + +} + +void test_add_list_remove_size_schedule(void) +{ + struct lttng_rotation_schedule *size_schedule; + + diag("Add, list, and remove a size threshold rotation schedule"); + size_schedule = lttng_rotation_schedule_size_threshold_create(); + (void) lttng_rotation_schedule_size_threshold_set_threshold( + size_schedule, SIZE_THRESHOLD_BYTES); + test_add_list_remove_schedule(size_schedule); + lttng_rotation_schedule_destroy(size_schedule); +} + +void test_add_list_remove_periodic_schedule(void) +{ + struct lttng_rotation_schedule *periodic_schedule; + + diag("Add, list, and remove a periodic rotation schedule"); + periodic_schedule = lttng_rotation_schedule_periodic_create(); + (void) lttng_rotation_schedule_periodic_set_period( + periodic_schedule, PERIODIC_TIME_US); + test_add_list_remove_schedule(periodic_schedule); + lttng_rotation_schedule_destroy(periodic_schedule); +} + +int main(int argc, char **argv) +{ + plan_tests(NUM_TESTS); + + if (argc < 2) { + diag("Usage: schedule_api SESSION_NAME"); + goto end; + } + + session_name = argv[1]; + + diag("Argument validation"); + test_add_null_session(); + test_add_null_schedule(); + test_add_uninitialized_schedule(); + test_remove_null_session(); + test_remove_null_schedule(); + test_remove_uninitialized_schedule(); + test_uninitialized_schedule_get(); + + test_add_list_remove_size_schedule(); + test_add_list_remove_periodic_schedule(); +end: + return exit_status(); +} diff --git a/tests/regression/tools/rotation/test_schedule_api b/tests/regression/tools/rotation/test_schedule_api new file mode 100755 index 000000000..48c47467f --- /dev/null +++ b/tests/regression/tools/rotation/test_schedule_api @@ -0,0 +1,40 @@ +#!/bin/bash +# +# Copyright (C) - 2018 Jérémie Galarneau +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +TEST_DESC="Rotation - Schedule API" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../../.. + +SESSION_NAME="my_session" +TRACE_PATH=$(mktemp -d) + +source $TESTDIR/utils/utils.sh + +print_test_banner "$TEST_DESC" + +start_lttng_sessiond_notap + +create_lttng_session_notap $SESSION_NAME $TRACE_PATH + +# The actual test is a native application as it tests the liblttng-ctl API +$CURDIR/schedule_api $SESSION_NAME + +destroy_lttng_session_notap $SESSION_NAME +stop_lttng_sessiond_notap + +# Remove tmp dir +rm -rf $TRACE_PATH -- 2.34.1