From d4196abbc6134a79970dd953c7821bbe671b2db7 Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Fri, 27 Nov 2015 06:39:37 -0500
Subject: [PATCH 2/4] TEST_TOOLS_COLONDB: Add tests for sss_colondb_open

There are three functions at API of colondb wrapper:
 * sss_colondb_open()
 * sss_colondb_readline()
 * sss_colondb_writeline()

This patch adds tests for sss_colondb_open() function.

We test those cases:
 * open nonexisting file for read
 * open nonexisting file for write
 * open existing file for read
 * open existing file for write

Resolves:
https://fedorahosted.org/sssd/ticket/2764
---
 Makefile.am                           |  19 +++
 src/tests/cmocka/test_tools_colondb.c | 246 ++++++++++++++++++++++++++++++++++
 2 files changed, 265 insertions(+)
 create mode 100644 src/tests/cmocka/test_tools_colondb.c

diff --git a/Makefile.am b/Makefile.am
index d7a6f29520980d933cf0afddf8d041b2d6f3b2ef..ceafd1bf0afd856859e835717a59dceac688f147 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -241,6 +241,7 @@ if HAVE_CMOCKA
         pam-srv-tests \
         test_ipa_subdom_util \
         test_ipa_subdom_server \
+        test_tools_colondb \
         test_krb5_wait_queue \
         test_cert_utils \
         test_ldap_id_cleanup \
@@ -2556,6 +2557,24 @@ test_ipa_subdom_server_LDADD = \
     libdlopen_test_providers.la \
     $(NULL)
 
+test_tools_colondb_SOURCES = \
+    src/tests/cmocka/test_tools_colondb.c \
+    src/tools/common/sss_colondb.c \
+    $(NULL)
+test_tools_colondb_CFLAGS = \
+    $(AM_CFLAGS) \
+    $(NULL)
+test_tools_colondb_LDFLAGS = \
+    $(NULL)
+test_tools_colondb_LDADD = \
+    $(CMOCKA_LIBS) \
+    $(POPT_LIBS) \
+    $(SSSD_LIBS) \
+    $(SSSD_INTERNAL_LTLIBS) \
+    libsss_debug.la \
+    libsss_test_common.la \
+    $(NULL)
+
 test_krb5_wait_queue_SOURCES = \
     src/tests/cmocka/common_mock_be.c \
     src/tests/cmocka/test_krb5_wait_queue.c \
