]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[rt25901_atf]: First uid_hash test ready (with 36 checks)
authorTomek Mrugalski <tomasz@isc.org>
Mon, 2 Jul 2012 11:41:35 +0000 (13:41 +0200)
committerTomek Mrugalski <tomasz@isc.org>
Mon, 2 Jul 2012 11:41:35 +0000 (13:41 +0200)
server/tests/hash_unittest.c

index 9bb30b82da78f066295a34233a04497caedbdbdd..6f7bf27da4e560e2e6349277e8a67d96ba535d73 100644 (file)
@@ -59,74 +59,217 @@ lease_ip_hash_t *lease_ip_addr_hash;
 lease_id_hash_t *lease_hw_addr_hash;
 #endif
 
-ATF_TC(lease_hash);
 
-ATF_TC_HEAD(lease_hash, tc) {
-    atf_tc_set_md_var(tc, "descr", "Basic hash functions tests");
 
-#if 0
-    host_hw_addr_hash = 0;
-    host_uid_hash = 0;
-    host_name_hash = 0;
-    lease_uid_hash = 0;
-    lease_ip_addr_hash = 0;
-    lease_hw_addr_hash = 0;
-#endif
+/**
+ *  @brief sets client-id field in host declaration
+ *
+ *  @param host pointer to host declaration
+ *  @param uid pointer to client-id data
+ *  @param uid_len length of the client-id data
+ *
+ *  @return 1 if successful, 0 otherwise
+ */
+int lease_set_clientid(struct host_decl *host, const unsigned char *uid, int uid_len) {
+    /* clean-up this mess and set client-identifier in a sane way */
+    memset(&host->client_identifier, 0, sizeof(host->client_identifier));
+    host->client_identifier.len = uid_len;
+    if (!buffer_allocate(&host->client_identifier.buffer, uid_len, MDL)) {
+        return 0;
+    }
+    host->client_identifier.data = host->client_identifier.buffer->data;
+    memcpy((char *)host->client_identifier.data, uid, uid_len);
+
+    return 1;
+}
+
+ATF_TC(lease_hash_basic);
+
+ATF_TC_HEAD(lease_hash_basic, tc) {
+    atf_tc_set_md_var(tc, "descr", "Basic lease hash tests");
+    /*
+     * The following functions are tested:
+     * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup()
+     * host_hash_add(), host_hash_delete()
+     */
 }
 
-ATF_TC_BODY(lease_hash, tc) {
+ATF_TC_BODY(lease_hash_basic, tc) {
+
+    unsigned char clientid1[] = { 0x1, 0x2, 0x3 };
+    unsigned char clientid2[] = { 0xff, 0xfe };
 
     dhcp_db_objects_setup ();
     dhcp_common_objects_setup ();
 
     /* check that there is actually zero hosts in the hash */
-    // host_hash_for_each(
+    /* @todo: host_hash_for_each() */
 
     struct host_decl *host1 = 0, *host2 = 0;
+    struct host_decl *check = 0;
+
+    /* === step 1: allocate hosts === */
     ATF_CHECK_MSG(host_allocate(&host1, MDL) == ISC_R_SUCCESS,
                   "Failed to allocate host");
     ATF_CHECK_MSG(host_allocate(&host2, MDL) == ISC_R_SUCCESS,
                   "Failed to allocate host");
 
-    /* check that there is actually two hosts in the hash */
-    // host_hash_for_each(...)
+    ATF_CHECK_MSG(host_new_hash(&host_uid_hash, HOST_HASH_SIZE, MDL) != 0,
+                  "Unable to create new hash");
 
-    if (!host_new_hash(&host_uid_hash, HOST_HASH_SIZE, MDL)) {
-        atf_tc_fail("Unable to create new hash");
-    } else {
-        printf("#### Hash created\n");
-    }
+    ATF_CHECK_MSG(buffer_allocate(&host1->client_identifier.buffer,
+                                  sizeof(clientid1), MDL) != 0,
+                  "Can't allocate uid buffer for host1");
 
-    /* Let's create client-identifier */
-    char buf[32];
-    memset(buf,0, 32);
-    for (int i = 0; i < 32; i++) {
-        buf[i] = i;
-    }
-    int bufLen = 16;
+    ATF_CHECK_MSG(buffer_allocate(&host2->client_identifier.buffer,
+                                  sizeof(clientid2), MDL) != 0,
+                  "Can't allocate uid buffer for host2");
 
-    /* clean-up this mess and set client-identifier in a sane way */
-    memset(&host1->client_identifier, 0, sizeof(host1->client_identifier));
-    host1->client_identifier.len = bufLen;
-    if (!buffer_allocate(&host1->client_identifier.buffer, bufLen, MDL)) {
-        atf_tc_fail("Can't allocate uid buffer");
-    }
-    host1->client_identifier.data = host1->client_identifier.buffer->data;
-    memcpy((char *)host1->client_identifier.data, buf, bufLen);
+    ATF_CHECK_MSG(lease_set_clientid(host1, clientid1, sizeof(clientid1)) != 0,
+                  "Failed to set client-id for host1");
+
+    ATF_CHECK_MSG(lease_set_clientid(host2, clientid2, sizeof(clientid2)) != 0,
+                  "Failed to set client-id for host2");
+
+    ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1");
+    ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2");
+
+    /* verify that our hosts are not in the hash yet */
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
+                                   sizeof(clientid1), MDL) == 0,
+                   "Host1 is not supposed to be in the uid_hash.");
+
+    ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash.");
 
-    /* actual test begins. Add hash */
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash,
+                                   (unsigned char *)clientid2,
+                                   sizeof(clientid2), MDL) == 0,
+                  "Host2 is not supposed to be in the uid_hash.");
+    ATF_CHECK_MSG(!check, "Host2 is not supposed to be in the uid_hash.");
+
+
+    /* === step 2: add first host to the hash === */
     host_hash_add(host_uid_hash, host1->client_identifier.data,
                   host1->client_identifier.len, host1, MDL);
 
