torture_su_alloc.c 18.7 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3
/*
 * This file is part of the Sofia-SIP package
 *
4
 * Copyright (C) 2006 Nokia Corporation.
Pekka Pessi's avatar
Pekka Pessi committed
5 6 7
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
8
 * This library is free software; you can redistribute it and/or
Pekka Pessi's avatar
Pekka Pessi committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

Pekka Pessi's avatar
Pekka Pessi committed
25
/**@internal 
Pekka Pessi's avatar
Pekka Pessi committed
26 27 28 29 30
 * @file su_alloc_test.c
 *
 * Testing functions for su_alloc functions.
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
31
 *
Pekka Pessi's avatar
Pekka Pessi committed
32 33 34 35 36 37 38
 * @date Created: Thu May  2 18:17:46 2002 ppessi
 */

#include "config.h"

#include <stdio.h>
#include <string.h>
39
#include <stdlib.h>
Pekka Pessi's avatar
Pekka Pessi committed
40

41
#include <sofia-sip/su_alloc.h>
42
#include <sofia-sip/su_errno.h>
43 44
#include <sofia-sip/su_strlst.h>
#include <sofia-sip/su_alloc_stat.h>
Pekka Pessi's avatar
Pekka Pessi committed
45 46

#define TSTFLAGS tstflags
47
#include <sofia-sip/tstdef.h>
Pekka Pessi's avatar
Pekka Pessi committed
48 49 50 51 52

int tstflags;

char const *name = "su_alloc_test";

53 54 55 56 57 58 59 60 61
/* Type derived from home */
typedef struct { su_home_t home[1]; int *p; } exhome_t;

void exdestructor(void *arg)
{
  exhome_t *ex = arg;
  (*ex->p)++;
}

Michael Jerris's avatar
Michael Jerris committed
62 63 64 65 66 67
void test_destructor(void *a)
{
  su_home_t *h = a;
  h->suh_size = 13;
}

68
/** Test basic memory home operations  */
69
static int test_alloc(void)
Pekka Pessi's avatar
Pekka Pessi committed
70
{
71
  exhome_t *h0, *h1, *h2, *h3;
Pekka Pessi's avatar
Pekka Pessi committed
72
  su_home_t home[1] = { SU_HOME_INIT(home) };
73
  su_home_t home0[1];
Pekka Pessi's avatar
Pekka Pessi committed
74 75 76 77
  enum { N = 40 };
  void *m0[N], *m1[N], *m;
  char *c, *c0, *p0, *p1;
  int i;
78
  enum { destructed_once = 1 };
79
  int d0, d1a, d1, d2, d3;
Pekka Pessi's avatar
Pekka Pessi committed
80 81 82

  BEGIN();

83 84 85 86 87
  /* su_home_init() was not initializing suh_locks */
  memset(home0, 0xff, sizeof home0);
  TEST(su_home_init(home0), 0);
  TEST_VOID(su_home_deinit(home0));

88
  TEST_1(h0 = su_home_new(sizeof(*h0)));
89 90
  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));

91 92
  d0 = d1a = d1 = d2 = d3 = 0;
  h0->p = &d0; h1->p = &d1a;
93 94
  TEST(su_home_destructor(h0->home, exdestructor), 0);
  TEST(su_home_destructor(h1->home, exdestructor), 0);
95 96 97 98

  TEST_1(h2 = su_home_ref(h0->home));
  su_home_unref(h0->home);
  TEST(d0, 0);
99 100 101 102

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h0->home, 16));

103 104 105 106 107 108 109
  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h1->home, 16));

  su_home_unref(h1->home);
  TEST(d1a, destructed_once);

  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));
110
  TEST(su_home_destructor(h1->home, exdestructor), 0);
111 112
  h1->p = &d1;

113 114 115 116 117 118
  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h1->home, 16));

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h2->home, 16));

119 120
  su_home_unref(h2->home); /* Should call destructor of cloned home, too */

121 122
  TEST(d0, destructed_once);
  TEST(d1, destructed_once);
123 124

  TEST_1(h0 = su_home_new(sizeof(*h0)));
