• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

proftpd / proftpd / 26182518137

20 May 2026 06:49PM UTC coverage: 93.024% (+0.4%) from 92.635%
26182518137

push

github

51329 of 55178 relevant lines covered (93.02%)

226.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.62
/tests/api/table.c
1
/*
2
 * ProFTPD - FTP server testsuite
3
 * Copyright (c) 2008-2026 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, see <https://www.gnu.org/licenses/>.
17
 *
18
 * As a special exemption, The ProFTPD Project team and other respective
19
 * copyright holders give permission to link this program with OpenSSL, and
20
 * distribute the resulting executable, without including the source code for
21
 * OpenSSL in the source distribution.
22
 */
23

24
/* Table API tests */
25

26
#include "tests.h"
27

28
static pool *p = NULL;
29

30
/* Fixtures */
31

32
static void set_up(void) {
33
  if (p == NULL) {
20✔
34
    p = make_sub_pool(NULL);
20✔
35
  }
20✔
36
}
37

20✔
38
static void tear_down(void) {
39
  if (p) {
20✔
40
    destroy_pool(p);
20✔
41
    p = NULL;
20✔
42
  }
20✔
43
}
44

20✔
45
/* Helper functions */
46

47
static unsigned int b_val_count = 0;
48

49
static int do_cb(const void *key, size_t keysz, const void *value,
50
    size_t valuesz, void *user_data) {
3✔
51

52
  if (*((const char *) value) == 'b') {
53
    b_val_count++;
3✔
54
  }
3✔
55

56
  return -1;
57
}
3✔
58

59
static int do_with_remove_cb(const void *key, size_t keysz, const void *value,
60
    size_t valuesz, void *user_data) {
2✔
61
  pr_table_t *tab;
62

2✔
63
  tab = user_data;
64

2✔
65
  if (*((const char *) value) == 'b') {
66
    b_val_count++;
2✔
67
  }
2✔
68

69
  pr_table_kremove(tab, key, keysz, NULL);
70
  return 0;
2✔
71
}
2✔
72

73
static void table_dump(const char *fmt, ...) {
74
}
×
75

×
76
/* Tests */
77

78
START_TEST (table_alloc_test) {
79
  pr_table_t *tab;
1✔
80

1✔
81
  tab = pr_table_alloc(NULL, 0);
82
  ck_assert_msg(tab == NULL, "Failed to handle null arguments");
1✔
83
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
84

1✔
85
  tab = pr_table_alloc(p, 0);
86
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
1✔
87
}
1✔
88
END_TEST
1✔
89

90
START_TEST (table_nalloc_test) {
91
  pr_table_t *tab;
1✔
92

1✔
93
  tab = pr_table_nalloc(NULL, 0, 0);
94
  ck_assert_msg(tab == NULL, "Failed to handle null arguments");
1✔
95
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
96

1✔
97
  tab = pr_table_nalloc(p, 0, 0);
98
  ck_assert_msg(tab == NULL, "Failed to handle zero chains");
1✔
99
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
100

1✔
101
  tab = pr_table_nalloc(p, 0, 1);
102
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
1✔
103
}
1✔
104
END_TEST
1✔
105

106
START_TEST (table_add_test) {
107
  int res;
1✔
108
  pr_table_t *tab;
1✔
109

1✔
110
  res = pr_table_add(NULL, NULL, NULL, 0);
111
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
112
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
113

1✔
114
  tab = pr_table_alloc(p, 0);
115
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
1✔
116

1✔
117
  res = pr_table_add(tab, NULL, NULL, 0);
118
  ck_assert_msg(res == -1, "Failed to handle null key");
1✔
119
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
120

1✔
121
  res = pr_table_add(tab, "", NULL, 0);
122
  ck_assert_msg(res == 0, "Failed to add null value (len 0) for empty key");
1✔
123

1✔
124
  res = pr_table_add(tab, "", NULL, 1);
125
  ck_assert_msg(res == -1, "Failed to handle null value (len 1) for empty key");
1✔
126
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
127

1✔
128
  res = pr_table_add(tab, "", NULL, 0);
129
  ck_assert_msg(res == -1, "Failed to handle duplicate (empty) key");
1✔
130
  ck_assert_msg(errno == EEXIST, "Failed to set errno to EEXIST");
1✔
131
}
1✔
132
END_TEST
1✔
133

