summaryrefslogtreecommitdiff
path: root/src/bank-lib
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-01-12 20:44:33 +0100
committerChristian Grothoff <christian@grothoff.org>2020-01-12 20:44:33 +0100
commit1788ca2be11b92f9c92d8b7ad31383f663608ac0 (patch)
tree92e5159f5ea21e802c6dcc5a5ff38c4e186337f3 /src/bank-lib
parentc75157e8caae542845cce2f9ff967d2b3943ea56 (diff)
downloadexchange-1788ca2be11b92f9c92d8b7ad31383f663608ac0.tar.gz
exchange-1788ca2be11b92f9c92d8b7ad31383f663608ac0.tar.bz2
exchange-1788ca2be11b92f9c92d8b7ad31383f663608ac0.zip
reorganization of file structure
Diffstat (limited to 'src/bank-lib')
-rw-r--r--src/bank-lib/Makefile.am88
-rw-r--r--src/bank-lib/bank.conf13
-rw-r--r--src/bank-lib/bank_twisted.conf39
-rw-r--r--src/bank-lib/test_bank_api_twisted.c222
-rw-r--r--src/bank-lib/testing_api_cmd_admin_add_incoming.c609
-rw-r--r--src/bank-lib/testing_api_cmd_history_credit.c765
-rw-r--r--src/bank-lib/testing_api_cmd_history_debit.c766
-rw-r--r--src/bank-lib/testing_api_cmd_transfer.c394
-rw-r--r--src/bank-lib/testing_api_helpers.c361
9 files changed, 1 insertions, 3256 deletions
diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am
index 76c85eac4..35af78262 100644
--- a/src/bank-lib/Makefile.am
+++ b/src/bank-lib/Makefile.am
@@ -30,8 +30,7 @@ taler_bank_transfer_LDADD = \
lib_LTLIBRARIES = \
libtalerbank.la \
- libtalerfakebank.la \
- libtalerbanktesting.la
+ libtalerfakebank.la
libtalerbank_la_LDFLAGS = \
-version-info 1:0:0 \
@@ -66,24 +65,6 @@ libtalerfakebank_la_LIBADD = \
-lmicrohttpd \
$(XLIB)
-libtalerbanktesting_la_LDFLAGS = \
- -version-info 0:0:0 \
- -no-undefined
-libtalerbanktesting_la_SOURCES = \
- testing_api_cmd_admin_add_incoming.c \
- testing_api_cmd_history_credit.c \
- testing_api_cmd_history_debit.c \
- testing_api_cmd_transfer.c \
- testing_api_helpers.c
-libtalerbanktesting_la_LIBADD = \
- libtalerbank.la \
- $(top_builddir)/src/json/libtalerjson.la \
- -lgnunetjson \
- -lgnunetutil \
- -ljansson \
- -lmicrohttpd \
- $(XLIB)
-
if HAVE_LIBCURL
libtalerbank_la_LIBADD += -lcurl
else
@@ -91,70 +72,3 @@ if HAVE_LIBGNURL
libtalerbank_la_LIBADD += -lgnurl
endif
endif
-
-check_PROGRAMS = \
- test_bank_api_with_fakebank \
- test_bank_api_with_pybank
-
-if HAVE_TWISTER
-check_PROGRAMS += \
- test_bank_api_with_pybank_twisted \
- test_bank_api_with_fakebank_twisted
-
-
-test_bank_api_with_pybank_twisted_SOURCES = \
- test_bank_api_twisted.c
-test_bank_api_with_pybank_twisted_LDADD = \
- $(top_builddir)/src/lib/libtalertesting.la \
- libtalerbank.la \
- libtalerbanktesting.la \
- libtalerfakebank.la \
- $(top_builddir)/src/lib/libtalerexchange.la \
- $(top_builddir)/src/json/libtalerjson.la \
- -ltalertwistertesting \
- -lgnunetjson \
- -lgnunetcurl \
- -lgnunetutil \
- -ljansson
-
-
-test_bank_api_with_fakebank_twisted_SOURCES = \
- test_bank_api_twisted.c
-test_bank_api_with_fakebank_twisted_LDADD = \
- $(top_builddir)/src/lib/libtalertesting.la \
- libtalerbank.la \
- libtalerbanktesting.la \
- libtalerfakebank.la \
- $(top_builddir)/src/lib/libtalerexchange.la \
- $(top_builddir)/src/json/libtalerjson.la \
- -ltalertwistertesting \
- -lgnunetjson \
- -lgnunetcurl \
- -lgnunetutil \
- -ljansson
-endif
-
-TESTS = \
- $(check_PROGRAMS)
-
-test_bank_api_with_pybank_SOURCES = \
- test_bank_api.c
-test_bank_api_with_pybank_LDADD = \
- $(top_builddir)/src/lib/libtalertesting.la \
- libtalerbanktesting.la \
- -ltalerexchange \
- -lgnunetutil \
- libtalerbank.la
-
-test_bank_api_with_fakebank_SOURCES = \
- test_bank_api.c
-test_bank_api_with_fakebank_LDADD = \
- $(top_builddir)/src/lib/libtalertesting.la \
- libtalerbanktesting.la \
- -ltalerexchange \
- -lgnunetutil \
- libtalerbank.la
-
-EXTRA_DIST = \
- bank.conf \
- bank_twisted.conf
diff --git a/src/bank-lib/bank.conf b/src/bank-lib/bank.conf
deleted file mode 100644
index 906b95fc5..000000000
--- a/src/bank-lib/bank.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-[taler]
-currency = KUDOS
-
-[account-1]
-URL = payto://x-taler-bank/localhost:8081/1
-
-[bank]
-SERVE = http
-HTTP_PORT = 8081
-DATABASE = postgres:///talercheck
-
-[exchange-wire-test]
-bank_url = http://localhost:8081/
diff --git a/src/bank-lib/bank_twisted.conf b/src/bank-lib/bank_twisted.conf
deleted file mode 100644
index 71bcaee00..000000000
--- a/src/bank-lib/bank_twisted.conf
+++ /dev/null
@@ -1,39 +0,0 @@
-
-[twister]
-# HTTP listen port for twister
-HTTP_PORT = 8888
-SERVE = tcp
-
-# HTTP Destination for twister. The test-Webserver needs
-# to listen on the port used here. Note: no trailing '/'!
-DESTINATION_BASE_URL = "http://localhost:8081"
-
-# Control port for TCP
-# PORT = 8889
-HOSTNAME = localhost
-ACCEPT_FROM = 127.0.0.1;
-ACCEPT_FROM6 = ::1;
-
-# Control port for UNIX
-UNIXPATH = /tmp/taler-service-twister.sock
-UNIX_MATCH_UID = NO
-UNIX_MATCH_GID = YES
-
-# Launching of twister by ARM
-# BINARY = taler-service-twister
-# AUTOSTART = NO
-# FORCESTART = NO
-
-[taler]
-currency = KUDOS
-
-[bank]
-serve = http
-http_port = 8081
-database = postgres:///talercheck
-
-[account-1]
-URL = payto://x-taler-bank/localhost:8081/1
-
-[exchange-wire-test]
-bank_url = http://localhost:8081/
diff --git a/src/bank-lib/test_bank_api_twisted.c b/src/bank-lib/test_bank_api_twisted.c
deleted file mode 100644
index ad8fd71d4..000000000
--- a/src/bank-lib/test_bank_api_twisted.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- 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 exchange/test_bank_api_with_fakebank_twisted.c
- * @author Marcello Stanisci
- * @author Sree Harsha Totakura <sreeharsha@totakura.in>
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_util.h"
-#include "taler_signatures.h"
-#include "taler_exchange_service.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler_bank_service.h"
-#include "taler_fakebank_lib.h"
-#include "taler_testing_lib.h"
-#include <taler/taler_twister_testing_lib.h>
-#include "taler_testing_bank_lib.h"
-#include <taler/taler_twister_service.h>
-
-/**
- * Configuration file we use. One (big) configuration is used
- * for the various components for this test.
- */
-#define CONFIG_FILE "bank_twisted.conf"
-
-/**
- * True when the test runs against Fakebank.
- */
-static int with_fakebank;
-
-/**
- * (real) Twister URL. Used at startup time to check if it runs.
- */
-static char *twister_url;
-
-/**
- * Account URL of the twister where all the connections to the
- * bank that have to be proxied should be addressed to.
- */
-static char *twisted_account_url;
-
-/**
- * Authentication data to use.
- */
-static struct TALER_BANK_AuthenticationData auth;
-
-/**
- * URL of the bank.
- */
-static char *bank_url;
-
-/**
- * Twister process.
- */
-static struct GNUNET_OS_Process *twisterd;
-
-/**
- * Python bank process handle.
- */
-static struct GNUNET_OS_Process *bankd;
-
-
-/**
- * Main function that will tell
- * the interpreter what commands to run.
- *
- * @param cls closure
- */
-static void
-run (void *cls,
- struct TALER_TESTING_Interpreter *is)
-{
- struct TALER_TESTING_Command commands[] = {
- /**
- * Can't use the "wait service" CMD here because the
- * fakebank runs inside the same process of the test.
- */
- TALER_TESTING_cmd_wait_service ("wait-service",
- twister_url),
- TALER_TESTING_cmd_bank_credits ("history-0",
- twisted_account_url,
- &auth,
- NULL,
- 5),
- TALER_TESTING_cmd_end ()
- };
-
- GNUNET_asprintf (&twisted_account_url,
- "%s/%s",
- twister_url,
- "alice");
- // FIXME: init 'auth'!
- if (GNUNET_YES == with_fakebank)
- TALER_TESTING_run_with_fakebank (is,
- commands,
- bank_url);
- else
- TALER_TESTING_run (is,
- commands);
-}
-
-
-/**
- * Kill, wait, and destroy convenience function.
- *
- * @param process process to purge.
- */
-static void
-purge_process (struct GNUNET_OS_Process *process)
-{
- GNUNET_OS_process_kill (process, SIGINT);
- GNUNET_OS_process_wait (process);
- GNUNET_OS_process_destroy (process);
-}
-
-
-int
-main (int argc,
- char *const *argv)
-{
- unsigned int ret;
-
- /* These environment variables get in the way... */
- unsetenv ("XDG_DATA_HOME");
- unsetenv ("XDG_CONFIG_HOME");
- GNUNET_log_setup ("test-bank-api-with-(fake)bank-twisted",
- "DEBUG",
- NULL);
- if (NULL == (twister_url = TALER_TESTING_prepare_twister
- (CONFIG_FILE)))
- {
- GNUNET_break (0);
- return 77;
- }
- if (NULL == (twisterd = TALER_TESTING_run_twister (CONFIG_FILE)))
- {
- GNUNET_break (0);
- GNUNET_free (twister_url);
- return 77;
- }
-
- with_fakebank = TALER_TESTING_has_in_name (argv[0],
- "_with_fakebank");
-
- if (GNUNET_YES == with_fakebank)
- {
- TALER_LOG_DEBUG ("Running against the Fakebank.\n");
- if (NULL == (bank_url = TALER_TESTING_prepare_fakebank
- (CONFIG_FILE,
- "account-1")))
- {
- GNUNET_break (0);
- GNUNET_free (twister_url);
- return 77;
- }
- }
- else
- {
- TALER_LOG_DEBUG ("Running against the Pybank.\n");
- if (NULL == (bank_url = TALER_TESTING_prepare_bank
- (CONFIG_FILE)))
- {
- GNUNET_break (0);
- GNUNET_free (twister_url);
- return 77;
- }
-
- if (NULL == (bankd = TALER_TESTING_run_bank (CONFIG_FILE,
- bank_url)))
- {
- GNUNET_break (0);
- GNUNET_free (twister_url);
- GNUNET_free (bank_url);
- return 77;
- }
- }
-
- ret = TALER_TESTING_setup (&run,
- NULL,
- CONFIG_FILE,
- NULL,
- GNUNET_NO);
- purge_process (twisterd);
-
- if (GNUNET_NO == with_fakebank)
- {
- GNUNET_OS_process_kill (bankd,
- SIGKILL);
- GNUNET_OS_process_wait (bankd);
- GNUNET_OS_process_destroy (bankd);
- }
-
- GNUNET_free (twister_url);
- GNUNET_free (bank_url);
-
- if (GNUNET_OK == ret)
- return 0;
-
- return 1;
-}
-
-
-/* end of test_bank_api_twisted.c */
diff --git a/src/bank-lib/testing_api_cmd_admin_add_incoming.c b/src/bank-lib/testing_api_cmd_admin_add_incoming.c
deleted file mode 100644
index 770b2e384..000000000
--- a/src/bank-lib/testing_api_cmd_admin_add_incoming.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2018-2020 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 exchange-lib/testing_api_cmd_admin_add_incoming.c
- * @brief implementation of a bank /admin/add-incoming command
- * @author Christian Grothoff
- * @author Marcello Stanisci
- */
-#include "platform.h"
-#include "backoff.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_bank_service.h"
-#include "taler_fakebank_lib.h"
-#include "taler_signatures.h"
-#include "taler_testing_lib.h"
-#include "taler_testing_bank_lib.h"
-
-
-/**
- * State for a "fakebank transfer" CMD.
- */
-struct AdminAddIncomingState
-{
-
- /**
- * Label of any command that can trait-offer a reserve priv.
- */
- const char *reserve_reference;
-
- /**
- * Wire transfer amount.
- */
- struct TALER_Amount amount;
-
- /**
- * Base URL of the credited account.
- */
- const char *exchange_credit_url;
-
- /**
- * Money sender account URL.
- */
- const char *payto_debit_account;
-
- /**
- * Username to use for authentication.
- */
- struct TALER_BANK_AuthenticationData auth;
-
- /**
- * Set (by the interpreter) to the reserve's private key
- * we used to make a wire transfer subject line with.
- */
- struct TALER_ReservePrivateKeyP reserve_priv;
-
- /**
- * Reserve public key matching @e reserve_priv.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * Handle to the pending request at the fakebank.
- */
- struct TALER_BANK_AdminAddIncomingHandle *aih;
-
- /**
- * Interpreter state.
- */
- struct TALER_TESTING_Interpreter *is;
-
- /**
- * Set to the wire transfer's unique ID.
- */
- uint64_t serial_id;
-
- /**
- * Timestamp of the transaction (as returned from the bank).
- */
- struct GNUNET_TIME_Absolute timestamp;
-
- /**
- * Merchant instance. Sometimes used to get the tip reserve
- * private key by reading the appropriate config section.
- */
- const char *instance;
-
- /**
- * Configuration filename. Used to get the tip reserve key
- * filename (used to obtain a public key to write in the
- * transfer subject).
- */
- const char *config_filename;
-
- /**
- * Task scheduled to try later.
- */
- struct GNUNET_SCHEDULER_Task *retry_task;
-
- /**
- * How long do we wait until we retry?
- */
- struct GNUNET_TIME_Relative backoff;
-
- /**
- * Was this command modified via
- * #TALER_TESTING_cmd_admin_add_incoming_with_retry to
- * enable retries?
- */
- int do_retry;
-};
-
-
-/**
- * Run the "fakebank transfer" CMD.
- *
- * @param cls closure.
- * @param cmd CMD being run.
- * @param is interpreter state.
- */
-static void
-admin_add_incoming_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is);
-
-
-/**
- * Task scheduled to re-try #admin_add_incoming_run.
- *
- * @param cls a `struct AdminAddIncomingState`
- */
-static void
-do_retry (void *cls)
-{
- struct AdminAddIncomingState *fts = cls;
-
- fts->retry_task = NULL;
- admin_add_incoming_run (fts,
- NULL,
- fts->is);
-}
-
-
-/**
- * This callback will process the fakebank response to the wire
- * transfer. It just checks whether the HTTP response code is
- * acceptable.
- *
- * @param cls closure with the interpreter state
- * @param http_status HTTP response code, #MHD_HTTP_OK (200) for
- * successful status request; 0 if the exchange's reply is
- * bogus (fails to follow the protocol)
- * @param ec taler-specific error code, #TALER_EC_NONE on success
- * @param serial_id unique ID of the wire transfer
- * @param timestamp time stamp of the transaction made.
- * @param json raw response
- */
-static void
-confirmation_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- uint64_t serial_id,
- struct GNUNET_TIME_Absolute timestamp,
- const json_t *json)
-{
- struct AdminAddIncomingState *fts = cls;
- struct TALER_TESTING_Interpreter *is = fts->is;
-
- fts->aih = NULL;
- if (MHD_HTTP_OK != http_status)
- {
- if (GNUNET_YES == fts->do_retry)
- {
- if ( (0 == http_status) ||
- (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) ||
- (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) )
- {
- GNUNET_log
- (GNUNET_ERROR_TYPE_INFO,
- "Retrying fakebank transfer failed with %u/%d\n",
- http_status,
- (int) ec);
- /* on DB conflicts, do not use backoff */
- if (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec)
- fts->backoff = GNUNET_TIME_UNIT_ZERO;
- else
- fts->backoff = EXCHANGE_LIB_BACKOFF (fts->backoff);
- fts->retry_task = GNUNET_SCHEDULER_add_delayed
- (fts->backoff,
- &do_retry,
- fts);
- return;
- }
- }
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Fakebank returned HTTP status %u/%d\n",
- http_status,
- (int) ec);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
-
- fts->serial_id = serial_id;
- fts->timestamp = timestamp;
- TALER_TESTING_interpreter_next (is);
-}
-
-
-/**
- * Run the "fakebank transfer" CMD.
- *
- * @param cls closure.
- * @param cmd CMD being run.
- * @param is interpreter state.
- */
-static void
-admin_add_incoming_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct AdminAddIncomingState *fts = cls;
-
- /* Use reserve public key as subject */
- if (NULL != fts->reserve_reference)
- {
- const struct TALER_TESTING_Command *ref;
- const struct TALER_ReservePrivateKeyP *reserve_priv;
-
- ref = TALER_TESTING_interpreter_lookup_command
- (is, fts->reserve_reference);
- if (NULL == ref)
- {
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
- if (GNUNET_OK !=
- TALER_TESTING_get_trait_reserve_priv (ref,
- 0,
- &reserve_priv))
- {
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
- fts->reserve_priv.eddsa_priv = reserve_priv->eddsa_priv;
- }
- else
- {
- if (NULL != fts->instance)
- {
- char *section;
- char *keys;
- struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
- struct GNUNET_CONFIGURATION_Handle *cfg;
-
- GNUNET_assert (NULL != fts->config_filename);
- cfg = GNUNET_CONFIGURATION_create ();
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_load (cfg,
- fts->config_filename))
- {
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
-
- GNUNET_asprintf (&section,
- "instance-%s",
- fts->instance);
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename
- (cfg,
- section,
- "TIP_RESERVE_PRIV_FILENAME",
- &keys))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Configuration fails to specify reserve"
- " private key filename in section %s\n",
- section);
- GNUNET_free (section);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
- priv = GNUNET_CRYPTO_eddsa_key_create_from_file (keys);
- GNUNET_free (keys);
- if (NULL == priv)
- {
- GNUNET_log_config_invalid
- (GNUNET_ERROR_TYPE_ERROR,
- section,
- "TIP_RESERVE_PRIV_FILENAME",
- "Failed to read private key");
- GNUNET_free (section);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
- fts->reserve_priv.eddsa_priv = *priv;
- GNUNET_free (section);
- GNUNET_free (priv);
- GNUNET_CONFIGURATION_destroy (cfg);
- }
- else
- {
- /* No referenced reserve, no instance to take priv
- * from, no explicit subject given: create new key! */
- struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
-
- priv = GNUNET_CRYPTO_eddsa_key_create ();
- fts->reserve_priv.eddsa_priv = *priv;
- GNUNET_free (priv);
- }
- }
- GNUNET_CRYPTO_eddsa_key_get_public (&fts->reserve_priv.eddsa_priv,
- &fts->reserve_pub.eddsa_pub);
- fts->is = is;
- fts->aih
- = TALER_BANK_admin_add_incoming
- (TALER_TESTING_interpreter_get_context (is),
- fts->exchange_credit_url,
- &fts->auth,
- &fts->reserve_pub,
- &fts->amount,
- fts->payto_debit_account,
- &confirmation_cb,
- fts);
- if (NULL == fts->aih)
- {
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
-}
-
-
-/**
- * Free the state of a "/admin/add-incoming" CMD, and possibly
- * cancel a pending operation thereof.
- *
- * @param cls closure
- * @param cmd current CMD being cleaned up.
- */
-static void
-admin_add_incoming_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct AdminAddIncomingState *fts = cls;
-
- if (NULL != fts->aih)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Command %s did not complete\n",
- cmd->label);
- TALER_BANK_admin_add_incoming_cancel (fts->aih);
- fts->aih = NULL;
- }
- if (NULL != fts->retry_task)
- {
- GNUNET_SCHEDULER_cancel (fts->retry_task);
- fts->retry_task = NULL;
- }
- GNUNET_free (fts);
-}
-
-
-/**
- * Offer internal data from a "/admin/add-incoming" 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
-admin_add_incoming_traits (void *cls,
- const void **ret,
- const char *trait,
- unsigned int index)
-{
- struct AdminAddIncomingState *fts = cls;
- struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_url (1, fts->payto_debit_account),
- TALER_TESTING_MAKE_TRAIT_ROW_ID (&fts->serial_id),
- TALER_TESTING_MAKE_TRAIT_CREDIT_ACCOUNT (fts->exchange_credit_url),
- TALER_TESTING_make_trait_amount_obj (0, &fts->amount),
- TALER_TESTING_make_trait_absolute_time (0, &fts->timestamp),
- TALER_TESTING_make_trait_reserve_priv (0,
- &fts->reserve_priv),
- TALER_TESTING_make_trait_reserve_pub (0,
- &fts->reserve_pub),
- TALER_TESTING_trait_end ()
- };
-
- return TALER_TESTING_get_trait (traits,
- ret,
- trait,
- index);
-}
-
-
-/**
- * Create admin/add-incoming command.
- *
- * @param label command label.
- * @param amount amount to transfer.
- * @param exchange_base_url base URL of the account that receives this
- * wire transer (which account receives money).
- * @param payto_debit_account which account sends money.
- * @param auth authentication data
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_admin_add_incoming
- (const char *label,
- const char *amount,
- const char *exchange_base_url,
- const struct TALER_BANK_AuthenticationData *auth,
- const char *payto_debit_account)
-{
- struct AdminAddIncomingState *fts;
-
- fts = GNUNET_new (struct AdminAddIncomingState);
- fts->exchange_credit_url = exchange_base_url;
- fts->payto_debit_account = payto_debit_account;
- fts->auth = *auth;
- if (GNUNET_OK !=
- TALER_string_to_amount (amount,
- &fts->amount))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to parse amount `%s' at %s\n",
- amount,
- label);
- GNUNET_assert (0);
- }
-
- {
- struct TALER_TESTING_Command cmd = {
- .cls = fts,
- .label = label,
- .run = &admin_add_incoming_run,
- .cleanup = &admin_add_incoming_cleanup,
- .traits = &admin_add_incoming_traits
- };
-
- return cmd;
- }
-}
-
-
-/**
- * Create "/admin/add-incoming" CMD, letting the caller specify
- * a reference to a command that can offer a reserve private key.
- * This private key will then be used to construct the subject line
- * of the wire transfer.
- *
- * @param label command label.
- * @param amount the amount to transfer.
- * @param account_bank_url base URL of the exchange account receiving the money
- * @param payto_debit_account which account sends money
- * @param auth authentication data
- * @param ref reference to a command that can offer a reserve
- * private key.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_admin_add_incoming_with_ref
- (const char *label,
- const char *amount,
- const char *account_base_url,
- const struct TALER_BANK_AuthenticationData *auth,
- const char *payto_debit_account,
- const char *ref)
-{
- struct AdminAddIncomingState *fts;
-
- fts = GNUNET_new (struct AdminAddIncomingState);
- fts->exchange_credit_url = account_base_url;
- fts->payto_debit_account = payto_debit_account;
- fts->auth = *auth;
- fts->reserve_reference = ref;
- if (GNUNET_OK !=
- TALER_string_to_amount (amount,
- &fts->amount))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to parse amount `%s' at %s\n",
- amount,
- label);
- GNUNET_assert (0);
- }
- {
- struct TALER_TESTING_Command cmd = {
- .cls = fts,
- .label = label,
- .run = &admin_add_incoming_run,
- .cleanup = &admin_add_incoming_cleanup,
- .traits = &admin_add_incoming_traits
- };
-
- return cmd;
- }
-}
-
-
-/**
- * Create "/admin/add-incoming" CMD, letting the caller specifying
- * the merchant instance. This version is useful when a tip
- * reserve should be topped up, in fact the interpreter will need
- * the "tipping instance" in order to get the instance public key
- * and make a wire transfer subject out of it.
- *
- * @param label command label.
- * @param amount amount to transfer.
- * @param account_bank_url base URL of the exchange bank account
- * that receives the wire transfer
- * @param payto_debit_account which account (expressed as a number)
- * gives money
- * @param auth authentication data
- * @param instance the instance that runs the tipping. Under this
- * instance, the configuration file will provide the private
- * key of the tipping reserve. This data will then used to
- * construct the wire transfer subject line.
- * @param config_filename configuration file to use.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_admin_add_incoming_with_instance
- (const char *label,
- const char *amount,
- const char *account_base_url,
- const struct TALER_BANK_AuthenticationData *auth,
- const char *payto_debit_account,
- const char *instance,
- const char *config_filename)
-{
- struct AdminAddIncomingState *fts;
-
- fts = GNUNET_new (struct AdminAddIncomingState);
- fts->exchange_credit_url = account_base_url;
- fts->payto_debit_account = payto_debit_account;
- fts->auth = *auth;
- fts->instance = instance;
- fts->config_filename = config_filename;
- if (GNUNET_OK !=
- TALER_string_to_amount (amount,
- &fts->amount))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to parse amount `%s' at %s\n",
- amount,
- label);
- GNUNET_assert (0);
- }
- {
- struct TALER_TESTING_Command cmd = {
- .cls = fts,
- .label = label,
- .run = &admin_add_incoming_run,
- .cleanup = &admin_add_incoming_cleanup,
- .traits = &admin_add_incoming_traits
- };
-
- return cmd;
- }
-}
-
-
-/**
- * Modify a fakebank transfer command to enable retries when the
- * reserve is not yet full or we get other transient errors from the
- * fakebank.
- *
- * @param cmd a fakebank transfer command
- * @return the command with retries enabled
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_admin_add_incoming_retry (struct TALER_TESTING_Command cmd)
-{
- struct AdminAddIncomingState *fts;
-
- GNUNET_assert (&admin_add_incoming_run == cmd.run);
- fts = cmd.cls;
- fts->do_retry = GNUNET_YES;
- return cmd;
-}
-
-
-/* end of testing_api_cmd_admin_add_incoming.c */
diff --git a/src/bank-lib/testing_api_cmd_history_credit.c b/src/bank-lib/testing_api_cmd_history_credit.c
deleted file mode 100644
index fefb2dda7..000000000
--- a/src/bank-lib/testing_api_cmd_history_credit.c
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2018-2020 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 bank-lib/testing_api_cmd_history.c
- * @brief command to check the /history API from the bank.
- * @author Marcello Stanisci
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_testing_lib.h"
-#include "taler_testing_bank_lib.h"
-#include "taler_fakebank_lib.h"
-#include "taler_bank_service.h"
-#include "taler_fakebank_lib.h"
-
-
-/**
- * State for a "history" CMD.
- */
-struct HistoryState
-{
- /**
- * Base URL of the account offering the "history" operation.
- */
- char *account_url;
-
- /**
- * Reference to command defining the
- * first row number we want in the result.
- */
- const char *start_row_reference;
-
- /**
- * How many rows we want in the result, _at most_,
- * and ascending/descending.
- */
- long long num_results;
-
- /**
- * Handle to a pending "history" operation.
- */
- struct TALER_BANK_CreditHistoryHandle *hh;
-
- /**
- * Authentication data for the operation.
- */
- struct TALER_BANK_AuthenticationData auth;
-
- /**
- * Expected number of results (= rows).
- */
- uint64_t results_obtained;
-
- /**
- * Set to GNUNET_YES if the callback detects something
- * unexpected.
- */
- int failed;
-
-};
-
-
-/**
- * Item in the transaction history, as reconstructed from the
- * command history.
- */
-struct History
-{
-
- /**
- * Wire details.
- */
- struct TALER_BANK_CreditDetails details;
-
- /**
- * Serial ID of the wire transfer.
- */
- uint64_t row_id;
-
- /**
- * URL to free.
- */
- char *url;
-};
-
-
-/**
- * Offer internal data to other commands.
- *
- * @param cls closure.
- * @param ret[out] set to the wanted data.
- * @param trait name of the trait.
- * @param index index number of the traits to be returned.
- *
- * @return #GNUNET_OK on success
- */
-static int
-history_traits (void *cls,
- const void **ret,
- const char *trait,
- unsigned int index)
-{
- (void) cls;
- (void) ret;
- (void) trait;
- (void) index;
- /* Must define this function because some callbacks
- * look for certain traits on _all_ the commands. */
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Free history @a h of length @a h_len.
- *
- * @param h history array to free.
- * @param h_len number of entries in @a h.
- */
-static void
-free_history (struct History *h,
- uint64_t h_len)
-{
- for (uint64_t off = 0; off<h_len; off++)
- GNUNET_free (h[off].url);
- GNUNET_free_non_null (h);
-}
-
-
-/**
- * Log which history we expected. Called when an error occurs.
- *
- * @param h what we expected.
- * @param h_len number of entries in @a h.
- * @param off position of the missmatch.
- */
-static void
-print_expected (struct History *h,
- uint64_t h_len,
- unsigned int off)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Transaction history missmatch at position %u/%llu\n",
- off,
- (unsigned long long) h_len);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Expected history:\n");
- for (uint64_t i = 0; i<h_len; i++)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "H(%llu): %s (serial: %llu, subject: %s,"
- " counterpart: %s)\n",
- (unsigned long long) i,
- TALER_amount2s (&h[i].details.amount),
- (unsigned long long) h[i].row_id,
- TALER_B2S (&h[i].details.reserve_pub),
- h[i].details.account_url);
- }
-}
-
-
-/**
- * Tell if the current item is beyond the allowed limit.
- *
- * @param total current number of items in the built history list.
- * Note, this is the list we build locally and compare with
- * what the server returned.
- * @param hs the history CMD state.
- * @param pos current item to be evaluated or not (if the list
- * has already enough elements).
- * @return GNUNET_OK / GNUNET_NO.
- */
-static int
-build_history_hit_limit (uint64_t total,
- const struct HistoryState *hs,
- const struct TALER_TESTING_Command *pos)
-{
- return total >= hs->num_results;
-}
-
-
-/**
- * This function constructs the list of history elements that
- * interest the account number of the caller. It has two main
- * loops: the first to figure out how many history elements have
- * to be allocated, and the second to actually populate every
- * element.
- *
- * @param is interpreter state (supposedly having the
- * current CMD pointing at a "history" CMD).
- * @param[out] rh history array to initialize.
- *
- * @return number of entries in @a rh.
- */
-static uint64_t
-build_history (struct TALER_TESTING_Interpreter *is,
- struct History **rh)
-{
- struct HistoryState *hs = is->commands[is->ip].cls;
- uint64_t total;
- struct History *h;
- const struct TALER_TESTING_Command *add_incoming_cmd;
- int inc;
- unsigned int start;
- unsigned int end;
-
- /**
- * @var turns GNUNET_YES whenever either no 'start' value was
- * given for the history query, or the given value is found
- * in the list of all the CMDs.
- */int ok;
- const uint64_t *row_id_start = NULL;
-
- if (NULL != hs->start_row_reference)
- {
- TALER_LOG_INFO
- ("`%s': start row given via reference `%s'\n",
- TALER_TESTING_interpreter_get_current_label (is),
- hs->start_row_reference);
- add_incoming_cmd = TALER_TESTING_interpreter_lookup_command
- (is, hs->start_row_reference);
- GNUNET_assert (NULL != add_incoming_cmd);
- GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_uint64
- (add_incoming_cmd, 0, &row_id_start));
- }
-
- GNUNET_assert (0 != hs->num_results);
- if (0 == is->ip)
- {
- TALER_LOG_DEBUG ("Checking history at first CMD..\n");
- *rh = NULL;
- return 0;
- }
-
- /* AKA 'delta'. */
- if (hs->num_results > 0)
- {
- inc = 1; /* _inc_rement */
- start = 0;
- end = is->ip - 1;
- }
- else
- {
- inc = -1;
- start = is->ip - 1;
- end = 0;
- }
-
- total = 0;
- ok = GNUNET_NO;
-
- if (NULL == row_id_start)
- ok = GNUNET_YES;
-
- /* This loop counts how many commands _later than "start"_ belong
- * to the history of the caller. This is stored in the @var total
- * variable. */
- for (unsigned int off = start; off != end + inc; off += inc)
- {
- const struct TALER_TESTING_Command *pos = &is->commands[off];
- const uint64_t *row_id;
- const char *credit_account;
- const char *debit_account;
-
- /**
- * The following command allows us to skip over those CMDs
- * that do not offer a "row_id" trait. Such skipped CMDs are
- * not interesting for building a history.
- */if (GNUNET_OK != TALER_TESTING_get_trait_uint64 (pos,
- 0,
- &row_id))
- continue;
-
- /* Seek "/history" starting row. */
- if (NULL != row_id_start)
- {
- if (*row_id_start == *row_id)
- {
- /* Doesn't count, start is excluded from output. */
- total = 0;
- ok = GNUNET_YES;
- continue;
- }
- }
-
- /* when 'start' was _not_ given, then ok == GNUNET_YES */
- if (GNUNET_NO == ok)
- continue; /* skip until we find the marker */
-
- TALER_LOG_DEBUG ("Found first row\n");
-
- if (build_history_hit_limit (total,
- hs,
- pos))
- {
- TALER_LOG_DEBUG ("Hit history limit\n");
- break;
- }
-
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_CREDIT_ACCOUNT
- (pos, &credit_account));
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_DEBIT_ACCOUNT
- (pos, &debit_account));
-
- TALER_LOG_INFO ("Potential history element:"
- " %s->%s; my account: %s\n",
- debit_account,
- credit_account,
- hs->account_url);
-
- if (0 == strcasecmp (hs->account_url,
- credit_account))
- {
- TALER_LOG_INFO ("+1 my history\n");
- total++; /* found matching record */
- }
- }
-
- GNUNET_assert (GNUNET_YES == ok);
-
- if (0 == total)
- {
- TALER_LOG_DEBUG ("Checking history at first CMD.. (2)\n");
- *rh = NULL;
- return 0;
- }
-
-
- GNUNET_assert (total < UINT_MAX);
- h = GNUNET_new_array ((unsigned int) total,
- struct History);
- total = 0;
- ok = GNUNET_NO;
- if (NULL == row_id_start)
- ok = GNUNET_YES;
-
- /**
- * This loop _only_ populates the array of history elements.
- */
- for (unsigned int off = start; off != end + inc; off += inc)
- {
- const struct TALER_TESTING_Command *pos = &is->commands[off];
- const uint64_t *row_id;
- char *bank_hostname;
- const char *credit_account;
- const char *debit_account;
-
- if (GNUNET_OK != TALER_TESTING_GET_TRAIT_ROW_ID
- (pos, &row_id))
- continue;
-
- if (NULL != row_id_start)
- {
-
- if (*row_id_start == *row_id)
- {
- /**
- * Warning: this zeroing is superfluous, as
- * total doesn't get incremented if 'start'
- * was given and couldn't be found.
- */total = 0;
- ok = GNUNET_YES;
- continue;
- }
- }
-
- TALER_LOG_INFO ("Found first row (2)\n");
-
- if (GNUNET_NO == ok)
- {
- TALER_LOG_INFO ("Skip on `%s'\n",
- pos->label);
- continue; /* skip until we find the marker */
- }
-
- if (build_history_hit_limit (total,
- hs,
- pos))
- {
- TALER_LOG_INFO ("Hit history limit (2)\n");
- break;
- }
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_CREDIT_ACCOUNT
- (pos, &credit_account));
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_DEBIT_ACCOUNT
- (pos, &debit_account));
-
- TALER_LOG_INFO ("Potential history bit:"
- " %s->%s; my account: %s\n",
- debit_account,
- credit_account,
- hs->account_url);
-
- /**
- * Discard transactions where the audited account played
- * _both_ the credit and the debit roles, but _only if_
- * the audit goes on both directions.. This needs more
- * explaination!
- */if (0 == strcasecmp (hs->account_url,
- credit_account))
- {
- GNUNET_break (0);
- continue;
- }
-
- bank_hostname = strchr (hs->account_url, ':');
- GNUNET_assert (NULL != bank_hostname);
- bank_hostname += 3;
-
- /* Next two blocks only put the 'direction' and 'banking'
- * information. */
-
- /* Asked for credit, and account got the credit. */
- if (0 == strcasecmp (hs->account_url,
- credit_account))
- {
- h[total].url = GNUNET_strdup (debit_account);
- h[total].details.account_url = h[total].url;
- }
-
- /* This block _completes_ the information of the current item,
- * with amount / subject / exchange URL. */
- if (0 == strcasecmp (hs->account_url,
- credit_account))
- {
- const struct TALER_Amount *amount;
- const struct TALER_ReservePublicKeyP *reserve_pub;
- const char *account_url;
-
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_amount_obj
- (pos, 0, &amount));
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_reserve_pub
- (pos, 0, &reserve_pub));
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_url
- (pos, 1,
- &account_url));
- h[total].details.amount = *amount;
- h[total].row_id = *row_id;
- h[total].details.reserve_pub = *reserve_pub;
- h[total].details.account_url = account_url;
- TALER_LOG_INFO ("+1-bit of my history\n");
- total++;
- }
- }
- *rh = h;
- return total;
-}
-
-
-/**
- * Compute how many results we expect to be returned for
- * the current command at @a is.
- *
- * @param is the interpreter state to inspect.
- * @return number of results expected.
- */
-static uint64_t
-compute_result_count (struct TALER_TESTING_Interpreter *is)
-{
- uint64_t total;
- struct History *h;
-
- total = build_history (is, &h);
- free_history (h, total);
- return total;
-}
-
-
-/**
- * Check that the "/history" response matches the
- * CMD whose offset in the list of CMDs is @a off.
- *
- * @param is the interpreter state.
- * @param off the offset (of the CMD list) where the command
- * to check is.
- * @param dir the expected direction of the transaction.
- * @param details the expected transaction details.
- *
- * @return #GNUNET_OK if the transaction is what we expect.
- */
-static int
-check_result (struct TALER_TESTING_Interpreter *is,
- unsigned int off,
- const struct TALER_BANK_CreditDetails *details)
-{
- uint64_t total;
- struct History *h;
-
- total = build_history (is, &h);
- if (off >= total)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Test says history has at most %u"
- " results, but got result #%u to check\n",
- (unsigned int) total,
- off);
- print_expected (h,
- total,
- off);
- return GNUNET_SYSERR;
- }
- if ( (0 != GNUNET_memcmp (&h[off].details.reserve_pub,
- &details->reserve_pub)) ||
- (0 != TALER_amount_cmp (&h[off].details.amount,
- &details->amount)) ||
- (0 != strcasecmp (h[off].details.account_url,
- details->account_url)) )
- {
- GNUNET_break (0);
- print_expected (h,
- total,
- off);
- free_history (h,
- total);
- return GNUNET_SYSERR;
- }
- free_history (h,
- total);
- return GNUNET_OK;
-}
-
-
-/**
- * This callback will (1) check that the HTTP response code
- * is acceptable and (2) that the history is consistent. The
- * consistency is checked by going through all the past CMDs,
- * reconstructing then the expected history as of those, and
- * finally check it against what the bank returned.
- *
- * @param cls closure.
- * @param http_status HTTP response code, #MHD_HTTP_OK (200)
- * for successful status request 0 if the bank's reply is
- * bogus (fails to follow the protocol),
- * #MHD_HTTP_NO_CONTENT if there are no more results; on
- * success the last callback is always of this status
- * (even if `abs(num_results)` were already returned).
- * @param ec taler status code.
- * @param dir direction of the transfer.
- * @param row_id monotonically increasing counter corresponding to
- * the transaction.
- * @param details details about the wire transfer.
- * @param json detailed response from the HTTPD, or NULL if
- * reply was not in JSON.
- * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
- */
-static int
-history_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- uint64_t row_id,
- const struct TALER_BANK_CreditDetails *details,
- const json_t *json)
-{
- struct TALER_TESTING_Interpreter *is = cls;
- struct HistoryState *hs = is->commands[is->ip].cls;
-
- (void) row_id;
- if (MHD_HTTP_OK != http_status)
- {
- hs->hh = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unwanted response code from /history: %u\n",
- http_status);
- TALER_TESTING_interpreter_fail (is);
- return GNUNET_SYSERR;
- }
- if (NULL == details)
- {
- hs->hh = NULL;
- if ( (hs->results_obtained != compute_result_count (is)) ||
- (GNUNET_YES == hs->failed) )
- {
- uint64_t total;
- struct History *h;
-
- GNUNET_break (0);
- total = build_history (is, &h);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Expected history of length %llu, got %llu;"
- " HTTP status code: %u/%d, failed: %d\n",
- (unsigned long long) total,
- (unsigned long long) hs->results_obtained,
- http_status,
- (int) ec,
- hs->failed);
- print_expected (h,
- total,
- UINT_MAX);
- free_history (h,
- total);
- TALER_TESTING_interpreter_fail (is);
- return GNUNET_SYSERR;
- }
- TALER_TESTING_interpreter_next (is);
- return GNUNET_OK;
- }
-
- /* check current element */
- if (GNUNET_OK != check_result (is,
- hs->results_obtained,
- details))
- {
- char *acc;
-
- GNUNET_break (0);
- acc = json_dumps (json,
- JSON_COMPACT);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Result %u was `%s'\n",
- (unsigned int) hs->results_obtained++,
- acc);
- if (NULL != acc)
- free (acc);
- hs->failed = GNUNET_YES;
- return GNUNET_SYSERR;
- }
- hs->results_obtained++;
- return GNUNET_OK;
-}
-
-
-/**
- * Run the command.
- *
- * @param cls closure.
- * @param cmd the command to execute.
- * @param is the interpreter state.
- */
-static void
-history_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct HistoryState *hs = cls;
- uint64_t row_id = (hs->num_results > 0) ? 0 : UINT64_MAX;
- const uint64_t *row_ptr;
-
- (void) cmd;
- /* Get row_id from trait. */
- if (NULL != hs->start_row_reference)
- {
- const struct TALER_TESTING_Command *history_cmd;
-
- history_cmd = TALER_TESTING_interpreter_lookup_command
- (is, hs->start_row_reference);
-
- if (NULL == history_cmd)
- TALER_TESTING_FAIL (is);
-
- if (GNUNET_OK !=
- TALER_TESTING_get_trait_uint64 (history_cmd,
- 0,
- &row_ptr))
- TALER_TESTING_FAIL (is);
- else
- row_id = *row_ptr;
- TALER_LOG_DEBUG ("row id (from trait) is %llu\n",
- (unsigned long long) row_id);
- }
-
- hs->hh = TALER_BANK_credit_history (is->ctx,
- hs->account_url,
- &hs->auth,
- row_id,
- hs->num_results,
- &history_cb,
- is);
- GNUNET_assert (NULL != hs->hh);
-}
-
-
-/**
- * Free the state from a "history" CMD, and possibly cancel
- * a pending operation thereof.
- *
- * @param cls closure.
- * @param cmd the command which is being cleaned up.
- */
-static void
-history_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct HistoryState *hs = cls;
-
- (void) cmd;
- if (NULL != hs->hh)
- {
- TALER_LOG_WARNING ("/history did not complete\n");
- TALER_BANK_credit_history_cancel (hs->hh);
- }
- GNUNET_free (hs->account_url);
- GNUNET_free (hs);
-}
-
-
-/**
- * Make a "history" CMD.
- *
- * @param label command label.
- * @param account_url base URL of the account offering the "history"
- * operation.
- * @param start_row_reference reference to a command that can
- * offer a row identifier, to be used as the starting row
- * to accept in the result.
- * @param num_results how many rows we want in the result.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_bank_credits (const char *label,
- const char *account_url,
- const struct
- TALER_BANK_AuthenticationData *auth,
- const char *start_row_reference,
- long long num_results)
-{
- struct HistoryState *hs;
-
- hs = GNUNET_new (struct HistoryState);
- hs->account_url = GNUNET_strdup (account_url);
- hs->start_row_reference = start_row_reference;
- hs->num_results = num_results;
- hs->auth = *auth;
- {
- struct TALER_TESTING_Command cmd = {
- .label = label,
- .cls = hs,
- .run = &history_run,
- .cleanup = &history_cleanup,
- .traits = &history_traits
- };
-
- return cmd;
- }
-}
-
-
-/* end of testing_api_cmd_credit_history.c */
diff --git a/src/bank-lib/testing_api_cmd_history_debit.c b/src/bank-lib/testing_api_cmd_history_debit.c
deleted file mode 100644
index 96f989c04..000000000
--- a/src/bank-lib/testing_api_cmd_history_debit.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2018-2020 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 bank-lib/testing_api_cmd_history.c
- * @brief command to check the /history API from the bank.
- * @author Marcello Stanisci
- */
-
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_testing_lib.h"
-#include "taler_testing_bank_lib.h"
-#include "taler_fakebank_lib.h"
-#include "taler_bank_service.h"
-#include "taler_fakebank_lib.h"
-
-
-/**
- * State for a "history" CMD.
- */
-struct HistoryState
-{
- /**
- * Base URL of the account offering the "history" operation.
- */
- const char *account_url;
-
- /**
- * Reference to command defining the
- * first row number we want in the result.
- */
- const char *start_row_reference;
-
- /**
- * How many rows we want in the result, _at most_,
- * and ascending/descending.
- */
- long long num_results;
-
- /**
- * Login data to use to authenticate.
- */
- struct TALER_BANK_AuthenticationData auth;
-
- /**
- * Handle to a pending "history" operation.
- */
- struct TALER_BANK_DebitHistoryHandle *hh;
-
- /**
- * Expected number of results (= rows).
- */
- uint64_t results_obtained;
-
- /**
- * Set to #GNUNET_YES if the callback detects something
- * unexpected.
- */
- int failed;
-
-};
-
-
-/**
- * Item in the transaction history, as reconstructed from the
- * command history.
- */
-struct History
-{
-
- /**
- * Wire details.
- */
- struct TALER_BANK_DebitDetails details;
-
- /**
- * Serial ID of the wire transfer.
- */
- uint64_t row_id;
-
- /**
- * URL to free.
- */
- char *url;
-};
-
-
-/**
- * Offer internal data to other commands.
- *
- * @param cls closure.
- * @param ret[out] set to the wanted data.
- * @param trait name of the trait.
- * @param index index number of the traits to be returned.
- *
- * @return #GNUNET_OK on success
- */
-static int
-history_traits (void *cls,
- const void **ret,
- const char *trait,
- unsigned int index)
-{
- (void) cls;
- (void) ret;
- (void) trait;
- (void) index;
- /* Must define this function because some callbacks
- * look for certain traits on _all_ the commands. */
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Free history @a h of length @a h_len.
- *
- * @param h history array to free.
- * @param h_len number of entries in @a h.
- */
-static void
-free_history (struct History *h,
- uint64_t h_len)
-{
- for (uint64_t off = 0; off<h_len; off++)
- GNUNET_free (h[off].url);
- GNUNET_free_non_null (h);
-}
-
-
-/**
- * Log which history we expected. Called when an error occurs.
- *
- * @param h what we expected.
- * @param h_len number of entries in @a h.
- * @param off position of the missmatch.
- */
-static void
-print_expected (struct History *h,
- uint64_t h_len,
- unsigned int off)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Transaction history missmatch at position %u/%llu\n",
- off,
- (unsigned long long) h_len);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Expected history:\n");
- for (uint64_t i = 0; i<h_len; i++)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "H(%llu): %s (serial: %llu, subject: %s,"
- " counterpart: %s)\n",
- (unsigned long long) i,
- TALER_amount2s (&h[i].details.amount),
- (unsigned long long) h[i].row_id,
- TALER_B2S (&h[i].details.wtid),
- h[i].details.account_url);
- }
-}
-
-
-/**
- * Tell if the current item is beyond the allowed limit.
- *
- * @param total current number of items in the built history list.
- * Note, this is the list we build locally and compare with
- * what the server returned.
- * @param hs the history CMD state.
- * @param pos current item to be evaluated or not (if the list
- * has already enough elements).
- * @return GNUNET_OK / GNUNET_NO.
- */
-static int
-build_history_hit_limit (uint64_t total,
- const struct HistoryState *hs,
- const struct TALER_TESTING_Command *pos)
-{
- return total >= hs->num_results;
-}
-
-
-/**
- * This function constructs the list of history elements that
- * interest the account number of the caller. It has two main
- * loops: the first to figure out how many history elements have
- * to be allocated, and the second to actually populate every
- * element.
- *
- * @param is interpreter state (supposedly having the
- * current CMD pointing at a "history" CMD).
- * @param[out] rh history array to initialize.
- *
- * @return number of entries in @a rh.
- */
-static uint64_t
-build_history (struct TALER_TESTING_Interpreter *is,
- struct History **rh)
-{
- struct HistoryState *hs = is->commands[is->ip].cls;
- uint64_t total;
- struct History *h;
- const struct TALER_TESTING_Command *add_incoming_cmd;
- int inc;
- unsigned int start;
- unsigned int end;
-
- /**
- * @var turns GNUNET_YES whenever either no 'start' value was
- * given for the history query, or the given value is found
- * in the list of all the CMDs.
- */int ok;
- const uint64_t *row_id_start = NULL;
-
- if (NULL != hs->start_row_reference)
- {
- TALER_LOG_INFO
- ("`%s': start row given via reference `%s'\n",
- TALER_TESTING_interpreter_get_current_label (is),
- hs->start_row_reference);
- add_incoming_cmd = TALER_TESTING_interpreter_lookup_command
- (is, hs->start_row_reference);
- GNUNET_assert (NULL != add_incoming_cmd);
- GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_uint64
- (add_incoming_cmd, 0, &row_id_start));
- }
-
- GNUNET_assert (0 != hs->num_results);
- if (0 == is->ip)
- {
- TALER_LOG_DEBUG ("Checking history at first CMD..\n");
- *rh = NULL;
- return 0;
- }
-
- /* AKA 'delta'. */
- if (hs->num_results > 0)
- {
- inc = 1; /* _inc_rement */
- start = 0;
- end = is->ip - 1;
- }
- else
- {
- inc = -1;
- start = is->ip - 1;
- end = 0;
- }
-
- total = 0;
- ok = GNUNET_NO;
-
- if (NULL == row_id_start)
- ok = GNUNET_YES;
-
- /* This loop counts how many commands _later than "start"_ belong
- * to the history of the caller. This is stored in the @var total
- * variable. */
- for (unsigned int off = start; off != end + inc; off += inc)
- {
- const struct TALER_TESTING_Command *pos = &is->commands[off];
- const uint64_t *row_id;
- const char *debit_account;
- const char *credit_account;
-
- /**
- * The following command allows us to skip over those CMDs
- * that do not offer a "row_id" trait. Such skipped CMDs are
- * not interesting for building a history.
- */if (GNUNET_OK != TALER_TESTING_get_trait_uint64 (pos,
- 0,
- &row_id))
- continue;
-
- /* Seek "/history" starting row. */
- if (NULL != row_id_start)
- {
- if (*row_id_start == *row_id)
- {
- /* Doesn't count, start is excluded from output. */
- total = 0;
- ok = GNUNET_YES;
- continue;
- }
- }
-
- /* when 'start' was _not_ given, then ok == GNUNET_YES */
- if (GNUNET_NO == ok)
- continue; /* skip until we find the marker */
-
- TALER_LOG_DEBUG ("Found first row\n");
-
- if (build_history_hit_limit (total,
- hs,
- pos))
- {
- TALER_LOG_DEBUG ("Hit history limit\n");
- break;
- }
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_DEBIT_ACCOUNT
- (pos, &debit_account));
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_CREDIT_ACCOUNT
- (pos, &credit_account));
-
- TALER_LOG_INFO ("Potential history element:"
- " %s->%s; my account: %s\n",
- debit_account,
- credit_account,
- hs->account_url);
-
- if (0 == strcasecmp (hs->account_url,
- debit_account))
- {
- TALER_LOG_INFO ("+1 my history\n");
- total++; /* found matching record */
- }
- }
-
- GNUNET_assert (GNUNET_YES == ok);
-
- if (0 == total)
- {
- TALER_LOG_DEBUG ("Checking history at first CMD.. (2)\n");
- *rh = NULL;
- return 0;
- }
-
-
- GNUNET_assert (total < UINT_MAX);
- h = GNUNET_new_array ((unsigned int) total,
- struct History);
- total = 0;
- ok = GNUNET_NO;
- if (NULL == row_id_start)
- ok = GNUNET_YES;
-
- /**
- * This loop _only_ populates the array of history elements.
- */
- for (unsigned int off = start; off != end + inc; off += inc)
- {
- const struct TALER_TESTING_Command *pos = &is->commands[off];
- const uint64_t *row_id;
- char *bank_hostname;
- const char *credit_account;
- const char *debit_account;
-
- if (GNUNET_OK != TALER_TESTING_GET_TRAIT_ROW_ID
- (pos, &row_id))
- continue;
-
- if (NULL != row_id_start)
- {
-
- if (*row_id_start == *row_id)
- {
- /**
- * Warning: this zeroing is superfluous, as
- * total doesn't get incremented if 'start'
- * was given and couldn't be found.
- */total = 0;
- ok = GNUNET_YES;
- continue;
- }
- }
-
- TALER_LOG_INFO ("Found first row (2)\n");
-
- if (GNUNET_NO == ok)
- {
- TALER_LOG_INFO ("Skip on `%s'\n",
- pos->label);
- continue; /* skip until we find the marker */
- }
-
- if (build_history_hit_limit (total,
- hs,
- pos))
- {
- TALER_LOG_INFO ("Hit history limit (2)\n");
- break;
- }
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_DEBIT_ACCOUNT
- (pos, &debit_account));
-
- GNUNET_assert
- (GNUNET_OK == TALER_TESTING_GET_TRAIT_CREDIT_ACCOUNT
- (pos, &credit_account));
-
- TALER_LOG_INFO ("Potential history bit:"
- " %s->%s; my account: %s\n",
- debit_account,
- credit_account,
- hs->account_url);
-
- /**
- * Discard transactions where the audited account played
- * _both_ the debit and the debit roles, but _only if_
- * the audit goes on both directions.. This needs more
- * explaination!
- */if (0 == strcasecmp (hs->account_url,
- debit_account))
- {
- GNUNET_break (0);
- continue;
- }
-
- bank_hostname = strchr (hs->account_url, ':');
- GNUNET_assert (NULL != bank_hostname);
- bank_hostname += 3;
-
- /* Next two blocks only put the 'direction' and 'banking'
- * information. */
-
- /* Asked for debit, and account got the debit. */
- if (0 == strcasecmp (hs->account_url,
- debit_account))
- {
- h[total].url = GNUNET_strdup (credit_account);
- h[total].details.account_url = h[total].url;
- }
-
- /* This block _completes_ the information of the current item,
- * with amount / subject / exchange URL. */
- if (0 == strcasecmp (hs->account_url,
- debit_account))
- {
- const struct TALER_Amount *amount;
- const struct TALER_WireTransferIdentifierRawP *wtid;
- const char *account_url;
-
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_amount_obj
- (pos, 0, &amount));
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_wtid
- (pos, 0, &wtid));
- GNUNET_assert (GNUNET_OK ==
- TALER_TESTING_get_trait_url
- (pos, 1,
- &account_url));
- h[total].details.amount = *amount;
- h[total].row_id = *row_id;
- h[total].details.wtid = *wtid;
- h[total].details.account_url = account_url;
- TALER_LOG_INFO ("+1-bit of my history\n");
- total++;
- }
- }
- *rh = h;
- return total;
-}
-
-
-/**
- * Compute how many results we expect to be returned for
- * the current command at @a is.
- *
- * @param is the interpreter state to inspect.
- * @return number of results expected.
- */
-static uint64_t
-compute_result_count (struct TALER_TESTING_Interpreter *is)
-{
- uint64_t total;
- struct History *h;
-
- total = build_history (is, &h);
- free_history (h, total);
- return total;
-}
-
-
-/**
- * Check that the "/history" response matches the
- * CMD whose offset in the list of CMDs is @a off.
- *
- * @param is the interpreter state.
- * @param off the offset (of the CMD list) where the command
- * to check is.
- * @param dir the expected direction of the transaction.
- * @param details the expected transaction details.
- *
- * @return #GNUNET_OK if the transaction is what we expect.
- */
-static int
-check_result (struct TALER_TESTING_Interpreter *is,
- unsigned int off,
- const struct TALER_BANK_DebitDetails *details)
-{
- uint64_t total;
- struct History *h;
-
- total = build_history (is, &h);
- if (off >= total)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Test says history has at most %u"
- " results, but got result #%u to check\n",
- (unsigned int) total,
- off);
- print_expected (h,
- total,
- off);
- return GNUNET_SYSERR;
- }
- if ( (0 != GNUNET_memcmp (&h[off].details.wtid,
- &details->wtid)) ||
- (0 != TALER_amount_cmp (&h[off].details.amount,
- &details->amount)) ||
- (0 != strcasecmp (h[off].details.account_url,
- details->account_url)) )
- {
- GNUNET_break (0);
- print_expected (h,
- total,
- off);
- free_history (h,
- total);
- return GNUNET_SYSERR;
- }
- free_history (h,
- total);
- return GNUNET_OK;
-}
-
-
-/**
- * This callback will (1) check that the HTTP response code
- * is acceptable and (2) that the history is consistent. The
- * consistency is checked by going through all the past CMDs,
- * reconstructing then the expected history as of those, and
- * finally check it against what the bank returned.
- *
- * @param cls closure.
- * @param http_status HTTP response code, #MHD_HTTP_OK (200)
- * for successful status request 0 if the bank's reply is
- * bogus (fails to follow the protocol),
- * #MHD_HTTP_NO_CONTENT if there are no more results; on
- * success the last callback is always of this status
- * (even if `abs(num_results)` were already returned).
- * @param ec taler status code.
- * @param dir direction of the transfer.
- * @param row_id monotonically increasing counter corresponding to
- * the transaction.
- * @param details details about the wire transfer.
- * @param json detailed response from the HTTPD, or NULL if
- * reply was not in JSON.
- * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
- */
-static int
-history_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- uint64_t row_id,
- const struct TALER_BANK_DebitDetails *details,
- const json_t *json)
-{
- struct TALER_TESTING_Interpreter *is = cls;
- struct HistoryState *hs = is->commands[is->ip].cls;
-
- (void) row_id;
- if (MHD_HTTP_OK != http_status)
- {
- hs->hh = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unwanted response code from /history: %u\n",
- http_status);
- TALER_TESTING_interpreter_fail (is);
- return GNUNET_SYSERR;
- }
- if (NULL == details)
- {
- hs->hh = NULL;
- if ( (hs->results_obtained != compute_result_count (is)) ||
- (GNUNET_YES == hs->failed) )
- {
- uint64_t total;
- struct History *h;
-
- GNUNET_break (0);
- total = build_history (is, &h);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Expected history of length %llu, got %llu;"
- " HTTP status code: %u/%d, failed: %d\n",
- (unsigned long long) total,
- (unsigned long long) hs->results_obtained,
- http_status,
- (int) ec,
- hs->failed);
- print_expected (h,
- total,
- UINT_MAX);
- free_history (h,
- total);
- TALER_TESTING_interpreter_fail (is);
- return GNUNET_SYSERR;
- }
- TALER_TESTING_interpreter_next (is);
- return GNUNET_OK;
- }
-
- /* check current element */
- if (GNUNET_OK != check_result (is,
- hs->results_obtained,
- details))
- {
- char *acc;
-
- GNUNET_break (0);
- acc = json_dumps (json,
- JSON_COMPACT);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Result %u was `%s'\n",
- (unsigned int) hs->results_obtained++,
- acc);
- if (NULL != acc)
- free (acc);
- hs->failed = GNUNET_YES;
- return GNUNET_SYSERR;
- }
- hs->results_obtained++;
- return GNUNET_OK;
-}
-
-
-/**
- * Run the command.
- *
- * @param cls closure.
- * @param cmd the command to execute.
- * @param is the interpreter state.
- */
-static void
-history_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct HistoryState *hs = cls;
- uint64_t row_id = (hs->num_results > 0) ? 0 : UINT64_MAX;
- const uint64_t *row_ptr;
-
- (void) cmd;
- /* Get row_id from trait. */
- if (NULL != hs->start_row_reference)
- {
- const struct TALER_TESTING_Command *history_cmd;
-
- history_cmd = TALER_TESTING_interpreter_lookup_command
- (is, hs->start_row_reference);
-
- if (NULL == history_cmd)
- TALER_TESTING_FAIL (is);
-
- if (GNUNET_OK !=
- TALER_TESTING_get_trait_uint64 (history_cmd,
- 0,
- &row_ptr))
- TALER_TESTING_FAIL (is);
- else
- row_id = *row_ptr;
- TALER_LOG_DEBUG ("row id (from trait) is %llu\n",
- (unsigned long long) row_id);
- }
-
- hs->hh = TALER_BANK_debit_history (is->ctx,
- hs->account_url,
- &hs->auth,
- row_id,
- hs->num_results,
- &history_cb,
- is);
- GNUNET_assert (NULL != hs->hh);
-}
-
-
-/**
- * Free the state from a "history" CMD, and possibly cancel
- * a pending operation thereof.
- *
- * @param cls closure.
- * @param cmd the command which is being cleaned up.
- */
-static void
-history_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct HistoryState *hs = cls;
-
- (void) cmd;
- if (NULL != hs->hh)
- {
- TALER_LOG_WARNING ("/history did not complete\n");
- TALER_BANK_debit_history_cancel (hs->hh);
- }
- GNUNET_free (hs);
-}
-
-
-/**
- * Make a "history" CMD.
- *
- * @param label command label.
- * @param account_url base URL of the account offering the "history"
- * operation.
- * @param auth login data to use
- * @param start_row_reference reference to a command that can
- * offer a row identifier, to be used as the starting row
- * to accept in the result.
- * @param num_results how many rows we want in the result.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_bank_debits (const char *label,
- const char *account_url,
- const struct TALER_BANK_AuthenticationData *auth,
- const char *start_row_reference,
- long long num_results)
-{
- struct HistoryState *hs;
-
- hs = GNUNET_new (struct HistoryState);
- hs->account_url = account_url;
- hs->start_row_reference = start_row_reference;
- hs->num_results = num_results;
- hs->auth = *auth;
-
- {
- struct TALER_TESTING_Command cmd = {
- .label = label,
- .cls = hs,
- .run = &history_run,
- .cleanup = &history_cleanup,
- .traits = &history_traits
- };
-
- return cmd;
- }
-}
-
-
-/* end of testing_api_cmd_history_debit.c */
diff --git a/src/bank-lib/testing_api_cmd_transfer.c b/src/bank-lib/testing_api_cmd_transfer.c
deleted file mode 100644
index d5a3872ed..000000000
--- a/src/bank-lib/testing_api_cmd_transfer.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2018-2020 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 exchange-lib/testing_api_cmd_transfer.c
- * @brief implementation of a bank /transfer command
- * @author Christian Grothoff
- * @author Marcello Stanisci
- */
-#include "platform.h"
-#include "backoff.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_bank_service.h"
-#include "taler_fakebank_lib.h"
-#include "taler_signatures.h"
-#include "taler_testing_lib.h"
-#include "taler_testing_bank_lib.h"
-
-
-/**
- * State for a "transfer" CMD.
- */
-struct TransferState
-{
-
- /**
- * Wire transfer amount.
- */
- struct TALER_Amount amount;
-
- /**
- * Base URL of the debit account.
- */
- const char *account_debit_url;
-
- /**
- * Money receiver account URL.
- */
- const char *payto_credit_account;
-
- /**
- * Username to use for authentication.
- */
- struct TALER_BANK_AuthenticationData auth;
-
- /**
- * Base URL of the exchange.
- */
- const char *exchange_base_url;
-
- /**
- * Wire transfer identifier to use.
- */
- struct TALER_WireTransferIdentifierRawP wtid;
-
- /**
- * Handle to the pending request at the fakebank.
- */
- struct TALER_BANK_WireExecuteHandle *weh;
-
- /**
- * Interpreter state.
- */
- struct TALER_TESTING_Interpreter *is;
-
- /**
- * Set to the wire transfer's unique ID.
- */
- uint64_t serial_id;
-
- /**
- * Timestamp of the transaction (as returned from the bank).
- */
- struct GNUNET_TIME_Absolute timestamp;
-
- /**
- * Configuration filename. Used to get the tip reserve key
- * filename (used to obtain a public key to write in the
- * transfer subject).
- */
- const char *config_filename;
-
- /**
- * Task scheduled to try later.
- */
- struct GNUNET_SCHEDULER_Task *retry_task;
-
- /**
- * How long do we wait until we retry?
- */
- struct GNUNET_TIME_Relative backoff;
-
- /**
- * Was this command modified via
- * #TALER_TESTING_cmd_admin_add_incoming_with_retry to
- * enable retries?
- */
- int do_retry;
-};
-
-
-/**
- * Run the "transfer" CMD.
- *
- * @param cls closure.
- * @param cmd CMD being run.
- * @param is interpreter state.
- */
-static void
-transfer_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is);
-
-
-/**
- * Task scheduled to re-try #transfer_run.
- *
- * @param cls a `struct TransferState`
- */
-static void
-do_retry (void *cls)
-{
- struct TransferState *fts = cls;
-
- fts->retry_task = NULL;
- transfer_run (fts,
- NULL,
- fts->is);
-}
-
-
-/**
- * This callback will process the fakebank response to the wire
- * transfer. It just checks whether the HTTP response code is
- * acceptable.
- *
- * @param cls closure with the interpreter state
- * @param http_status HTTP response code, #MHD_HTTP_OK (200) for
- * successful status request; 0 if the exchange's reply is
- * bogus (fails to follow the protocol)
- * @param ec taler-specific error code, #TALER_EC_NONE on success
- * @param serial_id unique ID of the wire transfer
- * @param timestamp time stamp of the transaction made.
- */
-static void
-confirmation_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- uint64_t serial_id,
- struct GNUNET_TIME_Absolute timestamp)
-{
- struct TransferState *fts = cls;
- struct TALER_TESTING_Interpreter *is = fts->is;
-
- fts->weh = NULL;
- if (MHD_HTTP_OK != http_status)
- {
- if (GNUNET_YES == fts->do_retry)
- {
- if ( (0 == http_status) ||
- (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) ||
- (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Retrying transfer failed with %u/%d\n",
- http_status,
- (int) ec);
- /* on DB conflicts, do not use backoff */
- if (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec)
- fts->backoff = GNUNET_TIME_UNIT_ZERO;
- else
- fts->backoff = EXCHANGE_LIB_BACKOFF (fts->backoff);
- fts->retry_task = GNUNET_SCHEDULER_add_delayed
- (fts->backoff,
- &do_retry,
- fts);
- return;
- }
- }
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Fakebank returned HTTP status %u/%d\n",
- http_status,
- (int) ec);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
-
- fts->serial_id = serial_id;
- fts->timestamp = timestamp;
- TALER_TESTING_interpreter_next (is);
-}
-
-
-/**
- * Run the "transfer" CMD.
- *
- * @param cls closure.
- * @param cmd CMD being run.
- * @param is interpreter state.
- */
-static void
-transfer_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct TransferState *fts = cls;
- void *buf;
- size_t buf_size;
-
- TALER_BANK_prepare_wire_transfer (fts->payto_credit_account,
- &fts->amount,
- fts->exchange_base_url,
- &fts->wtid,
- &buf,
- &buf_size);
- fts->is = is;
- fts->weh
- = TALER_BANK_execute_wire_transfer
- (TALER_TESTING_interpreter_get_context (is),
- fts->account_debit_url,
- &fts->auth,
- buf,
- buf_size,
- &confirmation_cb,
- fts);
- GNUNET_free (buf);
- if (NULL == fts->weh)
- {
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
-}
-
-
-/**
- * Free the state of a "fakebank transfer" CMD, and possibly
- * cancel a pending operation thereof.
- *
- * @param cls closure
- * @param cmd current CMD being cleaned up.
- */
-static void
-transfer_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct TransferState *fts = cls;
-
- if (NULL != fts->weh)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Command %s did not complete\n",
- cmd->label);
- TALER_BANK_execute_wire_transfer_cancel (fts->weh);
- fts->weh = NULL;
- }
- if (NULL != fts->retry_task)
- {
- GNUNET_SCHEDULER_cancel (fts->retry_task);
- fts->retry_task = NULL;
- }
- GNUNET_free (fts);
-}
-
-
-/**
- * Offer internal data from a "fakebank transfer" 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
-transfer_traits (void *cls,
- const void **ret,
- const char *trait,
- unsigned int index)
-{
- struct TransferState *fts = cls;
- struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_url (1, fts->account_debit_url),
- TALER_TESTING_MAKE_TRAIT_ROW_ID (&fts->serial_id),
- TALER_TESTING_MAKE_TRAIT_CREDIT_ACCOUNT (fts->payto_credit_account),
- TALER_TESTING_MAKE_TRAIT_DEBIT_ACCOUNT (fts->account_debit_url),
- TALER_TESTING_make_trait_amount_obj (0, &fts->amount),
- TALER_TESTING_make_trait_absolute_time (0, &fts->timestamp),
- TALER_TESTING_make_trait_wtid (0,
- &fts->wtid),
- TALER_TESTING_trait_end ()
- };
-
- return TALER_TESTING_get_trait (traits,
- ret,
- trait,
- index);
-}
-
-
-/**
- * Create transfer command.
- *
- * @param label command label.
- * @param amount amount to transfer.
- * @param account_base_url base URL of the account that implements this
- * wire transer (which account gives money).
- * @param auth authentication data to use
- * @param payto_credit_account which account receives money.
- * @param wtid wire transfer identifier to use
- * @param exchange_base_url exchange URL to use
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_transfer
- (const char *label,
- const char *amount,
- const char *account_base_url,
- const struct TALER_BANK_AuthenticationData *auth,
- const char *payto_credit_account,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const char *exchange_base_url)
-{
- struct TransferState *fts;
-
- fts = GNUNET_new (struct TransferState);
- fts->account_debit_url = account_base_url;
- fts->exchange_base_url = exchange_base_url;
- fts->payto_credit_account = payto_credit_account;
- fts->auth = *auth;
- fts->wtid = *wtid;
- if (GNUNET_OK !=
- TALER_string_to_amount (amount,
- &fts->amount))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to parse amount `%s' at %s\n",
- amount,
- label);
- GNUNET_assert (0);
- }
-
- {
- struct TALER_TESTING_Command cmd = {
- .cls = fts,
- .label = label,
- .run = &transfer_run,
- .cleanup = &transfer_cleanup,
- .traits = &transfer_traits
- };
-
- return cmd;
- }
-}
-
-
-/**
- * Modify a transfer command to enable retries when the reserve is not yet
- * full or we get other transient errors from the bank.
- *
- * @param cmd a fakebank transfer command
- * @return the command with retries enabled
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_transfer_retry (struct TALER_TESTING_Command cmd)
-{
- struct TransferState *fts;
-
- GNUNET_assert (&transfer_run == cmd.run);
- fts = cmd.cls;
- fts->do_retry = GNUNET_YES;
- return cmd;
-}
-
-
-/* end of testing_api_cmd_transfer.c */
diff --git a/src/bank-lib/testing_api_helpers.c b/src/bank-lib/testing_api_helpers.c
deleted file mode 100644
index 64976edbb..000000000
--- a/src/bank-lib/testing_api_helpers.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- 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
- <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file bank-lib/testing_api_helpers.c
- * @brief convenience functions for bank-lib tests.
- * @author Marcello Stanisci
- */
-
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include "taler_testing_bank_lib.h"
-#include "taler_fakebank_lib.h"
-
-
-#define BANK_FAIL() \
- do {GNUNET_break (0); return NULL; } while (0)
-
-
-/**
- * Keep each bank account credentials at index:
- * bank account number - 1
- */
-struct TALER_BANK_AuthenticationData AUTHS[] = {
-
- /* Bank credentials */
- {.method = TALER_BANK_AUTH_BASIC,
- .details.basic.username = TALER_TESTING_BANK_USERNAME,
- .details.basic.password = TALER_TESTING_BANK_PASSWORD},
-
- /* Exchange credentials */
- {.method = TALER_BANK_AUTH_BASIC,
- .details.basic.username = TALER_TESTING_EXCHANGE_USERNAME,
- .details.basic.password = TALER_TESTING_EXCHANGE_PASSWORD },
-
- /* User credentials */
- {.method = TALER_BANK_AUTH_BASIC,
- .details.basic.username = TALER_TESTING_USER_USERNAME,
- .details.basic.password = TALER_TESTING_USER_PASSWORD }
-};
-
-
-/**
- * Runs the Fakebank by guessing / extracting the portnumber
- * from the base URL.
- *
- * @param bank_url bank's base URL.
- * @return the fakebank process handle, or NULL if any
- * error occurs.
- */
-struct TALER_FAKEBANK_Handle *
-TALER_TESTING_run_fakebank (const char *bank_url)
-{
- const char *port;
- long pnum;
- struct TALER_FAKEBANK_Handle *fakebankd;
-
- port = strrchr (bank_url,
- (unsigned char) ':');
- if (NULL == port)
- pnum = 80;
- else
- pnum = strtol (port + 1, NULL, 10);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Starting Fakebank on port %u (%s)\n",
- (unsigned int) pnum,
- bank_url);
- fakebankd = TALER_FAKEBANK_start ((uint16_t) pnum);
- if (NULL == fakebankd)
- {
- GNUNET_break (0);
- return NULL;
- }
- return fakebankd;
-}
-
-
-/**
- * Look for substring in a programs' name.
- *
- * @param prog program's name to look into
- * @param marker chunk to find in @a prog
- */
-int
-TALER_TESTING_has_in_name (const char *prog_name,
- const char *marker)
-{
- size_t name_pos;
- size_t pos;
-
- if (! prog_name || ! marker)
- return GNUNET_NO;
-
- pos = 0;
- name_pos = 0;
- while (prog_name[pos])
- {
- if ('/' == prog_name[pos])
- name_pos = pos + 1;
- pos++;
- }
- if (name_pos == pos)
- return GNUNET_YES;
- return strstr (prog_name + name_pos, marker) != NULL;
-}
-
-
-/**
- * Start the (Python) bank process. Assume the port
- * is available and the database is clean. Use the "prepare
- * bank" function to do such tasks.
- *
- * @param config_filename configuration filename.
- * @param bank_url base URL of the bank, used by `wget' to check
- * that the bank was started right.
- *
- * @return the process, or NULL if the process could not
- * be started.
- */
-struct GNUNET_OS_Process *
-TALER_TESTING_run_bank (const char *config_filename,
- const char *bank_url)
-{
- struct GNUNET_OS_Process *bank_proc;
- unsigned int iter;
- char *wget_cmd;
- char *database;
- char *serve_cfg;
- char *serve_arg;
- struct GNUNET_CONFIGURATION_Handle *cfg;
-
- cfg = GNUNET_CONFIGURATION_create ();
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_load (cfg,
- config_filename))
- {
- GNUNET_break (0);
- GNUNET_CONFIGURATION_destroy (cfg);
- exit (77);
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "bank",
- "database",
- &database))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
- "bank",
- "database");
- GNUNET_break (0);
- GNUNET_CONFIGURATION_destroy (cfg);
- exit (77);
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "bank",
- "serve",
- &serve_cfg))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
- "bank",
- "serve");
- GNUNET_break (0);
- GNUNET_CONFIGURATION_destroy (cfg);
- GNUNET_free (database);
- exit (77);
- }
- GNUNET_CONFIGURATION_destroy (cfg);
-
- serve_arg = "serve-http";
- if (0 != strcmp ("http", serve_cfg))
- serve_arg = "serve-uwsgi";
- GNUNET_free (serve_cfg);
- bank_proc = GNUNET_OS_start_process
- (GNUNET_NO,
- GNUNET_OS_INHERIT_STD_ALL,
- NULL, NULL, NULL,
- "taler-bank-manage-testing",
- "taler-bank-manage-testing",
- config_filename,
- database,
- serve_arg, NULL);
- GNUNET_free (database);
- if (NULL == bank_proc)
- {
- BANK_FAIL ();
- }
-
- GNUNET_asprintf (&wget_cmd,
- "wget -q -t 2 -T 1 %s -o /dev/null -O /dev/null",
- bank_url);
-
- /* give child time to start and bind against the socket */
- fprintf (stderr,
- "Waiting for `taler-bank-manage' to be ready");
- iter = 0;
- do
- {
- if (10 == iter)
- {
- fprintf (
- stderr,
- "Failed to launch `taler-bank-manage' (or `wget')\n");
- GNUNET_OS_process_kill (bank_proc,
- SIGTERM);
- GNUNET_OS_process_wait (bank_proc);
- GNUNET_OS_process_destroy (bank_proc);
- GNUNET_free (wget_cmd);
- BANK_FAIL ();
- }
- fprintf (stderr, ".");
- sleep (1);
- iter++;
- }
- while (0 != system (wget_cmd));
- GNUNET_free (wget_cmd);
- fprintf (stderr, "\n");
-
- return bank_proc;
-
-}
-
-
-/**
- * Prepare the bank execution. Check if the port is available
- * and reset database.
- *
- * @param config_filename configuration file name.
- *
- * @return the base url, or NULL upon errors. Must be freed
- * by the caller.
- */
-char *
-TALER_TESTING_prepare_bank (const char *config_filename)
-{
- struct GNUNET_CONFIGURATION_Handle *cfg;
- unsigned long long port;
- struct GNUNET_OS_Process *dbreset_proc;
- enum GNUNET_OS_ProcessStatusType type;
- unsigned long code;
- char *base_url;
- char *database;
-
- cfg = GNUNET_CONFIGURATION_create ();
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_load (cfg, config_filename))
- {
- GNUNET_CONFIGURATION_destroy (cfg);
- BANK_FAIL ();
- }
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "bank",
- "DATABASE",
- &database))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "bank",
- "DATABASE");
- GNUNET_CONFIGURATION_destroy (cfg);
- BANK_FAIL ();
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg,
- "bank",
- "HTTP_PORT",
- &port))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "bank",
- "HTTP_PORT");
- GNUNET_CONFIGURATION_destroy (cfg);
- GNUNET_free (database);
- BANK_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);
- BANK_FAIL ();
- }
-
- /* DB preparation */
- if (NULL ==
- (dbreset_proc = GNUNET_OS_start_process (
- GNUNET_NO,
- GNUNET_OS_INHERIT_STD_ALL,
- NULL, NULL, NULL,
- "taler-bank-manage",
- "taler-bank-manage",
- "-c", "bank.conf",
- "--with-db", database,
- "django",
- "flush",
- "--no-input", NULL)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to flush the bank db.\n");
- GNUNET_free (database);
- BANK_FAIL ();
- }
- GNUNET_free (database);
-
- if (GNUNET_SYSERR ==
- GNUNET_OS_process_wait_status (dbreset_proc,
- &type,
- &code))
- {
- GNUNET_OS_process_destroy (dbreset_proc);
- BANK_FAIL ();
- }
- if ( (type == GNUNET_OS_PROCESS_EXITED) &&
- (0 != code) )
- {
- fprintf (stderr,
- "Failed to setup database\n");
- BANK_FAIL ();
- }
- if ( (type != GNUNET_OS_PROCESS_EXITED) ||
- (0 != code) )
- {
- fprintf (stderr,
- "Unexpected error running"
- " `taler-bank-manage django flush..'!\n");
- BANK_FAIL ();
- }
-
- GNUNET_OS_process_destroy (dbreset_proc);
-
- GNUNET_asprintf (&base_url,
- "http://localhost:%llu/",
- port);
- return base_url;
-}
-
-
-/* end of testing_api_helpers.c */