1 /*
2 * ProFTPD - FTP server testsuite
3 * Copyright (c) 2008-2017 The ProFTPD Project team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, The ProFTPD Project team and other respective
20 * copyright holders give permission to link this program with OpenSSL, and
21 * distribute the resulting executable, without including the source code for
22 * OpenSSL in the source distribution.
23 */
24
25 /* Table API tests */
26
27 #include "tests.h"
28
29 static pool *p = NULL;
30
31 /* Fixtures */
32
set_up(void)33 static void set_up(void) {
34 if (p == NULL) {
35 p = make_sub_pool(NULL);
36 }
37 }
38
tear_down(void)39 static void tear_down(void) {
40 if (p) {
41 destroy_pool(p);
42 p = NULL;
43 }
44 }
45
46 /* Helper functions */
47
48 static unsigned int b_val_count = 0;
49
do_cb(const void * key,size_t keysz,const void * value,size_t valuesz,void * user_data)50 static int do_cb(const void *key, size_t keysz, const void *value,
51 size_t valuesz, void *user_data) {
52
53 if (*((const char *) value) == 'b') {
54 b_val_count++;
55 }
56
57 return -1;
58 }
59
do_with_remove_cb(const void * key,size_t keysz,const void * value,size_t valuesz,void * user_data)60 static int do_with_remove_cb(const void *key, size_t keysz, const void *value,
61 size_t valuesz, void *user_data) {
62 pr_table_t *tab;
63
64 tab = user_data;
65
66 if (*((const char *) value) == 'b') {
67 b_val_count++;
68 }
69
70 pr_table_kremove(tab, key, keysz, NULL);
71 return 0;
72 }
73
table_dump(const char * fmt,...)74 static void table_dump(const char *fmt, ...) {
75 }
76
77 /* Tests */
78
START_TEST(table_alloc_test)79 START_TEST (table_alloc_test) {
80 pr_table_t *tab;
81
82 tab = pr_table_alloc(NULL, 0);
83 fail_unless(tab == NULL, "Failed to handle null arguments");
84 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
85
86 tab = pr_table_alloc(p, 0);
87 fail_unless(tab != NULL, "Failed to allocate table: %s", strerror(errno));
88 }
89 END_TEST
90
START_TEST(table_nalloc_test)91 START_TEST (table_nalloc_test) {
92 pr_table_t *tab;
93
94 tab = pr_table_nalloc(NULL, 0, 0);
95 fail_unless(tab == NULL, "Failed to handle null arguments");
96 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
97
98 tab = pr_table_nalloc(p, 0, 0);
99 fail_unless(tab == NULL, "Failed to handle zero chains");
100 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
101
102 tab = pr_table_nalloc(p, 0, 1);
103 fail_unless(tab != NULL, "Failed to allocate table: %s", strerror(errno));
104 }
105 END_TEST
106
START_TEST(table_add_test)107 START_TEST (table_add_test) {
108 int res;
109 pr_table_t *tab;
110
111 res = pr_table_add(NULL, NULL, NULL, 0);
112 fail_unless(res == -1, "Failed to handle null arguments");
113 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
114
115 tab = pr_table_alloc(p, 0);
116 fail_unless(tab != NULL, "Failed to allocate table: %s", strerror(errno));
117
118 res = pr_table_add(tab, NULL, NULL, 0);
119 fail_unless(res == -1, "Failed to handle null key");
120 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
121
122 res = pr_table_add(tab, "", NULL, 0);
123 fail_unless(res == 0, "Failed to add null value (len 0) for empty key");
124
125 res = pr_table_add(tab, "", NULL, 1);
126 fail_unless(res == -1, "Failed to handle null value (len 1) for empty key");
127 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
128
129 res = pr_table_add(tab, "", NULL, 0);
130 fail_unless(res == -1, "Failed to handle duplicate (empty) key");
131 fail_unless(errno == EEXIST, "Failed to set errno to EEXIST");
132 }
133 END_TEST
134
START_TEST(table_add_dup_test)135 START_TEST (table_add_dup_test) {
136 int res;
137 pr_table_t *tab;
138
139 res = pr_table_add_dup(NULL, NULL, NULL, 0);
140 fail_unless(res == -1, "Failed to handle null arguments");
141 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
142
143 tab = pr_table_alloc(p, 0);
144 fail_unless(tab != NULL, "Failed to allocate table: %s", strerror(errno));
145
146 res = pr_table_add_dup(tab, NULL, NULL, 0);
147 fail_unless(res == -1, "Failed to handle null key");
148 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
149
150 res = pr_table_add_dup(tab, "", NULL, 0);
151 fail_unless(res == 0, "Failed to add null value (len 0) for empty key");
152
153 res = pr_table_add_dup(tab, "", NULL, 1);
154 fail_unless(res == -1, "Failed to handle null value (len 1) for empty key");
155 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
156
157 res = pr_table_add_dup(tab, "", NULL, 0);
158 fail_unless(res == -1, "Failed to handle duplicate (empty) key");
159 fail_unless(errno == EEXIST, "Failed to set errno to EEXIST");
160
161 mark_point();
162 res = pr_table_add_dup(tab, "foo", "bar", 0);
163 fail_unless(res == 0, "Failed to add 'foo': %s", strerror(errno));
164 }
165 END_TEST
166
START_TEST(table_count_test)167 START_TEST (table_count_test) {
168 int res, ok;
169 pr_table_t *tab;
170
171 res = pr_table_count(NULL);
172 fail_unless(res == -1, "Failed to handle null arguments");
173 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
174
175 tab = pr_table_alloc(p, 0);
176
177 ok = 0;
178 res = pr_table_count(tab);
179 fail_unless(res == ok, "Expected count %d, got %d", ok, res);
180
181 res = pr_table_add(tab, "foo", NULL, 0);
182 fail_unless(res == 0, "Failed to add item to table: %s", strerror(errno));
183
184 ok = 1;
185 res = pr_table_count(tab);
186 fail_unless(res == ok, "Expected count %d, got %d", ok, res);
187
188 res = pr_table_add(tab, "bar", NULL, 0);
189 fail_unless(res == 0, "Failed to add item to table: %s", strerror(errno));
190
191 ok = 2;
192 res = pr_table_count(tab);
193 fail_unless(res == ok, "Expected count %d, got %d", ok, res);
194 }
195 END_TEST
196
START_TEST(table_exists_test)197 START_TEST (table_exists_test) {
198 int res, ok;
199 pr_table_t *tab;
200
201 res = pr_table_exists(NULL, NULL);
202 fail_unless(res == -1, "Failed to handle null arguments");
203 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
204
205 tab = pr_table_alloc(p, PR_TABLE_FL_MULTI_VALUE);
206 fail_unless(tab != NULL, "Failed to allocate table: %s", strerror(errno));
207
208 res = pr_table_exists(tab, NULL);
209 fail_unless(res == -1, "Failed to handle null key");
210 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
211
212 res = pr_table_exists(NULL, "foo");
213 fail_unless(res == -1, "Failed to handle null table");
214 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
215
216 ok = -1;
217 res = pr_table_exists(tab, "foo");
218 fail_unless(res == ok, "Expected value count %d, got %d", ok, res);
219 fail_unless(errno == ENOENT, "Failed to set errno to ENOENT");
220
221 res = pr_table_add(tab, "foo", "a", 0);
222 fail_unless(res == 0, "Failed to add key to table: %s", strerror(errno));
223
224 ok = 1;
225 res = pr_table_exists(tab, "foo");
226 fail_unless(res == ok, "Expected value count %d, got %d", ok, res);
227
228 res = pr_table_add(tab, "foo", "b", 0);
229 fail_unless(res == 0, "Failed to add key to table: %s", strerror(errno));
230
231 ok = 2;
232 res = pr_table_exists(tab, "foo");
233 fail_unless(res == ok, "Expected value count %d, got %d", ok, res);
234
235 mark_point();
236 res = pr_table_kexists(NULL, NULL, 0);
237 fail_unless(res < 0, "Failed to handle null table");
238 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
239 strerror(errno), errno);
240
241 mark_point();
242 res = pr_table_kexists(tab, NULL, 0);
243 fail_unless(res < 0, "Failed to handle null key_data");
244 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
245 strerror(errno), errno);
246 }
247 END_TEST
248
START_TEST(table_empty_test)249 START_TEST (table_empty_test) {
250 int res;
251 pr_table_t *tab;
252
253 res = pr_table_empty(NULL);
254 fail_unless(res == -1, "Failed to handle null table");
255 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
256
257 tab = pr_table_alloc(p, 0);
258
259 res = pr_table_empty(tab);
260 fail_unless(res == 0, "Failed to empty table: %s", strerror(errno));
261
262 res = pr_table_add(tab, "foo", NULL, 0);
263 fail_unless(res == 0, "Failed to add key to table: %s", strerror(errno));
264
265 res = pr_table_count(tab);
266 fail_unless(res == 1, "Expected table item count of 1, got %d", res);
267
268 res = pr_table_empty(tab);
269 fail_unless(res == 0, "Failed to empty table: %s", strerror(errno));
270
271 res = pr_table_count(tab);
272 fail_unless(res == 0, "Expected table item count of 0, got %d", res);
273 }
274 END_TEST
275
START_TEST(table_free_test)276 START_TEST (table_free_test) {
277 int res;
278 pr_table_t *tab;
279
280 res = pr_table_free(NULL);
281 fail_unless(res == -1, "Failed to handle null table");
282 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
283
284 tab = pr_table_alloc(p, 0);
285
286 res = pr_table_free(tab);
287 fail_unless(res == 0, "Failed to free table: %s", strerror(errno));
288
289 tab = pr_table_alloc(p, 0);
290 res = pr_table_add(tab, "foo", "bar", 0);
291 fail_unless(res == 0, "Failed to add item to table: %s", strerror(errno));
292
293 res = pr_table_free(tab);
294 fail_unless(res == -1, "Failed to handle non-empty table");
295 fail_unless(errno == EPERM, "Failed to set errno to EPERM");
296 }
297 END_TEST
298
START_TEST(table_get_test)299 START_TEST (table_get_test) {
300 int ok, xerrno;
301 const void *res;
302 pr_table_t *tab;
303 char *str;
304 size_t sz;
305
306 res = pr_table_get(NULL, NULL, NULL);
307 fail_unless(res == NULL, "Failed to handle null arguments");
308 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
309
310 tab = pr_table_alloc(p, 0);
311
312 res = pr_table_get(tab, NULL, NULL);
313 fail_unless(res == NULL, "Failed to handle null key");
314 fail_unless(errno == ENOENT, "Failed to set errno to ENOENT");
315
316 ok = pr_table_add(tab, "foo", NULL, 0);
317 fail_unless(ok == 0, "Failed to add null value to table: %s",
318 strerror(errno));
319
320 errno = xerrno = 0;
321 res = pr_table_get(tab, "foo", &sz);
322 xerrno = errno;
323
324 fail_unless(res == NULL, "Failed to lookup null value: %s", strerror(errno));
325 fail_unless(xerrno == 0, "Expected errno 0, got %d (%s)", xerrno,
326 strerror(xerrno));
327
328 ok = pr_table_add(tab, "bar", "baz", 0);
329 fail_unless(ok == 0, "Failed to add 'bar' to table: %s", strerror(errno));
330
331 res = pr_table_get(tab, "bar", &sz);
332 fail_unless(res != NULL, "Failed to lookup value for 'bar': %s",
333 strerror(errno));
334 fail_unless(sz == 4, "Expected result len of 4, got %u", sz);
335
336 str = pcalloc(p, sz);
337 memcpy(str, res, sz);
338
339 fail_unless(strcmp(str, "baz") == 0,
340 "Expected value '%s', got '%s'", "baz", str);
341
342 mark_point();
343 res = pr_table_kget(NULL, NULL, 0, NULL);
344 fail_unless(res == NULL, "Failed to handle null table");
345 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
346 strerror(errno), errno);
347 }
348 END_TEST
349
cache_key_hash(const void * key,size_t keysz)350 static unsigned int cache_key_hash(const void *key, size_t keysz) {
351 return 1;
352 }
353
START_TEST(table_get_use_cache_test)354 START_TEST (table_get_use_cache_test) {
355 int ok, xerrno;
356 const void *res;
357 pr_table_t *tab;
358 const char *key = "bar";
359 char *str;
360 size_t sz;
361
362 res = pr_table_get(NULL, NULL, NULL);
363 fail_unless(res == NULL, "Failed to handle null arguments");
364 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
365
366 tab = pr_table_alloc(p, PR_TABLE_FL_USE_CACHE);
367
368 /* We use this specific key hash function to ensure that all of the keys we
369 * add to this table end up in the same linked-list chain.
370 */
371
372 ok = pr_table_ctl(tab, PR_TABLE_CTL_SET_KEY_HASH, cache_key_hash);
373 fail_unless(ok == 0, "Failed to set key hash function for table: %s",
374 strerror(errno));
375
376 res = pr_table_get(tab, NULL, NULL);
377 fail_unless(res == NULL, "Failed to handle null key");
378 fail_unless(errno == ENOENT, "Failed to set errno to ENOENT");
379
380 ok = pr_table_add(tab, key, "baz", 0);
381 fail_unless(ok == 0, "Failed to add 'bar' to table: %s", strerror(errno));
382
383 res = pr_table_get(tab, key, &sz);
384 fail_unless(res != NULL, "Failed to lookup value for 'bar': %s",
385 strerror(errno));
386 fail_unless(sz == 4, "Expected result len of 4, got %u", sz);
387
388 str = pcalloc(p, sz);
389 memcpy(str, res, sz);
390
391 fail_unless(strcmp(str, "baz") == 0,
392 "Expected value '%s', got '%s'", "baz", str);
393
394 /* With the USE_CACHE flag on, we should still receive NULL here. */
395 errno = xerrno = 0;
396 res = pr_table_get(tab, key, &sz);
397 fail_unless(res == NULL, "Failed to return null next value: %s",
398 strerror(errno));
399 fail_unless(xerrno == 0, "Expected errno 0, got %d (%s)", xerrno,
400 strerror(xerrno));
401
402 }
403 END_TEST
404
START_TEST(table_next_test)405 START_TEST (table_next_test) {
406 int ok;
407 const char *res;
408 size_t sz = 0;
409 pr_table_t *tab;
410
411 res = pr_table_next(NULL);
412 fail_unless(res == NULL, "Failed to handle null table");
413 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
414
415 tab = pr_table_alloc(p, 0);
416
417 res = pr_table_next(tab);
418 fail_unless(res == NULL, "Failed to handle empty table");
419 fail_unless(errno == EPERM, "Failed to set errno to EPERM");
420
421 ok = pr_table_add(tab, "foo", NULL, 0);
422 fail_unless(ok == 0, "Failed to add 'foo' to table: %s", strerror(errno));
423
424 res = pr_table_next(tab);
425 fail_unless(res != NULL, "Failed to get next key: %s", strerror(errno));
426 fail_unless(strcmp(res, "foo") == 0,
427 "Expected key '%s', got '%s'", "foo", res);
428
429 res = pr_table_next(tab);
430 fail_unless(res == NULL, "Expected no more keys, got '%s'", res);
431
432 pr_table_rewind(tab);
433
434 res = pr_table_knext(tab, &sz);
435 fail_unless(res != NULL, "Failed to get next key: %s", strerror(errno));
436 fail_unless(sz == 4, "Expected 4, got %lu", (unsigned long) sz);
437 fail_unless(strcmp(res, "foo") == 0,
438 "Expected key '%s', got '%s'", "foo", res);
439
440 sz = 0;
441 res = pr_table_knext(tab, &sz);
442 fail_unless(res == NULL, "Expected no more keys, got '%s'", res);
443 }
444 END_TEST
445
START_TEST(table_rewind_test)446 START_TEST (table_rewind_test) {
447 int res;
448 const char *key;
449 pr_table_t *tab;
450
451 res = pr_table_rewind(NULL);
452 fail_unless(res == -1, "Failed to handle null table");
453 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
454
455 tab = pr_table_alloc(p, 0);
456
457 res = pr_table_rewind(tab);
458 fail_unless(res == 0, "Failed to handle empty table");
459
460 res = pr_table_add(tab, "foo", NULL, 0);
461 fail_unless(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
462
463 key = pr_table_next(tab);
464 fail_unless(key != NULL, "Failed to get next key: %s", strerror(errno));
465 fail_unless(strcmp(key, "foo") == 0,
466 "Expected key '%s', got '%s'", "foo", key);
467
468 key = pr_table_next(tab);
469 fail_unless(key == NULL, "Expected no more keys, got '%s'", key);
470
471 res = pr_table_rewind(tab);
472 fail_unless(res == 0, "Failed to rewind table: %s", strerror(errno));
473
474 key = pr_table_next(tab);
475 fail_unless(key != NULL, "Failed to get next key: %s", strerror(errno));
476 fail_unless(strcmp(key, "foo") == 0,
477 "Expected key '%s', got '%s'", "foo", key);
478
479 key = pr_table_next(tab);
480 fail_unless(key == NULL, "Expected no more keys, got '%s'", key);
481 }
482 END_TEST
483
START_TEST(table_remove_test)484 START_TEST (table_remove_test) {
485 int ok;
486 const char *res;
487 char *str;
488 pr_table_t *tab;
489 size_t sz;
490
491 res = pr_table_remove(NULL, NULL, NULL);
492 fail_unless(res == NULL, "Failed to handle null arguments");
493 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
494
495 tab = pr_table_alloc(p, 0);
496
497 res = pr_table_remove(tab, NULL, 0);
498 fail_unless(res == NULL, "Failed to handle null key");
499 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
500
501 res = pr_table_remove(tab, "foo", &sz);
502 fail_unless(res == NULL, "Failed to handle absent value");
503 fail_unless(errno == ENOENT, "Failed to set errno to ENOENT");
504
505 ok = pr_table_add(tab, "foo", "bar baz", 0);
506 fail_unless(ok == 0, "Failed to add key to table: %s", strerror(errno));
507
508 res = pr_table_remove(tab, "foo", &sz);
509 fail_unless(res != NULL, "Failed to remove 'foo': %s", strerror(errno));
510 fail_unless(sz == 8, "Expected value len of 8, got %u", sz);
511
512 str = pcalloc(p, sz);
513 memcpy(str, res, sz);
514
515 fail_unless(strcmp(str, "bar baz") == 0,
516 "Expected value of '%s', got '%s'", "bar baz", str);
517
518 ok = pr_table_count(tab);
519 fail_unless(ok == 0, "Expected table count of 0, got %d", ok);
520
521 res = pr_table_remove(tab, "foo", &sz);
522 fail_unless(res == NULL, "Failed to handle absent value");
523 fail_unless(errno == ENOENT, "Failed to set errno to ENOENT");
524
525 mark_point();
526 res = pr_table_kremove(NULL, NULL, 0, NULL);
527 fail_unless(res == NULL, "Failed to handle null table");
528 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
529 strerror(errno), errno);
530
531 mark_point();
532 res = pr_table_kremove(tab, NULL, 0, NULL);
533 fail_unless(res == NULL, "Failed to handle null key data");
534 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
535 strerror(errno), errno);
536 }
537 END_TEST
538
START_TEST(table_set_test)539 START_TEST (table_set_test) {
540 int res;
541 pr_table_t *tab;
542 const void *v;
543 char *str;
544 size_t sz;
545
546 res = pr_table_set(NULL, NULL, NULL, 0);
547 fail_unless(res == -1, "Failed to handle null arguments");
548 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
549
550 tab = pr_table_alloc(p, 0);
551
552 res = pr_table_set(tab, NULL, NULL, 0);
553 fail_unless(res == -1, "Failed to handle null key");
554 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
555
556 res = pr_table_set(tab, "foo", NULL, 1);
557 fail_unless(res == -1, "Failed to handle null value (len 1)");
558 fail_unless(errno == EINVAL, "Failed to handle null value (len 1)");
559
560 mark_point();
561 res = pr_table_set(tab, "foo", "bar", 1);
562 fail_unless(res < 0, "Failed to handle empty table");
563 fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
564 strerror(errno), errno);
565
566 res = pr_table_add(tab, "foo", "bar", 0);
567 fail_unless(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
568
569 res = pr_table_set(tab, "foo", "BAZ", 0);
570 fail_unless(res == 0, "Failed to set 'foo' in table: %s", strerror(errno));
571
572 v = pr_table_get(tab, "foo", &sz);
573 fail_unless(v != NULL, "Failed to retrieve 'foo' from table: %s",
574 strerror(errno));
575 fail_unless(sz == 4, "Expected len 4, got %u", sz);
576
577 str = pcalloc(p, sz);
578 memcpy(str, v, sz);
579
580 fail_unless(strcmp(str, "BAZ") == 0,
581 "Expected value of '%s', got '%s'", "BAZ", str);
582 }
583 END_TEST
584
START_TEST(table_do_test)585 START_TEST (table_do_test) {
586 int res;
587 pr_table_t *tab;
588
589 res = pr_table_do(NULL, NULL, NULL, 0);
590 fail_unless(res == -1, "Failed to handle null arguments");
591 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
592
593 tab = pr_table_alloc(p, 0);
594
595 res = pr_table_do(tab, NULL, NULL, 0);
596 fail_unless(res == -1, "Failed to handle null arguments");
597 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
598
599 res = pr_table_do(tab, do_cb, NULL, 0);
600 fail_unless(res == 0, "Failed to handle empty table");
601
602 res = pr_table_add(tab, "foo", "bar", 0);
603 fail_unless(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
604
605 res = pr_table_add(tab, "bar", "baz", 0);
606 fail_unless(res == 0, "Failed to add 'bar' to table: %s", strerror(errno));
607
608 res = pr_table_do(tab, do_cb, NULL, 0);
609 fail_unless(res == -1, "Expected res %d, got %d", -1, res);
610 fail_unless(errno == EPERM, "Failed to set errno to EPERM");
611 fail_unless(b_val_count == 1, "Expected count %u, got %u", 1, b_val_count);
612
613 b_val_count = 0;
614 res = pr_table_do(tab, do_cb, NULL, PR_TABLE_DO_FL_ALL);
615 fail_unless(res == 0, "Failed to do table: %s", strerror(errno));
616 fail_unless(b_val_count == 2, "Expected count %u, got %u", 2, b_val_count);
617 }
618 END_TEST
619
START_TEST(table_do_with_remove_test)620 START_TEST (table_do_with_remove_test) {
621 int res;
622 pr_table_t *tab;
623
624 tab = pr_table_alloc(p, 0);
625
626 res = pr_table_add(tab, "foo", "bar", 0);
627 fail_unless(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
628
629 res = pr_table_add(tab, "bar", "baz", 0);
630 fail_unless(res == 0, "Failed to add 'bar' to table: %s", strerror(errno));
631
632 b_val_count = 0;
633 res = pr_table_do(tab, do_with_remove_cb, tab, PR_TABLE_DO_FL_ALL);
634 fail_unless(res == 0, "Failed to do table: %s", strerror(errno));
635 fail_unless(b_val_count == 2, "Expected count %u, got %u", 2, b_val_count);
636 }
637 END_TEST
638
START_TEST(table_ctl_test)639 START_TEST (table_ctl_test) {
640 int res;
641 pr_table_t *tab;
642 unsigned long flags = 0;
643 unsigned int max_ents = 0, nchains = 0;
644
645 res = pr_table_ctl(NULL, 0, NULL);
646 fail_unless(res == -1, "Failed to handle null table");
647 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
648
649 tab = pr_table_alloc(p, 0);
650
651 mark_point();
652 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_ENT_INSERT, NULL);
653 fail_unless(res == 0, "Failed to set entry insert callback: %s",
654 strerror(errno));
655
656 mark_point();
657 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_ENT_REMOVE, NULL);
658 fail_unless(res == 0, "Failed to set entry removal callback: %s",
659 strerror(errno));
660
661 res = pr_table_add(tab, "foo", "bar", 0);
662 fail_unless(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
663
664 mark_point();
665 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, 0);
666 fail_unless(res < 0, "Failed to handle SET_MAX_ENTS smaller than table");
667 fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
668 strerror(errno), errno);
669
670 res = pr_table_ctl(tab, 0, NULL);
671 fail_unless(res == -1, "Failed to handle non-empty table");
672 fail_unless(errno == EPERM, "Failed to set errno to EPERM");
673
674 res = pr_table_empty(tab);
675 fail_unless(res == 0, "Failed to empty table: %s", strerror(errno));
676
677 res = pr_table_ctl(tab, 0, NULL);
678 fail_unless(res == -1, "Failed to handle unknown ctl");
679 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
680
681 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_FLAGS, NULL);
682 fail_unless(res == -1, "Failed to handle SET_FLAGS, null args");
683 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
684
685 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_FLAGS, &flags);
686 fail_unless(res == 0, "Failed to handle SET_FLAGS: %s", strerror(errno));
687
688 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, NULL);
689 fail_unless(res == -1, "Failed to handle SET_NCHAINS, null args");
690 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
691
692 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, &nchains);
693 fail_unless(res == -1, "Failed to handle SET_NCHAINS, zero args");
694 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
695
696 nchains = 1;
697 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, &nchains);
698 fail_unless(res == 0, "Failed to handle SET_NCHAINS: %s", strerror(errno));
699
700 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
701 fail_unless(res == -1, "Failed to handle SET_MAX_ENTS, zero args");
702 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
703
704 /* Add two entries, then try to set MAX_ENTS to one. We should get an
705 * EPERM back for that.
706 */
707 res = pr_table_add(tab, "foo", "bar", 0);
708 fail_unless(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
709
710 res = pr_table_add(tab, "baz", "quxx", 0);
711 fail_unless(res == 0, "Failed to add 'baz' to table: %s", strerror(errno));
712
713 max_ents = 1;
714 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
715 fail_unless(res == -1, "Failed to handle SET_MAX_ENTS on non-empty table");
716 fail_unless(errno == EPERM, "Failed to set errno to EPERM");
717
718 /* Now empty the table, set the MAX_ENTS to one, then try add two entries. */
719
720 res = pr_table_empty(tab);
721 fail_unless(res == 0, "Failed to empty table: %s", strerror(errno));
722
723 max_ents = 1;
724 res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
725 fail_unless(res == 0, "Failed to handle SET_MAX_ENTS to %d: %s",
726 max_ents, strerror(errno));
727
728 res = pr_table_add(tab, "foo", "bar", 0);
729 fail_unless(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
730
731 res = pr_table_add(tab, "baz", "quxx", 0);
732 fail_unless(res == -1, "Added second entry unexpectedly");
733 fail_unless(errno == ENOSPC,
734 "Failed to set errno to ENOSPC, received %s (%d)", errno, strerror(errno));
735 }
736 END_TEST
737
START_TEST(table_load_test)738 START_TEST (table_load_test) {
739 pr_table_t *tab = NULL;
740 float load;
741
742 load = pr_table_load(tab);
743 fail_unless(load < 0, "Failed to handle NULL table argument");
744 fail_unless(errno == EINVAL,
745 "Failed to set errno to EINVAL; received %s (%d)", errno, strerror(errno));
746
747 tab = pr_table_alloc(p, 0);
748 load = pr_table_load(tab);
749 fail_unless(load >= 0.0, "Failed to calculate load properly; load = %0.3f",
750 load);
751 }
752 END_TEST
753
START_TEST(table_dump_test)754 START_TEST (table_dump_test) {
755 pr_table_t *tab;
756
757 pr_table_dump(NULL, NULL);
758
759 tab = pr_table_alloc(p, 0);
760
761 pr_table_dump(NULL, tab);
762 pr_table_dump(table_dump, NULL);
763 }
764 END_TEST
765
START_TEST(table_pcalloc_test)766 START_TEST (table_pcalloc_test) {
767 void *res;
768 pr_table_t *tab;
769
770 res = pr_table_pcalloc(NULL, 0);
771 fail_unless(res == NULL, "Failed to handle null arguments");
772 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
773
774 tab = pr_table_alloc(p, 0);
775
776 res = pr_table_pcalloc(tab, 0);
777 fail_unless(res == NULL, "Failed to handle zero len argument");
778 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
779
780 res = pr_table_pcalloc(NULL, 1);
781 fail_unless(res == NULL, "Failed to handle null table");
782 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
783
784 res = pr_table_pcalloc(tab, 2);
785 fail_unless(res != NULL, "Failed to allocate len 2 from table: %s",
786 strerror(errno));
787 }
788 END_TEST
789
tests_get_table_suite(void)790 Suite *tests_get_table_suite(void) {
791 Suite *suite;
792 TCase *testcase;
793
794 suite = suite_create("table");
795 testcase = tcase_create("base");
796
797 tcase_add_checked_fixture(testcase, set_up, tear_down);
798
799 tcase_add_test(testcase, table_alloc_test);
800 tcase_add_test(testcase, table_nalloc_test);
801 tcase_add_test(testcase, table_add_test);
802 tcase_add_test(testcase, table_add_dup_test);
803 tcase_add_test(testcase, table_count_test);
804 tcase_add_test(testcase, table_exists_test);
805 tcase_add_test(testcase, table_empty_test);
806 tcase_add_test(testcase, table_free_test);
807 tcase_add_test(testcase, table_get_test);
808 tcase_add_test(testcase, table_get_use_cache_test);
809 tcase_add_test(testcase, table_next_test);
810 tcase_add_test(testcase, table_rewind_test);
811 tcase_add_test(testcase, table_remove_test);
812 tcase_add_test(testcase, table_set_test);
813 tcase_add_test(testcase, table_do_test);
814 tcase_add_test(testcase, table_do_with_remove_test);
815 tcase_add_test(testcase, table_ctl_test);
816 tcase_add_test(testcase, table_load_test);
817 tcase_add_test(testcase, table_dump_test);
818 tcase_add_test(testcase, table_pcalloc_test);
819
820 suite_add_tcase(suite, testcase);
821 return suite;
822 }
823