diff --git a/src/tests/cmocka/test_tools_colondb.c b/src/tests/cmocka/test_tools_colondb.c
new file mode 100644
index 0000000000000000000000000000000000000000..a3f66119e7ab887138a1d03811dfd15f19b89b12
--- /dev/null
+++ b/src/tests/cmocka/test_tools_colondb.c
@@ -0,0 +1,246 @@
+/*
+    Authors:
+        Petr Čech <pcech@redhat.com>
+
+    Copyright (C) 2015 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+#include <errno.h>
+#include <popt.h>
+
+#include "tests/cmocka/common_mock.h"
+#include "src/tools/common/sss_colondb.h"
+
+#define TESTS_PATH "tp_" BASE_FILE_STEM
+#define TESTS_FILE "test_colondb.ldb"
+
+#define new_test_with_file(test)                                               \
+    cmocka_unit_test_setup_teardown(test_##test, test_colondb_with_file_setup, \
+                                    test_colondb_teardown)
+
+#define new_test_without_file(test)                                            \
+    cmocka_unit_test_setup_teardown(                                           \
+        test_##test, test_colondb_without_file_setup, test_colondb_teardown)
+
+struct test_colondb_ctx
+{
+    bool is_file_created;
+};
+
+static int _create_dir(const char *path)
+{
+    errno_t ret;
+
+    ret = mkdir(path, 0775);
+    if (ret != 0 && errno != EEXIST) {
+        fprintf(stderr, "Could not create test directory\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static int _create_file(const char *path, const char *name)
+{
+    TALLOC_CTX *tmp_ctx = NULL;
+    char *file_name = NULL;
+    FILE *fp = NULL;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+        return 1;
+    }
+
+    ret = _create_dir(path);
+    if (ret != 0) {
+        ret = 1;
+        goto done;
+    }
+
+    file_name = talloc_asprintf(tmp_ctx, "%s/%s", path, name);
+    if (file_name == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct colondb path\n");
+        ret = 1;
+        goto done;
+    }
+
+    fp = fopen(file_name, "w");
+    if (fp == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Could not create file %s\n", file_name);
+        ret = 1;
+        goto done;
+    }
+    fclose(fp);
+
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
+static int test_colondb_setup(void **state, bool create_file)
+{
+    struct test_colondb_ctx *test_ctx = NULL;
+
+    assert_true(leak_check_setup());
+
+    test_ctx = talloc_zero(global_talloc_context, struct test_colondb_ctx);
+    assert_non_null(test_ctx);
+
+    if (create_file) {
+        _create_file(TESTS_PATH, TESTS_FILE);
+        test_ctx->is_file_created = true;
+    } else {
+        test_ctx->is_file_created = false;
+    }
+
+    *state = test_ctx;
+
+    return 0;
+}
+
+static int test_colondb_without_file_setup(void **state)
+{
+    return test_colondb_setup(state, false);
+}
+
+static int test_colondb_with_file_setup(void **state)
+{
+    return test_colondb_setup(state, true);
+}
+
+static int test_colondb_teardown(void **state)
+{
+    struct test_colondb_ctx *test_ctx = NULL;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct test_colondb_ctx);
+
+    if (test_ctx->is_file_created) {
+        errno = 0;
+        ret = unlink(TESTS_PATH "/" TESTS_FILE);
+        if (ret != 0 && errno != ENOENT) {
+            ret = errno;
+            DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test config "
+                                       "ldb file [%d]: (%s)\n",
+                  ret, sss_strerror(ret));
+        }
+    }
+
+    talloc_zfree(*state);
+    test_dom_suite_cleanup(TESTS_PATH, NULL, NULL);
+    assert_true(leak_check_teardown());
+
+    return 0;
+}
+
+void test_open_nonexist_for_read(void **state)
+{
+
+    struct test_colondb_ctx *test_ctx = NULL;
+    struct sss_colondb *db = NULL;
+
+    test_ctx = talloc_get_type_abort(*state, struct test_colondb_ctx);
+
+    check_leaks_push(test_ctx);
+    db =
+        sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE);
+    assert_true(check_leaks_pop(test_ctx) == true);
+    assert_null(db);
+}
+
+void test_open_nonexist_for_write(void **state)
+{
+
+    struct test_colondb_ctx *test_ctx = NULL;
+    struct sss_colondb *db = NULL;
+
+    test_ctx = talloc_get_type_abort(*state, struct test_colondb_ctx);
+
+    check_leaks_push(test_ctx);
+    db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+                          TESTS_PATH "/" TESTS_FILE);
+    test_ctx->is_file_created = true;
+    assert_true(check_leaks_pop(test_ctx) == true);
+    assert_null(db);
+}
+
+void test_open_exist_for_read(void **state)
+{
+
+    struct test_colondb_ctx *test_ctx = NULL;
+    struct sss_colondb *db = NULL;
+
+    test_ctx = talloc_get_type_abort(*state, struct test_colondb_ctx);
+
+    db =
+        sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE);
+    assert_non_null(db);
+}
+
+void test_open_exist_for_write(void **state)
+{
+
+    struct test_colondb_ctx *test_ctx = NULL;
+    struct sss_colondb *db = NULL;
+
+    test_ctx = talloc_get_type_abort(*state, struct test_colondb_ctx);
+
+    db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+                          TESTS_PATH "/" TESTS_FILE);
+    assert_non_null(db);
+}
+
+int main(int argc, const char *argv[])
+{
+    poptContext pc;
+    int opt;
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND};
+
+    const struct CMUnitTest tests[] = {
+        new_test_without_file(open_nonexist_for_read),
+        new_test_without_file(open_nonexist_for_write),
+        new_test_with_file(open_exist_for_read),
+        new_test_with_file(open_exist_for_write),
+    };
+
+    /* Set debug level to invalid value so we can deside if -d 0 was used. */
+    debug_level = SSSDBG_INVALID;
+
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+    while ((opt = poptGetNextOpt(pc)) != -1) {
+        switch (opt) {
+        default:
+            fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0),
+                    poptStrerror(opt));
+            poptPrintUsage(pc, stderr, 0);
+            return 1;
+        }
+    }
+    poptFreeContext(pc);
+
+    DEBUG_CLI_INIT(debug_level);
+
+    /* Even though normally the tests should clean up after themselves
+     * they might not after a failed run. Remove the old db to be sure */
+    tests_set_cwd();
+    test_dom_suite_cleanup(TESTS_PATH, NULL, NULL);
+
+    return cmocka_run_group_tests(tests, NULL, NULL);
+}
-- 
2.4.3

