nagios4/lib/test-dkhash.c

195 lines
4.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dkhash.c"
#include "t-utils.h"
static struct {
char *k1, *k2;
} keys[] = {
{ "nisse", "banan" },
{ "foo", "bar" },
{ "kalle", "penslar" },
{ "hello", "world" },
{ "test", "fnurg" },
{ "barsk", "nitfol" },
{ "andreas", "regerar" },
{ "Nagios", "rules" },
};
static int removed;
static struct test_data {
int x, i, j;
} del;
unsigned int dkhash_count_entries(dkhash_table *table)
{
unsigned int i, count = 0;
for (i = 0; i < table->num_buckets; i++) {
dkhash_bucket *bkt;
for (bkt = table->buckets[i]; bkt; bkt = bkt->next)
count++;
}
return count;
}
int dkhash_check_table(dkhash_table *t)
{
return t ? t->entries - dkhash_count_entries(t) : 0;
}
void dkhash_debug_print_table(dkhash_table *t, const char *name, int force)
{
int delta = dkhash_check_table(t);
unsigned int count;
if (!delta && !force)
return;
count = dkhash_count_entries(t);
printf("debug data for dkhash table '%s'\n", name);
printf(" entries: %u; counted: %u; delta: %d\n",
t->entries, count, delta);
printf(" added: %u; removed: %u; delta: %d\n",
t->added, t->removed, t->added - t->removed);
}
#define dkhash_debug_table(t, force) dkhash_debug_print_table(t, #t, force)
static struct test_data *ddup(int x, int i, int j)
{
struct test_data *d;
d = malloc(sizeof(*d));
d->x = x;
d->i = i;
d->j = j;
return d;
}
struct dkhash_check {
uint entries, count, max, added, removed;
int ent_delta, addrm_delta;
};
static int del_matching(void *data)
{
struct test_data *d = (struct test_data *)data;
if (!memcmp(d, &del, sizeof(del))) {
removed++;
return DKHASH_WALK_REMOVE;
}
return 0;
}
int main(int argc, char **argv)
{
dkhash_table *tx, *t;
unsigned int x;
int ret, r2;
struct test_data s;
char *p1, *p2;
char *strs[10];
char tmp[32];
t_set_colors(0);
t_start("dkhash basic test");
t = dkhash_create(512);
p1 = strdup("a not-so secret value");
dkhash_insert(t, "nisse", NULL, p1);
ok_int(dkhash_num_entries_max(t), 1, "Added one entry, so that's max");
ok_int(dkhash_num_entries_added(t), 1, "Added one entry, so one added");
ok_int(dkhash_table_size(t), 1024, "Table must be sized properly");
ok_int(dkhash_collisions(t), 0, "One entry, so zero collisions");
p2 = dkhash_get(t, "nisse", NULL);
test(p1 == p2, "get should get what insert set");
dkhash_insert(t, "kalle", "bananas", p1);
p2 = dkhash_get(t, "kalle", "bezinga");
test(p1 != p2, "we should never get the wrong key");
ok_int(2, dkhash_num_entries(t), "should be 2 entries after 2 inserts");
p2 = dkhash_remove(t, "kalle", "bezinga");
ok_int(2, dkhash_num_entries(t), "should be 2 entries after 2 inserts and 1 failed remove");
ok_int(0, dkhash_num_entries_removed(t), "should be 0 removed entries after failed remove");
p2 = dkhash_remove(t, "kalle", "bananas");
test(p1 == p2, "dkhash_remove() should return removed data");
ok_int(dkhash_num_entries(t), 1, "should be 1 entries after 2 inserts and 1 successful remove");
p2 = dkhash_remove(t, "nisse", NULL);
test(p1 == p2, "dkhash_remove() should return removed data");
ret = t_end();
t_reset();
/* lots of tests below, so we shut up while they're running */
t_verbose = 0;
t_start("dkhash_walk_data() test");
memset(&s, 0, sizeof(s));
/* first we set up the dkhash-tables */
tx = dkhash_create(16);
for (x = 0; x < ARRAY_SIZE(keys); x++) {
dkhash_insert(tx, keys[x].k1, NULL, ddup(x, 0, 0));
dkhash_insert(tx, keys[x].k2, NULL, ddup(x, 0, 0));
dkhash_insert(tx, keys[x].k1, keys[x].k2, ddup(x, 0, 0));
s.x += 3;
ok_int(s.x, dkhash_num_entries(tx), "x table adding");
}
ok_int(s.x, dkhash_num_entries(tx), "x table done adding");
for (x = 0; x < ARRAY_SIZE(keys); x++) {
del.x = x;
del.i = del.j = 0;
ok_int(s.x, dkhash_num_entries(tx), "x table pre-delete");
s.x -= 3;
dkhash_walk_data(tx, del_matching);
ok_int(s.x, dkhash_num_entries(tx), "x table post-delete");
}
test(0 == dkhash_num_entries(tx), "x table post all ops");
test(0 == dkhash_check_table(tx), "x table consistency post all ops");
dkhash_debug_table(tx, 0);
r2 = t_end();
ret = r2 ? r2 : ret;
t_reset();
for(x = 0; x < 10; x++) {
sprintf(tmp, "string %d", x);
strs[x] = strdup(tmp);
}
t_start("dkhash single bucket add remove forward");
t = dkhash_create(1);
for(x = 0; x < 10; x++) {
dkhash_insert(t, strs[x], NULL, strs[x]);
}
for(x = 0; x < 10; x++) {
p1 = strs[x];
p2 = dkhash_remove(t, p1, NULL);
test(p1 == p2, "remove should return a value");
}
r2 = t_end();
ret = r2 ? r2 : ret;
t_reset();
t_start("dkhash single bucket add remove backward");
t = dkhash_create(1);
for(x = 0; x < 10; x++) {
dkhash_insert(t, strs[x], NULL, strs[x]);
}
for(x = 9; x; x--) {
p1 = strs[x];
p2 = dkhash_remove(t, p1, NULL);
test(p1 == p2, "remove should return a value");
}
dkhash_destroy(t);
r2 = t_end();
return r2 ? r2 : ret;
}