test_linkedlists.c File Reference

Linked List Tests. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/strings.h"
#include "asterisk/logger.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dlinkedlists.h"

Include dependency graph for test_linkedlists.c:

Go to the source code of this file.

Data Structures

struct  test_dbl_llist
struct  test_llist
struct  test_val

Defines

#define ELEM_OR_FAIL(x, y)
#define MATCH_OR_FAIL(list, val, retbuf)
#define MATCH_OR_FAIL_DBL(list, val, retbuf)

Functions

static void __reg_module (void)
static void __unreg_module (void)
 AST_TEST_DEFINE (double_ll_tests)
 AST_TEST_DEFINE (single_ll_tests)
static int dbl_list_expect_forward (struct test_dbl_llist *test_list, const char *expect, struct ast_str **buf)
static int dbl_list_expect_reverse (struct test_dbl_llist *test_list, const char *expect, struct ast_str **buf)
static int list_expect (struct test_llist *test_list, const char *expect, struct ast_str **buf)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Test Linked Lists" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static struct test_val a = { "A" }
static struct ast_module_infoast_module_info = &__mod_info
static struct test_val b = { "B" }
static struct test_val c = { "C" }
static struct test_val d = { "D" }


Detailed Description

Linked List Tests.

Author:
Terry Wilson <twilson@digium.com>

Definition in file test_linkedlists.c.


Define Documentation

#define ELEM_OR_FAIL ( x,
 ) 

Value:

if ((x) != (y)) { \
      ast_test_status_update(test, "Expected: %s, Got: %s\n", (x)->name, (y)->name); \
      return AST_TEST_FAIL; \
   }

Definition at line 121 of file test_linkedlists.c.

Referenced by AST_TEST_DEFINE().

#define MATCH_OR_FAIL ( list,
val,
retbuf   ) 

Value:

if (list_expect(list, val, &retbuf)) { \
      ast_test_status_update(test, "Expected: %s, Got: %s\n", val, ast_str_buffer(retbuf)); \
      return AST_TEST_FAIL; \
   }

Definition at line 105 of file test_linkedlists.c.

Referenced by AST_TEST_DEFINE().

#define MATCH_OR_FAIL_DBL ( list,
val,
retbuf   ) 

Definition at line 111 of file test_linkedlists.c.

Referenced by AST_TEST_DEFINE().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 663 of file test_linkedlists.c.

static void __unreg_module ( void   )  [static]

Definition at line 663 of file test_linkedlists.c.

AST_TEST_DEFINE ( double_ll_tests   ) 

Definition at line 338 of file test_linkedlists.c.