125 126 127
  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));
  TEST_1(h2 = su_home_clone(h1->home, sizeof(*h2)));
  TEST_1(h3 = su_home_clone(h2->home, sizeof(*h3)));
Pekka Pessi's avatar
Pekka Pessi committed
128

129
  TEST(su_home_threadsafe(h0->home), 0);
Pekka Pessi's avatar
Pekka Pessi committed
130 131

  for (i = 0; i < N; i++) {
132 133
    TEST_1(m0[i] = su_zalloc(h3->home, 20));
    TEST_1(m1[i] = su_zalloc(h2->home, 20));
Pekka Pessi's avatar
Pekka Pessi committed
134 135
  }

136
  TEST_1(m = su_zalloc(h2->home, 20));
Pekka Pessi's avatar
Pekka Pessi committed
137

138 139
  TEST_1(su_in_home(h2->home, m));
  TEST_1(!su_in_home(h2->home, (char *)m + 1));
140
  TEST_1(!su_in_home(h2->home, (void *)(intptr_t)su_in_home));
141 142 143 144
  TEST_1(!su_in_home(h3->home, m));
  TEST_1(!su_in_home(NULL, m));
  TEST_1(!su_in_home(h3->home, NULL));

Pekka Pessi's avatar
Pekka Pessi committed
145 146
  TEST(su_home_move(home, NULL), 0);
  TEST(su_home_move(NULL, home), 0);
147 148 149
  TEST(su_home_move(home, h3->home), 0);
  TEST(su_home_move(h2->home, h3->home), 0);
  TEST(su_home_move(h1->home, h2->home), 0);
Pekka Pessi's avatar
Pekka Pessi committed
150 151 152 153

  su_home_preload(home, 1, 1024 + 2 * 8);

  TEST_1(c = su_zalloc(home, 64)); p0 = c; p1 = c + 1024;
154
  TEST_P(c = su_realloc(home, c0 = c, 127), c0);
Pekka Pessi's avatar
Pekka Pessi committed
155

156
  TEST_1(c = c0 = su_zalloc(home, 1024 - 128));
Pekka Pessi's avatar
Pekka Pessi committed
157
  TEST_1(p0 <= c); TEST_1(c < p1);
158 159 160
  TEST_P(c = su_realloc(home, c, 128), c0);
  TEST_P(c = su_realloc(home, c, 1023 - 128), c0);
  TEST_P(c = su_realloc(home, c, 1024 - 128), c0);
Pekka Pessi's avatar
Pekka Pessi committed
161 162 163
  TEST_1(c = su_realloc(home, c, 1024));
  TEST_1(c = su_realloc(home, c, 2 * 1024));

164
  TEST_P(c = su_realloc(home, p0, 126), p0);
Pekka Pessi's avatar
Pekka Pessi committed
165
  TEST_1(c = su_realloc(home, p0, 1024));
166
  TEST_P(c = su_realloc(home, c, 0), NULL);
Pekka Pessi's avatar
Pekka Pessi committed
167 168

  su_home_check(home);
169
  su_home_deinit(home);
Pekka Pessi's avatar
Pekka Pessi committed
170

171 172 173 174
  su_home_check(h2->home);
  su_home_zap(h2->home);
  su_home_check(h0->home);
  su_home_zap(h0->home);
Pekka Pessi's avatar
Pekka Pessi committed
175

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
  {
    su_home_t h1[1];

    memset(h1, 0, sizeof h1);

    TEST(su_home_init(h1), 0);
    TEST(su_home_threadsafe(h1), 0);

    TEST_1(su_home_ref(h1));
    TEST_1(su_home_ref(h1));

    TEST(su_home_destructor(h1, test_destructor), 0);

    TEST_1(!su_home_unref(h1));
    TEST_1(!su_home_unref(h1));
    TEST_1(su_home_unref(h1));
    TEST(h1->suh_size, 13);
  }

