1 /* $NetBSD: hash_unittest.c,v 1.3 2022/04/03 01:11:00 christos Exp $ */
2
3 /*
4 * Copyright (C) 2012-2022 Internet Systems Consortium, Inc. ("ISC")
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Internet Systems Consortium, Inc.
19 * PO Box 360
20 * Newmarket, NH 03857 USA
21 * <info@isc.org>
22 * https://www.isc.org/
23 *
24 */
25
26 #include <sys/cdefs.h>
27 __RCSID("$NetBSD: hash_unittest.c,v 1.3 2022/04/03 01:11:00 christos Exp $");
28
29 #include "config.h"
30 #include <atf-c.h>
31 #include <omapip/omapip_p.h>
32 #include "dhcpd.h"
33
34 /*
35 * The following structures are kept here for reference only. As hash functions
36 * are somewhat convoluted, they are copied here for the reference. Original
37 * location is specified. Keep in mind that it may change over time:
38 *
39 * copied from server/omapi.c:49 *
40 * omapi_object_type_t *dhcp_type_lease;
41 * omapi_object_type_t *dhcp_type_pool;
42 * omapi_object_type_t *dhcp_type_class;
43 * omapi_object_type_t *dhcp_type_subclass;
44 * omapi_object_type_t *dhcp_type_host;
45 *
46 * copied from server/salloc.c:138
47 * OMAPI_OBJECT_ALLOC (lease, struct lease, dhcp_type_lease)
48 * OMAPI_OBJECT_ALLOC (class, struct class, dhcp_type_class)
49 * OMAPI_OBJECT_ALLOC (subclass, struct class, dhcp_type_subclass)
50 * OMAPI_OBJECT_ALLOC (pool, struct pool, dhcp_type_pool)
51 * OMAPI_OBJECT_ALLOC (host, struct host_decl, dhcp_type_host)
52 *
53 * copied from server/mdb.c:2686
54 * HASH_FUNCTIONS(lease_ip, const unsigned char *, struct lease, lease_ip_hash_t,
55 * lease_reference, lease_dereference, do_ip4_hash)
56 * HASH_FUNCTIONS(lease_id, const unsigned char *, struct lease, lease_id_hash_t,
57 * lease_reference, lease_dereference, do_id_hash)
58 * HASH_FUNCTIONS (host, const unsigned char *, struct host_decl, host_hash_t,
59 * host_reference, host_dereference, do_string_hash)
60 * HASH_FUNCTIONS (class, const char *, struct class, class_hash_t,
61 * class_reference, class_dereference, do_string_hash)
62 *
63 * copied from server/mdb.c:46
64 * host_hash_t *host_hw_addr_hash;
65 * host_hash_t *host_uid_hash;
66 * host_hash_t *host_name_hash;
67 * lease_id_hash_t *lease_uid_hash;
68 * lease_ip_hash_t *lease_ip_addr_hash;
69 * lease_id_hash_t *lease_hw_addr_hash;
70 */
71
72 /**
73 * @brief sets client-id field in host declaration
74 *
75 * @param host pointer to host declaration
76 * @param uid pointer to client-id data
77 * @param uid_len length of the client-id data
78 *
79 * @return 1 if successful, 0 otherwise
80 */
lease_set_clientid(struct host_decl * host,const unsigned char * uid,int uid_len)81 int lease_set_clientid(struct host_decl *host, const unsigned char *uid, int uid_len) {
82
83 /* clean-up this mess and set client-identifier in a sane way */
84 int real_len = uid_len;
85 if (uid_len == 0) {
86 real_len = strlen((const char *)uid) + 1;
87 }
88
89 memset(&host->client_identifier, 0, sizeof(host->client_identifier));
90 host->client_identifier.len = uid_len;
91 if (!buffer_allocate(&host->client_identifier.buffer, real_len, MDL)) {
92 return 0;
93 }
94 host->client_identifier.data = host->client_identifier.buffer->data;
95 memcpy((char *)host->client_identifier.data, uid, real_len);
96
97 return 1;
98 }
99
100 /// @brief executes uid hash test for specified client-ids (2 hosts)
101 ///
102 /// Creates two host structures, adds first host to the uid hash,
103 /// then adds second host to the hash, then removes first host,
104 /// then removed the second. Many checks are performed during all
105 /// operations.
106 ///
107 /// @param clientid1 client-id of the first host
108 /// @param clientid1_len client-id1 length (may be 0 for strings)
109 /// @param clientid2 client-id of the second host
110 /// @param clientid2_len client-id2 length (may be 0 for strings)
lease_hash_test_2hosts(unsigned char clientid1[],size_t clientid1_len,unsigned char clientid2[],size_t clientid2_len)111 void lease_hash_test_2hosts(unsigned char clientid1[], size_t clientid1_len,
112 unsigned char clientid2[], size_t clientid2_len) {
113
114 printf("Checking hash operation for 2 hosts: clientid1-len=%lu"
115 "clientid2-len=%lu\n", (unsigned long) clientid1_len,
116 (unsigned long) clientid2_len);
117
118 dhcp_db_objects_setup ();
119 dhcp_common_objects_setup ();
120
121 /* check that there is actually zero hosts in the hash */
122 /* @todo: host_hash_for_each() */
123
124 struct host_decl *host1 = 0, *host2 = 0;
125 struct host_decl *check = 0;
126
127 /* === step 1: allocate hosts === */
128 ATF_CHECK_MSG(host_allocate(&host1, MDL) == ISC_R_SUCCESS,
129 "Failed to allocate host");
130 ATF_CHECK_MSG(host_allocate(&host2, MDL) == ISC_R_SUCCESS,
131 "Failed to allocate host");
132
133 ATF_CHECK_MSG(host_new_hash(&host_uid_hash, HOST_HASH_SIZE, MDL) != 0,
134 "Unable to create new hash");
135
136 ATF_CHECK_MSG(buffer_allocate(&host1->client_identifier.buffer,
137 clientid1_len, MDL) != 0,
138 "Can't allocate uid buffer for host1");
139
140 ATF_CHECK_MSG(buffer_allocate(&host2->client_identifier.buffer,
141 clientid2_len, MDL) != 0,
142 "Can't allocate uid buffer for host2");
143
144 /* setting up host1->client_identifier is actually not needed */
145 /*
146 ATF_CHECK_MSG(lease_set_clientid(host1, clientid1, actual1_len) != 0,
147 "Failed to set client-id for host1");
148
149 ATF_CHECK_MSG(lease_set_clientid(host2, clientid2, actual2_len) != 0,
150 "Failed to set client-id for host2");
151 */
152
153 ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1");
154 ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2");
155
156 /* verify that our hosts are not in the hash yet */
157 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
158 clientid1_len, MDL) == 0,
159 "Host1 is not supposed to be in the uid_hash.");
160
161 ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash.");
162
163 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
164 clientid2_len, MDL) == 0,
165 "Host2 is not supposed to be in the uid_hash.");
166 ATF_CHECK_MSG(!check, "Host2 is not supposed to be in the uid_hash.");
167
168
169 /* === step 2: add first host to the hash === */
170 host_hash_add(host_uid_hash, clientid1, clientid1_len, host1, MDL);
171
172 /* 2 pointers expected: ours (host1) and the one stored in hash */
173 ATF_CHECK_MSG(host1->refcnt == 2, "Invalid refcnt for host1");
174 /* 1 pointer expected: just ours (host2) */
175 ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2");
176
177 /* verify that host1 is really in the hash and the we can find it */
178 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
179 clientid1_len, MDL),
180 "Host1 was supposed to be in the uid_hash.");
181 ATF_CHECK_MSG(check, "Host1 was supposed to be in the uid_hash.");
182
183 /* Hey! That's not the host we were looking for! */
184 ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup");
185
186 /* 3 pointers: host1, (stored in hash), check */
187 ATF_CHECK_MSG(host1->refcnt == 3, "Invalid refcnt for host1");
188
189 /* reference count should be increased because we not have a pointer */
190
191 host_dereference(&check, MDL); /* we don't need it now */
192
193 ATF_CHECK_MSG(check == NULL, "check pointer is supposed to be NULL");
194
195 /* 2 pointers: host1, (stored in hash) */
196 ATF_CHECK_MSG(host1->refcnt == 2, "Invalid refcnt for host1");
197
198 /* verify that host2 is not in the hash */
199 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
200 clientid2_len, MDL) == 0,
201 "Host2 was not supposed to be in the uid_hash[2].");
202 ATF_CHECK_MSG(check == NULL, "Host2 was not supposed to be in the hash.");
203
204
205 /* === step 3: add second hot to the hash === */
206 host_hash_add(host_uid_hash, clientid2, clientid2_len, host2, MDL);
207
208 /* 2 pointers expected: ours (host1) and the one stored in hash */
209 ATF_CHECK_MSG(host2->refcnt == 2, "Invalid refcnt for host2");
210
211 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
212 clientid2_len, MDL),
213 "Host2 was supposed to be in the uid_hash.");
214 ATF_CHECK_MSG(check, "Host2 was supposed to be in the uid_hash.");
215
216 /* Hey! That's not the host we were looking for! */
217 ATF_CHECK_MSG(check == host2, "Wrong host returned by host_hash_lookup");
218
219 /* 3 pointers: host1, (stored in hash), check */
220 ATF_CHECK_MSG(host2->refcnt == 3, "Invalid refcnt for host1");
221
222 host_dereference(&check, MDL); /* we don't need it now */
223
224 /* now we have 2 hosts in the hash */
225
226 /* verify that host1 is still in the hash and the we can find it */
227 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
228 clientid1_len, MDL),
229 "Host1 was supposed to be in the uid_hash.");
230 ATF_CHECK_MSG(check, "Host1 was supposed to be in the uid_hash.");
231
232 /* Hey! That's not the host we were looking for! */
233 ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup");
234
235 /* 3 pointers: host1, (stored in hash), check */
236 ATF_CHECK_MSG(host1->refcnt == 3, "Invalid refcnt for host1");
237
238 host_dereference(&check, MDL); /* we don't need it now */
239
240
241 /**
242 * @todo check that there is actually two hosts in the hash.
243 * Use host_hash_for_each() for that.
244 */
245
246 /* === step 4: remove first host from the hash === */
247
248 /* delete host from hash */
249 host_hash_delete(host_uid_hash, clientid1, clientid1_len, MDL);
250
251 ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1");
252 ATF_CHECK_MSG(host2->refcnt == 2, "Invalid refcnt for host2");
253
254 /* verify that host1 is no longer in the hash */
255 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
256 clientid1_len, MDL) == 0,
257 "Host1 is not supposed to be in the uid_hash.");
258 ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash.");
259
260 /* host2 should be still there, though */
261 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
262 clientid2_len, MDL),
263 "Host2 was supposed to still be in the uid_hash.");
264 host_dereference(&check, MDL);
265
266 /* === step 5: remove second host from the hash === */
267 host_hash_delete(host_uid_hash, clientid2, clientid2_len, MDL);
268
269 ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1");
270 ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2");
271
272 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
273 clientid2_len, MDL) == 0,
274 "Host2 was not supposed to be in the uid_hash anymore.");
275
276 host_dereference(&host1, MDL);
277 host_dereference(&host2, MDL);
278
279 /*
280 * No easy way to check if the host object were actually released.
281 * We could run it in valgrind and check for memory leaks.
282 */
283
284 #if defined (DEBUG_MEMORY_LEAKAGE) && defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
285 /* @todo: Should be called in cleanup */
286 free_everything ();
287 #endif
288 }
289
290 /// @brief executes uid hash test for specified client-ids (3 hosts)
291 ///
292 /// Creates three host structures, adds first host to the uid hash,
293 /// then adds second host to the hash, then removes first host,
294 /// then removed the second. Many checks are performed during all
295 /// operations.
296 ///
297 /// @param clientid1 client-id of the first host
298 /// @param clientid1_len client-id1 length (may be 0 for strings)
299 /// @param clientid2 client-id of the second host
300 /// @param clientid2_len client-id2 length (may be 0 for strings)
301 /// @param clientid3 client-id of the second host
302 /// @param clientid3_len client-id2 length (may be 0 for strings)
lease_hash_test_3hosts(unsigned char clientid1[],size_t clientid1_len,unsigned char clientid2[],size_t clientid2_len,unsigned char clientid3[],size_t clientid3_len)303 void lease_hash_test_3hosts(unsigned char clientid1[], size_t clientid1_len,
304 unsigned char clientid2[], size_t clientid2_len,
305 unsigned char clientid3[], size_t clientid3_len) {
306
307 printf("Checking hash operation for 3 hosts: clientid1-len=%lu"
308 " clientid2-len=%lu clientid3-len=%lu\n",
309 (unsigned long) clientid1_len, (unsigned long) clientid2_len,
310 (unsigned long) clientid3_len);
311
312 dhcp_db_objects_setup ();
313 dhcp_common_objects_setup ();
314
315 /* check that there is actually zero hosts in the hash */
316 /* @todo: host_hash_for_each() */
317
318 struct host_decl *host1 = 0, *host2 = 0, *host3 = 0;
319 struct host_decl *check = 0;
320
321 /* === step 1: allocate hosts === */
322 ATF_CHECK_MSG(host_allocate(&host1, MDL) == ISC_R_SUCCESS,
323 "Failed to allocate host");
324 ATF_CHECK_MSG(host_allocate(&host2, MDL) == ISC_R_SUCCESS,
325 "Failed to allocate host");
326 ATF_CHECK_MSG(host_allocate(&host3, MDL) == ISC_R_SUCCESS,
327 "Failed to allocate host");
328
329 ATF_CHECK_MSG(host_new_hash(&host_uid_hash, HOST_HASH_SIZE, MDL) != 0,
330 "Unable to create new hash");
331
332 ATF_CHECK_MSG(buffer_allocate(&host1->client_identifier.buffer,
333 clientid1_len, MDL) != 0,
334 "Can't allocate uid buffer for host1");
335 ATF_CHECK_MSG(buffer_allocate(&host2->client_identifier.buffer,
336 clientid2_len, MDL) != 0,
337 "Can't allocate uid buffer for host2");
338 ATF_CHECK_MSG(buffer_allocate(&host3->client_identifier.buffer,
339 clientid3_len, MDL) != 0,
340 "Can't allocate uid buffer for host3");
341
342 /* verify that our hosts are not in the hash yet */
343 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
344 clientid1_len, MDL) == 0,
345 "Host1 is not supposed to be in the uid_hash.");
346
347 ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash.");
348
349 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
350 clientid2_len, MDL) == 0,
351 "Host2 is not supposed to be in the uid_hash.");
352 ATF_CHECK_MSG(!check, "Host2 is not supposed to be in the uid_hash.");
353
354 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3,
355 clientid3_len, MDL) == 0,
356 "Host3 is not supposed to be in the uid_hash.");
357 ATF_CHECK_MSG(!check, "Host3 is not supposed to be in the uid_hash.");
358
359 /* === step 2: add hosts to the hash === */
360 host_hash_add(host_uid_hash, clientid1, clientid1_len, host1, MDL);
361 host_hash_add(host_uid_hash, clientid2, clientid2_len, host2, MDL);
362 host_hash_add(host_uid_hash, clientid3, clientid3_len, host3, MDL);
363
364 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
365 clientid1_len, MDL),
366 "Host1 was supposed to be in the uid_hash.");
367 /* Hey! That's not the host we were looking for! */
368 ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup");
369 host_dereference(&check, MDL); /* we don't need it now */
370
371 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
372 clientid2_len, MDL),
373 "Host2 was supposed to be in the uid_hash.");
374 ATF_CHECK_MSG(check, "Host2 was supposed to be in the uid_hash.");
375 /* Hey! That's not the host we were looking for! */
376 ATF_CHECK_MSG(check == host2, "Wrong host returned by host_hash_lookup");
377 host_dereference(&check, MDL); /* we don't need it now */
378
379 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3,
380 clientid3_len, MDL),
381 "Host3 was supposed to be in the uid_hash.");
382 ATF_CHECK_MSG(check, "Host3 was supposed to be in the uid_hash.");
383 /* Hey! That's not the host we were looking for! */
384 ATF_CHECK_MSG(check == host3, "Wrong host returned by host_hash_lookup");
385 host_dereference(&check, MDL); /* we don't need it now */
386
387 /* === step 4: remove first host from the hash === */
388
389 /* delete host from hash */
390 host_hash_delete(host_uid_hash, clientid1, clientid1_len, MDL);
391
392 /* verify that host1 is no longer in the hash */
393 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
394 clientid1_len, MDL) == 0,
395 "Host1 is not supposed to be in the uid_hash.");
396 ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash.");
397
398 /* host2 and host3 should be still there, though */
399 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
400 clientid2_len, MDL),
401 "Host2 was supposed to still be in the uid_hash.");
402 host_dereference(&check, MDL);
403 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3,
404 clientid3_len, MDL),
405 "Host3 was supposed to still be in the uid_hash.");
406 host_dereference(&check, MDL);
407
408 /* === step 5: remove second host from the hash === */
409 host_hash_delete(host_uid_hash, clientid2, clientid2_len, MDL);
410
411 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
412 clientid2_len, MDL) == 0,
413 "Host2 was not supposed to be in the uid_hash anymore.");
414 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3,
415 clientid3_len, MDL),
416 "Host3 was supposed to still be in the uid_hash.");
417 host_dereference(&check, MDL);
418
419 /* === step 6: remove the last (third) host from the hash === */
420 host_hash_delete(host_uid_hash, clientid3, clientid3_len, MDL);
421
422 ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3,
423 clientid3_len, MDL) == 0,
424 "Host3 was not supposed to be in the uid_hash anymore.");
425 host_dereference(&check, MDL);
426
427
428 host_dereference(&host1, MDL);
429 host_dereference(&host2, MDL);
430 host_dereference(&host3, MDL);
431
432 /*
433 * No easy way to check if the host object were actually released.
434 * We could run it in valgrind and check for memory leaks.
435 */
436
437 #if defined (DEBUG_MEMORY_LEAKAGE) && defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
438 /* @todo: Should be called in cleanup */
439 free_everything ();
440 #endif
441 }
442
443 ATF_TC(lease_hash_basic_2hosts);
444
ATF_TC_HEAD(lease_hash_basic_2hosts,tc)445 ATF_TC_HEAD(lease_hash_basic_2hosts, tc) {
446 atf_tc_set_md_var(tc, "descr", "Basic lease hash tests");
447 /*
448 * The following functions are tested:
449 * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup()
450 * host_hash_add(), host_hash_delete()
451 */
452 }
453
ATF_TC_BODY(lease_hash_basic_2hosts,tc)454 ATF_TC_BODY(lease_hash_basic_2hosts, tc) {
455
456 unsigned char clientid1[] = { 0x1, 0x2, 0x3 };
457 unsigned char clientid2[] = { 0xff, 0xfe };
458
459 lease_hash_test_2hosts(clientid1, sizeof(clientid1),
460 clientid2, sizeof(clientid2));
461 }
462
463
464 ATF_TC(lease_hash_string_2hosts);
465
ATF_TC_HEAD(lease_hash_string_2hosts,tc)466 ATF_TC_HEAD(lease_hash_string_2hosts, tc) {
467 atf_tc_set_md_var(tc, "descr", "string-based lease hash tests");
468 /*
469 * The following functions are tested:
470 * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup()
471 * host_hash_add(), host_hash_delete()
472 */
473 }
474
ATF_TC_BODY(lease_hash_string_2hosts,tc)475 ATF_TC_BODY(lease_hash_string_2hosts, tc) {
476
477 unsigned char clientid1[] = "Alice";
478 unsigned char clientid2[] = "Bob";
479
480 lease_hash_test_2hosts(clientid1, 0, clientid2, 0);
481 }
482
483
484 ATF_TC(lease_hash_negative1);
485
ATF_TC_HEAD(lease_hash_negative1,tc)486 ATF_TC_HEAD(lease_hash_negative1, tc) {
487 atf_tc_set_md_var(tc, "descr", "Negative tests for lease hash");
488 }
489
ATF_TC_BODY(lease_hash_negative1,tc)490 ATF_TC_BODY(lease_hash_negative1, tc) {
491
492 unsigned char clientid1[] = { 0x1 };
493 unsigned char clientid2[] = { 0x0 };
494
495 lease_hash_test_2hosts(clientid1, 0, clientid2, 1);
496 }
497
498
499
500 ATF_TC(lease_hash_string_3hosts);
ATF_TC_HEAD(lease_hash_string_3hosts,tc)501 ATF_TC_HEAD(lease_hash_string_3hosts, tc) {
502 atf_tc_set_md_var(tc, "descr", "string-based lease hash tests");
503 /*
504 * The following functions are tested:
505 * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup()
506 * host_hash_add(), host_hash_delete()
507 */
508 }
ATF_TC_BODY(lease_hash_string_3hosts,tc)509 ATF_TC_BODY(lease_hash_string_3hosts, tc) {
510
511 unsigned char clientid1[] = "Alice";
512 unsigned char clientid2[] = "Bob";
513 unsigned char clientid3[] = "Charlie";
514
515 lease_hash_test_3hosts(clientid1, 0, clientid2, 0, clientid3, 0);
516 }
517
518
519 ATF_TC(lease_hash_basic_3hosts);
ATF_TC_HEAD(lease_hash_basic_3hosts,tc)520 ATF_TC_HEAD(lease_hash_basic_3hosts, tc) {
521 atf_tc_set_md_var(tc, "descr", "Basic lease hash tests");
522 /*
523 * The following functions are tested:
524 * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup()
525 * host_hash_add(), host_hash_delete()
526 */
527 }
ATF_TC_BODY(lease_hash_basic_3hosts,tc)528 ATF_TC_BODY(lease_hash_basic_3hosts, tc) {
529
530 unsigned char clientid1[] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 };
531 unsigned char clientid2[] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 };
532 unsigned char clientid3[] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };
533
534 lease_hash_test_3hosts(clientid1, sizeof(clientid1),
535 clientid2, sizeof(clientid2),
536 clientid3, sizeof(clientid3));
537 }
538
539 #if 0
540 /* This test is disabled as we solved the issue by prohibiting
541 the code from using an improper client id earlier and restoring
542 the hash code to its previous state. As we may choose to
543 redo the hash code again this test hasn't been deleted.
544 */
545 /* this test is a direct reproduction of 29851 issue */
546 ATF_TC(uid_hash_rt29851);
547
548 ATF_TC_HEAD(uid_hash_rt29851, tc) {
549 atf_tc_set_md_var(tc, "descr", "Uid hash tests");
550
551 /*
552 * this test should last less than millisecond. If its execution
553 * is longer than 3 second, we hit infinite loop.
554 */
555 atf_tc_set_md_var(tc, "timeout", "3");
556 }
557
558 ATF_TC_BODY(uid_hash_rt29851, tc) {
559
560 unsigned char clientid1[] = { 0x0 };
561 unsigned char clientid2[] = { 0x0 };
562 unsigned char clientid3[] = { 0x0 };
563
564 int clientid1_len = 1;
565 int clientid2_len = 1;
566 int clientid3_len = 0;
567
568 struct lease *lease1 = 0, *lease2 = 0, *lease3 = 0;
569
570 dhcp_db_objects_setup ();
571 dhcp_common_objects_setup ();
572
573 ATF_CHECK(lease_id_new_hash(&lease_uid_hash, LEASE_HASH_SIZE, MDL));
574
575 ATF_CHECK(lease_allocate (&lease1, MDL) == ISC_R_SUCCESS);
576 ATF_CHECK(lease_allocate (&lease2, MDL) == ISC_R_SUCCESS);
577 ATF_CHECK(lease_allocate (&lease3, MDL) == ISC_R_SUCCESS);
578
579 lease1->uid = clientid1;
580 lease2->uid = clientid2;
581 lease3->uid = clientid3;
582
583 lease1->uid_len = clientid1_len;
584 lease2->uid_len = clientid2_len;
585 lease3->uid_len = clientid3_len;
586
587 uid_hash_add(lease1);
588 /* uid_hash_delete(lease2); // not necessary for actual issue repro */
589 uid_hash_add(lease3);
590
591 /* lease2->uid_len = 0; // not necessary for actual issue repro */
592 /* uid_hash_delete(lease2); // not necessary for actual issue repro */
593 /* uid_hash_delete(lease3); // not necessary for actual issue repro */
594 uid_hash_delete(lease1);
595
596 /* lease2->uid_len = 1; // not necessary for actual issue repro */
597 uid_hash_add(lease1);
598 uid_hash_delete(lease2);
599 }
600 #endif
601
ATF_TP_ADD_TCS(tp)602 ATF_TP_ADD_TCS(tp) {
603 ATF_TP_ADD_TC(tp, lease_hash_basic_2hosts);
604 ATF_TP_ADD_TC(tp, lease_hash_basic_3hosts);
605 ATF_TP_ADD_TC(tp, lease_hash_string_2hosts);
606 ATF_TP_ADD_TC(tp, lease_hash_string_3hosts);
607 ATF_TP_ADD_TC(tp, lease_hash_negative1);
608 #if 0 /* see comment in function */
609 ATF_TP_ADD_TC(tp, uid_hash_rt29851);
610 #endif
611 return (atf_no_error());
612 }
613