diff options
| author | Christian Grothoff <christian@grothoff.org> | 2018-11-17 18:14:11 +0100 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2018-11-17 18:14:11 +0100 | 
| commit | 5f365133cd31a6c3ea13d40ba34fb11a7a530c4e (patch) | |
| tree | 0759cb23adc47996909baf0e04f6879f205f4f9a /src | |
| parent | e42f014cffae126a52c92fbf8151e6f5cecc9de0 (diff) | |
add list exchanges command
Diffstat (limited to 'src')
| -rw-r--r-- | src/auditor-lib/Makefile.am | 1 | ||||
| -rw-r--r-- | src/auditor-lib/testing_auditor_api_cmd_exchanges.c | 296 | ||||
| -rw-r--r-- | src/include/taler_testing_auditor_lib.h | 26 | 
3 files changed, 323 insertions, 0 deletions
| diff --git a/src/auditor-lib/Makefile.am b/src/auditor-lib/Makefile.am index 44849da2..df0b8b3d 100644 --- a/src/auditor-lib/Makefile.am +++ b/src/auditor-lib/Makefile.am @@ -42,6 +42,7 @@ libtalerauditortesting_la_LDFLAGS = \  libtalerauditortesting_la_SOURCES = \    testing_auditor_api_helpers.c \    testing_auditor_api_cmd_deposit_confirmation.c \ +  testing_auditor_api_cmd_exchanges.c \    testing_auditor_api_cmd_exec_auditor.c \    testing_auditor_api_cmd_exec_wire_auditor.c  libtalerauditortesting_la_LIBADD = \ diff --git a/src/auditor-lib/testing_auditor_api_cmd_exchanges.c b/src/auditor-lib/testing_auditor_api_cmd_exchanges.c new file mode 100644 index 00000000..71b82a39 --- /dev/null +++ b/src/auditor-lib/testing_auditor_api_cmd_exchanges.c @@ -0,0 +1,296 @@ +/* +  This file is part of TALER +  Copyright (C) 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 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 auditor-lib/testing_auditor_api_cmd_exchanges.c + * @brief command for testing /exchanges. + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_json_lib.h" +#include <gnunet/gnunet_curl_lib.h> +#include "taler_auditor_service.h" +#include "taler_testing_lib.h" +#include "taler_signatures.h" +#include "backoff.h" + + +/** + * State for a "deposit confirmation" CMD. + */ +struct ExchangesState +{ + +  /** +   * Exchanges handle while operation is running. +   */ +  struct TALER_AUDITOR_ListExchangesHandle *leh; + +  /** +   * Auditor connection. +   */ +  struct TALER_AUDITOR_Handle *auditor; +   +  /** +   * Interpreter state. +   */ +  struct TALER_TESTING_Interpreter *is; + +  /** +   * Task scheduled to try later. +   */ +  struct GNUNET_SCHEDULER_Task *retry_task; + +  /** +   * How long do we wait until we retry? +   */ +  struct GNUNET_TIME_Relative backoff; + +  /** +   * Expected HTTP response code. +   */ +  unsigned int expected_response_code; + +  /** +   * Should we retry on (transient) failures? +   */ +  int do_retry; + +}; + + +/** + * Run the command. + * + * @param cls closure. + * @param cmd the command to execute. + * @param is the interpreter state. + */ +static void +exchanges_run (void *cls, +	       const struct TALER_TESTING_Command *cmd, +	       struct TALER_TESTING_Interpreter *is); + + +/** + * Task scheduled to re-try #exchanges_run. + * + * @param cls a `struct ExchangesState` + */ +static void +do_retry (void *cls) +{ +  struct ExchangesState *es = cls; + +  es->retry_task = NULL; +  exchanges_run (es, +		 NULL, +		 es->is); +} + + +/** + * Callback to analyze the /exchanges response. + * + * @param cls closure. + * @param http_status HTTP response code. + * @param ec taler-specific error code. + * @param obj raw response from the auditor. + */ +static void +exchanges_cb (void *cls, +	      unsigned int http_status, +	      enum TALER_ErrorCode ec, +	      unsigned int num_exchanges, +	      const struct TALER_AUDITOR_ExchangeInfo *ei, +	      const json_t *raw_response) +{ +  struct ExchangesState *es = cls; + +  es->leh = NULL; +  if (es->expected_response_code != http_status) +  { +    if (GNUNET_YES == es->do_retry) +    { +      if ( (0 == http_status) || +           (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) || +	   (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) ) +      { +        GNUNET_log (GNUNET_ERROR_TYPE_INFO, +                    "Retrying list exchanges failed with %u/%d\n", +                    http_status, +                    (int) ec); +	/* on DB conflicts, do not use backoff */ +	if (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) +	  es->backoff = GNUNET_TIME_UNIT_ZERO; +	else +	  es->backoff = AUDITOR_LIB_BACKOFF (es->backoff); +	es->retry_task = GNUNET_SCHEDULER_add_delayed (es->backoff, +							&do_retry, +							es); +        return; +      } +    } +    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                "Unexpected response code %u to command %s in %s:%u\n", +                http_status, +                es->is->commands[es->is->ip].label, +                __FILE__, +                __LINE__); +    json_dumpf (raw_response, stderr, 0); +    TALER_TESTING_interpreter_fail (es->is); +    return; +  } +  TALER_TESTING_interpreter_next (es->is); +} + + +/** + * Run the command. + * + * @param cls closure. + * @param cmd the command to execute. + * @param is the interpreter state. + */ +static void +exchanges_run (void *cls, +	       const struct TALER_TESTING_Command *cmd, +	       struct TALER_TESTING_Interpreter *is) +{ +  struct ExchangesState *es = cls; +   +  es->is = is; +  es->leh = TALER_AUDITOR_list_exchanges +    (es->auditor, +     &exchanges_cb, +     es); + +  if (NULL == es->leh) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  return; +} + + +/** + * Free the state of a "exchanges" CMD, and possibly cancel a + * pending operation thereof. + * + * @param cls closure, a `struct ExchangesState` + * @param cmd the command which is being cleaned up. + */ +static void +exchanges_cleanup (void *cls, +		   const struct TALER_TESTING_Command *cmd) +{ +  struct ExchangesState *es = cls; + +  if (NULL != es->leh) +  { +    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, +                "Command %u (%s) did not complete\n", +                es->is->ip, +                cmd->label); +    TALER_AUDITOR_list_exchanges_cancel (es->leh); +    es->leh = NULL; +  } +  if (NULL != es->retry_task) +  { +    GNUNET_SCHEDULER_cancel (es->retry_task); +    es->retry_task = NULL; +  } +  GNUNET_free (es); +} + + +/** + * Offer internal data to other commands. + * + * @param cls closure. + * @param ret[out] set to the wanted data. + * @param trait name of the trait. + * @param index index number of the traits to be returned. + * + * @return #GNUNET_OK on success + */ +static int +exchanges_traits (void *cls, +		  const void **ret, +		  const char *trait, +		  unsigned int index) +{ +  /* Must define this function because some callbacks +   * look for certain traits on _all_ the commands. */ +  return GNUNET_SYSERR; +} + + +/** + * Create a "list exchanges" command. + * + * @param label command label. + * @param auditor auditor connection. + * @param expected_response_code expected HTTP response code. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_exchanges +  (const char *label, +   struct TALER_AUDITOR_Handle *auditor, +   unsigned int expected_response_code) +{ +  struct TALER_TESTING_Command cmd = {0}; /* need explicit zeroing..*/ +  struct ExchangesState *es; + +  es = GNUNET_new (struct ExchangesState); +  es->auditor = auditor; +  es->expected_response_code = expected_response_code; + +  cmd.cls = es; +  cmd.label = label; +  cmd.run = &exchanges_run; +  cmd.cleanup = &exchanges_cleanup; +  cmd.traits = &exchanges_traits; +   +  return cmd; +} + + +/** + * Modify an exchanges command to enable retries when we get + * transient errors from the auditor. + * + * @param cmd a deposit confirmation command + * @return the command with retries enabled + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_exchanges_with_retry (struct TALER_TESTING_Command cmd) +{ +  struct ExchangesState *es; + +  GNUNET_assert (&exchanges_run == cmd.run); +  es = cmd.cls; +  es->do_retry = GNUNET_YES; +  return cmd; +} + + +/* end of testing_auditor_api_cmd_exchanges.c */ diff --git a/src/include/taler_testing_auditor_lib.h b/src/include/taler_testing_auditor_lib.h index 2d7e8e14..fc8af678 100644 --- a/src/include/taler_testing_auditor_lib.h +++ b/src/include/taler_testing_auditor_lib.h @@ -94,6 +94,32 @@ struct TALER_TESTING_Command  TALER_TESTING_cmd_deposit_confirmation_with_retry (struct TALER_TESTING_Command cmd); +/** + * Create a "list exchanges" command. + * + * @param label command label. + * @param auditor auditor connection. + * @param expected_response_code expected HTTP response code. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_exchanges +  (const char *label, +   struct TALER_AUDITOR_Handle *auditor, +   unsigned int expected_response_code); + + +/** + * Modify an exchanges command to enable retries when we get + * transient errors from the auditor. + * + * @param cmd a deposit confirmation command + * @return the command with retries enabled + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_exchanges_with_retry (struct TALER_TESTING_Command cmd); + +  /* ********************* Helper functions ********************* */ | 