References a, ast_alloca, AST_DLLIST_APPEND_DLLIST, AST_DLLIST_EMPTY, AST_DLLIST_FIRST, AST_DLLIST_INSERT_AFTER, AST_DLLIST_INSERT_AFTER_CURRENT, AST_DLLIST_INSERT_BEFORE, AST_DLLIST_INSERT_BEFORE_CURRENT, AST_DLLIST_INSERT_HEAD, AST_DLLIST_INSERT_TAIL, AST_DLLIST_LAST, AST_DLLIST_NEXT, AST_DLLIST_PREV, AST_DLLIST_REMOVE, AST_DLLIST_REMOVE_CURRENT, AST_DLLIST_REMOVE_HEAD, AST_DLLIST_REMOVE_TAIL, AST_DLLIST_REMOVE_VERIFY, AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN, AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END, AST_DLLIST_TRAVERSE_SAFE_BEGIN, AST_DLLIST_TRAVERSE_SAFE_END, ast_free, ast_str_create(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, b, buf, c, d, test_val::dbl_list, ELEM_OR_FAIL, MATCH_OR_FAIL_DBL, NULL, RAII_VAR, TEST_EXECUTE, and TEST_INIT.

00339 {
00340    RAII_VAR(struct ast_str *, buf, NULL, ast_free);
00341    struct test_dbl_llist test_list = { 0, };
00342    struct test_dbl_llist other_list = { 0, };
00343    struct test_val *bogus;
00344 
00345    switch (cmd) {
00346    case TEST_INIT:
00347       info->name = "double_ll_tests";
00348       info->category = "/main/linkedlists/";
00349       info->summary = "double linked list unit test";
00350       info->description =
00351          "Test the double linked list API";
00352       return AST_TEST_NOT_RUN;
00353    case TEST_EXECUTE:
00354       break;
00355    }
00356 
00357    if (!(buf = ast_str_create(16))) {
00358       return AST_TEST_FAIL;
00359    }
00360 
00361    bogus = ast_alloca(sizeof(*bogus));
00362 
00363    if (AST_DLLIST_REMOVE_VERIFY(&test_list, bogus, dbl_list)) {
00364       ast_test_status_update(test, "AST_DLLIST_REMOVE_VERIFY should safely return NULL for missing element from empty list\n");
00365       return AST_TEST_FAIL;
00366    }
00367 
00368    /* INSERT_HEAD and REMOVE_HEAD tests */
00369    AST_DLLIST_INSERT_HEAD(&test_list, &a, dbl_list);
00370    MATCH_OR_FAIL_DBL(&test_list, "A", buf);
00371    AST_DLLIST_INSERT_HEAD(&test_list, &b, dbl_list);
00372    MATCH_OR_FAIL_DBL(&test_list, "BA", buf);
00373    AST_DLLIST_REMOVE_HEAD(&test_list, dbl_list);
00374    MATCH_OR_FAIL_DBL(&test_list, "A", buf);
00375    AST_DLLIST_REMOVE_HEAD(&test_list, dbl_list);
00376    MATCH_OR_FAIL_DBL(&test_list, "", buf);
00377    if (AST_DLLIST_REMOVE_HEAD(&test_list, dbl_list)) {
00378       ast_test_status_update(test, "Somehow removed an item from the head of a list that didn't exist\n");
00379       return AST_TEST_FAIL;
00380    }
00381    MATCH_OR_FAIL_DBL(&test_list, "", buf);
00382 
00383    /* Check empty list test */
00384 
00385    if (!AST_DLLIST_EMPTY(&test_list)) {
00386       ast_test_status_update(test, "List should be empty\n");
00387       return AST_TEST_FAIL;
00388    }
00389 
00390    /* Insert tail and remove specific item tests. */
00391 
00392    AST_DLLIST_INSERT_TAIL(&test_list, &a, dbl_list);
00393    MATCH_OR_FAIL_DBL(&test_list, "A", buf);
00394    AST_DLLIST_INSERT_TAIL(&test_list, &b, dbl_list);
00395    MATCH_OR_FAIL_DBL(&test_list, "AB", buf);
00396    AST_DLLIST_INSERT_TAIL(&test_list, &c, dbl_list);
00397    MATCH_OR_FAIL_DBL(&test_list, "ABC", buf);
00398    AST_DLLIST_INSERT_TAIL(&test_list, &d, dbl_list);
00399    MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00400    if (AST_DLLIST_REMOVE_VERIFY(&test_list, bogus, dbl_list)) {
00401       ast_test_status_update(test, "AST_DLLIST_REMOVE_VERIFY should safely return NULL for missing element\n");
00402       return AST_TEST_FAIL;
00403    }
00404    bogus = NULL;
00405    if (AST_DLLIST_REMOVE_VERIFY(&test_list, bogus, dbl_list)) {
00406       ast_test_status_update(test, "AST_DLLIST_REMOVE_VERIFY should safely return NULL for element set to NULL\n");
00407       return AST_TEST_FAIL;
00408    }
00409    AST_DLLIST_REMOVE(&test_list, &b, dbl_list);
00410    MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00411    AST_DLLIST_REMOVE(&test_list, &d, dbl_list);
00412    MATCH_OR_FAIL_DBL(&test_list, "AC", buf);
00413    AST_DLLIST_REMOVE(&test_list, &a, dbl_list);
00414    MATCH_OR_FAIL_DBL(&test_list, "C", buf);
00415    AST_DLLIST_REMOVE(&test_list, &c, dbl_list);
00416    MATCH_OR_FAIL_DBL(&test_list, "", buf);
00417    if (!AST_DLLIST_EMPTY(&test_list)) {
00418       ast_test_status_update(test, "List should be empty\n");
00419       return AST_TEST_FAIL;
00420    }
00421    if (AST_DLLIST_REMOVE_VERIFY(&test_list, bogus, dbl_list)) {
00422       ast_test_status_update(test, "AST_DLLIST_REMOVE_VERIFY should safely return NULL asked to remove a NULL pointer from an empty list\n");
00423       return AST_TEST_FAIL;
00424    }
00425 
00426    /* Insert item after and before specific item tests */
00427 
00428    AST_DLLIST_INSERT_HEAD(&test_list, &a, dbl_list);
00429    MATCH_OR_FAIL_DBL(&test_list, "A", buf);
00430    AST_DLLIST_INSERT_TAIL(&test_list, &c, dbl_list);
00431    MATCH_OR_FAIL_DBL(&test_list, "AC", buf);
00432    AST_DLLIST_INSERT_AFTER(&test_list, &a, &b, dbl_list);
00433    MATCH_OR_FAIL_DBL(&test_list, "ABC", buf);
00434    AST_DLLIST_INSERT_AFTER(&test_list, &c, &d, dbl_list);
00435    MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00436    AST_DLLIST_REMOVE_TAIL(&test_list, dbl_list);
00437    MATCH_OR_FAIL_DBL(&test_list, "ABC", buf);
00438    AST_DLLIST_REMOVE_TAIL(&test_list, dbl_list);
00439    MATCH_OR_FAIL_DBL(&test_list, "AB", buf);
00440    AST_DLLIST_INSERT_TAIL(&test_list, &d, dbl_list);
00441    MATCH_OR_FAIL_DBL(&test_list, "ABD", buf);
00442    AST_DLLIST_INSERT_BEFORE(&test_list, &d, &c, dbl_list);
00443    MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00444    AST_DLLIST_REMOVE_HEAD(&test_list, dbl_list);
00445    MATCH_OR_FAIL_DBL(&test_list, "BCD", buf);
00446    AST_DLLIST_INSERT_BEFORE(&test_list, &b, &a, dbl_list);
00447    MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00448 
00449    ELEM_OR_FAIL(AST_DLLIST_FIRST(&test_list), &a);
00450    ELEM_OR_FAIL(AST_DLLIST_LAST(&test_list), &d);
00451    ELEM_OR_FAIL(AST_DLLIST_NEXT(&a, dbl_list), &b);
00452    ELEM_OR_FAIL(AST_DLLIST_PREV(&b, dbl_list), &a);
00453 
00454    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00455       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00456    }
00457    AST_DLLIST_TRAVERSE_SAFE_END;
00458 
00459    if (!AST_DLLIST_EMPTY(&test_list)) {
00460       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00461       return AST_TEST_FAIL;
00462    }
00463 
00464    /* Append list test */
00465 
00466    AST_DLLIST_INSERT_HEAD(&test_list, &a, dbl_list);
00467    MATCH_OR_FAIL_DBL(&test_list, "A", buf);
00468    AST_DLLIST_INSERT_TAIL(&test_list, &b, dbl_list);
00469    MATCH_OR_FAIL_DBL(&test_list, "AB", buf);
00470    AST_DLLIST_INSERT_HEAD(&other_list, &c, dbl_list);
00471    MATCH_OR_FAIL_DBL(&other_list, "C", buf);
00472    AST_DLLIST_INSERT_TAIL(&other_list, &d, dbl_list);
00473    MATCH_OR_FAIL_DBL(&other_list, "CD", buf);
00474    AST_DLLIST_APPEND_DLLIST(&test_list, &other_list, dbl_list);
00475    MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00476    MATCH_OR_FAIL_DBL(&other_list, "", buf);
00477    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00478       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00479    }
00480    AST_DLLIST_TRAVERSE_SAFE_END;
00481    if (!AST_DLLIST_EMPTY(&test_list)) {
00482       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00483       return AST_TEST_FAIL;
00484    }
00485 
00486    /*
00487     * Safe traversal list modification tests
00488     * Traverse starting from first element
00489     */
00490 
00491    AST_DLLIST_INSERT_HEAD(&test_list, &a, dbl_list);
00492    MATCH_OR_FAIL_DBL(&test_list, "A", buf);
00493    AST_DLLIST_INSERT_TAIL(&test_list, &d, dbl_list);
00494    MATCH_OR_FAIL_DBL(&test_list, "AD", buf);
00495    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00496       if (bogus == &d) {
00497          AST_DLLIST_INSERT_BEFORE_CURRENT(&b, dbl_list);
00498          MATCH_OR_FAIL_DBL(&test_list, "ABD", buf);
00499          AST_DLLIST_INSERT_BEFORE_CURRENT(&c, dbl_list);
00500          MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00501          AST_DLLIST_REMOVE_CURRENT(dbl_list);
00502          MATCH_OR_FAIL_DBL(&test_list, "ABC", buf);
00503       }
00504    }
00505    AST_DLLIST_TRAVERSE_SAFE_END;
00506    MATCH_OR_FAIL_DBL(&test_list, "ABC", buf);
00507    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00508       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00509    }
00510    AST_DLLIST_TRAVERSE_SAFE_END;
00511    if (!AST_DLLIST_EMPTY(&test_list)) {
00512       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00513       return AST_TEST_FAIL;
00514    }
00515 
00516    AST_DLLIST_INSERT_HEAD(&test_list, &b, dbl_list);
00517    MATCH_OR_FAIL_DBL(&test_list, "B", buf);
00518    AST_DLLIST_INSERT_TAIL(&test_list, &d, dbl_list);
00519    MATCH_OR_FAIL_DBL(&test_list, "BD", buf);
00520    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00521       if (bogus == &b) {
00522          AST_DLLIST_INSERT_BEFORE_CURRENT(&a, dbl_list);
00523          MATCH_OR_FAIL_DBL(&test_list, "ABD", buf);
00524          AST_DLLIST_INSERT_AFTER_CURRENT(&c, dbl_list);
00525          MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00526          AST_DLLIST_REMOVE_CURRENT(dbl_list);
00527          MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00528       }
00529    }
00530    AST_DLLIST_TRAVERSE_SAFE_END;
00531    MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00532    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00533       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00534    }
00535    AST_DLLIST_TRAVERSE_SAFE_END;
00536    if (!AST_DLLIST_EMPTY(&test_list)) {
00537       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00538       return AST_TEST_FAIL;
00539    }
00540 
00541    AST_DLLIST_INSERT_HEAD(&test_list, &b, dbl_list);
00542    MATCH_OR_FAIL_DBL(&test_list, "B", buf);
00543    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00544       if (bogus == &b) {
00545          AST_DLLIST_INSERT_BEFORE_CURRENT(&a, dbl_list);
00546          MATCH_OR_FAIL_DBL(&test_list, "AB", buf);
00547          AST_DLLIST_INSERT_AFTER_CURRENT(&d, dbl_list);
00548          MATCH_OR_FAIL_DBL(&test_list, "ABD", buf);
00549          AST_DLLIST_INSERT_AFTER_CURRENT(&c, dbl_list);
00550          MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00551          AST_DLLIST_REMOVE_CURRENT(dbl_list);
00552          MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00553       }
00554    }
00555    AST_DLLIST_TRAVERSE_SAFE_END;
00556    MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00557    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00558       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00559    }
00560    AST_DLLIST_TRAVERSE_SAFE_END;
00561    if (!AST_DLLIST_EMPTY(&test_list)) {
00562       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00563       return AST_TEST_FAIL;
00564    }
00565 
00566    /*
00567     * Safe traversal list modification tests
00568     * Traverse starting from last element
00569     */
00570 
00571    AST_DLLIST_INSERT_HEAD(&test_list, &a, dbl_list);
00572    MATCH_OR_FAIL_DBL(&test_list, "A", buf);
00573    AST_DLLIST_INSERT_TAIL(&test_list, &d, dbl_list);
00574    MATCH_OR_FAIL_DBL(&test_list, "AD", buf);
00575    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00576       if (bogus == &d) {
00577          AST_DLLIST_INSERT_BEFORE_CURRENT(&b, dbl_list);
00578          MATCH_OR_FAIL_DBL(&test_list, "ABD", buf);
00579          AST_DLLIST_INSERT_BEFORE_CURRENT(&c, dbl_list);
00580          MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00581          AST_DLLIST_REMOVE_CURRENT(dbl_list);
00582          MATCH_OR_FAIL_DBL(&test_list, "ABC", buf);
00583       }
00584    }
00585    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
00586    MATCH_OR_FAIL_DBL(&test_list, "ABC", buf);
00587    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00588       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00589    }
00590    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
00591    if (!AST_DLLIST_EMPTY(&test_list)) {
00592       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00593       return AST_TEST_FAIL;
00594    }
00595 
00596    AST_DLLIST_INSERT_HEAD(&test_list, &b, dbl_list);
00597    MATCH_OR_FAIL_DBL(&test_list, "B", buf);
00598    AST_DLLIST_INSERT_TAIL(&test_list, &d, dbl_list);
00599    MATCH_OR_FAIL_DBL(&test_list, "BD", buf);
00600    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00601       if (bogus == &b) {
00602          AST_DLLIST_INSERT_BEFORE_CURRENT(&a, dbl_list);
00603          MATCH_OR_FAIL_DBL(&test_list, "ABD", buf);
00604          AST_DLLIST_INSERT_AFTER_CURRENT(&c, dbl_list);
00605          MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00606          AST_DLLIST_REMOVE_CURRENT(dbl_list);
00607          MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00608       }
00609    }
00610    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
00611    MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00612    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00613       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00614    }
00615    AST_DLLIST_TRAVERSE_SAFE_END;
00616    if (!AST_DLLIST_EMPTY(&test_list)) {
00617       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00618       return AST_TEST_FAIL;
00619    }
00620 
00621    AST_DLLIST_INSERT_HEAD(&test_list, &b, dbl_list);
00622    MATCH_OR_FAIL_DBL(&test_list, "B", buf);
00623    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00624       if (bogus == &b) {
00625          AST_DLLIST_INSERT_BEFORE_CURRENT(&a, dbl_list);
00626          MATCH_OR_FAIL_DBL(&test_list, "AB", buf);
00627          AST_DLLIST_INSERT_AFTER_CURRENT(&d, dbl_list);
00628          MATCH_OR_FAIL_DBL(&test_list, "ABD", buf);
00629          AST_DLLIST_INSERT_AFTER_CURRENT(&c, dbl_list);
00630          MATCH_OR_FAIL_DBL(&test_list, "ABCD", buf);
00631          AST_DLLIST_REMOVE_CURRENT(dbl_list);
00632          MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00633       }
00634    }
00635    AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
00636    MATCH_OR_FAIL_DBL(&test_list, "ACD", buf);
00637    AST_DLLIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, dbl_list) {
00638       AST_DLLIST_REMOVE_CURRENT(dbl_list);
00639    }
00640    AST_DLLIST_TRAVERSE_SAFE_END;
00641    if (!AST_DLLIST_EMPTY(&test_list)) {
00642       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00643       return AST_TEST_FAIL;
00644    }
00645 
00646    return AST_TEST_PASS;
00647 }