134
START_TEST (table_add_dup_test) {
135
  int res;
1✔
136
  pr_table_t *tab;
1✔
137

1✔
138
  res = pr_table_add_dup(NULL, NULL, NULL, 0);
139
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
140
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
141

1✔
142
  tab = pr_table_alloc(p, 0);
143
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
1✔
144

1✔
145
  res = pr_table_add_dup(tab, NULL, NULL, 0);
146
  ck_assert_msg(res == -1, "Failed to handle null key");
1✔
147
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
148

1✔
149
  res = pr_table_add_dup(tab, "", NULL, 0);
150
  ck_assert_msg(res == 0, "Failed to add null value (len 0) for empty key");
1✔
151

1✔
152
  res = pr_table_add_dup(tab, "", NULL, 1);
153
  ck_assert_msg(res == -1, "Failed to handle null value (len 1) for empty key");
1✔
154
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
155

1✔
156
  res = pr_table_add_dup(tab, "", NULL, 0);
157
  ck_assert_msg(res == 0, "Failed to handle empty value: %s", strerror(errno));
1✔
158

1✔
159
  mark_point();
160
  res = pr_table_add_dup(tab, "foo", "bar", 0);
1✔
161
  ck_assert_msg(res == 0, "Failed to add 'foo': %s", strerror(errno));
1✔
162
}
1✔
163
END_TEST
1✔
164

165
START_TEST (table_count_test) {
166
  int res, ok;
1✔
167
  pr_table_t *tab;
1✔
168

1✔
169
  res = pr_table_count(NULL);
170
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
171
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
172

1✔
173
  tab = pr_table_alloc(p, 0);
174

1✔
175
  ok = 0;
176
  res = pr_table_count(tab);
1✔
177
  ck_assert_msg(res == ok, "Expected count %d, got %d", ok, res);
1✔
178

1✔
179
  res = pr_table_add(tab, "foo", NULL, 0);
180
  ck_assert_msg(res == 0, "Failed to add item to table: %s", strerror(errno));
1✔
181

1✔
182
  ok = 1;
183
  res = pr_table_count(tab);
1✔
184
  ck_assert_msg(res == ok, "Expected count %d, got %d", ok, res);
1✔
185

1✔
186
  res = pr_table_add(tab, "bar", NULL, 0);
187
  ck_assert_msg(res == 0, "Failed to add item to table: %s", strerror(errno));
1✔
188

1✔
189
  ok = 2;
190
  res = pr_table_count(tab);
1✔
191
  ck_assert_msg(res == ok, "Expected count %d, got %d", ok, res);
1✔
192
}
1✔
193
END_TEST
1✔
194

195
START_TEST (table_exists_test) {
196
  int res, ok;
1✔
197
  pr_table_t *tab;
1✔
198

1✔
199
  res = pr_table_exists(NULL, NULL);
200
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
201
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
202

1✔
203
  tab = pr_table_alloc(p, PR_TABLE_FL_MULTI_VALUE);
204
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
1✔
205

1✔
206
  res = pr_table_exists(tab, NULL);
207
  ck_assert_msg(res == -1, "Failed to handle null key");
1✔
208
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
209

1✔
210
  res = pr_table_exists(NULL, "foo");
211
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
212
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
213

1✔
214
  ok = -1;
215
  res = pr_table_exists(tab, "foo");
1✔
216
  ck_assert_msg(res == ok, "Expected value count %d, got %d", ok, res);
1✔
217
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
1✔
218

1✔
219
  res = pr_table_add(tab, "foo", "a", 0);
220
  ck_assert_msg(res == 0, "Failed to add key to table: %s", strerror(errno));
1✔
221

1✔
222
  ok = 1;
223
  res = pr_table_exists(tab, "foo");
1✔
224
  ck_assert_msg(res == ok, "Expected value count %d, got %d", ok, res);
1✔
225

1✔
226
  res = pr_table_add(tab, "foo", "b", 0);
227
  ck_assert_msg(res == 0, "Failed to add key to table: %s", strerror(errno));
1✔
228

1✔
229
  ok = 2;
230
  res = pr_table_exists(tab, "foo");
1✔
231
  ck_assert_msg(res == ok, "Expected value count %d, got %d", ok, res);
1✔
232

1✔
233
  mark_point();
234
  res = pr_table_kexists(NULL, NULL, 0);
1✔
235
  ck_assert_msg(res < 0, "Failed to handle null table");
1✔
236
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
237
    strerror(errno), errno);
