Line data Source code
1 : /*
2 : * Tests exercising the ldb key value operations.
3 : *
4 : * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2019
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 : *
38 : * Tests for the ldb key value layer
39 : */
40 : #include <stdarg.h>
41 : #include <stddef.h>
42 : #include <stdint.h>
43 : #include <setjmp.h>
44 : #include <cmocka.h>
45 :
46 : #include <errno.h>
47 : #include <unistd.h>
48 : #include <talloc.h>
49 : #include <tevent.h>
50 : #include <string.h>
51 : #include <ctype.h>
52 :
53 : #include <sys/wait.h>
54 :
55 : #include "ldb_key_value/ldb_kv.c"
56 : #include "ldb_key_value/ldb_kv_index.c"
57 : #include "ldb_key_value/ldb_kv_search.c"
58 :
59 : #define DEFAULT_BE "tdb"
60 :
61 : #ifndef TEST_BE
62 : #define TEST_BE DEFAULT_BE
63 : #endif /* TEST_BE */
64 :
65 : #define NUM_RECS 1024
66 2 : int ldb_kv_cache_reload(struct ldb_module *module) {
67 2 : return LDB_SUCCESS;
68 : }
69 4 : int ldb_kv_cache_load(struct ldb_module *module) {
70 4 : return LDB_SUCCESS;
71 : }
72 0 : int ldb_kv_check_at_attributes_values(const struct ldb_val *value) {
73 0 : return LDB_SUCCESS;
74 : }
75 0 : int ldb_kv_increase_sequence_number(struct ldb_module *module) {
76 0 : return LDB_SUCCESS;
77 : }
78 :
79 : struct test_ctx { uint8_t dummy; };
80 :
81 7 : static int setup(void **state)
82 : {
83 7 : struct test_ctx *test_ctx;
84 :
85 7 : test_ctx = talloc_zero(NULL, struct test_ctx);
86 7 : *state = test_ctx;
87 7 : return 0;
88 : }
89 :
90 7 : static int teardown(void **state)
91 : {
92 7 : struct test_ctx *test_ctx = talloc_get_type_abort(*state,
93 : struct test_ctx);
94 :
95 7 : talloc_free(test_ctx);
96 7 : return 0;
97 : }
98 :
99 : /*
100 : * Test that the index cache is opened by ldb_kv_index_transaction_start
101 : * and correctly initialised with the passed index cache size.
102 : */
103 1 : static void test_index_cache_init(void **state)
104 : {
105 1 : struct test_ctx *test_ctx = talloc_get_type_abort(
106 : *state,
107 : struct test_ctx);
108 1 : struct ldb_module *module = NULL;
109 1 : struct ldb_kv_private *ldb_kv = NULL;
110 1 : int ret = LDB_SUCCESS;
111 :
112 1 : module = talloc_zero(test_ctx, struct ldb_module);
113 1 : ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private);
114 1 : ldb_module_set_private(module, ldb_kv);
115 :
116 1 : ret = ldb_kv_index_transaction_start(module, 191);
117 1 : assert_int_equal(LDB_SUCCESS, ret);
118 :
119 1 : assert_non_null(ldb_kv->idxptr);
120 1 : assert_non_null(ldb_kv->idxptr->itdb);
121 1 : assert_int_equal(191, tdb_hash_size(ldb_kv->idxptr->itdb));
122 :
123 1 : TALLOC_FREE(ldb_kv);
124 1 : TALLOC_FREE(module);
125 1 : }
126 :
127 1 : static int mock_begin_write(struct ldb_kv_private* ldb_kv) {
128 1 : return LDB_SUCCESS;
129 : }
130 1 : static int mock_abort_write(struct ldb_kv_private* ldb_kv) {
131 1 : return LDB_SUCCESS;
132 : }
133 :
134 : /*
135 : * Test that the index cache is set to the default cache size at the start of
136 : * a transaction.
137 : */
138 1 : static void test_default_index_cache_size(void **state)
139 : {
140 1 : struct test_ctx *test_ctx = talloc_get_type_abort(
141 : *state,
142 : struct test_ctx);
143 1 : struct ldb_module *module = NULL;
144 1 : struct ldb_kv_private *ldb_kv = NULL;
145 1 : int ret = LDB_SUCCESS;
146 1 : const struct kv_db_ops ops = {
147 : .begin_write = mock_begin_write,
148 : .abort_write = mock_abort_write
149 : };
150 :
151 1 : module = talloc_zero(test_ctx, struct ldb_module);
152 1 : ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private);
153 1 : ldb_kv->pid = getpid();
154 1 : ldb_kv->kv_ops = &ops;
155 1 : ldb_kv->index_transaction_cache_size = DEFAULT_INDEX_CACHE_SIZE;
156 1 : ldb_module_set_private(module, ldb_kv);
157 :
158 1 : ret = ldb_kv_start_trans(module);
159 1 : assert_int_equal(LDB_SUCCESS, ret);
160 :
161 1 : assert_int_equal(
162 : DEFAULT_INDEX_CACHE_SIZE,
163 : tdb_hash_size(ldb_kv->idxptr->itdb));
164 :
165 1 : ret = ldb_kv_del_trans(module);
166 1 : assert_int_equal(LDB_SUCCESS, ret);
167 :
168 1 : TALLOC_FREE(ldb_kv);
169 1 : TALLOC_FREE(module);
170 1 : }
171 :
172 : static int db_size = 0;
173 2 : static size_t mock_get_size(struct ldb_kv_private *ldb_kv) {
174 2 : return db_size;
175 : }
176 :
177 6 : static int mock_iterate(
178 : struct ldb_kv_private *ldb_kv,
179 : ldb_kv_traverse_fn fn,
180 : void *ctx) {
181 6 : return 1;
182 : }
183 :
184 : /*
185 : * Test that the index cache is correctly sized by the re_index call
186 : */
187 1 : static void test_reindex_cache_size(void **state)
188 : {
189 1 : struct test_ctx *test_ctx = talloc_get_type_abort(
190 : *state,
191 : struct test_ctx);
192 1 : struct ldb_module *module = NULL;
193 1 : struct ldb_kv_private *ldb_kv = NULL;
194 1 : int ret = LDB_SUCCESS;
195 1 : const struct kv_db_ops ops = {
196 : .iterate = mock_iterate,
197 : .get_size = mock_get_size,
198 : };
199 :
200 1 : module = talloc_zero(test_ctx, struct ldb_module);
201 1 : ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private);
202 1 : ldb_kv->kv_ops = &ops;
203 1 : ldb_module_set_private(module, ldb_kv);
204 :
205 : /*
206 : * Use a value less than the DEFAULT_INDEX_CACHE_SIZE
207 : * Should get the DEFAULT_INDEX_CACHE_SIZE
208 : */
209 1 : db_size = DEFAULT_INDEX_CACHE_SIZE - 1;
210 1 : ret = ldb_kv_reindex(module);
211 1 : assert_int_equal(LDB_SUCCESS, ret);
212 :
213 1 : assert_int_equal(
214 : DEFAULT_INDEX_CACHE_SIZE,
215 : tdb_hash_size(ldb_kv->idxptr->itdb));
216 :
217 : /*
218 : * Use a value greater than the DEFAULT_INDEX_CACHE_SIZE
219 : * Should get the value specified.
220 : */
221 1 : db_size = DEFAULT_INDEX_CACHE_SIZE + 1;
222 1 : ret = ldb_kv_reindex(module);
223 1 : assert_int_equal(LDB_SUCCESS, ret);
224 :
225 1 : assert_int_equal(db_size, tdb_hash_size(ldb_kv->idxptr->itdb));
226 :
227 1 : TALLOC_FREE(ldb_kv);
228 1 : TALLOC_FREE(module);
229 1 : }
230 :
231 : /*
232 : * Test that ldb_kv_init_store sets the default index transaction cache size
233 : * if the option is not supplied.
234 : */
235 1 : static void test_init_store_default_index_cache_size(void **state)
236 : {
237 1 : struct test_ctx *test_ctx = talloc_get_type_abort(
238 : *state,
239 : struct test_ctx);
240 1 : struct ldb_module *module = NULL;
241 1 : struct ldb_kv_private *ldb_kv = NULL;
242 1 : struct ldb_context *ldb = NULL;
243 1 : int ret = LDB_SUCCESS;
244 :
245 1 : module = talloc_zero(test_ctx, struct ldb_module);
246 1 : ldb = talloc_zero(test_ctx, struct ldb_context);
247 1 : ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private);
248 :
249 1 : ret = ldb_kv_init_store(ldb_kv, "test", ldb, NULL, &module);
250 1 : assert_int_equal(LDB_SUCCESS, ret);
251 :
252 1 : assert_int_equal(
253 : DEFAULT_INDEX_CACHE_SIZE,
254 : ldb_kv->index_transaction_cache_size);
255 :
256 1 : TALLOC_FREE(ldb_kv);
257 1 : TALLOC_FREE(module);
258 1 : TALLOC_FREE(ldb);
259 1 : }
260 :
261 : /*
262 : * Test that ldb_kv_init_store sets the index transaction cache size
263 : * to the value specified in the option.
264 : */
265 1 : static void test_init_store_set_index_cache_size(void **state)
266 : {
267 1 : struct test_ctx *test_ctx = talloc_get_type_abort(
268 : *state,
269 : struct test_ctx);
270 1 : struct ldb_module *module = NULL;
271 1 : struct ldb_kv_private *ldb_kv = NULL;
272 1 : struct ldb_context *ldb = NULL;
273 1 : const char *options[] = {"transaction_index_cache_size:1900", NULL};
274 1 : int ret = LDB_SUCCESS;
275 :
276 1 : module = talloc_zero(test_ctx, struct ldb_module);
277 1 : ldb = talloc_zero(test_ctx, struct ldb_context);
278 1 : ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private);
279 :
280 1 : ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module);
281 1 : assert_int_equal(LDB_SUCCESS, ret);
282 :
283 1 : assert_int_equal( 1900, ldb_kv->index_transaction_cache_size);
284 :
285 1 : TALLOC_FREE(ldb_kv);
286 1 : TALLOC_FREE(module);
287 1 : TALLOC_FREE(ldb);
288 1 : }
289 :
290 : /*
291 : * Test that ldb_kv_init_store sets the default index transaction cache size
292 : * if the value specified in the option is not a number.
293 : */
294 1 : static void test_init_store_set_index_cache_size_non_numeric(void **state)
295 : {
296 1 : struct test_ctx *test_ctx = talloc_get_type_abort(
297 : *state,
298 : struct test_ctx);
299 1 : struct ldb_module *module = NULL;
300 1 : struct ldb_kv_private *ldb_kv = NULL;
301 1 : struct ldb_context *ldb = NULL;
302 1 : const char *options[] = {"transaction_index_cache_size:fred", NULL};
303 1 : int ret = LDB_SUCCESS;
304 :
305 1 : module = talloc_zero(test_ctx, struct ldb_module);
306 1 : ldb = talloc_zero(test_ctx, struct ldb_context);
307 1 : ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private);
308 :
309 1 : ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module);
310 1 : assert_int_equal(LDB_SUCCESS, ret);
311 :
312 1 : assert_int_equal(
313 : DEFAULT_INDEX_CACHE_SIZE,
314 : ldb_kv->index_transaction_cache_size);
315 :
316 1 : TALLOC_FREE(ldb_kv);
317 1 : TALLOC_FREE(module);
318 1 : TALLOC_FREE(ldb);
319 1 : }
320 :
321 : /*
322 : * Test that ldb_kv_init_store sets the default index transaction cache size
323 : * if the value specified is too large
324 : */
325 1 : static void test_init_store_set_index_cache_size_range(void **state)
326 : {
327 1 : struct test_ctx *test_ctx = talloc_get_type_abort(
328 : *state,
329 : struct test_ctx);
330 1 : struct ldb_module *module = NULL;
331 1 : struct ldb_kv_private *ldb_kv = NULL;
332 1 : struct ldb_context *ldb = NULL;
333 1 : const char *options[] = {
334 : "transaction_index_cache_size:0xfffffffffffffffffffffffffffff",
335 : NULL};
336 1 : int ret = LDB_SUCCESS;
337 :
338 1 : module = talloc_zero(test_ctx, struct ldb_module);
339 1 : ldb = talloc_zero(test_ctx, struct ldb_context);
340 1 : ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private);
341 :
342 1 : ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module);
343 1 : assert_int_equal(LDB_SUCCESS, ret);
344 :
345 1 : assert_int_equal(
346 : DEFAULT_INDEX_CACHE_SIZE,
347 : ldb_kv->index_transaction_cache_size);
348 :
349 1 : TALLOC_FREE(ldb_kv);
350 1 : TALLOC_FREE(module);
351 1 : TALLOC_FREE(ldb);
352 1 : }
353 :
354 1 : int main(int argc, const char **argv)
355 : {
356 1 : const struct CMUnitTest tests[] = {
357 : cmocka_unit_test_setup_teardown(
358 : test_index_cache_init,
359 : setup,
360 : teardown),
361 : cmocka_unit_test_setup_teardown(
362 : test_default_index_cache_size,
363 : setup,
364 : teardown),
365 : cmocka_unit_test_setup_teardown(
366 : test_reindex_cache_size,
367 : setup,
368 : teardown),
369 : cmocka_unit_test_setup_teardown(
370 : test_init_store_default_index_cache_size,
371 : setup,
372 : teardown),
373 : cmocka_unit_test_setup_teardown(
374 : test_init_store_set_index_cache_size,
375 : setup,
376 : teardown),
377 : cmocka_unit_test_setup_teardown(
378 : test_init_store_set_index_cache_size_non_numeric,
379 : setup,
380 : teardown),
381 : cmocka_unit_test_setup_teardown(
382 : test_init_store_set_index_cache_size_range,
383 : setup,
384 : teardown),
385 : };
386 :
387 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
388 :
389 1 : return cmocka_run_group_tests(tests, NULL, NULL);
390 : }
|