1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

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)
This commit is contained in:
Martin Schwenke 2011-12-07 14:04:54 +11:00
parent 89b01c8e7b
commit af7611e4e0
4 changed files with 429 additions and 5 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);
}