4.14.3 Testing Overflow [ToC] [Index]     [Skip Back] [Skip Fwd]     [Prev] [Up] [Next]

Testing for overflow requires an entirely different set of test functions. The idea is to create a too-tall tree using one of the pathological insertion orders (ascending, descending, zig-zag, shifted ascending), then try out each of the functions that can overflow on it and make sure that they behave as they should.

There is a separate test function for each function that can overflow a stack but which is not tested by test(). These functions are called by driver function test_overflow(), which also takes care of creating, populating, and destroying the tree.

123. <BST overflow test function 123> =
<Overflow testers 125>

/* Tests the tree routines for proper handling of overflows.
   Inserting the n elements of order[] should produce a tree
   with height greater than BST_MAX_HEIGHT.
   Uses allocator as the allocator for tree and node data.
   Use verbosity to set the level of chatter on stdout. */
int 
test_overflow (struct libavl_allocator *allocator,
               int order[], int n, int verbosity)
{ /* An overflow tester function. */ typedef int test_func (struct bst_table *, int n); /* An overflow tester. */ struct test
    { test_func *func; /* Tester function. */ const char *name; /* Test name. */ }; /* All the overflow testers. */ static const struct test test[] =
    { {test_bst_t_first, "first item"}, {test_bst_t_last, "last item"}, {test_bst_t_find, "find item"}, {test_bst_t_insert, "insert item"}, {test_bst_t_next, "next item"}, {test_bst_t_prev, "previous item"}, {test_bst_copy, "copy tree"}, }; const struct test *i; /* Iterator. */ /* Run all the overflow testers. */ for (i = test; i < test + sizeof test / sizeof *test; i++)
    { struct bst_table *tree; int j; if (verbosity >= 2)
        printf (" Running %s test...\n", i->name); tree = bst_create (compare_ints, NULL, allocator); if (tree == NULL)
        { printf (" Out of memory creating tree.\n"); return 1; } for (j = 0; j < n; j++)
        { void **p = bst_probe (tree, &order[j]); if (p == NULL || *p != &order[j])
            { if (p == NULL && verbosity >= 0) printf (" Out of memory in insertion.\n"); else if (p != NULL)
                printf (" Duplicate item in tree!\n"); bst_destroy (tree, NULL); return p == NULL; } } if (i->func (tree, n) == 0) return 0; if (verify_tree (tree, order, n) == 0) return 0; bst_destroy (tree, NULL); } return 1; }

This code is included in 99, 188, 240, 292, 332, 370, 413, 451, 484, 517, 550, and 585.

124. <Test prototypes 102> +=
int test_overflow (struct libavl_allocator *, int order[], int n, 
                   int verbosity);

There is an overflow tester for almost every function that can overflow. Here is one example:

125. <Overflow testers 125> =
static int 
test_bst_t_first (struct bst_table *tree, int n)
{ struct bst_traverser trav; int *first; first = bst_t_first (&trav, tree); if (first == NULL || *first != 0)
    { printf (" First item test failed: expected 0, got %d\n", first != NULL ? *first : -1); return 0; } return 1; }

See also 646.

This code is included in 123.

Exercises:

1. Write the rest of the overflow tester functions. (The test_overflow() function lists all of them.) [answer]