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