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