From 72a629a8be1ed2adc7402285e0f19f8f06816a26 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sun, 19 Jan 2020 15:23:19 +0100 Subject: move testing logic and integration tests into separate directory --- src/testing/testing_api_cmd_check_keys.c | 358 +++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 src/testing/testing_api_cmd_check_keys.c (limited to 'src/testing/testing_api_cmd_check_keys.c') diff --git a/src/testing/testing_api_cmd_check_keys.c b/src/testing/testing_api_cmd_check_keys.c new file mode 100644 index 000000000..6e5c694cf --- /dev/null +++ b/src/testing/testing_api_cmd_check_keys.c @@ -0,0 +1,358 @@ +/* + 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 + +*/ +/** + * @file testing/testing_api_cmd_check_keys.c + * @brief Implementation of "check keys" test command. XXX-NOTE: + * the number of 'expected keys' is NOT the number of the + * downloaded keys, but rather the number of keys that the + * libtalerutil library keeps locally. As for the current + * design, keys are _never_ discarded by the library, + * therefore their (expected) number is monotonically + * ascending. + * + * @author Marcello Stanisci + */ +#include "platform.h" +#include "taler_json_lib.h" +#include +#include "taler_testing_lib.h" + + +/** + * State for a "check keys" CMD. + */ +struct CheckKeysState +{ + /** + * This number will instruct the CMD interpreter to + * make sure that /keys was downloaded `generation` times + * _before_ running the very CMD logic. + */ + unsigned int generation; + + /** + * How many denomination keys the exchange is + * supposed to have. + */ + unsigned int num_denom_keys; + + /** + * If this value is GNUNET_YES, then the "cherry + * picking" facility is turned off; whole /keys is + * downloaded. + */ + unsigned int pull_all_keys; + + /** + * If GNUNET_YES, then the user must specify the + * last_denom_issue_date manually. This way, it is possible + * to force whatever X value here (including 0): /keys?last_denom_issue=X. + */ + unsigned int set_last_denom; + + /** + * Value X to set as the URL parameter: + * "/keys?last_denom_issue=X" is used only when `set_last_denom' + * equals GNUNET_YES. + */ + struct GNUNET_TIME_Absolute last_denom_date; + + /** + * If GNUNET_YES, then we'll provide the "/keys" request. + * with the "now" argument. + */ + int with_now; + + /** + * Fake now as passed by the user. + */ + struct GNUNET_TIME_Absolute now; + +}; + + +/** + * Run the "check keys" command. + * + * @param cls closure. + * @param cmd the command currently being executed. + * @param is the interpreter state. + */ +static void +check_keys_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct CheckKeysState *cks = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "cmd `%s' (ip: %u), key generation: %d\n", + cmd->label, + is->ip, + is->key_generation); + + if (is->key_generation < cks->generation) + { + is->working = GNUNET_NO; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Triggering GET /keys, cmd `%s'\n", + cmd->label); + + if (GNUNET_YES == cks->set_last_denom) + { + TALER_LOG_DEBUG ("Forcing last_denom_date URL argument\n"); + TALER_EXCHANGE_set_last_denom (is->exchange, + cks->last_denom_date); + } + + if (GNUNET_YES == cks->with_now) + TALER_EXCHANGE_set_now (is->exchange, + cks->now); + /* Redownload /keys. */ + GNUNET_break + (0 == TALER_EXCHANGE_check_keys_current + (is->exchange, + GNUNET_YES, + cks->pull_all_keys).abs_value_us); + return; + } + +#if 0 + /** + * Not sure this check makes sense: GET /keys is performed on + * a "maybe" basis, so it can get quite hard to track /keys + * request. Rather, this CMD should just check if /keys was + * requested AT LEAST n times before going ahead with checks. + */// + if (is->key_generation > cks->generation) + { + /* We got /keys too often, strange. Fatal. May theoretically + happen if somehow we were really unlucky and /keys expired + "naturally", but obviously with a sane configuration this + should also not be. */ + GNUNET_break (0); + TALER_LOG_ERROR ("Acutal- vs expected key" + " generation: %u vs %u\n", + is->key_generation, + cks->generation); + TALER_TESTING_interpreter_fail (is); + return; + } +#endif + /* "/keys" was updated, let's check they were OK! */ + if (cks->num_denom_keys != is->keys->num_denom_keys) + { + /* Did not get the expected number of denomination keys! */ + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Got %u keys in step %s, expected %u\n", + is->keys->num_denom_keys, + cmd->label, + cks->num_denom_keys); + TALER_TESTING_interpreter_fail (is); + return; + } + + /* Let's unset the fake now before moving on. */ + TALER_EXCHANGE_unset_now (is->exchange); + TALER_TESTING_interpreter_next (is); +} + + +/** + * Cleanup the state. + * + * @param cls closure. + * @param cmd the command which is being cleaned up. + */ +static void +check_keys_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct CheckKeysState *cks = cls; + + GNUNET_free (cks); +} + + +/** + * Make a "check keys" command. This type of command + * checks whether the number of denomination keys from + * @a exchange matches @a num_denom_keys. Additionally, + * it lets the user set a last denom issue date to be + * used in the request for /keys. + * + * @param label command label + * @param generation when this command is run, exactly @a + * generation /keys downloads took place. If the number + * of downloads is less than @a generation, the logic will + * first make sure that @a generation downloads are done, + * and _then_ execute the rest of the command. + * @param num_denom_keys expected number of denomination keys. + * @param last_denom_date date to be set in the "last_denom_issue" + * URL parameter of /keys. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_check_keys_with_last_denom (const char *label, + unsigned int generation, + unsigned int num_denom_keys, + struct GNUNET_TIME_Absolute + last_denom_date) +{ + struct CheckKeysState *cks; + + cks = GNUNET_new (struct CheckKeysState); + cks->generation = generation; + cks->num_denom_keys = num_denom_keys; + cks->set_last_denom = GNUNET_YES; + cks->last_denom_date = last_denom_date; + { + struct TALER_TESTING_Command cmd = { + .cls = cks, + .label = label, + .run = &check_keys_run, + .cleanup = &check_keys_cleanup + }; + + return cmd; + } +} + + +/** + * Make a "check keys" command. This type of command + * checks whether the number of denomination keys from + * @a exchange matches @a num_denom_keys. + * + * @param label command label + * @param generation when this command is run, exactly @a + * generation /keys downloads took place. If the number + * of downloads is less than @a generation, the logic will + * first make sure that @a generation downloads are done, + * and _then_ execute the rest of the command. + * @param num_denom_keys expected number of denomination keys. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_check_keys (const char *label, + unsigned int generation, + unsigned int num_denom_keys) +{ + struct CheckKeysState *cks; + + cks = GNUNET_new (struct CheckKeysState); + cks->generation = generation; + cks->num_denom_keys = num_denom_keys; + { + struct TALER_TESTING_Command cmd = { + .cls = cks, + .label = label, + .run = &check_keys_run, + .cleanup = &check_keys_cleanup + }; + + return cmd; + } +} + + +/** + * Make a "check keys" command. This type of command + * checks whether the number of denomination keys from + * @a exchange matches @a num_denom_keys. + * + * @param label command label + * @param generation when this command is run, exactly @a + * generation /keys downloads took place. If the number + * of downloads is less than @a generation, the logic will + * first make sure that @a generation downloads are done, + * and _then_ execute the rest of the command. + * @param num_denom_keys expected number of denomination keys. + * @param now timestamp to use when fetching keys + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_check_keys_with_now (const char *label, + unsigned int generation, + unsigned int num_denom_keys, + struct GNUNET_TIME_Absolute now) +{ + struct CheckKeysState *cks; + + cks = GNUNET_new (struct CheckKeysState); + cks->generation = generation; + cks->num_denom_keys = num_denom_keys; + cks->now = now; + cks->with_now = GNUNET_YES; + + /* Force to NOT cherry pick, otherwise they conflict. */ + cks->pull_all_keys = GNUNET_YES; + { + struct TALER_TESTING_Command cmd = { + .cls = cks, + .label = label, + .run = &check_keys_run, + .cleanup = &check_keys_cleanup + }; + + return cmd; + } +} + + +/** + * Make a "check keys" command that forcedly does NOT cherry pick; + * just redownload the whole /keys. Then checks whether the number + * of denomination keys from @a exchange matches @a num_denom_keys. + * + * @param label command label + * @param generation when this command is run, exactly @a + * generation /keys downloads took place. If the number + * of downloads is less than @a generation, the logic will + * first make sure that @a generation downloads are done, + * and _then_ execute the rest of the command. + * @param num_denom_keys expected number of denomination keys. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label, + unsigned int generation, + unsigned int num_denom_keys) +{ + struct CheckKeysState *cks; + + cks = GNUNET_new (struct CheckKeysState); + cks->generation = generation; + cks->num_denom_keys = num_denom_keys; + cks->pull_all_keys = GNUNET_YES; + { + struct TALER_TESTING_Command cmd = { + .cls = cks, + .label = label, + .run = &check_keys_run, + .cleanup = &check_keys_cleanup + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_check_keys.c */ -- cgit v1.2.3