1 /* This file is part of GDBM test suite.
2 Copyright (C) 2011 Free Software Foundation, Inc.
4 GDBM is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 GDBM is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GDBM. If not, see <http://www.gnu.org/licenses/>.
28 int flags = 0; /* gdbm_open flags */
29 int mode = GDBM_WRCREAT; /* gdbm_open mode */
30 int block_size = 0; /* block size for the db. 0 means default */
31 size_t mapped_size_max = 32768; /* size of the memory mapped region */
32 size_t cache_size = 32; /* cache size */
35 get_max_mmap_size (const char *arg)
41 size = strtoul (arg, &p, 10);
45 fprintf (stderr, "%s: ", progname);
52 fprintf (stderr, "%s: bad maxmap\n", progname);
64 const char *resstr[] = { "PASS", "FAIL", "XFAIL", "SKIP" };
65 static int _res_max = sizeof(resstr) / sizeof(resstr[0]);
67 /* A single setopt testcase */
70 char *group; /* Group this testcase belongs to */
71 char *name; /* Testcase name */
72 /* gdbm_setopt arguments: */
73 int code; /* option code */
74 void *valptr; /* points to the value */
75 int valsize; /* size of the value */
76 /* end of arguments */
77 int xfail; /* if !0, expected value of gdbm_errno */
78 int (*test) (void *valptr); /* Test function (can be NULL) */
79 void (*init) (void *valptr, int valsize); /* Initialization function
83 /* Storage for the test value */
89 /* Individual test and initialization functions */
92 test_getflags (void *valptr)
94 int expected = mode | flags;
96 expected |= GDBM_NOMMAP;
98 return (*(int*) valptr == expected) ? RES_PASS : RES_FAIL;
102 test_dbname (void *valptr)
104 char *s = *(char**)valptr;
105 int rc = strcmp (string, dbname) == 0 ? RES_PASS : RES_FAIL;
107 printf ("[got %s instead of %s] ", s, dbname);
113 init_cachesize (void *valptr, int valsize)
115 *(size_t*) valptr = cache_size;
119 test_getcachesize (void *valptr)
121 return *(size_t*) valptr == cache_size ? RES_PASS : RES_FAIL;
125 init_true (void *valptr, int valsize)
131 init_false (void *valptr, int valsize)
137 init_negate_bool (void *valptr, int valsize)
139 *(int*) valptr = !retbool;
143 test_true (void *valptr)
145 return *(int*) valptr == 1 ? RES_PASS : RES_FAIL;
149 test_false (void *valptr)
151 return *(int*) valptr == 0 ? RES_PASS : RES_FAIL;
155 test_negate_bool (void *valptr)
157 return *(int*) valptr == !retbool ? RES_PASS : RES_FAIL;
161 test_bool (void *valptr)
163 return *(int*) valptr == retbool ? RES_PASS : RES_FAIL;
167 test_initial_maxmapsize(void *valptr)
169 return *(size_t*) valptr == SIZE_T_MAX ? RES_PASS : RES_FAIL;
173 init_maxmapsize (void *valptr, int valsize)
175 *(size_t*)valptr = mapped_size_max;
179 test_maxmapsize (void *valptr)
181 size_t page_size = sysconf (_SC_PAGESIZE);
182 size_t expected_size = ((mapped_size_max + page_size - 1) / page_size) *
184 return (*(size_t*) valptr == expected_size) ? RES_PASS : RES_FAIL;
188 test_mmap_group (void *valptr)
197 /* Create a group of testcases for testing a boolean option.
201 set - GDBM_SETxxx option
202 get - GDBM_GETxxx option
204 #define TEST_BOOL_OPTION(grp, set,get) \
206 { #grp, "initial " #get, get, &retbool, sizeof (retbool), \
208 { #grp, #set, set, &intval, sizeof (intval), \
209 0, NULL, init_negate_bool }, \
210 { #grp, #get, get, &intval, sizeof (intval), \
211 0, test_negate_bool, NULL }, \
212 { #grp, #set " true", set, &intval, sizeof (intval), \
213 0, NULL, init_true }, \
214 { #grp, #get, get, &intval, sizeof (intval), \
215 0, test_true, NULL }, \
216 { #grp, #set " false", set, &intval, sizeof (intval), \
217 0, NULL, init_false }, \
218 { #grp, #get, get, &intval, sizeof (intval), \
219 0, test_false, NULL }
222 /* Table of testcases: */
223 struct optest optest_tab[] = {
224 { "GETFLAGS", "GDBM_GETFLAGS", GDBM_GETFLAGS, &intval, sizeof (intval),
228 { "CACHESIZE", "initial GDBM_SETCACHESIZE", GDBM_SETCACHESIZE,
229 &size, sizeof (size), 0,
230 NULL, init_cachesize },
231 { "CACHESIZE", "GDBM_GETCACHESIZE", GDBM_GETCACHESIZE,
232 &size, sizeof (size), 0,
234 { "CACHESIZE", "second GDBM_SETCACHESIZE", GDBM_SETCACHESIZE,
235 &size, sizeof (size),
236 GDBM_OPT_ALREADY_SET, NULL, init_cachesize },
238 TEST_BOOL_OPTION (SYNCMODE, GDBM_SETSYNCMODE, GDBM_GETSYNCMODE),
239 TEST_BOOL_OPTION (CENTFREE, GDBM_SETCENTFREE, GDBM_GETCENTFREE),
240 TEST_BOOL_OPTION (COALESCEBLKS, GDBM_SETCOALESCEBLKS, GDBM_GETCOALESCEBLKS),
243 { "MMAP", NULL, 0, NULL, 0, 0, test_mmap_group },
245 { "MMAP", "initial GDBM_GETMMAP", GDBM_GETMMAP,
246 &intval, sizeof (intval), 0,
248 { "MMAP", "GDBM_SETMMAP false", GDBM_SETMMAP,
249 &intval, sizeof (intval), 0,
251 { "MMAP", "GDBM_GETMMAP", GDBM_GETMMAP,
252 &intval, sizeof (intval), 0,
255 { "MMAP", "initial GDBM_GETMAXMAPSIZE", GDBM_GETMAXMAPSIZE,
256 &size, sizeof (size), 0,
257 test_initial_maxmapsize, NULL },
258 { "MMAP", "GDBM_SETMAXMAPSIZE", GDBM_SETMAXMAPSIZE,
259 &size, sizeof (size), 0,
260 NULL, init_maxmapsize },
261 { "MMAP", "GDBM_GETMAXMAPSIZE", GDBM_GETMAXMAPSIZE,
262 &size, sizeof (size), 0,
263 test_maxmapsize, NULL },
266 { "GETDBNAME", "GDBM_GETDBNAME", GDBM_GETDBNAME,
267 &string, sizeof (string), 0,
272 /* Use ARGV to determine whether to run the given GROUP of
275 ARGV is a NULL-terminated array of allowed group names. A "!"
276 prefix can be used to denote negation. */
278 groupok (char **argv, const char *group)
286 while ((arg = *argv++))
290 if (strcasecmp (arg + 1, group) == 0)
296 if (strcasecmp (arg, group) == 0)
307 main (int argc, char **argv)
312 progname = canonical_progname (argv[0]);
317 if (strcmp (arg, "-h") == 0)
319 printf ("usage: %s [-blocksize=N] [-nolock] [-sync] [-maxmap=N] DBFILE [GROUP [GROUP...]\n",
323 else if (strcmp (arg, "-nolock") == 0)
324 flags |= GDBM_NOLOCK;
325 else if (strcmp (arg, "-sync") == 0)
327 else if (strncmp (arg, "-blocksize=", 11) == 0)
328 block_size = atoi (arg + 11);
329 else if (strncmp (arg, "-maxmap=", 8) == 0)
330 mapped_size_max = get_max_mmap_size (arg + 8);
331 else if (strcmp (arg, "--") == 0)
337 else if (arg[0] == '-')
339 fprintf (stderr, "%s: unknown option %s\n", progname, arg);
348 fprintf (stderr, "%s: wrong arguments\n", progname);
355 dbf = gdbm_open (dbname, block_size, mode|flags, 00664, NULL);
358 fprintf (stderr, "gdbm_open failed: %s\n", gdbm_strerror (gdbm_errno));
362 for (op = optest_tab; op->group; op++)
366 if (!groupok (argv, op->group))
372 const char *grp = op->group;
374 printf ("* %s:", grp);
375 if (op->test && (rc = op->test (NULL)) != RES_PASS)
377 printf (" %s", resstr[rc]);
378 for (op++; op->name && strcmp (op->group, grp) == 0; op++)
386 printf ("%s: ", op->name);
388 op->init (op->valptr, op->valsize);
390 rc = gdbm_setopt (dbf, op->code, op->valptr, op->valsize);
393 if (gdbm_errno == op->xfail)
394 puts (resstr[RES_XFAIL]);
396 printf ("%s: %s\n", resstr[RES_FAIL],
397 gdbm_strerror (gdbm_errno));
400 puts (resstr[RES_PASS]);
403 rc = op->test (op->valptr);
404 assert (rc >= 0 && rc < _res_max);