diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-25 19:04:38 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-25 19:04:38 -0400 |
| commit | 1ca38045a0be0b6121e7a1b75dc80dde5a955898 (patch) | |
| tree | 2d026f507dd239d04491f2d216132b9400dca71f /test | |
| parent | 5159f9717b20f5d2b63b57cea883ee9741a3cf24 (diff) | |
pkbktarr: created + bump pk.h version to 0.4.3
Diffstat (limited to 'test')
| -rw-r--r-- | test/pkbktarr.c | 367 | ||||
| -rw-r--r-- | test/pkbktarr.cpp | 63 |
2 files changed, 430 insertions, 0 deletions
diff --git a/test/pkbktarr.c b/test/pkbktarr.c new file mode 100644 index 0000000..2a00807 --- /dev/null +++ b/test/pkbktarr.c @@ -0,0 +1,367 @@ + +#include "../pkbktarr.h" + +#include <setjmp.h> +#include <unistd.h> + +static bool expected_exit = false; +static bool caught = false; +static jmp_buf jmp_env; +// https://stackoverflow.com/questions/64190847/how-to-catch-a-call-to-exit-for-unit-testing +// stub function +void +exit(int code) +{ + if (expected_exit) { + caught = true; + longjmp(jmp_env, 1); + } else { + _exit(code); + } +} + +void test_spinup(struct pk_membucket **bkt_buckets, struct pk_membucket **bkt_data) +{ + *bkt_buckets = pk_bucket_create("buckets", 1 << 16, false); + *bkt_data = pk_bucket_create("data", 1 << 16, false); +} + +void test_teardown(struct pk_membucket **bkt_buckets, struct pk_membucket **bkt_data) +{ + pk_bucket_destroy(*bkt_buckets); + pk_bucket_destroy(*bkt_data); + *bkt_buckets = nullptr; + *bkt_data = nullptr; +} + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + int b, i, v; + + struct pk_membucket *bkt_buckets = nullptr; + struct pk_membucket *bkt_data = nullptr; + + // test ancillary + { + struct pk_bkt_arr_handle handles[2][2]; + for (b = 0; b < 2; ++b) { + for (i = 0; i < 2; ++i) { + handles[b][i].b = b; + handles[b][i].i = i; + } + } + if (v = pk_bkt_arr_handle_compare(handles[0][0], handles[0][0]), v != 0) exit(1); + if (v = pk_bkt_arr_handle_compare(handles[1][0], handles[1][1]), v <= 0) exit(1); + if (v = pk_bkt_arr_handle_compare(handles[1][1], handles[1][0]), v >= 0) exit(1); + } + + // test ancillary 2 + { + struct pk_bkt_arr arr; + struct pk_bkt_arr_handle h1, h2; + arr.limits.b = 3; + arr.limits.i = 3; + + h1.b = 0; + h1.i = 0; + if (h2 = pk_bkt_arr_handle_increment(&arr, h1), h2.b != 0 || h2.i != 1) exit(1); + h1.b = 1; + h1.i = 1; + if (h2 = pk_bkt_arr_handle_increment(&arr, h1), h2.b != 1 || h2.i != 2) exit(1); + h1.b = 1; + h1.i = 2; + if (h2 = pk_bkt_arr_handle_increment(&arr, h1), h2.b != 2 || h2.i != 0) exit(1); + h1.b = 2; + h1.i = 2; + if (h2 = pk_bkt_arr_handle_increment(&arr, h1), h2.b != 2 || h2.i != 2) exit(1); + h1.b = 0; + h1.i = 0; + if (h2 = pk_bkt_arr_handle_decrement(&arr, h1), h2.b != 0 || h2.i != 0) exit(1); + h1.b = 2; + h1.i = 2; + if (h2 = pk_bkt_arr_handle_decrement(&arr, h1), h2.b != 2 || h2.i != 1) exit(1); + h1.b = 2; + h1.i = 0; + if (h2 = pk_bkt_arr_handle_decrement(&arr, h1), h2.b != 1 || h2.i != 2) exit(1); + } + + // test it works + test_spinup(&bkt_buckets, &bkt_data); + { + assert(bkt_buckets != nullptr); + assert(bkt_data != nullptr); + struct pk_bkt_arr arr = {0}; + struct pk_bkt_arr_handle limits; + limits.b = PK_BKT_ARR_HANDLE_B_MAX; + limits.i = PK_BKT_ARR_HANDLE_I_MAX; + pk_bkt_arr_init(&arr, sizeof(int), alignof(int), limits, bkt_buckets, bkt_data); + + struct pk_bkt_arr_handle h = pk_bkt_arr_new_handle(&arr); + if (h.b != 0) exit(1); + if (h.i != 0) exit(1); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 1) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 1) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + + pk_bkt_arr_free_handle(&arr, h); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 0) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 1) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + + pk_bkt_arr_teardown(&arr); + if (bkt_buckets->allocs != 0) exit(1); + if (bkt_data->allocs != 0) exit(1); + } + test_teardown(&bkt_buckets, &bkt_data); + + // test release & re-use slot + test_spinup(&bkt_buckets, &bkt_data); + { + assert(bkt_buckets != nullptr); + assert(bkt_data != nullptr); + struct pk_bkt_arr arr = {0}; + struct pk_bkt_arr_handle h1, h2, limits; + limits.b = PK_BKT_ARR_HANDLE_B_MAX; + limits.i = PK_BKT_ARR_HANDLE_I_MAX; + pk_bkt_arr_init(&arr, sizeof(int), alignof(int), limits, bkt_buckets, bkt_data); + + h1 = pk_bkt_arr_new_handle(&arr); + h2 = pk_bkt_arr_new_handle(&arr); + if (h1.b != 0) exit(1); + if (h1.i != 0) exit(1); + if (h2.b != 0) exit(1); + if (h2.i != 1) exit(1); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 2) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFFFC) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + + pk_bkt_arr_free_handle(&arr, h1); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 0) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFFFD) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + + h2 = pk_bkt_arr_new_handle(&arr); + if (h2.b != 0) exit(1); + if (h2.i != 0) exit(1); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 2) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFFFC) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + + pk_bkt_arr_teardown(&arr); + if (bkt_buckets->allocs != 0) exit(1); + if (bkt_data->allocs != 0) exit(1); + } + test_teardown(&bkt_buckets, &bkt_data); + + // test release & re-use slot & test allocating 2nd bucket + test_spinup(&bkt_buckets, &bkt_data); + { + assert(bkt_buckets != nullptr); + assert(bkt_data != nullptr); + struct pk_bkt_arr arr = {0}; + struct pk_bkt_arr_handle h1, h2, limits; + limits.b = 8; + limits.i = 8; + struct pk_bkt_arr_handle handles[limits.b][limits.i]; + pk_bkt_arr_init(&arr, sizeof(int), alignof(int), limits, bkt_buckets, bkt_data); + + for (i = 0; i < limits.i; ++i) { + handles[0][i] = pk_bkt_arr_new_handle(&arr); + if (handles[0][i].b != 0) exit(1); + if (handles[0][i].i != i) exit(1); + if (i == limits.i - 1) { + if (arr.head_l.b != 1) exit(1); + if (arr.head_l.i != 0) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 0) exit(1); + } else { + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != i + 1) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != i + 1) exit(1); + } + if (arr.reserved_buckets != 1) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + } + + h1 = pk_bkt_arr_new_handle(&arr); + if (h1.b != 1) exit(1); + if (h1.i != 0) exit(1); + if (arr.head_l.b != 1) exit(1); + if (arr.head_l.i != 1) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 1) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFF00) exit(1); + if (arr.idx_unused[1] != 0xFFFFFFFFFFFFFFFE) exit(1); + if (arr.reserved_buckets != 2) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 2) exit(1); + + h1 = pk_bkt_arr_new_handle(&arr); + if (h1.b != 1) exit(1); + if (h1.i != 1) exit(1); + if (arr.head_l.b != 1) exit(1); + if (arr.head_l.i != 2) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFF00) exit(1); + if (arr.idx_unused[1] != 0xFFFFFFFFFFFFFFFC) exit(1); + if (arr.reserved_buckets != 2) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 2) exit(1); + + h1.b = 0; + h1.i = 3; + pk_bkt_arr_free_handle(&arr, h1); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 3) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFF08) exit(1); + if (arr.idx_unused[1] != 0xFFFFFFFFFFFFFFFC) exit(1); + if (arr.reserved_buckets != 2) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 2) exit(1); + + h2 = pk_bkt_arr_new_handle(&arr); + if (h2.b != 0) exit(1); + if (h2.i != 3) exit(1); + if (arr.head_l.b != 1) exit(1); + if (arr.head_l.i != 2) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFF00) exit(1); + if (arr.idx_unused[1] != 0xFFFFFFFFFFFFFFFC) exit(1); + if (arr.reserved_buckets != 2) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 2) exit(1); + + h1.b = 1; + h1.i = 0; + h2.b = 1; + h2.i = 1; + pk_bkt_arr_free_handle(&arr, h1); + pk_bkt_arr_free_handle(&arr, h2); + if (arr.head_l.b != 1) exit(1); + if (arr.head_l.i != 0) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFF00) exit(1); + if (arr.idx_unused[1] != 0xFFFFFFFFFFFFFFFF) exit(1); + if (arr.reserved_buckets != 2) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 2) exit(1); + + h2 = pk_bkt_arr_new_handle(&arr); + if (h2.b != 1) exit(1); + if (h2.i != 0) exit(1); + if (arr.head_l.b != 1) exit(1); + if (arr.head_l.i != 1) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 2) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFF00) exit(1); + if (arr.idx_unused[1] != 0xFFFFFFFFFFFFFFFE) exit(1); + if (arr.reserved_buckets != 2) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 2) exit(1); + + pk_bkt_arr_teardown(&arr); + if (bkt_buckets->allocs != 0) exit(1); + if (bkt_data->allocs != 0) exit(1); + } + test_teardown(&bkt_buckets, &bkt_data); + + // test limits + test_spinup(&bkt_buckets, &bkt_data); + do + { + assert(bkt_buckets != nullptr); + assert(bkt_data != nullptr); + int b, i, r; + struct pk_bkt_arr arr = {0}; + struct pk_bkt_arr_handle limits; + limits.b = 2; + limits.i = 8; + struct pk_bkt_arr_handle handles[limits.b][limits.i]; + + expected_exit = false; + caught = false; + r = setjmp(jmp_env); + if (r == 1) { + if (expected_exit == true && caught == true) { + expected_exit = false; + caught = false; + PK_LOGV_INF("%s: successfully caught err.\n", __FILE__); + fflush(stdout); + fflush(stderr); + break; + } else { + goto uncaught_err; + } + } + + pk_bkt_arr_init(&arr, sizeof(int), alignof(int), limits, bkt_buckets, bkt_data); + + for (b = 0; b < limits.b; ++b) { + for (i = 0; i < limits.i; ++i) { + handles[b][i] = pk_bkt_arr_new_handle(&arr); + } + } + if (arr.head_l.b != 1) exit(1); + if (arr.head_l.i != 7) exit(1); + if (arr.head_r.b != 1) exit(1); + if (arr.head_r.i != 7) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 2) exit(1); + + expected_exit = true; + caught = false; + struct pk_bkt_arr_handle h = pk_bkt_arr_new_handle(&arr); + (void)h; + exit(1); + + /* + pk_bkt_arr_free_handle(&arr, h); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 0) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 1) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + + pk_bkt_arr_teardown(&arr); + if (bkt_buckets->allocs != 0) exit(1); + if (bkt_data->allocs != 0) exit(1); + */ + } + while (false); + test_teardown(&bkt_buckets, &bkt_data); + + return 0; +uncaught_err: + PK_LOGV_ERR("%s: failed to catch err.\n", __FILE__); + fflush(stdout); + fflush(stderr); + return -1; +} diff --git a/test/pkbktarr.cpp b/test/pkbktarr.cpp new file mode 100644 index 0000000..e7fb5ee --- /dev/null +++ b/test/pkbktarr.cpp @@ -0,0 +1,63 @@ + +#include "../pkbktarr.h" + +void test_spinup(struct pk_membucket **bkt_buckets, struct pk_membucket **bkt_data) +{ + *bkt_buckets = pk_bucket_create("buckets", 1 << 16, false); + *bkt_data = pk_bucket_create("data", 1 << 16, false); +} + +void test_teardown(struct pk_membucket **bkt_buckets, struct pk_membucket **bkt_data) +{ + pk_bucket_destroy(*bkt_buckets); + pk_bucket_destroy(*bkt_data); + *bkt_buckets = nullptr; + *bkt_data = nullptr; +} + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + struct pk_membucket *bkt_buckets = nullptr; + struct pk_membucket *bkt_data = nullptr; + + // test it works + test_spinup(&bkt_buckets, &bkt_data); + { + assert(bkt_buckets != nullptr); + assert(bkt_data != nullptr); + struct pk_bkt_arr_handle limits; + limits.b = PK_BKT_ARR_HANDLE_B_MAX; + limits.i = PK_BKT_ARR_HANDLE_I_MAX; + struct pk_bkt_arr_t<int> arr(limits, bkt_buckets, bkt_data); + + struct pk_bkt_arr_handle h = pk_bkt_arr_new_handle(&arr); + arr[h] = 128; + if (h.b != 0) exit(1); + if (h.i != 0) exit(1); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 1) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 1) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFFFE) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + if (arr[h] != 128) exit(1); + + pk_bkt_arr_free_handle(&arr, h); + if (arr.head_l.b != 0) exit(1); + if (arr.head_l.i != 0) exit(1); + if (arr.head_r.b != 0) exit(1); + if (arr.head_r.i != 1) exit(1); + if (arr.idx_unused[0] != 0xFFFFFFFFFFFFFFFF) exit(1); + if (bkt_buckets->allocs != 2) exit(1); + if (bkt_data->allocs != 1) exit(1); + + arr.~pk_bkt_arr_t<int>(); + if (bkt_buckets->allocs != 0) exit(1); + if (bkt_data->allocs != 0) exit(1); + } + test_teardown(&bkt_buckets, &bkt_data); +} |
