diff options
author | Martin Schwenke <martin@meltin.net> | 2011-12-07 14:04:54 +1100 |
---|---|---|
committer | Martin Schwenke <martin@meltin.net> | 2011-12-08 17:21:24 +1100 |
commit | af7611e4e05ba4a5d8e0d83de38d25c33da4a3ee (patch) | |
tree | 6feebb52a57c9cf7dc7991cd40afb72744b38723 /ctdb | |
parent | 89b01c8e7b32f7f5d9eeef1b01b2b9d1e778f48a (diff) | |
download | samba-af7611e4e05ba4a5d8e0d83de38d25c33da4a3ee.tar.gz samba-af7611e4e05ba4a5d8e0d83de38d25c33da4a3ee.tar.xz samba-af7611e4e05ba4a5d8e0d83de38d25c33da4a3ee.zip |
Tests - test code for parse_nodestring() function
This function is fairly complex so here is some test code.
This reworks Makefile a bit and also provides test stubs for some
libctdb functions.
Signed-off-by: Martin Schwenke <martin@meltin.net>
(This used to be ctdb commit 5b11f990404c26c279c9ae389483e560f1c01a81)
Diffstat (limited to 'ctdb')
-rwxr-xr-x | ctdb/Makefile.in | 17 | ||||
-rw-r--r-- | ctdb/tests/src/ctdb_parse_nodestring.c | 126 | ||||
-rw-r--r-- | ctdb/tests/src/ctdb_test.c | 60 | ||||
-rw-r--r-- | ctdb/tests/src/libctdb_test.c | 231 |
4 files changed, 429 insertions, 5 deletions
diff --git a/ctdb/Makefile.in b/ctdb/Makefile.in index 3b9648dfe5..2dd2bb7fb4 100755 --- a/ctdb/Makefile.in +++ b/ctdb/Makefile.in @@ -84,6 +84,7 @@ TEST_BINS=tests/bin/ctdb_bench tests/bin/ctdb_fetch tests/bin/ctdb_fetch_one \ tests/bin/ctdb_randrec tests/bin/ctdb_persistent \ tests/bin/ctdb_traverse tests/bin/rb_test tests/bin/ctdb_transaction \ tests/bin/ctdb_takeover_tests tests/bin/ctdb_update_record \ + tests/bin/ctdb_parse_nodestring \ @INFINIBAND_BINS@ BINS = bin/ctdb @CTDB_SCSI_IO@ bin/smnotify bin/ping_pong bin/ltdbtool @CTDB_PMDA@ @@ -234,19 +235,25 @@ tests/bin/ctdb_transaction: $(CTDB_CLIENT_OBJ) tests/src/ctdb_transaction.o @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_transaction.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) CTDB_SERVER_MOST_OBJ = $(CTDB_SERVER_OBJ:server/ctdbd.o=) -CTDB_TEST_C = $(CTDB_SERVER_MOST_OBJ:.o=.c) tests/src/ctdbd_test.c +CTDBD_TEST_C = $(CTDB_SERVER_MOST_OBJ:.o=.c) tests/src/ctdbd_test.c + +CTDB_TEST_C = $(CTDB_CLIENT_OBJ:.o=.c) tools/ctdb.c tools/ctdb_vacuum.c tests/src/ctdb_test.c + CTDB_TEST_OBJ = @TALLOC_OBJ@ @TDB_OBJ@ \ @LIBREPLACEOBJ@ $(EXTRA_OBJ) @TEVENT_OBJ@ $(SOCKET_WRAPPER_OBJ) -CTDB_TEST_DEPENDS = $(CTDB_TEST_OBJ) $(CTDB_SERVER_MOST_C) \ - tests/src/ctdbd_test.c - -tests/src/ctdb_takeover_tests.o: tests/src/ctdb_takeover_tests.c $(CTDB_TEST_C) +tests/src/ctdb_takeover_tests.o: tests/src/ctdb_takeover_tests.c $(CTDBD_TEST_C) tests/bin/ctdb_takeover_tests: $(CTDB_TEST_OBJ) tests/src/ctdb_takeover_tests.o @echo Linking $@ @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_takeover_tests.o $(CTDB_TEST_OBJ) $(LIB_FLAGS) +tests/src/ctdb_parse_nodestring.o: tests/src/ctdb_parse_nodestring.c tests/src/libctdb_test.c $(CTDB_TEST_C) + +tests/bin/ctdb_parse_nodestring: $(CTDB_TEST_OBJ) tests/src/ctdb_parse_nodestring.o + @echo Linking $@ + @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_parse_nodestring.o $(CTDB_TEST_OBJ) @POPT_OBJ@ $(LIB_FLAGS) + tests/bin/ibwrapper_test: $(CTDB_CLIENT_OBJ) ib/ibwrapper_test.o @echo Linking $@ @$(CC) $(CFLAGS) -o $@ ib/ibwrapper_test.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) diff --git a/ctdb/tests/src/ctdb_parse_nodestring.c b/ctdb/tests/src/ctdb_parse_nodestring.c new file mode 100644 index 0000000000..e467c36870 --- /dev/null +++ b/ctdb/tests/src/ctdb_parse_nodestring.c @@ -0,0 +1,126 @@ +/* + Tests for tools/ctdb.c:parse_nodestring() + + Copyright (C) Martin Schwenke 2011 + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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 this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "ctdb_test.c" +#include "libctdb_test.c" + +static void test_read_nodemap(void) +{ + struct ctdb_connection *ctdb = ctdb_connect("foo", NULL, NULL); + + libctdb_test_read_nodemap(ctdb); + libctdb_test_print_nodemap(ctdb); + + ctdb_disconnect(ctdb); +} + +static const char * decode_pnn_mode(uint32_t pnn_mode) +{ + int i; + static const struct { + uint32_t mode; + const char *name; + } pnn_modes[] = { + { CTDB_CURRENT_NODE, "CURRENT_NODE" }, + { CTDB_BROADCAST_ALL, "BROADCAST_ALL" }, + { CTDB_BROADCAST_VNNMAP, "BROADCAST_VNNMAP" }, + { CTDB_BROADCAST_CONNECTED, "BROADCAST_CONNECTED" }, + { CTDB_MULTICAST, "MULTICAST" }, + }; + + for (i = 0; i < ARRAY_SIZE(pnn_modes); i++) { + if (pnn_mode == pnn_modes[i].mode) { + return pnn_modes[i].name; + } + } + + return "PNN"; +} + +static void print_nodes(uint32_t *nodes, uint32_t pnn_mode) +{ + int i; + + printf("NODES:"); + for (i = 0; i < talloc_array_length(nodes); i++) { + printf(" %lu", (unsigned long) nodes[i]); + } + printf("\n"); + + printf("PNN MODE: %s (%lu)\n", + decode_pnn_mode(pnn_mode), (unsigned long) pnn_mode); +} + +static void test_parse_nodestring(const char *nodestring_s, + const char *dd_ok_s) +{ + const char *nodestring; + bool dd_ok; + struct ctdb_connection *ctdb; + uint32_t *nodes; + uint32_t pnn_mode; + + nodestring = strcmp("", nodestring_s) == 0 ? NULL : nodestring_s; + + if (strcasecmp(dd_ok_s, "yes") == 0 || + strcmp(dd_ok_s, "true") == 0) { + dd_ok = true; + } else { + dd_ok = false; + } + + ctdb = ctdb_connect("foo", NULL, NULL); + ctdb_connection = ctdb; + + libctdb_test_read_nodemap(ctdb); + + if (parse_nodestring(NULL, nodestring, dd_ok, &nodes, &pnn_mode)) { + print_nodes(nodes, pnn_mode); + } + + ctdb_disconnect(ctdb); +} + +static void usage(void) +{ + fprintf(stderr, "usage: ctdb_parse_nodelist <op>\n"); + exit(1); +} + +int main(int argc, const char *argv[]) +{ + LogLevel = DEBUG_DEBUG; + if (getenv("CTDB_TEST_LOGLEVEL")) { + LogLevel = atoi(getenv("CTDB_TEST_LOGLEVEL")); + } + + if (argc < 2) { + usage(); + } + + if (argc == 2 && strcmp(argv[1], "read_nodemap") == 0) { + test_read_nodemap(); + } else if (argc == 4 && strcmp(argv[1], "parse_nodestring") == 0) { + test_parse_nodestring(argv[2], argv[3]); + } else { + usage(); + } + + return 0; +} diff --git a/ctdb/tests/src/ctdb_test.c b/ctdb/tests/src/ctdb_test.c new file mode 100644 index 0000000000..533f3f48a1 --- /dev/null +++ b/ctdb/tests/src/ctdb_test.c @@ -0,0 +1,60 @@ +/* + ctdb test include file + + Copyright (C) Martin Schwenke 2011 + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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 this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _CTDBD_TEST_C +#define _CTDBD_TEST_C + +#define main(argc, argv) main_foobar(argc, argv) +#define usage usage_foobar +#include "tools/ctdb.c" +#undef main +#undef usage + +#undef TIMELIMIT +#include "tools/ctdb_vacuum.c" + +/* UTIL_OBJ */ +#include "lib/util/idtree.c" +#include "lib/util/db_wrap.c" +#include "lib/util/strlist.c" +#include "lib/util/util.c" +#include "lib/util/util_time.c" +#include "lib/util/util_file.c" +#include "lib/util/fault.c" +#include "lib/util/substitute.c" +#include "lib/util/signal.c" + +/* CTDB_COMMON_OBJ */ +#include "common/ctdb_io.c" +#include "common/ctdb_util.c" +#include "common/ctdb_ltdb.c" +#include "common/ctdb_message.c" +#include "common/cmdline.c" +#include "lib/util/debug.c" +#include "common/rb_tree.c" +#ifdef _LINUX_ERRNO_H +#include "common/system_linux.c" +#endif +#include "common/system_common.c" +#include "common/ctdb_logging.c" + +/* CTDB_CLIENT_OBJ */ +#include "client/ctdb_client.c" + +#endif /* _CTDBD_TEST_C */ diff --git a/ctdb/tests/src/libctdb_test.c b/ctdb/tests/src/libctdb_test.c new file mode 100644 index 0000000000..9e9c31eff5 --- /dev/null +++ b/ctdb/tests/src/libctdb_test.c @@ -0,0 +1,231 @@ +/* + Test stubs and support functions for some libctdb functions + + Copyright (C) Martin Schwenke 2011 + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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 this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <syslog.h> +#include "ctdb.h" + +/* Can't use the real definition, since including libctdb_private.h + * causes macro conflicts */ +struct ctdb_connection { + struct ctdb_node_map *nodemap; + uint32_t current_node; + uint32_t recmaster; + struct ctdb_ifaces_list *ifaces; +}; + + +/* Read a nodemap from stdin. Each line looks like: + * <PNN> <FLAGS> [RECMASTER] [CURRENT] + * EOF or a blank line terminates input. + */ +void libctdb_test_read_nodemap(struct ctdb_connection *ctdb) +{ + char line[1024]; + + ctdb->nodemap = (struct ctdb_node_map *) malloc(sizeof(uint32_t)); + if (ctdb->nodemap == NULL) { + DEBUG(DEBUG_ERR, ("OOM allocating nodemap\n")); + exit (1); + } + ctdb->nodemap->num = 0; + + while ((fgets(line, sizeof(line), stdin) != NULL) && + (line[0] != '\n')) { + uint32_t pnn, flags; + char *tok, *t; + + /* Get rid of pesky newline */ + if ((t = strchr(line, '\n')) != NULL) { + *t = '\0'; + } + + /* Get PNN */ + tok = strtok(line, " \t"); + if (tok == NULL) { + DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignoed :%s\n", line)); + continue; + } + pnn = (uint32_t)strtoul(tok, NULL, 0); + + /* Get flags */ + tok = strtok(NULL, " \t"); + if (tok == NULL) { + DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored :%s\n", line)); + continue; + } + flags = (uint32_t)strtoul(tok, NULL, 0); + + tok = strtok(NULL, " \t"); + while (tok != NULL) { + if (strcmp(tok, "CURRENT") == 0) { + ctdb->current_node = pnn; + } else if (strcmp(tok, "RECMASTER") == 0) { + ctdb->recmaster = pnn; + } + tok = strtok(NULL, " \t"); + } + + ctdb->nodemap = (struct ctdb_node_map *) realloc(ctdb->nodemap, sizeof(uint32_t) + (ctdb->nodemap->num + 1) * sizeof(struct ctdb_node_and_flags)); + if (ctdb->nodemap == NULL) { + DEBUG(DEBUG_ERR, ("OOM allocating nodemap\n")); + exit (1); + } + + ctdb->nodemap->nodes[ctdb->nodemap->num].pnn = pnn; + ctdb->nodemap->nodes[ctdb->nodemap->num].flags = flags; + ctdb->nodemap->num++; + } +} + +void libctdb_test_print_nodemap(struct ctdb_connection *ctdb) +{ + int i; + + for (i = 0; i < ctdb->nodemap->num; i++) { + printf("%ld\t0x%lx%s%s\n", + (unsigned long) ctdb->nodemap->nodes[i].pnn, + (unsigned long) ctdb->nodemap->nodes[i].flags, + ctdb->nodemap->nodes[i].pnn == ctdb->current_node ? "\tCURRENT" : "", + ctdb->nodemap->nodes[i].pnn == ctdb->recmaster ? "\tRECMASTER" : ""); + } +} + +/* Stubs... */ + +bool ctdb_getnodemap(struct ctdb_connection *ctdb, + uint32_t destnode, struct ctdb_node_map **nodemap) +{ + *nodemap = ctdb->nodemap; + return true; +} + +void ctdb_free_nodemap(struct ctdb_node_map *nodemap) +{ + return; +} + +bool ctdb_getifaces(struct ctdb_connection *ctdb, + uint32_t destnode, struct ctdb_ifaces_list **ifaces) +{ + *ifaces = ctdb->ifaces; + return false; /* Not implemented */ +} + +void ctdb_free_ifaces(struct ctdb_ifaces_list *ifaces) +{ + return; +} + +bool ctdb_getpnn(struct ctdb_connection *ctdb, + uint32_t destnode, + uint32_t *pnn) +{ + if (destnode == CTDB_CURRENT_NODE) { + *pnn = ctdb->current_node; + } else { + *pnn = destnode; + } + return true; +} + +bool ctdb_getrecmode(struct ctdb_connection *ctdb, + uint32_t destnode, + uint32_t *recmode) +{ + *recmode = 0; + return true; +} + +bool ctdb_getrecmaster(struct ctdb_connection *ctdb, + uint32_t destnode, + uint32_t *recmaster) +{ + *recmaster = ctdb->recmaster; + return true; +} + +bool +ctdb_getdbseqnum(struct ctdb_connection *ctdb, + uint32_t destnode, + uint32_t dbid, + uint64_t *seqnum) +{ + *seqnum = 0; + return false; /* Not implemented */ +} + +bool +ctdb_check_message_handlers(struct ctdb_connection *ctdb, + uint32_t destnode, + uint32_t num, + uint64_t *mhs, + uint8_t *result) +{ + *result = 0; + return false; /* Not implemented */ +} + +/* Not a stub, a copy */ +void ctdb_log_file(FILE *outf, int priority, const char *format, va_list ap) +{ + fprintf(outf, "%s:", + priority == LOG_EMERG ? "EMERG" : + priority == LOG_ALERT ? "ALERT" : + priority == LOG_CRIT ? "CRIT" : + priority == LOG_ERR ? "ERR" : + priority == LOG_WARNING ? "WARNING" : + priority == LOG_NOTICE ? "NOTICE" : + priority == LOG_INFO ? "INFO" : + priority == LOG_DEBUG ? "DEBUG" : + "Unknown Error Level"); + + vfprintf(outf, format, ap); + if (priority == LOG_ERR) { + fprintf(outf, " (%s)", strerror(errno)); + } + fprintf(outf, "\n"); +} + +/* Remove type-safety macro. */ +#undef ctdb_connect +struct ctdb_connection *ctdb_connect(const char *addr, + ctdb_log_fn_t log_func, void *log_priv) +{ + struct ctdb_connection *ctdb; + + ctdb = malloc(sizeof(struct ctdb_connection)); + if (ctdb == NULL) { + DEBUG(DEBUG_ERR, ("OOM allocating ctdb_connection\n")); + exit (1); + } + + ctdb->nodemap = NULL; + ctdb->current_node = 0; + ctdb->recmaster = 0; + + return ctdb; +} + +void ctdb_disconnect(struct ctdb_connection *ctdb) +{ + if (ctdb->nodemap != NULL) { + free(ctdb->nodemap); + } + free(ctdb); +} |