ctdb-daemon: Use ctdb_parse_node_address() in ctdbd
[samba4-gss.git] / lib / ldb / tests / ldb_lmdb_size_test.c
blob95eba878ba73b772a165c3d1af4659725c3dd574
1 /*
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
25 * self test runs.
27 * Setup and tear down code copied from ldb_mod_op_test.c
31 * from cmocka.c:
32 * These headers or their equivalents should be included prior to
33 * including
34 * this header file.
36 * #include <stdarg.h>
37 * #include <stddef.h>
38 * #include <setjmp.h>
40 * This allows test applications to use custom definitions of C standard
41 * library functions and types.
44 #include <stdarg.h>
45 #include <stddef.h>
46 #include <stdint.h>
47 #include <setjmp.h>
48 #include <cmocka.h>
50 #include <errno.h>
51 #include <unistd.h>
52 #include <talloc.h>
53 #include <tevent.h>
54 #include <ldb.h>
55 #include <ldb_module.h>
56 #include <ldb_private.h>
57 #include <string.h>
58 #include <ctype.h>
60 #include <sys/wait.h>
62 #include <lmdb.h>
65 #define TEST_BE "mdb"
67 struct ldbtest_ctx {
68 struct tevent_context *ev;
69 struct ldb_context *ldb;
71 const char *dbfile;
72 const char *lockfile; /* lockfile is separate */
74 const char *dbpath;
77 static void unlink_old_db(struct ldbtest_ctx *test_ctx)
79 int ret;
81 errno = 0;
82 ret = unlink(test_ctx->lockfile);
83 if (ret == -1 && errno != ENOENT) {
84 fail();
87 errno = 0;
88 ret = unlink(test_ctx->dbfile);
89 if (ret == -1 && errno != ENOENT) {
90 fail();
94 static int ldbtest_noconn_setup(void **state)
96 struct ldbtest_ctx *test_ctx;
98 test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
99 assert_non_null(test_ctx);
101 test_ctx->ev = tevent_context_init(test_ctx);
102 assert_non_null(test_ctx->ev);
104 test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
105 assert_non_null(test_ctx->ldb);
107 test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
108 assert_non_null(test_ctx->dbfile);
110 test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
111 test_ctx->dbfile);
112 assert_non_null(test_ctx->lockfile);
114 test_ctx->dbpath = talloc_asprintf(test_ctx,
115 TEST_BE"://%s", test_ctx->dbfile);
116 assert_non_null(test_ctx->dbpath);
118 unlink_old_db(test_ctx);
119 *state = test_ctx;
120 return 0;
123 static int ldbtest_noconn_teardown(void **state)
125 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
126 struct ldbtest_ctx);
128 unlink_old_db(test_ctx);
129 talloc_free(test_ctx);
130 return 0;
133 static int ldbtest_setup(void **state)
135 struct ldbtest_ctx *test_ctx;
136 int ret;
138 * We need to to set GUID index mode as it's required now required
139 * by LDB
141 struct ldb_ldif *ldif;
142 const char *index_ldif =
143 "dn: @INDEXLIST\n"
144 "@IDXGUID: objectUUID\n"
145 "@IDX_DN_GUID: GUID\n"
146 "\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);
163 *state = test_ctx;
164 return 0;
167 static int ldbtest_teardown(void **state)
169 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
170 struct ldbtest_ctx);
171 ldbtest_noconn_teardown((void **) &test_ctx);
172 return 0;
175 static void test_db_size_gt_4GB(void **state)
177 int ret, x;
178 struct ldb_message *msg;
179 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
180 struct ldbtest_ctx);
181 const int MB = 1024 * 1024;
182 char *blob = NULL;
184 TALLOC_CTX *tmp_ctx;
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
197 * 4GiB of disk space
199 for (x = 0; x < 6144; x++) {
200 char uuid[24];
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);
225 TALLOC_FREE(msg);
227 talloc_free(tmp_ctx);
229 struct stat s;
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(
243 test_db_size_gt_4GB,
244 ldbtest_setup,
245 ldbtest_teardown),
248 return cmocka_run_group_tests(tests, NULL, NULL);