summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-06-05 17:01:23 +0200
committerChristian Grothoff <christian@grothoff.org>2023-06-05 17:01:23 +0200
commit015b08b0489d72f3fda587eec900bc4193a6a57e (patch)
tree97f5aab61589f805f088940013c333a6038e11d5 /src
parent96cbda85e3dd584904e9abeca13a9d6570dcfbfe (diff)
downloadexchange-015b08b0489d72f3fda587eec900bc4193a6a57e.tar.gz
exchange-015b08b0489d72f3fda587eec900bc4193a6a57e.tar.bz2
exchange-015b08b0489d72f3fda587eec900bc4193a6a57e.zip
new command to use taler-benchmark-setup.sh
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bank-lib/test_bank.sh1
-rwxr-xr-xsrc/benchmark/taler-benchmark-setup.sh35
-rw-r--r--src/include/taler_testing_lib.h15
-rw-r--r--src/testing/Makefile.am1
-rw-r--r--src/testing/testing_api_cmd_system_start.c387
5 files changed, 437 insertions, 2 deletions
diff --git a/src/bank-lib/test_bank.sh b/src/bank-lib/test_bank.sh
index ab76d2bad..7d72497ea 100755
--- a/src/bank-lib/test_bank.sh
+++ b/src/bank-lib/test_bank.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+# This file is in the public domain.
set -eu
diff --git a/src/benchmark/taler-benchmark-setup.sh b/src/benchmark/taler-benchmark-setup.sh
index 57f2e0cde..70a7654bf 100755
--- a/src/benchmark/taler-benchmark-setup.sh
+++ b/src/benchmark/taler-benchmark-setup.sh
@@ -57,16 +57,19 @@ START_AUDITOR=0
START_BACKUP=0
START_EXCHANGE=0
START_FAKEBANK=0
+START_AGGREGATOR=0
START_MERCHANT=0
START_NEXUS=0
START_SANDBOX=0
+START_TRANSFER=0
+START_WIREWATCH=0
USE_VALGRIND=""
CONF_ORIG="~/.config/taler.conf"
LOGLEVEL="DEBUG"
DEFAULT_SLEEP="0.2"
# Parse command-line options
-while getopts ':abc:efhl:mnsv' OPTION; do
+while getopts ':abc:efghl:mnstvw' OPTION; do
case "$OPTION" in
a)
START_AUDITOR="1"
@@ -95,9 +98,14 @@ while getopts ':abc:efhl:mnsv' OPTION; do
echo ' -m -- start merchant'
echo ' -n -- start nexus'
echo ' -s -- start sandbox'
+ echo ' -t -- start transfer'
echo ' -v -- use valgrind'
+ echo ' -w -- start wirewatch'
exit 0
;;
+ g)
+ START_AGGREGATOR="1"
+ ;;
l)
LOGLEVEL="$OPTARG"
;;
@@ -110,10 +118,16 @@ while getopts ':abc:efhl:mnsv' OPTION; do
s)
START_SANDBOX="1"
;;
+ t)
+ START_TRANSFER="1"
+ ;;
v)
USE_VALGRIND="valgrind --leak-check=yes"
DEFAULT_SLEEP="2"
;;
+ w)
+ START_WIREWATCH="1"
+ ;;
?)
exit_fail "Unrecognized command line option"
;;
@@ -364,7 +378,6 @@ fi
if [ "1" = "$START_EXCHANGE" ]
then
echo -n "Starting exchange ..."
-
EXCHANGE_PORT=$(taler-config -c "$CONF" -s EXCHANGE -o PORT)
EXCHANGE_URL="http://localhost:${EXCHANGE_PORT}/"
MASTER_PRIV_FILE=$(taler-config -f -c "${CONF}" -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE")
@@ -384,10 +397,28 @@ then
$USE_VALGRIND taler-exchange-secmod-cs -c "$CONF" -L "$LOGLEVEL" 2> taler-exchange-secmod-cs.log &
$USE_VALGRIND taler-exchange-httpd -c "$CONF" -L "$LOGLEVEL" 2> taler-exchange-httpd.log &
EXCHANGE_HTTPD_PID=$!
+ echo " DONE"
+fi
+
+if [ "1" = "$START_WIREWATCH" ]
+then
+ echo -n "Starting wirewatch ..."
$USE_VALGRIND taler-exchange-wirewatch -c "$CONF" 2> taler-exchange-wirewatch.log &
WIREWATCH_PID=$!
+ echo " DONE"
+fi
+
+if [ "1" = "$START_AGGREGATOR" ]
+then
+ echo -n "Starting aggregator ..."
$USE_VALGRIND taler-exchange-aggregator -c "$CONF" 2> taler-exchange-aggregator.log &
AGGREGATOR_PID=$!
+ echo " DONE"
+fi
+
+if [ "1" = "$START_TRANSFER" ]
+then
+ echo -n "Starting transfer ..."
$USE_VALGRIND taler-exchange-transfer -c "$CONF" 2> taler-exchange-transfer.log &
TRANSFER_PID=$!
echo " DONE"
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 664db6ccd..23a4c2526 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -987,6 +987,21 @@ TALER_TESTING_history_entry_cmp (
/**
+ * Launch GNU Taler setup.
+ *
+ * @param label command label.
+ * @param config_file configuration file to use
+ * @param ... NULL-terminated (const char *) arguments to pass to taler-benchmark-setup.sh
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_system_start (
+ const char *label,
+ const char *config_file,
+ ...);
+
+
+/**
* Command to modify authorization header used in the CURL context.
* This will destroy the existing CURL context and create a fresh
* one. The command will fail (badly) if the existing CURL context
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 86cb029c7..8aa3ac1b9 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -107,6 +107,7 @@ libtalertesting_la_SOURCES = \
testing_api_cmd_signal.c \
testing_api_cmd_sleep.c \
testing_api_cmd_stat.c \
+ testing_api_cmd_system_start.c \
testing_api_cmd_take_aml_decision.c \
testing_api_cmd_transfer_get.c \
testing_api_cmd_wait.c \
diff --git a/src/testing/testing_api_cmd_system_start.c b/src/testing/testing_api_cmd_system_start.c
new file mode 100644
index 000000000..491f03c56
--- /dev/null
+++ b/src/testing/testing_api_cmd_system_start.c
@@ -0,0 +1,387 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2023 Taler Systems SA
+
+ TALER 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, or (at your
+ option) any later version.
+
+ TALER 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 TALER; see the file COPYING. If not,
+ see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file testing/testing_api_cmd_system_start.c
+ * @brief run taler-benchmark-setup.sh command
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_curl_lib.h>
+#include "taler_signatures.h"
+#include "taler_testing_lib.h"
+
+
+/**
+ * State for a "system" CMD.
+ */
+struct SystemState
+{
+
+ /**
+ * System process.
+ */
+ struct GNUNET_OS_Process *system_proc;
+
+ /**
+ * Input pipe to @e system_proc, used to keep the
+ * process alive until we are done.
+ */
+ struct GNUNET_DISK_PipeHandle *pipe_in;
+
+ /**
+ * Output pipe to @e system_proc, used to find out
+ * when the services are ready.
+ */
+ struct GNUNET_DISK_PipeHandle *pipe_out;
+
+ /**
+ * Task reading from @e pipe_in.
+ */
+ struct GNUNET_SCHEDULER_Task *reader;
+
+ /**
+ * Waiting for child to die.
+ */
+ struct GNUNET_ChildWaitHandle *cwh;
+
+ /**
+ * Our interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * NULL-terminated array of command-line arguments.
+ */
+ char **args;
+
+ /**
+ * Current input buffer, 0-terminated. Contains the last 15 bytes of input
+ * so we can search them again for the "<<READY>>" tag.
+ */
+ char ibuf[16];
+
+ /**
+ * Did we find the ready tag?
+ */
+ bool ready;
+
+ /**
+ * Is the child process still running?
+ */
+ bool active;
+};
+
+
+/**
+ * Defines a GNUNET_ChildCompletedCallback which is sent back
+ * upon death or completion of a child process.
+ *
+ * @param cls our `struct SystemState *`
+ * @param type type of the process
+ * @param exit_code status code of the process
+ */
+static void
+setup_terminated (void *cls,
+ enum GNUNET_OS_ProcessStatusType type,
+ long unsigned int exit_code)
+{
+ struct SystemState *as = cls;
+
+ as->cwh = NULL;
+ as->active = false;
+ if (NULL != as->reader)
+ {
+ GNUNET_SCHEDULER_cancel (as->reader);
+ as->reader = NULL;
+ }
+ if (! as->ready)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Launching Taler system failed: %d/%llu\n",
+ (int) type,
+ (unsigned long long) exit_code);
+ TALER_TESTING_interpreter_fail (as->is);
+ return;
+ }
+}
+
+
+/**
+ * Start helper to read from stdout of child.
+ *
+ * @param as our system state
+ */
+static void
+start_reader (struct SystemState *as);
+
+
+static void
+read_stdout (void *cls)
+{
+ struct SystemState *as = cls;
+ const struct GNUNET_DISK_FileHandle *fh;
+ char buf[1024 * 10];
+ ssize_t ret;
+ size_t off = 0;
+
+ as->reader = NULL;
+ strcpy (buf,
+ as->ibuf);
+ off = strlen (buf);
+ fh = GNUNET_DISK_pipe_handle (as->pipe_out,
+ GNUNET_DISK_PIPE_END_READ);
+ ret = GNUNET_DISK_file_read (fh,
+ &buf[off],
+ sizeof (buf) - off);
+ if (-1 == ret)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "read");
+ TALER_TESTING_interpreter_fail (as->is);
+ return;
+ }
+ if (0 == ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Child closed stdout\n");
+ return;
+ }
+ start_reader (as);
+ off += ret;
+ if (as->ready)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Taler system UP\n");
+ TALER_TESTING_interpreter_next (as->is);
+ return; /* done */
+ }
+ if (NULL !=
+ memmem (buf,
+ off,
+ "\n<<READY>>\n",
+ strlen ("\n<<READY>>\n")))
+ {
+ as->ready = true;
+ return;
+ }
+
+ {
+ size_t mcpy;
+
+ mcpy = GNUNET_MIN (off,
+ sizeof (as->ibuf) - 1);
+ memcpy (as->ibuf,
+ &buf[off - mcpy],
+ mcpy);
+ as->ibuf[mcpy] = '\0';
+ }
+}
+
+
+static void
+start_reader (struct SystemState *as)
+{
+ const struct GNUNET_DISK_FileHandle *fh;
+
+ GNUNET_assert (NULL == as->reader);
+ fh = GNUNET_DISK_pipe_handle (as->pipe_out,
+ GNUNET_DISK_PIPE_END_READ);
+ as->reader = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ fh,
+ &read_stdout,
+ as);
+}
+
+
+/**
+ * Run the command. Use the `taler-exchange-system' program.
+ *
+ * @param cls closure.
+ * @param cmd command being run.
+ * @param is interpreter state.
+ */
+static void
+system_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct SystemState *as = cls;
+
+ (void) cmd;
+ as->is = is;
+ as->pipe_in = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE);
+ GNUNET_assert (NULL != as->pipe_in);
+ as->pipe_out = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE);
+ GNUNET_assert (NULL != as->pipe_out);
+ as->system_proc
+ = GNUNET_OS_start_process_vap (
+ GNUNET_OS_INHERIT_STD_ERR,
+ as->pipe_in, as->pipe_out, NULL,
+ "taler-benchmark-setup.sh",
+ as->args);
+ if (NULL == as->system_proc)
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
+ as->active = true;
+ start_reader (as);
+ as->cwh = GNUNET_wait_child (as->system_proc,
+ &setup_terminated,
+ as);
+}
+
+
+/**
+ * Free the state of a "system" CMD, and possibly kill its
+ * process if it did not terminate correctly.
+ *
+ * @param cls closure.
+ * @param cmd the command being freed.
+ */
+static void
+system_cleanup (void *cls,
+ const struct TALER_TESTING_Command *cmd)
+{
+ struct SystemState *as = cls;
+
+ (void) cmd;
+ if (NULL != as->cwh)
+ {
+ GNUNET_wait_child_cancel (as->cwh);
+ as->cwh = NULL;
+ }
+ if (NULL != as->reader)
+ {
+ GNUNET_SCHEDULER_cancel (as->reader);
+ as->reader = NULL;
+ }
+ if (NULL != as->pipe_in)
+ {
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_DISK_pipe_close (as->pipe_in));
+ as->pipe_in = NULL;
+ }
+ if (NULL != as->pipe_out)
+ {
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_DISK_pipe_close (as->pipe_out));
+ as->pipe_out = NULL;
+ }
+ if (NULL != as->system_proc)
+ {
+ if (as->active)
+ {
+ GNUNET_break (0 ==
+ GNUNET_OS_process_kill (as->system_proc,
+ SIGTERM));
+ GNUNET_OS_process_wait (as->system_proc);
+ }
+ GNUNET_OS_process_destroy (as->system_proc);
+ as->system_proc = NULL;
+ }
+
+ for (unsigned int i = 0; NULL != as->args[i]; i++)
+ GNUNET_free (as->args[i]);
+ GNUNET_free (as->args);
+ GNUNET_free (as);
+}
+
+
+/**
+ * Offer "system" CMD internal data to other commands.
+ *
+ * @param cls closure.
+ * @param[out] ret result.
+ * @param trait name of the trait.
+ * @param index index number of the object to offer.
+ * @return #GNUNET_OK on success
+ */
+static enum GNUNET_GenericReturnValue
+system_traits (void *cls,
+ const void **ret,
+ const char *trait,
+ unsigned int index)
+{
+ struct SystemState *as = cls;
+ struct TALER_TESTING_Trait traits[] = {
+ TALER_TESTING_make_trait_process (&as->system_proc),
+ TALER_TESTING_trait_end ()
+ };
+
+ return TALER_TESTING_get_trait (traits,
+ ret,
+ trait,
+ index);
+}
+
+
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_system_start (
+ const char *label,
+ const char *config_file,
+ ...)
+{
+ struct SystemState *as;
+ va_list ap;
+ const char *arg;
+ unsigned int cnt;
+
+ as = GNUNET_new (struct SystemState);
+ cnt = 4; /* 0-2 reserved, +1 for NULL termination */
+ va_start (ap,
+ config_file);
+ while (NULL != (arg = va_arg (ap,
+ const char *)))
+ {
+ cnt++;
+ }
+ va_end (ap);
+ as->args = GNUNET_new_array (cnt,
+ char *);
+ as->args[0] = GNUNET_strdup ("taler-benchmark-setup");
+ as->args[1] = GNUNET_strdup ("-c");
+ as->args[2] = GNUNET_strdup (config_file);
+ cnt = 3;
+ va_start (ap,
+ config_file);
+ while (NULL != (arg = va_arg (ap,
+ const char *)))
+ {
+ as->args[cnt++] = GNUNET_strdup (arg);
+ }
+ va_end (ap);
+
+ {
+ struct TALER_TESTING_Command cmd = {
+ .cls = as,
+ .label = label,
+ .run = &system_run,
+ .cleanup = &system_cleanup,
+ .traits = &system_traits
+ };
+
+ return cmd;
+ }
+}
+
+
+/* end of testing_api_cmd_system_start.c */