File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / server / tests / hash_unittest.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:03:49 2012 UTC (11 years, 9 months ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, HEAD
dhcp 4.1 r7

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>