aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/testing_api_cmd_batch.c84
-rw-r--r--src/testing/testing_api_loop.c175
2 files changed, 219 insertions, 40 deletions
diff --git a/src/testing/testing_api_cmd_batch.c b/src/testing/testing_api_cmd_batch.c
index e8f76ca37..2e880e8df 100644
--- a/src/testing/testing_api_cmd_batch.c
+++ b/src/testing/testing_api_cmd_batch.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2021 Taler Systems SA
+ Copyright (C) 2014-2018 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
@@ -113,15 +113,22 @@ batch_cleanup (void *cls,
* @param index index number of the object to offer.
* @return #GNUNET_OK on success.
*/
-static enum GNUNET_GenericReturnValue
+static int
batch_traits (void *cls,
const void **ret,
const char *trait,
unsigned int index)
{
+#define CURRENT_CMD_INDEX 0
+#define BATCH_INDEX 1
+
struct BatchState *bs = cls;
+
struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_batch_cmds (&bs->batch),
+ TALER_TESTING_make_trait_cmd
+ (CURRENT_CMD_INDEX, &bs->batch[bs->batch_ip]),
+ TALER_TESTING_make_trait_cmd
+ (BATCH_INDEX, bs->batch),
TALER_TESTING_trait_end ()
};
@@ -133,6 +140,18 @@ batch_traits (void *cls,
}
+/**
+ * Create a "batch" command. Such command takes a
+ * end_CMD-terminated array of CMDs and executed them.
+ * Once it hits the end CMD, it passes the control
+ * to the next top-level CMD, regardless of it being
+ * another batch or ordinary CMD.
+ *
+ * @param label the command label.
+ * @param batch array of CMDs to execute.
+ *
+ * @return the command.
+ */
struct TALER_TESTING_Command
TALER_TESTING_cmd_batch (const char *label,
struct TALER_TESTING_Command *batch)
@@ -166,29 +185,68 @@ TALER_TESTING_cmd_batch (const char *label,
}
+/**
+ * Advance internal pointer to next command.
+ *
+ * @param is interpreter state.
+ * @param cmd batch to advance
+ */
void
-TALER_TESTING_cmd_batch_next (struct TALER_TESTING_Interpreter *is)
+TALER_TESTING_cmd_batch_next (struct TALER_TESTING_Interpreter *is,
+ struct TALER_TESTING_Command *par,
+ struct TALER_TESTING_Command *cmd)
{
- struct BatchState *bs = is->commands[is->ip].cls;
+ struct BatchState *bs = cmd->cls;
+ struct TALER_TESTING_Command *chld;
if (NULL == bs->batch[bs->batch_ip].label)
{
- is->commands[is->ip].finish_time = GNUNET_TIME_absolute_get ();
- is->ip++;
+ if (NULL == par)
+ {
+ is->commands[is->ip].finish_time = GNUNET_TIME_absolute_get ();
+ is->ip++;
+ }
+ else
+ {
+ struct BatchState *ps = par->cls;
+
+ cmd->finish_time = GNUNET_TIME_absolute_get ();
+ ps->batch_ip++;
+ }
return;
}
- bs->batch[bs->batch_ip].finish_time = GNUNET_TIME_absolute_get ();
- bs->batch_ip++;
+ chld = &bs->batch[bs->batch_ip];
+ if (TALER_TESTING_cmd_is_batch (chld))
+ {
+ TALER_TESTING_cmd_batch_next (is,
+ cmd,
+ chld);
+ }
+ else
+ {
+ bs->batch[bs->batch_ip].finish_time = GNUNET_TIME_absolute_get ();
+ bs->batch_ip++;
+ }
}
-bool
+/**
+ * Test if this command is a batch command.
+ *
+ * @return false if not, true if it is a batch command
+ */
+int
TALER_TESTING_cmd_is_batch (const struct TALER_TESTING_Command *cmd)
{
return cmd->run == &batch_run;
}
+/**
+ * Obtain what command the batch is at.
+ *
+ * @return cmd current batch command
+ */
struct TALER_TESTING_Command *
TALER_TESTING_cmd_batch_get_current (const struct TALER_TESTING_Command *cmd)
{
@@ -199,6 +257,12 @@ TALER_TESTING_cmd_batch_get_current (const struct TALER_TESTING_Command *cmd)
}
+/**
+ * Set what command the batch should be at.
+ *
+ * @param cmd current batch command
+ * @param new_ip where to move the IP
+ */
void
TALER_TESTING_cmd_batch_set_current (const struct TALER_TESTING_Command *cmd,
unsigned int new_ip)
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index f86c7765b..868a2d750 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -36,6 +36,49 @@
*/
static struct GNUNET_DISK_PipeHandle *sigpipe;
+
+const struct TALER_TESTING_Command *
+lookup_helper (const struct TALER_TESTING_Command *cmd,
+ const char *label)
+{
+#define BATCH_INDEX 1
+ struct TALER_TESTING_Command *batch;
+ struct TALER_TESTING_Command *current;
+ struct TALER_TESTING_Command *icmd;
+ const struct TALER_TESTING_Command *match;
+
+ current = TALER_TESTING_cmd_batch_get_current (cmd);
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_cmd (cmd,
+ BATCH_INDEX,
+ &batch));
+ /* We must do the loop forward, but we can find the last match */
+ match = NULL;
+ for (unsigned int j = 0;
+ NULL != (icmd = &batch[j])->label;
+ j++)
+ {
+ if (TALER_TESTING_cmd_is_batch (icmd))
+ {
+ const struct TALER_TESTING_Command *imatch;
+
+ imatch = lookup_helper (icmd,
+ label);
+ if (NULL != imatch)
+ match = imatch;
+ }
+ if ( (current != icmd) &&
+ (NULL != icmd->label) &&
+ (0 == strcmp (icmd->label,
+ label)) )
+ match = icmd;
+ if (current == icmd)
+ break;
+ }
+ return match;
+}
+
+
/**
* Lookup command by label.
*
@@ -66,30 +109,12 @@ TALER_TESTING_interpreter_lookup_command (struct TALER_TESTING_Interpreter *is,
if (TALER_TESTING_cmd_is_batch (cmd))
{
- struct TALER_TESTING_Command **batch;
- struct TALER_TESTING_Command *current;
- struct TALER_TESTING_Command *icmd;
- const struct TALER_TESTING_Command *match;
-
- current = TALER_TESTING_cmd_batch_get_current (cmd);
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_batch_cmds (cmd,
- &batch));
- /* We must do the loop forward, but we can find the last match */
- match = NULL;
- for (unsigned int j = 0;
- NULL != (icmd = &(*batch)[j])->label;
- j++)
- {
- if (current == icmd)
- break; /* do not go past current command */
- if ( (NULL != icmd->label) &&
- (0 == strcmp (icmd->label,
- label)) )
- match = icmd;
- }
- if (NULL != match)
- return match;
+ const struct TALER_TESTING_Command *ret;
+
+ ret = lookup_helper (cmd,
+ label);
+ if (NULL != ret)
+ return ret;
}
}
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -118,6 +143,15 @@ TALER_TESTING_interpreter_get_fakebank (struct TALER_TESTING_Interpreter *is)
}
+/**
+ * Run tests starting the "fakebank" first. The "fakebank"
+ * is a C minimalist version of the human-oriented Python bank,
+ * which is also part of the Taler project.
+ *
+ * @param is pointer to the interpreter state
+ * @param commands the list of commands to execute
+ * @param bank_url the url the fakebank is supposed to run on
+ */
void
TALER_TESTING_run_with_fakebank (struct TALER_TESTING_Interpreter *is,
struct TALER_TESTING_Command *commands,
@@ -155,6 +189,9 @@ static void
interpreter_run (void *cls);
+/**
+ * Current command is done, run the next one.
+ */
void
TALER_TESTING_interpreter_next (struct TALER_TESTING_Interpreter *is)
{
@@ -166,7 +203,9 @@ TALER_TESTING_interpreter_next (struct TALER_TESTING_Interpreter *is)
return; /* ignore, we already failed! */
if (TALER_TESTING_cmd_is_batch (cmd))
{
- TALER_TESTING_cmd_batch_next (is);
+ TALER_TESTING_cmd_batch_next (is,
+ NULL,
+ cmd);
}
else
{
@@ -189,6 +228,11 @@ TALER_TESTING_interpreter_next (struct TALER_TESTING_Interpreter *is)
}
+/**
+ * Current command failed, clean up and fail the test case.
+ *
+ * @param is interpreter of the test
+ */
void
TALER_TESTING_interpreter_fail (struct TALER_TESTING_Interpreter *is)
{
@@ -209,6 +253,11 @@ TALER_TESTING_interpreter_fail (struct TALER_TESTING_Interpreter *is)
}
+/**
+ * Create command array terminator.
+ *
+ * @return a end-command.
+ */
struct TALER_TESTING_Command
TALER_TESTING_cmd_end (void)
{
@@ -219,6 +268,9 @@ TALER_TESTING_cmd_end (void)
}
+/**
+ * Obtain current label.
+ */
const char *
TALER_TESTING_interpreter_get_current_label (struct
TALER_TESTING_Interpreter *is)
@@ -289,9 +341,8 @@ do_shutdown (void *cls)
for (unsigned int j = 0;
NULL != (cmd = &is->commands[j])->label;
j++)
- if (NULL != cmd->cleanup)
- cmd->cleanup (cmd->cls,
- cmd);
+ cmd->cleanup (cmd->cls,
+ cmd);
if (NULL != is->exchange)
{
@@ -367,8 +418,17 @@ maint_child_death (void *cls)
enum GNUNET_OS_ProcessStatusType type;
unsigned long code;
- while (TALER_TESTING_cmd_is_batch (cmd))
- cmd = TALER_TESTING_cmd_batch_get_current (cmd);
+ if (TALER_TESTING_cmd_is_batch (cmd))
+ {
+ struct TALER_TESTING_Command *batch_cmd;
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_cmd (cmd,
+ 0,
+ &batch_cmd));
+ cmd = batch_cmd;
+ }
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Got SIGCHLD for `%s'.\n",
cmd->label);
@@ -381,6 +441,7 @@ maint_child_death (void *cls)
sizeof (c)));
if (GNUNET_OK !=
TALER_TESTING_get_trait_process (cmd,
+ 0,
&processp))
{
GNUNET_break (0);
@@ -433,6 +494,12 @@ maint_child_death (void *cls)
}
+/**
+ * Wait until we receive SIGCHLD signal.
+ * Then obtain the process trait of the current
+ * command, wait on the the zombie and continue
+ * with the next command.
+ */
void
TALER_TESTING_wait_for_sigchld (struct TALER_TESTING_Interpreter *is)
{
@@ -449,6 +516,16 @@ TALER_TESTING_wait_for_sigchld (struct TALER_TESTING_Interpreter *is)
}
+/**
+ * Run the testsuite. Note, CMDs are copied into
+ * the interpreter state because they are _usually_
+ * defined into the "run" method that returns after
+ * having scheduled the test interpreter.
+ *
+ * @param is the interpreter state
+ * @param commands the list of command to execute
+ * @param timeout how long to wait
+ */
void
TALER_TESTING_run2 (struct TALER_TESTING_Interpreter *is,
struct TALER_TESTING_Command *commands,
@@ -478,6 +555,15 @@ TALER_TESTING_run2 (struct TALER_TESTING_Interpreter *is,
}
+/**
+ * Run the testsuite. Note, CMDs are copied into
+ * the interpreter state because they are _usually_
+ * defined into the "run" method that returns after
+ * having scheduled the test interpreter.
+ *
+ * @param is the interpreter state
+ * @param commands the list of command to execute
+ */
void
TALER_TESTING_run (struct TALER_TESTING_Interpreter *is,
struct TALER_TESTING_Command *commands)
@@ -536,6 +622,16 @@ sighandler_child_death (void)
}
+/**
+ * "Canonical" cert_cb used when we are connecting to the
+ * Exchange.
+ *
+ * @param cls closure, typically, the "run" method containing
+ * all the commands to be run, and a closure for it.
+ * @param hr HTTP response details
+ * @param keys the exchange's keys.
+ * @param compat protocol compatibility information.
+ */
void
TALER_TESTING_cert_cb (void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
@@ -804,6 +900,25 @@ load_urls (struct TALER_TESTING_Interpreter *is)
}
+/**
+ * Install signal handlers plus schedules the main wrapper
+ * around the "run" method.
+ *
+ * @param main_cb the "run" method which contains all the
+ * commands.
+ * @param main_cb_cls a closure for "run", typically NULL.
+ * @param cfg configuration to use
+ * @param exchanged exchange process handle: will be put in the
+ * state as some commands - e.g. revoke - need to send
+ * signal to it, for example to let it know to reload the
+ * key state.. if NULL, the interpreter will run without
+ * trying to connect to the exchange first.
+ * @param exchange_connect #GNUNET_YES if the test should connect
+ * to the exchange, #GNUNET_NO otherwise
+ * @return #GNUNET_OK if all is okay, != #GNUNET_OK otherwise.
+ * non-GNUNET_OK codes are #GNUNET_SYSERR most of the
+ * times.
+ */
int
TALER_TESTING_setup (TALER_TESTING_Main main_cb,
void *main_cb_cls,