From feec78dd56f261dac02899c2dc96019d95f94d13 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Wed, 20 Jun 2018 22:16:24 +0200 Subject: Implementing #5306. --- src/exchange-lib/Makefile.am | 3 +- src/exchange-lib/testing_api_cmd_batch.c | 49 +++++++++++++++++- src/exchange-lib/testing_api_cmd_deposit.c | 3 +- src/exchange-lib/testing_api_loop.c | 34 +++++++++++-- src/exchange-lib/testing_api_trait_cmd.c | 82 ++++++++++++++++++++++++++++++ src/include/taler_testing_lib.h | 57 +++++++++++++++++---- 6 files changed, 209 insertions(+), 19 deletions(-) create mode 100644 src/exchange-lib/testing_api_trait_cmd.c (limited to 'src') diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am index 0bb19576b..f2bfae438 100644 --- a/src/exchange-lib/Makefile.am +++ b/src/exchange-lib/Makefile.am @@ -70,7 +70,8 @@ libtalertesting_la_SOURCES = \ testing_api_trait_string.c \ testing_api_trait_key_peer.c \ testing_api_trait_wtid.c \ - testing_api_trait_amount.c + testing_api_trait_amount.c \ + testing_api_trait_cmd.c libtalertesting_la_LIBADD = \ $(top_builddir)/src/wire/libtalerwire.la \ $(top_builddir)/src/json/libtalerjson.la \ diff --git a/src/exchange-lib/testing_api_cmd_batch.c b/src/exchange-lib/testing_api_cmd_batch.c index 1ebaa7948..3912762f1 100644 --- a/src/exchange-lib/testing_api_cmd_batch.c +++ b/src/exchange-lib/testing_api_cmd_batch.c @@ -37,7 +37,7 @@ struct BatchState struct TALER_TESTING_Command *batch; /* Internal comand pointer. */ - unsigned int batch_ip; + int batch_ip; }; @@ -55,9 +55,16 @@ batch_run (void *cls, { struct BatchState *bs = cls; + bs->batch_ip++; + + TALER_LOG_DEBUG ("Running batched command: %s\n", + bs->batch[bs->batch_ip].label); + /* hit end command, leap to next top-level command. */ if (NULL == bs->batch[bs->batch_ip].label) { + TALER_LOG_INFO ("Exiting from batch: %s\n", + cmd->label); TALER_TESTING_interpreter_next (is); return; } @@ -65,7 +72,6 @@ batch_run (void *cls, bs->batch[bs->batch_ip].run (bs->batch[bs->batch_ip].cls, &bs->batch[bs->batch_ip], is); - bs->batch_ip++; } @@ -91,6 +97,42 @@ batch_cleanup (void *cls, } +/** + * Offer internal data from a "batch" CMD, to other commands. + * + * @param cls closure. + * @param ret[out] result. + * @param trait name of the trait. + * @param index index number of the object to offer. + * + * @return #GNUNET_OK on success. + */ +static int +batch_traits (void *cls, + 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_cmd + (CURRENT_CMD_INDEX, &bs->batch[bs->batch_ip]), + TALER_TESTING_make_trait_cmd + (BATCH_INDEX, bs->batch), + TALER_TESTING_trait_end () + }; + + /* Always return current command. */ + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + /** * Create a "batch" command. Such command takes a * end_CMD-terminated array of CMDs and executed them. @@ -111,7 +153,9 @@ TALER_TESTING_cmd_batch (const char *label, struct BatchState *bs; unsigned int i; + cmd.meta = GNUNET_YES; bs = GNUNET_new (struct BatchState); + bs->batch_ip = -1; /* Get number of commands. */ for (i=0;NULL != batch[i].label;i++) @@ -128,6 +172,7 @@ TALER_TESTING_cmd_batch (const char *label, cmd.label = label; cmd.run = &batch_run; cmd.cleanup = &batch_cleanup; + cmd.traits = &batch_traits; return cmd; } diff --git a/src/exchange-lib/testing_api_cmd_deposit.c b/src/exchange-lib/testing_api_cmd_deposit.c index 9756d0bee..e8bcf0289 100644 --- a/src/exchange-lib/testing_api_cmd_deposit.c +++ b/src/exchange-lib/testing_api_cmd_deposit.c @@ -370,7 +370,8 @@ deposit_traits (void *cls, struct TALER_TESTING_Trait traits[] = { TALER_TESTING_make_trait_coin_priv (0, coin_spent_priv), TALER_TESTING_make_trait_wire_details (0, ds->wire_details), - TALER_TESTING_make_trait_contract_terms (0, ds->contract_terms), + TALER_TESTING_make_trait_contract_terms + (0, ds->contract_terms), TALER_TESTING_make_trait_peer_key (0, &ds->merchant_priv.eddsa_priv), TALER_TESTING_trait_end () diff --git a/src/exchange-lib/testing_api_loop.c b/src/exchange-lib/testing_api_loop.c index 7293aa080..ac688594e 100644 --- a/src/exchange-lib/testing_api_loop.c +++ b/src/exchange-lib/testing_api_loop.c @@ -69,10 +69,14 @@ TALER_TESTING_interpreter_lookup_command if (GNUNET_YES == cmd->meta) { - struct TALER_TESTING_Command *batch = cmd->cls; + #define BATCH_INDEX 1 + struct TALER_TESTING_Command *batch; + + /* NEED BATCH HERE FROM TRAIT. */ + GNUNET_assert + (GNUNET_OK == TALER_TESTING_get_trait_cmd + (cmd, BATCH_INDEX, &batch)); - /* NOTE: the batch does need a "end" CMD in the - * last place. */ for (unsigned int i=0; NULL != (cmd = &batch[i])->label; i++) @@ -166,10 +170,23 @@ interpreter_run (void *cls); void TALER_TESTING_interpreter_next (struct TALER_TESTING_Interpreter *is) { + struct TALER_TESTING_Command *cmd = &is->commands[is->ip]; + if (GNUNET_SYSERR == is->result) return; /* ignore, we already failed! */ - if (GNUNET_NO == is->commands[is->ip].meta) + if (GNUNET_YES == cmd->meta) + { + #define CURRENT_BATCH_SUBCMD_INDEX 0 + struct TALER_TESTING_Command *sub_cmd; + + GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_cmd + (cmd, CURRENT_BATCH_SUBCMD_INDEX, &sub_cmd)); + + if (NULL == sub_cmd->label) + is->ip++; + } + else is->ip++; is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, is); @@ -337,6 +354,15 @@ maint_child_death (void *cls) struct GNUNET_OS_Process **processp; char c[16]; + if (GNUNET_YES == cmd->meta) + { + struct TALER_TESTING_Command *batch_cmd; + GNUNET_assert + (GNUNET_OK == TALER_TESTING_get_trait_cmd + (cmd, 0, &batch_cmd)); /* bad? */ + cmd = batch_cmd; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got SIGCHLD for `%s'.\n", cmd->label); diff --git a/src/exchange-lib/testing_api_trait_cmd.c b/src/exchange-lib/testing_api_trait_cmd.c new file mode 100644 index 000000000..9f7c8d5c8 --- /dev/null +++ b/src/exchange-lib/testing_api_trait_cmd.c @@ -0,0 +1,82 @@ +/* + 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 + +*/ + +/** + * @file exchange-lib/testing_api_trait_cmd.c + * @brief offers CMDs as traits. + * @author Marcello Stanisci + */ +#include "platform.h" +#include "taler_json_lib.h" +#include +#include "exchange_api_handle.h" +#include "taler_signatures.h" +#include "taler_testing_lib.h" + +#define TALER_TESTING_TRAIT_CMD "cmd" + +/** + * Obtain a command from @a cmd. + * + * @param cmd command to extract the command from. + * @param index always zero. Commands offering this + * kind of traits do not need this index. For + * example, a "meta" CMD returns always the + * CMD currently being executed. + * @param cmd_[out] where to write the wire details. + * + * @return #GNUNET_OK on success. + */ +int +TALER_TESTING_get_trait_cmd + (const struct TALER_TESTING_Command *cmd, + unsigned int index, + struct TALER_TESTING_Command **_cmd) +{ + return cmd->traits (cmd->cls, + (void **) _cmd, + TALER_TESTING_TRAIT_CMD, + index); +} + +/** + * Offer a command in a trait. + * + * @param index always zero. Commands offering this + * kind of traits do not need this index. For + * example, a "meta" CMD returns always the + * CMD currently being executed. + * @param cmd wire details to offer. + * + * @return the trait. + */ +struct TALER_TESTING_Trait +TALER_TESTING_make_trait_cmd + (unsigned int index, + const struct TALER_TESTING_Command *cmd) +{ + struct TALER_TESTING_Trait ret = { + .index = index, + .trait_name = TALER_TESTING_TRAIT_CMD, + .ptr = (const struct TALER_TESTING_Command *) cmd + }; + return ret; +} + +/* end of testing_api_trait_cmd.c */ diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 4cfb25a9b..b63bd8c67 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -1115,6 +1115,23 @@ TALER_TESTING_cmd_check_keys unsigned int num_denom_keys, struct TALER_EXCHANGE_Handle *exchange); +/** + * 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); + + /* *** Generic trait logic for implementing traits ********* */ /** @@ -1808,18 +1825,36 @@ TALER_TESTING_get_trait_rejected /** - * 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. + * Offer a command in a trait. * - * @param label the command label. - * @param batch array of CMDs to execute. + * @param index always zero. Commands offering this + * kind of traits do not need this index. For + * example, a "meta" CMD returns always the + * CMD currently being executed. + * @param cmd wire details to offer. * - * @return the command. + * @return the trait. */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_batch (const char *label, - struct TALER_TESTING_Command *batch); +struct TALER_TESTING_Trait +TALER_TESTING_make_trait_cmd + (unsigned int index, + const struct TALER_TESTING_Command *cmd); + +/** + * Obtain a command from @a cmd. + * + * @param cmd command to extract the command from. + * @param index always zero. Commands offering this + * kind of traits do not need this index. For + * example, a "meta" CMD returns always the + * CMD currently being executed. + * @param cmd_[out] where to write the wire details. + * + * @return #GNUNET_OK on success. + */ +int +TALER_TESTING_get_trait_cmd + (const struct TALER_TESTING_Command *cmd, + unsigned int index, + struct TALER_TESTING_Command **_cmd); #endif -- cgit v1.2.3