From: jsing Date: Wed, 8 May 2024 15:13:23 +0000 (+0000) Subject: Add more regress coverage for lhash. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=080cd0facda91e23daed705d6597785ebeb20dbd;p=openbsd Add more regress coverage for lhash. --- diff --git a/regress/lib/libcrypto/lhash/lhash_test.c b/regress/lib/libcrypto/lhash/lhash_test.c index c7bd51c042e..d6dcb336b0b 100644 --- a/regress/lib/libcrypto/lhash/lhash_test.c +++ b/regress/lib/libcrypto/lhash/lhash_test.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lhash_test.c,v 1.1 2024/05/06 14:31:25 jsing Exp $ */ +/* $OpenBSD: lhash_test.c,v 1.2 2024/05/08 15:13:23 jsing Exp $ */ /* * Copyright (c) 2024 Joel Sing * @@ -21,8 +21,182 @@ #include +/* + * Need to add test coverage for: + * - custom hash function + * - custom comparison function + */ + static void -test_doall_fn(void *arg1, void *arg2) +test_doall_count(void *arg1, void *arg2) +{ + int *count = arg2; + + (*count)++; +} + +static int +test_lhash(void) +{ + const char *a = "a", *b = "b", *c = "c", *d = "d"; + const char *a2 = "a", *b2 = "b"; + _LHASH *lh; + int count; + int failed = 1; + + if ((lh = lh_new(NULL, NULL)) == NULL) + goto failure; + + /* + * Another amazing API... both a successful insert and a failure will + * return NULL. The only way you can tell the difference is to follow + * with a call to lh_error(). + */ + if (lh_retrieve(lh, "a") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved a before insert\n"); + goto failure; + } + if (lh_insert(lh, (void *)a) != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: insert a\n"); + goto failure; + } + if (lh_retrieve(lh, "a") != a) { + fprintf(stderr, "FAIL: failed to retrieve a\n"); + goto failure; + } + + if (lh_retrieve(lh, "b") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved b before insert\n"); + goto failure; + } + if (lh_insert(lh, (void *)b) != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: insert b\n"); + goto failure; + } + if (lh_retrieve(lh, "b") != b) { + fprintf(stderr, "FAIL: failed to retrieve b\n"); + goto failure; + } + + if (lh_retrieve(lh, "c") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved c before insert\n"); + goto failure; + } + if (lh_insert(lh, (void *)c) != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: insert c\n"); + goto failure; + } + if (lh_retrieve(lh, "c") != c) { + fprintf(stderr, "FAIL: failed to retrieve c\n"); + goto failure; + } + + if (lh_retrieve(lh, "d") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved d before insert\n"); + goto failure; + } + if (lh_insert(lh, (void *)d) != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: insert d\n"); + goto failure; + } + if (lh_retrieve(lh, "d") != d) { + fprintf(stderr, "FAIL: failed to retrieve d\n"); + goto failure; + } + + if (lh_num_items(lh) != 4) { + fprintf(stderr, "FAIL: lh_num_items() = %ld, want 4\n", + lh_num_items(lh)); + goto failure; + } + + /* Insert should replace. */ + if (lh_insert(lh, (void *)a2) != a || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: replace a\n"); + goto failure; + } + if (lh_retrieve(lh, "a") != a2) { + fprintf(stderr, "FAIL: failed to retrieve a2\n"); + goto failure; + } + if (lh_insert(lh, (void *)b2) != b || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: replace b\n"); + goto failure; + } + if (lh_retrieve(lh, "b") != b2) { + fprintf(stderr, "FAIL: failed to retrieve b2\n"); + goto failure; + } + + if (lh_num_items(lh) != 4) { + fprintf(stderr, "FAIL: lh_num_items() = %ld, want 4\n", + lh_num_items(lh)); + goto failure; + } + + /* Do all. */ + count = 0; + lh_doall_arg(lh, test_doall_count, &count); + if (count != 4) { + fprintf(stderr, "FAIL: lh_doall_arg failed (count = %d)\n", + count); + goto failure; + } + + /* Delete. */ + if (lh_delete(lh, "z") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: delete succeeded for z\n"); + goto failure; + } + if (lh_delete(lh, "a") != a2 || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: delete failed for a\n"); + goto failure; + } + if (lh_retrieve(lh, "a") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved a after deletion\n"); + goto failure; + } + if (lh_delete(lh, "b") != b2 || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: delete failed for b\n"); + goto failure; + } + if (lh_retrieve(lh, "b") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved b after deletion\n"); + goto failure; + } + if (lh_delete(lh, "c") != c || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: delete failed for c\n"); + goto failure; + } + if (lh_retrieve(lh, "c") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved c after deletion\n"); + goto failure; + } + if (lh_delete(lh, "d") != d || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: delete failed for d\n"); + goto failure; + } + if (lh_retrieve(lh, "d") != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: retrieved d after deletion\n"); + goto failure; + } + + if (lh_num_items(lh) != 0) { + fprintf(stderr, "FAIL: lh_num_items() = %ld, want 0\n", + lh_num_items(lh)); + goto failure; + } + + failed = 0; + + failure: + lh_free(lh); + + return failed; +} + +static void +test_doall_fn(void *arg1) { } @@ -38,13 +212,97 @@ test_lhash_doall(void) /* Call doall multiple times while linked hash is empty. */ for (i = 0; i < 100; i++) - lh_doall_arg(lh, test_doall_fn, NULL); + lh_doall(lh, test_doall_fn); + + failed = 0; + failure: lh_free(lh); + return failed; +} + +static void +test_doall_delete_some(void *arg1, void *arg2) +{ + void *data; + + if (arc4random_uniform(32) != 0) + return; + + data = lh_delete(arg2, arg1); + free(data); +} + +static void +test_doall_delete_all(void *arg1, void *arg2) +{ + void *data; + + data = lh_delete(arg2, arg1); + free(data); +} + +static int +test_lhash_load(void) +{ + uint8_t c3 = 1, c2 = 1, c1 = 1, c0 = 1; + _LHASH *lh; + char *data = NULL; + int i, j; + int failed = 1; + + if ((lh = lh_new(NULL, NULL)) == NULL) + goto failure; + + for (i = 0; i < 1024; i++) { + for (j = 0; j < 1024; j++) { + if ((data = calloc(1, 128)) == NULL) + goto failure; + + data[0] = c0; + data[1] = c1; + data[2] = c2; + data[3] = c3; + + if (++c0 == 0) { + c0++; + c1++; + } + if (c1 == 0) { + c1++; + c2++; + } + if (c2 == 0) { + c2++; + c3++; + } + + if (lh_insert(lh, data) != NULL || lh_error(lh) != 0) { + fprintf(stderr, "FAIL: lh_insert() failed\n"); + goto failure; + } + data = NULL; + } + lh_doall_arg(lh, test_doall_delete_some, lh); + } + + /* We should have ~31,713 entries. */ + if (lh_num_items(lh) < 31000 || lh_num_items(lh) > 33000) { + fprintf(stderr, "FAIL: unexpected number of entries (%ld)\n", + lh_num_items(lh)); + goto failure; + } + failed = 0; failure: + if (lh != NULL) + lh_doall_arg(lh, test_doall_delete_all, lh); + + lh_free(lh); + free(data); + return failed; } @@ -53,7 +311,9 @@ main(int argc, char **argv) { int failed = 0; + failed |= test_lhash(); failed |= test_lhash_doall(); + failed |= test_lhash_load(); return failed; }