1✔
238

239
  mark_point();
240
  res = pr_table_kexists(tab, NULL, 0);
1✔
241
  ck_assert_msg(res < 0, "Failed to handle null key_data");
1✔
242
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
243
    strerror(errno), errno);
1✔
244
}
245
END_TEST
1✔
246

247
START_TEST (table_empty_test) {
248
  int res;
1✔
249
  pr_table_t *tab;
1✔
250

1✔
251
  res = pr_table_empty(NULL);
252
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
253
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
254

1✔
255
  tab = pr_table_alloc(p, 0);
256

1✔
257
  res = pr_table_empty(tab);
258
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
1✔
259

1✔
260
  res = pr_table_add(tab, "foo", NULL, 0);
261
  ck_assert_msg(res == 0, "Failed to add key to table: %s", strerror(errno));
1✔
262

1✔
263
  res = pr_table_count(tab);
264
  ck_assert_msg(res == 1, "Expected table item count of 1, got %d", res);
1✔
265

1✔
266
  res = pr_table_empty(tab);
267
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
1✔
268

1✔
269
  res = pr_table_count(tab);
270
  ck_assert_msg(res == 0, "Expected table item count of 0, got %d", res);
1✔
271
}
1✔
272
END_TEST
1✔
273

274
START_TEST (table_free_test) {
275
  int res;
1✔
276
  pr_table_t *tab;
1✔
277

1✔
278
  res = pr_table_free(NULL);
279
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
280
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
281

1✔
282
  tab = pr_table_alloc(p, 0);
283

1✔
284
  res = pr_table_free(tab);
285
  ck_assert_msg(res == 0, "Failed to free table: %s", strerror(errno));
1✔
286

1✔
287
  tab = pr_table_alloc(p, 0);
288
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
289
  ck_assert_msg(res == 0, "Failed to add item to table: %s", strerror(errno));
1✔
290

1✔
291
  res = pr_table_free(tab);
292
  ck_assert_msg(res == -1, "Failed to handle non-empty table");
1✔
293
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
1✔
294
}
1✔
295
END_TEST
1✔
296

297
START_TEST (table_get_test) {
298
  int ok, xerrno;
1✔
299
  const void *res;
1✔
300
  pr_table_t *tab;
1✔
301
  char *str;
1✔
302
  size_t sz;
1✔
303

1✔
304
  res = pr_table_get(NULL, NULL, NULL);
305
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
306
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
307

1✔
308
  tab = pr_table_alloc(p, 0);
309

1✔
310
  res = pr_table_get(tab, NULL, NULL);
311
  ck_assert_msg(res == NULL, "Failed to handle null key");
1✔
312
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
1✔
313

1✔
314
  ok = pr_table_add(tab, "foo", NULL, 0);
315
  ck_assert_msg(ok == 0, "Failed to add null value to table: %s",
1✔
316
    strerror(errno));
1✔
317

318
  errno = xerrno = 0;
319
  res = pr_table_get(tab, "foo", &sz);
1✔
320
  xerrno = errno;
1✔
321

1✔
322
  ck_assert_msg(res == NULL, "Failed to lookup null value: %s", strerror(errno));
323
  ck_assert_msg(xerrno == 0, "Expected errno 0, got %d (%s)", xerrno,
1✔
324
    strerror(xerrno));
1✔
325

326
  ok = pr_table_add(tab, "bar", "baz", 0);
327
  ck_assert_msg(ok == 0, "Failed to add 'bar' to table: %s", strerror(errno));
1✔
328

1✔
329
  res = pr_table_get(tab, "bar", &sz);
330
  ck_assert_msg(res != NULL, "Failed to lookup value for 'bar': %s",
1✔
331
    strerror(errno));
1✔
332
  ck_assert_msg(sz == 4, "Expected result len of 4, got %lu", (unsigned long)sz);
333

1✔
334
  str = pcalloc(p, sz);
335
  memcpy(str, res, sz);
1✔
336

1✔
337
  ck_assert_msg(strcmp(str, "baz") == 0,
338
    "Expected value '%s', got '%s'", "baz", str);
1✔
339

340
  mark_point();
341
  res = pr_table_kget(NULL, NULL, 0, NULL);
1✔
342
  ck_assert_msg(res == NULL, "Failed to handle null table");
1✔
343
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
344
    strerror(errno), errno);