AST_TEST_DEFINE ( single_ll_tests   ) 

Definition at line 127 of file test_linkedlists.c.

References a, ast_alloca, ast_free, AST_LIST_APPEND_LIST, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_INSERT_AFTER, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_LIST_AFTER, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_str_create(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, b, buf, c, d, ELEM_OR_FAIL, test_val::list, MATCH_OR_FAIL, NULL, RAII_VAR, TEST_EXECUTE, and TEST_INIT.

00128 {
00129    RAII_VAR(struct ast_str *, buf, NULL, ast_free);
00130    struct test_llist test_list = { 0, };
00131    struct test_llist other_list = { 0, };
00132    struct test_val *bogus;
00133 
00134    switch (cmd) {
00135    case TEST_INIT:
00136       info->name = "ll_tests";
00137       info->category = "/main/linkedlists/";
00138       info->summary = "single linked list unit test";
00139       info->description =
00140          "Test the single linked list API";
00141       return AST_TEST_NOT_RUN;
00142    case TEST_EXECUTE:
00143       break;
00144    }
00145 
00146    if (!(buf = ast_str_create(16))) {
00147       return AST_TEST_FAIL;
00148    }
00149 
00150    if (!(bogus = ast_alloca(sizeof(*bogus)))) {
00151       return AST_TEST_FAIL;
00152    }
00153 
00154    if (AST_LIST_REMOVE(&test_list, bogus, list)) {
00155       ast_test_status_update(test, "AST_LIST_REMOVE should safely return NULL for missing element from empty list\n");
00156       return AST_TEST_FAIL;
00157    }
00158 
00159    /* INSERT_HEAD and REMOVE_HEAD tests */
00160    AST_LIST_INSERT_HEAD(&test_list, &a, list);
00161    MATCH_OR_FAIL(&test_list, "A", buf);
00162    AST_LIST_INSERT_HEAD(&test_list, &b, list);
00163    MATCH_OR_FAIL(&test_list, "BA", buf);
00164    AST_LIST_REMOVE_HEAD(&test_list, list);
00165    MATCH_OR_FAIL(&test_list, "A", buf);
00166    AST_LIST_REMOVE_HEAD(&test_list, list);
00167    MATCH_OR_FAIL(&test_list, "", buf);
00168    if (AST_LIST_REMOVE_HEAD(&test_list, list)) {
00169       ast_test_status_update(test, "Somehow removed an item from the head of a list that didn't exist\n");
00170       return AST_TEST_FAIL;
00171    }
00172    MATCH_OR_FAIL(&test_list, "", buf);
00173 
00174    /* Check empty list test */
00175 
00176    if (!AST_LIST_EMPTY(&test_list)) {
00177       ast_test_status_update(test, "List should be empty\n");
00178       return AST_TEST_FAIL;
00179    }
00180 
00181    /* Insert tail and remove specific item tests. */
00182 
00183    AST_LIST_INSERT_TAIL(&test_list, &a, list);
00184    MATCH_OR_FAIL(&test_list, "A", buf);
00185    AST_LIST_INSERT_TAIL(&test_list, &b, list);
00186    MATCH_OR_FAIL(&test_list, "AB", buf);
00187    AST_LIST_INSERT_TAIL(&test_list, &c, list);
00188    MATCH_OR_FAIL(&test_list, "ABC", buf);
00189    AST_LIST_INSERT_TAIL(&test_list, &d, list);
00190    MATCH_OR_FAIL(&test_list, "ABCD", buf);
00191    if (AST_LIST_REMOVE(&test_list, bogus, list)) {
00192       ast_test_status_update(test, "AST_LIST_REMOVE should safely return NULL for missing element\n");
00193       return AST_TEST_FAIL;
00194    }
00195    bogus = NULL;
00196    if (AST_LIST_REMOVE(&test_list, bogus, list)) {
00197       ast_test_status_update(test, "AST_LIST_REMOVE should safely return NULL for element set to NULL\n");
00198       return AST_TEST_FAIL;
00199    }
00200    AST_LIST_REMOVE(&test_list, &b, list);
00201    MATCH_OR_FAIL(&test_list, "ACD", buf);
00202    AST_LIST_REMOVE(&test_list, &d, list);
00203    MATCH_OR_FAIL(&test_list, "AC", buf);
00204    AST_LIST_REMOVE(&test_list, &a, list);
00205    MATCH_OR_FAIL(&test_list, "C", buf);
00206    AST_LIST_REMOVE(&test_list, &c, list);
00207    MATCH_OR_FAIL(&test_list, "", buf);
00208    if (!AST_LIST_EMPTY(&test_list)) {
00209       ast_test_status_update(test, "List should be empty\n");
00210       return AST_TEST_FAIL;
00211    }
00212    if (AST_LIST_REMOVE(&test_list, bogus, list)) {
00213       ast_test_status_update(test, "AST_LIST_REMOVE should safely return NULL asked to remove a NULL pointer from an empty list\n");
00214       return AST_TEST_FAIL;
00215    }
00216 
00217    /* Insert item after specific item tests */
00218 
00219    AST_LIST_INSERT_HEAD(&test_list, &a, list);
00220    MATCH_OR_FAIL(&test_list, "A", buf);
00221    AST_LIST_INSERT_TAIL(&test_list, &c, list);
00222    MATCH_OR_FAIL(&test_list, "AC", buf);
00223    AST_LIST_INSERT_AFTER(&test_list, &a, &b, list);
00224    MATCH_OR_FAIL(&test_list, "ABC", buf);
00225    AST_LIST_INSERT_AFTER(&test_list, &c, &d, list);
00226    MATCH_OR_FAIL(&test_list, "ABCD", buf);
00227 
00228    ELEM_OR_FAIL(AST_LIST_FIRST(&test_list), &a);
00229    ELEM_OR_FAIL(AST_LIST_LAST(&test_list), &d);
00230    ELEM_OR_FAIL(AST_LIST_NEXT(&a, list), &b);
00231 
00232    AST_LIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, list) {
00233       AST_LIST_REMOVE_CURRENT(list);
00234    }
00235    AST_LIST_TRAVERSE_SAFE_END;
00236 
00237    if (!AST_LIST_EMPTY(&test_list)) {
00238       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00239       return AST_TEST_FAIL;
00240    }
00241 
00242    /* Append list test */
00243 
00244    AST_LIST_INSERT_HEAD(&test_list, &a, list);
00245    MATCH_OR_FAIL(&test_list, "A", buf);
00246    AST_LIST_INSERT_TAIL(&test_list, &b, list);
00247    MATCH_OR_FAIL(&test_list, "AB", buf);
00248    AST_LIST_INSERT_HEAD(&other_list, &c, list);
00249    MATCH_OR_FAIL(&other_list, "C", buf);
00250    AST_LIST_INSERT_TAIL(&other_list, &d, list);
00251    MATCH_OR_FAIL(&other_list, "CD", buf);
00252    AST_LIST_APPEND_LIST(&test_list, &other_list, list);
00253    MATCH_OR_FAIL(&test_list, "ABCD", buf);
00254    MATCH_OR_FAIL(&other_list, "", buf);
00255    AST_LIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, list) {
00256       AST_LIST_REMOVE_CURRENT(list);
00257    }
00258    AST_LIST_TRAVERSE_SAFE_END;
00259    if (!AST_LIST_EMPTY(&test_list)) {
00260       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00261       return AST_TEST_FAIL;
00262    }
00263 
00264    /* Insert list after specific item in middle test */
00265 
00266    AST_LIST_INSERT_HEAD(&test_list, &a, list);
00267    MATCH_OR_FAIL(&test_list, "A", buf);
00268    AST_LIST_INSERT_TAIL(&test_list, &d, list);
00269    MATCH_OR_FAIL(&test_list, "AD", buf);
00270    AST_LIST_INSERT_HEAD(&other_list, &b, list);
00271    MATCH_OR_FAIL(&other_list, "B", buf);
00272    AST_LIST_INSERT_TAIL(&other_list, &c, list);
00273    MATCH_OR_FAIL(&other_list, "BC", buf);
00274    AST_LIST_INSERT_LIST_AFTER(&test_list, &other_list, &a, list);
00275    MATCH_OR_FAIL(&test_list, "ABCD", buf);
00276    MATCH_OR_FAIL(&other_list, "", buf);
00277    AST_LIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, list) {
00278       AST_LIST_REMOVE_CURRENT(list);
00279    }
00280    AST_LIST_TRAVERSE_SAFE_END;
00281    if (!AST_LIST_EMPTY(&test_list)) {
00282       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00283       return AST_TEST_FAIL;
00284    }
00285 
00286    /* Insert list after specific item on end test */
00287 
00288    AST_LIST_INSERT_HEAD(&test_list, &a, list);
00289    MATCH_OR_FAIL(&test_list, "A", buf);
00290    AST_LIST_INSERT_TAIL(&test_list, &b, list);
00291    MATCH_OR_FAIL(&test_list, "AB", buf);
00292    AST_LIST_INSERT_HEAD(&other_list, &c, list);
00293    MATCH_OR_FAIL(&other_list, "C", buf);
00294    AST_LIST_INSERT_TAIL(&other_list, &d, list);
00295    MATCH_OR_FAIL(&other_list, "CD", buf);
00296    AST_LIST_INSERT_LIST_AFTER(&test_list, &other_list, &b, list);
00297    MATCH_OR_FAIL(&test_list, "ABCD", buf);
00298    MATCH_OR_FAIL(&other_list, "", buf);
00299    AST_LIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, list) {
00300       AST_LIST_REMOVE_CURRENT(list);
00301    }
00302    AST_LIST_TRAVERSE_SAFE_END;
00303    if (!AST_LIST_EMPTY(&test_list)) {
00304       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00305       return AST_TEST_FAIL;
00306    }
00307 
00308    /* Safe traversal list modification tests */
00309 
00310    AST_LIST_INSERT_HEAD(&test_list, &a, list);
00311    MATCH_OR_FAIL(&test_list, "A", buf);
00312    AST_LIST_INSERT_TAIL(&test_list, &d, list);
00313    MATCH_OR_FAIL(&test_list, "AD", buf);
00314    AST_LIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, list) {
00315       if (bogus == &d) {
00316          AST_LIST_INSERT_BEFORE_CURRENT(&b, list);
00317          MATCH_OR_FAIL(&test_list, "ABD", buf);
00318          AST_LIST_INSERT_BEFORE_CURRENT(&c, list);
00319          MATCH_OR_FAIL(&test_list, "ABCD", buf);
00320          AST_LIST_REMOVE_CURRENT(list);
00321          MATCH_OR_FAIL(&test_list, "ABC", buf);
00322       }
00323    }
00324    AST_LIST_TRAVERSE_SAFE_END;
00325    MATCH_OR_FAIL(&test_list, "ABC", buf);
00326    AST_LIST_TRAVERSE_SAFE_BEGIN(&test_list, bogus, list) {
00327       AST_LIST_REMOVE_CURRENT(list);
00328    }
00329    AST_LIST_TRAVERSE_SAFE_END;
00330    if (!AST_LIST_EMPTY(&test_list)) {
00331       ast_test_status_update(test, "List should be empty after traversing and removal. It wasn't.\n");
00332       return AST_TEST_FAIL;
00333    }
00334 
00335    return AST_TEST_PASS;
00336 }

