3 * These headers or their equivalents should be included prior to
11 * This allows test applications to use custom definitions of C standard
12 * library functions and types.
25 #include <ldb_private.h>
30 struct ldb_message
*msg
;
33 static int ldb_msg_setup(void **state
)
35 struct test_ctx
*test_ctx
;
37 test_ctx
= talloc_zero(NULL
, struct test_ctx
);
38 assert_non_null(test_ctx
);
40 test_ctx
->msg
= ldb_msg_new(test_ctx
);
46 static int ldb_msg_teardown(void **state
)
48 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
51 talloc_free(test_ctx
);
56 static void add_uint_value(struct test_ctx
*test_ctx
,
57 struct ldb_message
*msg
,
62 struct ldb_val v
, v_dup
;
64 snprintf(s
, sizeof(s
), "%04x", x
);
65 v
.data
= (uint8_t *)s
;
67 v_dup
= ldb_val_dup(test_ctx
, &v
);
68 assert_non_null(v_dup
.data
);
69 assert_ptr_not_equal(v_dup
.data
, v
.data
);
70 assert_int_equal(v_dup
.length
, 4);
72 ret
= ldb_msg_add_value(msg
, attr
, &v_dup
, NULL
);
73 assert_int_equal(ret
, LDB_SUCCESS
);
77 static void test_ldb_msg_find_duplicate_val(void **state
)
81 struct test_ctx
*test_ctx
= talloc_get_type_abort(*state
,
83 struct ldb_message
*msg
= test_ctx
->msg
;
84 struct ldb_message_element
*el
;
86 struct ldb_val
*dupe
= &dummy
; /* so we can tell it was modified to NULL, not left as NULL */
88 ret
= ldb_msg_add_empty(msg
, "el1", 0, &el
);
89 assert_int_equal(ret
, LDB_SUCCESS
);
91 /* An empty message contains no duplicates */
92 ret
= ldb_msg_find_duplicate_val(NULL
, test_ctx
, el
, &dupe
, 0);
93 assert_int_equal(ret
, LDB_SUCCESS
);
96 for (i
= 0; i
< 5; i
++) {
97 add_uint_value(test_ctx
, msg
, "el1", i
);
99 /* at this point there are no duplicates, and the check uses the naive
101 ret
= ldb_msg_find_duplicate_val(NULL
, test_ctx
, el
, &dupe
, 0);
102 assert_int_equal(ret
, LDB_SUCCESS
);
105 /* add a duplicate, still using quadratric path */
106 add_uint_value(test_ctx
, msg
, "el1", 3);
107 ret
= ldb_msg_find_duplicate_val(NULL
, test_ctx
, el
, &dupe
, 0);
108 assert_int_equal(ret
, LDB_SUCCESS
);
109 assert_non_null(dupe
);
110 assert_int_equal(dupe
->length
, 4);
111 assert_memory_equal(dupe
->data
, "0003", 4);
113 /* add some more, triggering algorithmic jump */
114 for (i
= 2; i
< 11; i
++) {
115 add_uint_value(test_ctx
, msg
, "el1", i
);
117 ret
= ldb_msg_find_duplicate_val(NULL
, test_ctx
, el
, &dupe
, 0);
118 assert_int_equal(ret
, LDB_SUCCESS
);
119 assert_non_null(dupe
);
120 assert_int_equal(dupe
->length
, 4);
121 /*XXX not really guaranteed by the API */
122 assert_memory_equal(dupe
->data
, "0002", 4);
124 /* start a new element without duplicates, for the clever algorithm */
125 ldb_msg_add_empty(msg
, "el2", 0, &el
);
126 for (i
= 0; i
< 12; i
++) {
127 add_uint_value(test_ctx
, msg
, "el2", i
);
129 ret
= ldb_msg_find_duplicate_val(NULL
, test_ctx
, el
, &dupe
, 0);
130 assert_int_equal(ret
, LDB_SUCCESS
);
135 static struct ldb_message_element
*new_msg_element(TALLOC_CTX
*mem_ctx
,
137 unsigned int value_offset
,
138 unsigned int num_values
)
141 struct ldb_message_element
*el
= talloc_zero(mem_ctx
,
142 struct ldb_message_element
);
144 el
->values
= talloc_array(el
, struct ldb_val
, num_values
);
145 for (i
= 0; i
< num_values
; i
++) {
148 v
.data
= (uint8_t *)s
;
149 /* % 3 is to ensure the values list is unsorted */
150 x
= i
+ value_offset
;
151 v
.length
= snprintf(s
, sizeof(s
), "%u %u", x
% 3, x
);
152 el
->values
[i
] = ldb_val_dup(mem_ctx
, &v
);
155 el
->num_values
= num_values
;
159 static void _assert_element_equal(struct ldb_message_element
*a
,
160 struct ldb_message_element
*b
,
161 const char * const file
,
165 _assert_int_equal(a
->num_values
, b
->num_values
, file
, line
);
166 _assert_int_equal(a
->flags
, b
->flags
, file
, line
);
167 _assert_string_equal(a
->name
, b
->name
, file
, line
);
168 for (i
= 0; i
< a
->num_values
; i
++) {
169 struct ldb_val
*v1
= &a
->values
[i
];
170 struct ldb_val
*v2
= &b
->values
[i
];
171 _assert_int_equal(v1
->length
, v2
->length
, file
, line
);
172 _assert_memory_equal(v1
->data
, v2
->data
, v1
->length
,
177 #define assert_element_equal(a, b) \
178 _assert_element_equal((a), (b), \
182 static void test_ldb_msg_find_common_values(void **state
)
184 /* we only use the state as a talloc context */
185 struct ldb_message_element
*el
, *el2
, *el3
, *el4
, *el2b
, *empty
;
186 struct ldb_message_element
*orig
, *orig2
, *orig3
, *orig4
;
188 const uint32_t remove_dupes
= LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES
;
189 el
= new_msg_element(*state
, "test", 0, 4);
190 el2
= new_msg_element(*state
, "test", 4, 4);
191 el3
= new_msg_element(*state
, "test", 6, 4);
192 empty
= new_msg_element(*state
, "test", 0, 0);
193 orig
= new_msg_element(*state
, "test", 0, 4);
194 orig2
= new_msg_element(*state
, "test", 4, 4);
195 orig3
= new_msg_element(*state
, "test", 6, 4);
197 /* first round is with short value arrays, using quadratic method */
198 /* we expect no collisions here */
199 ret
= ldb_msg_find_common_values(NULL
, *state
, el
, el2
, 0);
200 assert_int_equal(ret
, LDB_SUCCESS
);
203 ret
= ldb_msg_find_common_values(NULL
, *state
, el
, el3
, 0);
204 assert_int_equal(ret
, LDB_SUCCESS
);
206 /* the same elements in reverse order */
207 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el
, 0);
208 assert_int_equal(ret
, LDB_SUCCESS
);
210 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, el
, 0);
211 assert_int_equal(ret
, LDB_SUCCESS
);
214 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el3
, 0);
215 assert_int_equal(ret
, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
218 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, el2
, 0);
219 assert_int_equal(ret
, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
221 /* make sure the arrays haven't changed */
222 assert_element_equal(el
, orig
);
223 assert_element_equal(el2
, orig2
);
224 assert_element_equal(el3
, orig3
);
226 /* now with the control permisive flag, the first element should be
227 modified to remove the overlap.*/
229 /* 6, 7 collide, so el2 will only have 4 and 5 */
230 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el3
, remove_dupes
);
231 assert_int_equal(ret
, LDB_SUCCESS
);
233 assert_element_equal(el3
, orig3
);
234 assert_int_not_equal(el2
->num_values
, orig2
->num_values
);
235 assert_int_equal(el2
->num_values
, 2);
236 el2b
= new_msg_element(*state
, "test", 4, 2);
237 assert_element_equal(el2
, el2b
);
239 /* now try the same things with a long and a short value list.
240 this should still trigger the quadratic path.
242 el2
= new_msg_element(*state
, "test", 4, 10);
243 orig2
= new_msg_element(*state
, "test", 4, 10);
246 ret
= ldb_msg_find_common_values(NULL
, *state
, el
, el2
, 0);
247 assert_int_equal(ret
, LDB_SUCCESS
);
248 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el
, 0);
249 assert_int_equal(ret
, LDB_SUCCESS
);
252 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, el2
, 0);
253 assert_int_equal(ret
, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
255 assert_element_equal(el
, orig
);
256 assert_element_equal(el2
, orig2
);
257 assert_element_equal(el3
, orig3
);
259 /*collisions with permissive flag*/
260 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, el2
, remove_dupes
);
261 assert_int_equal(ret
, LDB_SUCCESS
);
262 assert_element_equal(el2
, orig2
);
263 assert_int_equal(el3
->num_values
, 0);
265 /* permutations involving empty elements.
266 everything should succeed. */
267 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, el2
, 0);
268 assert_int_equal(ret
, LDB_SUCCESS
);
269 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, el
, 0);
270 assert_int_equal(ret
, LDB_SUCCESS
);
271 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el3
, 0);
272 assert_int_equal(ret
, LDB_SUCCESS
);
273 assert_int_equal(el2
->num_values
, orig2
->num_values
);
274 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, el2
, remove_dupes
);
275 assert_int_equal(ret
, LDB_SUCCESS
);
276 assert_int_equal(el2
->num_values
, orig2
->num_values
);
277 assert_int_equal(el3
->num_values
, 0); /* el3 is now empty */
278 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el3
, remove_dupes
);
279 assert_int_equal(ret
, LDB_SUCCESS
);
280 ret
= ldb_msg_find_common_values(NULL
, *state
, el3
, empty
, 0);
281 assert_int_equal(ret
, LDB_SUCCESS
);
282 ret
= ldb_msg_find_common_values(NULL
, *state
, empty
, empty
, 0);
283 assert_int_equal(ret
, LDB_SUCCESS
);
284 ret
= ldb_msg_find_common_values(NULL
, *state
, empty
, el3
, 0);
285 assert_int_equal(ret
, LDB_SUCCESS
);
287 assert_element_equal(el2
, orig2
);
288 assert_element_equal(el
, orig
);
289 assert_int_equal(el3
->num_values
, 0);
291 /* now with two large value lists */
292 el
= new_msg_element(*state
, "test", 0, 12);
293 orig
= new_msg_element(*state
, "test", 0, 12);
294 el4
= new_msg_element(*state
, "test", 12, 12);
295 orig4
= new_msg_element(*state
, "test", 12, 12);
298 ret
= ldb_msg_find_common_values(NULL
, *state
, el
, el4
, 0);
299 assert_int_equal(ret
, LDB_SUCCESS
);
301 ret
= ldb_msg_find_common_values(NULL
, *state
, el4
, el
, 0);
302 assert_int_equal(ret
, LDB_SUCCESS
);
305 ret
= ldb_msg_find_common_values(NULL
, *state
, el4
, el2
, 0);
306 assert_int_equal(ret
, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
307 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el4
, 0);
308 assert_int_equal(ret
, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
309 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el
, 0);
310 assert_int_equal(ret
, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
);
312 assert_element_equal(el
, orig
);
313 assert_element_equal(el2
, orig2
);
314 assert_element_equal(el4
, orig4
);
316 /* with permissive control, but no collisions */
317 ret
= ldb_msg_find_common_values(NULL
, *state
, el
, el4
, remove_dupes
);
318 assert_int_equal(ret
, LDB_SUCCESS
);
319 ret
= ldb_msg_find_common_values(NULL
, *state
, el4
, el
, remove_dupes
);
320 assert_int_equal(ret
, LDB_SUCCESS
);
322 assert_element_equal(el
, orig
);
323 assert_element_equal(el4
, orig4
);
325 /* now with collisions, thus modifications.
327 el is 0-11 (inclusive)
332 ret
= ldb_msg_find_common_values(NULL
, *state
, el4
, el2
, remove_dupes
);
333 assert_int_equal(ret
, LDB_SUCCESS
);
334 assert_element_equal(el2
, orig2
);
335 assert_int_not_equal(el4
->num_values
, orig4
->num_values
);
336 /* 4 should start at 14 */
337 orig4
= new_msg_element(*state
, "test", 14, 10);
338 assert_element_equal(el4
, orig4
);
340 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el
, remove_dupes
);
341 assert_int_equal(ret
, LDB_SUCCESS
);
342 assert_element_equal(el
, orig
);
343 assert_int_not_equal(el2
->num_values
, orig2
->num_values
);
344 orig2
= new_msg_element(*state
, "test", 12, 2);
345 assert_element_equal(el2
, orig2
);
347 /* test the empty el against the full elements */
348 ret
= ldb_msg_find_common_values(NULL
, *state
, el
, empty
, 0);
349 assert_int_equal(ret
, LDB_SUCCESS
);
350 ret
= ldb_msg_find_common_values(NULL
, *state
, empty
, el
, 0);
351 assert_int_equal(ret
, LDB_SUCCESS
);
352 ret
= ldb_msg_find_common_values(NULL
, *state
, el
, empty
, remove_dupes
);
353 assert_int_equal(ret
, LDB_SUCCESS
);
354 ret
= ldb_msg_find_common_values(NULL
, *state
, empty
, el
, remove_dupes
);
355 assert_int_equal(ret
, LDB_SUCCESS
);
356 assert_element_equal(el
, orig
);
357 assert_element_equal(empty
, el3
);
359 /* make sure an identical element with a different name is rejected */
360 el2
= new_msg_element(*state
, "fish", 12, 2);
361 ret
= ldb_msg_find_common_values(NULL
, *state
, el2
, el
, remove_dupes
);
362 assert_int_equal(ret
, LDB_ERR_INAPPROPRIATE_MATCHING
);
367 int main(int argc
, const char **argv
)
369 const struct CMUnitTest tests
[] = {
370 cmocka_unit_test_setup_teardown(test_ldb_msg_find_duplicate_val
,
373 cmocka_unit_test_setup_teardown(
374 test_ldb_msg_find_common_values
,
379 cmocka_set_message_output(CM_OUTPUT_SUBUNIT
);
381 return cmocka_run_group_tests(tests
, NULL
, NULL
);