source: mainline/uspace/lib/c/test/adt/odict.c@ cdec2a1

Last change on this file since cdec2a1 was cdec2a1, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

correcting location of pcut test for odict

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 * Copyright (c) 2016 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <adt/odict.h>
30#include <pcut/pcut.h>
31#include <stdio.h>
32#include <stdlib.h>
33
34/** Test entry */
35typedef struct {
36 odlink_t odict;
37 int key;
38} test_entry_t;
39
40enum {
41 /** Length of test number sequences */
42 test_seq_len = 100
43};
44
45/** Test get key function.
46 *
47 * @param odlink Ordered dictionary link
48 * @return Pointer to key
49 */
50static void *test_getkey(odlink_t *odlink)
51{
52 return &odict_get_instance(odlink, test_entry_t, odict)->key;
53}
54
55/** Test compare function.
56 *
57 * @param a First key
58 * @param b Second key
59 * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
60 */
61static int test_cmp(void *a, void *b)
62{
63 int *ia = (int *)a;
64 int *ib = (int *)b;
65
66 return *ia - *ib;
67}
68
69PCUT_INIT;
70
71PCUT_TEST_SUITE(odict);
72
73/** Increasing sequence test.
74 *
75 * Test initialization, emptiness, insertion of increasing sequence and walking.
76 */
77PCUT_TEST(incr_seq)
78{
79 odict_t odict;
80 test_entry_t *e;
81 odlink_t *c;
82 int i;
83
84 odict_initialize(&odict, test_getkey, test_cmp);
85
86 PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
87
88 for (i = 0; i < test_seq_len; i++) {
89 e = calloc(1, sizeof(test_entry_t));
90 PCUT_ASSERT_NOT_NULL(e);
91
92 e->key = i;
93 odict_insert(&e->odict, &odict, NULL);
94 PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
95 }
96
97 i = 0;
98 c = odict_first(&odict);
99 while (c != NULL) {
100 e = odict_get_instance(c, test_entry_t, odict);
101 PCUT_ASSERT_INT_EQUALS(i, e->key);
102 c = odict_next(c, &odict);
103 ++i;
104 }
105 PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
106
107 i = test_seq_len;
108 c = odict_last(&odict);
109 while (c != NULL) {
110 --i;
111 e = odict_get_instance(c, test_entry_t, odict);
112 PCUT_ASSERT_INT_EQUALS(i, e->key);
113 c = odict_prev(c, &odict);
114 }
115
116 PCUT_ASSERT_INT_EQUALS(0, i);
117}
118
119/** Decreasing sequence test.
120 *
121 * Test initialization, emptiness, insertion of decreasing sequence and walking.
122 */
123PCUT_TEST(decr_seq)
124{
125 odict_t odict;
126 test_entry_t *e;
127 odlink_t *c;
128 int i;
129
130 odict_initialize(&odict, test_getkey, test_cmp);
131
132 PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
133
134 for (i = 0; i < test_seq_len; i++) {
135 e = calloc(1, sizeof(test_entry_t));
136 PCUT_ASSERT_NOT_NULL(e);
137
138 e->key = test_seq_len - i - 1;
139 odict_insert(&e->odict, &odict, NULL);
140 PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
141 }
142
143 i = 0;
144 c = odict_first(&odict);
145 while (c != NULL) {
146 e = odict_get_instance(c, test_entry_t, odict);
147 PCUT_ASSERT_INT_EQUALS(i, e->key);
148 c = odict_next(c, &odict);
149 ++i;
150 }
151 PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
152
153 i = test_seq_len;
154 c = odict_last(&odict);
155 while (c != NULL) {
156 --i;
157 e = odict_get_instance(c, test_entry_t, odict);
158 PCUT_ASSERT_INT_EQUALS(i, e->key);
159 c = odict_prev(c, &odict);
160 }
161
162 PCUT_ASSERT_INT_EQUALS(0, i);
163}
164
165/** Increasing sequence insertion and removal test.
166 *
167 * Test sequential insertion of increasing sequence and sequential removal.
168 */
169PCUT_TEST(incr_seq_ins_rem)
170{
171 odict_t odict;
172 test_entry_t *e;
173 odlink_t *c;
174 int i;
175
176 odict_initialize(&odict, test_getkey, test_cmp);
177
178 PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
179
180 for (i = 0; i < test_seq_len; i++) {
181 e = calloc(1, sizeof(test_entry_t));
182 PCUT_ASSERT_NOT_NULL(e);
183
184 e->key = i;
185 odict_insert(&e->odict, &odict, NULL);
186 PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
187 }
188
189 i = 0;
190 c = odict_first(&odict);
191 while (c != NULL) {
192 e = odict_get_instance(c, test_entry_t, odict);
193 PCUT_ASSERT_INT_EQUALS(i, e->key);
194
195 odict_remove(c);
196 PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
197
198 c = odict_first(&odict);
199 ++i;
200 }
201
202 PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
203}
204
205/** Generate pseudorandom sequence. */
206static int seq_next(int cur)
207{
208 return (cur * 1951) % 1000000;
209}
210
211/** Test 4.
212 *
213 * Test inserting a pseudorandom sequence and then extracting it again.
214 */
215PCUT_TEST(prseq_ins_extract)
216{
217 odict_t odict;
218 test_entry_t *e, *ep;
219 odlink_t *c, *d;
220 int prev;
221 int i;
222 int v;
223
224 odict_initialize(&odict, test_getkey, test_cmp);
225
226 PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
227
228 v = 1;
229 ep = NULL;
230 for (i = 0; i < test_seq_len; i++) {
231 e = calloc(1, sizeof(test_entry_t));
232 PCUT_ASSERT_NOT_NULL(e);
233
234 e->key = v;
235 odict_insert(&e->odict, &odict, &ep->odict);
236 PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
237 v = seq_next(v);
238 ep = e;
239 }
240
241 /* Verify that entries are in ascending order */
242 c = odict_first(&odict);
243 prev = -1;
244 i = 0;
245 while (c != NULL) {
246 e = odict_get_instance(c, test_entry_t, odict);
247 PCUT_ASSERT_EQUALS(true, e->key > prev);
248
249 prev = e->key;
250 c = odict_next(c, &odict);
251 ++i;
252 }
253
254 PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
255
256 /* Try extracting the sequence */
257 v = 1;
258 for (i = 0; i < test_seq_len; i++) {
259 c = odict_find_eq(&odict, (void *)&v, NULL);
260 PCUT_ASSERT_NOT_NULL(c);
261
262 e = odict_get_instance(c, test_entry_t, odict);
263 PCUT_ASSERT_INT_EQUALS(v, e->key);
264
265 d = odict_find_eq_last(&odict, (void *)&v, NULL);
266 PCUT_ASSERT_NOT_NULL(d);
267
268 e = odict_get_instance(d, test_entry_t, odict);
269 PCUT_ASSERT_INT_EQUALS(v, e->key);
270
271 odict_remove(c);
272 PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
273
274 v = seq_next(v);
275 }
276}
277
278PCUT_EXPORT(odict);
Note: See TracBrowser for help on using the repository browser.