1 /*
2  * Tests exercising the ldb key value operations.
3  *
4  *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
5  *
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.
10  *
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.
15  *
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/>.
18  *
19  */
20 
21 /*
22  * from cmocka.c:
23  * These headers or their equivalents should be included prior to
24  * including
25  * this header file.
26  *
27  * #include <stdarg.h>
28  * #include <stddef.h>
29  * #include <setjmp.h>
30  *
31  * This allows test applications to use custom definitions of C standard
32  * library functions and types.
33  *
34  */
35 
36 /*
37  * A KV module is expected to have the following behaviour
38  *
39  * - A transaction must be open to perform any read, write or delete operation
40  * - Writes and Deletes should not be visible until a transaction is commited
41  * - Nested transactions are not permitted
42  * - transactions can be rolled back and commited.
43  * - supports iteration over all records in the database
44  * - supports the update_in_iterate operation allowing entries to be
45  *   re-keyed.
46  * - has a get_size implementation that returns an estimate of the number of
47  *   records in the database.  Note that this can be an estimate rather than
48  *   an accurate size.
49  */
50 #include <stdarg.h>
51 #include <stddef.h>
52 #include <stdint.h>
53 #include <setjmp.h>
54 #include <cmocka.h>
55 
56 #include <errno.h>
57 #include <unistd.h>
58 #include <talloc.h>
59 #include <tevent.h>
60 #include <ldb.h>
61 #include <ldb_module.h>
62 #include <ldb_private.h>
63 #include <string.h>
64 #include <ctype.h>
65 
66 #include <sys/wait.h>
67 
68 #include "ldb_tdb/ldb_tdb.h"
69 #include "ldb_key_value/ldb_kv.h"
70 
71 
72 #define DEFAULT_BE  "tdb"
73 
74 #ifndef TEST_BE
75 #define TEST_BE DEFAULT_BE
76 #endif /* TEST_BE */
77 
78 #define NUM_RECS 1024
79 
80 
81 struct test_ctx {
82 	struct tevent_context *ev;
83 	struct ldb_context *ldb;
84 
85 	const char *dbfile;
86 	const char *lockfile;   /* lockfile is separate */
87 
88 	const char *dbpath;
89 };
90 
unlink_old_db(struct test_ctx * test_ctx)91 static void unlink_old_db(struct test_ctx *test_ctx)
92 {
93 	int ret;
94 
95 	errno = 0;
96 	ret = unlink(test_ctx->lockfile);
97 	if (ret == -1 && errno != ENOENT) {
98 		fail();
99 	}
100 
101 	errno = 0;
102 	ret = unlink(test_ctx->dbfile);
103 	if (ret == -1 && errno != ENOENT) {
104 		fail();
105 	}
106 }
107 
noconn_setup(void ** state)108 static int noconn_setup(void **state)
109 {
110 	struct test_ctx *test_ctx;
111 
112 	test_ctx = talloc_zero(NULL, struct test_ctx);
113 	assert_non_null(test_ctx);
114 
115 	test_ctx->ev = tevent_context_init(test_ctx);
116 	assert_non_null(test_ctx->ev);
117 
118 	test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
119 	assert_non_null(test_ctx->ldb);
120 
121 	test_ctx->dbfile = talloc_strdup(test_ctx, "kvopstest.ldb");
122 	assert_non_null(test_ctx->dbfile);
123 
124 	test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
125 					     test_ctx->dbfile);
126 	assert_non_null(test_ctx->lockfile);
127 
128 	test_ctx->dbpath = talloc_asprintf(test_ctx,
129 			TEST_BE"://%s", test_ctx->dbfile);
130 	assert_non_null(test_ctx->dbpath);
131 
132 	unlink_old_db(test_ctx);
133 	*state = test_ctx;
134 	return 0;
135 }
136 
noconn_teardown(void ** state)137 static int noconn_teardown(void **state)
138 {
139 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
140 							  struct test_ctx);
141 
142 	unlink_old_db(test_ctx);
143 	talloc_free(test_ctx);
144 	return 0;
145 }
146 
setup(void ** state)147 static int setup(void **state)
148 {
149 	struct test_ctx *test_ctx;
150 	int ret;
151 	struct ldb_ldif *ldif;
152 	const char *index_ldif =		\
153 		"dn: @INDEXLIST\n"
154 		"@IDXGUID: objectUUID\n"
155 		"@IDX_DN_GUID: GUID\n"
156 		"\n";
157 
158 	noconn_setup((void **) &test_ctx);
159 
160 	ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
161 	assert_int_equal(ret, 0);
162 
163 	while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
164 		ret = ldb_add(test_ctx->ldb, ldif->msg);
165 		assert_int_equal(ret, LDB_SUCCESS);
166 	}
167 	*state = test_ctx;
168 	return 0;
169 }
170 
teardown(void ** state)171 static int teardown(void **state)
172 {
173 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
174 							  struct test_ctx);
175 	noconn_teardown((void **) &test_ctx);
176 	return 0;
177 }
178 
get_ldb_kv(struct ldb_context * ldb)179 static struct ldb_kv_private *get_ldb_kv(struct ldb_context *ldb)
180 {
181 	void *data = NULL;
182 	struct ldb_kv_private *ldb_kv = NULL;
183 
184 	data = ldb_module_get_private(ldb->modules);
185 	assert_non_null(data);
186 
187 	ldb_kv = talloc_get_type(data, struct ldb_kv_private);
188 	assert_non_null(ldb_kv);
189 
190 	return ldb_kv;
191 }
192 
parse(struct ldb_val key,struct ldb_val data,void * private_data)193 static int parse(struct ldb_val key,
194 		 struct ldb_val data,
195 		 void *private_data)
196 {
197 	struct ldb_val* read = private_data;
198 
199 	/* Yes, we leak this.  That is OK */
200 	read->data = talloc_size(NULL,
201 				 data.length);
202 	assert_non_null(read->data);
203 
204 	memcpy(read->data, data.data, data.length);
205 	read->length = data.length;
206 	return LDB_SUCCESS;
207 }
208 
209 /*
210  * Parse function that just returns the int we pass it.
211  */
parse_return(struct ldb_val key,struct ldb_val data,void * private_data)212 static int parse_return(struct ldb_val key,
213 		        struct ldb_val data,
214 		        void *private_data)
215 {
216 	int *rcode = private_data;
217 	return *rcode;
218 }
219 
220 /*
221  * Test that data can be written to the kv store and be read back.
222  */
test_add_get(void ** state)223 static void test_add_get(void **state)
224 {
225 	int ret;
226 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
227 							  struct test_ctx);
228 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
229 	uint8_t key_val[] = "TheKey";
230 	struct ldb_val key = {
231 		.data   = key_val,
232 		.length = sizeof(key_val)
233 	};
234 
235 	uint8_t value[] = "The record contents";
236 	struct ldb_val data = {
237 		.data    = value,
238 		.length = sizeof(value)
239 	};
240 
241 	struct ldb_val read;
242 	int rcode;
243 
244 	int flags = 0;
245 	TALLOC_CTX *tmp_ctx;
246 
247 	tmp_ctx = talloc_new(test_ctx);
248 	assert_non_null(tmp_ctx);
249 
250 	/*
251 	 * Begin a transaction
252 	 */
253 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
254 	assert_int_equal(ret, 0);
255 
256 	/*
257 	 * Write the record
258 	 */
259 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
260 	assert_int_equal(ret, 0);
261 
262 	/*
263 	 * Commit the transaction
264 	 */
265 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
266 	assert_int_equal(ret, 0);
267 
268 	/*
269 	 * And now read it back
270 	 */
271 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
272 	assert_int_equal(ret, 0);
273 
274 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
275 	assert_int_equal(ret, 0);
276 
277 	assert_int_equal(sizeof(value), read.length);
278 	assert_memory_equal(value, read.data, sizeof(value));
279 
280 	/*
281 	 * Now check that the error code we return in the
282 	 * parse function is returned by fetch_and_parse.
283 	 */
284 	for (rcode=0; rcode<50; rcode++) {
285 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key,
286 						      parse_return,
287 						      &rcode);
288 		assert_int_equal(ret, rcode);
289 	}
290 
291 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
292 	assert_int_equal(ret, 0);
293 	talloc_free(tmp_ctx);
294 }
295 
296 /*
297  * Test that attempts to read data without a read transaction fail.
298  */
test_read_outside_transaction(void ** state)299 static void test_read_outside_transaction(void **state)
300 {
301 	int ret;
302 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
303 							  struct test_ctx);
304 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
305 	uint8_t key_val[] = "TheKey";
306 	struct ldb_val key = {
307 		.data   = key_val,
308 		.length = sizeof(key_val)
309 	};
310 
311 	uint8_t value[] = "The record contents";
312 	struct ldb_val data = {
313 		.data    = value,
314 		.length = sizeof(value)
315 	};
316 
317 	struct ldb_val read;
318 
319 	int flags = 0;
320 	TALLOC_CTX *tmp_ctx;
321 
322 	tmp_ctx = talloc_new(test_ctx);
323 	assert_non_null(tmp_ctx);
324 
325 	/*
326 	 * Begin a transaction
327 	 */
328 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
329 	assert_int_equal(ret, 0);
330 
331 	/*
332 	 * Write the record
333 	 */
334 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
335 	assert_int_equal(ret, 0);
336 
337 	/*
338 	 * Commit the transaction
339 	 */
340 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
341 	assert_int_equal(ret, 0);
342 
343 	/*
344 	 * And now read it back
345 	 * Note there is no read transaction active
346 	 */
347 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
348 	assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
349 
350 	talloc_free(tmp_ctx);
351 }
352 
353 /*
354  * Test that data can be deleted from the kv store
355  */
test_delete(void ** state)356 static void test_delete(void **state)
357 {
358 	int ret;
359 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
360 							  struct test_ctx);
361 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
362 	uint8_t key_val[] = "TheKey";
363 	struct ldb_val key = {
364 		.data   = key_val,
365 		.length = sizeof(key_val)
366 	};
367 
368 	uint8_t value[] = "The record contents";
369 	struct ldb_val data = {
370 		.data    = value,
371 		.length = sizeof(value)
372 	};
373 
374 	struct ldb_val read;
375 
376 	int flags = 0;
377 	TALLOC_CTX *tmp_ctx;
378 
379 	tmp_ctx = talloc_new(test_ctx);
380 	assert_non_null(tmp_ctx);
381 
382 	/*
383 	 * Begin a transaction
384 	 */
385 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
386 	assert_int_equal(ret, 0);
387 
388 	/*
389 	 * Write the record
390 	 */
391 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
392 	assert_int_equal(ret, 0);
393 
394 	/*
395 	 * Commit the transaction
396 	 */
397 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
398 	assert_int_equal(ret, 0);
399 
400 	/*
401 	 * And now read it back
402 	 */
403 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
404 	assert_int_equal(ret, 0);
405 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
406 	assert_int_equal(ret, 0);
407 	assert_int_equal(sizeof(value), read.length);
408 	assert_memory_equal(value, read.data, sizeof(value));
409 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
410 	assert_int_equal(ret, 0);
411 
412 	/*
413 	 * Begin a transaction
414 	 */
415 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
416 	assert_int_equal(ret, 0);
417 
418 	/*
419 	 * Now delete it.
420 	 */
421 	ret = ldb_kv->kv_ops->delete (ldb_kv, key);
422 	assert_int_equal(ret, 0);
423 
424 	/*
425 	 * Commit the transaction
426 	 */
427 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
428 	assert_int_equal(ret, 0);
429 
430 	/*
431 	 * And now try to read it back
432 	 */
433 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
434 	assert_int_equal(ret, 0);
435 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
436 	assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
437 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
438 	assert_int_equal(ret, 0);
439 
440 	talloc_free(tmp_ctx);
441 }
442 
443 /*
444  * Check that writes are correctly rolled back when a transaction
445  * is rolled back.
446  */
test_transaction_abort_write(void ** state)447 static void test_transaction_abort_write(void **state)
448 {
449 	int ret;
450 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
451 							  struct test_ctx);
452 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
453 	uint8_t key_val[] = "TheKey";
454 	struct ldb_val key = {
455 		.data   = key_val,
456 		.length = sizeof(key_val)
457 	};
458 
459 	uint8_t value[] = "The record contents";
460 	struct ldb_val data = {
461 		.data    = value,
462 		.length = sizeof(value)
463 	};
464 
465 	struct ldb_val read;
466 
467 	int flags = 0;
468 	TALLOC_CTX *tmp_ctx;
469 
470 	tmp_ctx = talloc_new(test_ctx);
471 	assert_non_null(tmp_ctx);
472 
473 	/*
474 	 * Begin a transaction
475 	 */
476 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
477 	assert_int_equal(ret, 0);
478 
479 	/*
480 	 * Write the record
481 	 */
482 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
483 	assert_int_equal(ret, 0);
484 
485 	/*
486 	 * And now read it back
487 	 */
488 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
489 	assert_int_equal(ret, 0);
490 	assert_int_equal(sizeof(value), read.length);
491 	assert_memory_equal(value, read.data, sizeof(value));
492 
493 
494 	/*
495 	 * Now abort the transaction
496 	 */
497 	ret = ldb_kv->kv_ops->abort_write(ldb_kv);
498 	assert_int_equal(ret, 0);
499 
500 	/*
501 	 * And now read it back, should not be there
502 	 */
503 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
504 	assert_int_equal(ret, 0);
505 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
506 	assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
507 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
508 	assert_int_equal(ret, 0);
509 
510 	talloc_free(tmp_ctx);
511 }
512 
513 /*
514  * Check that deletes are correctly rolled back when a transaction is
515  * aborted.
516  */
test_transaction_abort_delete(void ** state)517 static void test_transaction_abort_delete(void **state)
518 {
519 	int ret;
520 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
521 							  struct test_ctx);
522 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
523 	uint8_t key_val[] = "TheKey";
524 	struct ldb_val key = {
525 		.data   = key_val,
526 		.length = sizeof(key_val)
527 	};
528 
529 	uint8_t value[] = "The record contents";
530 	struct ldb_val data = {
531 		.data    = value,
532 		.length = sizeof(value)
533 	};
534 
535 	struct ldb_val read;
536 
537 	int flags = 0;
538 	TALLOC_CTX *tmp_ctx;
539 
540 	tmp_ctx = talloc_new(test_ctx);
541 	assert_non_null(tmp_ctx);
542 
543 	/*
544 	 * Begin a transaction
545 	 */
546 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
547 	assert_int_equal(ret, 0);
548 
549 	/*
550 	 * Write the record
551 	 */
552 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
553 	assert_int_equal(ret, 0);
554 
555 	/*
556 	 * Commit the transaction
557 	 */
558 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
559 	assert_int_equal(ret, 0);
560 
561 	/*
562 	 * And now read it back
563 	 */
564 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
565 	assert_int_equal(ret, 0);
566 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
567 	assert_int_equal(ret, 0);
568 	assert_int_equal(sizeof(value), read.length);
569 	assert_memory_equal(value, read.data, sizeof(value));
570 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
571 	assert_int_equal(ret, 0);
572 
573 	/*
574 	 * Begin a transaction
575 	 */
576 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
577 	assert_int_equal(ret, 0);
578 
579 	/*
580 	 * Now delete it.
581 	 */
582 	ret = ldb_kv->kv_ops->delete (ldb_kv, key);
583 	assert_int_equal(ret, 0);
584 
585 	/*
586 	 * And now read it back
587 	 */
588 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
589 	assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
590 
591 	/*
592 	 * Abort the transaction
593 	 */
594 	ret = ldb_kv->kv_ops->abort_write(ldb_kv);
595 	assert_int_equal(ret, 0);
596 
597 	/*
598 	 * And now try to read it back
599 	 */
600 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
601 	assert_int_equal(ret, 0);
602 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
603 	assert_int_equal(ret, 0);
604 	assert_int_equal(sizeof(value), read.length);
605 	assert_memory_equal(value, read.data, sizeof(value));
606 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
607 	assert_int_equal(ret, 0);
608 
609 	talloc_free(tmp_ctx);
610 }
611 
612 /*
613  * Test that writes outside a transaction fail
614  */
test_write_outside_transaction(void ** state)615 static void test_write_outside_transaction(void **state)
616 {
617 	int ret;
618 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
619 							  struct test_ctx);
620 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
621 	uint8_t key_val[] = "TheKey";
622 	struct ldb_val key = {
623 		.data   = key_val,
624 		.length = sizeof(key_val)
625 	};
626 
627 	uint8_t value[] = "The record contents";
628 	struct ldb_val data = {
629 		.data    = value,
630 		.length = sizeof(value)
631 	};
632 
633 
634 	int flags = 0;
635 	TALLOC_CTX *tmp_ctx;
636 
637 	tmp_ctx = talloc_new(test_ctx);
638 	assert_non_null(tmp_ctx);
639 
640 	/*
641 	 * Attempt to write the record
642 	 */
643 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
644 	assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
645 
646 	talloc_free(tmp_ctx);
647 }
648 
649 /*
650  * Test data can not be deleted outside a transaction
651  */
test_delete_outside_transaction(void ** state)652 static void test_delete_outside_transaction(void **state)
653 {
654 	int ret;
655 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
656 							  struct test_ctx);
657 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
658 	uint8_t key_val[] = "TheKey";
659 	struct ldb_val key = {
660 		.data   = key_val,
661 		.length = sizeof(key_val)
662 	};
663 
664 	uint8_t value[] = "The record contents";
665 	struct ldb_val data = {
666 		.data    = value,
667 		.length = sizeof(value)
668 	};
669 
670 	struct ldb_val read;
671 
672 	int flags = 0;
673 	TALLOC_CTX *tmp_ctx;
674 
675 	tmp_ctx = talloc_new(test_ctx);
676 	assert_non_null(tmp_ctx);
677 
678 	/*
679 	 * Begin a transaction
680 	 */
681 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
682 	assert_int_equal(ret, 0);
683 
684 	/*
685 	 * Write the record
686 	 */
687 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
688 	assert_int_equal(ret, 0);
689 
690 	/*
691 	 * Commit the transaction
692 	 */
693 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
694 	assert_int_equal(ret, 0);
695 
696 	/*
697 	 * And now read it back
698 	 */
699 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
700 	assert_int_equal(ret, 0);
701 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
702 	assert_int_equal(ret, 0);
703 	assert_int_equal(sizeof(value), read.length);
704 	assert_memory_equal(value, read.data, sizeof(value));
705 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
706 	assert_int_equal(ret, 0);
707 
708 	/*
709 	 * Now attempt to delete a record
710 	 */
711 	ret = ldb_kv->kv_ops->delete (ldb_kv, key);
712 	assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
713 
714 	/*
715 	 * And now read it back
716 	 */
717 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
718 	assert_int_equal(ret, 0);
719 	ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read);
720 	assert_int_equal(ret, 0);
721 	assert_int_equal(sizeof(value), read.length);
722 	assert_memory_equal(value, read.data, sizeof(value));
723 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
724 	assert_int_equal(ret, 0);
725 
726 	talloc_free(tmp_ctx);
727 }
728 
traverse_fn(struct ldb_kv_private * ldb_kv,struct ldb_val key,struct ldb_val data,void * ctx)729 static int traverse_fn(struct ldb_kv_private *ldb_kv,
730 		       struct ldb_val key,
731 		       struct ldb_val data,
732 		       void *ctx)
733 {
734 
735 	int *visits = ctx;
736 	int i;
737 
738 	if (strncmp("key ", (char *) key.data, 4) == 0) {
739 		i = strtol((char *) &key.data[4], NULL, 10);
740 		visits[i]++;
741 	}
742 	return LDB_SUCCESS;
743 }
744 
745 /*
746  * Test that iterate visits all the records.
747  */
test_iterate(void ** state)748 static void test_iterate(void **state)
749 {
750 	int ret;
751 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
752 							  struct test_ctx);
753 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
754 	int i;
755 	int num_recs = 1024;
756 	int visits[num_recs];
757 
758 	TALLOC_CTX *tmp_ctx;
759 
760 	tmp_ctx = talloc_new(test_ctx);
761 	assert_non_null(tmp_ctx);
762 
763 	/*
764 	 * Begin a transaction
765 	 */
766 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
767 	assert_int_equal(ret, 0);
768 
769 	/*
770 	 * Write the records
771 	 */
772 	for (i = 0; i < num_recs; i++) {
773 		struct ldb_val key;
774 		struct ldb_val rec;
775 		int flags = 0;
776 
777 		visits[i] = 0;
778 		key.data   = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i);
779 		key.length = strlen((char *)key.data) + 1;
780 
781 		rec.data = (uint8_t *) talloc_asprintf(tmp_ctx,
782 						       "data for record (%04d)",
783 						       i);
784 		rec.length = strlen((char *)rec.data) + 1;
785 
786 		ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags);
787 		assert_int_equal(ret, 0);
788 
789 		TALLOC_FREE(key.data);
790 		TALLOC_FREE(rec.data);
791 	}
792 
793 	/*
794 	 * Commit the transaction
795 	 */
796 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
797 	assert_int_equal(ret, 0);
798 
799 	/*
800 	 * Now iterate over the kv store and ensure that all the
801 	 * records are visited.
802 	 */
803 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
804 	assert_int_equal(ret, 0);
805 	ret = ldb_kv->kv_ops->iterate(ldb_kv, traverse_fn, visits);
806 	for (i = 0; i <num_recs; i++) {
807 		assert_int_equal(1, visits[i]);
808 	}
809 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
810 	assert_int_equal(ret, 0);
811 
812 	TALLOC_FREE(tmp_ctx);
813 }
814 
do_iterate_range_test(void ** state,int range_start,int range_end,bool fail)815 static void do_iterate_range_test(void **state, int range_start,
816 				  int range_end, bool fail)
817 {
818 	int ret;
819 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
820 							  struct test_ctx);
821 	struct ldb_kv_private *ldb_kv = NULL;
822 	int i;
823 	int num_recs = 1024;
824 	int skip_recs = 10;
825 	int visits[num_recs];
826 	struct ldb_val sk, ek;
827 
828 	TALLOC_CTX *tmp_ctx;
829 
830 	ldb_kv = get_ldb_kv(test_ctx->ldb);
831 	assert_non_null(ldb_kv);
832 
833 	for (i = 0; i < num_recs; i++){
834 		visits[i] = 0;
835 	}
836 
837 	/*
838 	 * No iterate_range on tdb
839 	 */
840 	if (strcmp(TEST_BE, "tdb") == 0) {
841 		return;
842 	}
843 
844 	tmp_ctx = talloc_new(test_ctx);
845 	assert_non_null(tmp_ctx);
846 
847 	/*
848 	 * Begin a transaction
849 	 */
850 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
851 	assert_int_equal(ret, 0);
852 
853 	/*
854 	 * Write the records
855 	 */
856 	for (i = skip_recs; i <= num_recs - skip_recs; i++) {
857 		struct ldb_val key;
858 		struct ldb_val rec;
859 		int flags = 0;
860 
861 		key.data   = (uint8_t *)talloc_asprintf(tmp_ctx,
862 							"key %04d",
863 							i);
864 		key.length = strlen((char *)key.data);
865 
866 		rec.data = (uint8_t *)talloc_asprintf(tmp_ctx,
867 						      "data for record (%04d)",
868 						      i);
869 		rec.length = strlen((char *)rec.data) + 1;
870 
871 		ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags);
872 		assert_int_equal(ret, 0);
873 
874 		TALLOC_FREE(key.data);
875 		TALLOC_FREE(rec.data);
876 	}
877 
878 	/*
879 	 * Commit the transaction
880 	 */
881 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
882 	assert_int_equal(ret, 0);
883 
884 	sk.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_start);
885 	sk.length = strlen((char *)sk.data);
886 
887 	ek.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_end);
888 	ek.length = strlen((char *)ek.data) + 1;
889 
890 	ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules);
891 	assert_int_equal(ret, 0);
892 	ret = ldb_kv->kv_ops->iterate_range(ldb_kv, sk, ek,
893 					    traverse_fn, visits);
894 	if (fail){
895 		assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR);
896 		TALLOC_FREE(tmp_ctx);
897 		return;
898 	} else{
899 		assert_int_equal(ret, 0);
900 	}
901 	for (i = 0; i < num_recs; i++) {
902 		if (i >= skip_recs && i <= num_recs - skip_recs &&
903 		    i >= range_start && i <= range_end){
904 			assert_int_equal(1, visits[i]);
905 		} else {
906 			assert_int_equal(0, visits[i]);
907 		}
908 	}
909 
910 	ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules);
911 	assert_int_equal(ret, 0);
912 
913 	TALLOC_FREE(tmp_ctx);
914 }
915 
916 /*
917  * Test that iterate_range visits all the records between two keys.
918  */
test_iterate_range(void ** state)919 static void test_iterate_range(void **state)
920 {
921 	do_iterate_range_test(state, 300, 900, false);
922 
923 	/*
924 	 * test start_key = end_key
925 	 */
926 	do_iterate_range_test(state, 20, 20, false);
927 
928 	/*
929 	 * test reverse range fails
930 	 */
931 	do_iterate_range_test(state, 50, 40, true);
932 
933 	/*
934 	 * keys are between 10-1014 so test with keys outside that range
935 	 */
936 	do_iterate_range_test(state, 0, 20, false);
937 	do_iterate_range_test(state, 1010, 1030, false);
938 	do_iterate_range_test(state, 0, 1030, false);
939 }
940 
941 struct update_context {
942 	struct ldb_context* ldb;
943 	int visits[NUM_RECS];
944 };
945 
update_fn(struct ldb_kv_private * ldb_kv,struct ldb_val key,struct ldb_val data,void * ctx)946 static int update_fn(struct ldb_kv_private *ldb_kv,
947 		     struct ldb_val key,
948 		     struct ldb_val data,
949 		     void *ctx)
950 {
951 
952 	struct ldb_val new_key;
953 	struct ldb_module *module = NULL;
954 	struct update_context *context =NULL;
955 	int ret = LDB_SUCCESS;
956 	TALLOC_CTX *tmp_ctx;
957 
958 	tmp_ctx = talloc_new(ldb_kv);
959 	assert_non_null(tmp_ctx);
960 
961 	context = talloc_get_type_abort(ctx, struct update_context);
962 
963 	module = talloc_zero(tmp_ctx, struct ldb_module);
964 	module->ldb = context->ldb;
965 
966 	if (strncmp("key ", (char *) key.data, 4) == 0) {
967 		int i = strtol((char *) &key.data[4], NULL, 10);
968 		context->visits[i]++;
969 		new_key.data = talloc_memdup(tmp_ctx, key.data, key.length);
970 		new_key.length  = key.length;
971 		new_key.data[0] = 'K';
972 
973 		ret = ldb_kv->kv_ops->update_in_iterate(
974 		    ldb_kv, key, new_key, data, &module);
975 	}
976 	TALLOC_FREE(tmp_ctx);
977 	return ret;
978 }
979 
980 /*
981  * Test that update_in_iterate behaves as expected.
982  */
test_update_in_iterate(void ** state)983 static void test_update_in_iterate(void **state)
984 {
985 	int ret;
986 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
987 							  struct test_ctx);
988 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
989 	int i;
990 	struct update_context *context = NULL;
991 
992 
993 	TALLOC_CTX *tmp_ctx;
994 
995 	tmp_ctx = talloc_new(test_ctx);
996 	assert_non_null(tmp_ctx);
997 
998 	context = talloc_zero(tmp_ctx, struct update_context);
999 	assert_non_null(context);
1000 	context->ldb = test_ctx->ldb;
1001 	/*
1002 	 * Begin a transaction
1003 	 */
1004 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
1005 	assert_int_equal(ret, 0);
1006 
1007 	/*
1008 	 * Write the records
1009 	 */
1010 	for (i = 0; i < NUM_RECS; i++) {
1011 		struct ldb_val key;
1012 		struct ldb_val rec;
1013 		int flags = 0;
1014 
1015 		key.data   = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i);
1016 		key.length = strlen((char *)key.data) + 1;
1017 
1018 		rec.data   = (uint8_t *) talloc_asprintf(tmp_ctx,
1019 							 "data for record (%04d)",
1020 							 i);
1021 		rec.length = strlen((char *)rec.data) + 1;
1022 
1023 		ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags);
1024 		assert_int_equal(ret, 0);
1025 
1026 		TALLOC_FREE(key.data);
1027 		TALLOC_FREE(rec.data);
1028 	}
1029 
1030 	/*
1031 	 * Commit the transaction
1032 	 */
1033 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
1034 	assert_int_equal(ret, 0);
1035 
1036 	/*
1037 	 * Now iterate over the kv store and ensure that all the
1038 	 * records are visited.
1039 	 */
1040 
1041 	/*
1042 	 * Needs to be done inside a transaction
1043 	 */
1044 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
1045 	assert_int_equal(ret, 0);
1046 
1047 	ret = ldb_kv->kv_ops->iterate(ldb_kv, update_fn, context);
1048 	for (i = 0; i < NUM_RECS; i++) {
1049 		assert_int_equal(1, context->visits[i]);
1050 	}
1051 
1052 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
1053 	assert_int_equal(ret, 0);
1054 
1055 	TALLOC_FREE(tmp_ctx);
1056 }
1057 
1058 /*
1059  * Ensure that writes are not visible until the transaction has been
1060  * committed.
1061  */
test_write_transaction_isolation(void ** state)1062 static void test_write_transaction_isolation(void **state)
1063 {
1064 	int ret;
1065 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
1066 							  struct test_ctx);
1067 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
1068 	struct ldb_val key;
1069 	struct ldb_val val;
1070 
1071 	const char *KEY1 = "KEY01";
1072 	const char *VAL1 = "VALUE01";
1073 
1074 	const char *KEY2 = "KEY02";
1075 	const char *VAL2 = "VALUE02";
1076 
1077 	/*
1078 	 * Pipes etc to co-ordinate the processes
1079 	 */
1080 	int to_child[2];
1081 	int to_parent[2];
1082 	char buf[2];
1083 	pid_t pid, w_pid;
1084 	int wstatus;
1085 
1086 	TALLOC_CTX *tmp_ctx;
1087 	tmp_ctx = talloc_new(test_ctx);
1088 	assert_non_null(tmp_ctx);
1089 
1090 
1091 	/*
1092 	 * Add a record to the database
1093 	 */
1094 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
1095 	assert_int_equal(ret, 0);
1096 
1097 	key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
1098 	key.length = strlen(KEY1) + 1;
1099 
1100 	val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1);
1101 	val.length = strlen(VAL1) + 1;
1102 
1103 	ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0);
1104 	assert_int_equal(ret, 0);
1105 
1106 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
1107 	assert_int_equal(ret, 0);
1108 
1109 
1110 	ret = pipe(to_child);
1111 	assert_int_equal(ret, 0);
1112 	ret = pipe(to_parent);
1113 	assert_int_equal(ret, 0);
1114 	/*
1115 	 * Now fork a new process
1116 	 */
1117 
1118 	pid = fork();
1119 	if (pid == 0) {
1120 
1121 		struct ldb_context *ldb = NULL;
1122 		close(to_child[1]);
1123 		close(to_parent[0]);
1124 
1125 		/*
1126 		 * Wait for the transaction to start
1127 		 */
1128 		ret = read(to_child[0], buf, 2);
1129 		if (ret != 2) {
1130 			print_error(__location__": read returned (%d)\n",
1131 				    ret);
1132 			exit(LDB_ERR_OPERATIONS_ERROR);
1133 		}
1134 		ldb = ldb_init(test_ctx, test_ctx->ev);
1135 		ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL);
1136 		if (ret != LDB_SUCCESS) {
1137 			print_error(__location__": ldb_connect returned (%d)\n",
1138 				    ret);
1139 			exit(ret);
1140 		}
1141 
1142 		ldb_kv = get_ldb_kv(ldb);
1143 
1144 		ret = ldb_kv->kv_ops->lock_read(ldb->modules);
1145 		if (ret != LDB_SUCCESS) {
1146 			print_error(__location__": lock_read returned (%d)\n",
1147 				    ret);
1148 			exit(ret);
1149 		}
1150 
1151 		/*
1152 		 * Check that KEY1 is there
1153 		 */
1154 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
1155 		key.length = strlen(KEY1) + 1;
1156 
1157 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1158 		if (ret != LDB_SUCCESS) {
1159 			print_error(__location__": fetch_and_parse returned "
1160 				    "(%d)\n",
1161 				    ret);
1162 			exit(ret);
1163 		}
1164 
1165 		if ((strlen(VAL1) + 1) != val.length) {
1166 			print_error(__location__": KEY1 value lengths different"
1167 				    ", expected (%d) actual(%d)\n",
1168 				    (int)(strlen(VAL1) + 1), (int)val.length);
1169 			exit(LDB_ERR_OPERATIONS_ERROR);
1170 		}
1171 		if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
1172 			print_error(__location__": KEY1 values different, "
1173 				    "expected (%s) actual(%s)\n",
1174 				    VAL1,
1175 				    val.data);
1176 			exit(LDB_ERR_OPERATIONS_ERROR);
1177 		}
1178 
1179 		ret = ldb_kv->kv_ops->unlock_read(ldb->modules);
1180 		if (ret != LDB_SUCCESS) {
1181 			print_error(__location__": unlock_read returned (%d)\n",
1182 				    ret);
1183 			exit(ret);
1184 		}
1185 
1186 		/*
1187 		 * Check that KEY2 is not there
1188 		 */
1189 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
1190 		key.length = strlen(KEY2 + 1);
1191 
1192 		ret = ldb_kv->kv_ops->lock_read(ldb->modules);
1193 		if (ret != LDB_SUCCESS) {
1194 			print_error(__location__": lock_read returned (%d)\n",
1195 				    ret);
1196 			exit(ret);
1197 		}
1198 
1199 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1200 		if (ret != LDB_ERR_NO_SUCH_OBJECT) {
1201 			print_error(__location__": fetch_and_parse returned "
1202 				    "(%d)\n",
1203 				    ret);
1204 			exit(ret);
1205 		}
1206 
1207 		ret = ldb_kv->kv_ops->unlock_read(ldb->modules);
1208 		if (ret != LDB_SUCCESS) {
1209 			print_error(__location__": unlock_read returned (%d)\n",
1210 				    ret);
1211 			exit(ret);
1212 		}
1213 
1214 		/*
1215 		 * Signal the other process to commit the transaction
1216 		 */
1217 		ret = write(to_parent[1], "GO", 2);
1218 		if (ret != 2) {
1219 			print_error(__location__": write returned (%d)\n",
1220 				    ret);
1221 			exit(LDB_ERR_OPERATIONS_ERROR);
1222 		}
1223 
1224 		/*
1225 		 * Wait for the transaction to be commited
1226 		 */
1227 		ret = read(to_child[0], buf, 2);
1228 		if (ret != 2) {
1229 			print_error(__location__": read returned (%d)\n",
1230 				    ret);
1231 			exit(LDB_ERR_OPERATIONS_ERROR);
1232 		}
1233 
1234 		/*
1235 		 * Check that KEY1 is there
1236 		 */
1237 		ret = ldb_kv->kv_ops->lock_read(ldb->modules);
1238 		if (ret != LDB_SUCCESS) {
1239 			print_error(__location__": unlock_read returned (%d)\n",
1240 				    ret);
1241 			exit(ret);
1242 		}
1243 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
1244 		key.length = strlen(KEY1) + 1;
1245 
1246 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1247 		if (ret != LDB_SUCCESS) {
1248 			print_error(__location__": fetch_and_parse returned "
1249 				    "(%d)\n",
1250 				    ret);
1251 			exit(ret);
1252 		}
1253 
1254 		if ((strlen(VAL1) + 1) != val.length) {
1255 			print_error(__location__": KEY1 value lengths different"
1256 				    ", expected (%d) actual(%d)\n",
1257 				    (int)(strlen(VAL1) + 1), (int)val.length);
1258 			exit(LDB_ERR_OPERATIONS_ERROR);
1259 		}
1260 		if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
1261 			print_error(__location__": KEY1 values different, "
1262 				    "expected (%s) actual(%s)\n",
1263 				    VAL1,
1264 				    val.data);
1265 			exit(LDB_ERR_OPERATIONS_ERROR);
1266 		}
1267 
1268 		ret = ldb_kv->kv_ops->unlock_read(ldb->modules);
1269 		if (ret != LDB_SUCCESS) {
1270 			print_error(__location__": unlock_read returned (%d)\n",
1271 				    ret);
1272 			exit(ret);
1273 		}
1274 
1275 
1276 		/*
1277 		 * Check that KEY2 is there
1278 		 */
1279 		ret = ldb_kv->kv_ops->lock_read(ldb->modules);
1280 		if (ret != LDB_SUCCESS) {
1281 			print_error(__location__": unlock_read returned (%d)\n",
1282 				    ret);
1283 			exit(ret);
1284 		}
1285 
1286 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
1287 		key.length = strlen(KEY2) + 1;
1288 
1289 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1290 		if (ret != LDB_SUCCESS) {
1291 			print_error(__location__": fetch_and_parse returned "
1292 				    "(%d)\n",
1293 				    ret);
1294 			exit(ret);
1295 		}
1296 
1297 		if ((strlen(VAL2) + 1) != val.length) {
1298 			print_error(__location__": KEY2 value lengths different"
1299 				    ", expected (%d) actual(%d)\n",
1300 				    (int)(strlen(VAL2) + 1), (int)val.length);
1301 			exit(LDB_ERR_OPERATIONS_ERROR);
1302 		}
1303 		if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) {
1304 			print_error(__location__": KEY2 values different, "
1305 				    "expected (%s) actual(%s)\n",
1306 				    VAL2,
1307 				    val.data);
1308 			exit(LDB_ERR_OPERATIONS_ERROR);
1309 		}
1310 
1311 		ret = ldb_kv->kv_ops->unlock_read(ldb->modules);
1312 		if (ret != LDB_SUCCESS) {
1313 			print_error(__location__": unlock_read returned (%d)\n",
1314 				    ret);
1315 			exit(ret);
1316 		}
1317 
1318 		exit(0);
1319 	}
1320 	close(to_child[0]);
1321 	close(to_parent[1]);
1322 
1323 	/*
1324 	 * Begin a transaction and add a record to the database
1325 	 * but leave the transaction open
1326 	 */
1327 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
1328 	assert_int_equal(ret, 0);
1329 
1330 	key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
1331 	key.length = strlen(KEY2) + 1;
1332 
1333 	val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2);
1334 	val.length = strlen(VAL2) + 1;
1335 
1336 	ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0);
1337 	assert_int_equal(ret, 0);
1338 
1339 	/*
1340 	 * Signal the child process
1341 	 */
1342 	ret = write(to_child[1], "GO", 2);
1343 	assert_int_equal(2, ret);
1344 
1345 	/*
1346 	 * Wait for the child process to check the DB state while the
1347 	 * transaction is active
1348 	 */
1349 	ret = read(to_parent[0], buf, 2);
1350 	assert_int_equal(2, ret);
1351 
1352 	/*
1353 	 * commit the transaction
1354 	 */
1355 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
1356 	assert_int_equal(0, ret);
1357 
1358 	/*
1359 	 * Signal the child process
1360 	 */
1361 	ret = write(to_child[1], "GO", 2);
1362 	assert_int_equal(2, ret);
1363 
1364 	w_pid = waitpid(pid, &wstatus, 0);
1365 	assert_int_equal(pid, w_pid);
1366 
1367 	assert_true(WIFEXITED(wstatus));
1368 
1369 	assert_int_equal(WEXITSTATUS(wstatus), 0);
1370 
1371 
1372 	TALLOC_FREE(tmp_ctx);
1373 }
1374 
1375 /*
1376  * Ensure that deletes are not visible until the transaction has been
1377  * committed.
1378  */
test_delete_transaction_isolation(void ** state)1379 static void test_delete_transaction_isolation(void **state)
1380 {
1381 	int ret;
1382 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
1383 							  struct test_ctx);
1384 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
1385 	struct ldb_val key;
1386 	struct ldb_val val;
1387 
1388 	const char *KEY1 = "KEY01";
1389 	const char *VAL1 = "VALUE01";
1390 
1391 	const char *KEY2 = "KEY02";
1392 	const char *VAL2 = "VALUE02";
1393 
1394 	/*
1395 	 * Pipes etc to co-ordinate the processes
1396 	 */
1397 	int to_child[2];
1398 	int to_parent[2];
1399 	char buf[2];
1400 	pid_t pid, w_pid;
1401 	int wstatus;
1402 
1403 	TALLOC_CTX *tmp_ctx;
1404 	tmp_ctx = talloc_new(test_ctx);
1405 	assert_non_null(tmp_ctx);
1406 
1407 
1408 	/*
1409 	 * Add records to the database
1410 	 */
1411 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
1412 	assert_int_equal(ret, 0);
1413 
1414 	key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
1415 	key.length = strlen(KEY1) + 1;
1416 
1417 	val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1);
1418 	val.length = strlen(VAL1) + 1;
1419 
1420 	ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0);
1421 	assert_int_equal(ret, 0);
1422 
1423 	key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
1424 	key.length = strlen(KEY2) + 1;
1425 
1426 	val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2);
1427 	val.length = strlen(VAL2) + 1;
1428 
1429 	ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0);
1430 	assert_int_equal(ret, 0);
1431 
1432 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
1433 	assert_int_equal(ret, 0);
1434 
1435 
1436 	ret = pipe(to_child);
1437 	assert_int_equal(ret, 0);
1438 	ret = pipe(to_parent);
1439 	assert_int_equal(ret, 0);
1440 	/*
1441 	 * Now fork a new process
1442 	 */
1443 
1444 	pid = fork();
1445 	if (pid == 0) {
1446 
1447 		struct ldb_context *ldb = NULL;
1448 		close(to_child[1]);
1449 		close(to_parent[0]);
1450 
1451 		/*
1452 		 * Wait for the transaction to be started
1453 		 */
1454 		ret = read(to_child[0], buf, 2);
1455 		if (ret != 2) {
1456 			print_error(__location__": read returned (%d)\n",
1457 				    ret);
1458 			exit(LDB_ERR_OPERATIONS_ERROR);
1459 		}
1460 
1461 		ldb = ldb_init(test_ctx, test_ctx->ev);
1462 		ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL);
1463 		if (ret != LDB_SUCCESS) {
1464 			print_error(__location__": ldb_connect returned (%d)\n",
1465 				    ret);
1466 			exit(ret);
1467 		}
1468 
1469 		ldb_kv = get_ldb_kv(ldb);
1470 
1471 		ret = ldb_kv->kv_ops->lock_read(ldb->modules);
1472 		if (ret != LDB_SUCCESS) {
1473 			print_error(__location__": lock_read returned (%d)\n",
1474 				    ret);
1475 			exit(ret);
1476 		}
1477 
1478 		/*
1479 		 * Check that KEY1 is there
1480 		 */
1481 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
1482 		key.length = strlen(KEY1) + 1;
1483 
1484 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1485 		if (ret != LDB_SUCCESS) {
1486 			print_error(__location__": fetch_and_parse returned "
1487 				    "(%d)\n",
1488 				    ret);
1489 			exit(ret);
1490 		}
1491 
1492 		if ((strlen(VAL1) + 1) != val.length) {
1493 			print_error(__location__": KEY1 value lengths different"
1494 				    ", expected (%d) actual(%d)\n",
1495 				    (int)(strlen(VAL1) + 1), (int)val.length);
1496 			exit(LDB_ERR_OPERATIONS_ERROR);
1497 		}
1498 		if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
1499 			print_error(__location__": KEY1 values different, "
1500 				    "expected (%s) actual(%s)\n",
1501 				    VAL1,
1502 				    val.data);
1503 			exit(LDB_ERR_OPERATIONS_ERROR);
1504 		}
1505 
1506 		/*
1507 		 * Check that KEY2 is there
1508 		 */
1509 
1510 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
1511 		key.length = strlen(KEY2) + 1;
1512 
1513 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1514 		if (ret != LDB_SUCCESS) {
1515 			print_error(__location__": fetch_and_parse returned "
1516 				    "(%d)\n",
1517 				    ret);
1518 			exit(ret);
1519 		}
1520 
1521 		if ((strlen(VAL2) + 1) != val.length) {
1522 			print_error(__location__": KEY2 value lengths different"
1523 				    ", expected (%d) actual(%d)\n",
1524 				    (int)(strlen(VAL2) + 1), (int)val.length);
1525 			exit(LDB_ERR_OPERATIONS_ERROR);
1526 		}
1527 		if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) {
1528 			print_error(__location__": KEY2 values different, "
1529 				    "expected (%s) actual(%s)\n",
1530 				    VAL2,
1531 				    val.data);
1532 			exit(LDB_ERR_OPERATIONS_ERROR);
1533 		}
1534 
1535 		ret = ldb_kv->kv_ops->unlock_read(ldb->modules);
1536 		if (ret != LDB_SUCCESS) {
1537 			print_error(__location__": unlock_read returned (%d)\n",
1538 				    ret);
1539 			exit(ret);
1540 		}
1541 
1542 		/*
1543 		 * Signal the other process to commit the transaction
1544 		 */
1545 		ret = write(to_parent[1], "GO", 2);
1546 		if (ret != 2) {
1547 			print_error(__location__": write returned (%d)\n",
1548 				    ret);
1549 			exit(LDB_ERR_OPERATIONS_ERROR);
1550 		}
1551 
1552 		/*
1553 		 * Wait for the transaction to be commited
1554 		 */
1555 		ret = read(to_child[0], buf, 2);
1556 		if (ret != 2) {
1557 			print_error(__location__": read returned (%d)\n",
1558 				    ret);
1559 			exit(LDB_ERR_OPERATIONS_ERROR);
1560 		}
1561 
1562 		/*
1563 		 * Check that KEY1 is there
1564 		 */
1565 		ret = ldb_kv->kv_ops->lock_read(ldb->modules);
1566 		if (ret != LDB_SUCCESS) {
1567 			print_error(__location__": unlock_read returned (%d)\n",
1568 				    ret);
1569 			exit(ret);
1570 		}
1571 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1);
1572 		key.length = strlen(KEY1) + 1;
1573 
1574 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1575 		if (ret != LDB_SUCCESS) {
1576 			print_error(__location__": fetch_and_parse returned "
1577 				    "(%d)\n",
1578 				    ret);
1579 			exit(ret);
1580 		}
1581 
1582 		if ((strlen(VAL1) + 1) != val.length) {
1583 			print_error(__location__": KEY1 value lengths different"
1584 				    ", expected (%d) actual(%d)\n",
1585 				    (int)(strlen(VAL1) + 1), (int)val.length);
1586 			exit(LDB_ERR_OPERATIONS_ERROR);
1587 		}
1588 		if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) {
1589 			print_error(__location__": KEY1 values different, "
1590 				    "expected (%s) actual(%s)\n",
1591 				    VAL1,
1592 				    val.data);
1593 			exit(LDB_ERR_OPERATIONS_ERROR);
1594 		}
1595 		ret = ldb_kv->kv_ops->unlock_read(ldb->modules);
1596 		if (ret != LDB_SUCCESS) {
1597 			print_error(__location__": unlock_read returned (%d)\n",
1598 				    ret);
1599 			exit(ret);
1600 		}
1601 
1602 		/*
1603 		 * Check that KEY2 is not there
1604 		 */
1605 		key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
1606 		key.length = strlen(KEY2 + 1);
1607 
1608 		ret = ldb_kv->kv_ops->lock_read(ldb->modules);
1609 		if (ret != LDB_SUCCESS) {
1610 			print_error(__location__": lock_read returned (%d)\n",
1611 				    ret);
1612 			exit(ret);
1613 		}
1614 
1615 		ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val);
1616 		if (ret != LDB_ERR_NO_SUCH_OBJECT) {
1617 			print_error(__location__": fetch_and_parse returned "
1618 				    "(%d)\n",
1619 				    ret);
1620 			exit(ret);
1621 		}
1622 
1623 		ret = ldb_kv->kv_ops->unlock_read(ldb->modules);
1624 		if (ret != LDB_SUCCESS) {
1625 			print_error(__location__": unlock_read returned (%d)\n",
1626 				    ret);
1627 			exit(ret);
1628 		}
1629 		TALLOC_FREE(tmp_ctx);
1630 		exit(0);
1631 	}
1632 	close(to_child[0]);
1633 	close(to_parent[1]);
1634 
1635 	/*
1636 	 * Begin a transaction and delete a record from the database
1637 	 * but leave the transaction open
1638 	 */
1639 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
1640 	assert_int_equal(ret, 0);
1641 
1642 	key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2);
1643 	key.length = strlen(KEY2) + 1;
1644 
1645 	ret = ldb_kv->kv_ops->delete (ldb_kv, key);
1646 	assert_int_equal(ret, 0);
1647 	/*
1648 	 * Signal the child process
1649 	 */
1650 	ret = write(to_child[1], "GO", 2);
1651 	assert_int_equal(2, ret);
1652 
1653 	/*
1654 	 * Wait for the child process to check the DB state while the
1655 	 * transaction is active
1656 	 */
1657 	ret = read(to_parent[0], buf, 2);
1658 	assert_int_equal(2, ret);
1659 
1660 	/*
1661 	 * commit the transaction
1662 	 */
1663 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
1664 	assert_int_equal(0, ret);
1665 
1666 	/*
1667 	 * Signal the child process
1668 	 */
1669 	ret = write(to_child[1], "GO", 2);
1670 	assert_int_equal(2, ret);
1671 
1672 	w_pid = waitpid(pid, &wstatus, 0);
1673 	assert_int_equal(pid, w_pid);
1674 
1675 	assert_true(WIFEXITED(wstatus));
1676 
1677 	assert_int_equal(WEXITSTATUS(wstatus), 0);
1678 
1679 
1680 	TALLOC_FREE(tmp_ctx);
1681 }
1682 
1683 
1684 /*
1685  * Test that get_size returns a sensible estimate of the number of records
1686  * in the database.
1687  */
test_get_size(void ** state)1688 static void test_get_size(void **state)
1689 {
1690 	int ret;
1691 	struct test_ctx *test_ctx = talloc_get_type_abort(*state,
1692 							  struct test_ctx);
1693 	struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb);
1694 	uint8_t key_val[] = "TheKey";
1695 	struct ldb_val key = {
1696 		.data   = key_val,
1697 		.length = sizeof(key_val)
1698 	};
1699 
1700 	uint8_t value[] = "The record contents";
1701 	struct ldb_val data = {
1702 		.data    = value,
1703 		.length = sizeof(value)
1704 	};
1705 	size_t size = 0;
1706 
1707 	int flags = 0;
1708 	TALLOC_CTX *tmp_ctx;
1709 
1710 	tmp_ctx = talloc_new(test_ctx);
1711 	assert_non_null(tmp_ctx);
1712 
1713 	size = ldb_kv->kv_ops->get_size(ldb_kv);
1714 #if defined(TEST_LMDB)
1715 	assert_int_equal(2, size);
1716 #else
1717 	/*
1718 	 * The tdb implementation of get_size over estimates for sparse files
1719 	 * which is perfectly acceptable for it's intended use.
1720 	 */
1721 	assert_in_range(size, 2500, 5000);
1722 #endif
1723 
1724 	/*
1725 	 * Begin a transaction
1726 	 */
1727 	ret = ldb_kv->kv_ops->begin_write(ldb_kv);
1728 	assert_int_equal(ret, 0);
1729 
1730 	/*
1731 	 * Write the record
1732 	 */
1733 	ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags);
1734 	assert_int_equal(ret, 0);
1735 
1736 	/*
1737 	 * Commit the transaction
1738 	 */
1739 	ret = ldb_kv->kv_ops->finish_write(ldb_kv);
1740 	assert_int_equal(ret, 0);
1741 
1742 	size = ldb_kv->kv_ops->get_size(ldb_kv);
1743 #ifdef TEST_LMDB
1744 	assert_int_equal(3, size);
1745 #else
1746 	/*
1747 	 * The tdb implementation of get_size over estimates for sparse files
1748 	 * which is perfectly acceptable for it's intended use.
1749 	 */
1750 	assert_in_range(size, 2500, 5000);
1751 #endif
1752 	talloc_free(tmp_ctx);
1753 }
1754 
main(int argc,const char ** argv)1755 int main(int argc, const char **argv)
1756 {
1757 	const struct CMUnitTest tests[] = {
1758 		cmocka_unit_test_setup_teardown(
1759 			test_add_get,
1760 			setup,
1761 			teardown),
1762 		cmocka_unit_test_setup_teardown(
1763 			test_delete,
1764 			setup,
1765 			teardown),
1766 		cmocka_unit_test_setup_teardown(
1767 			test_transaction_abort_write,
1768 			setup,
1769 			teardown),
1770 		cmocka_unit_test_setup_teardown(
1771 			test_transaction_abort_delete,
1772 			setup,
1773 			teardown),
1774 		cmocka_unit_test_setup_teardown(
1775 			test_read_outside_transaction,
1776 			setup,
1777 			teardown),
1778 		cmocka_unit_test_setup_teardown(
1779 			test_write_outside_transaction,
1780 			setup,
1781 			teardown),
1782 		cmocka_unit_test_setup_teardown(
1783 			test_delete_outside_transaction,
1784 			setup,
1785 			teardown),
1786 		cmocka_unit_test_setup_teardown(
1787 			test_iterate,
1788 			setup,
1789 			teardown),
1790 		cmocka_unit_test_setup_teardown(
1791 			test_iterate_range,
1792 			setup,
1793 			teardown),
1794 		cmocka_unit_test_setup_teardown(
1795 			test_update_in_iterate,
1796 			setup,
1797 			teardown),
1798 		cmocka_unit_test_setup_teardown(
1799 			test_write_transaction_isolation,
1800 			setup,
1801 			teardown),
1802 		cmocka_unit_test_setup_teardown(
1803 			test_delete_transaction_isolation,
1804 			setup,
1805 			teardown),
1806 		cmocka_unit_test_setup_teardown(
1807 			test_get_size,
1808 			setup,
1809 			teardown),
1810 	};
1811 
1812 	return cmocka_run_group_tests(tests, NULL, NULL);
1813 }
1814