/*
* Copyright (c) 2000-2005 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.
*/
#include "sm/generic.h"
SM_IDSTR(id, "@(#)$Id: t-rpool.c,v 1.18 2005/04/14 17:14:02 ca Exp $")
#include <stdio.h>
#include "sm/assert.h"
#include "sm/debug.h"
#include "sm/heap.h"
#include "sm/rpool.h"
#include "sm/test.h"
#if SM_HEAP_CHECK
#include "sm/io.h"
extern SM_DEBUG_T SmHeapCheck;
# define HEAP_CHECK (SmHeapCheck > 0)
#else
# define HEAP_CHECK 0
#endif
static void rfree(void *cx);
static int freeattachments = 0;
static void
rfree(cx)
void *cx;
{
SM_TEST(freeattachments > 0);
--freeattachments;
if (SmTestVerbose)
(void) fprintf(stdout,"rfree freeing `%s'\n", (char *) cx);
}
#define TRPOOLS 26
#define RPMAXS 32768
#define M1 128
#define M2 256
#define M3 512
#define M4 1000
int
main(int argc, char *argv[])
{
sm_rpool_P rpool;
char *p, *np;
char *a[TRPOOLS];
int i, c;
size_t s, l, j;
sm_rpool_attach_T att;
#if SM_HEAP_CHECK
SmHeapCheck = 0;
#endif
while ((c = getopt(argc, argv, "H:")) != -1)
{
switch (c)
{
#if SM_HEAP_CHECK
case 'H':
SmHeapCheck = atoi(optarg);
break;
#endif /* SM_HEAP_CHECK */
#if 0
default:
usage(argv[0]);
return(1);
#endif /* 0 */
}
}
sm_test_begin(argc, argv, "test rpool");
rpool = sm_rpool_new(NULL);
SM_TEST(rpool != NULL);
att = sm_rpool_attach(rpool, rfree, "attachment #1");
SM_TEST(att != NULL);
++freeattachments;
for (i = 1; i < TRPOOLS; ++i)
{
size_t sz;
sz = i * i * i;
a[i] = sm_rpool_malloc(rpool, sz);
SM_TEST(a[i] != NULL);
if (a[i] == NULL)
{
fprintf(stderr, "failed for i=%d, sz=%d\n", i,
(int) sz);
goto err;
}
p = a[i];
for (j = 0; j < sz; ++j)
*p++ = 'a' + i;
}
att = sm_rpool_attach(rpool, rfree, "attachment #2");
++freeattachments;
(void) sm_rpool_attach(rpool, rfree, "attachment #3");
++freeattachments;
sm_rpool_detach(att);
--freeattachments;
sm_rpool_delete(rpool);
SM_TEST(freeattachments == 0);
rpool = sm_rpool_new(NULL);
SM_TEST(rpool != NULL);
sm_rpool_setsizes(rpool, 8192, 4096, RPMAXS);
p = sm_rpool_malloc(rpool, RPMAXS);
SM_TEST(p != NULL);
sm_rpool_delete(rpool);
rpool = sm_rpool_new(NULL);
SM_TEST(rpool != NULL);
p = sm_rpool_malloc(rpool, M1);
SM_TEST(p != NULL);
for (i = 0; i < M1; i++)
p[i] = (uchar) i;
for (i = 0; i < M1; i++)
SM_TEST((uchar) p[i] == (uchar) i);
np = sm_rpool_realloc(rpool, p, M1, M2);
SM_TEST(np != NULL);
for (i = 0; i < M1; i++)
SM_TEST(np[i] == (uchar) i);
for (i = M1; i < M2; i++)
np[i] = (uchar) i;
p = sm_rpool_realloc(rpool, np, M2, M3);
SM_TEST(p != NULL);
for (i = 0; i < M2; i++)
SM_TEST((uchar) p[i] == (uchar) i);
for (i = M2; i < M3; i++)
p[i] = (uchar) i;
np = sm_rpool_realloc(rpool, p, M3, M4);
SM_TEST(np != NULL);
for (i = 0; i < M3; i++)
SM_TEST((uchar) np[i] == (uchar) i);
sm_rpool_delete(rpool);
rpool = sm_rpool_new(NULL);
SM_TEST(rpool != NULL);
sm_rpool_setsizes(rpool, 8192, 4096, RPMAXS);
p = sm_rpool_malloc(rpool, RPMAXS + 1);
SM_TEST(p == NULL);
p = sm_rpool_malloc(rpool, RPMAXS / 2);
SM_TEST(p != NULL);
p = sm_rpool_malloc(rpool, RPMAXS / 2);
SM_TEST(p != NULL);
p = sm_rpool_malloc(rpool, 2);
SM_TEST(p == NULL);
sm_rpool_delete(rpool);
rpool = sm_rpool_new(NULL);
SM_TEST(rpool != NULL);
sm_rpool_setsizes(rpool, 8192, 4096, RPMAXS);
for (j = 0; j < RPMAXS / SM_ALIGN_SIZE; ++j)
{
p = sm_rpool_malloc(rpool, SM_ALIGN_SIZE);
SM_TEST(p != NULL);
}
p = sm_rpool_malloc(rpool, 1);
SM_TEST(p == NULL);
#if SM_HEAP_CHECK
if (HEAP_CHECK)
{
sm_io_fprintf(smioout, "heap after filling up rpool:\n");
sm_heap_report(smioout, 3);
}
#endif /* SM_HEAP_CHECK */
sm_rpool_delete(rpool);
rpool = sm_rpool_new(NULL);
SM_TEST(rpool != NULL);
for (s = 10; s < 1000; s += 50)
{
p = sm_rpool_zalloc(rpool, s);
SM_TEST(p != NULL);
if (p != NULL)
{
char *ptr;
ptr = p;
for (l = 0; l < s; l++)
SM_TEST(ptr[l] == '\0');
}
}
sm_rpool_delete(rpool);
#if SM_HEAP_CHECK
/* XXX more tests? */
if (HEAP_CHECK)
{
sm_io_fprintf(smioout, "heap after freeing rpool:\n");
sm_heap_report(smioout, 3);
}
#endif /* SM_HEAP_CHECK */
err:
return sm_test_end();
}
syntax highlighted by Code2HTML, v. 0.9.1