Test: session rotation schedule API
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 7 Aug 2018 18:33:27 +0000 (14:33 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 16 Aug 2018 20:01:30 +0000 (16:01 -0400)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
.gitignore
src/lib/lttng-ctl/rotate.c
tests/regression/Makefile.am
tests/regression/tools/rotation/Makefile.am
tests/regression/tools/rotation/schedule_api.c [new file with mode: 0644]
tests/regression/tools/rotation/test_schedule_api [new file with mode: 0755]

index 1ad59422bdcd46b5219b91bf7058ee63c8725a19..f8d11834be95a50449ae2e706901c305f297d757 100644 (file)
@@ -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
index 5c5b1b70cc05b2eecee78809cce1309d716b9a14..d9871dc9d3e9f6c651126f917d765321adc116f2 100644 (file)
@@ -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;
        }
index 50e89e4c52ad7f5a9426003c356082ffe62e70cc..4d306d42dc2ca83289f8c42b42eee12640e55044 100644 (file)
@@ -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
index 2fbb54e046386e626e9cca966c59a418c7d416ab..c063a8036970fd0ebc23092215ce0306195127a3 100644 (file)
@@ -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 (file)
index 0000000..0ab3671
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * schedule_api.c
+ *
+ * Unit tests for the session rotation schedule API
+ *
+ * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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 <stddef.h>
+#include <stdbool.h>
+#include <tap/tap.h>
+
+#include <lttng/lttng.h>
+
+#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 (executable)
index 0000000..48c4746
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/bash
+#
+# Copyright (C) - 2018 Jérémie Galarneau <jdesfossez@efficios.com>
+#
+# 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
This page took 0.031122 seconds and 4 git commands to generate.