Pekka Pessi's avatar
Pekka Pessi committed
195 196 197
  END();
}

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
static int test_lock(void)
{
  su_home_t home[1] = { SU_HOME_INIT(home) };

  BEGIN();

  TEST(su_home_mutex_lock(home), -1);
  TEST(su_home_mutex_unlock(home), -1);

  TEST(su_home_lock(home), -1);
  TEST(su_home_trylock(home), -1);
  TEST(su_home_unlock(home), -1);

  TEST(su_home_init(home), 0);

  TEST(su_home_mutex_lock(home), 0);
  TEST(su_home_trylock(home), -1);
  TEST(su_home_mutex_unlock(home), 0);
  TEST(su_home_trylock(home), -1);

  TEST(su_home_threadsafe(home), 0);

  TEST(su_home_mutex_lock(home), 0);
  TEST(su_home_trylock(home), EBUSY);
  TEST(su_home_mutex_unlock(home), 0);

  TEST(su_home_lock(home), 0);
  TEST(su_home_trylock(home), EBUSY);
  TEST(su_home_unlock(home), 0);

  TEST(su_home_trylock(home), 0);
  TEST(su_home_unlock(home), 0);

  END();
}

Pekka Pessi's avatar
Pekka Pessi committed
234 235 236 237 238 239 240 241 242 243
static int test_strdupcat(void)
{
  su_home_t home[1] = { SU_HOME_INIT(home) };

  BEGIN();

  TEST_S(su_strdup(home, "foo"), "foo");
  TEST_S(su_strcat(home, "foo", "bar"), "foobar");
  TEST_S(su_strndup(home, "foobar", 3), "foo");

244 245 246
  TEST_S(su_strcat_all(home, NULL), "");
  TEST_S(su_strcat_all(home, "a", "", "b", "", NULL), "ab");

Pekka Pessi's avatar
Pekka Pessi committed
247
  su_home_deinit(home);
248

Pekka Pessi's avatar
Pekka Pessi committed
249 250 251
  END();
}

252 253 254 255 256 257 258 259 260 261 262 263 264 265
#include <stdarg.h>

static int test_sprintf(char const *fmt, ...)
{
  BEGIN();

  su_home_t home[1] = { SU_HOME_INIT(home) };
  va_list va;

  TEST_S(su_sprintf(home, "foo%s", "bar"), "foobar");

  va_start(va, fmt);
  TEST_S(su_vsprintf(home, fmt, va), "foo.bar");

266
  TEST_S(su_sprintf(home, "foo%200s", "bar"),
267 268 269 270 271 272
	 "foo                                                             "
	 "                                                                "
	 "                                                                "
	 "        bar");

  su_home_deinit(home);
273

274 275 276
  END();
}

