diff options
Diffstat (limited to 'src/testing')
| -rw-r--r-- | src/testing/testing_api_cmd_batch.c | 84 | ||||
| -rw-r--r-- | src/testing/testing_api_loop.c | 175 | 
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 e8f76ca3..2e880e8d 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 f86c7765..868a2d75 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,  | 
