xref: /netbsd-src/external/mpl/dhcp/dist/server/tests/hash_unittest.c (revision f407d9293b6650aa8c33d6a995f797bb6aaefd90)
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