Pekka Pessi's avatar
Pekka Pessi committed
277 278 279 280 281 282 283 284 285
static int test_strlst(void)
{
  su_home_t home[1] = { SU_HOME_INIT(home) };
  su_strlst_t *l, *l1, *l2;
  char *s;
  char foo[] = "foo";
  char bar[] = "bar";
  char baz[] = "baz";

286 287
  su_home_stat_t parent[1], kids[2];

Pekka Pessi's avatar
Pekka Pessi committed
288 289
  BEGIN();

290 291 292
  parent->hs_size = (sizeof parent);
  kids[0].hs_size = (sizeof kids[0]);
  kids[1].hs_size = (sizeof kids[1]);
293

294 295
  su_home_init_stats(home);

Pekka Pessi's avatar
Pekka Pessi committed
296 297 298 299 300 301 302 303 304 305
  /* Test API for invalid arguments */
  TEST_1(l = su_strlst_create(NULL));
  TEST_1(l2 = su_strlst_dup(home, l));
  TEST_VOID(su_strlst_destroy(l2));
  TEST_1(!su_strlst_dup(home, NULL));
  TEST_1(l1 = su_strlst_copy(home, l));
  TEST_VOID(su_strlst_destroy(l1));
  TEST_1(!su_strlst_copy(home, NULL));

  TEST_VOID(su_strlst_destroy(NULL));
306
  TEST_VOID(su_strlst_destroy(l));
Pekka Pessi's avatar
Pekka Pessi committed
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321

  TEST_1(!su_strlst_dup_append(NULL, "aa"));
  TEST_1(!su_strlst_append(NULL, "bee"));
  TEST_1(!su_strlst_item(NULL, 1));
  TEST_1(!su_strlst_set_item(NULL, 1, "cee"));
  TEST_1(!su_strlst_remove(NULL, 1));
  TEST_S(s = su_strlst_join(NULL, home, "a"), "");
  TEST_VOID(su_free(home, s));

  TEST_1(!su_strlst_split(home, NULL, "."));

  TEST_1(s = su_strdup(home, "aaa"));
  TEST_1(l = su_strlst_split(home, s, NULL));
  TEST_S(su_strlst_item(l, 0), "aaa");
  TEST_VOID(su_strlst_destroy(l));
322

Pekka Pessi's avatar
Pekka Pessi committed
323 324 325 326 327 328 329 330
  TEST_VOID(su_free(home, s));

  TEST_1(!su_strlst_dup_split(home, NULL, "."));

  TEST_1(l1 = su_strlst_dup_split(home, "aaa", ""));
  TEST_S(su_strlst_item(l1, 0), "aaa");
  TEST_VOID(su_strlst_destroy(l1));

331
  TEST_SIZE(su_strlst_len(NULL), 0);
Pekka Pessi's avatar
Pekka Pessi committed
332 333
  TEST_1(!su_strlst_get_array(NULL));
  TEST_VOID(su_strlst_free_array(NULL, NULL));
334

Pekka Pessi's avatar
Pekka Pessi committed
335 336 337 338 339 340 341 342
  TEST_1(l = su_strlst_create(home));
  TEST_VOID(su_strlst_free_array(l, NULL));
  TEST_S(su_strlst_dup_append(l, "oh"), "oh");
  TEST_VOID(su_strlst_free_array(l, NULL));
  TEST_VOID(su_strlst_destroy(l));

  /* Test functionality */
  TEST_1(l = su_strlst_create(home));
343 344

  su_home_init_stats(su_strlst_home(l));
345 346

  TEST_S(su_strlst_join(l, home, "bar"), "");
Pekka Pessi's avatar
Pekka Pessi committed
347 348 349
  TEST_S(su_strlst_append(l, foo), "foo");
  TEST_S(su_strlst_dup_append(l, bar), "bar");
  TEST_S(su_strlst_append(l, baz), "baz");
350
  TEST_S((s = su_strlst_join(l, home, "!")), "foo!bar!baz");
Pekka Pessi's avatar
Pekka Pessi committed
351 352 353 354

  TEST_S(su_strlst_item(l, 0), foo);
  TEST_S(su_strlst_item(l, 1), bar);
  TEST_S(su_strlst_item(l, 2), baz);
355 356
  TEST_P(su_strlst_item(l, 3), NULL);
  TEST_P(su_strlst_item(l, (unsigned)-1), NULL);
Pekka Pessi's avatar
Pekka Pessi committed
357 358 359

  TEST_1(l1 = su_strlst_copy(su_strlst_home(l), l));
  TEST_1(l2 = su_strlst_dup(su_strlst_home(l), l));
360

Pekka Pessi's avatar
Pekka Pessi committed
361
  strcpy(foo, "hum"); strcpy(bar, "pah"); strcpy(baz, "hah");
362

363 364
  TEST_S(su_strlst_dup_append(l1, "kuik"), "kuik");
  TEST_S(su_strlst_dup_append(l2, "uik"), "uik");
365 366 367 368

  TEST_S((s = su_strlst_join(l, home, ".")), "hum.bar.hah");
  TEST_S((su_strlst_join(l1, home, ".")), "hum.bar.hah.kuik");
  TEST_S((su_strlst_join(l2, home, ".")), "foo.bar.baz.uik");
369 370 371 372 373

  su_strlst_destroy(l2);

  su_home_get_stats(su_strlst_home(l), 0, kids, sizeof kids);

374 375 376
  TEST_SIZE(kids->hs_clones, 2);
  TEST64(kids->hs_allocs.hsa_number, 3);
  TEST64(kids->hs_frees.hsf_number, 1);
Pekka Pessi's avatar
Pekka Pessi committed
377 378 379 380 381 382

  su_strlst_destroy(l);

  TEST_S(s, "hum.bar.hah");

  TEST_1(l = su_strlst_create(home));
383 384 385

  su_home_init_stats(su_strlst_home(l));

Pekka Pessi's avatar
Pekka Pessi committed
386 387 388 389 390 391 392 393 394 395 396 397
  TEST_S(su_strlst_join(l, home, "bar"), "");
  TEST_S(su_strlst_append(l, "a"), "a");
  TEST_S(su_strlst_append(l, "b"), "b");
  TEST_S(su_strlst_append(l, "c"), "c");
  TEST_S(su_strlst_append(l, "d"), "d");
  TEST_S(su_strlst_append(l, "e"), "e");
  TEST_S(su_strlst_append(l, "f"), "f");
  TEST_S(su_strlst_append(l, "g"), "g");
  TEST_S(su_strlst_append(l, "h"), "h");
  TEST_S(su_strlst_append(l, "i"), "i");
  TEST_S(su_strlst_append(l, "j"), "j");

398
  TEST_S((s = su_strlst_join(l, home, "")), "abcdefghij");
Pekka Pessi's avatar
Pekka Pessi committed
399 400 401 402 403 404 405 406 407 408 409
  TEST_S(su_strlst_append(l, "a"), "a");
  TEST_S(su_strlst_append(l, "b"), "b");
  TEST_S(su_strlst_append(l, "c"), "c");
  TEST_S(su_strlst_append(l, "d"), "d");
  TEST_S(su_strlst_append(l, "e"), "e");
  TEST_S(su_strlst_append(l, "f"), "f");
  TEST_S(su_strlst_append(l, "g"), "g");
  TEST_S(su_strlst_append(l, "h"), "h");
  TEST_S(su_strlst_append(l, "i"), "i");
  TEST_S(su_strlst_append(l, "j"), "j");

410
  TEST_S((s = su_strlst_join(l, home, "")), "abcdefghijabcdefghij");
Pekka Pessi's avatar
Pekka Pessi committed
411

412 413 414
  su_home_get_stats(su_strlst_home(l), 0, kids + 1, (sizeof kids[1]));
  su_home_stat_add(kids, kids + 1);

Pekka Pessi's avatar
Pekka Pessi committed
415
  su_strlst_destroy(l);
416 417

  su_home_get_stats(home, 1, parent, (sizeof parent));
418

Pekka Pessi's avatar
Pekka Pessi committed
419 420 421 422 423 424 425 426
  su_home_check(home);
  su_home_deinit(home);

  su_home_init(home);

  {
    char s[] = "foo\nfaa\n";
    TEST_1((l = su_strlst_split(home, s, "\n")));
427
    TEST_SIZE(su_strlst_len(l), 3);
Pekka Pessi's avatar
Pekka Pessi committed
428 429 430 431 432 433 434
    TEST_1(su_strlst_append(l, "bar"));
    TEST_S(su_strlst_join(l, home, "\n"), "foo\nfaa\n\nbar");
  }

  {
    char s[] = "foo";
    TEST_1((l = su_strlst_split(home, s, "\n")));
435
    TEST_SIZE(su_strlst_len(l), 1);
Pekka Pessi's avatar
Pekka Pessi committed
436 437 438 439 440
  }

  {
    char s[] = "\n\n";
    TEST_1((l = su_strlst_split(home, s, "\n")));
441
    TEST_SIZE(su_strlst_len(l), 3);
Pekka Pessi's avatar
Pekka Pessi committed
442 443 444 445 446
  }

  {
    char s[] = "";
    TEST_1((l = su_strlst_split(home, s, "\n")));
447
    TEST_SIZE(su_strlst_len(l), 1);
Pekka Pessi's avatar
Pekka Pessi committed
448
  }
449

Pekka Pessi's avatar
Pekka Pessi committed
450 451 452 453 454 455 456 457 458 459 460 461
  {
    int i;

#define S \
      "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\n" \
      "n\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n" \
      "A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\n" \
      "N\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n"

    char s[] = S;

    TEST_1((l = su_strlst_split(home, s, "\n")));
462
    TEST_SIZE(su_strlst_len(l), 53);
Pekka Pessi's avatar
Pekka Pessi committed
463 464 465 466 467 468 469 470
    TEST_1(su_strlst_append(l, "bar"));
    TEST_S(su_strlst_join(l, home, "\n"), S "\nbar");

    TEST_1(!su_strlst_remove(l, 54));

    for (i = 0; i < 54; i++) {
      TEST_1(su_strlst_remove(l, 0));
      TEST_1(!su_strlst_remove(l, 53 - i));
471
      TEST_SIZE(su_strlst_len(l), 53 - i);
Pekka Pessi's avatar
Pekka Pessi committed
472 473 474
    }

    TEST_1(!su_strlst_remove(l, 0));
475
    TEST_SIZE(su_strlst_len(l), 0);
Pekka Pessi's avatar
Pekka Pessi committed
476 477
  }

478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
  {
    char const *s0;

    TEST_1(l = su_strlst_create_with(NULL, s0 = "a", "b", NULL));
    TEST_1(su_strlst_item(l, 0) == s0);
    TEST_S(su_strlst_item(l, 0), "a");
    TEST_S(su_strlst_item(l, 1), "b");
    TEST_1(su_strlst_item(l, 2) == NULL);

    TEST_S(su_slprintf(l, "1: %u", 1), "1: 1");
    TEST_S(su_slprintf(l, "1.0: %g", 1.0), "1.0: 1");

    TEST_1(su_strlst_append(l, ""));

    TEST_S(su_strlst_join(l, home, "\n"), 
	   "a\n" "b\n" "1: 1\n" "1.0: 1\n");

    TEST_VOID(su_strlst_destroy(l));

    TEST_1(l2 = su_strlst_create_with_dup(NULL,
					  s0 = "0", "1", "2", "3",
					  "4", "5", "6", "7",
					  NULL));
    TEST_1(su_strlst_item(l2, 0) != s0);
    TEST_S(su_strlst_item(l2, 0), "0");
    TEST_S(su_strlst_item(l2, 1), "1");
    TEST_S(su_strlst_item(l2, 2), "2");
    TEST_S(su_strlst_item(l2, 3), "3");
    TEST_S(su_strlst_item(l2, 4), "4");
    TEST_S(su_strlst_item(l2, 5), "5");
    TEST_S(su_strlst_item(l2, 6), "6");
    TEST_S(su_strlst_item(l2, 7), "7");
    TEST_1(su_strlst_item(l2, 8) == NULL);

    TEST_S(su_strlst_join(l2, home, ""), "01234567");

    TEST_VOID(su_strlst_destroy(l2));
  }
  su_home_check(home);
Pekka Pessi's avatar
Pekka Pessi committed
517 518 519 520 521
  su_home_deinit(home);

  END();
}

