summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am12
-rw-r--r--src/providers/ad/ad_common.c16
-rw-r--r--src/providers/data_provider.h5
-rw-r--r--src/providers/data_provider_opts.c42
-rw-r--r--src/tests/cmocka/test_dp_opts.c421
-rw-r--r--src/tests/ipa_ldap_opt-tests.c2
6 files changed, 476 insertions, 22 deletions
diff --git a/Makefile.am b/Makefile.am
index f490bc39a..d9d41df5f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -154,6 +154,7 @@ if HAVE_CMOCKA
test_utils \
ad_access_filter_tests \
ad_common_tests \
+ dp_opt_tests \
test_search_bases
endif
@@ -1456,6 +1457,17 @@ ad_common_tests_LDADD = \
libsss_krb5_common.la \
libsss_test_common.la
+dp_opt_tests_SOURCES = \
+ src/providers/data_provider_opts.c \
+ src/tests/cmocka/test_dp_opts.c
+dp_opt_tests_CFLAGS = \
+ $(AM_CFLAGS)
+dp_opt_tests_LDADD = \
+ $(CMOCKA_LIBS) \
+ $(TALLOC_LIBS) \
+ $(SSSD_INTERNAL_LTLIBS) \
+ libsss_test_common.la
+
endif
noinst_PROGRAMS = pam_test_client
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 99fa4c07a..605de49f7 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -44,10 +44,10 @@ ad_create_default_sdap_options(TALLOC_CTX *mem_ctx)
return NULL;
}
- ret = dp_copy_options(id_opts,
- ad_def_ldap_opts,
- SDAP_OPTS_BASIC,
- &id_opts->basic);
+ ret = dp_copy_defaults(id_opts,
+ ad_def_ldap_opts,
+ SDAP_OPTS_BASIC,
+ &id_opts->basic);
if (ret != EOK) {
goto fail;
}
@@ -117,10 +117,10 @@ ad_create_default_options(TALLOC_CTX *mem_ctx,
ad_options = talloc_zero(mem_ctx, struct ad_options);
if (ad_options == NULL) return NULL;
- ret = dp_copy_options(ad_options,
- ad_basic_opts,
- AD_OPTS_BASIC,
- &ad_options->basic);
+ ret = dp_copy_defaults(ad_options,
+ ad_basic_opts,
+ AD_OPTS_BASIC,
+ &ad_options->basic);
if (ret != EOK) {
talloc_free(ad_options);
return NULL;
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index d086d5d2f..d86ff58e6 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -295,6 +295,11 @@ int dp_copy_options(TALLOC_CTX *memctx,
int num_opts,
struct dp_option **_opts);
+int dp_copy_defaults(TALLOC_CTX *memctx,
+ struct dp_option *src_opts,
+ int num_opts,
+ struct dp_option **_opts);
+
const char *_dp_opt_get_cstring(struct dp_option *opts,
int id, const char *location);
char *_dp_opt_get_string(struct dp_option *opts,
diff --git a/src/providers/data_provider_opts.c b/src/providers/data_provider_opts.c
index 5a2e3b74d..0cc48e46e 100644
--- a/src/providers/data_provider_opts.c
+++ b/src/providers/data_provider_opts.c
@@ -131,11 +131,11 @@ done:
}
/* =Basic-Option-Helpers================================================== */
-
-int dp_copy_options(TALLOC_CTX *memctx,
- struct dp_option *src_opts,
- int num_opts,
- struct dp_option **_opts)
+static int dp_copy_options_ex(TALLOC_CTX *memctx,
+ bool copy_values,
+ struct dp_option *src_opts,
+ int num_opts,
+ struct dp_option **_opts)
{
struct dp_option *opts;
int i, ret = EOK;
@@ -151,9 +151,9 @@ int dp_copy_options(TALLOC_CTX *memctx,
switch (src_opts[i].type) {
case DP_OPT_STRING:
- if (src_opts[i].val.string) {
+ if (copy_values) {
ret = dp_opt_set_string(opts, i, src_opts[i].val.string);
- } else if (src_opts[i].def_val.string) {
+ } else {
ret = dp_opt_set_string(opts, i, src_opts[i].def_val.string);
}
if (ret != EOK) {
@@ -169,9 +169,9 @@ int dp_copy_options(TALLOC_CTX *memctx,
break;
case DP_OPT_BLOB:
- if (src_opts[i].val.blob.data) {
+ if (copy_values) {
ret = dp_opt_set_blob(opts, i, src_opts[i].val.blob);
- } else if (src_opts[i].def_val.blob.data) {
+ } else {
ret = dp_opt_set_blob(opts, i, src_opts[i].def_val.blob);
}
if (ret != EOK) {
@@ -185,9 +185,9 @@ int dp_copy_options(TALLOC_CTX *memctx,
break;
case DP_OPT_NUMBER:
- if (src_opts[i].val.number) {
+ if (copy_values) {
ret = dp_opt_set_int(opts, i, src_opts[i].val.number);
- } else if (src_opts[i].def_val.number) {
+ } else {
ret = dp_opt_set_int(opts, i, src_opts[i].def_val.number);
}
if (ret != EOK) {
@@ -201,9 +201,9 @@ int dp_copy_options(TALLOC_CTX *memctx,
break;
case DP_OPT_BOOL:
- if (src_opts[i].val.boolean) {
+ if (copy_values) {
ret = dp_opt_set_bool(opts, i, src_opts[i].val.boolean);
- } else if (src_opts[i].def_val.boolean) {
+ } else {
ret = dp_opt_set_bool(opts, i, src_opts[i].def_val.boolean);
}
if (ret != EOK) {
@@ -225,6 +225,22 @@ done:
return ret;
}
+int dp_copy_options(TALLOC_CTX *memctx,
+ struct dp_option *src_opts,
+ int num_opts,
+ struct dp_option **_opts)
+{
+ return dp_copy_options_ex(memctx, true, src_opts, num_opts, _opts);
+}
+
+int dp_copy_defaults(TALLOC_CTX *memctx,
+ struct dp_option *src_opts,
+ int num_opts,
+ struct dp_option **_opts)
+{
+ return dp_copy_options_ex(memctx, false, src_opts, num_opts, _opts);
+}
+
static const char *dp_opt_type_to_string(enum dp_opt_type type)
{
switch (type) {
diff --git a/src/tests/cmocka/test_dp_opts.c b/src/tests/cmocka/test_dp_opts.c
new file mode 100644
index 000000000..07998b403
--- /dev/null
+++ b/src/tests/cmocka/test_dp_opts.c
@@ -0,0 +1,421 @@
+/*
+ Authors:
+ Jakub Hrozek <jhrozek@redhat.com>
+
+ Copyright (C) 2014 Red Hat
+
+ SSSD tests: Data Provider Option Tests
+
+ 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 <popt.h>
+
+#include "providers/data_provider.h"
+
+#include "tests/cmocka/common_mock.h"
+
+#define STRING_DEFAULT "stringval"
+#define BLOB_DEFAULT "blobval"
+#define INT_DEFAULT 123
+
+#define TESTS_PATH "tests_opts"
+#define TEST_CONF_DB "test_opt_conf.ldb"
+#define TEST_SYSDB_FILE "cache_opt_test.ldb"
+#define TEST_DOM_NAME "opt_test"
+#define TEST_ID_PROVIDER "ldap"
+
+enum test_opts {
+ OPT_STRING_NODEFAULT,
+ OPT_STRING_DEFAULT,
+ OPT_BLOB_NODEFAULT,
+ OPT_BLOB_DEFAULT,
+ OPT_INT_NODEFAULT,
+ OPT_INT_DEFAULT,
+ OPT_BOOL_TRUE,
+ OPT_BOOL_FALSE,
+
+ OPT_NUM_OPTS
+};
+
+struct dp_option test_def_opts[] = {
+ { "string_nodefault", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "string_default", DP_OPT_STRING, { STRING_DEFAULT }, NULL_STRING},
+ { "blob_nodefault", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB },
+ { "blob_default", DP_OPT_BLOB,
+ { .blob = { discard_const(BLOB_DEFAULT),
+ sizeof(BLOB_DEFAULT) - 1 } },
+ NULL_BLOB },
+ { "int_nodefault", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER },
+ { "int_default", DP_OPT_NUMBER, { .number = INT_DEFAULT }, NULL_NUMBER },
+ { "bool_true", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
+ { "bool_false", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+ DP_OPTION_TERMINATOR
+};
+
+static void assert_defaults(struct dp_option *opts)
+{
+ char *s;
+ struct dp_opt_blob b;
+ int i;
+ bool bo;
+
+ s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
+ assert_null(s);
+
+ s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
+ assert_non_null(s);
+ assert_string_equal(s, STRING_DEFAULT);
+
+ b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
+ assert_null(b.data);
+ assert_int_equal(b.length, 0);
+
+ b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
+ assert_non_null(b.data);
+ assert_int_equal(b.length, strlen(BLOB_DEFAULT));
+ assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT));
+
+ i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
+ assert_int_equal(i, 0);
+
+ i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
+ assert_int_equal(i, INT_DEFAULT);
+
+ bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
+ assert_true(bo == true);
+
+ bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE);
+ assert_true(bo == false);
+}
+
+void opt_test_copy_default(void **state)
+{
+ int ret;
+ TALLOC_CTX *mem_ctx;
+ struct dp_option *opts;
+ struct dp_opt_blob b;
+
+ mem_ctx = talloc_new(global_talloc_context);
+ assert_non_null(mem_ctx);
+
+ ret = dp_copy_defaults(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts);
+ assert_int_equal(ret, EOK);
+ assert_defaults(opts);
+
+ /* Test that copy_defaults would still copy defaults even if we
+ * change the values
+ */
+ ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1");
+ assert_int_equal(ret, EOK);
+ ret = dp_opt_set_string(opts, OPT_STRING_DEFAULT, "str2");
+ assert_int_equal(ret, EOK);
+
+ b.data = discard_const_p(uint8_t, "blob1");
+ b.length = strlen("blob1");
+ ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b);
+ assert_int_equal(ret, EOK);
+
+ ret = dp_opt_set_blob(opts, OPT_BLOB_DEFAULT, b);
+ b.data = discard_const_p(uint8_t, "blob2");
+ b.length = strlen("blob2");
+ assert_int_equal(ret, EOK);
+
+ ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456);
+ assert_int_equal(ret, EOK);
+ ret = dp_opt_set_int(opts, OPT_INT_DEFAULT, 789);
+ assert_int_equal(ret, EOK);
+
+ ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
+ assert_int_equal(ret, EOK);
+ ret = dp_opt_set_bool(opts, OPT_BOOL_FALSE, true);
+ assert_int_equal(ret, EOK);
+
+ talloc_free(opts);
+ ret = dp_copy_defaults(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts);
+ assert_int_equal(ret, EOK);
+ assert_defaults(opts);
+}
+
+void opt_test_copy_options(void **state)
+{
+ int ret;
+ TALLOC_CTX *mem_ctx;
+ struct dp_option *opts;
+ char *s;
+ struct dp_opt_blob b;
+ int i;
+ bool bo;
+
+ mem_ctx = talloc_new(global_talloc_context);
+ assert_non_null(mem_ctx);
+
+ ret = dp_copy_options(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts);
+ assert_int_equal(ret, EOK);
+ assert_int_equal(ret, EOK);
+
+ ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1");
+ assert_int_equal(ret, EOK);
+
+ b.data = discard_const_p(uint8_t, "blob1");
+ b.length = strlen("blob1");
+ ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b);
+ assert_int_equal(ret, EOK);
+
+ ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456);
+ assert_int_equal(ret, EOK);
+
+ ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
+ assert_int_equal(ret, EOK);
+
+ /* Test that options set to an explicit value retain
+ * the value and even options with default value
+ * do not return the default unless explicitly set
+ */
+ s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
+ assert_string_equal(s, "str1");
+ s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
+ assert_null(s);
+
+ b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
+ assert_non_null(b.data);
+ assert_int_equal(b.length, strlen("blob1"));
+ assert_memory_equal(b.data, "blob1", strlen("blob1"));
+ b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
+ assert_null(b.data);
+ assert_int_equal(b.length, 0);
+
+ i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
+ assert_int_equal(i, 456);
+ i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
+ assert_int_equal(i, 0);
+
+ bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
+ assert_false(bo == true);
+}
+
+void opt_test_get(void **state)
+{
+ int ret;
+ struct sss_test_ctx *tctx;
+ struct dp_option *opts;
+ char *dompath;
+ struct sss_test_conf_param params[] = {
+ { "string_nodefault", "stringval2" },
+ { "blob_nodefault", "blobval2" },
+ { "int_nodefault", "456" },
+ { "bool_true", "false" },
+ { NULL, NULL }, /* Sentinel */
+ };
+ char *s;
+ struct dp_opt_blob b;
+ int i;
+ bool bo;
+
+ tctx = create_dom_test_ctx(global_talloc_context, TESTS_PATH, TEST_CONF_DB,
+ TEST_SYSDB_FILE, TEST_DOM_NAME,
+ TEST_ID_PROVIDER, params);
+ assert_non_null(tctx);
+
+ dompath = talloc_asprintf(tctx, "config/domain/%s", TEST_DOM_NAME);
+ assert_non_null(dompath);
+
+ ret = dp_get_options(global_talloc_context, tctx->confdb, dompath,
+ test_def_opts, OPT_NUM_OPTS, &opts);
+ assert_int_equal(ret, EOK);
+
+ /* Options that were not specified explicitly should only have the default
+ * value, those that have been specified explicitly should carry that
+ * value
+ */
+ s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
+ assert_non_null(s);
+ assert_string_equal(s, "stringval2");
+
+ s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
+ assert_non_null(s);
+ assert_string_equal(s, STRING_DEFAULT);
+
+ b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
+ assert_non_null(b.data);
+ assert_int_equal(b.length, strlen("blobval2"));
+ assert_memory_equal(b.data, "blobval2", strlen("blobval2"));
+
+ b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
+ assert_non_null(b.data);
+ assert_int_equal(b.length, strlen(BLOB_DEFAULT));
+ assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT));
+
+ i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
+ assert_int_equal(i, 456);
+
+ i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
+ assert_int_equal(i, INT_DEFAULT);
+
+ bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
+ assert_true(bo == false);
+
+ bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE);
+ assert_true(bo == false);
+}
+
+void opt_test_getset_setup(void **state)
+{
+ int ret;
+ struct dp_option *opts;
+
+ ret = dp_copy_defaults(global_talloc_context,
+ test_def_opts, OPT_NUM_OPTS, &opts);
+ assert_int_equal(ret, EOK);
+ assert_defaults(opts);
+
+ *state = opts;
+}
+
+void opt_test_getset_teardown(void **state)
+{
+ struct dp_option *opts = talloc_get_type(*state, struct dp_option);
+ talloc_free(opts);
+}
+
+void opt_test_getset_string(void **state)
+{
+ struct dp_option *opts = talloc_get_type(*state, struct dp_option);
+ int ret;
+ char *s;
+
+ s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
+ assert_null(s);
+
+ ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1");
+ assert_int_equal(ret, EOK);
+
+ s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
+ assert_non_null(s);
+ assert_string_equal(s, "str1");
+}
+
+void opt_test_getset_blob(void **state)
+{
+ struct dp_option *opts = talloc_get_type(*state, struct dp_option);
+ int ret;
+ struct dp_opt_blob b;
+
+ b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
+ assert_null(b.data);
+ assert_int_equal(b.length, 0);
+
+ b.data = discard_const_p(uint8_t, "blob2");
+ b.length = strlen("blob2");
+ ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b);
+ assert_int_equal(ret, EOK);
+
+ b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
+ assert_non_null(b.data);
+ assert_int_equal(b.length, strlen("blob2"));
+ assert_memory_equal(b.data, "blob2", strlen("blob2"));
+}
+
+void opt_test_getset_int(void **state)
+{
+ struct dp_option *opts = talloc_get_type(*state, struct dp_option);
+ int ret;
+ int i;
+
+ i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
+ assert_int_equal(i, 0);
+
+ ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456);
+ assert_int_equal(ret, EOK);
+
+ i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
+ assert_int_equal(i, 456);
+}
+
+void opt_test_getset_bool(void **state)
+{
+ struct dp_option *opts = talloc_get_type(*state, struct dp_option);
+ int ret;
+ bool b;
+
+ b = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
+ assert_true(b == true);
+
+ ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
+ assert_int_equal(ret, EOK);
+
+ b = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
+ assert_false(b == true);
+}
+
+int main(int argc, const char *argv[])
+{
+ int no_cleanup = 0;
+ poptContext pc;
+ int opt;
+ int ret;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_DEBUG_OPTS
+ {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
+ _("Do not delete the test database after a test run"), NULL },
+ POPT_TABLEEND
+ };
+ const UnitTest tests[] = {
+ unit_test_setup_teardown(opt_test_getset_string,
+ opt_test_getset_setup,
+ opt_test_getset_teardown),
+ unit_test_setup_teardown(opt_test_getset_int,
+ opt_test_getset_setup,
+ opt_test_getset_teardown),
+ unit_test_setup_teardown(opt_test_getset_bool,
+ opt_test_getset_setup,
+ opt_test_getset_teardown),
+ unit_test_setup_teardown(opt_test_getset_blob,
+ opt_test_getset_setup,
+ opt_test_getset_teardown),
+ unit_test(opt_test_copy_default),
+ unit_test(opt_test_copy_options),
+ unit_test(opt_test_get)
+ };
+
+ /* 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_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, TEST_CONF_DB, TEST_SYSDB_FILE);
+ test_dom_suite_setup(TESTS_PATH);
+
+ ret = run_tests(tests);
+ if (ret == 0 && !no_cleanup) {
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE);
+ }
+ return ret;
+}
diff --git a/src/tests/ipa_ldap_opt-tests.c b/src/tests/ipa_ldap_opt-tests.c
index 40afa5cba..25a094082 100644
--- a/src/tests/ipa_ldap_opt-tests.c
+++ b/src/tests/ipa_ldap_opt-tests.c
@@ -170,7 +170,7 @@ START_TEST(test_copy_opts)
tmp_ctx = talloc_new(NULL);
fail_unless(tmp_ctx != NULL, "talloc_new failed");
- ret = dp_copy_options(tmp_ctx, ad_def_ldap_opts, SDAP_OPTS_BASIC, &opts);
+ ret = dp_copy_defaults(tmp_ctx, ad_def_ldap_opts, SDAP_OPTS_BASIC, &opts);
fail_unless(ret == EOK, "[%s]", strerror(ret));
for (int i=0; i < SDAP_OPTS_BASIC; i++) {