Annotation of embedaddon/dhcp/common/tests/test_alloc.c, revision 1.1
1.1 ! misho 1: /*
! 2: * We test the functions provided in alloc.c here. These are very
! 3: * basic functions, and it is very important that they work correctly.
! 4: *
! 5: * You can see two different styles of testing:
! 6: *
! 7: * - In the first, we have a single test for each function that tests
! 8: * all of the possible ways it can operate. (This is the case for
! 9: * the buffer tests.)
! 10: *
! 11: * - In the second, we have a separate test for each of the ways a
! 12: * function can operate. (This is the case for the data_string
! 13: * tests.)
! 14: *
! 15: * The advantage of a single test per function is that you have fewer
! 16: * tests, and less duplicated and extra code. The advantage of having
! 17: * a separate test is that each test is simpler. Plus if you need to
! 18: * allow certain tests to fail for some reason (known bugs that are
! 19: * hard to fix for example), then
! 20: */
! 21:
! 22: /* TODO: dmalloc() test */
! 23:
! 24: #include "config.h"
! 25: #include "t_api.h"
! 26:
! 27: #include "dhcpd.h"
! 28:
! 29: static void test_buffer_allocate(void);
! 30: static void test_buffer_reference(void);
! 31: static void test_buffer_dereference(void);
! 32: static void test_data_string_forget(void);
! 33: static void test_data_string_forget_nobuf(void);
! 34: static void test_data_string_copy(void);
! 35: static void test_data_string_copy_nobuf(void);
! 36:
! 37: /*
! 38: * T_testlist is a list of tests that are invoked.
! 39: */
! 40: testspec_t T_testlist[] = {
! 41: { test_buffer_allocate,
! 42: "buffer_allocate()" },
! 43: { test_buffer_reference,
! 44: "buffer_reference()" },
! 45: { test_buffer_dereference,
! 46: "buffer_dereference()" },
! 47: { test_data_string_forget,
! 48: "data_string_forget()" },
! 49: { test_data_string_forget_nobuf,
! 50: "data_string_forget(), no buffer" },
! 51: { test_data_string_copy,
! 52: "data_string_copy()" },
! 53: { test_data_string_copy_nobuf,
! 54: "data_string_copy(), no buffer" },
! 55: { NULL, NULL }
! 56: };
! 57:
! 58: static void
! 59: test_buffer_allocate(void) {
! 60: static const char *test_desc =
! 61: "buffer_allocate basic test";
! 62:
! 63: struct buffer *buf;
! 64:
! 65: t_assert("buffer_allocate", 1, T_REQUIRED, "%s", test_desc);
! 66:
! 67: /*
! 68: * Check a 0-length buffer.
! 69: */
! 70: buf = NULL;
! 71: if (!buffer_allocate(&buf, 0, MDL)) {
! 72: t_info("failed on 0-len buffer\n");
! 73: t_result(T_FAIL);
! 74: return;
! 75: }
! 76: if (!buffer_dereference(&buf, MDL)) {
! 77: t_info("buffer_dereference() failed\n");
! 78: t_result(T_FAIL);
! 79: return;
! 80: }
! 81: if (buf != NULL) {
! 82: t_info("buffer_dereference() did not NULL-out buffer\n");
! 83: t_result(T_FAIL);
! 84: return;
! 85: }
! 86:
! 87: /*
! 88: * Check an actual buffer.
! 89: */
! 90: buf = NULL;
! 91: if (!buffer_allocate(&buf, 100, MDL)) {
! 92: t_info("failed on allocate\n");
! 93: t_result(T_FAIL);
! 94: return;
! 95: }
! 96: if (!buffer_dereference(&buf, MDL)) {
! 97: t_info("buffer_dereference() failed\n");
! 98: t_result(T_FAIL);
! 99: return;
! 100: }
! 101: if (buf != NULL) {
! 102: t_info("buffer_dereference() did not NULL-out buffer\n");
! 103: t_result(T_FAIL);
! 104: return;
! 105: }
! 106:
! 107: /*
! 108: * Okay, we're happy.
! 109: */
! 110: t_result(T_PASS);
! 111: }
! 112:
! 113: static void
! 114: test_buffer_reference(void) {
! 115: static const char *test_desc =
! 116: "buffer_reference basic test";
! 117: int result = T_PASS;
! 118:
! 119: struct buffer *a, *b;
! 120:
! 121: t_assert("buffer_reference", 1, T_REQUIRED, "%s", test_desc);
! 122:
! 123: /*
! 124: * Create a buffer.
! 125: */
! 126: a = NULL;
! 127: if (!buffer_allocate(&a, 100, MDL)) {
! 128: t_info("failed on allocate\n");
! 129: t_result(T_FAIL);
! 130: return;
! 131: }
! 132:
! 133: /*
! 134: * Confirm buffer_reference() doesn't work if we pass in NULL.
! 135: *
! 136: * TODO: we should confirm we get an error message here.
! 137: */
! 138: if (buffer_reference(NULL, a, MDL)) {
! 139: t_info("succeeded on an error input\n");
! 140: t_result(T_FAIL);
! 141: return;
! 142: }
! 143:
! 144: /*
! 145: * TODO: we should confirm we get an error message if we pass
! 146: * a non-NULL target.
! 147: */
! 148:
! 149: /*
! 150: * Confirm we work under normal circumstances.
! 151: */
! 152: b = NULL;
! 153: if (!buffer_reference(&b, a, MDL)) {
! 154: t_info("buffer_reference() failed\n");
! 155: t_result(T_FAIL);
! 156: return;
! 157: }
! 158:
! 159: if (b != a) {
! 160: t_info("incorrect pointer\n");
! 161: result = T_FAIL;
! 162: }
! 163: if (b->refcnt != 2) {
! 164: t_info("incorrect refcnt\n");
! 165: result = T_FAIL;
! 166: }
! 167:
! 168: /*
! 169: * Clean up.
! 170: */
! 171: if (!buffer_dereference(&b, MDL)) {
! 172: t_info("buffer_dereference() failed\n");
! 173: t_result(T_FAIL);
! 174: return;
! 175: }
! 176: if (!buffer_dereference(&a, MDL)) {
! 177: t_info("buffer_dereference() failed\n");
! 178: t_result(T_FAIL);
! 179: return;
! 180: }
! 181:
! 182: t_result(result);
! 183: }
! 184:
! 185: static void
! 186: test_buffer_dereference(void) {
! 187: static const char *test_desc =
! 188: "buffer_dereference basic test";
! 189:
! 190: struct buffer *a, *b;
! 191:
! 192: t_assert("buffer_dereference", 1, T_REQUIRED, "%s", test_desc);
! 193:
! 194: /*
! 195: * Confirm buffer_dereference() doesn't work if we pass in NULL.
! 196: *
! 197: * TODO: we should confirm we get an error message here.
! 198: */
! 199: if (buffer_dereference(NULL, MDL)) {
! 200: t_info("succeeded on an error input\n");
! 201: t_result(T_FAIL);
! 202: return;
! 203: }
! 204:
! 205: /*
! 206: * Confirm buffer_dereference() doesn't work if we pass in
! 207: * a pointer to NULL.
! 208: *
! 209: * TODO: we should confirm we get an error message here.
! 210: */
! 211: a = NULL;
! 212: if (buffer_dereference(&a, MDL)) {
! 213: t_info("succeeded on an error input\n");
! 214: t_result(T_FAIL);
! 215: return;
! 216: }
! 217:
! 218: /*
! 219: * Confirm we work under normal circumstances.
! 220: */
! 221: a = NULL;
! 222: if (!buffer_allocate(&a, 100, MDL)) {
! 223: t_info("failed on allocate\n");
! 224: t_result(T_FAIL);
! 225: return;
! 226: }
! 227: if (!buffer_dereference(&a, MDL)) {
! 228: t_info("buffer_dereference() failed\n");
! 229: t_result(T_FAIL);
! 230: return;
! 231: }
! 232: if (a != NULL) {
! 233: t_info("non-null buffer after buffer_dereference()\n");
! 234: t_result(T_FAIL);
! 235: return;
! 236: }
! 237:
! 238: /*
! 239: * Confirm we get an error from negative refcnt.
! 240: *
! 241: * TODO: we should confirm we get an error message here.
! 242: */
! 243: a = NULL;
! 244: if (!buffer_allocate(&a, 100, MDL)) {
! 245: t_info("failed on allocate\n");
! 246: t_result(T_FAIL);
! 247: return;
! 248: }
! 249: b = NULL;
! 250: if (!buffer_reference(&b, a, MDL)) {
! 251: t_info("buffer_reference() failed\n");
! 252: t_result(T_FAIL);
! 253: return;
! 254: }
! 255: a->refcnt = 0; /* purposely set to invalid value */
! 256: if (buffer_dereference(&a, MDL)) {
! 257: t_info("buffer_dereference() succeeded on error input\n");
! 258: t_result(T_FAIL);
! 259: return;
! 260: }
! 261: a->refcnt = 2;
! 262: if (!buffer_dereference(&b, MDL)) {
! 263: t_info("buffer_dereference() failed\n");
! 264: t_result(T_FAIL);
! 265: return;
! 266: }
! 267: if (!buffer_dereference(&a, MDL)) {
! 268: t_info("buffer_dereference() failed\n");
! 269: t_result(T_FAIL);
! 270: return;
! 271: }
! 272:
! 273: t_result(T_PASS);
! 274: }
! 275:
! 276: static void
! 277: test_data_string_forget(void) {
! 278: static const char *test_desc =
! 279: "data_string_forget basic test";
! 280: int result = T_PASS;
! 281:
! 282: struct buffer *buf;
! 283: struct data_string a;
! 284: const char *str = "Lorem ipsum dolor sit amet turpis duis.";
! 285:
! 286: t_assert("data_string_forget", 1, T_REQUIRED, "%s", test_desc);
! 287:
! 288: /*
! 289: * Create the string we want to forget.
! 290: */
! 291: memset(&a, 0, sizeof(a));
! 292: a.len = strlen(str);
! 293: buf = NULL;
! 294: if (!buffer_allocate(&buf, a.len, MDL)) {
! 295: t_info("out of memory\n");
! 296: t_result(T_FAIL);
! 297: return;
! 298: }
! 299: if (!buffer_reference(&a.buffer, buf, MDL)) {
! 300: t_info("buffer_reference() failed\n");
! 301: t_result(T_FAIL);
! 302: return;
! 303: }
! 304: a.data = a.buffer->data;
! 305: memcpy(a.buffer->data, str, a.len);
! 306:
! 307: /*
! 308: * Forget and confirm we've forgotten.
! 309: */
! 310: data_string_forget(&a, MDL);
! 311:
! 312: if (a.len != 0) {
! 313: t_info("incorrect length\n");
! 314: result = T_FAIL;
! 315: }
! 316: if (a.data != NULL) {
! 317: t_info("incorrect data\n");
! 318: result = T_FAIL;
! 319: }
! 320: if (a.terminated) {
! 321: t_info("incorrect terminated\n");
! 322: result = T_FAIL;
! 323: }
! 324: if (a.buffer != NULL) {
! 325: t_info("incorrect buffer\n");
! 326: result = T_FAIL;
! 327: }
! 328: if (buf->refcnt != 1) {
! 329: t_info("too many references to buf\n");
! 330: result = T_FAIL;
! 331: }
! 332:
! 333: /*
! 334: * Clean up buffer.
! 335: */
! 336: if (!buffer_dereference(&buf, MDL)) {
! 337: t_info("buffer_reference() failed\n");
! 338: t_result(T_FAIL);
! 339: return;
! 340: }
! 341:
! 342: t_result(result);
! 343: }
! 344:
! 345: static void
! 346: test_data_string_forget_nobuf(void) {
! 347: static const char *test_desc =
! 348: "data_string_forget test, data_string without buffer";
! 349: int result = T_PASS;
! 350:
! 351: struct data_string a;
! 352: const char *str = "Lorem ipsum dolor sit amet massa nunc.";
! 353:
! 354: t_assert("data_string_forget, no buffer", 1, T_REQUIRED, "%s", test_desc);
! 355:
! 356: /*
! 357: * Create the string we want to forget.
! 358: */
! 359: memset(&a, 0, sizeof(a));
! 360: a.len = strlen(str);
! 361: a.data = (const unsigned char *)str;
! 362: a.terminated = 1;
! 363:
! 364: /*
! 365: * Forget and confirm we've forgotten.
! 366: */
! 367: data_string_forget(&a, MDL);
! 368:
! 369: if (a.len != 0) {
! 370: t_info("incorrect length\n");
! 371: result = T_FAIL;
! 372: }
! 373: if (a.data != NULL) {
! 374: t_info("incorrect data\n");
! 375: result = T_FAIL;
! 376: }
! 377: if (a.terminated) {
! 378: t_info("incorrect terminated\n");
! 379: result = T_FAIL;
! 380: }
! 381: if (a.buffer != NULL) {
! 382: t_info("incorrect buffer\n");
! 383: result = T_FAIL;
! 384: }
! 385:
! 386: t_result(result);
! 387: }
! 388:
! 389: static void
! 390: test_data_string_copy(void) {
! 391: static const char *test_desc =
! 392: "data_string_copy basic test";
! 393: int result = T_PASS;
! 394:
! 395: struct data_string a, b;
! 396: const char *str = "Lorem ipsum dolor sit amet orci aliquam.";
! 397:
! 398: t_assert("data_string_copy", 1, T_REQUIRED, "%s", test_desc);
! 399:
! 400:
! 401: /*
! 402: * Create the string we want to copy.
! 403: */
! 404: memset(&a, 0, sizeof(a));
! 405: a.len = strlen(str);
! 406: if (!buffer_allocate(&a.buffer, a.len, MDL)) {
! 407: t_info("out of memory\n");
! 408: t_result(T_FAIL);
! 409: return;
! 410: }
! 411: a.data = a.buffer->data;
! 412: memcpy(a.buffer->data, str, a.len);
! 413:
! 414: /*
! 415: * Copy the string, and confirm it works.
! 416: */
! 417: memset(&b, 0, sizeof(b));
! 418: data_string_copy(&b, &a, MDL);
! 419:
! 420: if (b.len != a.len) {
! 421: t_info("incorrect length\n");
! 422: result = T_FAIL;
! 423: }
! 424: if (b.data != a.data) {
! 425: t_info("incorrect data\n");
! 426: result = T_FAIL;
! 427: }
! 428: if (b.terminated != a.terminated) {
! 429: t_info("incorrect terminated\n");
! 430: result = T_FAIL;
! 431: }
! 432: if (b.buffer != a.buffer) {
! 433: t_info("incorrect buffer\n");
! 434: result = T_FAIL;
! 435: }
! 436:
! 437: /*
! 438: * Clean up.
! 439: */
! 440: data_string_forget(&b, MDL);
! 441: data_string_forget(&a, MDL);
! 442:
! 443: t_result(result);
! 444: }
! 445:
! 446: static void
! 447: test_data_string_copy_nobuf(void) {
! 448: static const char *test_desc =
! 449: "data_string_copy test, data_string without buffer";
! 450: int result = T_PASS;
! 451:
! 452: struct data_string a, b;
! 453: const char *str = "Lorem ipsum dolor sit amet cras amet.";
! 454:
! 455: t_assert("data_string_copy, no buffer", 1, T_REQUIRED, "%s",
! 456: test_desc);
! 457:
! 458:
! 459: /*
! 460: * Create the string we want to copy.
! 461: */
! 462: memset(&a, 0, sizeof(a));
! 463: a.len = strlen(str);
! 464: a.data = (const unsigned char *)str;
! 465: a.terminated = 1;
! 466:
! 467: /*
! 468: * Copy the string, and confirm it works.
! 469: */
! 470: memset(&b, 0, sizeof(b));
! 471: data_string_copy(&b, &a, MDL);
! 472:
! 473: if (b.len != a.len) {
! 474: t_info("incorrect length\n");
! 475: result = T_FAIL;
! 476: }
! 477: if (b.data != a.data) {
! 478: t_info("incorrect data\n");
! 479: result = T_FAIL;
! 480: }
! 481: if (b.terminated != a.terminated) {
! 482: t_info("incorrect terminated\n");
! 483: result = T_FAIL;
! 484: }
! 485: if (b.buffer != a.buffer) {
! 486: t_info("incorrect buffer\n");
! 487: result = T_FAIL;
! 488: }
! 489:
! 490: /*
! 491: * Clean up.
! 492: */
! 493: data_string_forget(&b, MDL);
! 494: data_string_forget(&a, MDL);
! 495:
! 496: t_result(result);
! 497: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>