522
#include <sofia-sip/su_vector.h>
Pekka Pessi's avatar
Pekka Pessi committed
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552

typedef struct test_data_s {
  su_home_t test_home[1];
  int data;
} test_data_t;

static void test_vector_free(void *data)
{
  su_home_zap((su_home_t *) data);
}

static int test_vectors(void)
{
  su_home_t home[1] = { SU_HOME_INIT(home) };
  su_vector_t *v, *w;
  test_data_t *data1, *data2, *data3, *data4;
  char foo[] = "foo";
  char bar[] = "bar";
  char baz[] = "baz";
  void **a;
  int i;

  BEGIN();

  TEST_1(v = su_vector_create(home, NULL));
  TEST_1(su_vector_is_empty(v));
  TEST(su_vector_append(v, foo), 0);
  TEST(su_vector_append(v, bar), 0);
  TEST(su_vector_insert(v, 0, baz), 0);

553 554 555 556 557
  TEST_P(su_vector_item(v, 0), baz);
  TEST_P(su_vector_item(v, 1), foo);
  TEST_P(su_vector_item(v, 2), bar);
  TEST_P(su_vector_item(v, 3), NULL);
  TEST_P(su_vector_item(v, (unsigned)-1), NULL);
Pekka Pessi's avatar
Pekka Pessi committed
558
  TEST_1(!su_vector_is_empty(v));
559

Pekka Pessi's avatar
Pekka Pessi committed
560 561 562 563 564 565 566 567 568 569 570 571 572 573
  su_vector_destroy(v);

  TEST_1(v = su_vector_create(home, NULL));
  TEST(su_vector_insert(v, 0, "j"), 0);
  TEST(su_vector_insert(v, 0, "i"), 0);
  TEST(su_vector_insert(v, 0, "h"), 0);
  TEST(su_vector_insert(v, 0, "g"), 0);
  TEST(su_vector_insert(v, 0, "f"), 0);
  TEST(su_vector_insert(v, 0, "e"), 0);
  TEST(su_vector_insert(v, 0, "d"), 0);
  TEST(su_vector_insert(v, 0, "c"), 0);
  TEST(su_vector_insert(v, 0, "b"), 0);
  TEST(su_vector_insert(v, 0, "a"), 0);

574
  TEST_SIZE(su_vector_len(v), 10);
Pekka Pessi's avatar
Pekka Pessi committed
575 576 577 578 579 580
  TEST_1(a = su_vector_get_array(v));

  for (i = 0; i < 10; i++) {
    TEST_S(su_vector_item(v, i), a[i]);
  }

581 582
  TEST_P(su_vector_item(v, 10), NULL);
  TEST_P(a[10], NULL);
Pekka Pessi's avatar
Pekka Pessi committed
583 584 585 586 587 588 589 590 591 592 593 594 595

  TEST_1(w = su_vector_create(home, NULL));
  TEST(su_vector_append(w, "a"), 0);
  TEST(su_vector_append(w, "b"), 0);
  TEST(su_vector_append(w, "c"), 0);
  TEST(su_vector_append(w, "d"), 0);
  TEST(su_vector_append(w, "e"), 0);
  TEST(su_vector_append(w, "f"), 0);
  TEST(su_vector_append(w, "g"), 0);
  TEST(su_vector_append(w, "h"), 0);
  TEST(su_vector_append(w, "i"), 0);
  TEST(su_vector_append(w, "j"), 0);

596
  TEST_SIZE(su_vector_len(w), 10);
Pekka Pessi's avatar
Pekka Pessi committed
597 598 599 600 601 602 603 604 605 606

  for (i = 0; i < 10; i++) {
    TEST_S(su_vector_item(v, i), a[i]);
  }

  su_vector_empty(w);
  TEST_1(su_vector_is_empty(w));

  su_vector_destroy(v);
  su_vector_destroy(w);
607

Pekka Pessi's avatar
Pekka Pessi committed
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
  TEST_1(v = su_vector_create(home, test_vector_free));
  data1 = su_home_clone(home, sizeof(test_data_t));
  data1->data = 1;

  data2 = su_home_clone(home, sizeof(test_data_t));
  data2->data = 2;

  data3 = su_home_clone(home, sizeof(test_data_t));
  data3->data = 3;

  data4 = su_home_clone(home, sizeof(test_data_t));
  data4->data = 4;

  TEST(su_vector_append(v, data1), 0);
  TEST(su_vector_append(v, data2), 0);
  TEST(su_vector_append(v, data3), 0);
624
  TEST(su_vector_append(v, data4), 0);
Pekka Pessi's avatar
Pekka Pessi committed
625

626
  TEST_SIZE(su_vector_len(v), 4);
Pekka Pessi's avatar
Pekka Pessi committed
627

628 629 630 631
  TEST_P(su_vector_item(v, 0), data1);
  TEST_P(su_vector_item(v, 1), data2);
  TEST_P(su_vector_item(v, 2), data3);
  TEST_P(su_vector_item(v, 3), data4);
Pekka Pessi's avatar
Pekka Pessi committed
632 633 634 635 636 637 638 639

  TEST(data1->data, 1);
  TEST(data2->data, 2);
  TEST(data3->data, 3);
  TEST(data4->data, 4);

  TEST(su_vector_remove(v, 2), 0);

640
  TEST_SIZE(su_vector_len(v), 3);
Pekka Pessi's avatar
Pekka Pessi committed
641

642 643 644
  TEST_P(su_vector_item(v, 0), data1);
  TEST_P(su_vector_item(v, 1), data2);
  TEST_P(su_vector_item(v, 2), data4);
Pekka Pessi's avatar
Pekka Pessi committed
645 646 647 648 649 650 651 652 653 654 655 656

  TEST(data1->data, 1);
  TEST(data2->data, 2);
  TEST(data4->data, 4);

  su_vector_destroy(v);

  su_home_check(home);
  su_home_deinit(home);

  END();
}
Pekka Pessi's avatar
Pekka Pessi committed
657 658

