1 /* 2 * Copyright (c) 2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "qdf_ptr_hash.h" 20 #include "qdf_ptr_hash_test.h" 21 #include "qdf_trace.h" 22 23 #define qdf_ptr_hash_bits 4 /* 16 buckets */ 24 #define qdf_ptr_hash_entry_count 10 25 26 struct qdf_ptr_hash_test_item { 27 uint32_t id; 28 struct qdf_ptr_hash_entry entry; 29 }; 30 31 static uint32_t __qdf_ptr_hash_test_empty(struct qdf_ptr_hash *ht) 32 { 33 struct qdf_ptr_hash_test_item *item; 34 35 /* a new ptr_hash should ... */ 36 37 /* ... be empty */ 38 QDF_BUG(qdf_ptr_hash_empty(ht)); 39 40 /* ... return NULL with get()'d */ 41 QDF_BUG(!qdf_ptr_hash_get(ht, NULL, item, entry)); 42 43 return 0; 44 } 45 46 static uint32_t qdf_ptr_hash_test_empty(void) 47 { 48 qdf_ptr_hash_declare_ptr(ht, qdf_ptr_hash_bits); 49 int errors; 50 51 qdf_ptr_hash_init(ht); 52 errors = __qdf_ptr_hash_test_empty(ht); 53 qdf_ptr_hash_deinit(ht); 54 55 return errors; 56 } 57 58 static uint32_t __qdf_ptr_hash_test_add_remove(struct qdf_ptr_hash *ht) 59 { 60 struct qdf_ptr_hash_test_item items[qdf_ptr_hash_entry_count]; 61 struct qdf_ptr_hash_test_item *item; 62 int i; 63 64 /* a ptr_hash with items should ... */ 65 for (i = 0; i < qdf_ptr_hash_entry_count; i++) { 66 items[i].id = i; 67 qdf_ptr_hash_add(ht, &items[i], &items[i], entry); 68 } 69 70 /* ... not be empty */ 71 QDF_BUG(!qdf_ptr_hash_empty(ht)); 72 73 /* ... be able to get() all items previously add()'d */ 74 for (i = 0; i < qdf_ptr_hash_entry_count; i++) { 75 QDF_BUG(qdf_ptr_hash_get(ht, &items[i], item, entry)); 76 QDF_BUG(item->id == items[i].id); 77 } 78 79 /* ... be able to remove() all items previously add()'d */ 80 for (i = 0; i < qdf_ptr_hash_entry_count; i++) { 81 QDF_BUG(qdf_ptr_hash_remove(ht, &items[i], item, entry)); 82 QDF_BUG(item->id == items[i].id); 83 } 84 85 /* ... be empty after remove()'ing all items */ 86 QDF_BUG(qdf_ptr_hash_empty(ht)); 87 88 return 0; 89 } 90 91 static uint32_t qdf_ptr_hash_test_add_remove(void) 92 { 93 qdf_ptr_hash_declare_ptr(ht, qdf_ptr_hash_bits); 94 int errors; 95 96 qdf_ptr_hash_init(ht); 97 errors = __qdf_ptr_hash_test_add_remove(ht); 98 qdf_ptr_hash_deinit(ht); 99 100 return errors; 101 } 102 103 static uint32_t __qdf_ptr_hash_test_for_each(struct qdf_ptr_hash *ht) 104 { 105 struct qdf_ptr_hash_bucket *bucket; 106 struct qdf_ptr_hash_test_item items[qdf_ptr_hash_entry_count]; 107 struct qdf_ptr_hash_test_item *item; 108 int i; 109 int count; 110 111 /* a ptr_hash with items should ... */ 112 for (i = 0; i < qdf_ptr_hash_entry_count; i++) { 113 items[i].id = i; 114 qdf_ptr_hash_add(ht, i, &items[i], entry); 115 } 116 117 /* ... be able to iterate over each item */ 118 count = 0; 119 qdf_ptr_hash_for_each(ht, bucket, item, entry) { 120 QDF_BUG(item->id == items[item->id].id); 121 count++; 122 } 123 QDF_BUG(count == qdf_ptr_hash_entry_count); 124 125 /* ... be able to interate by hash value */ 126 count = 0; 127 for (i = 0; i < qdf_ptr_hash_entry_count; i++) { 128 qdf_ptr_hash_for_each_by_hash(ht, i, item, entry) { 129 QDF_BUG(item->id == items[item->id].id); 130 count++; 131 } 132 } 133 QDF_BUG(count >= qdf_ptr_hash_entry_count); 134 135 /* ... be able to interate by key value */ 136 for (i = 0; i < qdf_ptr_hash_entry_count; i++) { 137 count = 0; 138 qdf_ptr_hash_for_each_by_key(ht, i, item, entry) { 139 QDF_BUG(item->id == items[i].id); 140 count++; 141 } 142 QDF_BUG(count == 1); 143 } 144 145 /* ... be able to remove each item */ 146 for (i = 0; i < qdf_ptr_hash_entry_count; i++) { 147 qdf_ptr_hash_remove(ht, i, item, entry); 148 QDF_BUG(item); 149 QDF_BUG(item->id == items[i].id); 150 } 151 152 /* ... be empty after all items are removed */ 153 QDF_BUG(qdf_ptr_hash_empty(ht)); 154 155 return 0; 156 } 157 158 static uint32_t qdf_ptr_hash_test_for_each(void) 159 { 160 qdf_ptr_hash_declare_ptr(ht, qdf_ptr_hash_bits); 161 int errors; 162 163 qdf_ptr_hash_init(ht); 164 errors = __qdf_ptr_hash_test_for_each(ht); 165 qdf_ptr_hash_deinit(ht); 166 167 return errors; 168 } 169 170 static uint32_t qdf_ptr_hash_test_create_destroy(void) 171 { 172 struct qdf_ptr_hash *ht = qdf_ptr_hash_create(qdf_ptr_hash_bits); 173 uint32_t errors = 0; 174 175 QDF_BUG(ht); 176 errors += __qdf_ptr_hash_test_empty(ht); 177 errors += __qdf_ptr_hash_test_add_remove(ht); 178 errors += __qdf_ptr_hash_test_for_each(ht); 179 180 qdf_ptr_hash_destroy(ht); 181 182 return errors; 183 } 184 185 uint32_t qdf_ptr_hash_unit_test(void) 186 { 187 uint32_t errors = 0; 188 189 errors += qdf_ptr_hash_test_empty(); 190 errors += qdf_ptr_hash_test_add_remove(); 191 errors += qdf_ptr_hash_test_for_each(); 192 errors += qdf_ptr_hash_test_create_destroy(); 193 194 return errors; 195 } 196 197