1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) Copyright 2019 4 * Roman Kapl, SYSGO, rka@sysgo.com 5 */ 6 7 #include <common.h> 8 #include <command.h> 9 #include <search.h> 10 #include <stdio.h> 11 #include <test/env.h> 12 #include <test/ut.h> 13 14 #define SIZE 32 15 #define ITERATIONS 10000 16 17 static int htab_fill(struct unit_test_state *uts, 18 struct hsearch_data *htab, size_t size) 19 { 20 size_t i; 21 ENTRY item; 22 ENTRY *ritem; 23 char key[20]; 24 25 for (i = 0; i < size; i++) { 26 sprintf(key, "%d", (int)i); 27 item.callback = NULL; 28 item.data = key; 29 item.flags = 0; 30 item.key = key; 31 ut_asserteq(1, hsearch_r(item, ENTER, &ritem, htab, 0)); 32 } 33 34 return 0; 35 } 36 37 static int htab_check_fill(struct unit_test_state *uts, 38 struct hsearch_data *htab, size_t size) 39 { 40 size_t i; 41 ENTRY item; 42 ENTRY *ritem; 43 char key[20]; 44 45 for (i = 0; i < size; i++) { 46 sprintf(key, "%d", (int)i); 47 item.callback = NULL; 48 item.flags = 0; 49 item.data = key; 50 item.key = key; 51 hsearch_r(item, FIND, &ritem, htab, 0); 52 ut_assert(ritem); 53 ut_asserteq_str(key, ritem->key); 54 ut_asserteq_str(key, ritem->data); 55 } 56 57 return 0; 58 } 59 60 static int htab_create_delete(struct unit_test_state *uts, 61 struct hsearch_data *htab, size_t iterations) 62 { 63 size_t i; 64 ENTRY item; 65 ENTRY *ritem; 66 char key[20]; 67 68 for (i = 0; i < iterations; i++) { 69 sprintf(key, "cd-%d", (int)i); 70 item.callback = NULL; 71 item.flags = 0; 72 item.data = key; 73 item.key = key; 74 hsearch_r(item, ENTER, &ritem, htab, 0); 75 ritem = NULL; 76 77 hsearch_r(item, FIND, &ritem, htab, 0); 78 ut_assert(ritem); 79 ut_asserteq_str(key, ritem->key); 80 ut_asserteq_str(key, ritem->data); 81 82 ut_asserteq(1, hdelete_r(key, htab, 0)); 83 } 84 85 return 0; 86 } 87 88 /* Completely fill up the hash table */ 89 static int env_test_htab_fill(struct unit_test_state *uts) 90 { 91 struct hsearch_data htab; 92 93 memset(&htab, 0, sizeof(htab)); 94 ut_asserteq(1, hcreate_r(SIZE, &htab)); 95 96 ut_assertok(htab_fill(uts, &htab, SIZE)); 97 ut_assertok(htab_check_fill(uts, &htab, SIZE)); 98 ut_asserteq(SIZE, htab.filled); 99 100 hdestroy_r(&htab); 101 return 0; 102 } 103 104 ENV_TEST(env_test_htab_fill, 0); 105 106 /* Fill the hashtable up halfway an repeateadly delete/create elements 107 * and check for corruption 108 */ 109 static int env_test_htab_deletes(struct unit_test_state *uts) 110 { 111 struct hsearch_data htab; 112 113 memset(&htab, 0, sizeof(htab)); 114 ut_asserteq(1, hcreate_r(SIZE, &htab)); 115 116 ut_assertok(htab_fill(uts, &htab, SIZE / 2)); 117 ut_assertok(htab_create_delete(uts, &htab, ITERATIONS)); 118 ut_assertok(htab_check_fill(uts, &htab, SIZE / 2)); 119 ut_asserteq(SIZE / 2, htab.filled); 120 121 hdestroy_r(&htab); 122 return 0; 123 } 124 125 ENV_TEST(env_test_htab_deletes, 0); 126