#define ALIGNMENT (8)
659
#define ALIGN(n)  ((size_t)((n) + (ALIGNMENT - 1)) & (size_t)~(ALIGNMENT - 1))
Pekka Pessi's avatar
Pekka Pessi committed
660 661 662 663 664 665

static int test_auto(void)
{
  BEGIN();

  int i;
666
  su_home_t tmphome[SU_HOME_AUTO_SIZE(8000)];
Pekka Pessi's avatar
Pekka Pessi committed
667
  char *b = NULL;
668
  su_home_stat_t hs[1];
Pekka Pessi's avatar
Pekka Pessi committed
669 670 671

  TEST_1(!su_home_auto(tmphome, sizeof tmphome[0]));
  TEST_1(su_home_auto(tmphome, sizeof tmphome));
672

Pekka Pessi's avatar
Pekka Pessi committed
673 674 675 676 677 678
  for (i = 0; i < 8192; i++)
    TEST_1(su_alloc(tmphome, 12));

  TEST_VOID(su_home_deinit(tmphome));

  TEST_1(su_home_auto(tmphome, sizeof tmphome));
679

680 681
  su_home_init_stats(tmphome);

Pekka Pessi's avatar
Pekka Pessi committed
682 683
  for (i = 1; i < 8192; i++) {
    TEST_1(b = su_realloc(tmphome, b, i));
684 685 686 687 688 689 690 691 692 693
    b[i - 1] = '\125';
  }

  for (i = 1; i < 8192; i++) {
    TEST(b[i - 1], '\125');
  }

  for (i = 1; i < 8192; i++) {
    TEST_1(b = su_realloc(tmphome, b, i));
    b[i - 1] = '\125';
694

695 696
    if ((i % 32) == 0)
      TEST_1(b = su_realloc(tmphome, b, 1));
Pekka Pessi's avatar
Pekka Pessi committed
697 698
  }

699 700
  su_home_get_stats(tmphome, 0, hs, sizeof *hs);

701
  TEST64(hs->hs_allocs.hsa_preload + hs->hs_allocs.hsa_number, 
702
	  8191 + 8191 + 8191 / 32);
703
  TEST64(hs->hs_frees.hsf_preload + hs->hs_frees.hsf_number,
704
	 8191 + 8191 + 8191 / 32 - 1);
705 706 707 708
  /*
    This test depends on macro SU_HOME_AUTO_SIZE() calculating
    offsetof(su_block_t, sub_nodes[7]) correctly with

709
    ((3 * sizeof (void *) + 4 * sizeof(unsigned) +
710 711
      7 * (sizeof (long) + sizeof(void *)) + 7)
  */
712 713
  TEST_1(hs->hs_frees.hsf_preload == hs->hs_allocs.hsa_preload);

714 715 716 717 718
  su_free(tmphome, b);

  for (i = 1; i < 8192; i++)
    TEST_1(b = su_alloc(tmphome, 1));

Pekka Pessi's avatar
Pekka Pessi committed
719
  TEST_VOID(su_home_deinit(tmphome));
720

Pekka Pessi's avatar
Pekka Pessi committed
721 722
  END();
}
723

724
void usage(int exitcode)
725
{
726 727
  fprintf(stderr, "usage: %s [-v] [-a]\n", name);
  exit(exitcode);
728 729 730 731 732 733 734 735 736 737
}

int main(int argc, char *argv[])
{
  int retval = 0;
  int i;

  for (i = 1; argv[i]; i++) {
    if (strcmp(argv[i], "-v") == 0)
      tstflags |= tst_verbatim;
738 739
    else if (strcmp(argv[i], "-a") == 0)
      tstflags |= tst_abort;
740
    else
741
      usage(1);
742
  }
743 744 745
#if HAVE_OPEN_C
  tstflags |= tst_verbatim;
#endif
746

747
  retval |= test_alloc();
748
  retval |= test_lock();
749 750 751 752 753 754 755 756
  retval |= test_strdupcat();
  retval |= test_sprintf("%s.%s", "foo", "bar");
  retval |= test_strlst();
  retval |= test_vectors();
  retval |= test_auto();

  return retval;
}