static int dbl_list_expect_forward ( struct test_dbl_llist test_list,
const char *  expect,
struct ast_str **  buf 
) [static]

Definition at line 68 of file test_linkedlists.c.

References AST_DLLIST_TRAVERSE, ast_str_append(), ast_str_buffer(), ast_str_reset(), test_val::dbl_list, and test_val::name.

00069 {
00070    struct test_val *i;
00071 
00072    ast_str_reset(*buf);
00073    AST_DLLIST_TRAVERSE(test_list, i, dbl_list) {
00074       ast_str_append(buf, 0, "%s", i->name);
00075    }
00076 
00077    return strcmp(expect, ast_str_buffer(*buf));
00078 }

static int dbl_list_expect_reverse ( struct test_dbl_llist test_list,
const char *  expect,
struct ast_str **  buf 
) [static]

Definition at line 80 of file test_linkedlists.c.

References AST_DLLIST_TRAVERSE_BACKWARDS, ast_str_append(), ast_str_buffer(), ast_str_reset(), test_val::dbl_list, len(), test_val::name, and str.

00081 {
00082    struct test_val *i;
00083    char *str;
00084    int len = strlen(expect);
00085    int idx;
00086 
00087    ast_str_reset(*buf);
00088    AST_DLLIST_TRAVERSE_BACKWARDS(test_list, i, dbl_list) {
00089       ast_str_append(buf, 0, "%s", i->name);
00090    }
00091 
00092    /* Check reverse string. */
00093    str = ast_str_buffer(*buf);
00094    if (len != strlen(str)) {
00095       return 1;
00096    }
00097    for (idx = 0; idx < len; ++idx) {
00098       if (expect[idx] != str[len - idx - 1]) {
00099          return 1;
00100       }
00101    }
00102    return 0;
00103 }

