merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit a635ebe25d24117b214ebde6d2d4f6e9abfafe54
parent 4bb0c9520f5c3b29f2edbeaced861bf94eda7655
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Sat, 10 Jan 2026 22:26:11 +0900

explicitly call donaukeyupdate instead of sleeping

Diffstat:
Msrc/include/taler_merchant_testing_lib.h | 160++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/testing/Makefile.am | 1+
Msrc/testing/test_merchant_api.c | 19+++++++++----------
Asrc/testing/testing_api_cmd_exec_donaukeyupdate.c | 160+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 256 insertions(+), 84 deletions(-)

diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h @@ -38,7 +38,7 @@ #define MERCHANT_FAIL() \ - do {GNUNET_break (0); return NULL; } while (0) + do {GNUNET_break (0); return NULL; } while (0) /** @@ -2248,6 +2248,18 @@ TALER_TESTING_cmd_merchant_get_statisticsamount (const char *label, uint64_t intervals_length, unsigned int http_status); + +/** + * Run the taler-merchant-donaukeyupdate command (with -t). + * + * @param label command label + * @param config_filename configuration file to pass to the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_exec_donaukeyupdate (const char *label, + const char *config_filename); + + /* ****** Specific traits supported by this component ******* */ @@ -2258,65 +2270,65 @@ TALER_TESTING_cmd_merchant_get_statisticsamount (const char *label, */ // FIXME: rename: refund_entry->refund_detail #define TALER_MERCHANT_TESTING_SIMPLE_TRAITS(op) \ - op (claim_nonce, const struct GNUNET_CRYPTO_EddsaPublicKey) \ - op (pickup_id, const struct TALER_PickupIdentifierP) \ - op (instance_name, const char) \ - op (instance_id, const char) \ - op (address, const json_t) \ - op (product_description, const char) \ - op (product_image, const char) \ - op (product_stock, const int64_t) \ - op (product_unit_total_stock, const char) \ - op (product_unit_precision_level, const uint32_t) \ - op (product_unit_allow_fraction, const bool) \ - op (product_unit, const char) \ - op (product_id, const char) \ - op (unit_id, const char) \ - op (unit_name_long, const char) \ - op (unit_name_short, const char) \ - op (unit_allow_fraction, const bool) \ - op (unit_precision_level, const uint32_t) \ - op (unit_active, const bool) \ - op (unit_builtin, const bool) \ - op (unit_name_long_i18n, const json_t) \ - op (unit_name_short_i18n, const json_t) \ - op (reason, const char) \ - op (lock_uuid, const char) \ - op (auth_token, const char) \ - op (bearer_token, const char) \ - op (paths_length, const uint32_t) \ - op (payto_length, const uint32_t) \ - op (num_planchets, const uint32_t) \ - op (i18n_description, const json_t) \ - op (taxes, const json_t) \ - op (fee, const struct TALER_Amount) \ - op (use_stefan, const bool) \ - op (jurisdiction, const json_t) \ - op (wire_delay, const struct GNUNET_TIME_Relative) \ - op (pay_delay, const struct GNUNET_TIME_Relative) \ - op (refund_entry, const struct TALER_MERCHANT_RefundDetail) \ - op (order_terms, const json_t) \ - op (h_contract_terms, const struct TALER_PrivateContractHashP) \ - op (h_wire, const struct TALER_MerchantWireHashP) \ - op (proposal_reference, const char) \ - op (template_description, const char) \ - op (otp_device_description, const char) \ - op (otp_id, const char) \ - op (otp_key, const char) \ - op (otp_alg, const enum TALER_MerchantConfirmationAlgorithm) \ - op (template_id, const char) \ - op (template_contract, const json_t) \ - op (event_type, const char) \ - op (webhook_id, const char) \ - op (merchant_base_url, const char) \ - op (url, const char) \ - op (http_method, const char) \ - op (header_template, const char) \ - op (body_template, const char) \ - op (summary, const char) \ - op (token_family_slug, const char) \ - op (token_family_duration, const struct GNUNET_TIME_Relative) \ - op (token_family_kind, const char) + op (claim_nonce, const struct GNUNET_CRYPTO_EddsaPublicKey) \ + op (pickup_id, const struct TALER_PickupIdentifierP) \ + op (instance_name, const char) \ + op (instance_id, const char) \ + op (address, const json_t) \ + op (product_description, const char) \ + op (product_image, const char) \ + op (product_stock, const int64_t) \ + op (product_unit_total_stock, const char) \ + op (product_unit_precision_level, const uint32_t) \ + op (product_unit_allow_fraction, const bool) \ + op (product_unit, const char) \ + op (product_id, const char) \ + op (unit_id, const char) \ + op (unit_name_long, const char) \ + op (unit_name_short, const char) \ + op (unit_allow_fraction, const bool) \ + op (unit_precision_level, const uint32_t) \ + op (unit_active, const bool) \ + op (unit_builtin, const bool) \ + op (unit_name_long_i18n, const json_t) \ + op (unit_name_short_i18n, const json_t) \ + op (reason, const char) \ + op (lock_uuid, const char) \ + op (auth_token, const char) \ + op (bearer_token, const char) \ + op (paths_length, const uint32_t) \ + op (payto_length, const uint32_t) \ + op (num_planchets, const uint32_t) \ + op (i18n_description, const json_t) \ + op (taxes, const json_t) \ + op (fee, const struct TALER_Amount) \ + op (use_stefan, const bool) \ + op (jurisdiction, const json_t) \ + op (wire_delay, const struct GNUNET_TIME_Relative) \ + op (pay_delay, const struct GNUNET_TIME_Relative) \ + op (refund_entry, const struct TALER_MERCHANT_RefundDetail) \ + op (order_terms, const json_t) \ + op (h_contract_terms, const struct TALER_PrivateContractHashP) \ + op (h_wire, const struct TALER_MerchantWireHashP) \ + op (proposal_reference, const char) \ + op (template_description, const char) \ + op (otp_device_description, const char) \ + op (otp_id, const char) \ + op (otp_key, const char) \ + op (otp_alg, const enum TALER_MerchantConfirmationAlgorithm) \ + op (template_id, const char) \ + op (template_contract, const json_t) \ + op (event_type, const char) \ + op (webhook_id, const char) \ + op (merchant_base_url, const char) \ + op (url, const char) \ + op (http_method, const char) \ + op (header_template, const char) \ + op (body_template, const char) \ + op (summary, const char) \ + op (token_family_slug, const char) \ + op (token_family_duration, const struct GNUNET_TIME_Relative) \ + op (token_family_kind, const char) /** @@ -2325,20 +2337,20 @@ TALER_TESTING_cmd_merchant_get_statisticsamount (const char *label, * @param op macro to call */ #define TALER_MERCHANT_TESTING_INDEXED_TRAITS(op) \ - op (coin_reference, const char) \ - op (paths, const char) \ - op (payto_uris, const struct TALER_FullPayto) \ - op (h_wires, const struct TALER_MerchantWireHashP) \ - op (amounts, const struct TALER_Amount) \ - op (urls, const char) \ - op (http_methods, const char) \ - op (http_header, const char) \ - op (http_body, const void) \ - op (http_body_size, const size_t) \ - op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ - op (token_priv, const struct TALER_TokenUsePrivateKeyP) \ - op (token_issue_sig, const struct TALER_TokenIssueSignature) \ - op (token_issue_pub, const struct TALER_TokenIssuePublicKey) + op (coin_reference, const char) \ + op (paths, const char) \ + op (payto_uris, const struct TALER_FullPayto) \ + op (h_wires, const struct TALER_MerchantWireHashP) \ + op (amounts, const struct TALER_Amount) \ + op (urls, const char) \ + op (http_methods, const char) \ + op (http_header, const char) \ + op (http_body, const void) \ + op (http_body_size, const size_t) \ + op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ + op (token_priv, const struct TALER_TokenUsePrivateKeyP) \ + op (token_issue_sig, const struct TALER_TokenIssueSignature) \ + op (token_issue_pub, const struct TALER_TokenIssuePublicKey) TALER_MERCHANT_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT) diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am @@ -59,6 +59,7 @@ libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_delete_unit.c \ testing_api_cmd_delete_webhook.c \ testing_api_cmd_delete_transfer.c \ + testing_api_cmd_exec_donaukeyupdate.c \ testing_api_cmd_forget_order.c \ testing_api_cmd_kyc_get.c \ testing_api_cmd_lock_product.c \ diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c @@ -2189,7 +2189,7 @@ run (void *cls, TALER_TESTING_cmd_end () }; - #ifdef HAVE_DONAU_DONAU_SERVICE_H +#ifdef HAVE_DONAU_DONAU_SERVICE_H const struct DONAU_BearerToken bearer = { .token = NULL }; @@ -2199,7 +2199,7 @@ run (void *cls, "donau", TALER_TESTING_cmd_get_donau ("get-donau", cred.cfg, - true)), + true /* wait for response */)), TALER_TESTING_cmd_charity_post_merchant ("post-charity", "example", "example.com", @@ -2231,9 +2231,8 @@ run (void *cls, merchant_url, 1, MHD_HTTP_OK), - TALER_TESTING_cmd_sleep ( - "In this time donaukeyupdate must fetch the keys from the donau", - 1), + TALER_TESTING_cmd_exec_donaukeyupdate ("run-merchant-donaukeyupdate", + config_file), TALER_TESTING_cmd_merchant_get_donau_instances ( "get-donau-instance", merchant_url, @@ -2276,7 +2275,7 @@ run (void *cls, MHD_HTTP_OK), TALER_TESTING_cmd_end () }; - #endif +#endif struct TALER_TESTING_Command commands[] = { /* general setup */ @@ -2284,15 +2283,15 @@ run (void *cls, "run-fakebank", cred.cfg, "exchange-account-exchange"), - #ifdef HAVE_DONAU_DONAU_SERVICE_H +#ifdef HAVE_DONAU_DONAU_SERVICE_H TALER_TESTING_cmd_system_start ( "start-taler", config_file, - "-emaDZ", + "-emaD", "-u", "exchange-account-exchange", "-r", "merchant-exchange-test", NULL), - #else +#else TALER_TESTING_cmd_system_start ( "start-taler", config_file, @@ -2300,7 +2299,7 @@ run (void *cls, "-u", "exchange-account-exchange", "-r", "merchant-exchange-test", NULL), - #endif +#endif TALER_TESTING_cmd_get_exchange ( "get-exchange", cred.cfg, diff --git a/src/testing/testing_api_cmd_exec_donaukeyupdate.c b/src/testing/testing_api_cmd_exec_donaukeyupdate.c @@ -0,0 +1,160 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 testing/testing_api_cmd_exec_donaukeyupdate.c + * @brief run the taler-merchant-donaukeyupdate command + * @author Christian Grothoff + */ +#include "platform.h" +#include <taler/taler_json_lib.h> +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler_signatures.h> +#include "taler_merchant_testing_lib.h" + + +/** + * State for a "donaukeyupdate" CMD. + */ +struct DonaukeyupdateState +{ + + /** + * Donaukeyupdate process. + */ + struct GNUNET_OS_Process *donaukeyupdate_proc; + + /** + * Configuration file used by the donaukeyupdate. + */ + const char *config_filename; +}; + + +/** + * Run the command. Use the `taler-merchant-donaukeyupdate` program. + * + * @param cls closure. + * @param cmd command being run. + * @param is interpreter state. + */ +static void +donaukeyupdate_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct DonaukeyupdateState *as = cls; + + (void) cmd; + as->donaukeyupdate_proc + = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL, + NULL, NULL, NULL, + "taler-merchant-donaukeyupdate", + "taler-merchant-donaukeyupdate", + "-c", as->config_filename, + "-L", "INFO", + "-t", /* exit when done */ + NULL); + if (NULL == as->donaukeyupdate_proc) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Free the state of a "donaukeyupdate" CMD, and possibly kill its + * process if it did not terminate correctly. + * + * @param cls closure. + * @param cmd the command being freed. + */ +static void +donaukeyupdate_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct DonaukeyupdateState *as = cls; + + (void) cmd; + if (NULL != as->donaukeyupdate_proc) + { + GNUNET_break (0 == + GNUNET_OS_process_kill (as->donaukeyupdate_proc, + SIGKILL)); + GNUNET_OS_process_wait (as->donaukeyupdate_proc); + GNUNET_OS_process_destroy (as->donaukeyupdate_proc); + as->donaukeyupdate_proc = NULL; + } + GNUNET_free (as); +} + + +/** + * Offer "donaukeyupdate" CMD internal data to other commands. + * + * @param cls closure. + * @param[out] ret result. + * @param trait name of the trait. + * @param index index number of the object to offer. + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +donaukeyupdate_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct DonaukeyupdateState *as = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_process (&as->donaukeyupdate_proc), + TALER_TESTING_trait_end () + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_exec_donaukeyupdate (const char *label, + const char *config_filename) +{ + struct DonaukeyupdateState *as; + + as = GNUNET_new (struct DonaukeyupdateState); + as->config_filename = config_filename; + { + struct TALER_TESTING_Command cmd = { + .cls = as, + .label = label, + .run = &donaukeyupdate_run, + .cleanup = &donaukeyupdate_cleanup, + .traits = &donaukeyupdate_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_exec_donaukeyupdate.c */