1✔
345
}
346
END_TEST
1✔
347

348
static unsigned int cache_key_hash(const void *key, size_t keysz) {
349
  return 1;
3✔
350
}
3✔
351

352
START_TEST (table_get_use_cache_test) {
353
  int ok, xerrno;
1✔
354
  const void *res;
1✔
355
  pr_table_t *tab;
1✔
356
  const char *key = "bar";
1✔
357
  char *str;
1✔
358
  size_t sz;
1✔
359

1✔
360
  res = pr_table_get(NULL, NULL, NULL);
361
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
362
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
363

1✔
364
  tab = pr_table_alloc(p, PR_TABLE_FL_USE_CACHE);
365

1✔
366
  /* We use this specific key hash function to ensure that all of the keys we
367
   * add to this table end up in the same linked-list chain.
368
   */
369

370
  ok = pr_table_ctl(tab, PR_TABLE_CTL_SET_KEY_HASH, cache_key_hash);
371
  ck_assert_msg(ok == 0, "Failed to set key hash function for table: %s",
1✔
372
    strerror(errno));
1✔
373

374
  res = pr_table_get(tab, NULL, NULL);
375
  ck_assert_msg(res == NULL, "Failed to handle null key");
1✔
376
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
1✔
377

1✔
378
  ok = pr_table_add(tab, key, "baz", 0);
379
  ck_assert_msg(ok == 0, "Failed to add 'bar' to table: %s", strerror(errno));
1✔
380

1✔
381
  res = pr_table_get(tab, key, &sz);
382
  ck_assert_msg(res != NULL, "Failed to lookup value for 'bar': %s",
1✔
383
    strerror(errno));
1✔
384
  ck_assert_msg(sz == 4, "Expected result len of 4, got %lu", (unsigned long)sz);
385

1✔
386
  str = pcalloc(p, sz);
387
  memcpy(str, res, sz);
1✔
388

1✔
389
  ck_assert_msg(strcmp(str, "baz") == 0,
390
    "Expected value '%s', got '%s'", "baz", str);
1✔
391

392
  /* With the USE_CACHE flag on, we should still receive NULL here. */
393
  errno = xerrno = 0;
394
  res = pr_table_get(tab, key, &sz);
1✔
395
  ck_assert_msg(res == NULL, "Failed to return null next value: %s",
1✔
396
    strerror(errno));
1✔
397
  ck_assert_msg(xerrno == 0, "Expected errno 0, got %d (%s)", xerrno,
398
    strerror(xerrno));
1✔
399

400
}
401
END_TEST
1✔
402

