diff options
| author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-03-12 16:09:32 +1100 |
|---|---|---|
| committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-03-12 16:10:09 +1100 |
| commit | f7b2adfde6e2fc225bcb9271dde5d73cfab656bf (patch) | |
| tree | 350cde140fc2b3815259793ac829fbf4c0ac1193 | |
| parent | b9e581e720f567d732aef534f6c9da54438a877c (diff) | |
Test: add test tool and test that UPDATE_RECORD works on persistent databases
(This used to be ctdb commit f06634951331232cddf0b48eac3552b92aca5b93)
| -rwxr-xr-x | ctdb/Makefile.in | 5 | ||||
| -rwxr-xr-x | ctdb/tests/simple/72_update_record_persistent.sh | 89 | ||||
| -rw-r--r-- | ctdb/tests/src/ctdb_update_record_persistent.c | 136 |
3 files changed, 230 insertions, 0 deletions
diff --git a/ctdb/Makefile.in b/ctdb/Makefile.in index 24283f3b08..9055a8f64d 100755 --- a/ctdb/Makefile.in +++ b/ctdb/Makefile.in @@ -85,6 +85,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_update_record_persistent \ tests/bin/ctdb_tool_libctdb tests/bin/ctdb_tool_stubby \ @INFINIBAND_BINS@ @@ -215,6 +216,10 @@ tests/bin/ctdb_update_record: $(CTDB_CLIENT_OBJ) tests/src/ctdb_update_record.o @echo Linking $@ @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_update_record.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) +tests/bin/ctdb_update_record_persistent: $(CTDB_CLIENT_OBJ) tests/src/ctdb_update_record_persistent.o + @echo Linking $@ + @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_update_record_persistent.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) + tests/bin/ctdb_store: $(CTDB_CLIENT_OBJ) tests/src/ctdb_store.o @echo Linking $@ @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_store.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) diff --git a/ctdb/tests/simple/72_update_record_persistent.sh b/ctdb/tests/simple/72_update_record_persistent.sh new file mode 100755 index 0000000000..d232b4006f --- /dev/null +++ b/ctdb/tests/simple/72_update_record_persistent.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +test_info() +{ + cat <<EOF +UPDATE_RECORD control should be able to create new records and update +existing records in a persistent database. + +Prerequisites: + +* An active CTDB cluster with at least one active node. + +Steps: + +1. Verify that the status on all of the ctdb nodes is 'OK'. +2. create a persistent test database +3, wipe the database to make sure it is empty +4, create a new record +5, update the record + +Expected results: + +* 4 created record found in the tdb +* 5 updated record found in the tdb + +EOF +} + +. ctdb_test_functions.bash + +ctdb_test_init "$@" + +set -e + +cluster_is_healthy + +try_command_on_node 0 "$CTDB listnodes" +num_nodes=$(echo "$out" | wc -l) + +# create a temporary persistent database to test with +echo create persistent test database persistent_test.tdb +try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb attach persistent_test.tdb persistent + + +# 3, +echo wipe the persistent test database +try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb wipedb persistent_test.tdb +echo force a recovery +try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb recover + +# check that the database is wiped +num_records=$(try_command_on_node -v -pq 1 $CTDB_TEST_WRAPPER ctdb cattdb persistent_test.tdb | grep key | wc -l) +[ $num_records != "0" ] && { + echo "BAD: we did not end up with an empty database" + exit 1 +} +echo "OK. database was wiped" + +TDB=`try_command_on_node -v -q 0 $CTDB_TEST_WRAPPER ctdb getdbmap | grep persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"` + +# 4, +echo Create a new record in the persistent database using UPDATE_RECORD +try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb_update_record_persistent --database=persistent_test.tdb --record=Update_Record_Persistent --value=FirstValue + +num_records=`tdbdump $TDB | grep "FirstValue" | wc -l` +[ $num_records != 1 ] && { + echo "BAD: we did find the record after the create/update" + exit 1 +} + +# 5, +echo Modify an existing record in the persistent database using UPDATE_RECORD +try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb_update_record_persistent --database=persistent_test.tdb --record=Update_Record_Persistent --value=SecondValue + +num_records=`tdbdump $TDB | grep "FirstValue" | wc -l` +[ $num_records != 0 ] && { + echo "BAD: we still found the old record after the modify/update" + exit 1 +} + +num_records=`tdbdump $TDB | grep "SecondValue" | wc -l` +[ $num_records != 1 ] && { + echo "BAD: could not find the record after the modify/update" + exit 1 +} + + +echo wipe the persistent test databases and clean up +try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb wipedb persistent_test.tdb diff --git a/ctdb/tests/src/ctdb_update_record_persistent.c b/ctdb/tests/src/ctdb_update_record_persistent.c new file mode 100644 index 0000000000..c54c0e4466 --- /dev/null +++ b/ctdb/tests/src/ctdb_update_record_persistent.c @@ -0,0 +1,136 @@ +/* + simple ctdb test tool + This test just creates/updates a record in a persistent database + + Copyright (C) Ronnie Sahlberg 2012 + + 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 "includes.h" +#include "lib/tevent/tevent.h" +#include "lib/util/db_wrap.h" +#include "system/filesys.h" +#include "popt.h" +#include "cmdline.h" +#include "ctdb_private.h" + + +static void update_once(struct ctdb_context *ctdb, struct event_context *ev, struct ctdb_db_context *ctdb_db, char *record, char *value) +{ + TDB_DATA key, data, olddata; + struct ctdb_ltdb_header header; + + memset(&header, sizeof(header), 0); + + key.dptr = (uint8_t *)record; + key.dsize = strlen(record); + + data.dptr = (uint8_t *)value; + data.dsize = strlen(value); + + olddata = tdb_fetch(ctdb_db->ltdb->tdb, key); + if (olddata.dsize != 0) { + memcpy(&header, olddata.dptr, sizeof(header)); + header.rsn++; + } + + if (ctdb_ctrl_updaterecord(ctdb, ctdb, timeval_zero(), CTDB_CURRENT_NODE, ctdb_db, key, &header, data) != 0) { + printf("Failed to update record\n"); + exit(1); + } +} + +/* + main program +*/ +int main(int argc, const char *argv[]) +{ + struct ctdb_context *ctdb; + char *test_db = NULL; + char *record = NULL; + char *value = NULL; + struct ctdb_db_context *ctdb_db; + struct event_context *ev; + + struct poptOption popt_options[] = { + POPT_AUTOHELP + POPT_CTDB_CMDLINE + { "database", 'D', POPT_ARG_STRING, &test_db, 0, "database", "string" }, + { "record", 'R', POPT_ARG_STRING, &record, 0, "record", "string" }, + { "value", 'V', POPT_ARG_STRING, &value, 0, "value", "string" }, + POPT_TABLEEND + }; + int opt; + const char **extra_argv; + int extra_argc = 0; + poptContext pc; + + + pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + default: + fprintf(stderr, "Invalid option %s: %s\n", + poptBadOption(pc, 0), poptStrerror(opt)); + exit(1); + } + } + + /* setup the remaining options for the main program to use */ + extra_argv = poptGetArgs(pc); + if (extra_argv) { + extra_argv++; + while (extra_argv[extra_argc]) extra_argc++; + } + + ev = event_context_init(NULL); + + ctdb = ctdb_cmdline_client(ev, timeval_current_ofs(5, 0)); + + if (test_db == NULL) { + fprintf(stderr, "You must specify the database\n"); + exit(10); + } + + if (record == NULL) { + fprintf(stderr, "You must specify the record\n"); + exit(10); + } + + if (value == NULL) { + fprintf(stderr, "You must specify the value\n"); + exit(10); + } + + /* attach to a specific database */ + ctdb_db = ctdb_attach(ctdb, timeval_current_ofs(5, 0), test_db, true, 0); + if (!ctdb_db) { + printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb)); + exit(1); + } + + printf("Waiting for cluster\n"); + while (1) { + uint32_t recmode=1; + ctdb_ctrl_getrecmode(ctdb, ctdb, timeval_zero(), CTDB_CURRENT_NODE, &recmode); + if (recmode == 0) break; + event_loop_once(ev); + } + + update_once(ctdb, ev, ctdb_db, record, value); + + return 0; +} |
