twister

HTTP fault injector for testing
Log | Files | Refs | README | LICENSE

commit 175ad8496607f0191a974fc28b092a4beb515e70
parent 423a44dde049974023f488a3438c739333bae38c
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Fri,  2 Mar 2018 14:19:46 +0100

helpers compile.

Diffstat:
Asrc/include/taler_twister_testing_lib.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/twister/testing_api_cmd_exec_client.c | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/twister/testing_api_helpers.c | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 312 insertions(+), 0 deletions(-)

diff --git a/src/include/taler_twister_testing_lib.h b/src/include/taler_twister_testing_lib.h @@ -0,0 +1,50 @@ +/* + 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) + +/** + * Command that replaces the HTTP response code for + * the next connection that will be made to the twister. + * + * @param label command label + * @param http_status new response code to use + * @param config_filename configuration filename. + * + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_hack_response_code (const char *label, + unsigned int http_status); + + + +#endif diff --git a/src/twister/testing_api_cmd_exec_client.c b/src/twister/testing_api_cmd_exec_client.c @@ -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/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/taler_twsiter_testing_lib.h> + +struct HackResponseCodeState +{ + /** + * Process handle for the twister CLI client. + */ + struct GNUNET_OS_Process *proc; + + /** + * HTTP status code the twister will return upon its next + * connection. + */ + unsigned int http_status; + + /** + * Config file name to pass to the CLI client. + */ + const char *config_filename; +}; + + +/** + * Clean up after the command. Run during forced termination + * (CTRL-C) or test failure or test success. + * + * @param cls closure + */ +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); +} + +/** + * Extract information from a command that is useful for other + * commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param selector more detailed information about which object + * to return in case there were multiple generated + * by the command + * @return #GNUNET_OK on success + */ +static int +hack_response_code_traits (void *cls, + void **ret, + const char *trait, + unsigned int index) +{ + /* Some other command may "probe" here looking for traits. */ + return GNUNET_SYSERR; +} + +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, + "-a", http_status, + NULL); + if (NULL == hrcs->proc) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Command that replaces the HTTP response code for + * the next connection that will be made to the twister. + * + * @param label command label + * @param http_status new response code to use + * @param config_filename configuration filename. + * + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_hack_response_code (const char *label, + unsigned int http_status) +{ + struct HackResponseCodeState *hrcs; + struct TALER_TESTING_Command cmd; + + hrcs = GNUNET_new (struct HackResponseCodeState); + hrcs->http_status = http_status; + hrcs->config_filename = config_filename; + + cmd.label = label; + cmd.run = &hack_response_code_run; + cmd.cleanup = &hack_response_code_cleanup; + cmd.traits = &hack_response_code_traits; + cmd.cls = hrcs; + + return cmd; +} diff --git a/src/twister/testing_api_helpers.c b/src/twister/testing_api_helpers.c @@ -0,0 +1,106 @@ +/* + 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" + +/** + * @param config_filename configuration filename. + * + * @return the process, or NULL if the process could not + * be started. + */ +struct GNUNET_OS_Process * +TALER_TESTING_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; +}