diff options
| author | Florian Dold <florian.dold@gmail.com> | 2020-01-19 16:06:29 +0100 | 
|---|---|---|
| committer | Florian Dold <florian.dold@gmail.com> | 2020-01-19 16:06:29 +0100 | 
| commit | 9f522baadcf3b5288d35216962a91b5aeb688820 (patch) | |
| tree | ba6406aaeafee9739b850c220b267d77e4c1c909 | |
| parent | 03bcd50d9ad7147683ef9e8631af4efcecca1079 (diff) | |
add missing files and adjust .gitignore rules for testing move
| -rw-r--r-- | .gitignore | 20 | ||||
| -rw-r--r-- | src/include/taler_twister_testing_lib.h | 156 | ||||
| -rw-r--r-- | src/testing/testing_api_cmd_twister_exec_client.c | 1023 | ||||
| -rw-r--r-- | src/testing/testing_api_twister_helpers.c | 157 | 
4 files changed, 1346 insertions, 10 deletions
| @@ -42,10 +42,10 @@ src/bank-lib/test_bank_api_with_fakebank_twisted  src/bank-lib/test_bank_api_with_pybank_twisted  src/lib/test_exchange_api -src/lib/test_taler_exchange_httpd_home/.local/share/taler/exchange/live-keys/ -src/lib/test_taler_exchange_httpd_home/.local/share/taler/exchange/wirefees/ -src/lib/test_taler_exchange_httpd_home/.local/share/taler/auditor/ -src/lib/test_taler_exchange_httpd_home/.local/share/taler/auditors/ +src/testing/test_taler_exchange_httpd_home/.local/share/taler/exchange/live-keys/ +src/testing/test_taler_exchange_httpd_home/.local/share/taler/exchange/wirefees/ +src/testing/test_taler_exchange_httpd_home/.local/share/taler/auditor/ +src/testing/test_taler_exchange_httpd_home/.local/share/taler/auditors/  src/testing/test_exchange_api_keys_cherry_picking_home/.local/share/taler/exchange/live-keys/  src/testing/test_exchange_api_keys_cherry_picking_home/.local/share/taler/exchange/wirefees/ @@ -55,7 +55,7 @@ src/testing/test_exchange_api_home/.local/share/taler/exchange/live-keys/  src/testing/test_exchange_api_home/.local/share/taler/exchange/wirefees/  src/testing/test_exchange_api_home/.local/share/taler/auditor/  src/testing/test_exchange_api_home/.local/share/taler/auditors/ -src/lib/auditor.in +src/testing/auditor.in  src/testing/test_exchange_api_twisted  src/exchange/taler-exchange-aggregator  src/exchange/test_taler_exchange_aggregator-postgres @@ -109,7 +109,7 @@ doc/manual/manual.vr  doc/prebuilt/*  contrib/taler-exchange.tag  doxygen-doc/ -src/lib/test_exchange_api_keys_cherry_picking +src/testing/test_exchange_api_keys_cherry_picking  src/auditor/taler-wire-auditor  contrib/auditor-report.aux  contrib/auditor-report.log @@ -117,10 +117,10 @@ contrib/auditor-report.tex  contrib/auditor-report.pdf  src/bank-lib/taler-bank-transfer  src/bank-lib/test_bank_api_twisted -src/lib/test_exchange_api -src/lib/test_auditor_api -src/lib/test_exchange_api_overlapping_keys_bug -src/lib/test_exchange_api_home/.local/share/taler/exchange/revocations/ +src/testing/test_exchange_api +src/testing/test_auditor_api +src/testing/test_exchange_api_overlapping_keys_bug +src/testing/test_exchange_api_home/.local/share/taler/exchange/revocations/  src/wire-plugins/test_wire_plugin_legacy_taler_bank  uncrustify.cfg  vgcore.* diff --git a/src/include/taler_twister_testing_lib.h b/src/include/taler_twister_testing_lib.h new file mode 100644 index 00000000..fb0c352d --- /dev/null +++ b/src/include/taler_twister_testing_lib.h @@ -0,0 +1,156 @@ +/* +  This file is part of TALER +  (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 include/taler_twister_testing_lib.h + * @brief API for using twister-dependant test commands. + * @author Christian Grothoff <christian@grothoff.org> + * @author Marcello Stanisci + */ +#ifndef TALER_TWISTER_TESTING_LIB_H +#define TALER_TWISTER_TESTING_LIB_H + +#include <taler/taler_testing_lib.h> + +#define TWISTER_FAIL() \ +  do {GNUNET_break (0); return NULL; } while (0) + +/** + * Define a "hack response code" CMD.  This causes the next + * response code (from the service proxied by the twister) to + * be substituted with @a http_status. + * + * @param label command label + * @param config_filename configuration filename. + * @param http_status new response code to use + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_hack_response_code (const char *label, +                                      const char *config_filename, +                                      unsigned int http_status); + +/** + * Create a "delete object" CMD.  This command deletes + * the JSON object pointed by @a path. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to delete. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_delete_object (const char *label, +                                 const char *config_filename, +                                 const char *path); + +/** + * Create a "modify object" CMD.  This command instructs + * the twister to modify the next object that is downloaded + * from the proxied service. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to modify. + * @param value value to put as the object's. + * + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_modify_object_dl (const char *label, +                                    const char *config_filename, +                                    const char *path, +                                    const char *value); + +/** + * Create a "modify object" CMD.  This command instructs + * the twister to modify the next object that will be uploaded + * to the proxied service. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation pointing the object + *        to modify. + * @param value value to put as the object's. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_modify_object_ul (const char *label, +                                    const char *config_filename, +                                    const char *path, +                                    const char *value); + + +/** + * Create a "malform response" CMD.  This command makes + * the next response randomly malformed (by truncating it). + * + * @param label command label + * @param config_filename configuration filename. + * + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_malform_response (const char *label, +                                    const char *config_filename); + +/** + * Create a "malform request" CMD.  This command makes the + * next request randomly malformed (by truncating it). + * + * @param label command label + * @param config_filename configuration filename. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_malform_request (const char *label, +                                   const char *config_filename); + +/** + * Define a "flip object" command, for objects to upload. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to flip. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_flip_upload (const char *label, +                               const char *config_filename, +                               const char *path); + + +/** + * Define a "flip object" command, for objects to download. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to flip. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_flip_download (const char *label, +                                 const char *config_filename, +                                 const char *path); + +#endif diff --git a/src/testing/testing_api_cmd_twister_exec_client.c b/src/testing/testing_api_cmd_twister_exec_client.c new file mode 100644 index 00000000..6350d1d5 --- /dev/null +++ b/src/testing/testing_api_cmd_twister_exec_client.c @@ -0,0 +1,1023 @@ +/* +  This file is part of TALER +  (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 include/testing_api_cmd_exec_client.h + * @brief test commands aimed to call the CLI twister client + *        to drive its behaviour. + * @author Christian Grothoff <christian@grothoff.org> + * @author Marcello Stanisci + */ + +#include "platform.h" +#include <taler/taler_testing_lib.h> +#include "taler_twister_testing_lib.h" + + +/** + * State for a "modify object" CMD. + */ +struct ModifyObjectState +{ +  /** +   * Process handle for the twister CLI client. +   */ +  struct GNUNET_OS_Process *proc; + +  /** +   * Object-like notation to the object to delete. +   */ +  const char *path; + + +  /** +   * Value to substitute to the original one. +   */ +  const char *value; + +  /** +   * Config file name to pass to the CLI client. +   */ +  const char *config_filename; +}; + + +/** + * State for a "flip object" CMD. + */ +struct FlipObjectState +{ +  /** +   * Process handle for the twister CLI client. +   */ +  struct GNUNET_OS_Process *proc; + +  /** +   * Object-like notation to the string-object to flip. +   */ +  const char *path; + +  /** +   * Config file name to pass to the CLI client. +   */ +  const char *config_filename; +}; + + +/** + * State for a "delete object" CMD. + */ +struct DeleteObjectState +{ +  /** +   * Process handle for the twister CLI client. +   */ +  struct GNUNET_OS_Process *proc; + +  /** +   * Object-like notation to the object to delete. +   */ +  const char *path; + +  /** +   * Config file name to pass to the CLI client. +   */ +  const char *config_filename; +}; + + +/** + * State for a "malform request" CMD. + */ +struct MalformRequestState +{ +  /** +   * Process handle for the twister CLI client. +   */ +  struct GNUNET_OS_Process *proc; + +  /** +   * Config file name to pass to the CLI client. +   */ +  const char *config_filename; +}; + + +/** + * State for a "malform response" CMD. + */ +struct MalformResponseState +{ +  /** +   * Process handle for the twister CLI client. +   */ +  struct GNUNET_OS_Process *proc; + +  /** +   * Config file name to pass to the CLI client. +   */ +  const char *config_filename; +}; + + +/** + * State for a "hack response code" CMD. + */ +struct HackResponseCodeState +{ +  /** +   * Process handle for the twister CLI client. +   */ +  struct GNUNET_OS_Process *proc; + +  /** +   * HTTP status code to substitute to the original one. +   */ +  unsigned int http_status; + +  /** +   * Config file name to pass to the CLI client. +   */ +  const char *config_filename; +}; + + +/** + * Free the state from a "hack response code" CMD, and + * possibly kill its process if it did not terminate yet. + * + * @param cls closure. + * @param cmd the command being cleaned up. + */ +static void +hack_response_code_cleanup +  (void *cls, +  const struct TALER_TESTING_Command *cmd) +{ +  struct HackResponseCodeState *hrcs = cls; + +  if (NULL != hrcs->proc) +  { +    GNUNET_break (0 == GNUNET_OS_process_kill (hrcs->proc, +                                               SIGKILL)); +    GNUNET_OS_process_wait (hrcs->proc); +    GNUNET_OS_process_destroy (hrcs->proc); +    hrcs->proc = NULL; +  } +  GNUNET_free (hrcs); +} + + +/** + * Offer data internal to a "hack response code" CMD, + * to other commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param index index number of the object to offer. + * @return #GNUNET_OK on success + */ +static int +hack_response_code_traits (void *cls, +                           const void **ret, +                           const char *trait, +                           unsigned int index) +{ + +  struct HackResponseCodeState *hrcs = cls; +  struct TALER_TESTING_Trait traits[] = { +    TALER_TESTING_make_trait_process (0, &hrcs->proc), +    TALER_TESTING_trait_end () +  }; + +  return TALER_TESTING_get_trait (traits, +                                  ret, +                                  trait, +                                  index); +} + + +/** + * Run a "hack response code" CMD. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +hack_response_code_run (void *cls, +                        const struct TALER_TESTING_Command *cmd, +                        struct TALER_TESTING_Interpreter *is) +{ +  struct HackResponseCodeState *hrcs = cls; +  char *http_status; + +  GNUNET_asprintf (&http_status, "%u", +                   hrcs->http_status); + +  hrcs->proc = GNUNET_OS_start_process +                 (GNUNET_NO, +                 GNUNET_OS_INHERIT_STD_ALL, +                 NULL, NULL, NULL, +                 "taler-twister", +                 "taler-twister", +                 "-c", hrcs->config_filename, +                 "--responsecode", http_status, +                 NULL); +  if (NULL == hrcs->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +  GNUNET_free (http_status); +} + + +/** + * Define a "hack response code" CMD.  This causes the next + * response code (from the service proxied by the twister) to + * be substituted with @a http_status. + * + * @param label command label + * @param config_filename configuration filename. + * @param http_status new response code to use + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_hack_response_code (const char *label, +                                      const char *config_filename, +                                      unsigned int http_status) +{ +  struct HackResponseCodeState *hrcs; + +  hrcs = GNUNET_new (struct HackResponseCodeState); +  hrcs->http_status = http_status; +  hrcs->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &hack_response_code_run, +    .cleanup = &hack_response_code_cleanup, +    .traits = &hack_response_code_traits, +    .cls = hrcs +  }; + +  return cmd; +} + + +/** + * Free the state from a "delete object" CMD, and + * possibly kill its process if it did not terminate yet. + * + * @param cls closure. + * @param cmd the command being cleaned up. + */ +static void +delete_object_cleanup +  (void *cls, +  const struct TALER_TESTING_Command *cmd) +{ +  struct DeleteObjectState *dos = cls; + +  if (NULL != dos->proc) +  { +    GNUNET_break (0 == GNUNET_OS_process_kill (dos->proc, +                                               SIGKILL)); +    GNUNET_OS_process_wait (dos->proc); +    GNUNET_OS_process_destroy (dos->proc); +    dos->proc = NULL; +  } +  GNUNET_free (dos); +} + + +/** + * Offer data internal to a "delete object" CMD, + * to other commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param index index number of the object to offer. + * @return #GNUNET_OK on success + */ +static int +delete_object_traits (void *cls, +                      const void **ret, +                      const char *trait, +                      unsigned int index) +{ + +  struct DeleteObjectState *dos = cls; +  struct TALER_TESTING_Trait traits[] = { +    TALER_TESTING_make_trait_process (0, &dos->proc), +    TALER_TESTING_trait_end () +  }; + +  return TALER_TESTING_get_trait (traits, +                                  ret, +                                  trait, +                                  index); +} + + +/** + * Run a "delete object" CMD. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +delete_object_run (void *cls, +                   const struct TALER_TESTING_Command *cmd, +                   struct TALER_TESTING_Interpreter *is) +{ +  struct DeleteObjectState *dos = cls; + +  dos->proc = GNUNET_OS_start_process (GNUNET_NO, +                                       GNUNET_OS_INHERIT_STD_ALL, +                                       NULL, NULL, NULL, +                                       "taler-twister", +                                       "taler-twister", +                                       "-c", dos->config_filename, +                                       "--deleteobject", dos->path, +                                       NULL); +  if (NULL == dos->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Free the state from a "modify object" CMD, and + * possibly kill its process if it did not terminate yet. + * + * @param cls closure. + * @param cmd the command being cleaned up. + */ +static void +modify_object_cleanup +  (void *cls, +  const struct TALER_TESTING_Command *cmd) +{ +  struct ModifyObjectState *mos = cls; + +  if (NULL != mos->proc) +  { +    GNUNET_break (0 == GNUNET_OS_process_kill (mos->proc, +                                               SIGKILL)); +    GNUNET_OS_process_wait (mos->proc); +    GNUNET_OS_process_destroy (mos->proc); +    mos->proc = NULL; +  } +  GNUNET_free (mos); +} + + +/** + * Offer data internal to a "modify object" CMD, + * to other commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param index index number of the object to offer. + * @return #GNUNET_OK on success + */ +static int +modify_object_traits (void *cls, +                      const void **ret, +                      const char *trait, +                      unsigned int index) +{ + +  struct ModifyObjectState *mos = cls; +  struct TALER_TESTING_Trait traits[] = { +    TALER_TESTING_make_trait_process (0, &mos->proc), +    TALER_TESTING_trait_end () +  }; + +  return TALER_TESTING_get_trait (traits, +                                  ret, +                                  trait, +                                  index); +} + + +/** + * Run a "modify object" CMD.  The "download fashion" of it. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +modify_object_dl_run (void *cls, +                      const struct TALER_TESTING_Command *cmd, +                      struct TALER_TESTING_Interpreter *is) +{ +  struct ModifyObjectState *mos = cls; + +  mos->proc = GNUNET_OS_start_process (GNUNET_NO, +                                       GNUNET_OS_INHERIT_STD_ALL, +                                       NULL, NULL, NULL, +                                       "taler-twister", +                                       "taler-twister", +                                       "-c", mos->config_filename, +                                       "-m", mos->path, +                                       "--value", mos->value, +                                       NULL); +  if (NULL == mos->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Run a "modify object" CMD, the "upload fashion" of it. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +modify_object_ul_run (void *cls, +                      const struct TALER_TESTING_Command *cmd, +                      struct TALER_TESTING_Interpreter *is) +{ +  struct ModifyObjectState *mos = cls; + +  mos->proc = GNUNET_OS_start_process (GNUNET_NO, +                                       GNUNET_OS_INHERIT_STD_ALL, +                                       NULL, NULL, NULL, +                                       "taler-twister", +                                       "taler-twister", +                                       "-c", mos->config_filename, +                                       "-X", mos->path, +                                       "--value", mos->value, +                                       NULL); +  if (NULL == mos->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Create a "delete object" CMD.  This command deletes + * the JSON object pointed by @a path. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to delete. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_delete_object (const char *label, +                                 const char *config_filename, +                                 const char *path) +{ +  struct DeleteObjectState *dos; + +  dos = GNUNET_new (struct DeleteObjectState); +  dos->path = path; +  dos->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &delete_object_run, +    .cleanup = &delete_object_cleanup, +    .traits = &delete_object_traits, +    .cls = dos +  }; + +  return cmd; +} + + +/** + * Free the state from a "flip object" CMD, and + * possibly kill its process if it did not terminate yet. + * + * @param cls closure. + * @param cmd the command being cleaned up. + */ +static void +flip_object_cleanup +  (void *cls, +  const struct TALER_TESTING_Command *cmd) +{ +  struct FlipObjectState *fos = cls; + +  if (NULL != fos->proc) +  { +    GNUNET_break (0 == GNUNET_OS_process_kill (fos->proc, +                                               SIGKILL)); +    GNUNET_OS_process_wait (fos->proc); +    GNUNET_OS_process_destroy (fos->proc); +    fos->proc = NULL; +  } +  GNUNET_free (fos); +} + + +/** + * Offer data internal to a "flip object" CMD, + * to other commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param index index number of the object to offer. + * @return #GNUNET_OK on success + */ +static int +flip_object_traits (void *cls, +                    const void **ret, +                    const char *trait, +                    unsigned int index) +{ + +  struct FlipObjectState *fos = cls; +  struct TALER_TESTING_Trait traits[] = { +    TALER_TESTING_make_trait_process (0, &fos->proc), +    TALER_TESTING_trait_end () +  }; + +  return TALER_TESTING_get_trait (traits, +                                  ret, +                                  trait, +                                  index); +} + + +/** + * Run a "flip object" CMD, the upload fashion of it. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +flip_upload_run (void *cls, +                 const struct TALER_TESTING_Command *cmd, +                 struct TALER_TESTING_Interpreter *is) +{ +  struct FlipObjectState *fos = cls; + +  fos->proc = GNUNET_OS_start_process (GNUNET_NO, +                                       GNUNET_OS_INHERIT_STD_ALL, +                                       NULL, NULL, NULL, +                                       "taler-twister", +                                       "taler-twister", +                                       "-c", fos->config_filename, +                                       "--flip-ul", fos->path, +                                       NULL); +  if (NULL == fos->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Run a "flip object" CMD, the download fashion of it. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +flip_download_run (void *cls, +                   const struct TALER_TESTING_Command *cmd, +                   struct TALER_TESTING_Interpreter *is) +{ +  struct FlipObjectState *fos = cls; + +  fos->proc = GNUNET_OS_start_process (GNUNET_NO, +                                       GNUNET_OS_INHERIT_STD_ALL, +                                       NULL, NULL, NULL, +                                       "taler-twister", +                                       "taler-twister", +                                       "-c", fos->config_filename, +                                       "--flip-dl", fos->path, +                                       NULL); +  if (NULL == fos->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Define a "flip object" command, for objects to upload. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to flip. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_flip_upload (const char *label, +                               const char *config_filename, +                               const char *path) +{ +  struct FlipObjectState *dos; + +  dos = GNUNET_new (struct FlipObjectState); +  dos->path = path; +  dos->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &flip_upload_run, +    .cleanup = &flip_object_cleanup, +    .traits = &flip_object_traits, +    .cls = dos +  }; + +  return cmd; +} + + +/** + * Define a "flip object" command, for objects to download. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to flip. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_flip_download (const char *label, +                                 const char *config_filename, +                                 const char *path) +{ +  struct FlipObjectState *dos; + +  dos = GNUNET_new (struct FlipObjectState); +  dos->path = path; +  dos->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &flip_download_run, +    .cleanup = &flip_object_cleanup, +    .traits = &flip_object_traits, +    .cls = dos +  }; + +  return cmd; +} + + +/** + * Free the state from a "malform request" CMD, and + * possibly kill its process if it did not terminate yet. + * + * @param cls closure. + * @param cmd the command being cleaned up. + */ +static void +malform_request_cleanup (void *cls, +                         const struct TALER_TESTING_Command *cmd) +{ +  struct MalformRequestState *mrs = cls; + +  if (NULL != mrs->proc) +  { +    GNUNET_break (0 == GNUNET_OS_process_kill (mrs->proc, +                                               SIGKILL)); +    GNUNET_OS_process_wait (mrs->proc); +    GNUNET_OS_process_destroy (mrs->proc); +    mrs->proc = NULL; +  } +  GNUNET_free (mrs); +} + + +/** + * Offer data internal to a "malform request" CMD, + * to other commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param index index number of the object to offer. + * @return #GNUNET_OK on success + */ +static int +malform_request_traits (void *cls, +                        const void **ret, +                        const char *trait, +                        unsigned int index) +{ +  struct MalformRequestState *mrs = cls; +  struct TALER_TESTING_Trait traits[] = { +    TALER_TESTING_make_trait_process (0, &mrs->proc), +    TALER_TESTING_trait_end () +  }; + +  return TALER_TESTING_get_trait (traits, +                                  ret, +                                  trait, +                                  index); +} + + +/** + * Run a "malform request" CMD. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +malform_request_run (void *cls, +                     const struct TALER_TESTING_Command *cmd, +                     struct TALER_TESTING_Interpreter *is) +{ +  struct MalformRequestState *mrs = cls; + +  mrs->proc = GNUNET_OS_start_process (GNUNET_NO, +                                       GNUNET_OS_INHERIT_STD_ALL, +                                       NULL, NULL, NULL, +                                       "taler-twister", +                                       "taler-twister", +                                       "-c", mrs->config_filename, +                                       "--malformupload", +                                       NULL); +  if (NULL == mrs->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Free the state from a "malform response" CMD, and + * possibly kill its process if it did not terminate yet. + * + * @param cls closure. + * @param cmd the command being cleaned up. + */ +static void +malform_response_cleanup +  (void *cls, +  const struct TALER_TESTING_Command *cmd) +{ +  struct MalformResponseState *mrs = cls; + +  if (NULL != mrs->proc) +  { +    GNUNET_break (0 == GNUNET_OS_process_kill (mrs->proc, +                                               SIGKILL)); +    GNUNET_OS_process_wait (mrs->proc); +    GNUNET_OS_process_destroy (mrs->proc); +    mrs->proc = NULL; +  } +  GNUNET_free (mrs); +} + + +/** + * Offer data internal to a "malform response" CMD, + * to other commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param index index number of the object to offer. + * @return #GNUNET_OK on success + */ +static int +malform_response_traits (void *cls, +                         const void **ret, +                         const char *trait, +                         unsigned int index) +{ +  struct MalformResponseState *mrs = cls; +  struct TALER_TESTING_Trait traits[] = { +    TALER_TESTING_make_trait_process (0, &mrs->proc), +    TALER_TESTING_trait_end () +  }; + +  return TALER_TESTING_get_trait (traits, +                                  ret, +                                  trait, +                                  index); +} + + +/** + * Run a "malform response" CMD. + * + * @param cls closure. + * @param cmd the command being run. + * @param is the interpreter state. + */ +static void +malform_response_run (void *cls, +                      const struct TALER_TESTING_Command *cmd, +                      struct TALER_TESTING_Interpreter *is) +{ +  struct MalformResponseState *mrs = cls; + +  mrs->proc = GNUNET_OS_start_process (GNUNET_NO, +                                       GNUNET_OS_INHERIT_STD_ALL, +                                       NULL, NULL, NULL, +                                       "taler-twister", +                                       "taler-twister", +                                       "-c", mrs->config_filename, +                                       "--malform", +                                       NULL); +  if (NULL == mrs->proc) +  { +    GNUNET_break (0); +    TALER_TESTING_interpreter_fail (is); +    return; +  } +  TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Create a "malform request" CMD.  This command makes the + * next request randomly malformed (by truncating it). + * + * @param label command label + * @param config_filename configuration filename. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_malform_request (const char *label, +                                   const char *config_filename) +{ +  struct MalformRequestState *mrs; + +  mrs = GNUNET_new (struct MalformRequestState); +  mrs->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &malform_request_run, +    .cleanup = &malform_request_cleanup, +    .traits = &malform_request_traits, +    .cls = mrs +  }; + +  return cmd; +} + + +/** + * Create a "malform response" CMD.  This command makes + * the next response randomly malformed (by truncating it). + * + * @param label command label + * @param config_filename configuration filename. + * + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_malform_response (const char *label, +                                    const char *config_filename) +{ +  struct MalformResponseState *mrs; + +  mrs = GNUNET_new (struct MalformResponseState); +  mrs->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &malform_response_run, +    .cleanup = &malform_response_cleanup, +    .traits = &malform_response_traits, +    .cls = mrs +  }; + +  return cmd; + +} + + +/** + * Create a "modify object" CMD.  This command instructs + * the twister to modify the next object that is downloaded + * from the proxied service. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation to point the object + *        to modify. + * @param value value to put as the object's. + * + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_modify_object_dl (const char *label, +                                    const char *config_filename, +                                    const char *path, +                                    const char *value) +{ +  struct ModifyObjectState *mos; + +  mos = GNUNET_new (struct ModifyObjectState); +  mos->path = path; +  mos->value = value; +  mos->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &modify_object_dl_run, +    .cleanup = &modify_object_cleanup, +    .traits = &modify_object_traits, +    .cls = mos +  }; + +  return cmd; +} + + +/** + * Create a "modify object" CMD.  This command instructs + * the twister to modify the next object that will be uploaded + * to the proxied service. + * + * @param label command label + * @param config_filename configuration filename. + * @param path object-like path notation pointing the object + *        to modify. + * @param value value to put as the object's. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_modify_object_ul (const char *label, +                                    const char *config_filename, +                                    const char *path, +                                    const char *value) +{ +  struct ModifyObjectState *mos; + +  mos = GNUNET_new (struct ModifyObjectState); +  mos->path = path; +  mos->value = value; +  mos->config_filename = config_filename; + +  struct TALER_TESTING_Command cmd = { +    .label = label, +    .run = &modify_object_ul_run, +    .cleanup = &modify_object_cleanup, +    .traits = &modify_object_traits, +    .cls = mos +  }; + +  return cmd; +} + + +/* end of testing_api_cmd_exec_client.c */ diff --git a/src/testing/testing_api_twister_helpers.c b/src/testing/testing_api_twister_helpers.c new file mode 100644 index 00000000..6fab02c3 --- /dev/null +++ b/src/testing/testing_api_twister_helpers.c @@ -0,0 +1,157 @@ +/* +  This file is part of TALER +  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 +  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 twister/testing_api_helpers.c + * @brief helper functions for test library. + * @author Christian Grothoff + * @author Marcello Stanisci + */ + +#include "platform.h" +#include <gnunet/gnunet_util_lib.h> +#include "taler_twister_testing_lib.h" + +/** + * Prepare twister for execution; mainly checks whether the + * HTTP port is available and construct the base URL based on it. + * + * @param config_filename configuration file name. + * @return twister base URL, NULL upon errors. + */ +char * +TALER_TWISTER_prepare_twister (const char *config_filename) +{ +  struct GNUNET_CONFIGURATION_Handle *cfg; +  unsigned long long port; +  char *base_url; + +  cfg = GNUNET_CONFIGURATION_create (); + +  if (GNUNET_OK != GNUNET_CONFIGURATION_load +        (cfg, config_filename)) +    TWISTER_FAIL (); + +  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number +        (cfg, "twister", +        "HTTP_PORT", &port)) +  { +    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, +                               "twister", +                               "HTTP_PORT"); +    GNUNET_CONFIGURATION_destroy (cfg); +    TWISTER_FAIL (); +  } + +  GNUNET_CONFIGURATION_destroy (cfg); + +  if (GNUNET_OK != GNUNET_NETWORK_test_port_free +        (IPPROTO_TCP, (uint16_t) port)) +  { +    fprintf (stderr, +             "Required port %llu not available, skipping.\n", +             port); +    TWISTER_FAIL (); +  } + +  GNUNET_assert (0 < GNUNET_asprintf +                   (&base_url, +                   "http://localhost:%llu/", +                   port)); + +  return base_url; +} + + +/** + * Run the twister service. + * + * @param config_filename configuration file name. + * @return twister process handle, NULL upon errors. + */ +struct GNUNET_OS_Process * +TALER_TWISTER_run_twister (const char *config_filename) +{ +  struct GNUNET_OS_Process *proc; +  struct GNUNET_OS_Process *client_proc; +  unsigned long code; +  enum GNUNET_OS_ProcessStatusType type; + +  proc = GNUNET_OS_start_process (GNUNET_NO, +                                  GNUNET_OS_INHERIT_STD_ALL, +                                  NULL, NULL, NULL, +                                  "taler-twister-service", +                                  "taler-twister-service", +                                  "-c", config_filename, +                                  NULL); +  if (NULL == proc) +    TWISTER_FAIL (); + +  client_proc = GNUNET_OS_start_process (GNUNET_NO, +                                         GNUNET_OS_INHERIT_STD_ALL, +                                         NULL, NULL, NULL, +                                         "taler-twister", +                                         "taler-twister", +                                         "-c", config_filename, +                                         "-a", NULL); +  if (NULL == client_proc) +  { +    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                "Could not start the taler-twister client\n"); +    GNUNET_OS_process_kill (proc, SIGTERM); +    GNUNET_OS_process_wait (proc); +    GNUNET_OS_process_destroy (proc); +    TWISTER_FAIL (); +  } + + +  if (GNUNET_SYSERR == GNUNET_OS_process_wait_status +        (client_proc, &type, &code)) +  { +    GNUNET_OS_process_destroy (client_proc); +    GNUNET_OS_process_kill (proc, SIGTERM); +    GNUNET_OS_process_wait (proc); +    GNUNET_OS_process_destroy (proc); +    TWISTER_FAIL (); +  } +  if ( (type == GNUNET_OS_PROCESS_EXITED) && +       (0 != code) ) +  { +    fprintf (stderr, "Failed to check twister works.\n"); +    GNUNET_OS_process_destroy (client_proc); +    GNUNET_OS_process_kill (proc, SIGTERM); +    GNUNET_OS_process_wait (proc); +    GNUNET_OS_process_destroy (proc); +    TWISTER_FAIL (); +  } +  if ( (type != GNUNET_OS_PROCESS_EXITED) || +       (0 != code) ) +  { +    fprintf (stderr, "Unexpected error running" +             " `taler-twister'!\n"); +    GNUNET_OS_process_destroy (client_proc); +    GNUNET_OS_process_kill (proc, SIGTERM); +    GNUNET_OS_process_wait (proc); +    GNUNET_OS_process_destroy (proc); +    TWISTER_FAIL (); +  } +  GNUNET_OS_process_destroy (client_proc); + +  return proc; +} | 
