2 * Tests exercising the ldb key value operations.
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/>.
23 * These headers or their equivalents should be included prior to
31 * This allows test applications to use custom definitions of C standard
32 * library functions and types.
37 * A KV module is expected to have the following behaviour
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 committed
41 * - Nested transactions are not permitted
42 * - transactions can be rolled back and committed.
43 * - supports iteration over all records in the database
44 * - supports the update_in_iterate operation allowing entries to be
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
61 #include <ldb_module.h>
62 #include <ldb_private.h>
68 #include "ldb_tdb/ldb_tdb.h"
69 #include "ldb_key_value/ldb_kv.h"
72 #define DEFAULT_BE "tdb"
75 #define TEST_BE DEFAULT_BE
82 struct tevent_context
*ev
;
83 struct ldb_context
*ldb
;
86 const char *lockfile
; /* lockfile is separate */
91 static void unlink_old_db(struct test_ctx
*test_ctx
)
96 ret
= unlink(test_ctx
->lockfile
);
97 if (ret
== -1 && errno
!= ENOENT
) {
102 ret
= unlink(test_ctx
->dbfile
);
103 if (ret
== -1 && errno
!= ENOENT
) {
108 static int noconn_setup(void **state
)
110 struct test_ctx
*test_ctx
;
112 test_ctx
= talloc_zero(NULL
, struct test_ctx
);
113 assert_non_null(test_ctx
);
115 test_ctx
->ev
= tevent_context_init(test_ctx
);
116 assert_non_null(test_ctx
->ev
);
118 test_ctx
->ldb
= ldb_init(test_ctx
, test_ctx
->ev
);
119 assert_non_null(test_ctx
->ldb
);
121 test_ctx
->dbfile
= talloc_strdup(test_ctx
, "kvopstest.ldb");
122 assert_non_null(test_ctx
->dbfile
);
124 test_ctx
->lockfile
= talloc_asprintf(test_ctx
, "%s-lock",
126 assert_non_null(test_ctx
->lockfile
);
128 test_ctx
->dbpath
= talloc_asprintf(test_ctx
,
129 TEST_BE
"://%s", test_ctx
->dbfile
);
130 assert_non_null(test_ctx
->dbpath
);
132 unlink_old_db(test_ctx
);
137 static int noconn_teardown(void **state
)
139 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
142 unlink_old_db(test_ctx
);
143 talloc_free(test_ctx
);
147 static int setup(void **state
)
149 struct test_ctx
*test_ctx
;
151 struct ldb_ldif
*ldif
;
152 const char *index_ldif
= \
154 "@IDXGUID: objectUUID\n"
155 "@IDX_DN_GUID: GUID\n"
158 noconn_setup((void **) &test_ctx
);
160 ret
= ldb_connect(test_ctx
->ldb
, test_ctx
->dbpath
, 0, NULL
);
161 assert_int_equal(ret
, 0);
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
);
171 static int teardown(void **state
)
173 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
175 noconn_teardown((void **) &test_ctx
);
179 static struct ldb_kv_private
*get_ldb_kv(struct ldb_context
*ldb
)
182 struct ldb_kv_private
*ldb_kv
= NULL
;
184 data
= ldb_module_get_private(ldb
->modules
);
185 assert_non_null(data
);
187 ldb_kv
= talloc_get_type(data
, struct ldb_kv_private
);
188 assert_non_null(ldb_kv
);
193 static int parse(struct ldb_val key
,
197 struct ldb_val
* read
= private_data
;
199 /* Yes, we leak this. That is OK */
200 read
->data
= talloc_size(NULL
,
202 assert_non_null(read
->data
);
204 memcpy(read
->data
, data
.data
, data
.length
);
205 read
->length
= data
.length
;
210 * Parse function that just returns the int we pass it.
212 static int parse_return(struct ldb_val key
,
216 int *rcode
= private_data
;
221 * Test that data can be written to the kv store and be read back.
223 static void test_add_get(void **state
)
226 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
228 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
229 uint8_t key_val
[] = "TheKey";
230 struct ldb_val key
= {
232 .length
= sizeof(key_val
)
235 uint8_t value
[] = "The record contents";
236 struct ldb_val data
= {
238 .length
= sizeof(value
)
247 tmp_ctx
= talloc_new(test_ctx
);
248 assert_non_null(tmp_ctx
);
251 * Begin a transaction
253 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
254 assert_int_equal(ret
, 0);
259 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
260 assert_int_equal(ret
, 0);
263 * Commit the transaction
265 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
266 assert_int_equal(ret
, 0);
269 * And now read it back
271 ret
= ldb_kv
->kv_ops
->lock_read(test_ctx
->ldb
->modules
);
272 assert_int_equal(ret
, 0);
274 ret
= ldb_kv
->kv_ops
->fetch_and_parse(ldb_kv
, key
, parse
, &read
);
275 assert_int_equal(ret
, 0);
277 assert_int_equal(sizeof(value
), read
.length
);
278 assert_memory_equal(value
, read
.data
, sizeof(value
));
281 * Now check that the error code we return in the
282 * parse function is returned by fetch_and_parse.
284 for (rcode
=0; rcode
<50; rcode
++) {
285 ret
= ldb_kv
->kv_ops
->fetch_and_parse(ldb_kv
, key
,
288 assert_int_equal(ret
, rcode
);
291 ret
= ldb_kv
->kv_ops
->unlock_read(test_ctx
->ldb
->modules
);
292 assert_int_equal(ret
, 0);
293 talloc_free(tmp_ctx
);
297 * Test that attempts to read data without a read transaction fail.
299 static void test_read_outside_transaction(void **state
)
302 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
304 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
305 uint8_t key_val
[] = "TheKey";
306 struct ldb_val key
= {
308 .length
= sizeof(key_val
)
311 uint8_t value
[] = "The record contents";
312 struct ldb_val data
= {
314 .length
= sizeof(value
)
322 tmp_ctx
= talloc_new(test_ctx
);
323 assert_non_null(tmp_ctx
);
326 * Begin a transaction
328 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
329 assert_int_equal(ret
, 0);
334 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
335 assert_int_equal(ret
, 0);
338 * Commit the transaction
340 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
341 assert_int_equal(ret
, 0);
344 * And now read it back
345 * Note there is no read transaction active
347 ret
= ldb_kv
->kv_ops
->fetch_and_parse(ldb_kv
, key
, parse
, &read
);
348 assert_int_equal(ret
, LDB_ERR_PROTOCOL_ERROR
);
350 talloc_free(tmp_ctx
);
354 * Test that data can be deleted from the kv store
356 static void test_delete(void **state
)
359 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
361 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
362 uint8_t key_val
[] = "TheKey";
363 struct ldb_val key
= {
365 .length
= sizeof(key_val
)
368 uint8_t value
[] = "The record contents";
369 struct ldb_val data
= {
371 .length
= sizeof(value
)
379 tmp_ctx
= talloc_new(test_ctx
);
380 assert_non_null(tmp_ctx
);
383 * Begin a transaction
385 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
386 assert_int_equal(ret
, 0);
391 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
392 assert_int_equal(ret
, 0);
395 * Commit the transaction
397 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
398 assert_int_equal(ret
, 0);
401 * And now read it back
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);
413 * Begin a transaction
415 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
416 assert_int_equal(ret
, 0);
421 ret
= ldb_kv
->kv_ops
->delete (ldb_kv
, key
);
422 assert_int_equal(ret
, 0);
425 * Commit the transaction
427 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
428 assert_int_equal(ret
, 0);
431 * And now try to read it back
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);
440 talloc_free(tmp_ctx
);
444 * Check that writes are correctly rolled back when a transaction
447 static void test_transaction_abort_write(void **state
)
450 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
452 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
453 uint8_t key_val
[] = "TheKey";
454 struct ldb_val key
= {
456 .length
= sizeof(key_val
)
459 uint8_t value
[] = "The record contents";
460 struct ldb_val data
= {
462 .length
= sizeof(value
)
470 tmp_ctx
= talloc_new(test_ctx
);
471 assert_non_null(tmp_ctx
);
474 * Begin a transaction
476 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
477 assert_int_equal(ret
, 0);
482 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
483 assert_int_equal(ret
, 0);
486 * And now read it back
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
));
495 * Now abort the transaction
497 ret
= ldb_kv
->kv_ops
->abort_write(ldb_kv
);
498 assert_int_equal(ret
, 0);
501 * And now read it back, should not be there
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);
510 talloc_free(tmp_ctx
);
514 * Check that deletes are correctly rolled back when a transaction is
517 static void test_transaction_abort_delete(void **state
)
520 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
522 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
523 uint8_t key_val
[] = "TheKey";
524 struct ldb_val key
= {
526 .length
= sizeof(key_val
)
529 uint8_t value
[] = "The record contents";
530 struct ldb_val data
= {
532 .length
= sizeof(value
)
540 tmp_ctx
= talloc_new(test_ctx
);
541 assert_non_null(tmp_ctx
);
544 * Begin a transaction
546 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
547 assert_int_equal(ret
, 0);
552 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
553 assert_int_equal(ret
, 0);
556 * Commit the transaction
558 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
559 assert_int_equal(ret
, 0);
562 * And now read it back
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);
574 * Begin a transaction
576 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
577 assert_int_equal(ret
, 0);
582 ret
= ldb_kv
->kv_ops
->delete (ldb_kv
, key
);
583 assert_int_equal(ret
, 0);
586 * And now read it back
588 ret
= ldb_kv
->kv_ops
->fetch_and_parse(ldb_kv
, key
, parse
, &read
);
589 assert_int_equal(ret
, LDB_ERR_NO_SUCH_OBJECT
);
592 * Abort the transaction
594 ret
= ldb_kv
->kv_ops
->abort_write(ldb_kv
);
595 assert_int_equal(ret
, 0);
598 * And now try to read it back
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);
609 talloc_free(tmp_ctx
);
613 * Test that writes outside a transaction fail
615 static void test_write_outside_transaction(void **state
)
618 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
620 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
621 uint8_t key_val
[] = "TheKey";
622 struct ldb_val key
= {
624 .length
= sizeof(key_val
)
627 uint8_t value
[] = "The record contents";
628 struct ldb_val data
= {
630 .length
= sizeof(value
)
637 tmp_ctx
= talloc_new(test_ctx
);
638 assert_non_null(tmp_ctx
);
641 * Attempt to write the record
643 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
644 assert_int_equal(ret
, LDB_ERR_PROTOCOL_ERROR
);
646 talloc_free(tmp_ctx
);
650 * Test data can not be deleted outside a transaction
652 static void test_delete_outside_transaction(void **state
)
655 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
657 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
658 uint8_t key_val
[] = "TheKey";
659 struct ldb_val key
= {
661 .length
= sizeof(key_val
)
664 uint8_t value
[] = "The record contents";
665 struct ldb_val data
= {
667 .length
= sizeof(value
)
675 tmp_ctx
= talloc_new(test_ctx
);
676 assert_non_null(tmp_ctx
);
679 * Begin a transaction
681 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
682 assert_int_equal(ret
, 0);
687 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
688 assert_int_equal(ret
, 0);
691 * Commit the transaction
693 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
694 assert_int_equal(ret
, 0);
697 * And now read it back
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);
709 * Now attempt to delete a record
711 ret
= ldb_kv
->kv_ops
->delete (ldb_kv
, key
);
712 assert_int_equal(ret
, LDB_ERR_PROTOCOL_ERROR
);
715 * And now read it back
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);
726 talloc_free(tmp_ctx
);
729 static int traverse_fn(struct ldb_kv_private
*ldb_kv
,
738 if (strncmp("key ", (char *) key
.data
, 4) == 0) {
739 i
= strtol((char *) &key
.data
[4], NULL
, 10);
746 * Test that iterate visits all the records.
748 static void test_iterate(void **state
)
751 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
753 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
756 int visits
[num_recs
];
760 tmp_ctx
= talloc_new(test_ctx
);
761 assert_non_null(tmp_ctx
);
764 * Begin a transaction
766 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
767 assert_int_equal(ret
, 0);
772 for (i
= 0; i
< num_recs
; i
++) {
778 key
.data
= (uint8_t *)talloc_asprintf(tmp_ctx
, "key %04d", i
);
779 key
.length
= strlen((char *)key
.data
) + 1;
781 rec
.data
= (uint8_t *) talloc_asprintf(tmp_ctx
,
782 "data for record (%04d)",
784 rec
.length
= strlen((char *)rec
.data
) + 1;
786 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, rec
, flags
);
787 assert_int_equal(ret
, 0);
789 TALLOC_FREE(key
.data
);
790 TALLOC_FREE(rec
.data
);
794 * Commit the transaction
796 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
797 assert_int_equal(ret
, 0);
800 * Now iterate over the kv store and ensure that all the
801 * records are visited.
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
]);
809 ret
= ldb_kv
->kv_ops
->unlock_read(test_ctx
->ldb
->modules
);
810 assert_int_equal(ret
, 0);
812 TALLOC_FREE(tmp_ctx
);
815 static void do_iterate_range_test(void **state
, int range_start
,
816 int range_end
, bool fail
)
819 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
821 struct ldb_kv_private
*ldb_kv
= NULL
;
825 int visits
[num_recs
];
826 struct ldb_val sk
, ek
;
830 ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
831 assert_non_null(ldb_kv
);
833 for (i
= 0; i
< num_recs
; i
++){
838 * No iterate_range on tdb
840 if (strcmp(TEST_BE
, "tdb") == 0) {
844 tmp_ctx
= talloc_new(test_ctx
);
845 assert_non_null(tmp_ctx
);
848 * Begin a transaction
850 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
851 assert_int_equal(ret
, 0);
856 for (i
= skip_recs
; i
<= num_recs
- skip_recs
; i
++) {
861 key
.data
= (uint8_t *)talloc_asprintf(tmp_ctx
,
864 key
.length
= strlen((char *)key
.data
);
866 rec
.data
= (uint8_t *)talloc_asprintf(tmp_ctx
,
867 "data for record (%04d)",
869 rec
.length
= strlen((char *)rec
.data
) + 1;
871 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, rec
, flags
);
872 assert_int_equal(ret
, 0);
874 TALLOC_FREE(key
.data
);
875 TALLOC_FREE(rec
.data
);
879 * Commit the transaction
881 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
882 assert_int_equal(ret
, 0);
884 sk
.data
= (uint8_t *)talloc_asprintf(tmp_ctx
, "key %04d", range_start
);
885 sk
.length
= strlen((char *)sk
.data
);
887 ek
.data
= (uint8_t *)talloc_asprintf(tmp_ctx
, "key %04d", range_end
);
888 ek
.length
= strlen((char *)ek
.data
) + 1;
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
);
895 assert_int_equal(ret
, LDB_ERR_PROTOCOL_ERROR
);
896 TALLOC_FREE(tmp_ctx
);
899 assert_int_equal(ret
, 0);
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
]);
906 assert_int_equal(0, visits
[i
]);
910 ret
= ldb_kv
->kv_ops
->unlock_read(test_ctx
->ldb
->modules
);
911 assert_int_equal(ret
, 0);
913 TALLOC_FREE(tmp_ctx
);
917 * Test that iterate_range visits all the records between two keys.
919 static void test_iterate_range(void **state
)
921 do_iterate_range_test(state
, 300, 900, false);
924 * test start_key = end_key
926 do_iterate_range_test(state
, 20, 20, false);
929 * test reverse range fails
931 do_iterate_range_test(state
, 50, 40, true);
934 * keys are between 10-1014 so test with keys outside that range
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);
941 struct update_context
{
942 struct ldb_context
* ldb
;
943 int visits
[NUM_RECS
];
946 static int update_fn(struct ldb_kv_private
*ldb_kv
,
952 struct ldb_val new_key
;
953 struct ldb_module
*module
= NULL
;
954 struct update_context
*context
=NULL
;
955 int ret
= LDB_SUCCESS
;
958 tmp_ctx
= talloc_new(ldb_kv
);
959 assert_non_null(tmp_ctx
);
961 context
= talloc_get_type_abort(ctx
, struct update_context
);
963 module
= talloc_zero(tmp_ctx
, struct ldb_module
);
964 module
->ldb
= context
->ldb
;
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';
973 ret
= ldb_kv
->kv_ops
->update_in_iterate(
974 ldb_kv
, key
, new_key
, data
, &module
);
976 TALLOC_FREE(tmp_ctx
);
981 * Test that update_in_iterate behaves as expected.
983 static void test_update_in_iterate(void **state
)
986 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
988 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
990 struct update_context
*context
= NULL
;
995 tmp_ctx
= talloc_new(test_ctx
);
996 assert_non_null(tmp_ctx
);
998 context
= talloc_zero(tmp_ctx
, struct update_context
);
999 assert_non_null(context
);
1000 context
->ldb
= test_ctx
->ldb
;
1002 * Begin a transaction
1004 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
1005 assert_int_equal(ret
, 0);
1010 for (i
= 0; i
< NUM_RECS
; i
++) {
1015 key
.data
= (uint8_t *)talloc_asprintf(tmp_ctx
, "key %04d", i
);
1016 key
.length
= strlen((char *)key
.data
) + 1;
1018 rec
.data
= (uint8_t *) talloc_asprintf(tmp_ctx
,
1019 "data for record (%04d)",
1021 rec
.length
= strlen((char *)rec
.data
) + 1;
1023 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, rec
, flags
);
1024 assert_int_equal(ret
, 0);
1026 TALLOC_FREE(key
.data
);
1027 TALLOC_FREE(rec
.data
);
1031 * Commit the transaction
1033 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
1034 assert_int_equal(ret
, 0);
1037 * Now iterate over the kv store and ensure that all the
1038 * records are visited.
1042 * Needs to be done inside a transaction
1044 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
1045 assert_int_equal(ret
, 0);
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
]);
1052 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
1053 assert_int_equal(ret
, 0);
1055 TALLOC_FREE(tmp_ctx
);
1059 * Ensure that writes are not visible until the transaction has been
1062 static void test_write_transaction_isolation(void **state
)
1065 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
1067 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
1071 const char *KEY1
= "KEY01";
1072 const char *VAL1
= "VALUE01";
1074 const char *KEY2
= "KEY02";
1075 const char *VAL2
= "VALUE02";
1078 * Pipes etc to coordinate the processes
1086 TALLOC_CTX
*tmp_ctx
;
1087 tmp_ctx
= talloc_new(test_ctx
);
1088 assert_non_null(tmp_ctx
);
1092 * Add a record to the database
1094 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
1095 assert_int_equal(ret
, 0);
1097 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY1
);
1098 key
.length
= strlen(KEY1
) + 1;
1100 val
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, VAL1
);
1101 val
.length
= strlen(VAL1
) + 1;
1103 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, val
, 0);
1104 assert_int_equal(ret
, 0);
1106 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
1107 assert_int_equal(ret
, 0);
1110 ret
= pipe(to_child
);
1111 assert_int_equal(ret
, 0);
1112 ret
= pipe(to_parent
);
1113 assert_int_equal(ret
, 0);
1115 * Now fork a new process
1121 struct ldb_context
*ldb
= NULL
;
1123 close(to_parent
[0]);
1126 * Wait for the transaction to start
1128 ret
= read(to_child
[0], buf
, 2);
1130 print_error(__location__
": read returned (%d)\n",
1132 exit(LDB_ERR_OPERATIONS_ERROR
);
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",
1142 ldb_kv
= get_ldb_kv(ldb
);
1144 ret
= ldb_kv
->kv_ops
->lock_read(ldb
->modules
);
1145 if (ret
!= LDB_SUCCESS
) {
1146 print_error(__location__
": lock_read returned (%d)\n",
1152 * Check that KEY1 is there
1154 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY1
);
1155 key
.length
= strlen(KEY1
) + 1;
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 "
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
);
1171 if (memcmp(VAL1
, val
.data
, strlen(VAL1
)) != 0) {
1172 print_error(__location__
": KEY1 values different, "
1173 "expected (%s) actual(%s)\n",
1176 exit(LDB_ERR_OPERATIONS_ERROR
);
1179 ret
= ldb_kv
->kv_ops
->unlock_read(ldb
->modules
);
1180 if (ret
!= LDB_SUCCESS
) {
1181 print_error(__location__
": unlock_read returned (%d)\n",
1187 * Check that KEY2 is not there
1189 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY2
);
1190 key
.length
= strlen(KEY2
+ 1);
1192 ret
= ldb_kv
->kv_ops
->lock_read(ldb
->modules
);
1193 if (ret
!= LDB_SUCCESS
) {
1194 print_error(__location__
": lock_read returned (%d)\n",
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 "
1207 ret
= ldb_kv
->kv_ops
->unlock_read(ldb
->modules
);
1208 if (ret
!= LDB_SUCCESS
) {
1209 print_error(__location__
": unlock_read returned (%d)\n",
1215 * Signal the other process to commit the transaction
1217 ret
= write(to_parent
[1], "GO", 2);
1219 print_error(__location__
": write returned (%d)\n",
1221 exit(LDB_ERR_OPERATIONS_ERROR
);
1225 * Wait for the transaction to be committed
1227 ret
= read(to_child
[0], buf
, 2);
1229 print_error(__location__
": read returned (%d)\n",
1231 exit(LDB_ERR_OPERATIONS_ERROR
);
1235 * Check that KEY1 is there
1237 ret
= ldb_kv
->kv_ops
->lock_read(ldb
->modules
);
1238 if (ret
!= LDB_SUCCESS
) {
1239 print_error(__location__
": unlock_read returned (%d)\n",
1243 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY1
);
1244 key
.length
= strlen(KEY1
) + 1;
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 "
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
);
1260 if (memcmp(VAL1
, val
.data
, strlen(VAL1
)) != 0) {
1261 print_error(__location__
": KEY1 values different, "
1262 "expected (%s) actual(%s)\n",
1265 exit(LDB_ERR_OPERATIONS_ERROR
);
1268 ret
= ldb_kv
->kv_ops
->unlock_read(ldb
->modules
);
1269 if (ret
!= LDB_SUCCESS
) {
1270 print_error(__location__
": unlock_read returned (%d)\n",
1277 * Check that KEY2 is there
1279 ret
= ldb_kv
->kv_ops
->lock_read(ldb
->modules
);
1280 if (ret
!= LDB_SUCCESS
) {
1281 print_error(__location__
": unlock_read returned (%d)\n",
1286 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY2
);
1287 key
.length
= strlen(KEY2
) + 1;
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 "
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
);
1303 if (memcmp(VAL2
, val
.data
, strlen(VAL2
)) != 0) {
1304 print_error(__location__
": KEY2 values different, "
1305 "expected (%s) actual(%s)\n",
1308 exit(LDB_ERR_OPERATIONS_ERROR
);
1311 ret
= ldb_kv
->kv_ops
->unlock_read(ldb
->modules
);
1312 if (ret
!= LDB_SUCCESS
) {
1313 print_error(__location__
": unlock_read returned (%d)\n",
1321 close(to_parent
[1]);
1324 * Begin a transaction and add a record to the database
1325 * but leave the transaction open
1327 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
1328 assert_int_equal(ret
, 0);
1330 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY2
);
1331 key
.length
= strlen(KEY2
) + 1;
1333 val
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, VAL2
);
1334 val
.length
= strlen(VAL2
) + 1;
1336 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, val
, 0);
1337 assert_int_equal(ret
, 0);
1340 * Signal the child process
1342 ret
= write(to_child
[1], "GO", 2);
1343 assert_int_equal(2, ret
);
1346 * Wait for the child process to check the DB state while the
1347 * transaction is active
1349 ret
= read(to_parent
[0], buf
, 2);
1350 assert_int_equal(2, ret
);
1353 * commit the transaction
1355 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
1356 assert_int_equal(0, ret
);
1359 * Signal the child process
1361 ret
= write(to_child
[1], "GO", 2);
1362 assert_int_equal(2, ret
);
1364 w_pid
= waitpid(pid
, &wstatus
, 0);
1365 assert_int_equal(pid
, w_pid
);
1367 assert_true(WIFEXITED(wstatus
));
1369 assert_int_equal(WEXITSTATUS(wstatus
), 0);
1372 TALLOC_FREE(tmp_ctx
);
1376 * Ensure that deletes are not visible until the transaction has been
1379 static void test_delete_transaction_isolation(void **state
)
1382 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
1384 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
1388 const char *KEY1
= "KEY01";
1389 const char *VAL1
= "VALUE01";
1391 const char *KEY2
= "KEY02";
1392 const char *VAL2
= "VALUE02";
1395 * Pipes etc to coordinate the processes
1403 TALLOC_CTX
*tmp_ctx
;
1404 tmp_ctx
= talloc_new(test_ctx
);
1405 assert_non_null(tmp_ctx
);
1409 * Add records to the database
1411 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
1412 assert_int_equal(ret
, 0);
1414 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY1
);
1415 key
.length
= strlen(KEY1
) + 1;
1417 val
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, VAL1
);
1418 val
.length
= strlen(VAL1
) + 1;
1420 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, val
, 0);
1421 assert_int_equal(ret
, 0);
1423 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY2
);
1424 key
.length
= strlen(KEY2
) + 1;
1426 val
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, VAL2
);
1427 val
.length
= strlen(VAL2
) + 1;
1429 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, val
, 0);
1430 assert_int_equal(ret
, 0);
1432 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
1433 assert_int_equal(ret
, 0);
1436 ret
= pipe(to_child
);
1437 assert_int_equal(ret
, 0);
1438 ret
= pipe(to_parent
);
1439 assert_int_equal(ret
, 0);
1441 * Now fork a new process
1447 struct ldb_context
*ldb
= NULL
;
1449 close(to_parent
[0]);
1452 * Wait for the transaction to be started
1454 ret
= read(to_child
[0], buf
, 2);
1456 print_error(__location__
": read returned (%d)\n",
1458 exit(LDB_ERR_OPERATIONS_ERROR
);
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",
1469 ldb_kv
= get_ldb_kv(ldb
);
1471 ret
= ldb_kv
->kv_ops
->lock_read(ldb
->modules
);
1472 if (ret
!= LDB_SUCCESS
) {
1473 print_error(__location__
": lock_read returned (%d)\n",
1479 * Check that KEY1 is there
1481 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY1
);
1482 key
.length
= strlen(KEY1
) + 1;
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 "
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
);
1498 if (memcmp(VAL1
, val
.data
, strlen(VAL1
)) != 0) {
1499 print_error(__location__
": KEY1 values different, "
1500 "expected (%s) actual(%s)\n",
1503 exit(LDB_ERR_OPERATIONS_ERROR
);
1507 * Check that KEY2 is there
1510 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY2
);
1511 key
.length
= strlen(KEY2
) + 1;
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 "
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
);
1527 if (memcmp(VAL2
, val
.data
, strlen(VAL2
)) != 0) {
1528 print_error(__location__
": KEY2 values different, "
1529 "expected (%s) actual(%s)\n",
1532 exit(LDB_ERR_OPERATIONS_ERROR
);
1535 ret
= ldb_kv
->kv_ops
->unlock_read(ldb
->modules
);
1536 if (ret
!= LDB_SUCCESS
) {
1537 print_error(__location__
": unlock_read returned (%d)\n",
1543 * Signal the other process to commit the transaction
1545 ret
= write(to_parent
[1], "GO", 2);
1547 print_error(__location__
": write returned (%d)\n",
1549 exit(LDB_ERR_OPERATIONS_ERROR
);
1553 * Wait for the transaction to be committed
1555 ret
= read(to_child
[0], buf
, 2);
1557 print_error(__location__
": read returned (%d)\n",
1559 exit(LDB_ERR_OPERATIONS_ERROR
);
1563 * Check that KEY1 is there
1565 ret
= ldb_kv
->kv_ops
->lock_read(ldb
->modules
);
1566 if (ret
!= LDB_SUCCESS
) {
1567 print_error(__location__
": unlock_read returned (%d)\n",
1571 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY1
);
1572 key
.length
= strlen(KEY1
) + 1;
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 "
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
);
1588 if (memcmp(VAL1
, val
.data
, strlen(VAL1
)) != 0) {
1589 print_error(__location__
": KEY1 values different, "
1590 "expected (%s) actual(%s)\n",
1593 exit(LDB_ERR_OPERATIONS_ERROR
);
1595 ret
= ldb_kv
->kv_ops
->unlock_read(ldb
->modules
);
1596 if (ret
!= LDB_SUCCESS
) {
1597 print_error(__location__
": unlock_read returned (%d)\n",
1603 * Check that KEY2 is not there
1605 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY2
);
1606 key
.length
= strlen(KEY2
+ 1);
1608 ret
= ldb_kv
->kv_ops
->lock_read(ldb
->modules
);
1609 if (ret
!= LDB_SUCCESS
) {
1610 print_error(__location__
": lock_read returned (%d)\n",
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 "
1623 ret
= ldb_kv
->kv_ops
->unlock_read(ldb
->modules
);
1624 if (ret
!= LDB_SUCCESS
) {
1625 print_error(__location__
": unlock_read returned (%d)\n",
1629 TALLOC_FREE(tmp_ctx
);
1633 close(to_parent
[1]);
1636 * Begin a transaction and delete a record from the database
1637 * but leave the transaction open
1639 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
1640 assert_int_equal(ret
, 0);
1642 key
.data
= (uint8_t *)talloc_strdup(tmp_ctx
, KEY2
);
1643 key
.length
= strlen(KEY2
) + 1;
1645 ret
= ldb_kv
->kv_ops
->delete (ldb_kv
, key
);
1646 assert_int_equal(ret
, 0);
1648 * Signal the child process
1650 ret
= write(to_child
[1], "GO", 2);
1651 assert_int_equal(2, ret
);
1654 * Wait for the child process to check the DB state while the
1655 * transaction is active
1657 ret
= read(to_parent
[0], buf
, 2);
1658 assert_int_equal(2, ret
);
1661 * commit the transaction
1663 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
1664 assert_int_equal(0, ret
);
1667 * Signal the child process
1669 ret
= write(to_child
[1], "GO", 2);
1670 assert_int_equal(2, ret
);
1672 w_pid
= waitpid(pid
, &wstatus
, 0);
1673 assert_int_equal(pid
, w_pid
);
1675 assert_true(WIFEXITED(wstatus
));
1677 assert_int_equal(WEXITSTATUS(wstatus
), 0);
1680 TALLOC_FREE(tmp_ctx
);
1685 * Test that get_size returns a sensible estimate of the number of records
1688 static void test_get_size(void **state
)
1691 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
1693 struct ldb_kv_private
*ldb_kv
= get_ldb_kv(test_ctx
->ldb
);
1694 uint8_t key_val
[] = "TheKey";
1695 struct ldb_val key
= {
1697 .length
= sizeof(key_val
)
1700 uint8_t value
[] = "The record contents";
1701 struct ldb_val data
= {
1703 .length
= sizeof(value
)
1708 TALLOC_CTX
*tmp_ctx
;
1710 tmp_ctx
= talloc_new(test_ctx
);
1711 assert_non_null(tmp_ctx
);
1713 size
= ldb_kv
->kv_ops
->get_size(ldb_kv
);
1714 #if defined(TEST_LMDB)
1715 assert_int_equal(2, size
);
1718 * The tdb implementation of get_size over estimates for sparse files
1719 * which is perfectly acceptable for it's intended use.
1720 * mipsel, ia64: 9994
1721 * ppc64el, powerpc, ppc64: 13369
1724 assert_in_range(size
, 2500, 15000);
1728 * Begin a transaction
1730 ret
= ldb_kv
->kv_ops
->begin_write(ldb_kv
);
1731 assert_int_equal(ret
, 0);
1736 ret
= ldb_kv
->kv_ops
->store(ldb_kv
, key
, data
, flags
);
1737 assert_int_equal(ret
, 0);
1740 * Commit the transaction
1742 ret
= ldb_kv
->kv_ops
->finish_write(ldb_kv
);
1743 assert_int_equal(ret
, 0);
1745 size
= ldb_kv
->kv_ops
->get_size(ldb_kv
);
1747 assert_int_equal(3, size
);
1750 * The tdb implementation of get_size over estimates for sparse files
1751 * which is perfectly acceptable for it's intended use.
1752 * mipsel, ia64: 9994
1753 * ppc64el, powerpc, ppc64: 13369
1756 assert_in_range(size
, 2500, 15000);
1758 talloc_free(tmp_ctx
);
1761 int main(int argc
, const char **argv
)
1763 const struct CMUnitTest tests
[] = {
1764 cmocka_unit_test_setup_teardown(
1768 cmocka_unit_test_setup_teardown(
1772 cmocka_unit_test_setup_teardown(
1773 test_transaction_abort_write
,
1776 cmocka_unit_test_setup_teardown(
1777 test_transaction_abort_delete
,
1780 cmocka_unit_test_setup_teardown(
1781 test_read_outside_transaction
,
1784 cmocka_unit_test_setup_teardown(
1785 test_write_outside_transaction
,
1788 cmocka_unit_test_setup_teardown(
1789 test_delete_outside_transaction
,
1792 cmocka_unit_test_setup_teardown(
1796 cmocka_unit_test_setup_teardown(
1800 cmocka_unit_test_setup_teardown(
1801 test_update_in_iterate
,
1804 cmocka_unit_test_setup_teardown(
1805 test_write_transaction_isolation
,
1808 cmocka_unit_test_setup_teardown(
1809 test_delete_transaction_isolation
,
1812 cmocka_unit_test_setup_teardown(
1818 cmocka_set_message_output(CM_OUTPUT_SUBUNIT
);
1820 return cmocka_run_group_tests(tests
, NULL
, NULL
);