ctdb-scripts: Move nfslock out of basic_stop() and basic_start()
[samba.git] / lib / ldb / tests / ldb_lmdb_test.c
blob798a1916281f05c4209fbbacd4258c2b7a0234be
1 /*
2 * lmdb backend specific tests for ldb
4 * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * lmdb backend specific tests for ldb
24 * Setup and tear down code copied from ldb_mod_op_test.c
28 * from cmocka.c:
29 * These headers or their equivalents should be included prior to
30 * including
31 * this header file.
33 * #include <stdarg.h>
34 * #include <stddef.h>
35 * #include <setjmp.h>
37 * This allows test applications to use custom definitions of C standard
38 * library functions and types.
41 #include <stdarg.h>
42 #include <stddef.h>
43 #include <stdint.h>
44 #include <setjmp.h>
45 #include <cmocka.h>
47 #include <errno.h>
48 #include <unistd.h>
49 #include <talloc.h>
50 #include <tevent.h>
51 #include <ldb.h>
52 #include <ldb_module.h>
53 #include <ldb_private.h>
54 #include <string.h>
55 #include <ctype.h>
57 #include <sys/wait.h>
59 #include "../ldb_tdb/ldb_tdb.h"
60 #include "../ldb_mdb/ldb_mdb.h"
61 #include "../ldb_key_value/ldb_kv.h"
63 #define TEST_BE "mdb"
65 #define LMDB_MAX_KEY_SIZE 511
67 struct ldbtest_ctx {
68 struct tevent_context *ev;
69 struct ldb_context *ldb;
71 const char *dbfile;
72 const char *lockfile; /* lockfile is separate */
74 const char *dbpath;
77 static void unlink_old_db(struct ldbtest_ctx *test_ctx)
79 int ret;
81 errno = 0;
82 ret = unlink(test_ctx->lockfile);
83 if (ret == -1 && errno != ENOENT) {
84 fail();
87 errno = 0;
88 ret = unlink(test_ctx->dbfile);
89 if (ret == -1 && errno != ENOENT) {
90 fail();
94 static int ldbtest_noconn_setup(void **state)
96 struct ldbtest_ctx *test_ctx;
98 test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
99 assert_non_null(test_ctx);
101 test_ctx->ev = tevent_context_init(test_ctx);
102 assert_non_null(test_ctx->ev);
104 test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
105 assert_non_null(test_ctx->ldb);
107 test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
108 assert_non_null(test_ctx->dbfile);
110 test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
111 test_ctx->dbfile);
112 assert_non_null(test_ctx->lockfile);
114 test_ctx->dbpath = talloc_asprintf(test_ctx,
115 TEST_BE"://%s", test_ctx->dbfile);
116 assert_non_null(test_ctx->dbpath);
118 unlink_old_db(test_ctx);
119 *state = test_ctx;
120 return 0;
123 static int ldbtest_noconn_teardown(void **state)
125 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
126 struct ldbtest_ctx);
128 unlink_old_db(test_ctx);
129 talloc_free(test_ctx);
130 return 0;
133 static int ldbtest_setup(void **state)
135 struct ldbtest_ctx *test_ctx;
136 int ret;
137 struct ldb_ldif *ldif;
138 const char *index_ldif = \
139 "dn: @INDEXLIST\n"
140 "@IDXGUID: objectUUID\n"
141 "@IDX_DN_GUID: GUID\n"
142 "\n";
144 ldbtest_noconn_setup((void **) &test_ctx);
146 ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
147 assert_int_equal(ret, 0);
149 while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
150 ret = ldb_add(test_ctx->ldb, ldif->msg);
151 assert_int_equal(ret, LDB_SUCCESS);
153 *state = test_ctx;
154 return 0;
157 static int ldbtest_teardown(void **state)
159 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
160 struct ldbtest_ctx);
161 ldbtest_noconn_teardown((void **) &test_ctx);
162 return 0;
165 static void test_ldb_add_key_len_gt_max(void **state)
167 int ret;
168 int xs_size = 0;
169 struct ldb_message *msg;
170 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
171 struct ldbtest_ctx);
172 char *xs = NULL;
173 TALLOC_CTX *tmp_ctx;
175 tmp_ctx = talloc_new(test_ctx);
176 assert_non_null(tmp_ctx);
178 msg = ldb_msg_new(tmp_ctx);
179 assert_non_null(msg);
182 * The zero terminator is part of the key if we were not in
183 * GUID mode
186 xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */
187 xs_size += 1; /* want key on char too long */
188 xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
189 memset(xs, 'x', xs_size);
191 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
192 assert_non_null(msg->dn);
194 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
195 assert_int_equal(ret, 0);
197 ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
198 assert_int_equal(ret, 0);
200 ret = ldb_add(test_ctx->ldb, msg);
201 assert_int_equal(ret, LDB_SUCCESS);
203 talloc_free(tmp_ctx);
206 static void test_ldb_add_key_len_2x_gt_max(void **state)
208 int ret;
209 int xs_size = 0;
210 struct ldb_message *msg;
211 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
212 struct ldbtest_ctx);
213 char *xs = NULL;
214 TALLOC_CTX *tmp_ctx;
216 tmp_ctx = talloc_new(test_ctx);
217 assert_non_null(tmp_ctx);
219 msg = ldb_msg_new(tmp_ctx);
220 assert_non_null(msg);
223 * The zero terminator is part of the key if we were not in
224 * GUID mode
227 xs_size = 2 * LMDB_MAX_KEY_SIZE;
228 xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
229 memset(xs, 'x', xs_size);
231 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
232 assert_non_null(msg->dn);
234 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
235 assert_int_equal(ret, 0);
237 ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
238 assert_int_equal(ret, 0);
240 ret = ldb_add(test_ctx->ldb, msg);
241 assert_int_equal(ret, LDB_SUCCESS);
243 talloc_free(tmp_ctx);
246 static void test_ldb_add_key_len_eq_max(void **state)
248 int ret;
249 int xs_size = 0;
250 struct ldb_message *msg;
251 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
252 struct ldbtest_ctx);
253 char *xs = NULL;
254 TALLOC_CTX *tmp_ctx;
256 tmp_ctx = talloc_new(test_ctx);
257 assert_non_null(tmp_ctx);
259 msg = ldb_msg_new(tmp_ctx);
260 assert_non_null(msg);
263 * The zero terminator is part of the key if we were not in
264 * GUID mode
267 xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */
268 xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
269 memset(xs, 'x', xs_size);
271 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
272 assert_non_null(msg->dn);
274 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
275 assert_int_equal(ret, 0);
277 ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
278 assert_int_equal(ret, 0);
280 ret = ldb_add(test_ctx->ldb, msg);
281 assert_int_equal(ret, 0);
283 talloc_free(tmp_ctx);
286 static int ldbtest_setup_noguid(void **state)
288 struct ldbtest_ctx *test_ctx;
289 int ret;
291 ldbtest_noconn_setup((void **) &test_ctx);
293 ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
294 assert_int_equal(ret, 0);
296 *state = test_ctx;
297 return 0;
300 static void test_ldb_add_special_key_len_gt_max(void **state)
302 int ret;
303 int xs_size = 0;
304 struct ldb_message *msg;
305 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
306 struct ldbtest_ctx);
307 char *xs = NULL;
308 TALLOC_CTX *tmp_ctx;
310 tmp_ctx = talloc_new(test_ctx);
311 assert_non_null(tmp_ctx);
313 msg = ldb_msg_new(tmp_ctx);
314 assert_non_null(msg);
317 * The zero terminator is part of the key if we were not in
318 * GUID mode
321 xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */
322 xs_size += 1; /* want key on char too long */
323 xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
324 memset(xs, 'x', xs_size);
326 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs);
327 assert_non_null(msg->dn);
329 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
330 assert_int_equal(ret, 0);
332 ret = ldb_add(test_ctx->ldb, msg);
333 assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
335 talloc_free(tmp_ctx);
338 static void test_ldb_add_special_key_len_eq_max(void **state)
340 int ret;
341 int xs_size = 0;
342 struct ldb_message *msg;
343 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
344 struct ldbtest_ctx);
345 char *xs = NULL;
346 TALLOC_CTX *tmp_ctx;
348 tmp_ctx = talloc_new(test_ctx);
349 assert_non_null(tmp_ctx);
351 msg = ldb_msg_new(tmp_ctx);
352 assert_non_null(msg);
355 * The zero terminator is part of the key if we were not in
356 * GUID mode
359 xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */
360 xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
361 memset(xs, 'x', xs_size);
363 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs);
364 assert_non_null(msg->dn);
366 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
367 assert_int_equal(ret, 0);
369 ret = ldb_add(test_ctx->ldb, msg);
370 assert_int_equal(ret, LDB_SUCCESS);
372 talloc_free(tmp_ctx);
375 static void test_ldb_add_dn_no_guid_mode(void **state)
377 int ret;
378 int xs_size = 0;
379 struct ldb_message *msg;
380 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
381 struct ldbtest_ctx);
382 char *xs = NULL;
383 TALLOC_CTX *tmp_ctx;
385 tmp_ctx = talloc_new(test_ctx);
386 assert_non_null(tmp_ctx);
388 msg = ldb_msg_new(tmp_ctx);
389 assert_non_null(msg);
392 * The zero terminator is part of the key if we were not in
393 * GUID mode
396 xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */
397 xs_size += 1; /* want key on char too long */
398 xs = talloc_zero_size(tmp_ctx, (xs_size + 1));
399 memset(xs, 'x', xs_size);
401 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs);
402 assert_non_null(msg->dn);
404 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
405 assert_int_equal(ret, 0);
407 ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
408 assert_int_equal(ret, 0);
410 ret = ldb_add(test_ctx->ldb, msg);
411 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
413 talloc_free(tmp_ctx);
416 static struct MDB_env *get_mdb_env(struct ldb_context *ldb)
418 void *data = NULL;
419 struct ldb_kv_private *ldb_kv = NULL;
420 struct lmdb_private *lmdb = NULL;
421 struct MDB_env *env = NULL;
423 data = ldb_module_get_private(ldb->modules);
424 assert_non_null(data);
426 ldb_kv = talloc_get_type(data, struct ldb_kv_private);
427 assert_non_null(ldb_kv);
429 lmdb = ldb_kv->lmdb_private;
430 assert_non_null(lmdb);
432 env = lmdb->env;
433 assert_non_null(env);
435 return env;
438 static void test_multiple_opens(void **state)
440 struct ldb_context *ldb1 = NULL;
441 struct ldb_context *ldb2 = NULL;
442 struct ldb_context *ldb3 = NULL;
443 struct MDB_env *env1 = NULL;
444 struct MDB_env *env2 = NULL;
445 struct MDB_env *env3 = NULL;
446 int ret;
447 struct ldbtest_ctx *test_ctx = NULL;
449 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
452 * Open the database again
454 ldb1 = ldb_init(test_ctx, test_ctx->ev);
455 ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
456 assert_int_equal(ret, 0);
458 ldb2 = ldb_init(test_ctx, test_ctx->ev);
459 ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
460 assert_int_equal(ret, 0);
462 ldb3 = ldb_init(test_ctx, test_ctx->ev);
463 ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
464 assert_int_equal(ret, 0);
466 * We now have 3 ldb's open pointing to the same on disk database
467 * they should all share the same MDB_env
469 env1 = get_mdb_env(ldb1);
470 env2 = get_mdb_env(ldb2);
471 env3 = get_mdb_env(ldb3);
473 assert_ptr_equal(env1, env2);
474 assert_ptr_equal(env1, env3);
477 static void test_multiple_opens_across_fork(void **state)
479 struct ldb_context *ldb1 = NULL;
480 struct ldb_context *ldb2 = NULL;
481 struct MDB_env *env1 = NULL;
482 struct MDB_env *env2 = NULL;
483 int ret;
484 struct ldbtest_ctx *test_ctx = NULL;
485 int pipes[2];
486 char buf[2];
487 int wstatus;
488 pid_t pid, child_pid;
490 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
493 * Open the database again
495 ldb1 = ldb_init(test_ctx, test_ctx->ev);
496 ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
497 assert_int_equal(ret, 0);
499 ldb2 = ldb_init(test_ctx, test_ctx->ev);
500 ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
501 assert_int_equal(ret, 0);
503 env1 = get_mdb_env(ldb1);
504 env2 = get_mdb_env(ldb2);
506 ret = pipe(pipes);
507 assert_int_equal(ret, 0);
509 child_pid = fork();
510 if (child_pid == 0) {
511 struct ldb_context *ldb3 = NULL;
512 struct MDB_env *env3 = NULL;
514 close(pipes[0]);
515 ldb3 = ldb_init(test_ctx, test_ctx->ev);
516 ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
517 if (ret != 0) {
518 print_error(__location__": ldb_connect returned (%d)\n",
519 ret);
520 exit(ret);
522 env3 = get_mdb_env(ldb3);
523 if (env1 != env2) {
524 print_error(__location__": env1 != env2\n");
525 exit(LDB_ERR_OPERATIONS_ERROR);
527 if (env1 == env3) {
528 print_error(__location__": env1 == env3\n");
529 exit(LDB_ERR_OPERATIONS_ERROR);
531 ret = write(pipes[1], "GO", 2);
532 if (ret != 2) {
533 print_error(__location__
534 " write returned (%d)",
535 ret);
536 exit(LDB_ERR_OPERATIONS_ERROR);
538 exit(LDB_SUCCESS);
540 close(pipes[1]);
541 ret = read(pipes[0], buf, 2);
542 assert_int_equal(ret, 2);
544 pid = waitpid(child_pid, &wstatus, 0);
545 assert_int_equal(pid, child_pid);
547 assert_true(WIFEXITED(wstatus));
549 assert_int_equal(WEXITSTATUS(wstatus), 0);
552 int main(int argc, const char **argv)
554 const struct CMUnitTest tests[] = {
555 cmocka_unit_test_setup_teardown(
556 test_ldb_add_key_len_eq_max,
557 ldbtest_setup,
558 ldbtest_teardown),
559 cmocka_unit_test_setup_teardown(
560 test_ldb_add_key_len_gt_max,
561 ldbtest_setup,
562 ldbtest_teardown),
563 cmocka_unit_test_setup_teardown(
564 test_ldb_add_key_len_2x_gt_max,
565 ldbtest_setup,
566 ldbtest_teardown),
567 cmocka_unit_test_setup_teardown(
568 test_ldb_add_special_key_len_eq_max,
569 ldbtest_setup_noguid,
570 ldbtest_teardown),
571 cmocka_unit_test_setup_teardown(
572 test_ldb_add_special_key_len_gt_max,
573 ldbtest_setup_noguid,
574 ldbtest_teardown),
575 cmocka_unit_test_setup_teardown(
576 test_ldb_add_dn_no_guid_mode,
577 ldbtest_setup_noguid,
578 ldbtest_teardown),
579 cmocka_unit_test_setup_teardown(
580 test_multiple_opens,
581 ldbtest_setup,
582 ldbtest_teardown),
583 cmocka_unit_test_setup_teardown(
584 test_multiple_opens_across_fork,
585 ldbtest_setup,
586 ldbtest_teardown),
589 return cmocka_run_group_tests(tests, NULL, NULL);