summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xctdb/Makefile.in17
-rw-r--r--ctdb/tests/src/ctdb_parse_nodestring.c126
-rw-r--r--ctdb/tests/src/ctdb_test.c60
-rw-r--r--ctdb/tests/src/libctdb_test.c231
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);
+}