Blame testsuite/test-hash.c

Packit Service 68b988
/*
Packit Service 68b988
 * Copyright (C)  2014 Intel Corporation. All rights reserved.
Packit Service 68b988
 *
Packit Service 68b988
 * This program is free software; you can redistribute it and/or
Packit Service 68b988
 * modify it under the terms of the GNU Lesser General Public
Packit Service 68b988
 * License as published by the Free Software Foundation; either
Packit Service 68b988
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 68b988
 *
Packit Service 68b988
 * This program is distributed in the hope that it will be useful,
Packit Service 68b988
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 68b988
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 68b988
 * Lesser General Public License for more details.
Packit Service 68b988
 *
Packit Service 68b988
 * You should have received a copy of the GNU Lesser General Public
Packit Service 68b988
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit Service 68b988
 */
Packit Service 68b988
Packit Service 68b988
#include <errno.h>
Packit Service 68b988
#include <stddef.h>
Packit Service 68b988
#include <stdio.h>
Packit Service 68b988
#include <stdlib.h>
Packit Service 68b988
#include <string.h>
Packit Service 68b988
#include <unistd.h>
Packit Service 68b988
Packit Service 68b988
#include <shared/hash.h>
Packit Service 68b988
#include <shared/util.h>
Packit Service 68b988
Packit Service 68b988
#include "testsuite.h"
Packit Service 68b988
Packit Service 68b988
static int freecount;
Packit Service 68b988
Packit Service 68b988
static void countfreecalls(void *v)
Packit Service 68b988
{
Packit Service 68b988
	freecount++;
Packit Service 68b988
}
Packit Service 68b988
Packit Service 68b988
static int test_hash_new(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	struct hash *h = hash_new(8, NULL);
Packit Service 68b988
	assert_return(h != NULL, EXIT_FAILURE);
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_new,
Packit Service 68b988
		.description = "test hash_new");
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_get_count(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	struct hash *h = hash_new(8, NULL);
Packit Service 68b988
	const char *k1 = "k1", *k2 = "k2", *k3 = "k3";
Packit Service 68b988
	const char *v1 = "v1", *v2 = "v2", *v3 = "v3";
Packit Service 68b988
Packit Service 68b988
	hash_add(h, k1, v1);
Packit Service 68b988
	hash_add(h, k2, v2);
Packit Service 68b988
	hash_add(h, k3, v3);
Packit Service 68b988
Packit Service 68b988
	assert_return(hash_get_count(h) == 3, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_get_count,
Packit Service 68b988
		.description = "test hash_add / hash_get_count");
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_replace(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	struct hash *h = hash_new(8, countfreecalls);
Packit Service 68b988
	const char *k1 = "k1", *k2 = "k2", *k3 = "k3";
Packit Service 68b988
	const char *v1 = "v1", *v2 = "v2", *v3 = "v3", *v4 = "v4";
Packit Service 68b988
	const char *v;
Packit Service 68b988
	int r = 0;
Packit Service 68b988
Packit Service 68b988
	r |= hash_add(h, k1, v1);
Packit Service 68b988
	r |= hash_add(h, k2, v2);
Packit Service 68b988
	r |= hash_add(h, k3, v3);
Packit Service 68b988
Packit Service 68b988
	/* replace v1 */
Packit Service 68b988
	r |= hash_add(h, k1, v4);
Packit Service 68b988
Packit Service 68b988
	assert_return(r == 0, EXIT_FAILURE);
Packit Service 68b988
	assert_return(hash_get_count(h) == 3, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	v = hash_find(h, "k1");
Packit Service 68b988
	assert_return(streq(v, v4), EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	assert_return(freecount == 1, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_replace,
Packit Service 68b988
		.description = "test hash_add replacing existing value");
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_replace_failing(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	struct hash *h = hash_new(8, countfreecalls);
Packit Service 68b988
	const char *k1 = "k1", *k2 = "k2", *k3 = "k3";
Packit Service 68b988
	const char *v1 = "v1", *v2 = "v2", *v3 = "v3", *v4 = "v4";
Packit Service 68b988
	const char *v;
Packit Service 68b988
	int r = 0;
Packit Service 68b988
Packit Service 68b988
	r |= hash_add(h, k1, v1);
Packit Service 68b988
	r |= hash_add(h, k2, v2);
Packit Service 68b988
	r |= hash_add(h, k3, v3);
Packit Service 68b988
Packit Service 68b988
	assert_return(r == 0, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	/* replace v1 */
Packit Service 68b988
	r = hash_add_unique(h, k1, v4);
Packit Service 68b988
	assert_return(r != 0, EXIT_FAILURE);
Packit Service 68b988
	assert_return(hash_get_count(h) == 3, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	v = hash_find(h, "k1");
Packit Service 68b988
	assert_return(streq(v, v1), EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	assert_return(freecount == 0, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_replace_failing,
Packit Service 68b988
		.description = "test hash_add_unique failing to replace existing value");
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_iter(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	struct hash *h = hash_new(8, NULL);
Packit Service 68b988
	struct hash *h2 = hash_new(8, NULL);
Packit Service 68b988
	const char *k1 = "k1", *k2 = "k2", *k3 = "k3";
Packit Service 68b988
	const char *v1 = "v1", *v2 = "v2", *v3 = "v3";
Packit Service 68b988
	struct hash_iter iter;
Packit Service 68b988
	const char *k, *v;
Packit Service 68b988
Packit Service 68b988
	hash_add(h, k1, v1);
Packit Service 68b988
	hash_add(h2, k1, v1);
Packit Service 68b988
	hash_add(h, k2, v2);
Packit Service 68b988
	hash_add(h2, k2, v2);
Packit Service 68b988
	hash_add(h, k3, v3);
Packit Service 68b988
	hash_add(h2, k3, v3);
Packit Service 68b988
Packit Service 68b988
	for (hash_iter_init(h, &iter);
Packit Service 68b988
	     hash_iter_next(&iter, &k, (const void **) &v);) {
Packit Service 68b988
		v2 = hash_find(h2, k);
Packit Service 68b988
		assert_return(v2 != NULL, EXIT_FAILURE);
Packit Service 68b988
		hash_del(h2, k);
Packit Service 68b988
	}
Packit Service 68b988
Packit Service 68b988
	assert_return(hash_get_count(h) == 3, EXIT_FAILURE);
Packit Service 68b988
	assert_return(hash_get_count(h2) == 0, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
	hash_free(h2);
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_iter,
Packit Service 68b988
		.description = "test hash_iter");
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_iter_after_del(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	struct hash *h = hash_new(8, NULL);
Packit Service 68b988
	struct hash *h2 = hash_new(8, NULL);
Packit Service 68b988
	const char *k1 = "k1", *k2 = "k2", *k3 = "k3";
Packit Service 68b988
	const char *v1 = "v1", *v2 = "v2", *v3 = "v3";
Packit Service 68b988
	struct hash_iter iter;
Packit Service 68b988
	const char *k, *v;
Packit Service 68b988
Packit Service 68b988
	hash_add(h, k1, v1);
Packit Service 68b988
	hash_add(h2, k1, v1);
Packit Service 68b988
	hash_add(h, k2, v2);
Packit Service 68b988
	hash_add(h2, k2, v2);
Packit Service 68b988
	hash_add(h, k3, v3);
Packit Service 68b988
	hash_add(h2, k3, v3);
Packit Service 68b988
Packit Service 68b988
	hash_del(h, k1);
Packit Service 68b988
Packit Service 68b988
	for (hash_iter_init(h, &iter);
Packit Service 68b988
	     hash_iter_next(&iter, &k, (const void **) &v);) {
Packit Service 68b988
		v2 = hash_find(h2, k);
Packit Service 68b988
		assert_return(v2 != NULL, EXIT_FAILURE);
Packit Service 68b988
		hash_del(h2, k);
Packit Service 68b988
	}
Packit Service 68b988
Packit Service 68b988
	assert_return(hash_get_count(h) == 2, EXIT_FAILURE);
Packit Service 68b988
	assert_return(hash_get_count(h2) == 1, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
	hash_free(h2);
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_iter_after_del,
Packit Service 68b988
		.description = "test hash_iter, after deleting element");
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_free(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	struct hash *h = hash_new(8, countfreecalls);
Packit Service 68b988
	const char *k1 = "k1", *k2 = "k2", *k3 = "k3";
Packit Service 68b988
	const char *v1 = "v1", *v2 = "v2", *v3 = "v3";
Packit Service 68b988
Packit Service 68b988
	hash_add(h, k1, v1);
Packit Service 68b988
	hash_add(h, k2, v2);
Packit Service 68b988
	hash_add(h, k3, v3);
Packit Service 68b988
Packit Service 68b988
	hash_del(h, k1);
Packit Service 68b988
Packit Service 68b988
	assert_return(freecount == 1, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	assert_return(hash_get_count(h) == 2, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
Packit Service 68b988
	assert_return(freecount == 3, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_free,
Packit Service 68b988
		.description = "test hash_free calling free function for all values");
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_add_unique(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	const char *k[] = { "k1", "k2", "k3", "k4", "k5" };
Packit Service 68b988
	const char *v[] = { "v1", "v2", "v3", "v4", "v5" };
Packit Service 68b988
	unsigned int i, j, N;
Packit Service 68b988
Packit Service 68b988
	N = ARRAY_SIZE(k);
Packit Service 68b988
	for (i = 0; i < N; i++) {
Packit Service 68b988
		/* With N - 1 buckets, there'll be a bucket with more than one key. */
Packit Service 68b988
		struct hash *h = hash_new(N - 1, NULL);
Packit Service 68b988
Packit Service 68b988
		/* Add the keys in different orders. */
Packit Service 68b988
		for (j = 0; j < N; j++) {
Packit Service 68b988
			unsigned int idx = (j + i) % N;
Packit Service 68b988
			hash_add_unique(h, k[idx], v[idx]);
Packit Service 68b988
		}
Packit Service 68b988
Packit Service 68b988
		assert_return(hash_get_count(h) == N, EXIT_FAILURE);
Packit Service 68b988
		hash_free(h);
Packit Service 68b988
	}
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_add_unique,
Packit Service 68b988
		.description = "test hash_add_unique with different key orders")
Packit Service 68b988
Packit Service 68b988
Packit Service 68b988
static int test_hash_massive_add_del(const struct test *t)
Packit Service 68b988
{
Packit Service 68b988
	char buf[1024 * 8];
Packit Service 68b988
	char *k;
Packit Service 68b988
	struct hash *h;
Packit Service 68b988
	unsigned int i, N = 1024;
Packit Service 68b988
Packit Service 68b988
	h = hash_new(8, NULL);
Packit Service 68b988
Packit Service 68b988
	k = &buf[0];
Packit Service 68b988
	for (i = 0; i < N; i++) {
Packit Service 68b988
		snprintf(k, 8, "k%d", i);
Packit Service 68b988
		hash_add(h, k, k);
Packit Service 68b988
		k += 8;
Packit Service 68b988
	}
Packit Service 68b988
Packit Service 68b988
	assert_return(hash_get_count(h) == N, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	k = &buf[0];
Packit Service 68b988
	for (i = 0; i < N; i++) {
Packit Service 68b988
		hash_del(h, k);
Packit Service 68b988
		k += 8;
Packit Service 68b988
	}
Packit Service 68b988
Packit Service 68b988
	assert_return(hash_get_count(h) == 0, EXIT_FAILURE);
Packit Service 68b988
Packit Service 68b988
	hash_free(h);
Packit Service 68b988
	return 0;
Packit Service 68b988
}
Packit Service 68b988
DEFINE_TEST(test_hash_massive_add_del,
Packit Service 68b988
		.description = "test multiple adds followed by multiple dels")
Packit Service 68b988
Packit Service 68b988
TESTSUITE_MAIN();