/*
 * Copyright (c) 2004 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

/*
**  Test id generation
**  This is a very incomplete test!
*/

#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-id-0.c,v 1.3 2004/12/26 04:08:53 ca Exp $")

#include "sm/assert.h"
#include "sm/heap.h"
#include "sm/test.h"
#include "sm/servid.h"

#include <stdio.h>

#define SMT_MAX_IDS	16
#define SMT_UNUSED_ID	(-1)

static int Verbose = 0;

static int
checkids(uint *ids, uint size)
{
	uint i, j;

	for (i = 0; i < size; i++)
	{
		if (ids[i] == SMT_UNUSED_ID)
			continue;
		for (j = i + 1; j < size; j++)
		{
			if (ids[j] == SMT_UNUSED_ID)
				continue;
			SM_TEST(ids[i] != ids[j]);
		}
	}
	return 0;
}

static int
testid(void)
{
	sm_ret_T ret;
	uint size, id, i;
	uint ids[SMT_MAX_IDS];
	id_ctx_P id_ctx;

	size = 8;
	ret = sm_new_id_ctx(size, SMT_MAX_IDS, &id_ctx);
	SM_TEST_ERR(ret == SM_SUCCESS);

	for (i = 0; i < SMT_MAX_IDS; i++)
		ids[i] = SMT_UNUSED_ID;

	for (i = 0; i < size; i++)
	{
		ret = sm_new_id(id_ctx, &id);
		SM_TEST(ret == SM_SUCCESS);
		ids[i] = id;
		checkids(ids, i);
	}
#if 0
	ret = sm_new_id(id_ctx, &id);
	SM_TEST(ret != SM_SUCCESS);
#endif /* 0 */

	for (i = 0; i < size; i++)
	{
		ret = sm_free_id(id_ctx, ids[i]);
		SM_TEST(ret == SM_SUCCESS);
		ids[i] = SMT_UNUSED_ID;
	}

	size = 10;
	ret = sm_chg_id_ctx(id_ctx, size);
	SM_TEST_ERR(ret == SM_SUCCESS);
	for (i = 0; i < size; i++)
	{
		ret = sm_new_id(id_ctx, &id);
		SM_TEST(ret == SM_SUCCESS);
		ids[i] = id;
		checkids(ids, i);
	}
	ret = sm_new_id(id_ctx, &id);
	SM_TEST(ret != SM_SUCCESS);
	for (i = 0; i < size; i++)
	{
		ret = sm_free_id(id_ctx, ids[i]);
		SM_TEST(ret == SM_SUCCESS);
		ids[i] = SMT_UNUSED_ID;
	}

	size = 2;
	ret = sm_chg_id_ctx(id_ctx, size);
	SM_TEST_ERR(ret == SM_SUCCESS);
	for (i = 0; i < size; i++)
	{
		ret = sm_new_id(id_ctx, &id);
		SM_TEST(ret == SM_SUCCESS);
		ids[i] = id;
		checkids(ids, i);
	}
	ret = sm_new_id(id_ctx, &id);
	SM_TEST(ret != SM_SUCCESS);
	for (i = 0; i < size; i++)
	{
		ret = sm_free_id(id_ctx, ids[i]);
		SM_TEST(ret == SM_SUCCESS);
		ids[i] = SMT_UNUSED_ID;
	}

	size = SMT_MAX_IDS;
	ret = sm_chg_id_ctx(id_ctx, size);
	for (i = 0; i < size; i++)
	{
		ret = sm_new_id(id_ctx, &id);
		SM_TEST(ret == SM_SUCCESS);
		ids[i] = id;
		checkids(ids, i);
	}
	ret = sm_new_id(id_ctx, &id);
	SM_TEST(ret != SM_SUCCESS);
	ret = sm_free_id(id_ctx, ids[0]);
	SM_TEST(ret == SM_SUCCESS);
	ret = sm_new_id(id_ctx, &id);
	SM_TEST(ret == SM_SUCCESS);
	SM_TEST(id == ids[0]);
	SM_TEST(id == 1);

	ret = sm_destroy_id_ctx(id_ctx);
	SM_TEST(ret == SM_SUCCESS);
	return 0;

  error:
	return -1;
}

static int
testid2(void)
{
	sm_ret_T ret;
	uint size, id, i, prev;
	id_ctx_P id_ctx;

	size = 256;
	ret = sm_new_id_ctx(size, 1024, &id_ctx);
	SM_TEST_ERR(ret == SM_SUCCESS);

	prev = 0;
	for (i = 0; i < size * 2; i++)
	{
		ret = sm_new_id(id_ctx, &id);
		SM_TEST_ERR(ret == SM_SUCCESS);
		SM_TEST_ERR(id > prev);
		prev = id;
	}

	for (i = 1; i < size * 2; i += 2)
	{
		ret = sm_free_id(id_ctx, i);
	}

	for (i = 0; i < 1024 - 256; i++)
	{
		ret = sm_new_id(id_ctx, &id);
		SM_TEST_ERR(ret == SM_SUCCESS);
		if (Verbose > 0)
			printf("i=%4d, id=%d\n", i, id);
	}

	ret = sm_new_id(id_ctx, &id);
	SM_TEST(ret != SM_SUCCESS);

	ret = sm_destroy_id_ctx(id_ctx);
	SM_TEST(ret == SM_SUCCESS);
	return 0;

  error:
	return -1;
}

int
main(int argc, char **argv)
{
	int c;

	while ((c = getopt(argc, argv, "V")) != -1)
	{
		switch (c)
		{
		  case 'V':
			++Verbose;
			break;
		  default:
			break;
		}
	}
	sm_test_begin(argc, argv, "test id-0");
	argc -= optind;
	argv += optind;

	(void) testid();
	(void) testid2();

	return sm_test_end();
}


syntax highlighted by Code2HTML, v. 0.9.1