diff --git a/ctdb/tests/src/test_options.c b/ctdb/tests/src/test_options.c
new file mode 100644
index 00000000000..f330764a1b9
--- /dev/null
+++ b/ctdb/tests/src/test_options.c
@@ -0,0 +1,183 @@
+/*
+ CTDB tests commandline options
+
+ Copyright (C) Amitay Isaacs 2015
+
+ 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 .
+*/
+
+#include "replace.h"
+
+#include
+#include
+
+#include "lib/util/debug.h"
+
+#include "common/logging.h"
+
+#include "tests/src/test_options.h"
+
+static struct test_options _values;
+
+static struct poptOption options_basic[] = {
+ { "socket", 's', POPT_ARG_STRING, &_values.socket, 0,
+ "CTDB socket path", "filename" },
+ { "timelimit", 't', POPT_ARG_INT, &_values.timelimit, 0,
+ "Time limit (in seconds)" },
+ { "num-nodes", 'n', POPT_ARG_INT, &_values.num_nodes, 0,
+ "Number of cluster nodes" },
+ { "debug", 'd', POPT_ARG_STRING, &_values.debugstr, 0,
+ "Debug level" },
+ { NULL }
+};
+
+#define TEST_OPTIONS_BASIC \
+ { NULL, 0, POPT_ARG_INCLUDE_TABLE, options_basic, 0, \
+ "General options:", NULL },
+
+static struct poptOption options_database[] = {
+ { "database", 'D', POPT_ARG_STRING, &_values.dbname, 0,
+ "CTDB database name" },
+ { "key", 'k', POPT_ARG_STRING, &_values.keystr, 0,
+ "Name of database key" },
+ { "value", 'v', POPT_ARG_STRING, &_values.valuestr, 0,
+ "Value of database key" },
+ { NULL }
+};
+
+#define TEST_OPTIONS_DATABASE \
+ { NULL, 0, POPT_ARG_INCLUDE_TABLE, options_database, 0, \
+ "Database options:", NULL },
+
+static void set_defaults_basic(struct test_options *opts)
+{
+ const char *ctdb_socket;
+
+ /* Set default options */
+ opts->socket = CTDB_SOCKET;
+ opts->timelimit = 10;
+ opts->num_nodes = 1;
+ opts->debugstr = "ERR";
+
+ ctdb_socket = getenv("CTDB_SOCKET");
+ if (ctdb_socket != NULL) {
+ opts->socket = ctdb_socket;
+ }
+}
+
+static void set_defaults_database(struct test_options *opts)
+{
+ opts->dbname = NULL;
+ opts->keystr = NULL;
+ opts->valuestr = NULL;
+}
+
+static bool verify_options_basic(struct test_options *opts)
+{
+ enum debug_level log_level;
+ bool status;
+
+ status = debug_level_parse(opts->debugstr, &log_level);
+ if (! status) {
+ fprintf(stderr, "Error: Invalid debug string '%s'\n",
+ opts->debugstr);
+ return false;
+ }
+
+ DEBUGLEVEL = debug_level_to_int(log_level);
+
+ return true;
+}
+
+static bool verify_options_database(struct test_options *opts)
+{
+ if (opts->dbname == NULL) {
+ fprintf(stderr, "Error: Please specify database\n");
+ return false;
+ }
+ if (opts->keystr == NULL) {
+ fprintf(stderr, "Error: Please specify key name\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool process_options_common(int argc, const char **argv,
+ struct poptOption *options)
+{
+ poptContext pc;
+ int opt;
+
+ pc = poptGetContext(argv[0], argc, argv, options,
+ POPT_CONTEXT_KEEP_FIRST);
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ fprintf(stderr, "Invalid option %s: %s\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ return false;
+ }
+
+ return true;
+}
+
+bool process_options_basic(int argc, const char **argv,
+ const struct test_options **opts)
+{
+ struct poptOption options[] = {
+ POPT_AUTOHELP
+ TEST_OPTIONS_BASIC
+ POPT_TABLEEND
+ };
+
+ set_defaults_basic(&_values);
+
+ if (! process_options_common(argc, argv, options)) {
+ return false;
+ }
+
+ if (! verify_options_basic(&_values)) {
+ return false;
+ }
+
+ *opts = &_values;
+ return true;
+}
+
+bool process_options_database(int argc, const char **argv,
+ const struct test_options **opts)
+{
+ struct poptOption options[] = {
+ POPT_AUTOHELP
+ TEST_OPTIONS_BASIC
+ TEST_OPTIONS_DATABASE
+ POPT_TABLEEND
+ };
+
+ set_defaults_basic(&_values);
+ set_defaults_database(&_values);
+
+ if (! process_options_common(argc, argv, options)) {
+ return false;
+ }
+
+ if (! verify_options_basic(&_values)) {
+ return false;
+ }
+ if (! verify_options_database(&_values)) {
+ return false;
+ }
+
+ *opts = &_values;
+ return true;
+}
diff --git a/ctdb/tests/src/test_options.h b/ctdb/tests/src/test_options.h
new file mode 100644
index 00000000000..d299f4b55fe
--- /dev/null
+++ b/ctdb/tests/src/test_options.h
@@ -0,0 +1,42 @@
+/*
+ CTDB tests commandline options
+
+ Copyright (C) Amitay Isaacs 2015
+
+ 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 .
+*/
+
+#ifndef __TEST_OPTIONS_H__
+#define __TEST_OPTIONS_H__
+
+struct test_options {
+ /* Basic options */
+ const char *socket;
+ int timelimit;
+ int num_nodes;
+ const char *debugstr;
+
+ /* Database options */
+ const char *dbname;
+ const char *keystr;
+ const char *valuestr;
+};
+
+bool process_options_basic(int argc, const char **argv,
+ const struct test_options **opts);
+
+bool process_options_database(int argc, const char **argv,
+ const struct test_options **opts);
+
+#endif /* __TEST_OPTIONS_H__ */
diff --git a/ctdb/wscript b/ctdb/wscript
index bdce3623194..2f52f3ace9f 100755
--- a/ctdb/wscript
+++ b/ctdb/wscript
@@ -705,7 +705,7 @@ def build(bld):
bld.SAMBA_SUBSYSTEM('ctdb-tests-common',
source=bld.SUBDIR('tests/src',
- 'cluster_wait.c'),
+ 'cluster_wait.c test_options.c'),
includes='include',
deps='replace popt talloc tevent tdb')