2 * lmdb backend specific tests for ldb
3 * Tests for truncated index keys
5 * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * These tests confirm that database sizes of > 4GB are supported
24 * Due to the disk space requirement they are not run as part of the normal
27 * Setup and tear down code copied from ldb_mod_op_test.c
32 * These headers or their equivalents should be included prior to
40 * This allows test applications to use custom definitions of C standard
41 * library functions and types.
55 #include <ldb_module.h>
56 #include <ldb_private.h>
68 struct tevent_context
*ev
;
69 struct ldb_context
*ldb
;
72 const char *lockfile
; /* lockfile is separate */
77 static void unlink_old_db(struct ldbtest_ctx
*test_ctx
)
82 ret
= unlink(test_ctx
->lockfile
);
83 if (ret
== -1 && errno
!= ENOENT
) {
88 ret
= unlink(test_ctx
->dbfile
);
89 if (ret
== -1 && errno
!= ENOENT
) {
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",
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
);
123 static int ldbtest_noconn_teardown(void **state
)
125 struct ldbtest_ctx
*test_ctx
= talloc_get_type_abort(*state
,
128 unlink_old_db(test_ctx
);
129 talloc_free(test_ctx
);
133 static int ldbtest_setup(void **state
)
135 struct ldbtest_ctx
*test_ctx
;
138 * We need to to set GUID index mode as it's required now required
141 struct ldb_ldif
*ldif
;
142 const char *index_ldif
=
144 "@IDXGUID: objectUUID\n"
145 "@IDX_DN_GUID: GUID\n"
148 * Set the lmdb map size to 8Gb
150 const char *options
[] = {"lmdb_env_size:8589934592", NULL
};
152 ldbtest_noconn_setup((void **) &test_ctx
);
155 ret
= ldb_connect(test_ctx
->ldb
, test_ctx
->dbpath
, 0, options
);
156 assert_int_equal(ret
, 0);
158 while ((ldif
= ldb_ldif_read_string(test_ctx
->ldb
, &index_ldif
))) {
159 ret
= ldb_add(test_ctx
->ldb
, ldif
->msg
);
160 assert_int_equal(ret
, LDB_SUCCESS
);
167 static int ldbtest_teardown(void **state
)
169 struct ldbtest_ctx
*test_ctx
= talloc_get_type_abort(*state
,
171 ldbtest_noconn_teardown((void **) &test_ctx
);
175 static void test_db_size_gt_4GB(void **state
)
178 struct ldb_message
*msg
;
179 struct ldbtest_ctx
*test_ctx
= talloc_get_type_abort(*state
,
181 const int MB
= 1024 * 1024;
186 tmp_ctx
= talloc_new(test_ctx
);
187 assert_non_null(tmp_ctx
);
190 blob
= talloc_zero_size(tmp_ctx
, (MB
+ 1));
191 assert_non_null(blob
);
192 memset(blob
, 'x', MB
);
196 * Write 6144 1Mb records to the database, this will require more than
199 for (x
= 0; x
< 6144; x
++) {
201 msg
= ldb_msg_new(tmp_ctx
);
202 assert_non_null(msg
);
205 * Generate a unique dn for each record
207 msg
->dn
= ldb_dn_new_fmt(msg
, test_ctx
->ldb
, "dc=test%d", x
);
208 assert_non_null(msg
->dn
);
211 * Generate a unique uuid for each added record
213 sprintf(uuid
, "000000000000%04d", x
);
214 ret
= ldb_msg_add_string(msg
, "objectUUID", uuid
);
215 assert_int_equal(ret
, 0);
217 ldb_transaction_start(test_ctx
->ldb
);
218 ret
= ldb_msg_add_string(msg
, "blob", blob
);
219 assert_int_equal(ret
, 0);
221 ret
= ldb_add(test_ctx
->ldb
, msg
);
222 assert_int_equal(ret
, 0);
223 ldb_transaction_commit(test_ctx
->ldb
);
227 talloc_free(tmp_ctx
);
230 ret
= stat(test_ctx
->dbfile
, &s
);
231 assert_int_equal(ret
, 0);
233 * There should have been at least 6GiB written to disk
235 assert_true(s
.st_size
> (6144LL * MB
));
239 int main(int argc
, const char **argv
)
241 const struct CMUnitTest tests
[] = {
242 cmocka_unit_test_setup_teardown(
248 return cmocka_run_group_tests(tests
, NULL
, NULL
);