-    /** @todo: do some checks here */
+    /* 2 pointers expected: ours (host1) and the one stored in hash */
+    ATF_CHECK_MSG(host1->refcnt == 2, "Invalid refcnt for host1");
+    /* 1 pointer expected: just ours (host2) */
+    ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2");
+
+    /* verify that host1 is really in the hash and the we can find it */
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash,
+                                   (unsigned char *)clientid1,
+                                   sizeof(clientid1), MDL),
+                  "Host1 was supposed to be in the uid_hash.");
+    ATF_CHECK_MSG(check, "Host1 was supposed to be in the uid_hash.");
+
+    /* Hey! That's not the host we were looking for! */
+    ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup");
+
+    /* 3 pointers: host1, (stored in hash), check */
+    ATF_CHECK_MSG(host1->refcnt == 3, "Invalid refcnt for host1");
+
+    /* reference count should be increased because we not have a pointer */
+
+    host_dereference(&check, MDL); /* we don't need it now */
+
+    ATF_CHECK_MSG(check == NULL, "check pointer is supposed to be NULL");
+
+    /* 2 pointers: host1, (stored in hash) */
+    ATF_CHECK_MSG(host1->refcnt == 2, "Invalid refcnt for host1");
+
+    /* verify that host2 is not in the hash */
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash,
+                                   (unsigned char *)clientid2,
+                                   sizeof(clientid2), MDL) == 0,
+                  "Host2 was not supposed to be in the uid_hash[2].");
+    ATF_CHECK_MSG(check == NULL, "Host2 was not supposed to be in the hash.");
+
+
+    /* === step 3: add second hot to the hash === */
+    host_hash_add(host_uid_hash, host2->client_identifier.data,
+                  host2->client_identifier.len, host2, MDL);
+
+    /* 2 pointers expected: ours (host1) and the one stored in hash */
+    ATF_CHECK_MSG(host2->refcnt == 2, "Invalid refcnt for host2");
+
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash,
+                                   (unsigned char *)clientid2,
+                                   sizeof(clientid2), MDL),
+                  "Host2 was supposed to be in the uid_hash.");
+    ATF_CHECK_MSG(check, "Host2 was supposed to be in the uid_hash.");
+
+    /* Hey! That's not the host we were looking for! */
+    ATF_CHECK_MSG(check == host2, "Wrong host returned by host_hash_lookup");
+
+    /* 3 pointers: host1, (stored in hash), check */
+    ATF_CHECK_MSG(host2->refcnt == 3, "Invalid refcnt for host1");
+
+    host_dereference(&check, MDL); /* we don't need it now */
+
+    /* now we have 2 hosts in the hash */
+
+    /* verify that host1 is still in the hash and the we can find it */
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash,
+                                   (unsigned char *)clientid1,
+                                   sizeof(clientid1), MDL),
+                  "Host1 was supposed to be in the uid_hash.");
+    ATF_CHECK_MSG(check, "Host1 was supposed to be in the uid_hash.");
+
+    /* Hey! That's not the host we were looking for! */
+    ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup");
+
+    /* 3 pointers: host1, (stored in hash), check */
+    ATF_CHECK_MSG(host1->refcnt == 3, "Invalid refcnt for host1");
+
+    host_dereference(&check, MDL); /* we don't need it now */
+
+
+    /**
+     * @todo check that there is actually two hosts in the hash.
+     * Use host_hash_for_each() for that.
+     */
+
+    /* === step 4: remove first host from the hash === */
 
     /* delete host from hash */
-    host_hash_delete(host_uid_hash,
-                     host1->client_identifier.data,
-                     host1->client_identifier.len,
-                     MDL);
+    host_hash_delete(host_uid_hash, (unsigned char *) clientid1,
+                     sizeof(clientid1), MDL);
+
+    ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1");
+    ATF_CHECK_MSG(host2->refcnt == 2, "Invalid refcnt for host2");
+
+    /* verify that host1 is no longer in the hash */
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1,
+                                   sizeof(clientid1), MDL) == 0,
+                   "Host1 is not supposed to be in the uid_hash.");
+    ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash.");
+
+    /* host2 should be still there, though */
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
+                                   sizeof(clientid2), MDL),
+                   "Host2 was supposed to still be in the uid_hash.");
+    host_dereference(&check, MDL);
+
+    /* === step 5: remove second host from the hash === */
+    host_hash_delete(host_uid_hash, (unsigned char *) clientid2,
+                     sizeof(clientid2), MDL);
+
+    ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1");
+    ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2");
+
+    ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2,
+                                   sizeof(clientid2), MDL) == 0,
+                   "Host2 was not supposed to be in the uid_hash anymore.");
+
+    host_dereference(&host1, MDL);
+    host_dereference(&host2, MDL);
 
-    /** @todo: do some checks here */
+    /*
+     * No easy way to check if the host object were actually released.
+     * We could run it in valgrind and check for memory leaks.
+     */
 
 #if defined (DEBUG_MEMORY_LEAKAGE) && defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
     /* @todo: Should be called in cleanup */
@@ -136,7 +279,7 @@ ATF_TC_BODY(lease_hash, tc) {
 }
 
 ATF_TP_ADD_TCS(tp) {
-    ATF_TP_ADD_TC(tp, lease_hash);
+    ATF_TP_ADD_TC(tp, lease_hash_basic);
 
     return (atf_no_error());
 }