403
START_TEST (table_next_test) {
404
  int ok;
1✔
405
  const char *res;
1✔
406
  size_t sz = 0;
1✔
407
  pr_table_t *tab;
1✔
408

1✔
409
  res = pr_table_next(NULL);
410
  ck_assert_msg(res == NULL, "Failed to handle null table");
1✔
411
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
412

1✔
413
  tab = pr_table_alloc(p, 0);
414

1✔
415
  res = pr_table_next(tab);
416
  ck_assert_msg(res == NULL, "Failed to handle empty table");
1✔
417
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
1✔
418

1✔
419
  ok = pr_table_add(tab, "foo", NULL, 0);
420
  ck_assert_msg(ok == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
421

1✔
422
  res = pr_table_next(tab);
423
  ck_assert_msg(res != NULL, "Failed to get next key: %s", strerror(errno));
1✔
424
  ck_assert_msg(strcmp(res, "foo") == 0,
1✔
425
    "Expected key '%s', got '%s'", "foo", res);
1✔
426

427
  res = pr_table_next(tab);
428
  ck_assert_msg(res == NULL, "Expected no more keys, got '%s'", res);
1✔
429

1✔
430
  pr_table_rewind(tab);
431

1✔
432
  res = pr_table_knext(tab, &sz);
433
  ck_assert_msg(res != NULL, "Failed to get next key: %s", strerror(errno));
1✔
434
  ck_assert_msg(sz == 4, "Expected 4, got %lu", (unsigned long) sz);
1✔
435
  ck_assert_msg(strcmp(res, "foo") == 0,
1✔
436
    "Expected key '%s', got '%s'", "foo", res);
1✔
437

438
  sz = 0;
439
  res = pr_table_knext(tab, &sz);
1✔
440
  ck_assert_msg(res == NULL, "Expected no more keys, got '%s'", res);
1✔
441
}
1✔
442
END_TEST
1✔
443

444
START_TEST (table_rewind_test) {
445
  int res;
1✔
446
  const char *key;
1✔
447
  pr_table_t *tab;
1✔
448

1✔
449
  res = pr_table_rewind(NULL);
450
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
451
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
452

1✔
453
  tab = pr_table_alloc(p, 0);
454

1✔
455
  res = pr_table_rewind(tab);
456
  ck_assert_msg(res == 0, "Failed to handle empty table");
1✔
457

1✔
458
  res = pr_table_add(tab, "foo", NULL, 0);
459
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
460

1✔
461
  key = pr_table_next(tab);
462
  ck_assert_msg(key != NULL, "Failed to get next key: %s", strerror(errno));
1✔
463
  ck_assert_msg(strcmp(key, "foo") == 0,
1✔
464
    "Expected key '%s', got '%s'", "foo", key);
1✔
465

466
  key = pr_table_next(tab);
467
  ck_assert_msg(key == NULL, "Expected no more keys, got '%s'", key);
1✔
468

1✔
469
  res = pr_table_rewind(tab);
470
  ck_assert_msg(res == 0, "Failed to rewind table: %s", strerror(errno));
1✔
471

1✔
472
  key = pr_table_next(tab);
473
  ck_assert_msg(key != NULL, "Failed to get next key: %s", strerror(errno));
1✔
474
  ck_assert_msg(strcmp(key, "foo") == 0,
1✔
475
    "Expected key '%s', got '%s'", "foo", key);
1✔
476

477
  key = pr_table_next(tab);
478
  ck_assert_msg(key == NULL, "Expected no more keys, got '%s'", key);
1✔
479
}
1✔
480
END_TEST
1✔
481

482
START_TEST (table_remove_test) {
483
  int ok;
1✔
484
  const char *res;
1✔
485
  char *str;
1✔
486
  pr_table_t *tab;
1✔
487
  size_t sz;
1✔
488

1✔
489
  res = pr_table_remove(NULL, NULL, NULL);
490
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
491
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
492

1✔
493
  tab = pr_table_alloc(p, 0);
494

1✔
495
  res = pr_table_remove(tab, NULL, 0);
496
  ck_assert_msg(res == NULL, "Failed to handle null key");
1✔
497
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
498

1✔
499
  res = pr_table_remove(tab, "foo", &sz);
500
  ck_assert_msg(res == NULL, "Failed to handle absent value");
1✔
501
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
1✔
502

1✔
503
  ok = pr_table_add(tab, "foo", "bar baz", 0);
504
  ck_assert_msg(ok == 0, "Failed to add key to table: %s", strerror(errno));
1✔
505

1✔
506
  res = pr_table_remove(tab, "foo", &sz);
507
  ck_assert_msg(res != NULL, "Failed to remove 'foo': %s", strerror(errno));
1✔
508
  ck_assert_msg(sz == 8, "Expected value len of 8, got %lu", (unsigned long)sz);
1✔
509

1✔
510
  str = pcalloc(p, sz);
511
  memcpy(str, res, sz);
1✔
512

1✔
513
  ck_assert_msg(strcmp(str, "bar baz") == 0,
514
    "Expected value of '%s', got '%s'", "bar baz", str);
1✔
515

516
  ok = pr_table_count(tab);
517
  ck_assert_msg(ok == 0, "Expected table count of 0, got %d", ok);
1✔
518

1✔
519
  res = pr_table_remove(tab, "foo", &sz);
520
  ck_assert_msg(res == NULL, "Failed to handle absent value");
1✔
521
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
1✔
522

1✔
523
  mark_point();
524
  res = pr_table_kremove(NULL, NULL, 0, NULL);
1✔
525
  ck_assert_msg(res == NULL, "Failed to handle null table");
1✔
526
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
527
    strerror(errno), errno);
1✔
528

529
  mark_point();
530
  res = pr_table_kremove(tab, NULL, 0, NULL);
1✔
531
  ck_assert_msg(res == NULL, "Failed to handle null key data");
1✔
532
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
533
    strerror(errno), errno);
