diff options
Diffstat (limited to 'src/crypto/lhash/lhash_test.c')
-rw-r--r-- | src/crypto/lhash/lhash_test.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/src/crypto/lhash/lhash_test.c b/src/crypto/lhash/lhash_test.c new file mode 100644 index 0000000..cf5e99b --- /dev/null +++ b/src/crypto/lhash/lhash_test.c @@ -0,0 +1,196 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 201410L +#endif + +#include <openssl/crypto.h> +#include <openssl/lhash.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +struct dummy_lhash_node { + char *s; + struct dummy_lhash_node *next; +}; + +struct dummy_lhash { + struct dummy_lhash_node *head; +}; + +static void dummy_lh_free(struct dummy_lhash *lh) { + struct dummy_lhash_node *cur, *next; + + for (cur = lh->head; cur != NULL; cur = next) { + next = cur->next; + free(cur->s); + free(cur); + } +} + +static size_t dummy_lh_num_items(const struct dummy_lhash *lh) { + size_t count = 0; + struct dummy_lhash_node *cur; + + for (cur = lh->head; cur != NULL; cur = cur->next) { + count++; + } + + return count; +} + +static char *dummy_lh_retrieve(struct dummy_lhash *lh, const char *s) { + struct dummy_lhash_node *cur; + + for (cur = lh->head; cur != NULL; cur = cur->next) { + if (strcmp(cur->s, s) == 0) { + return cur->s; + } + } + + return NULL; +} + +static int dummy_lh_insert(struct dummy_lhash *lh, char **old_data, char *s) { + struct dummy_lhash_node *node, *cur; + + for (cur = lh->head; cur != NULL; cur = cur->next) { + if (strcmp(cur->s, s) == 0) { + *old_data = cur->s; + cur->s = s; + return 1; + } + } + + node = malloc(sizeof(struct dummy_lhash_node)); + *old_data = NULL; + node->s = s; + node->next = lh->head; + lh->head = node; + return 1; +} + +static char *dummy_lh_delete(struct dummy_lhash *lh, const void *s) { + struct dummy_lhash_node *cur, **next_ptr; + char *ret; + + next_ptr = &lh->head; + for (cur = lh->head; cur != NULL; cur = cur->next) { + if (strcmp(cur->s, s) == 0) { + ret = cur->s; + *next_ptr = cur->next; + free(cur); + return ret; + } + next_ptr = &cur->next; + } + + return NULL; +} + +static char *rand_string(void) { + unsigned len = 1 + (rand() % 3); + char *ret = malloc(len + 1); + unsigned i; + + for (i = 0; i < len; i++) { + ret[i] = '0' + (rand() & 7); + } + ret[i] = 0; + + return ret; +} + +int main(int argc, char **argv) { + _LHASH *lh; + struct dummy_lhash dummy_lh = {NULL}; + unsigned i; + + CRYPTO_library_init(); + + lh = lh_new(NULL, NULL); + + for (i = 0; i < 100000; i++) { + unsigned action; + char *s, *s1, *s2; + + if (dummy_lh_num_items(&dummy_lh) != lh_num_items(lh)) { + fprintf(stderr, "Length mismatch\n"); + return 1; + } + + action = rand() % 3; + switch (action) { + case 0: + s = rand_string(); + s1 = (char *)lh_retrieve(lh, s); + s2 = dummy_lh_retrieve(&dummy_lh, s); + if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) { + fprintf(stderr, "lh_retrieve failure\n"); + abort(); + } + free(s); + break; + + case 1: + s = rand_string(); + lh_insert(lh, (void **)&s1, s); + dummy_lh_insert(&dummy_lh, &s2, strdup(s)); + + if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) { + fprintf(stderr, "lh_insert failure\n"); + abort(); + } + + if (s1) { + free(s1); + } + if (s2) { + free(s2); + } + break; + + case 2: + s = rand_string(); + s1 = lh_delete(lh, s); + s2 = dummy_lh_delete(&dummy_lh, s); + + if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) { + fprintf(stderr, "lh_insert failure\n"); + abort(); + } + + if (s1) { + free(s1); + } + if (s2) { + free(s2); + } + free(s); + break; + + default: + abort(); + } + } + + lh_doall(lh, free); + lh_free(lh); + dummy_lh_free(&dummy_lh); + printf("PASS\n"); + return 0; +} |