[PATCH] Re: ldb cmocka tests
Andreas Schneider
asn at samba.org
Mon Apr 10 10:13:11 UTC 2017
On Monday, 10 April 2017 00:26:06 CEST Andrew Bartlett wrote:
> On Fri, 2017-04-07 at 11:11 +0200, Andreas Schneider wrote:
> > On Friday, 7 April 2017 05:18:02 CEST Andrew Bartlett wrote:
> > > > Can you look at this cmocka test for me? I've been writing one
> > > > to
> > > > show
> > > > the ldb_tdb locking bug in the other thread. I like cmocka!
> > > >
> > > > I'm not sure what the correct interaction with fork() is meant to
> > > > be,
> > > > but I've made this work for now.
> >
> > The test looks fine. I think the original idea of the file is to test
> > the API.
> >
> > This test you wrote is a special case. I would put that in its own
> > binary.
> >
> > The setup/teardown functions could be shared.
>
> Currently we don't have a good framework for multiple tests in ldb. To
> split it out we need to create that, with a set of test names and a way
> to ensure we run them all.
>
> I think we both want to get the concept of cmocka in for now, can we
> leave this for the next large test expansion?
>
> Otherwise, could you show how you would like it split up by splitting
> the existing test up, so I can just follow the same pattern?
Ok, lets first bring the patchset upstream.
Here is a rebased version on the third_party cmocka code which is upstream
now. After this is upstream we can look at your additions to the ldb tests.
Are you OK with that?
Cheers,
Andreas
--
Andreas Schneider GPG-ID: CC014E3D
Samba Team asn at samba.org
www.samba.org
-------------- next part --------------
>From 9f2892b753aeb41039c852dcf4117ae8feb01f9f Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Mon, 11 May 2015 22:24:01 +0200
Subject: [PATCH 01/14] ldb_tdb: Remove unused function ltdb_add_attr_results
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/ldb_tdb/ldb_search.c | 134 -------------------------------------------
lib/ldb/ldb_tdb/ldb_tdb.h | 6 --
2 files changed, 140 deletions(-)
diff --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c
index 373855fd428..53355e04f6b 100644
--- a/lib/ldb/ldb_tdb/ldb_search.c
+++ b/lib/ldb/ldb_tdb/ldb_search.c
@@ -109,102 +109,6 @@ static int msg_add_distinguished_name(struct ldb_message *msg)
}
/*
- add all elements from one message into another
- */
-static int msg_add_all_elements(struct ldb_module *module, struct ldb_message *ret,
- const struct ldb_message *msg)
-{
- struct ldb_context *ldb;
- unsigned int i;
- int check_duplicates = (ret->num_elements != 0);
-
- ldb = ldb_module_get_ctx(module);
-
- if (msg_add_distinguished_name(ret) != 0) {
- return -1;
- }
-
- for (i=0;i<msg->num_elements;i++) {
- const struct ldb_schema_attribute *a;
- a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name);
- if (a->flags & LDB_ATTR_FLAG_HIDDEN) {
- continue;
- }
- if (msg_add_element(ret, &msg->elements[i],
- check_duplicates) != 0) {
- return -1;
- }
- }
-
- return 0;
-}
-
-
-/*
- pull the specified list of attributes from a message
- */
-static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
- TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg,
- const char * const *attrs)
-{
- struct ldb_message *ret;
- unsigned int i;
-
- ret = talloc(mem_ctx, struct ldb_message);
- if (!ret) {
- return NULL;
- }
-
- ret->dn = ldb_dn_copy(ret, msg->dn);
- if (!ret->dn) {
- talloc_free(ret);
- return NULL;
- }
-
- ret->num_elements = 0;
- ret->elements = NULL;
-
- if (!attrs) {
- if (msg_add_all_elements(module, ret, msg) != 0) {
- talloc_free(ret);
- return NULL;
- }
- return ret;
- }
-
- for (i=0;attrs[i];i++) {
- struct ldb_message_element *el;
-
- if (strcmp(attrs[i], "*") == 0) {
- if (msg_add_all_elements(module, ret, msg) != 0) {
- talloc_free(ret);
- return NULL;
- }
- continue;
- }
-
- if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) {
- if (msg_add_distinguished_name(ret) != 0) {
- return NULL;
- }
- continue;
- }
-
- el = ldb_msg_find_element(msg, attrs[i]);
- if (!el) {
- continue;
- }
- if (msg_add_element(ret, el, 1) != 0) {
- talloc_free(ret);
- return NULL;
- }
- }
-
- return ret;
-}
-
-/*
search the database for a single simple dn.
return LDB_ERR_NO_SUCH_OBJECT on record-not-found
and LDB_SUCCESS on success
@@ -346,44 +250,6 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes
}
/*
- add a set of attributes from a record to a set of results
- return 0 on success, -1 on failure
-*/
-int ltdb_add_attr_results(struct ldb_module *module,
- TALLOC_CTX *mem_ctx,
- struct ldb_message *msg,
- const char * const attrs[],
- unsigned int *count,
- struct ldb_message ***res)
-{
- struct ldb_message *msg2;
- struct ldb_message **res2;
-
- /* pull the attributes that the user wants */
- msg2 = ltdb_pull_attrs(module, mem_ctx, msg, attrs);
- if (!msg2) {
- return -1;
- }
-
- /* add to the results list */
- res2 = talloc_realloc(mem_ctx, *res, struct ldb_message *, (*count)+2);
- if (!res2) {
- talloc_free(msg2);
- return -1;
- }
-
- (*res) = res2;
-
- (*res)[*count] = talloc_move(*res, &msg2);
- (*res)[(*count)+1] = NULL;
- (*count)++;
-
- return 0;
-}
-
-
-
-/*
filter the specified list of attributes from a message
removing not requested attrs from the new message constructed.
diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h
index 7caedebe4c7..26ae68e89c8 100644
--- a/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -102,12 +102,6 @@ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name,
void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg);
int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg,
unsigned int unpack_flags);
-int ltdb_add_attr_results(struct ldb_module *module,
- TALLOC_CTX *mem_ctx,
- struct ldb_message *msg,
- const char * const attrs[],
- unsigned int *count,
- struct ldb_message ***res);
int ltdb_filter_attrs(TALLOC_CTX *mem_ctx,
const struct ldb_message *msg, const char * const *attrs,
struct ldb_message **filtered_msg);
--
2.12.2
>From 79ac15fd5e4a85d112aec69be2e9fcfd2a7019db Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Mon, 2 Feb 2015 15:33:24 +0100
Subject: [PATCH 02/14] ldb_tdb: Remove unused function parameter
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/ldb_tdb/ldb_tdb.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c
index 6b1187e64ad..e1903695bf3 100644
--- a/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -571,7 +571,6 @@ static int ltdb_msg_add_element(struct ldb_context *ldb,
delete all elements having a specified attribute name
*/
static int msg_delete_attribute(struct ldb_module *module,
- struct ldb_context *ldb,
struct ldb_message *msg, const char *name)
{
unsigned int i;
@@ -638,7 +637,7 @@ static int msg_delete_element(struct ldb_module *module,
}
if (matched) {
if (el->num_values == 1) {
- return msg_delete_attribute(module, ldb, msg, name);
+ return msg_delete_attribute(module, msg, name);
}
ret = ltdb_index_del_value(module, msg->dn, el, i);
@@ -901,7 +900,7 @@ int ltdb_modify_internal(struct ldb_module *module,
}
/* Delete the attribute if it exists in the DB */
- if (msg_delete_attribute(module, ldb, msg2,
+ if (msg_delete_attribute(module, msg2,
el->name) != 0) {
ret = LDB_ERR_OTHER;
goto done;
@@ -930,7 +929,7 @@ int ltdb_modify_internal(struct ldb_module *module,
if (msg->elements[i].num_values == 0) {
/* Delete the whole attribute */
- ret = msg_delete_attribute(module, ldb, msg2,
+ ret = msg_delete_attribute(module, msg2,
msg->elements[i].name);
if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE &&
control_permissive) {
--
2.12.2
>From c715fb006b9066f9be494ee399fdb5395244c15a Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Mon, 2 Feb 2015 15:48:47 +0100
Subject: [PATCH 03/14] ldb_tdb: Remove unused function parameter
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/ldb_tdb/ldb_tdb.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c
index e1903695bf3..c0d7a1a432b 100644
--- a/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -526,8 +526,7 @@ static int find_element(const struct ldb_message *msg, const char *name)
returns 0 on success, -1 on failure (and sets errno)
*/
-static int ltdb_msg_add_element(struct ldb_context *ldb,
- struct ldb_message *msg,
+static int ltdb_msg_add_element(struct ldb_message *msg,
struct ldb_message_element *el)
{
struct ldb_message_element *e2;
@@ -772,7 +771,7 @@ int ltdb_modify_internal(struct ldb_module *module,
/* Checks if element already exists */
idx = find_element(msg2, el->name);
if (idx == -1) {
- if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
+ if (ltdb_msg_add_element(msg2, el) != 0) {
ret = LDB_ERR_OTHER;
goto done;
}
@@ -908,7 +907,7 @@ int ltdb_modify_internal(struct ldb_module *module,
}
/* Recreate it with the new values */
- if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
+ if (ltdb_msg_add_element(msg2, el) != 0) {
ret = LDB_ERR_OTHER;
goto done;
}
--
2.12.2
>From c1abc5d6da197ab6efaa7327affd396beae3731a Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Fri, 16 Jan 2015 18:52:48 +0100
Subject: [PATCH 04/14] ldb: Clarify LDB_MODULES_PATH is used
Make it (hopefully more) clear where modules are loaded from.
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/include/ldb.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h
index afcf9eb6351..1160a48cc06 100644
--- a/lib/ldb/include/ldb.h
+++ b/lib/ldb/include/ldb.h
@@ -1056,6 +1056,10 @@ int ldb_global_init(void);
\param mem_ctx pointer to a talloc memory context. Pass NULL if there is
no suitable context available.
+ \note The LDB modules will be loaded from directory specified by the environment
+ variable LDB_MODULES_PATH. If the variable is not specified, the compiled-in default
+ is used.
+
\return pointer to ldb_context that should be free'd (using talloc_free())
at the end of the program.
*/
--
2.12.2
>From ab00efdc6117056e88b75ee1104468f5a3e28631 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Sat, 17 Jan 2015 18:06:09 +0100
Subject: [PATCH 05/14] ldb:tests: Add a simple cmocka test for ldb_connect()
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 107 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 lib/ldb/tests/ldb_mod_op_test.c
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
new file mode 100644
index 00000000000..afd47a9773d
--- /dev/null
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -0,0 +1,107 @@
+/*
+ * from cmocka.c:
+ * These headers or their equivalents should be included prior to
+ * including
+ * this header file.
+ *
+ * #include <stdarg.h>
+ * #include <stddef.h>
+ * #include <setjmp.h>
+ *
+ * This allows test applications to use custom definitions of C standard
+ * library functions and types.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <cmocka.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <talloc.h>
+#include <ldb.h>
+
+#define DEFAULT_BE "tdb"
+
+#ifndef TEST_BE
+#define TEST_BE DEFAULT_BE
+#endif /* TEST_BE */
+
+struct ldbtest_ctx {
+ struct tevent_context *ev;
+ struct ldb_context *ldb;
+
+ const char *dbfile;
+ const char *lockfile;
+
+ const char *dbpath;
+ const char *lockpath; /* lockfile is separate */
+};
+
+static int ldbtest_noconn_setup(void **state)
+{
+ struct ldbtest_ctx *test_ctx;
+
+ test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
+ assert_non_null(test_ctx);
+
+ test_ctx->ev = tevent_context_init(test_ctx);
+ assert_non_null(test_ctx->ev);
+
+ test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
+ assert_non_null(test_ctx->ldb);
+
+ test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
+ assert_non_null(test_ctx->dbfile);
+
+ test_ctx->lockfile = talloc_asprintf(test_ctx,
+ "%s-lock", test_ctx->dbfile);
+ assert_non_null(test_ctx->lockfile);
+
+ test_ctx->dbpath = talloc_asprintf(test_ctx,
+ TEST_BE"://%s", test_ctx->dbfile);
+ assert_non_null(test_ctx->dbpath);
+
+ test_ctx->lockpath = talloc_asprintf(test_ctx,
+ "%s-lock", test_ctx->dbpath);
+ assert_non_null(test_ctx->lockpath);
+
+ *state = test_ctx;
+ return 0;
+}
+
+static int ldbtest_noconn_teardown(void **state)
+{
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+
+ unlink(test_ctx->lockfile);
+
+ unlink(test_ctx->dbfile);
+
+ talloc_free(test_ctx);
+ return 0;
+}
+
+static void test_connect(void **state)
+{
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ int ret;
+
+ ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
+ assert_int_equal(ret, 0);
+}
+
+int main(int argc, const char **argv)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_connect,
+ ldbtest_noconn_setup,
+ ldbtest_noconn_teardown),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
--
2.12.2
>From 9f196ead7716341db9524af5dcb58052584e03ee Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 2 Oct 2015 11:36:50 +0200
Subject: [PATCH 06/14] ldb:tests: Build a ldb test for the tdb backend
Pair-Programmed-With: Andrew Bartlet <abartlet at samba.org>
Signed-off-by: Andreas Schneider <asn at samba.org>
Signed-off-by: Andrew Bartlet <abartlet at samba.org>
---
lib/ldb/wscript | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/lib/ldb/wscript b/lib/ldb/wscript
index c877f3bc7f6..14a13fdce00 100644
--- a/lib/ldb/wscript
+++ b/lib/ldb/wscript
@@ -35,12 +35,18 @@ def configure(conf):
if conf.CHECK_FOR_THIRD_PARTY():
conf.RECURSE('third_party/popt')
+ conf.RECURSE('third_party/cmocka')
else:
if not conf.CHECK_POPT():
raise Utils.WafError('popt development packages have not been found.\nIf third_party is installed, check that it is in the proper place.')
else:
conf.define('USING_SYSTEM_POPT', 1)
+ if not conf.CHECK_CMOCKA():
+ raise Utils.WafError('cmocka development package have not been found.\nIf third_party is installed, check that it is in the proper place.')
+ else:
+ conf.define('USING_SYSTEM_CMOCKA', 1)
+
conf.RECURSE('lib/replace')
conf.find_program('python', var='PYTHON')
conf.find_program('xsltproc', var='XSLTPROC')
@@ -107,6 +113,7 @@ def build(bld):
if bld.CHECK_FOR_THIRD_PARTY():
bld.RECURSE('third_party/popt')
+ bld.RECURSE('third_party/cmocka')
bld.RECURSE('lib/replace')
bld.RECURSE('lib/tdb')
@@ -307,14 +314,23 @@ def build(bld):
deps='ldb dl popt',
private_library=True)
+ bld.SAMBA_BINARY('ldb_tdb_mod_op_test',
+ source='tests/ldb_mod_op_test.c',
+ cflags='-DTEST_BE=\"tdb\"',
+ deps='cmocka ldb',
+ install=False)
def test(ctx):
'''run ldb testsuite'''
import Utils, samba_utils, shutil
+ env = samba_utils.LOAD_ENVIRONMENT()
+ ctx.env = env
+
test_prefix = "%s/st" % (Utils.g_module.blddir)
shutil.rmtree(test_prefix, ignore_errors=True)
os.makedirs(test_prefix)
os.environ['TEST_DATA_PREFIX'] = test_prefix
+ os.environ['LD_LIBRARY_PATH'] = Utils.g_module.blddir + '/bin/default/lib/ldb'
cmd = 'tests/test-tdb.sh %s' % Utils.g_module.blddir
ret = samba_utils.RUN_COMMAND(cmd)
print("testsuite returned %d" % ret)
@@ -326,7 +342,13 @@ def test(ctx):
['tests/python/api.py'],
extra_env={'SELFTEST_PREFIX': test_prefix})
print("Python testsuite returned %d" % pyret)
- sys.exit(ret or pyret)
+
+ os.environ['LDB_MODULES_PATH'] = Utils.g_module.blddir + '/modules/ldb'
+ os.environ['LD_LIBRARY_PATH'] = Utils.g_module.blddir + '/bin/default/lib/ldb'
+ cmd = Utils.g_module.blddir + '/ldb_tdb_mod_op_test'
+ cmocka_ret = samba_utils.RUN_COMMAND(cmd)
+
+ sys.exit(ret or pyret or cmocka_ret)
def dist():
'''makes a tarball for distribution'''
--
2.12.2
>From bbdb3975ac9cb5aaec4d0736972cce6b7aba23b9 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Tue, 15 Sep 2015 22:39:08 +0200
Subject: [PATCH 07/14] ldb:tests: A rudimentary ldb_add() test
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 51 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index afd47a9773d..fe6a0e8af63 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -95,12 +95,63 @@ static void test_connect(void **state)
assert_int_equal(ret, 0);
}
+static int ldbtest_setup(void **state)
+{
+ struct ldbtest_ctx *test_ctx;
+ int ret;
+
+ ldbtest_noconn_setup((void **) &test_ctx);
+
+ ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
+ assert_int_equal(ret, 0);
+
+ *state = test_ctx;
+ return 0;
+}
+
+static int ldbtest_teardown(void **state)
+{
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ ldbtest_noconn_teardown((void **) &test_ctx);
+ return 0;
+}
+
+static void test_ldb_add(void **state)
+{
+ int ret;
+ struct ldb_message *msg;
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ msg = ldb_msg_new(tmp_ctx);
+ assert_non_null(msg);
+
+ msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
+ assert_non_null(msg->dn);
+
+ ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
+ assert_int_equal(ret, 0);
+
+ ret = ldb_add(test_ctx->ldb, msg);
+ assert_int_equal(ret, 0);
+
+ talloc_free(tmp_ctx);
+}
+
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_connect,
ldbtest_noconn_setup,
ldbtest_noconn_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_add,
+ ldbtest_setup,
+ ldbtest_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
>From e50028432a22bcc4e0db48fc8c170fa65e40875b Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Sat, 2 May 2015 15:01:13 +0200
Subject: [PATCH 08/14] ldb:tests: Add a basic search test
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 72 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index fe6a0e8af63..1396c16836d 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -143,6 +143,75 @@ static void test_ldb_add(void **state)
talloc_free(tmp_ctx);
}
+static void test_ldb_search(void **state)
+{
+ int ret;
+ struct ldb_message *msg;
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *basedn;
+ struct ldb_dn *basedn2;
+ struct ldb_result *result = NULL;
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
+ assert_non_null(basedn);
+
+ ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, 0);
+ assert_non_null(result);
+ assert_int_equal(result->count, 0);
+
+ msg = ldb_msg_new(tmp_ctx);
+ assert_non_null(msg);
+
+ msg->dn = basedn;
+ assert_non_null(msg->dn);
+
+ ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
+ assert_int_equal(ret, 0);
+
+ ret = ldb_add(test_ctx->ldb, msg);
+ assert_int_equal(ret, 0);
+
+ basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2");
+ assert_non_null(basedn2);
+
+ msg = ldb_msg_new(tmp_ctx);
+ assert_non_null(msg);
+
+ msg->dn = basedn2;
+ assert_non_null(msg->dn);
+
+ ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
+ assert_int_equal(ret, 0);
+
+ ret = ldb_add(test_ctx->ldb, msg);
+ assert_int_equal(ret, 0);
+
+ ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, 0);
+ assert_non_null(result);
+ assert_int_equal(result->count, 1);
+ assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
+ ldb_dn_get_linearized(basedn));
+
+ ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, 0);
+ assert_non_null(result);
+ assert_int_equal(result->count, 1);
+ assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
+ ldb_dn_get_linearized(basedn2));
+
+ talloc_free(tmp_ctx);
+}
+
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
@@ -152,6 +221,9 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_ldb_add,
ldbtest_setup,
ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_search,
+ ldbtest_setup,
+ ldbtest_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
>From b398763d7ac6d2658710cd3146e1a709c0397b79 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Tue, 20 Jan 2015 12:11:34 +0100
Subject: [PATCH 09/14] ldb:tests: Add a basic delete test
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 134 ++++++++++++++++++++++++++++++++++++----
1 file changed, 121 insertions(+), 13 deletions(-)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index 1396c16836d..3f4b49fe8ab 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -34,12 +34,28 @@ struct ldbtest_ctx {
struct ldb_context *ldb;
const char *dbfile;
- const char *lockfile;
+ const char *lockfile; /* lockfile is separate */
const char *dbpath;
- const char *lockpath; /* lockfile is separate */
};
+static void unlink_old_db(struct ldbtest_ctx *test_ctx)
+{
+ int ret;
+
+ errno = 0;
+ ret = unlink(test_ctx->lockfile);
+ if (ret == -1 && errno != ENOENT) {
+ fail();
+ }
+
+ errno = 0;
+ ret = unlink(test_ctx->dbfile);
+ if (ret == -1 && errno != ENOENT) {
+ fail();
+ }
+}
+
static int ldbtest_noconn_setup(void **state)
{
struct ldbtest_ctx *test_ctx;
@@ -56,18 +72,15 @@ static int ldbtest_noconn_setup(void **state)
test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
assert_non_null(test_ctx->dbfile);
- test_ctx->lockfile = talloc_asprintf(test_ctx,
- "%s-lock", test_ctx->dbfile);
+ test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
+ test_ctx->dbfile);
assert_non_null(test_ctx->lockfile);
test_ctx->dbpath = talloc_asprintf(test_ctx,
- TEST_BE"://%s", test_ctx->dbfile);
+ TEST_BE"://%s", test_ctx->dbfile);
assert_non_null(test_ctx->dbpath);
- test_ctx->lockpath = talloc_asprintf(test_ctx,
- "%s-lock", test_ctx->dbpath);
- assert_non_null(test_ctx->lockpath);
-
+ unlink_old_db(test_ctx);
*state = test_ctx;
return 0;
}
@@ -77,10 +90,7 @@ static int ldbtest_noconn_teardown(void **state)
struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
struct ldbtest_ctx);
- unlink(test_ctx->lockfile);
-
- unlink(test_ctx->dbfile);
-
+ unlink_old_db(test_ctx);
talloc_free(test_ctx);
return 0;
}
@@ -212,6 +222,98 @@ static void test_ldb_search(void **state)
talloc_free(tmp_ctx);
}
+static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+ int ret;
+ int count;
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, LDB_SUCCESS);
+ assert_non_null(result);
+
+ count = result->count;
+ talloc_free(tmp_ctx);
+ return count;
+}
+
+static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
+ const char *entry_dn)
+{
+ int count;
+
+ count = base_search_count(test_ctx, entry_dn);
+ assert_int_equal(count, 1);
+}
+
+static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
+ const char *entry_dn)
+{
+ int count;
+
+ count = base_search_count(test_ctx, entry_dn);
+ assert_int_equal(count, 0);
+}
+
+static void test_ldb_del(void **state)
+{
+ int ret;
+ struct ldb_message *msg;
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ TALLOC_CTX *tmp_ctx;
+ const char *basedn = "dc=ldb_del_test";
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ assert_dn_doesnt_exist(test_ctx, basedn);
+
+ msg = ldb_msg_new(tmp_ctx);
+ assert_non_null(msg);
+
+ msg->dn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", basedn);
+ assert_non_null(msg->dn);
+
+ ret = ldb_msg_add_string(msg, "cn", "test_del_cn_val");
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ ret = ldb_add(test_ctx->ldb, msg);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ assert_dn_exists(test_ctx, basedn);
+
+ ret = ldb_delete(test_ctx->ldb, msg->dn);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ assert_dn_doesnt_exist(test_ctx, basedn);
+
+ talloc_free(tmp_ctx);
+}
+
+static void test_ldb_del_noexist(void **state)
+{
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ struct ldb_dn *basedn;
+ int ret;
+
+ basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace");
+ assert_non_null(basedn);
+
+ ret = ldb_delete(test_ctx->ldb, basedn);
+ assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
+}
+
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
@@ -224,6 +326,12 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_ldb_search,
ldbtest_setup,
ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_del,
+ ldbtest_setup,
+ ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
+ ldbtest_setup,
+ ldbtest_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
>From c79c98410b57a1da56a5b93e082ef58891dd18a0 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Fri, 25 Sep 2015 07:02:12 +0200
Subject: [PATCH 10/14] ldb:tests: Add a test for ldb transactions
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 80 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index 3f4b49fe8ab..89561fff9ca 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -314,6 +314,83 @@ static void test_ldb_del_noexist(void **state)
assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
}
+static void add_keyval(struct ldbtest_ctx *test_ctx,
+ const char *key,
+ const char *val)
+{
+ int ret;
+ struct ldb_message *msg;
+
+ msg = ldb_msg_new(test_ctx);
+ assert_non_null(msg);
+
+ msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val);
+ assert_non_null(msg->dn);
+
+ ret = ldb_msg_add_string(msg, key, val);
+ assert_int_equal(ret, 0);
+
+ ret = ldb_add(test_ctx->ldb, msg);
+ assert_int_equal(ret, 0);
+
+ talloc_free(msg);
+}
+
+static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
+ const char *key,
+ const char *val)
+{
+ int ret;
+ struct ldb_result *result;
+ struct ldb_dn *basedn;
+
+ basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val);
+ assert_non_null(basedn);
+
+ ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, 0);
+
+ return result;
+}
+
+static void test_transactions(void **state)
+{
+ int ret;
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ struct ldb_result *res;
+
+ /* start lev-0 transaction */
+ ret = ldb_transaction_start(test_ctx->ldb);
+ assert_int_equal(ret, 0);
+
+ add_keyval(test_ctx, "vegetable", "carrot");
+
+ /* commit lev-0 transaction */
+ ret = ldb_transaction_commit(test_ctx->ldb);
+ assert_int_equal(ret, 0);
+
+ /* start another lev-1 nested transaction */
+ ret = ldb_transaction_start(test_ctx->ldb);
+ assert_int_equal(ret, 0);
+
+ add_keyval(test_ctx, "fruit", "apple");
+
+ /* abort lev-1 nested transaction */
+ ret = ldb_transaction_cancel(test_ctx->ldb);
+ assert_int_equal(ret, 0);
+
+ res = get_keyval(test_ctx, "vegetable", "carrot");
+ assert_non_null(res);
+ assert_int_equal(res->count, 1);
+
+ res = get_keyval(test_ctx, "fruit", "apple");
+ assert_non_null(res);
+ assert_int_equal(res->count, 0);
+}
+
+
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
@@ -332,6 +409,9 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
ldbtest_setup,
ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(test_transactions,
+ ldbtest_setup,
+ ldbtest_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
>From 23fbe618a1dec330fbea11c1eab1277c8c85a8c0 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Sat, 3 Oct 2015 20:43:45 +0200
Subject: [PATCH 11/14] ldb:tests: Add a modify test
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 423 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 423 insertions(+)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index 89561fff9ca..065bd60a55b 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -390,6 +390,402 @@ static void test_transactions(void **state)
assert_int_equal(res->count, 0);
}
+struct ldb_mod_test_ctx {
+ struct ldbtest_ctx *ldb_test_ctx;
+ const char *entry_dn;
+};
+
+struct keyval {
+ const char *key;
+ const char *val;
+};
+
+static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
+ struct ldbtest_ctx *test_ctx,
+ const char *dn,
+ int modify_flags,
+ struct keyval *kvs)
+{
+ struct ldb_message *msg;
+ int ret;
+ int i;
+
+ msg = ldb_msg_new(mem_ctx);
+ assert_non_null(msg);
+
+ msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
+ assert_non_null(msg->dn);
+
+ for (i = 0; kvs[i].key != NULL; i++) {
+ if (modify_flags) {
+ ret = ldb_msg_add_empty(msg, kvs[i].key,
+ modify_flags, NULL);
+ assert_int_equal(ret, 0);
+ }
+
+ if (kvs[i].val) {
+ ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
+ assert_int_equal(ret, LDB_SUCCESS);
+ }
+ }
+
+ return msg;
+}
+
+static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
+ struct keyval *kvs)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_message *msg;
+ struct ldb_result *result = NULL;
+ struct ldbtest_ctx *ldb_test_ctx;
+ int ret;
+
+ ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
+
+ tmp_ctx = talloc_new(mod_test_ctx);
+ assert_non_null(tmp_ctx);
+
+ msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
+ mod_test_ctx->entry_dn, 0, kvs);
+ assert_non_null(msg);
+
+ ret = ldb_add(ldb_test_ctx->ldb, msg);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, LDB_SUCCESS);
+ assert_non_null(result);
+ assert_int_equal(result->count, 1);
+ assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
+ ldb_dn_get_linearized(msg->dn));
+
+ talloc_free(tmp_ctx);
+}
+
+static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+ int ret;
+ struct ldbtest_ctx *ldb_test_ctx;
+
+ ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
+
+ tmp_ctx = talloc_new(mod_test_ctx);
+ assert_non_null(tmp_ctx);
+
+ basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
+ "%s", mod_test_ctx->entry_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_delete(ldb_test_ctx->ldb, basedn);
+ assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
+
+ ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, basedn,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, LDB_SUCCESS);
+ assert_non_null(result);
+ assert_int_equal(result->count, 0);
+
+ talloc_free(tmp_ctx);
+}
+
+static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
+ int modify_flags,
+ struct keyval *kvs)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+ struct ldb_message *mod_msg;
+ struct ldb_dn *basedn;
+ struct ldbtest_ctx *ldb_test_ctx;
+ int ret;
+
+ ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
+
+ tmp_ctx = talloc_new(mod_test_ctx);
+ assert_non_null(tmp_ctx);
+
+ mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
+ modify_flags, kvs);
+ assert_non_null(mod_msg);
+
+ ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
+ "%s", mod_test_ctx->entry_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
+ LDB_SCOPE_BASE, NULL, NULL);
+ assert_int_equal(ret, LDB_SUCCESS);
+ assert_non_null(res);
+ assert_int_equal(res->count, 1);
+ assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
+ ldb_dn_get_linearized(mod_msg->dn));
+
+ talloc_free(tmp_ctx);
+ return res;
+}
+
+static int ldb_modify_test_setup(void **state)
+{
+ struct ldbtest_ctx *ldb_test_ctx;
+ struct ldb_mod_test_ctx *mod_test_ctx;
+ struct keyval kvs[] = {
+ { "cn", "test_mod_cn" },
+ { NULL, NULL },
+ };
+
+ ldbtest_setup((void **) &ldb_test_ctx);
+
+ mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
+ assert_non_null(mod_test_ctx);
+
+ mod_test_ctx->entry_dn = "dc=mod_test_entry";
+ mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
+
+ mod_test_remove_data(mod_test_ctx);
+ mod_test_add_data(mod_test_ctx, kvs);
+ *state = mod_test_ctx;
+ return 0;
+}
+
+static int ldb_modify_test_teardown(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct ldbtest_ctx *ldb_test_ctx;
+
+ ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
+
+ mod_test_remove_data(mod_test_ctx);
+ talloc_free(mod_test_ctx);
+
+ ldbtest_teardown((void **) &ldb_test_ctx);
+ return 0;
+}
+
+static void test_ldb_modify_add_key(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct keyval mod_kvs[] = {
+ { "name", "test_mod_name" },
+ { NULL, NULL },
+ };
+ struct ldb_result *res;
+ struct ldb_message_element *el;
+
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
+ assert_non_null(res);
+
+ /* Check cn is intact and name was added */
+ assert_int_equal(res->count, 1);
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_non_null(el);
+ assert_int_equal(el->num_values, 1);
+ assert_string_equal(el->values[0].data, "test_mod_cn");
+
+ el = ldb_msg_find_element(res->msgs[0], "name");
+ assert_non_null(el);
+ assert_int_equal(el->num_values, 1);
+ assert_string_equal(el->values[0].data, "test_mod_name");
+}
+
+static void test_ldb_modify_extend_key(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct keyval mod_kvs[] = {
+ { "cn", "test_mod_cn2" },
+ { NULL, NULL },
+ };
+ struct ldb_result *res;
+ struct ldb_message_element *el;
+
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
+ assert_non_null(res);
+
+ /* Check cn was extended with another value */
+ assert_int_equal(res->count, 1);
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_non_null(el);
+ assert_int_equal(el->num_values, 2);
+ assert_string_equal(el->values[0].data, "test_mod_cn");
+ assert_string_equal(el->values[1].data, "test_mod_cn2");
+}
+
+static void test_ldb_modify_add_key_noval(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct ldb_message *mod_msg;
+ struct ldbtest_ctx *ldb_test_ctx;
+ struct ldb_message_element *el;
+ int ret;
+
+ ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
+
+ mod_msg = ldb_msg_new(mod_test_ctx);
+ assert_non_null(mod_msg);
+
+ mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
+ "%s", mod_test_ctx->entry_dn);
+ assert_non_null(mod_msg->dn);
+
+ el = talloc_zero(mod_msg, struct ldb_message_element);
+ el->flags = LDB_FLAG_MOD_ADD;
+ assert_non_null(el);
+ el->name = talloc_strdup(el, "cn");
+ assert_non_null(el->name);
+
+ mod_msg->elements = el;
+ mod_msg->num_elements = 1;
+
+ ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
+ assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
+}
+
+static void test_ldb_modify_replace_key(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ const char *new_cn = "new_cn";
+ struct keyval mod_kvs[] = {
+ { "cn", new_cn },
+ { NULL, NULL },
+ };
+ struct ldb_result *res;
+ struct ldb_message_element *el;
+
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
+ assert_non_null(res);
+
+ /* Check cn was replaced */
+ assert_int_equal(res->count, 1);
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_non_null(el);
+ assert_int_equal(el->num_values, 1);
+ assert_string_equal(el->values[0].data, new_cn);
+}
+
+static void test_ldb_modify_replace_noexist_key(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct keyval mod_kvs[] = {
+ { "name", "name_val" },
+ { NULL, NULL },
+ };
+ struct ldb_result *res;
+ struct ldb_message_element *el;
+
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
+ assert_non_null(res);
+
+ /* Check cn is intact and name was added */
+ assert_int_equal(res->count, 1);
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_non_null(el);
+ assert_int_equal(el->num_values, 1);
+ assert_string_equal(el->values[0].data, "test_mod_cn");
+
+ el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
+ assert_non_null(el);
+ assert_int_equal(el->num_values, 1);
+ assert_string_equal(el->values[0].data, mod_kvs[0].val);
+}
+
+static void test_ldb_modify_replace_zero_vals(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct ldb_message_element *el;
+ struct ldb_result *res;
+ struct keyval kvs[] = {
+ { "cn", NULL },
+ { NULL, NULL },
+ };
+
+ /* cn must be gone */
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
+ assert_non_null(res);
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_null(el);
+}
+
+static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct ldb_message_element *el;
+ struct ldb_result *res;
+ struct keyval kvs[] = {
+ { "noexist_key", NULL },
+ { NULL, NULL },
+ };
+
+ /* cn must be gone */
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
+ assert_non_null(res);
+
+ /* cn should be intact */
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_non_null(el);
+}
+
+static void test_ldb_modify_del_key(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct ldb_message_element *el;
+ struct ldb_result *res;
+ struct keyval kvs[] = {
+ { "cn", NULL },
+ { NULL, NULL },
+ };
+
+ /* cn must be gone */
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
+ assert_non_null(res);
+
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_null(el);
+}
+
+static void test_ldb_modify_del_keyval(void **state)
+{
+ struct ldb_mod_test_ctx *mod_test_ctx = \
+ talloc_get_type_abort(*state,
+ struct ldb_mod_test_ctx);
+ struct ldb_message_element *el;
+ struct ldb_result *res;
+ struct keyval kvs[] = {
+ { "cn", "test_mod_cn" },
+ { NULL, NULL },
+ };
+
+ /* cn must be gone */
+ res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
+ assert_non_null(res);
+
+ el = ldb_msg_find_element(res->msgs[0], "cn");
+ assert_null(el);
+}
int main(int argc, const char **argv)
{
@@ -412,6 +808,33 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_transactions,
ldbtest_setup,
ldbtest_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
+ ldb_modify_test_setup,
+ ldb_modify_test_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
>From a13b5e9a1bc9cc3d33505d079096ee12fe8cd6a0 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Thu, 14 May 2015 22:49:00 +0200
Subject: [PATCH 12/14] ldb:tests: unit test for ldb_search()
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 393 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 380 insertions(+), 13 deletions(-)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index 065bd60a55b..2de15838dfd 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <talloc.h>
#include <ldb.h>
+#include <string.h>
#define DEFAULT_BE "tdb"
@@ -432,22 +433,21 @@ static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
return msg;
}
-static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
+static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
+ struct ldbtest_ctx *ldb_test_ctx,
+ const char *basedn,
struct keyval *kvs)
{
TALLOC_CTX *tmp_ctx;
struct ldb_message *msg;
struct ldb_result *result = NULL;
- struct ldbtest_ctx *ldb_test_ctx;
int ret;
- ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
-
- tmp_ctx = talloc_new(mod_test_ctx);
+ tmp_ctx = talloc_new(mem_ctx);
assert_non_null(tmp_ctx);
msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
- mod_test_ctx->entry_dn, 0, kvs);
+ basedn, 0, kvs);
assert_non_null(msg);
ret = ldb_add(ldb_test_ctx->ldb, msg);
@@ -464,21 +464,20 @@ static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
talloc_free(tmp_ctx);
}
-static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
+static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
+ struct ldbtest_ctx *ldb_test_ctx,
+ const char *strdn)
{
TALLOC_CTX *tmp_ctx;
- struct ldb_dn *basedn;
struct ldb_result *result = NULL;
+ struct ldb_dn *basedn;
int ret;
- struct ldbtest_ctx *ldb_test_ctx;
-
- ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
- tmp_ctx = talloc_new(mod_test_ctx);
+ tmp_ctx = talloc_new(mem_ctx);
assert_non_null(tmp_ctx);
basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
- "%s", mod_test_ctx->entry_dn);
+ "%s", strdn);
assert_non_null(basedn);
ret = ldb_delete(ldb_test_ctx->ldb, basedn);
@@ -493,6 +492,22 @@ static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
talloc_free(tmp_ctx);
}
+static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
+ struct keyval *kvs)
+{
+ ldb_test_add_data(mod_test_ctx,
+ mod_test_ctx->ldb_test_ctx,
+ mod_test_ctx->entry_dn,
+ kvs);
+}
+
+static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
+{
+ ldb_test_remove_data(mod_test_ctx,
+ mod_test_ctx->ldb_test_ctx,
+ mod_test_ctx->entry_dn);
+}
+
static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
int modify_flags,
struct keyval *kvs)
@@ -787,6 +802,343 @@ static void test_ldb_modify_del_keyval(void **state)
assert_null(el);
}
+struct search_test_ctx {
+ struct ldbtest_ctx *ldb_test_ctx;
+ const char *base_dn;
+};
+
+static char *get_full_dn(TALLOC_CTX *mem_ctx,
+ struct search_test_ctx *search_test_ctx,
+ const char *rdn)
+{
+ char *full_dn;
+
+ full_dn = talloc_asprintf(mem_ctx,
+ "%s,%s", rdn, search_test_ctx->base_dn);
+ assert_non_null(full_dn);
+
+ return full_dn;
+}
+
+static void search_test_add_data(struct search_test_ctx *search_test_ctx,
+ const char *rdn,
+ struct keyval *kvs)
+{
+ char *full_dn;
+
+ full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
+
+ ldb_test_add_data(search_test_ctx,
+ search_test_ctx->ldb_test_ctx,
+ full_dn,
+ kvs);
+}
+
+static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
+ const char *rdn)
+{
+ char *full_dn;
+
+ full_dn = talloc_asprintf(search_test_ctx,
+ "%s,%s", rdn, search_test_ctx->base_dn);
+ assert_non_null(full_dn);
+
+ ldb_test_remove_data(search_test_ctx,
+ search_test_ctx->ldb_test_ctx,
+ full_dn);
+}
+
+static int ldb_search_test_setup(void **state)
+{
+ struct ldbtest_ctx *ldb_test_ctx;
+ struct search_test_ctx *search_test_ctx;
+ struct keyval kvs[] = {
+ { "cn", "test_search_cn" },
+ { "cn", "test_search_cn2" },
+ { "uid", "test_search_uid" },
+ { "uid", "test_search_uid2" },
+ { NULL, NULL },
+ };
+ struct keyval kvs2[] = {
+ { "cn", "test_search_2_cn" },
+ { "cn", "test_search_2_cn2" },
+ { "uid", "test_search_2_uid" },
+ { "uid", "test_search_2_uid2" },
+ { NULL, NULL },
+ };
+
+ ldbtest_setup((void **) &ldb_test_ctx);
+
+ search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
+ assert_non_null(search_test_ctx);
+
+ search_test_ctx->base_dn = "dc=search_test_entry";
+ search_test_ctx->ldb_test_ctx = ldb_test_ctx;
+
+ search_test_remove_data(search_test_ctx, "cn=test_search_cn");
+ search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
+
+ search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
+ search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
+
+ *state = search_test_ctx;
+ return 0;
+}
+
+static int ldb_search_test_teardown(void **state)
+{
+ struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
+ struct search_test_ctx);
+ struct ldbtest_ctx *ldb_test_ctx;
+
+ ldb_test_ctx = search_test_ctx->ldb_test_ctx;
+
+ search_test_remove_data(search_test_ctx, "cn=test_search_cn");
+ search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
+ ldbtest_teardown((void **) &ldb_test_ctx);
+ return 0;
+}
+
+static void assert_attr_has_vals(struct ldb_message *msg,
+ const char *attr,
+ const char *vals[],
+ const size_t nvals)
+{
+ struct ldb_message_element *el;
+ size_t i;
+
+ el = ldb_msg_find_element(msg, attr);
+ assert_non_null(el);
+
+ assert_int_equal(el->num_values, nvals);
+ for (i = 0; i < nvals; i++) {
+ assert_string_equal(el->values[i].data,
+ vals[i]);
+ }
+}
+
+static void assert_has_no_attr(struct ldb_message *msg,
+ const char *attr)
+{
+ struct ldb_message_element *el;
+
+ el = ldb_msg_find_element(msg, attr);
+ assert_null(el);
+}
+
+static bool has_dn(struct ldb_message *msg, const char *dn)
+{
+ const char *msgdn;
+
+ msgdn = ldb_dn_get_linearized(msg->dn);
+ if (strcmp(dn, msgdn) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+static void test_search_match_none(void **state)
+{
+ struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
+ struct search_test_ctx);
+ int ret;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+
+ basedn = ldb_dn_new_fmt(search_test_ctx,
+ search_test_ctx->ldb_test_ctx->ldb,
+ "%s",
+ search_test_ctx->base_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
+ search_test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_SUBTREE, NULL,
+ "dc=no_such_entry");
+ assert_int_equal(ret, 0);
+ assert_non_null(result);
+ assert_int_equal(result->count, 0);
+}
+
+static void test_search_match_one(void **state)
+{
+ struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
+ struct search_test_ctx);
+ int ret;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+ const char *cn_vals[] = { "test_search_cn",
+ "test_search_cn2" };
+ const char *uid_vals[] = { "test_search_uid",
+ "test_search_uid2" };
+
+ basedn = ldb_dn_new_fmt(search_test_ctx,
+ search_test_ctx->ldb_test_ctx->ldb,
+ "%s",
+ search_test_ctx->base_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
+ search_test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_SUBTREE, NULL,
+ "cn=test_search_cn");
+ assert_int_equal(ret, 0);
+ assert_non_null(result);
+ assert_int_equal(result->count, 1);
+
+ assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
+ assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
+}
+
+static void test_search_match_filter(void **state)
+{
+ struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
+ struct search_test_ctx);
+ int ret;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+ const char *cn_vals[] = { "test_search_cn",
+ "test_search_cn2" };
+ const char *attrs[] = { "cn", NULL };
+
+ basedn = ldb_dn_new_fmt(search_test_ctx,
+ search_test_ctx->ldb_test_ctx->ldb,
+ "%s",
+ search_test_ctx->base_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
+ search_test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_SUBTREE,
+ attrs,
+ "cn=test_search_cn");
+ assert_int_equal(ret, 0);
+ assert_non_null(result);
+ assert_int_equal(result->count, 1);
+
+ assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
+ assert_has_no_attr(result->msgs[0], "uid");
+}
+
+static void assert_expected(struct search_test_ctx *search_test_ctx,
+ struct ldb_message *msg)
+{
+ char *full_dn1;
+ char *full_dn2;
+ const char *cn_vals[] = { "test_search_cn",
+ "test_search_cn2" };
+ const char *uid_vals[] = { "test_search_uid",
+ "test_search_uid2" };
+ const char *cn2_vals[] = { "test_search_2_cn",
+ "test_search_2_cn2" };
+ const char *uid2_vals[] = { "test_search_2_uid",
+ "test_search_2_uid2" };
+
+ full_dn1 = get_full_dn(search_test_ctx,
+ search_test_ctx,
+ "cn=test_search_cn");
+
+ full_dn2 = get_full_dn(search_test_ctx,
+ search_test_ctx,
+ "cn=test_search_2_cn");
+
+ if (has_dn(msg, full_dn1) == true) {
+ assert_attr_has_vals(msg, "cn", cn_vals, 2);
+ assert_attr_has_vals(msg, "uid", uid_vals, 2);
+ } else if (has_dn(msg, full_dn2) == true) {
+ assert_attr_has_vals(msg, "cn", cn2_vals, 2);
+ assert_attr_has_vals(msg, "uid", uid2_vals, 2);
+ } else {
+ fail();
+ }
+}
+
+static void test_search_match_both(void **state)
+{
+ struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
+ struct search_test_ctx);
+ int ret;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+
+ basedn = ldb_dn_new_fmt(search_test_ctx,
+ search_test_ctx->ldb_test_ctx->ldb,
+ "%s",
+ search_test_ctx->base_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
+ search_test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_SUBTREE, NULL,
+ "cn=test_search_*");
+ assert_int_equal(ret, 0);
+ assert_non_null(result);
+ assert_int_equal(result->count, 2);
+
+ assert_expected(search_test_ctx, result->msgs[0]);
+ assert_expected(search_test_ctx, result->msgs[1]);
+}
+
+static void test_search_match_basedn(void **state)
+{
+ struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
+ struct search_test_ctx);
+ int ret;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+ struct ldb_message *msg;
+
+ basedn = ldb_dn_new_fmt(search_test_ctx,
+ search_test_ctx->ldb_test_ctx->ldb,
+ "dc=nosuchdn");
+ assert_non_null(basedn);
+
+ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
+ search_test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_SUBTREE, NULL,
+ "cn=*");
+ assert_int_equal(ret, 0);
+
+ /* Add 'checkBaseOnSearch' to @OPTIONS */
+ msg = ldb_msg_new(search_test_ctx);
+ assert_non_null(msg);
+
+ msg->dn = ldb_dn_new_fmt(msg,
+ search_test_ctx->ldb_test_ctx->ldb,
+ "@OPTIONS");
+ assert_non_null(msg->dn);
+
+ ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
+ assert_int_equal(ret, 0);
+
+ ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
+ assert_int_equal(ret, 0);
+
+ /* Search again */
+ /* The search should return LDB_ERR_NO_SUCH_OBJECT */
+ ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
+ search_test_ctx,
+ &result,
+ basedn,
+ LDB_SCOPE_SUBTREE, NULL,
+ "cn=*");
+ assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
+
+ ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
+ assert_int_equal(ret, 0);
+}
+
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
@@ -835,6 +1187,21 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
ldb_modify_test_setup,
ldb_modify_test_teardown),
+ cmocka_unit_test_setup_teardown(test_search_match_none,
+ ldb_search_test_setup,
+ ldb_search_test_teardown),
+ cmocka_unit_test_setup_teardown(test_search_match_one,
+ ldb_search_test_setup,
+ ldb_search_test_teardown),
+ cmocka_unit_test_setup_teardown(test_search_match_filter,
+ ldb_search_test_setup,
+ ldb_search_test_teardown),
+ cmocka_unit_test_setup_teardown(test_search_match_both,
+ ldb_search_test_setup,
+ ldb_search_test_teardown),
+ cmocka_unit_test_setup_teardown(test_search_match_basedn,
+ ldb_search_test_setup,
+ ldb_search_test_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
>From 873b9a3c3066e821fa578c22be89cbfa20c1a79e Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Tue, 24 Nov 2015 20:12:43 +0100
Subject: [PATCH 13/14] ldb:tests: Add tests for case insensitive searches
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 114 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index 2de15838dfd..1a0ca5299f2 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -247,6 +247,36 @@ static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
return count;
}
+static int sub_search_count(struct ldbtest_ctx *test_ctx,
+ const char *base_dn,
+ const char *filter)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *basedn;
+ struct ldb_result *result = NULL;
+ int ret;
+ int count;
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn);
+ assert_non_null(basedn);
+
+ ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
+ LDB_SCOPE_SUBTREE, NULL, "%s", filter);
+ assert_int_equal(ret, LDB_SUCCESS);
+ assert_non_null(result);
+
+ count = result->count;
+ talloc_free(tmp_ctx);
+ return count;
+}
+
+/* In general it would be better if utility test functions didn't assert
+ * but only returned a value, then assert in the test shows correct
+ * line
+ */
static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
const char *entry_dn)
{
@@ -1139,6 +1169,87 @@ static void test_search_match_basedn(void **state)
assert_int_equal(ret, 0);
}
+static int ldb_case_test_setup(void **state)
+{
+ int ret;
+ struct ldb_ldif *ldif;
+ struct ldbtest_ctx *ldb_test_ctx;
+ const char *attrs_ldif = \
+ "dn: @ATTRIBUTES\n"
+ "cn: CASE_INSENSITIVE\n"
+ "\n";
+ struct keyval kvs[] = {
+ { "cn", "CaseInsensitiveValue" },
+ { "uid", "CaseSensitiveValue" },
+ { NULL, NULL },
+ };
+
+
+ ldbtest_setup((void **) &ldb_test_ctx);
+
+ while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
+ ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
+ assert_int_equal(ret, LDB_SUCCESS);
+ }
+
+ ldb_test_add_data(ldb_test_ctx,
+ ldb_test_ctx,
+ "cn=CaseInsensitiveValue",
+ kvs);
+
+ *state = ldb_test_ctx;
+ return 0;
+}
+
+static int ldb_case_test_teardown(void **state)
+{
+ int ret;
+ struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+
+ struct ldb_dn *del_dn;
+
+ del_dn = ldb_dn_new_fmt(ldb_test_ctx,
+ ldb_test_ctx->ldb,
+ "@ATTRIBUTES");
+ assert_non_null(del_dn);
+
+ ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ assert_dn_doesnt_exist(ldb_test_ctx,
+ "@ATTRIBUTES");
+
+ ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
+ "cn=CaseInsensitiveValue");
+
+ ldbtest_teardown((void **) &ldb_test_ctx);
+ return 0;
+}
+
+static void test_ldb_attrs_case_insensitive(void **state)
+{
+ int cnt;
+ struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+
+ /* cn matches exact case */
+ cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
+ assert_int_equal(cnt, 1);
+
+ /* cn matches lower case */
+ cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
+ assert_int_equal(cnt, 1);
+
+ /* uid matches exact case */
+ cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
+ assert_int_equal(cnt, 1);
+
+ /* uid does not match lower case */
+ cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
+ assert_int_equal(cnt, 0);
+}
+
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
@@ -1202,6 +1313,9 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_search_match_basedn,
ldb_search_test_setup,
ldb_search_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
+ ldb_case_test_setup,
+ ldb_case_test_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
>From 61215f4308091ba10c9d7973c617e8b6647ca1f8 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jakub.hrozek at posteo.se>
Date: Wed, 7 Oct 2015 18:07:13 +0200
Subject: [PATCH 14/14] ldb:tests: Unit test the ldb_rename() operation
Signed-off-by: Jakub Hrozek <jakub.hrozek at posteo.se>
Reviewed-by: Andreas Schneider <asn at samba.org>
---
lib/ldb/tests/ldb_mod_op_test.c | 294 ++++++++++++++++++++++++++++++++++------
1 file changed, 256 insertions(+), 38 deletions(-)
diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c
index 1a0ca5299f2..e609d3a8492 100644
--- a/lib/ldb/tests/ldb_mod_op_test.c
+++ b/lib/ldb/tests/ldb_mod_op_test.c
@@ -23,6 +23,7 @@
#include <talloc.h>
#include <ldb.h>
#include <string.h>
+#include <ctype.h>
#define DEFAULT_BE "tdb"
@@ -295,40 +296,52 @@ static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
assert_int_equal(count, 0);
}
-static void test_ldb_del(void **state)
+static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
+ struct ldb_dn *dn,
+ const char *cn_value)
{
int ret;
- struct ldb_message *msg;
- struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ldbtest_ctx);
TALLOC_CTX *tmp_ctx;
- const char *basedn = "dc=ldb_del_test";
+ struct ldb_message *msg;
tmp_ctx = talloc_new(test_ctx);
assert_non_null(tmp_ctx);
- assert_dn_doesnt_exist(test_ctx, basedn);
+ assert_dn_doesnt_exist(test_ctx,
+ ldb_dn_get_linearized(dn));
msg = ldb_msg_new(tmp_ctx);
assert_non_null(msg);
+ msg->dn = dn;
- msg->dn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", basedn);
- assert_non_null(msg->dn);
-
- ret = ldb_msg_add_string(msg, "cn", "test_del_cn_val");
+ ret = ldb_msg_add_string(msg, "cn", cn_value);
assert_int_equal(ret, LDB_SUCCESS);
ret = ldb_add(test_ctx->ldb, msg);
assert_int_equal(ret, LDB_SUCCESS);
- assert_dn_exists(test_ctx, basedn);
+ assert_dn_exists(test_ctx,
+ ldb_dn_get_linearized(dn));
+ talloc_free(tmp_ctx);
+}
- ret = ldb_delete(test_ctx->ldb, msg->dn);
+static void test_ldb_del(void **state)
+{
+ int ret;
+ struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct ldbtest_ctx);
+ const char *basedn = "dc=ldb_del_test";
+ struct ldb_dn *dn;
+
+ dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
+ assert_non_null(dn);
+
+ add_dn_with_cn(test_ctx, dn, "test_del_cn_val");
+
+ ret = ldb_delete(test_ctx->ldb, dn);
assert_int_equal(ret, LDB_SUCCESS);
assert_dn_doesnt_exist(test_ctx, basedn);
-
- talloc_free(tmp_ctx);
}
static void test_ldb_del_noexist(void **state)
@@ -499,9 +512,9 @@ static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
const char *strdn)
{
TALLOC_CTX *tmp_ctx;
- struct ldb_result *result = NULL;
struct ldb_dn *basedn;
int ret;
+ size_t count;
tmp_ctx = talloc_new(mem_ctx);
assert_non_null(tmp_ctx);
@@ -513,11 +526,8 @@ static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
ret = ldb_delete(ldb_test_ctx->ldb, basedn);
assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
- ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, basedn,
- LDB_SCOPE_BASE, NULL, NULL);
- assert_int_equal(ret, LDB_SUCCESS);
- assert_non_null(result);
- assert_int_equal(result->count, 0);
+ count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
+ assert_int_equal(count, 0);
talloc_free(tmp_ctx);
}
@@ -972,25 +982,11 @@ static void test_search_match_none(void **state)
{
struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
struct search_test_ctx);
- int ret;
- struct ldb_dn *basedn;
- struct ldb_result *result = NULL;
+ size_t count;
- basedn = ldb_dn_new_fmt(search_test_ctx,
- search_test_ctx->ldb_test_ctx->ldb,
- "%s",
- search_test_ctx->base_dn);
- assert_non_null(basedn);
-
- ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
- search_test_ctx,
- &result,
- basedn,
- LDB_SCOPE_SUBTREE, NULL,
- "dc=no_such_entry");
- assert_int_equal(ret, 0);
- assert_non_null(result);
- assert_int_equal(result->count, 0);
+ count = base_search_count(search_test_ctx->ldb_test_ctx,
+ "dc=no_such_entry");
+ assert_int_equal(count, 0);
}
static void test_search_match_one(void **state)
@@ -1227,6 +1223,69 @@ static int ldb_case_test_teardown(void **state)
return 0;
}
+struct rename_test_ctx {
+ struct ldbtest_ctx *ldb_test_ctx;
+
+ struct ldb_dn *basedn;
+ const char *str_basedn;
+
+ const char *teardown_dn;
+};
+
+static int ldb_rename_test_setup(void **state)
+{
+ struct ldbtest_ctx *ldb_test_ctx;
+ struct rename_test_ctx *rename_test_ctx;
+ const char *strdn = "dc=rename_test_entry_from";
+
+ ldbtest_setup((void **) &ldb_test_ctx);
+
+ rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
+ assert_non_null(rename_test_ctx);
+ rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
+ assert_non_null(rename_test_ctx->ldb_test_ctx);
+
+ rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
+ rename_test_ctx->ldb_test_ctx->ldb,
+ "%s", strdn);
+ assert_non_null(rename_test_ctx->basedn);
+
+ rename_test_ctx->str_basedn = strdn;
+ rename_test_ctx->teardown_dn = strdn;
+
+ add_dn_with_cn(ldb_test_ctx,
+ rename_test_ctx->basedn,
+ "test_rename_cn_val");
+
+ *state = rename_test_ctx;
+ return 0;
+}
+
+static int ldb_rename_test_teardown(void **state)
+{
+ int ret;
+ struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
+ struct rename_test_ctx);
+ struct ldbtest_ctx *ldb_test_ctx;
+ struct ldb_dn *del_dn;
+
+ ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
+
+ del_dn = ldb_dn_new_fmt(rename_test_ctx,
+ rename_test_ctx->ldb_test_ctx->ldb,
+ "%s", rename_test_ctx->teardown_dn);
+ assert_non_null(del_dn);
+
+ ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ assert_dn_doesnt_exist(ldb_test_ctx,
+ rename_test_ctx->teardown_dn);
+
+ ldbtest_teardown((void **) &ldb_test_ctx);
+ return 0;
+}
+
static void test_ldb_attrs_case_insensitive(void **state)
{
int cnt;
@@ -1250,6 +1309,150 @@ static void test_ldb_attrs_case_insensitive(void **state)
assert_int_equal(cnt, 0);
}
+static void test_ldb_rename(void **state)
+{
+ struct rename_test_ctx *rename_test_ctx =
+ talloc_get_type_abort(*state, struct rename_test_ctx);
+ int ret;
+ const char *str_new_dn = "dc=rename_test_entry_to";
+ struct ldb_dn *new_dn;
+
+ new_dn = ldb_dn_new_fmt(rename_test_ctx,
+ rename_test_ctx->ldb_test_ctx->ldb,
+ "%s", str_new_dn);
+ assert_non_null(new_dn);
+
+ ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
+ rename_test_ctx->basedn,
+ new_dn);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
+ assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
+ rename_test_ctx->str_basedn);
+ rename_test_ctx->teardown_dn = str_new_dn;
+
+ /* FIXME - test the values which didn't change */
+}
+
+static void test_ldb_rename_from_doesnt_exist(void **state)
+{
+ struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
+ *state,
+ struct rename_test_ctx);
+ int ret;
+ const char *str_new_dn = "dc=rename_test_entry_to";
+ const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
+ struct ldb_dn *new_dn;
+ struct ldb_dn *bad_old_dn;
+
+ new_dn = ldb_dn_new_fmt(rename_test_ctx,
+ rename_test_ctx->ldb_test_ctx->ldb,
+ "%s", str_new_dn);
+ assert_non_null(new_dn);
+
+ bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
+ rename_test_ctx->ldb_test_ctx->ldb,
+ "%s", str_bad_old_dn);
+ assert_non_null(bad_old_dn);
+
+ assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
+ str_bad_old_dn);
+
+ ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
+ bad_old_dn, new_dn);
+ assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
+
+ assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
+ str_new_dn);
+}
+
+static void test_ldb_rename_to_exists(void **state)
+{
+ struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
+ *state,
+ struct rename_test_ctx);
+ int ret;
+ const char *str_new_dn = "dc=rename_test_already_exists";
+ struct ldb_dn *new_dn;
+
+ new_dn = ldb_dn_new_fmt(rename_test_ctx,
+ rename_test_ctx->ldb_test_ctx->ldb,
+ "%s", str_new_dn);
+ assert_non_null(new_dn);
+
+ add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
+ new_dn,
+ "test_rename_cn_val");
+
+ ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
+ rename_test_ctx->basedn,
+ new_dn);
+ assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
+
+ /* Old object must still exist */
+ assert_dn_exists(rename_test_ctx->ldb_test_ctx,
+ rename_test_ctx->str_basedn);
+
+ ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
+ new_dn);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ assert_dn_exists(rename_test_ctx->ldb_test_ctx,
+ rename_test_ctx->teardown_dn);
+}
+
+static void test_ldb_rename_self(void **state)
+{
+ struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
+ *state,
+ struct rename_test_ctx);
+ int ret;
+
+ /* Oddly enough, this is a success in ldb.. */
+ ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
+ rename_test_ctx->basedn,
+ rename_test_ctx->basedn);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ /* Old object must still exist */
+ assert_dn_exists(rename_test_ctx->ldb_test_ctx,
+ rename_test_ctx->str_basedn);
+}
+
+static void test_ldb_rename_dn_case_change(void **state)
+{
+ struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
+ *state,
+ struct rename_test_ctx);
+ int ret;
+ char *str_new_dn;
+ struct ldb_dn *new_dn;
+ unsigned i;
+
+ str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
+ assert_non_null(str_new_dn);
+ for (i = 0; str_new_dn[i]; i++) {
+ str_new_dn[i] = toupper(str_new_dn[i]);
+ }
+
+ new_dn = ldb_dn_new_fmt(rename_test_ctx,
+ rename_test_ctx->ldb_test_ctx->ldb,
+ "%s", str_new_dn);
+ assert_non_null(new_dn);
+
+ ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
+ rename_test_ctx->basedn,
+ new_dn);
+ assert_int_equal(ret, LDB_SUCCESS);
+
+ /* DNs are case insensitive, so both searches will match */
+ assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
+ assert_dn_exists(rename_test_ctx->ldb_test_ctx,
+ rename_test_ctx->str_basedn);
+ /* FIXME - test the values didn't change */
+}
+
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
@@ -1316,6 +1519,21 @@ int main(int argc, const char **argv)
cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
ldb_case_test_setup,
ldb_case_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_rename,
+ ldb_rename_test_setup,
+ ldb_rename_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
+ ldb_rename_test_setup,
+ ldb_rename_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
+ ldb_rename_test_setup,
+ ldb_rename_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_rename_self,
+ ldb_rename_test_setup,
+ ldb_rename_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
+ ldb_rename_test_setup,
+ ldb_rename_test_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
--
2.12.2
More information about the samba-technical
mailing list