static int list_expect ( struct test_llist test_list,
const char *  expect,
struct ast_str **  buf 
) [static]

Definition at line 56 of file test_linkedlists.c.

References AST_LIST_TRAVERSE, ast_str_append(), ast_str_buffer(), ast_str_reset(), test_val::list, and test_val::name.

00057 {
00058    struct test_val *i;
00059 
00060    ast_str_reset(*buf);
00061    AST_LIST_TRAVERSE(test_list, i, list) {
00062       ast_str_append(buf, 0, "%s", i->name);
00063    }
00064 
00065    return strcmp(expect, ast_str_buffer(*buf));
00066 }

static int load_module ( void   )  [static]

Definition at line 656 of file test_linkedlists.c.

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

00657 {
00658    AST_TEST_REGISTER(single_ll_tests);
00659    AST_TEST_REGISTER(double_ll_tests);
00660    return AST_MODULE_LOAD_SUCCESS;
00661 }

static int unload_module ( void   )  [static]

Definition at line 649 of file test_linkedlists.c.

References AST_TEST_UNREGISTER.

00650 {
00651    AST_TEST_UNREGISTER(single_ll_tests);
00652    AST_TEST_UNREGISTER(double_ll_tests);
00653    return 0;
00654 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Test Linked Lists" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, } [static]

Definition at line 663 of file test_linkedlists.c.

struct test_val a = { "A" } [static]

Definition at line 663 of file test_linkedlists.c.

struct test_val b = { "B" } [static]

struct test_val c = { "C" } [static]

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 50 of file test_linkedlists.c.

Referenced by __analog_handle_event(), __bt_curdel(), __bt_delete(), __bt_seqadv(), _macro_exec(), action_getvar(), action_hangup(), action_sendtext(), action_setvar(), action_timeout(), add_sdp(), agi_handle_command(), analog_call(), analog_my_getsigstr(), analog_new_ast_channel(), append_history_va(), apply_outgoing(), ast_add_extension(), ast_add_extension2_lockopt(), ast_add_extension_nolock(), ast_compile_ael2(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_include2(), ast_context_add_switch(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hashtab_hash_string_sax(), ast_hashtab_insert_immediate_bucket(), ast_hashtab_resize(), ast_parse_digest(), ast_smdi_interface_find(), AST_TEST_DEFINE(), ast_unescape_c(), ast_writefile(), base_encode(), bt_psplit(), change_monitor_action(), check_auth(), check_day(), check_dow(), check_month(), check_switch_expr(), check_via(), chunked_atoh(), cli_complete_notify(), common_exec(), compile_script(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_context(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_fn(), complete_show_dialplan_context(), complete_sip_notify(), complete_sipch(), conf_run(), console_print(), dll_tests(), do_forward(), do_pause_or_unpause(), dtmf_info_incoming_request(), ebl_callback(), enum_callback(), ext_cmp1(), ext_cmp_pattern_pos(), extract_uri(), fileexists_test(), find_cache(), find_context_locked(), find_matching_endwhile(), find_ringing_channel(), find_subchannel_and_lock(), func_channels_read(), generate_filenames_string(), generic_fax_exec(), get_also_info(), get_comma(), getnum(), getqzname(), getzname(), handle_call_outgoing(), handle_callforward_button(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_save(), handle_core_set_debug_channel(), handle_enbloc_call_message(), handle_hangup(), handle_hd_hf(), handle_invite_replaces(), handle_mgcp_audit_endpoint(), handle_offhook_message(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_response(), handle_soft_key_event_message(), handle_softhangup(), handle_stimulus_message(), handle_transfer_button(), handle_updates(), handle_uri(), headers_to_vars(), history_load(), htonll(), httpd_process_request(), iax2_predestroy(), iax2_request(), iax_prov_complete_template(), ices_exec(), ivr_dispatch(), load_pktccops_config(), lua_find_extension(), main(), manager_mixmonitor(), manager_mute_mixmonitor(), manager_mutestream(), manager_show_dialplan_helper(), manager_stop_mixmonitor(), MD5Transform(), moh_rescan_files(), ntohll(), onAlerting(), onCallEstablished(), onProgress(), ooh323_onReceivedSetup(), ooh323c_call_thread(), ooh323c_start_call_thread(), oss_new(), oss_request(), parse(), parse__escape(), parse_ok_contact(), parse_request(), parse_uri_full(), parse_via(), parseintarg(), pbcwhere(), pbx_load_users(), pbx_thread(), populate_addr(), process_sdp(), process_text_line(), re_fastaddc(), re_refresh_cursor(), re_update_line(), read_some(), register_verify(), reply_digest(), reqprep(), rotate_file(), run_agi(), safe_mkdir(), send_waveform_to_fd(), sendfax_exec(), set_message_vars_from_req(), setsubstate(), shift_pop(), show_chanstats_cb(), show_debug_helper(), show_dialplan_helper(), sip_report_security_event(), skinny_dialer(), skinny_newcall(), smdi_read(), socket_process_helper(), socket_receive_file_to_buff(), softhangup_exec(), spawn_ras(), speex_get_wb_sz_at(), speex_samples(), split_ec(), srv_callback(), start_monitor_action(), stop_monitor_action(), store_tone_zone_ring_cadence(), strsvis(), strsvisx(), strtoq(), strunvisx(), t30_phase_e_handler(), table_config_for_table_name(), table_configs_free(), tdd_feed(), tdd_generate(), term_alloc_display(), term_overwrite(), term_rebuffer_display(), transmit_fake_auth_response(), transmit_refer(), transmit_state_notify(), try_load_key(), txt_callback(), unistim_sp(), update_connectedline(), wait_for_answer(), write_history(), and xmpp_client_receive().

struct test_val d = { "D" } [static]

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 51 of file test_linkedlists.c.

Referenced by __ast_play_and_record(), _skinny_message_clear(), _skinny_message_set(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), add_sip_domain(), ast_play_and_wait(), ast_readstring_full(), AST_TEST_DEFINE(), auth_http_callback(), build_device(), calc_rxstamp(), change_favorite_icon(), check_sip_domain(), clear_sip_domains(), complete_fn(), complete_skinny_devices(), complete_skinny_show_line(), config_device(), config_parse_variables(), console_dial(), delete_devices(), destroy_session_details(), dialandactivatesub(), dll_tests(), dumpsub(), find_line_by_name(), find_subchannel_by_name(), find_subline_by_name(), finish_bookmark(), g726_encode(), get_button_template(), get_folder(), get_folder_ja(), get_unaligned_uint16(), get_unaligned_uint32(), get_unaligned_uint64(), handle_button_template_req_message(), handle_call_outgoing(), handle_callforward_button(), handle_capabilities_res_message(), handle_enbloc_call_message(), handle_keypad_button_message(), handle_message(), handle_offhook_message(), handle_onhook_message(), handle_open_receive_channel_ack_message(), handle_skinny_reset(), handle_soft_key_event_message(), handle_stimulus_message(), handle_transfer_button(), initreqprep(), key_select_extension(), lintog726_framein(), lintog726aal2_framein(), load_pktccops_config(), main(), manager_ph_control(), manager_ph_control_block(), MD5Transform(), mwi_event_cb(), parse_naptr(), push_callinfo(), put_unaligned_uint16(), put_unaligned_uint32(), put_unaligned_uint64(), rcv_mac_addr(), reload_config(), rxqcheck(), say_and_wait(), send_callinfo(), session_details_new(), setsubstate(), sip_show_domains(), sip_show_settings(), skinny_call(), skinny_device_alloc(), skinny_dialer(), skinny_extensionstate_cb(), skinny_indicate(), skinny_new(), skinny_newcall(), skinny_register(), skinny_reload(), skinny_senddigit_end(), skinny_session_cleanup(), skinny_set_rtp_peer(), sms_exec(), sms_nextoutgoing(), sms_readfile(), start_monitor_action(), start_rtp(), strlcat(), strlcpy(), tdd_decode_baudot(), transfer_call_step1(), transfer_cancel_step2(), transmit_keepaliveack(), transtime(), tty_stty(), txqcheck(), unistim_answer(), unistim_hangup(), unistim_register(), unistim_request(), unload_module(), and update_connectedline().


Generated on Thu Apr 16 06:34:21 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6