1✔
534
}
535
END_TEST
1✔
536

537
START_TEST (table_set_test) {
538
  int res;
1✔
539
  pr_table_t *tab;
1✔
540
  const void *v;
1✔
541
  char *str;
1✔
542
  size_t sz;
1✔
543

1✔
544
  res = pr_table_set(NULL, NULL, NULL, 0);
545
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
546
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
547

1✔
548
  tab = pr_table_alloc(p, 0);
549

1✔
550
  res = pr_table_set(tab, NULL, NULL, 0);
551
  ck_assert_msg(res == -1, "Failed to handle null key");
1✔
552
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
553

1✔
554
  res = pr_table_set(tab, "foo", NULL, 1);
555
  ck_assert_msg(res == -1, "Failed to handle null value (len 1)");
1✔
556
  ck_assert_msg(errno == EINVAL, "Failed to handle null value (len 1)");
1✔
557

1✔
558
  mark_point();
559
  res = pr_table_set(tab, "foo", "bar", 1);
1✔
560
  ck_assert_msg(res < 0, "Failed to handle empty table");
1✔
561
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
562
    strerror(errno), errno);
1✔
563

564
  res = pr_table_add(tab, "foo", "bar", 0);
565
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
566

1✔
567
  res = pr_table_set(tab, "foo", "BAZ", 0);
568
  ck_assert_msg(res == 0, "Failed to set 'foo' in table: %s", strerror(errno));
1✔
569

1✔
570
  v = pr_table_get(tab, "foo", &sz);
571
  ck_assert_msg(v != NULL, "Failed to retrieve 'foo' from table: %s",
1✔
572
    strerror(errno));
1✔
573
  ck_assert_msg(sz == 4, "Expected len 4, got %lu", (unsigned long)sz);
574

1✔
575
  str = pcalloc(p, sz);
576
  memcpy(str, v, sz);
1✔
577

1✔
578
  ck_assert_msg(strcmp(str, "BAZ") == 0,
579
    "Expected value of '%s', got '%s'", "BAZ", str);
1✔
580
}
581
END_TEST
1✔
582

583
START_TEST (table_do_test) {
584
  int res;
1✔
585
  pr_table_t *tab;
1✔
586

1✔
587
  res = pr_table_do(NULL, NULL, NULL, 0);
588
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
589
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
590

1✔
591
  tab = pr_table_alloc(p, 0);
592

1✔
593
  res = pr_table_do(tab, NULL, NULL, 0);
594
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
595
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
596

1✔
597
  res = pr_table_do(tab, do_cb, NULL, 0);
598
  ck_assert_msg(res == 0, "Failed to handle empty table");
1✔
599

1✔
600
  res = pr_table_add(tab, "foo", "bar", 0);
601
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
602

1✔
603
  res = pr_table_add(tab, "bar", "baz", 0);
604
  ck_assert_msg(res == 0, "Failed to add 'bar' to table: %s", strerror(errno));
1✔
605

1✔
606
  res = pr_table_do(tab, do_cb, NULL, 0);
607
  ck_assert_msg(res == -1, "Expected res %d, got %d", -1, res);
1✔
608
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
1✔
609
  ck_assert_msg(b_val_count == 1, "Expected count %u, got %u", 1, b_val_count);
1✔
610

1✔
611
  b_val_count = 0;
612
  res = pr_table_do(tab, do_cb, NULL, PR_TABLE_DO_FL_ALL);
1✔
613
  ck_assert_msg(res == 0, "Failed to do table: %s", strerror(errno));
1✔
614
  ck_assert_msg(b_val_count == 2, "Expected count %u, got %u", 2, b_val_count);
1✔
615
}
1✔
616
END_TEST
1✔
617

