diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-08-11 16:45:54 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-08-11 16:45:54 +0000 |
commit | 580c5e7d1e0ced62182bd936c7c2698b6611e000 (patch) | |
tree | 4badf97f24436088222de22e7ee254f01133a0c5 | |
parent | bd2e0f98caf08c5c0448773cd1cf91dceee557bb (diff) | |
download | gdbm-580c5e7d1e0ced62182bd936c7c2698b6611e000.tar.gz gdbm-580c5e7d1e0ced62182bd936c7c2698b6611e000.tar.bz2 |
Add testcases for gdbm_setopt.
* tests/gtopt.c: New file
* tests/.cvsignore: Update.
* tests/setopt00.at: New testcase.
* tests/setopt01.at: New testcase.
* tests/Makefile.am: Build gtopt. Add setopt00.at and setopt01.at.
* tests/testsuite.at: Include setopt00.at and setopt01.at.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | tests/.cvsignore | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/gtopt.c | 414 | ||||
-rw-r--r-- | tests/setopt00.at | 61 | ||||
-rw-r--r-- | tests/setopt01.at | 37 | ||||
-rw-r--r-- | tests/testsuite.at | 5 |
7 files changed, 533 insertions, 0 deletions
@@ -1,5 +1,16 @@ 2011-08-11 Sergey Poznyakoff <gray@gnu.org.ua> + Add testcases for gdbm_setopt. + + * tests/gtopt.c: New file + * tests/.cvsignore: Update. + * tests/setopt00.at: New testcase. + * tests/setopt01.at: New testcase. + * tests/Makefile.am: Build gtopt. Add setopt00.at and setopt01.at. + * tests/testsuite.at: Include setopt00.at and setopt01.at. + +2011-08-11 Sergey Poznyakoff <gray@gnu.org.ua> + New option GDBM_GETDBNAME. * src/gdbm.h.in (GDBM_GETDBNAME): New option. diff --git a/tests/.cvsignore b/tests/.cvsignore index 8950eb4..3275961 100644 --- a/tests/.cvsignore +++ b/tests/.cvsignore @@ -13,6 +13,7 @@ gtdel gtdump gtfetch gtload +gtopt gtver num2word package.m4 diff --git a/tests/Makefile.am b/tests/Makefile.am index 4520ed1..0339549 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -60,6 +60,8 @@ TESTSUITE_AT = \ delete02.at\ fetch00.at\ fetch01.at\ + setopt00.at\ + setopt01.at\ version.at TESTSUITE = $(srcdir)/testsuite @@ -97,6 +99,7 @@ check_PROGRAMS = \ gtdump\ gtfetch\ gtload\ + gtopt\ gtver\ num2word\ $(DBMPROGS) @@ -108,6 +111,7 @@ gtload_LDADD = ../src/libgdbm.la gtdump_LDADD = ../src/libgdbm.la gtfetch_LDADD = ../src/libgdbm.la gtver_LDADD = ../src/libgdbm.la +gtopt_LDADD = ../src/libgdbm.la dtload_LDADD = ../src/libgdbm.la ../compat/libgdbm_compat.la dtdump_LDADD = ../src/libgdbm.la ../compat/libgdbm_compat.la diff --git a/tests/gtopt.c b/tests/gtopt.c new file mode 100644 index 0000000..13ad8cc --- /dev/null +++ b/tests/gtopt.c @@ -0,0 +1,414 @@ +/* This file is part of GDBM test suite. + Copyright (C) 2011 Free Software Foundation, Inc. + + GDBM is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GDBM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GDBM. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "autoconf.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include "gdbmdefs.h" +#include "progname.h" + +const char *progname; +const char *dbname; +int flags = 0; /* gdbm_open flags */ +int mode = GDBM_WRCREAT; /* gdbm_open mode */ +int block_size = 0; /* block size for the db. 0 means default */ +size_t mapped_size_max = 32768; /* size of the memory mapped region */ +size_t cache_size = 32; /* cache size */ + +static size_t +get_max_mmap_size (const char *arg) +{ + char *p; + size_t size; + + errno = 0; + size = strtoul (arg, &p, 10); + + if (errno) + { + fprintf (stderr, "%s: ", progname); + perror ("maxmap"); + exit (1); + } + + if (*p) + { + fprintf (stderr, "%s: bad maxmap\n", progname); + exit (1); + } + return size; +} + +/* Test results */ +#define RES_PASS 0 +#define RES_FAIL 1 +#define RES_XFAIL 2 +#define RES_SKIP 3 + +const char *resstr[] = { "PASS", "FAIL", "XFAIL", "SKIP" }; +static int _res_max = sizeof(resstr) / sizeof(resstr[0]); + +/* A single setopt testcase */ +struct optest +{ + char *group; /* Group this testcase belongs to */ + char *name; /* Testcase name */ + /* gdbm_setopt arguments: */ + int code; /* option code */ + void *valptr; /* points to the value */ + int valsize; /* size of the value */ + /* end of arguments */ + int xfail; /* if !0, expected value of gdbm_errno */ + int (*test) (void *valptr); /* Test function (can be NULL) */ + void (*init) (void *valptr, int valsize); /* Initialization function + (can be NULL) */ +}; + +/* Storage for the test value */ +char *string; +size_t size; +int intval; +int retbool; + +/* Individual test and initialization functions */ + +int +test_getflags (void *valptr) +{ + int expected = mode | flags; +#ifndef HAVE_MMAP + expected |= GDBM_NOMMAP; +#endif + return (*(int*) valptr == expected) ? RES_PASS : RES_FAIL; +} + +int +test_dbname (void *valptr) +{ + char *s = *(char**)valptr; + int rc = strcmp (string, dbname) == 0 ? RES_PASS : RES_FAIL; + if (rc != RES_PASS) + printf ("[got %s instead of %s] ", s, dbname); + free (s); + return rc; +} + +void +init_cachesize (void *valptr, int valsize) +{ + *(size_t*) valptr = cache_size; +} + +int +test_getcachesize (void *valptr) +{ + return *(size_t*) valptr == cache_size ? RES_PASS : RES_FAIL; +} + +void +init_true (void *valptr, int valsize) +{ + *(int*) valptr = 1; +} + +void +init_false (void *valptr, int valsize) +{ + *(int*) valptr = 0; +} + +void +init_negate_bool (void *valptr, int valsize) +{ + *(int*) valptr = !retbool; +} + +int +test_true (void *valptr) +{ + return *(int*) valptr == 1 ? RES_PASS : RES_FAIL; +} + +int +test_false (void *valptr) +{ + return *(int*) valptr == 0 ? RES_PASS : RES_FAIL; +} + +int +test_negate_bool (void *valptr) +{ + return *(int*) valptr == !retbool ? RES_PASS : RES_FAIL; +} + +int +test_bool (void *valptr) +{ + return *(int*) valptr == retbool ? RES_PASS : RES_FAIL; +} + +int +test_initial_maxmapsize(void *valptr) +{ + return *(size_t*) valptr == SIZE_T_MAX ? RES_PASS : RES_FAIL; +} + +void +init_maxmapsize (void *valptr, int valsize) +{ + *(size_t*)valptr = mapped_size_max; +} + +int +test_maxmapsize (void *valptr) +{ + size_t page_size = sysconf (_SC_PAGESIZE); + size_t expected_size = ((mapped_size_max + page_size - 1) / page_size) * + page_size; + return (*(size_t*) valptr == expected_size) ? RES_PASS : RES_FAIL; +} + +int +test_mmap_group (void *valptr) +{ +#ifdef HAVE_MMAP + return RES_PASS; +#else + return RES_SKIP; +#endif +} + +/* Create a group of testcases for testing a boolean option. + Arguments: + + grp - group name + set - GDBM_SETxxx option + get - GDBM_GETxxx option +*/ +#define TEST_BOOL_OPTION(grp, set,get) \ + { #grp, }, \ + { #grp, "initial " #get, get, &retbool, sizeof (retbool), \ + 0, NULL, NULL }, \ + { #grp, #set, set, &intval, sizeof (intval), \ + 0, NULL, init_negate_bool }, \ + { #grp, #get, get, &intval, sizeof (intval), \ + 0, test_negate_bool, NULL }, \ + { #grp, #set " true", set, &intval, sizeof (intval), \ + 0, NULL, init_true }, \ + { #grp, #get, get, &intval, sizeof (intval), \ + 0, test_true, NULL }, \ + { #grp, #set " false", set, &intval, sizeof (intval), \ + 0, NULL, init_false }, \ + { #grp, #get, get, &intval, sizeof (intval), \ + 0, test_false, NULL } + + +/* Table of testcases: */ +struct optest optest_tab[] = { + { "GETFLAGS", "GDBM_GETFLAGS", GDBM_GETFLAGS, &intval, sizeof (intval), + 0, test_getflags }, + + { "CACHESIZE" }, + { "CACHESIZE", "initial GDBM_SETCACHESIZE", GDBM_SETCACHESIZE, + &size, sizeof (size), 0, + NULL, init_cachesize }, + { "CACHESIZE", "GDBM_GETCACHESIZE", GDBM_GETCACHESIZE, + &size, sizeof (size), 0, + test_getcachesize }, + { "CACHESIZE", "second GDBM_SETCACHESIZE", GDBM_SETCACHESIZE, + &size, sizeof (size), + GDBM_OPT_ALREADY_SET, NULL, init_cachesize }, + + TEST_BOOL_OPTION (SYNCMODE, GDBM_SETSYNCMODE, GDBM_GETSYNCMODE), + TEST_BOOL_OPTION (CENTFREE, GDBM_SETCENTFREE, GDBM_GETCENTFREE), + TEST_BOOL_OPTION (COALESCEBLKS, GDBM_SETCOALESCEBLKS, GDBM_GETCOALESCEBLKS), + + /* MMAP group */ + { "MMAP", NULL, 0, NULL, 0, 0, test_mmap_group }, + + { "MMAP", "initial GDBM_GETMMAP", GDBM_GETMMAP, + &intval, sizeof (intval), 0, + test_true }, + { "MMAP", "GDBM_SETMMAP false", GDBM_SETMMAP, + &intval, sizeof (intval), 0, + NULL, init_false }, + { "MMAP", "GDBM_GETMMAP", GDBM_GETMMAP, + &intval, sizeof (intval), 0, + test_false }, + + { "MMAP", "initial GDBM_GETMAXMAPSIZE", GDBM_GETMAXMAPSIZE, + &size, sizeof (size), 0, + test_initial_maxmapsize, NULL }, + { "MMAP", "GDBM_SETMAXMAPSIZE", GDBM_SETMAXMAPSIZE, + &size, sizeof (size), 0, + NULL, init_maxmapsize }, + { "MMAP", "GDBM_GETMAXMAPSIZE", GDBM_GETMAXMAPSIZE, + &size, sizeof (size), 0, + test_maxmapsize, NULL }, + + + { "GETDBNAME", "GDBM_GETDBNAME", GDBM_GETDBNAME, + &string, sizeof (string), 0, + test_dbname, NULL }, + { NULL } +}; + +/* Use ARGV to determine whether to run the given GROUP of + testcases. + + ARGV is a NULL-terminated array of allowed group names. A "!" + prefix can be used to denote negation. */ +int +groupok (char **argv, const char *group) +{ + int retval = 1; + + if (*argv) + { + char *arg; + + while ((arg = *argv++)) + { + if (*arg == '!') + { + if (strcasecmp (arg + 1, group) == 0) + return 0; + retval = 1; + } + else + { + if (strcasecmp (arg, group) == 0) + return 1; + retval = 0; + } + } + } + + return retval; +} + +int +main (int argc, char **argv) +{ + GDBM_FILE dbf; + struct optest *op; + + progname = canonical_progname (argv[0]); + while (--argc) + { + char *arg = *++argv; + + if (strcmp (arg, "-h") == 0) + { + printf ("usage: %s [-blocksize=N] [-nolock] [-sync] [-maxmap=N] DBFILE [GROUP [GROUP...]\n", + progname); + exit (0); + } + else if (strcmp (arg, "-nolock") == 0) + flags |= GDBM_NOLOCK; + else if (strcmp (arg, "-sync") == 0) + flags |= GDBM_SYNC; + else if (strncmp (arg, "-blocksize=", 11) == 0) + block_size = atoi (arg + 11); + else if (strncmp (arg, "-maxmap=", 8) == 0) + mapped_size_max = get_max_mmap_size (arg + 8); + else if (strcmp (arg, "--") == 0) + { + --argc; + ++argv; + break; + } + else if (arg[0] == '-') + { + fprintf (stderr, "%s: unknown option %s\n", progname, arg); + exit (1); + } + else + break; + } + + if (argc == 0) + { + fprintf (stderr, "%s: wrong arguments\n", progname); + exit (1); + } + dbname = *argv; + ++argv; + --argc; + + dbf = gdbm_open (dbname, block_size, mode|flags, 00664, NULL); + if (!dbf) + { + fprintf (stderr, "gdbm_open failed: %s\n", gdbm_strerror (gdbm_errno)); + exit (1); + } + + for (op = optest_tab; op->group; op++) + { + int rc; + + if (!groupok (argv, op->group)) + continue; + + if (!op->name) + { + /* Group header */ + const char *grp = op->group; + + printf ("* %s:", grp); + if (op->test && (rc = op->test (NULL)) != RES_PASS) + { + printf (" %s", resstr[rc]); + for (op++; op->name && strcmp (op->group, grp) == 0; op++) + ; + op--; + } + putchar ('\n'); + continue; + } + + printf ("%s: ", op->name); + if (op->init) + op->init (op->valptr, op->valsize); + + rc = gdbm_setopt (dbf, op->code, op->valptr, op->valsize); + if (rc) + { + if (gdbm_errno == op->xfail) + puts (resstr[RES_XFAIL]); + else + printf ("%s: %s\n", resstr[RES_FAIL], + gdbm_strerror (gdbm_errno)); + } + else if (!op->test) + puts (resstr[RES_PASS]); + else + { + rc = op->test (op->valptr); + assert (rc >= 0 && rc < _res_max); + puts (resstr[rc]); + } + } + + gdbm_close (dbf); + exit (0); +} + + + diff --git a/tests/setopt00.at b/tests/setopt00.at new file mode 100644 index 0000000..6fe3f41 --- /dev/null +++ b/tests/setopt00.at @@ -0,0 +1,61 @@ +# This file is part of GDBM. -*- autoconf -*- +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# GDBM is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GDBM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ + +AT_SETUP([setopt]) +AT_KEYWORDS([setopt setopt00]) + +AT_CHECK([ +num2word 1:1000 | gtload test.db || exit 2 +gtopt test.db '!MMAP' +], +[0], +[GDBM_GETFLAGS: PASS +* CACHESIZE: +initial GDBM_SETCACHESIZE: PASS +GDBM_GETCACHESIZE: PASS +second GDBM_SETCACHESIZE: XFAIL +* SYNCMODE: +initial GDBM_GETSYNCMODE: PASS +GDBM_SETSYNCMODE: PASS +GDBM_GETSYNCMODE: PASS +GDBM_SETSYNCMODE true: PASS +GDBM_GETSYNCMODE: PASS +GDBM_SETSYNCMODE false: PASS +GDBM_GETSYNCMODE: PASS +* CENTFREE: +initial GDBM_GETCENTFREE: PASS +GDBM_SETCENTFREE: PASS +GDBM_GETCENTFREE: FAIL +GDBM_SETCENTFREE true: PASS +GDBM_GETCENTFREE: FAIL +GDBM_SETCENTFREE false: PASS +GDBM_GETCENTFREE: FAIL +* COALESCEBLKS: +initial GDBM_GETCOALESCEBLKS: PASS +GDBM_SETCOALESCEBLKS: PASS +GDBM_GETCOALESCEBLKS: PASS +GDBM_SETCOALESCEBLKS true: PASS +GDBM_GETCOALESCEBLKS: PASS +GDBM_SETCOALESCEBLKS false: PASS +GDBM_GETCOALESCEBLKS: PASS +GDBM_GETDBNAME: PASS +]) + +AT_CLEANUP + + + + diff --git a/tests/setopt01.at b/tests/setopt01.at new file mode 100644 index 0000000..fbe9c71 --- /dev/null +++ b/tests/setopt01.at @@ -0,0 +1,37 @@ +# This file is part of GDBM. -*- autoconf -*- +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# GDBM is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GDBM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ + +AT_SETUP([setopt: mmap options]) +AT_KEYWORDS([setopt setopt01 mmap]) + +AT_CHECK([ +num2word 1:1000 | gtload test.db || exit 2 +gtopt test.db 'MMAP' > out +grep 'MMAP: SKIP' out >/dev/null && AT_SKIP_TEST +cat out +], +[0], +[* MMAP: +initial GDBM_GETMMAP: PASS +GDBM_SETMMAP false: PASS +GDBM_GETMMAP: PASS +initial GDBM_GETMAXMAPSIZE: PASS +GDBM_SETMAXMAPSIZE: PASS +GDBM_GETMAXMAPSIZE: PASS +]) + +AT_CLEANUP + diff --git a/tests/testsuite.at b/tests/testsuite.at index c2f9260..a7827c2 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -54,4 +54,9 @@ m4_include([dbmdel00.at]) m4_include([dbmdel01.at]) m4_include([dbmdel02.at]) +AT_BANNER([DB options]) + +m4_include([setopt00.at]) +m4_include([setopt01.at]) + # End of testsuite.at |