diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:42:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:42:04 +0000 |
commit | 0d47952611198ef6b1163f366dc03922d20b1475 (patch) | |
tree | 3d840a3b8c0daef0754707bfb9f5e873b6b1ac13 /nsock/tests/ghheaps.c | |
parent | Initial commit. (diff) | |
download | nmap-0d47952611198ef6b1163f366dc03922d20b1475.tar.xz nmap-0d47952611198ef6b1163f366dc03922d20b1475.zip |
Adding upstream version 7.94+git20230807.3be01efb1+dfsg.upstream/7.94+git20230807.3be01efb1+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | nsock/tests/ghheaps.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/nsock/tests/ghheaps.c b/nsock/tests/ghheaps.c new file mode 100644 index 0000000..0d4d2cb --- /dev/null +++ b/nsock/tests/ghheaps.c @@ -0,0 +1,151 @@ +/* + * Nsock regression test suite + * Same license as nmap -- see https://nmap.org/book/man-legal.html + */ + +#include "test-common.h" +#include "../src/gh_heap.h" +#include <stdint.h> +#include <time.h> + + +#define HEAP_COUNT 3 + +struct testitem { + int val; + gh_hnode_t node; +}; + +static int hnode_int_cmp(gh_hnode_t *n1, gh_hnode_t *n2) { + struct testitem *a; + struct testitem *b; + + a = container_of(n1, struct testitem, node); + b = container_of(n2, struct testitem, node); + + return (a->val < b->val); +} + +static gh_hnode_t *mknode(int val) { + struct testitem *item; + + item = calloc(1, sizeof(struct testitem)); + assert(item != NULL); + item->val = val; + gh_hnode_invalidate(&item->node); + return &item->node; +} + +static int node2int(gh_hnode_t *hnode) { + struct testitem *item; + + item = container_of(hnode, struct testitem, node); + return item->val; +} + +static int ghheap_ordering(void *tdata) { + gh_heap_t heap; + int i, n, k; + + gh_heap_init(&heap, hnode_int_cmp); + + for (i = 25000; i < 50000; i++) + gh_heap_push(&heap, mknode(i)); + + for (i = 24999; i >= 0; i--) + gh_heap_push(&heap, mknode(i)); + + for (i = 25000; i < 50000; i++) + gh_heap_push(&heap, mknode(i)); + + n = -1; + do { + gh_hnode_t *current; + + current = gh_heap_pop(&heap); + assert(!gh_hnode_is_valid(current)); + k = node2int(current); + + if (k < n) + return -EINVAL; + + n = k; + free(container_of(current, struct testitem, node)); + } while (gh_heap_count(&heap) > 0); + + gh_heap_free(&heap); + return 0; +} + +static int ghheap_stress(void *tdata) { + gh_heap_t heaps[HEAP_COUNT]; + int i, num; + + for (i = 0; i < HEAP_COUNT; i++) + gh_heap_init(&heaps[i], hnode_int_cmp); + + for (num = 25000; num < 50000; num++) { + for (i = 0; i < HEAP_COUNT; i++) { + gh_heap_push(&heaps[i], mknode(num)); + } + } + + for (num = 24999; num >= 0; num--) { + for (i = 0; i < HEAP_COUNT; i++) { + gh_heap_push(&heaps[i], mknode(num)); + } + } + + for (num = 0; num < 50000; num++) { + for (i = 0; i < HEAP_COUNT; i++) { + int r_min, r_pop; + gh_hnode_t *hnode; + + r_min = node2int(gh_heap_min(&heaps[i])); + hnode = gh_heap_pop(&heaps[i]); + r_pop = node2int(hnode); + + if (r_min != r_pop) { + fprintf(stderr, "Bogus min/pop return values (%d != %d)\n", r_min, r_pop); + return -EINVAL; + } + + if (r_min != num) { + fprintf(stderr, "Bogus return value %d when expected %d\n", r_min, num); + return -EINVAL; + } + + free(container_of(hnode, struct testitem, node)); + } + } + + for (i = 0; i < HEAP_COUNT; i++) { + void *ret; + + ret = gh_heap_pop(&heaps[i]); + if (ret != NULL) { + fprintf(stderr, "Ret is bogus for heap %d\n", i); + return -EINVAL; + } + } + + for (i = 0; i < HEAP_COUNT; i++) + gh_heap_free(&heaps[i]); + + return 0; +} + + +const struct test_case TestGHHeaps = { + .t_name = "test nsock internal ghheaps", + .t_setup = NULL, + .t_run = ghheap_stress, + .t_teardown = NULL +}; + +const struct test_case TestHeapOrdering = { + .t_name = "test heaps conditions", + .t_setup = NULL, + .t_run = ghheap_ordering, + .t_teardown = NULL +}; |