618
START_TEST (table_do_with_remove_test) {
619
  int res;
1✔
620
  pr_table_t *tab;
1✔
621

1✔
622
  tab = pr_table_alloc(p, 0);
623

1✔
624
  res = pr_table_add(tab, "foo", "bar", 0);
625
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
626

1✔
627
  res = pr_table_add(tab, "bar", "baz", 0);
628
  ck_assert_msg(res == 0, "Failed to add 'bar' to table: %s", strerror(errno));
1✔
629

1✔
630
  b_val_count = 0;
631
  res = pr_table_do(tab, do_with_remove_cb, tab, PR_TABLE_DO_FL_ALL);
1✔
632
  ck_assert_msg(res == 0, "Failed to do table: %s", strerror(errno));
1✔
633
  ck_assert_msg(b_val_count == 2, "Expected count %u, got %u", 2, b_val_count);
1✔
634
}
1✔
635
END_TEST
1✔
636

637
START_TEST (table_ctl_test) {
638
  int res;
1✔
639
  pr_table_t *tab;
1✔
640
  unsigned long flags = 0;
1✔
641
  unsigned int max_ents = 0, nchains = 0;
1✔
642

1✔
643
  res = pr_table_ctl(NULL, 0, NULL);
644
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
645
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
646

1✔
647
  tab = pr_table_alloc(p, 0);
648

1✔
649
  mark_point();
650
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_ENT_INSERT, NULL);
1✔
651
  ck_assert_msg(res == 0, "Failed to set entry insert callback: %s",
1✔
652
    strerror(errno));
1✔
653

654
  mark_point();
655
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_ENT_REMOVE, NULL);
1✔
656
  ck_assert_msg(res == 0, "Failed to set entry removal callback: %s",
1✔
657
    strerror(errno));
1✔
658

659
  res = pr_table_add(tab, "foo", "bar", 0);
660
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
661

1✔
662
  mark_point();
663
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, 0);
1✔
664
  ck_assert_msg(res < 0, "Failed to handle SET_MAX_ENTS smaller than table");
1✔
665
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
666
    strerror(errno), errno);
1✔
667

668
  res = pr_table_ctl(tab, 0, NULL);
669
  ck_assert_msg(res == -1, "Failed to handle non-empty table");
1✔
670
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
1✔
671

1✔
672
  res = pr_table_empty(tab);
673
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
1✔
674

1✔
675
  res = pr_table_ctl(tab, 0, NULL);
676
  ck_assert_msg(res == -1, "Failed to handle unknown ctl");
1✔
677
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
678

1✔
679
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_FLAGS, NULL);
680
  ck_assert_msg(res == -1, "Failed to handle SET_FLAGS, null args");
1✔
681
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
682

1✔
683
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_FLAGS, &flags);
684
  ck_assert_msg(res == 0, "Failed to handle SET_FLAGS: %s", strerror(errno));
1✔
685

1✔
686
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, NULL);
687
  ck_assert_msg(res == -1, "Failed to handle SET_NCHAINS, null args");
1✔
688
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
689

1✔
690
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, &nchains);
691
  ck_assert_msg(res == -1, "Failed to handle SET_NCHAINS, zero args");
1✔
692
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
693

1✔
694
  nchains = 1;
695
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, &nchains);
1✔
696
  ck_assert_msg(res == 0, "Failed to handle SET_NCHAINS: %s", strerror(errno));
1✔
697

1✔
698
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
699
  ck_assert_msg(res == -1, "Failed to handle SET_MAX_ENTS, zero args");
1✔
700
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
701

1✔
702
  /* Add two entries, then try to set MAX_ENTS to one.  We should get an
703
   * EPERM back for that.
704
   */
705
  res = pr_table_add(tab, "foo", "bar", 0);
706
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
707

1✔
708
  res = pr_table_add(tab, "baz", "quxx", 0);
709
  ck_assert_msg(res == 0, "Failed to add 'baz' to table: %s", strerror(errno));
1✔
710

1✔
711
  max_ents = 1;
712
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
1✔
713
  ck_assert_msg(res == -1, "Failed to handle SET_MAX_ENTS on non-empty table");
1✔
714
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
1✔
715

1✔
716
  /* Now empty the table, set the MAX_ENTS to one, then try add two entries. */
717

718
  res = pr_table_empty(tab);
719
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
1✔
720

1✔
721
  max_ents = 1;
722
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
1✔
723
  ck_assert_msg(res == 0, "Failed to handle SET_MAX_ENTS to %d: %s",
1✔
724
    max_ents, strerror(errno));
1✔
725

726
  res = pr_table_add(tab, "foo", "bar", 0);
727
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
728

1✔
729
  res = pr_table_add(tab, "baz", "quxx", 0);
730
  ck_assert_msg(res == -1, "Added second entry unexpectedly");
1✔
731
  ck_assert_msg(errno == ENOSPC,
1✔
732
    "Failed to set errno to ENOSPC, received %d (%s)", errno, strerror(errno));
1✔
733
}
734
END_TEST
1✔
735

736
START_TEST (table_load_test) {
737
  pr_table_t *tab = NULL;
1✔
738
  float load;
1✔
739

1✔
740
  load = pr_table_load(tab);
741
  ck_assert_msg(load < 0, "Failed to handle NULL table argument");
1✔
742
  ck_assert_msg(errno == EINVAL,
1✔
743
    "Failed to set errno to EINVAL; received %d (%s)", errno, strerror(errno));
1✔
744

745
  tab = pr_table_alloc(p, 0);
746
  load = pr_table_load(tab);
1✔
747
  ck_assert_msg(load >= 0.0, "Failed to calculate load properly; load = %0.3f",
1✔
748
    load);
1✔
749
}
750
END_TEST
1✔
751

752
START_TEST (table_dump_test) {
753
  pr_table_t *tab;
1✔
754

1✔
755
  pr_table_dump(NULL, NULL);
756

1✔
757
  tab = pr_table_alloc(p, 0);
758

1✔
759
  pr_table_dump(NULL, tab);
760
  pr_table_dump(table_dump, NULL);
1✔
761
}
1✔
762
END_TEST
1✔
763

764
START_TEST (table_pcalloc_test) {
765
  void *res;
1✔
766
  pr_table_t *tab;
1✔
767

1✔
768
  res = pr_table_pcalloc(NULL, 0);
769
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
770
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
771

1✔
772
  tab = pr_table_alloc(p, 0);
773

1✔
774
  res = pr_table_pcalloc(tab, 0);
775
  ck_assert_msg(res == NULL, "Failed to handle zero len argument");
1✔
776
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
777

1✔
778
  res = pr_table_pcalloc(NULL, 1);
779
  ck_assert_msg(res == NULL, "Failed to handle null table");
1✔
780
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
1✔
781

1✔
782
  res = pr_table_pcalloc(tab, 2);
783
  ck_assert_msg(res != NULL, "Failed to allocate len 2 from table: %s",
1✔
784
    strerror(errno));
1✔
785
}
786
END_TEST
1✔
787

788
Suite *tests_get_table_suite(void) {
789
  Suite *suite;
889✔
790
  TCase *testcase;
889✔
791

889✔
792
  suite = suite_create("table");
793
  testcase = tcase_create("base");
889✔
794

889✔
795
  tcase_add_checked_fixture(testcase, set_up, tear_down);
796

889✔
797
  tcase_add_test(testcase, table_alloc_test);
798
  tcase_add_test(testcase, table_nalloc_test);
889✔
799
  tcase_add_test(testcase, table_add_test);
889✔
800
  tcase_add_test(testcase, table_add_dup_test);
889✔
801
  tcase_add_test(testcase, table_count_test);
889✔
802
  tcase_add_test(testcase, table_exists_test);
889✔
803
  tcase_add_test(testcase, table_empty_test);
889✔
804
  tcase_add_test(testcase, table_free_test);
889✔
805
  tcase_add_test(testcase, table_get_test);
889✔
806
  tcase_add_test(testcase, table_get_use_cache_test);
889✔
807
  tcase_add_test(testcase, table_next_test);
889✔
808
  tcase_add_test(testcase, table_rewind_test);
889✔
809
  tcase_add_test(testcase, table_remove_test);
889✔
810
  tcase_add_test(testcase, table_set_test);
889✔
811
  tcase_add_test(testcase, table_do_test);
889✔
812
  tcase_add_test(testcase, table_do_with_remove_test);
889✔
813
  tcase_add_test(testcase, table_ctl_test);
889✔
814
  tcase_add_test(testcase, table_load_test);
889✔
815
  tcase_add_test(testcase, table_dump_test);
889✔
816
  tcase_add_test(testcase, table_pcalloc_test);
889✔
817

889✔
818
  suite_add_tcase(suite, testcase);
819
  return suite;
889✔
820
}
889✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc