diff --git a/.gitignore b/.gitignore index 20d4b52c2..1c3cba8fe 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ GTAGS src/lib/test_exchange_api doc/doxygen/doxygen_sqlite3.db src/bank-lib/test_bank_api +src/bank-lib/test_bank_api_with_fakebank src/exchange-lib/test_exchange_api src/exchange-lib/test_exchange_api_home/.local/share/taler/exchange/live-keys/ src/exchange/taler-exchange-aggregator diff --git a/doc/taler-exchange-aggregator.1 b/doc/taler-exchange-aggregator.1 index 954f88b20..d0da4cbca 100644 --- a/doc/taler-exchange-aggregator.1 +++ b/doc/taler-exchange-aggregator.1 @@ -23,7 +23,7 @@ Overrides WIREFORMAT option from the configuation file. Print short help on options. .B .IP "\-t, \-\-test" -Run in test mode (use temporary tables). Only useful for testcases. +Run in test mode and exit when idle. .B .IP "\-v, \-\-version" Print version information. diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am index e833c533c..f7f5dd738 100644 --- a/src/bank-lib/Makefile.am +++ b/src/bank-lib/Makefile.am @@ -47,15 +47,30 @@ endif endif check_PROGRAMS = \ - test_bank_api + test_bank_api \ + test_bank_api_with_fakebank TESTS = \ $(check_PROGRAMS) test_bank_api_SOURCES = \ + test_bank_interpreter.c test_bank_interpreter.h \ test_bank_api.c test_bank_api_LDADD = \ libtalerbank.la \ + libfakebank.la \ + $(top_builddir)/src/util/libtalerutil.la \ + -lgnunetcurl \ + -lgnunetutil \ + -ljansson + + +test_bank_api_with_fakebank_SOURCES = \ + test_bank_interpreter.c test_bank_interpreter.h \ + test_bank_api_with_fakebank.c +test_bank_api_with_fakebank_LDADD = \ + libtalerbank.la \ + libfakebank.la \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetcurl \ -lgnunetutil \ diff --git a/src/bank-lib/test_bank_api.c b/src/bank-lib/test_bank_api.c index fe02fb8e5..deba9fd53 100644 --- a/src/bank-lib/test_bank_api.c +++ b/src/bank-lib/test_bank_api.c @@ -15,7 +15,7 @@ */ /** * @file bank/test_bank_api.c - * @brief testcase to test bank's HTTP API interface + * @brief testcase to test bank's HTTP API interface against the "real" bank * @author Christian Grothoff */ #include "platform.h" @@ -25,440 +25,7 @@ #include #include #include - - -/** - * Main execution context for the main loop. - */ -static struct GNUNET_CURL_Context *ctx; - -/** - * Task run on shutdown. - */ -static struct GNUNET_SCHEDULER_Task *shutdown_task; - -/** - * Task that runs the main event loop. - */ -static struct GNUNET_SCHEDULER_Task *ctx_task; - -/** - * Result of the testcases, #GNUNET_OK on success - */ -static int result; - - -/** - * Opcodes for the interpreter. - */ -enum OpCode -{ - /** - * Termination code, stops the interpreter loop (with success). - */ - OC_END = 0, - - /** - * Add funds to a reserve by (faking) incoming wire transfer. - */ - OC_ADMIN_ADD_INCOMING - -}; - - -/** - * Details for a bank operation to execute. - */ -struct Command -{ - /** - * Opcode of the command. - */ - enum OpCode oc; - - /** - * Label for the command, can be NULL. - */ - const char *label; - - /** - * Which response code do we expect for this command? - */ - unsigned int expected_response_code; - - /** - * Details about the command. - */ - union - { - - /** - * Information for a #OC_ADMIN_ADD_INCOMING command. - */ - struct - { - - /** - * String describing the amount to add to the reserve. - */ - const char *amount; - - /** - * Credited account number. - */ - uint64_t credit_account_no; - - /** - * Debited account number. - */ - uint64_t debit_account_no; - - /** - * Wire transfer identifier to use. Initialized to - * a random value. - */ - struct TALER_WireTransferIdentifierRawP wtid; - - /** - * Set to the API's handle during the operation. - */ - struct TALER_BANK_AdminAddIncomingHandle *aih; - - } admin_add_incoming; - - } details; - -}; - - -/** - * State of the interpreter loop. - */ -struct InterpreterState -{ - /** - * Keys from the bank. - */ - const struct TALER_BANK_Keys *keys; - - /** - * Commands the interpreter will run. - */ - struct Command *commands; - - /** - * Interpreter task (if one is scheduled). - */ - struct GNUNET_SCHEDULER_Task *task; - - /** - * Instruction pointer. Tells #interpreter_run() which - * instruction to run next. - */ - unsigned int ip; - -}; - - -/** - * Task that runs the context's event loop with the GNUnet scheduler. - * - * @param cls unused - */ -static void -context_task (void *cls); - - -/** - * Run the context task, the working set has changed. - */ -static void -trigger_context_task () -{ - GNUNET_SCHEDULER_cancel (ctx_task); - ctx_task = GNUNET_SCHEDULER_add_now (&context_task, - NULL); -} - - -/** - * The testcase failed, return with an error code. - * - * @param is interpreter state to clean up - */ -static void -fail (struct InterpreterState *is) -{ - result = GNUNET_SYSERR; - GNUNET_SCHEDULER_shutdown (); -} - - -#if 0 -/** - * Find a command by label. - * - * @param is interpreter state to search - * @param label label to look for - * @return NULL if command was not found - */ -static const struct Command * -find_command (const struct InterpreterState *is, - const char *label) -{ - unsigned int i; - const struct Command *cmd; - - if (NULL == label) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Attempt to lookup command for empty label\n"); - return NULL; - } - for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++) - if ( (NULL != cmd->label) && - (0 == strcmp (cmd->label, - label)) ) - return cmd; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Command not found: %s\n", - label); - return NULL; -} -#endif - - -/** - * Run the main interpreter loop that performs bank operations. - * - * @param cls contains the `struct InterpreterState` - */ -static void -interpreter_run (void *cls); - - -/** - * Function called upon completion of our /admin/add/incoming request. - * - * @param cls closure with the interpreter state - * @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) - * @param json detailed response from the HTTPD, or NULL if reply was not in JSON - */ -static void -add_incoming_cb (void *cls, - unsigned int http_status, - const json_t *json) -{ - struct InterpreterState *is = cls; - struct Command *cmd = &is->commands[is->ip]; - - cmd->details.admin_add_incoming.aih = NULL; - if (cmd->expected_response_code != http_status) - { - GNUNET_break (0); - if (NULL != json) - { - fprintf (stderr, - "Unexpected response code %u:\n", - http_status); - json_dumpf (json, stderr, 0); - fprintf (stderr, "\n"); - } - fail (is); - return; - } - is->ip++; - is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, - is); -} - - -/** - * Run the main interpreter loop that performs bank operations. - * - * @param cls contains the `struct InterpreterState` - */ -static void -interpreter_run (void *cls) -{ - struct InterpreterState *is = cls; - struct Command *cmd = &is->commands[is->ip]; - struct TALER_Amount amount; - const struct GNUNET_SCHEDULER_TaskContext *tc; - - is->task = NULL; - tc = GNUNET_SCHEDULER_get_task_context (); - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - { - fprintf (stderr, - "Test aborted by shutdown request\n"); - fail (is); - return; - } - switch (cmd->oc) - { - case OC_END: - result = GNUNET_OK; - GNUNET_SCHEDULER_shutdown (); - return; - case OC_ADMIN_ADD_INCOMING: - - if (GNUNET_OK != - TALER_string_to_amount (cmd->details.admin_add_incoming.amount, - &amount)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse amount `%s' at %u\n", - cmd->details.admin_add_incoming.amount, - is->ip); - fail (is); - return; - } - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, - &cmd->details.admin_add_incoming.wtid, - sizeof (cmd->details.admin_add_incoming.wtid)); - cmd->details.admin_add_incoming.aih - = TALER_BANK_admin_add_incoming (ctx, - "http://localhost:8081", - &cmd->details.admin_add_incoming.wtid, - &amount, - cmd->details.admin_add_incoming.debit_account_no, - cmd->details.admin_add_incoming.credit_account_no, - &add_incoming_cb, - is); - if (NULL == cmd->details.admin_add_incoming.aih) - { - GNUNET_break (0); - fail (is); - return; - } - trigger_context_task (); - return; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unknown instruction %d at %u (%s)\n", - cmd->oc, - is->ip, - cmd->label); - fail (is); - return; - } -} - - -/** - * Function run when the test terminates (good or bad). - * Cleans up our state. - * - * @param cls the interpreter state. - */ -static void -do_shutdown (void *cls) -{ - struct InterpreterState *is = cls; - struct Command *cmd; - unsigned int i; - - shutdown_task = NULL; - for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++) - { - switch (cmd->oc) - { - case OC_END: - GNUNET_assert (0); - break; - case OC_ADMIN_ADD_INCOMING: - if (NULL != cmd->details.admin_add_incoming.aih) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Command %u (%s) did not complete\n", - i, - cmd->label); - TALER_BANK_admin_add_incoming_cancel (cmd->details.admin_add_incoming.aih); - cmd->details.admin_add_incoming.aih = NULL; - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unknown instruction %d at %u (%s)\n", - cmd->oc, - i, - cmd->label); - break; - } - } - if (NULL != is->task) - { - GNUNET_SCHEDULER_cancel (is->task); - is->task = NULL; - } - GNUNET_free (is); - if (NULL != ctx_task) - { - GNUNET_SCHEDULER_cancel (ctx_task); - ctx_task = NULL; - } - if (NULL != ctx) - { - GNUNET_CURL_fini (ctx); - ctx = NULL; - } -} - - -/** - * Task that runs the context's event loop with the GNUnet scheduler. - * - * @param cls unused - */ -static void -context_task (void *cls) -{ - long timeout; - int max_fd; - fd_set read_fd_set; - fd_set write_fd_set; - fd_set except_fd_set; - struct GNUNET_NETWORK_FDSet *rs; - struct GNUNET_NETWORK_FDSet *ws; - struct GNUNET_TIME_Relative delay; - - ctx_task = NULL; - GNUNET_CURL_perform (ctx); - max_fd = -1; - timeout = -1; - FD_ZERO (&read_fd_set); - FD_ZERO (&write_fd_set); - FD_ZERO (&except_fd_set); - GNUNET_CURL_get_select_info (ctx, - &read_fd_set, - &write_fd_set, - &except_fd_set, - &max_fd, - &timeout); - if (timeout >= 0) - delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, - timeout); - else - delay = GNUNET_TIME_UNIT_FOREVER_REL; - rs = GNUNET_NETWORK_fdset_create (); - GNUNET_NETWORK_fdset_copy_native (rs, - &read_fd_set, - max_fd + 1); - ws = GNUNET_NETWORK_fdset_create (); - GNUNET_NETWORK_fdset_copy_native (ws, - &write_fd_set, - max_fd + 1); - ctx_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - delay, - rs, - ws, - &context_task, - cls); - GNUNET_NETWORK_fdset_destroy (rs); - GNUNET_NETWORK_fdset_destroy (ws); -} +#include "test_bank_interpreter.h" /** @@ -469,33 +36,23 @@ context_task (void *cls) static void run (void *cls) { - struct InterpreterState *is; - static struct Command commands[] = + int *resultp = cls; + static struct TBI_Command commands[] = { /* Add EUR:5.01 to account 42 */ - { .oc = OC_ADMIN_ADD_INCOMING, + { .oc = TBI_OC_ADMIN_ADD_INCOMING, .label = "deposit-1", .expected_response_code = MHD_HTTP_OK, .details.admin_add_incoming.credit_account_no = 1, .details.admin_add_incoming.debit_account_no = 2, .details.admin_add_incoming.amount = "PUDOS:5.01" }, - { .oc = OC_END } + { .oc = TBI_OC_END } }; - is = GNUNET_new (struct InterpreterState); - is->commands = commands; - - ctx = GNUNET_CURL_init (); - GNUNET_assert (NULL != ctx); - ctx_task = GNUNET_SCHEDULER_add_now (&context_task, - ctx); - is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, - is); - shutdown_task - = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 150), - &do_shutdown, is); + TBI_run_interpreter (resultp, + GNUNET_NO /* we use the "real" taler bank */, + commands); } @@ -511,6 +68,7 @@ main (int argc, { struct GNUNET_OS_Process *bankd; unsigned int cnt; + int result; GNUNET_log_setup ("test-bank-api", "WARNING", @@ -545,7 +103,7 @@ main (int argc, fprintf (stderr, "\n"); result = GNUNET_SYSERR; if (cnt <= 30) - GNUNET_SCHEDULER_run (&run, NULL); + GNUNET_SCHEDULER_run (&run, &result); GNUNET_OS_process_kill (bankd, SIGTERM); GNUNET_OS_process_wait (bankd); diff --git a/src/bank-lib/test_bank_api_with_fakebank.c b/src/bank-lib/test_bank_api_with_fakebank.c new file mode 100644 index 000000000..fccdf6645 --- /dev/null +++ b/src/bank-lib/test_bank_api_with_fakebank.c @@ -0,0 +1,78 @@ +/* + This file is part of TALER + Copyright (C) 2016 GNUnet e.V. + + 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, If not, see +*/ +/** + * @file bank/test_bank_api_with_fakebank.c + * @brief testcase to test bank's HTTP API interface against the fakebank + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_signatures.h" +#include "taler_bank_service.h" +#include +#include +#include +#include "test_bank_interpreter.h" + + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + */ +static void +run (void *cls) +{ + int *resultp = cls; + static struct TBI_Command commands[] = + { + /* Add EUR:5.01 to account 42 */ + { .oc = TBI_OC_ADMIN_ADD_INCOMING, + .label = "deposit-1", + .expected_response_code = MHD_HTTP_OK, + .details.admin_add_incoming.credit_account_no = 1, + .details.admin_add_incoming.debit_account_no = 2, + .details.admin_add_incoming.amount = "PUDOS:5.01" }, + + { .oc = TBI_OC_END } + }; + + TBI_run_interpreter (resultp, + GNUNET_YES, + commands); +} + + +/** + * Main function for the testcase for the bank API. + * + * @param argc expected to be 1 + * @param argv expected to only contain the program name + */ +int +main (int argc, + char * const *argv) +{ + int result; + + GNUNET_log_setup ("test-bank-api-with-fakebank", + "WARNING", + NULL); + GNUNET_SCHEDULER_run (&run, &result); + return (GNUNET_OK == result) ? 0 : 1; +} + +/* end of test_bank_api_with_fakebank.c */ diff --git a/src/bank-lib/test_bank_interpreter.c b/src/bank-lib/test_bank_interpreter.c new file mode 100644 index 000000000..7fff8be2f --- /dev/null +++ b/src/bank-lib/test_bank_interpreter.c @@ -0,0 +1,361 @@ +/* + This file is part of TALER + Copyright (C) 2016 GNUnet e.V. + + 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, If not, see +*/ +/** + * @file bank/test_bank_interpreter.c + * @brief interpreter for tests of the bank's HTTP API interface + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_signatures.h" +#include "taler_bank_service.h" +#include +#include +#include +#include "test_bank_interpreter.h" +#include "fakebank.h" + + +/** + * State of the interpreter loop. + */ +struct InterpreterState +{ + /** + * Keys from the bank. + */ + const struct TALER_BANK_Keys *keys; + + /** + * Commands the interpreter will run. + */ + struct TBI_Command *commands; + + /** + * Interpreter task (if one is scheduled). + */ + struct GNUNET_SCHEDULER_Task *task; + + /** + * Main execution context for the main loop. + */ + struct GNUNET_CURL_Context *ctx; + + /** + * Task run on timeout. + */ + struct GNUNET_SCHEDULER_Task *timeout_task; + + /** + * Context for running the main loop with GNUnet's SCHEDULER API. + */ + struct GNUNET_CURL_RescheduleContext *rc; + + /** + * Where to store the final result. + */ + int *resultp; + + /** + * Fakebank, or NULL if we are not using the fakebank. + */ + struct FAKEBANK_Handle *fakebank; + + /** + * Instruction pointer. Tells #interpreter_run() which + * instruction to run next. + */ + unsigned int ip; + +}; + + +/** + * The testcase failed, return with an error code. + * + * @param is interpreter state to clean up + */ +static void +fail (struct InterpreterState *is) +{ + *is->resultp = GNUNET_SYSERR; + GNUNET_SCHEDULER_shutdown (); +} + + +#if 0 +/** + * Find a command by label. + * + * @param is interpreter state to search + * @param label label to look for + * @return NULL if command was not found + */ +static const struct TBI_Command * +find_command (const struct InterpreterState *is, + const char *label) +{ + unsigned int i; + const struct TBI_Command *cmd; + + if (NULL == label) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Attempt to lookup command for empty label\n"); + return NULL; + } + for (i=0;TBI_OC_END != (cmd = &is->commands[i])->oc;i++) + if ( (NULL != cmd->label) && + (0 == strcmp (cmd->label, + label)) ) + return cmd; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Command not found: %s\n", + label); + return NULL; +} +#endif + + +/** + * Run the main interpreter loop that performs bank operations. + * + * @param cls contains the `struct InterpreterState` + */ +static void +interpreter_run (void *cls); + + +/** + * Function called upon completion of our /admin/add/incoming request. + * + * @param cls closure with the interpreter state + * @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) + * @param json detailed response from the HTTPD, or NULL if reply was not in JSON + */ +static void +add_incoming_cb (void *cls, + unsigned int http_status, + const json_t *json) +{ + struct InterpreterState *is = cls; + struct TBI_Command *cmd = &is->commands[is->ip]; + + cmd->details.admin_add_incoming.aih = NULL; + if (cmd->expected_response_code != http_status) + { + GNUNET_break (0); + fprintf (stderr, + "Unexpected response code %u:\n", + http_status); + if (NULL != json) + { + json_dumpf (json, stderr, 0); + fprintf (stderr, "\n"); + } + fail (is); + return; + } + is->ip++; + is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, + is); +} + + +/** + * Run the main interpreter loop that performs bank operations. + * + * @param cls contains the `struct InterpreterState` + */ +static void +interpreter_run (void *cls) +{ + struct InterpreterState *is = cls; + struct TBI_Command *cmd = &is->commands[is->ip]; + struct TALER_Amount amount; + const struct GNUNET_SCHEDULER_TaskContext *tc; + + is->task = NULL; + tc = GNUNET_SCHEDULER_get_task_context (); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + { + fprintf (stderr, + "Test aborted by shutdown request\n"); + fail (is); + return; + } + switch (cmd->oc) + { + case TBI_OC_END: + *is->resultp = GNUNET_OK; + GNUNET_SCHEDULER_shutdown (); + return; + case TBI_OC_ADMIN_ADD_INCOMING: + + if (GNUNET_OK != + TALER_string_to_amount (cmd->details.admin_add_incoming.amount, + &amount)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse amount `%s' at %u\n", + cmd->details.admin_add_incoming.amount, + is->ip); + fail (is); + return; + } + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &cmd->details.admin_add_incoming.wtid, + sizeof (cmd->details.admin_add_incoming.wtid)); + cmd->details.admin_add_incoming.aih + = TALER_BANK_admin_add_incoming (is->ctx, + "http://localhost:8081", + &cmd->details.admin_add_incoming.wtid, + &amount, + cmd->details.admin_add_incoming.debit_account_no, + cmd->details.admin_add_incoming.credit_account_no, + &add_incoming_cb, + is); + if (NULL == cmd->details.admin_add_incoming.aih) + { + GNUNET_break (0); + fail (is); + return; + } + return; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unknown instruction %d at %u (%s)\n", + cmd->oc, + is->ip, + cmd->label); + fail (is); + return; + } +} + + +/** + * Function run on timeout. + * + * @param cls the `struct InterpreterState` + */ +static void +do_timeout (void *cls) +{ + struct InterpreterState *is = cls; + + is->timeout_task = NULL; + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Function run when the test terminates (good or bad). + * Cleans up our state. + * + * @param cls the interpreter state. + */ +static void +do_shutdown (void *cls) +{ + struct InterpreterState *is = cls; + struct TBI_Command *cmd; + unsigned int i; + + if (NULL != is->timeout_task) + { + GNUNET_SCHEDULER_cancel (is->timeout_task); + is->timeout_task = NULL; + } + + for (i=0;TBI_OC_END != (cmd = &is->commands[i])->oc;i++) + { + switch (cmd->oc) + { + case TBI_OC_END: + GNUNET_assert (0); + break; + case TBI_OC_ADMIN_ADD_INCOMING: + if (NULL != cmd->details.admin_add_incoming.aih) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Command %u (%s) did not complete\n", + i, + cmd->label); + TALER_BANK_admin_add_incoming_cancel (cmd->details.admin_add_incoming.aih); + cmd->details.admin_add_incoming.aih = NULL; + } + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unknown instruction %d at %u (%s)\n", + cmd->oc, + i, + cmd->label); + break; + } + } + if (NULL != is->task) + { + GNUNET_SCHEDULER_cancel (is->task); + is->task = NULL; + } + if (NULL != is->fakebank) + { + FAKEBANK_stop (is->fakebank); + is->fakebank = NULL; + } + GNUNET_CURL_fini (is->ctx); + is->ctx = NULL; + GNUNET_CURL_gnunet_rc_destroy (is->rc); + GNUNET_free (is); +} + + +/** + * Entry point to the interpeter. + * + * @param resultp where to store the final result + * @param run_bank #GNUNET_YES to run the fakebank + * @param commands list of commands to run + */ +void +TBI_run_interpreter (int *resultp, + int run_bank, + struct TBI_Command *commands) +{ + struct InterpreterState *is; + + is = GNUNET_new (struct InterpreterState); + if (GNUNET_YES == run_bank) + is->fakebank = FAKEBANK_start (8081); + is->resultp = resultp; + is->commands = commands; + is->ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, + &is->rc); + GNUNET_assert (NULL != is->ctx); + is->rc = GNUNET_CURL_gnunet_rc_create (is->ctx); + is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, + is); + is->timeout_task + = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 150), + &do_timeout, is); + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, is); +} + +/* end of test_bank_interpeter.c */ diff --git a/src/bank-lib/test_bank_interpreter.h b/src/bank-lib/test_bank_interpreter.h new file mode 100644 index 000000000..f54986973 --- /dev/null +++ b/src/bank-lib/test_bank_interpreter.h @@ -0,0 +1,127 @@ +/* + This file is part of TALER + Copyright (C) 2016 GNUnet e.V. + + 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, If not, see +*/ +/** + * @file bank/test_bank_interpreter.h + * @brief interpreter for tests of the bank's HTTP API interface + * @author Christian Grothoff + */ +#ifndef TEST_BANK_INTERPRETER_H +#define TEST_BANK_INTERPRETER_H + +#include "taler_util.h" +#include "taler_signatures.h" +#include "taler_bank_service.h" +#include +#include +#include + + +/** + * Opcodes for the interpreter. + */ +enum TBI_OpCode +{ + /** + * Termination code, stops the interpreter loop (with success). + */ + TBI_OC_END = 0, + + /** + * Add funds to a reserve by (faking) incoming wire transfer. + */ + TBI_OC_ADMIN_ADD_INCOMING + +}; + + +/** + * Details for a bank operation to execute. + */ +struct TBI_Command +{ + /** + * Opcode of the command. + */ + enum TBI_OpCode oc; + + /** + * Label for the command, can be NULL. + */ + const char *label; + + /** + * Which response code do we expect for this command? + */ + unsigned int expected_response_code; + + /** + * Details about the command. + */ + union + { + + /** + * Information for a #TBI_OC_ADMIN_ADD_INCOMING command. + */ + struct + { + + /** + * String describing the amount to add to the reserve. + */ + const char *amount; + + /** + * Credited account number. + */ + uint64_t credit_account_no; + + /** + * Debited account number. + */ + uint64_t debit_account_no; + + /** + * Wire transfer identifier to use. Initialized to + * a random value. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * Set to the API's handle during the operation. + */ + struct TALER_BANK_AdminAddIncomingHandle *aih; + + } admin_add_incoming; + + } details; + +}; + + +/** + * Entry point to the interpeter. + * + * @param resultp where to store the final result + * @param run_bank #GNUNET_YES to run the fakebank + * @param commands list of commands to run + */ +void +TBI_run_interpreter (int *resultp, + int run_bank, + struct TBI_Command *commands); + +#endif diff --git a/src/exchange-lib/exchange_api_handle.c b/src/exchange-lib/exchange_api_handle.c index 47658052d..04508aa34 100644 --- a/src/exchange-lib/exchange_api_handle.c +++ b/src/exchange-lib/exchange_api_handle.c @@ -247,7 +247,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, { struct GNUNET_TIME_Absolute valid_from; struct GNUNET_TIME_Absolute withdraw_valid_until; - struct GNUNET_TIME_Absolute deposit_valid_until; + struct GNUNET_TIME_Absolute expire_deposit; struct GNUNET_TIME_Absolute expire_legal; struct TALER_Amount value; struct TALER_Amount fee_withdraw; @@ -262,7 +262,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, GNUNET_JSON_spec_fixed_auto ("master_sig", &sig), GNUNET_JSON_spec_absolute_time ("stamp_expire_deposit", - &deposit_valid_until), + &expire_deposit), GNUNET_JSON_spec_absolute_time ("stamp_expire_withdraw", &withdraw_valid_until), GNUNET_JSON_spec_absolute_time ("stamp_start", @@ -302,7 +302,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, denom_key_issue.master = *master_key; denom_key_issue.start = GNUNET_TIME_absolute_hton (valid_from); denom_key_issue.expire_withdraw = GNUNET_TIME_absolute_hton (withdraw_valid_until); - denom_key_issue.expire_spend = GNUNET_TIME_absolute_hton (deposit_valid_until); + denom_key_issue.expire_deposit = GNUNET_TIME_absolute_hton (expire_deposit); denom_key_issue.expire_legal = GNUNET_TIME_absolute_hton (expire_legal); TALER_amount_hton (&denom_key_issue.value, &value); @@ -326,7 +326,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, denom_key->h_key = denom_key_issue.denom_hash; denom_key->valid_from = valid_from; denom_key->withdraw_valid_until = withdraw_valid_until; - denom_key->deposit_valid_until = deposit_valid_until; + denom_key->expire_deposit = expire_deposit; denom_key->expire_legal = expire_legal; denom_key->value = value; denom_key->fee_withdraw = fee_withdraw; @@ -431,7 +431,7 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor, } kv.start = GNUNET_TIME_absolute_hton (dk->valid_from); kv.expire_withdraw = GNUNET_TIME_absolute_hton (dk->withdraw_valid_until); - kv.expire_spend = GNUNET_TIME_absolute_hton (dk->deposit_valid_until); + kv.expire_deposit = GNUNET_TIME_absolute_hton (dk->expire_deposit); kv.expire_legal = GNUNET_TIME_absolute_hton (dk->expire_legal); TALER_amount_hton (&kv.value, &dk->value); diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c index 5fe175672..f112152ca 100644 --- a/src/exchange-lib/exchange_api_refresh.c +++ b/src/exchange-lib/exchange_api_refresh.c @@ -73,7 +73,7 @@ struct MeltedCoinP /** * Timestamp indicating when coins of this denomination become invalid. */ - struct GNUNET_TIME_AbsoluteNBO deposit_valid_until; + struct GNUNET_TIME_AbsoluteNBO expire_deposit; /** * Size of the encoded public key that follows. @@ -189,7 +189,7 @@ struct MeltedCoin /** * Timestamp indicating when coins of this denomination become invalid. */ - struct GNUNET_TIME_Absolute deposit_valid_until; + struct GNUNET_TIME_Absolute expire_deposit; /** * Denomination key of the original coin. @@ -396,7 +396,7 @@ serialize_melted_coin (const struct MeltedCoin *mc, &mc->original_value); for (i=0;itransfer_priv[i]; - mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until); + mcp.expire_deposit = GNUNET_TIME_absolute_hton (mc->expire_deposit); mcp.pbuf_size = htons ((uint16_t) pbuf_size); mcp.sbuf_size = htons ((uint16_t) sbuf_size); memcpy (&buf[off], @@ -478,7 +478,7 @@ deserialize_melted_coin (struct MeltedCoin *mc, &mcp.original_value); for (i=0;itransfer_priv[i] = mcp.transfer_priv[i]; - mc->deposit_valid_until = GNUNET_TIME_absolute_ntoh (mcp.deposit_valid_until); + mc->expire_deposit = GNUNET_TIME_absolute_ntoh (mcp.expire_deposit); return off; } @@ -891,8 +891,8 @@ TALER_EXCHANGE_refresh_prepare (unsigned int num_melts, md.melted_coins[i].transfer_priv[j].ecdhe_priv = *tpk; GNUNET_free (tpk); } - md.melted_coins[i].deposit_valid_until - = melt_pks[i].deposit_valid_until; + md.melted_coins[i].expire_deposit + = melt_pks[i].expire_deposit; md.melted_coins[i].pub_key.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (melt_pks[i].key.rsa_public_key); md.melted_coins[i].sig.rsa_signature diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 2936f68fb..e48c59b2a 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -48,14 +48,14 @@ static struct GNUNET_CURL_Context *ctx; static struct TALER_EXCHANGE_Handle *exchange; /** - * Task run on shutdown. + * Context for running the CURL event loop. */ -static struct GNUNET_SCHEDULER_Task *shutdown_task; +static struct GNUNET_CURL_RescheduleContext *rc; /** - * Task that runs the main event loop. + * Task run on timeout. */ -static struct GNUNET_SCHEDULER_Task *ctx_task; +static struct GNUNET_SCHEDULER_Task *timeout_task; /** * Result of the testcases, #GNUNET_OK on success @@ -569,27 +569,6 @@ struct InterpreterState }; -/** - * Task that runs the context's event loop with the GNUnet scheduler. - * - * @param cls unused - */ -static void -context_task (void *cls); - - -/** - * Run the context task, the working set has changed. - */ -static void -trigger_context_task () -{ - GNUNET_SCHEDULER_cancel (ctx_task); - ctx_task = GNUNET_SCHEDULER_add_now (&context_task, - NULL); -} - - /** * The testcase failed, return with an error code. * @@ -1499,7 +1478,6 @@ interpreter_run (void *cls) fail (is); return; } - trigger_context_task (); return; case OC_WITHDRAW_STATUS: GNUNET_assert (NULL != @@ -1515,7 +1493,6 @@ interpreter_run (void *cls) &reserve_pub, &reserve_status_cb, is); - trigger_context_task (); return; case OC_WITHDRAW_SIGN: GNUNET_assert (NULL != @@ -1575,7 +1552,6 @@ interpreter_run (void *cls) fail (is); return; } - trigger_context_task (); return; case OC_DEPOSIT: { @@ -1728,7 +1704,6 @@ interpreter_run (void *cls) return; } json_decref (wire); - trigger_context_task (); return; } case OC_REFRESH_MELT: @@ -1826,7 +1801,6 @@ interpreter_run (void *cls) } } } - trigger_context_task (); return; case OC_REFRESH_REVEAL: ref = find_command (is, @@ -1845,7 +1819,6 @@ interpreter_run (void *cls) fail (is); return; } - trigger_context_task (); return; case OC_REFRESH_LINK: /* find reveal command */ @@ -1885,13 +1858,11 @@ interpreter_run (void *cls) fail (is); return; } - trigger_context_task (); return; case OC_WIRE: cmd->details.wire.wh = TALER_EXCHANGE_wire (exchange, &wire_cb, is); - trigger_context_task (); return; case OC_WIRE_DEPOSITS: if (NULL != cmd->details.wire_deposits.wtid_ref) @@ -1906,7 +1877,6 @@ interpreter_run (void *cls) &cmd->details.wire_deposits.wtid, &wire_deposits_cb, is); - trigger_context_task (); return; case OC_DEPOSIT_WTID: { @@ -1969,7 +1939,6 @@ interpreter_run (void *cls) ref->details.deposit.transaction_id, &deposit_wtid_cb, is); - trigger_context_task (); } return; default: @@ -1984,6 +1953,19 @@ interpreter_run (void *cls) } +/** + * Function run when the test terminates (good or bad) with timeout. + * + * @param cls NULL + */ +static void +do_timeout (void *cls) +{ + timeout_task = NULL; + GNUNET_SCHEDULER_shutdown (); +} + + /** * Function run when the test terminates (good or bad). * Cleans up our state. @@ -1997,7 +1979,6 @@ do_shutdown (void *cls) struct Command *cmd; unsigned int i; - shutdown_task = NULL; for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++) { switch (cmd->oc) @@ -2156,11 +2137,6 @@ do_shutdown (void *cls) is->task = NULL; } GNUNET_free (is); - if (NULL != ctx_task) - { - GNUNET_SCHEDULER_cancel (ctx_task); - ctx_task = NULL; - } if (NULL != exchange) { TALER_EXCHANGE_disconnect (exchange); @@ -2171,6 +2147,16 @@ do_shutdown (void *cls) GNUNET_CURL_fini (ctx); ctx = NULL; } + if (NULL != rc) + { + GNUNET_CURL_gnunet_rc_destroy (rc); + rc = NULL; + } + if (NULL != timeout_task) + { + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = NULL; + } } @@ -2208,60 +2194,6 @@ cert_cb (void *cls, } -/** - * Task that runs the context's event loop with the GNUnet scheduler. - * - * @param cls unused - */ -static void -context_task (void *cls) -{ - long timeout; - int max_fd; - fd_set read_fd_set; - fd_set write_fd_set; - fd_set except_fd_set; - struct GNUNET_NETWORK_FDSet *rs; - struct GNUNET_NETWORK_FDSet *ws; - struct GNUNET_TIME_Relative delay; - - ctx_task = NULL; - GNUNET_CURL_perform (ctx); - max_fd = -1; - timeout = -1; - FD_ZERO (&read_fd_set); - FD_ZERO (&write_fd_set); - FD_ZERO (&except_fd_set); - GNUNET_CURL_get_select_info (ctx, - &read_fd_set, - &write_fd_set, - &except_fd_set, - &max_fd, - &timeout); - if (timeout >= 0) - delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, - timeout); - else - delay = GNUNET_TIME_UNIT_FOREVER_REL; - rs = GNUNET_NETWORK_fdset_create (); - GNUNET_NETWORK_fdset_copy_native (rs, - &read_fd_set, - max_fd + 1); - ws = GNUNET_NETWORK_fdset_create (); - GNUNET_NETWORK_fdset_copy_native (ws, - &write_fd_set, - max_fd + 1); - ctx_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - delay, - rs, - ws, - &context_task, - cls); - GNUNET_NETWORK_fdset_destroy (rs); - GNUNET_NETWORK_fdset_destroy (ws); -} - - /** * Main function that will be run by the scheduler. * @@ -2507,19 +2439,20 @@ run (void *cls) is = GNUNET_new (struct InterpreterState); is->commands = commands; - ctx = GNUNET_CURL_init (); + ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, + &rc); + rc = GNUNET_CURL_gnunet_rc_create (ctx); GNUNET_assert (NULL != ctx); - ctx_task = GNUNET_SCHEDULER_add_now (&context_task, - ctx); exchange = TALER_EXCHANGE_connect (ctx, "http://localhost:8081", &cert_cb, is, TALER_EXCHANGE_OPTION_END); GNUNET_assert (NULL != exchange); - shutdown_task + timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 150), - &do_shutdown, is); + &do_timeout, NULL); + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, is); } diff --git a/src/exchange-lib/test_exchange_api.conf b/src/exchange-lib/test_exchange_api.conf index 5fcc36552..a8c690786 100644 --- a/src/exchange-lib/test_exchange_api.conf +++ b/src/exchange-lib/test_exchange_api.conf @@ -30,12 +30,17 @@ TESTRUN = YES [exchangedb-postgres] DB_CONN_STR = "postgres:///talercheck" -[wire-incoming-test] +[exchange-wire-incoming-sepa] +# This is the response we give out for the /wire request. It provides +# wallets with the bank information for transfers to the exchange. +SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json + +[exchange-wire-incoming-test] # This is the response we give out for the /wire request. It provides # wallets with the bank information for transfers to the exchange. TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json -[wire-outgoing-test] +[exchange-wire-outgoing-test] # What is the main website of the bank? BANK_URI = "http://localhost:8082/" # Into which account at the 'bank' should (incoming) wire transfers be made? diff --git a/src/exchange-tools/taler-auditor-sign.c b/src/exchange-tools/taler-auditor-sign.c index 71c80f5ee..3652bc9e6 100644 --- a/src/exchange-tools/taler-auditor-sign.c +++ b/src/exchange-tools/taler-auditor-sign.c @@ -118,7 +118,7 @@ print_dk (const struct TALER_DenominationKeyValidityPS *dk) GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_withdraw))); fprintf (stdout, "Deposit end time: %s\n", - GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_spend))); + GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_deposit))); fprintf (stdout, "Legal dispute end time: %s\n", GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_legal))); @@ -320,7 +320,7 @@ main (int argc, print_dk (dk); kv.start = dk->start; kv.expire_withdraw = dk->expire_withdraw; - kv.expire_spend = dk->expire_spend; + kv.expire_deposit = dk->expire_deposit; kv.expire_legal = dk->expire_legal; kv.value = dk->value; kv.fee_withdraw = dk->fee_withdraw; diff --git a/src/exchange-tools/taler-exchange-dbinit.c b/src/exchange-tools/taler-exchange-dbinit.c index f936e64d6..e51f5a21a 100644 --- a/src/exchange-tools/taler-exchange-dbinit.c +++ b/src/exchange-tools/taler-exchange-dbinit.c @@ -54,8 +54,7 @@ run (void *cls, return; } if (GNUNET_OK != - plugin->create_tables (plugin->cls, - GNUNET_NO)) + plugin->create_tables (plugin->cls)) { fprintf (stderr, "Failed to initialize database.\n"); diff --git a/src/exchange-tools/taler-exchange-keycheck.c b/src/exchange-tools/taler-exchange-keycheck.c index dbe156526..103de138c 100644 --- a/src/exchange-tools/taler-exchange-keycheck.c +++ b/src/exchange-tools/taler-exchange-keycheck.c @@ -145,7 +145,7 @@ denomkeys_iter (void *cls, if ( (0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us % 1000000) || (0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_withdraw).abs_value_us % 1000000) || (0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_legal).abs_value_us % 1000000) || - (0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us % 1000000) ) + (0 != GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit).abs_value_us % 1000000) ) { fprintf (stderr, "Timestamps are not multiples of a round second\n"); diff --git a/src/exchange-tools/taler-exchange-keyup.c b/src/exchange-tools/taler-exchange-keyup.c index 0cd9a30ca..155861936 100644 --- a/src/exchange-tools/taler-exchange-keyup.c +++ b/src/exchange-tools/taler-exchange-keyup.c @@ -765,7 +765,7 @@ create_denomkey_issue (const struct CoinTypeParams *params, dki->issue.properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (params->anchor, params->duration_withdraw)); - dki->issue.properties.expire_spend = + dki->issue.properties.expire_deposit = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (params->anchor, params->duration_spend)); dki->issue.properties.expire_legal = diff --git a/src/exchange-tools/taler-exchange-reservemod.c b/src/exchange-tools/taler-exchange-reservemod.c index de3e57f1f..2aeb951ce 100644 --- a/src/exchange-tools/taler-exchange-reservemod.c +++ b/src/exchange-tools/taler-exchange-reservemod.c @@ -73,8 +73,7 @@ run_transaction (const struct TALER_ReservePublicKeyP *reserve_pub, int ret; struct TALER_EXCHANGEDB_Session *session; - session = plugin->get_session (plugin->cls, - GNUNET_NO); + session = plugin->get_session (plugin->cls); if (NULL == session) { fprintf (stderr, diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 57eab8138..4732e4e18 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -173,7 +173,7 @@ static struct AggregationUnit *au; static int global_ret; /** - * #GNUNET_YES if we are in test mode and are using temporary tables. + * #GNUNET_YES if we are in test mode and should exit when idle. */ static int test_mode; @@ -518,8 +518,7 @@ run_aggregation (void *cls) return; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Checking for ready deposits to aggregate\n"); - if (NULL == (session = db_plugin->get_session (db_plugin->cls, - test_mode))) + if (NULL == (session = db_plugin->get_session (db_plugin->cls))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to obtain database session!\n"); @@ -891,8 +890,7 @@ run_transfers (void *cls) tc = GNUNET_SCHEDULER_get_task_context (); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - if (NULL == (session = db_plugin->get_session (db_plugin->cls, - test_mode))) + if (NULL == (session = db_plugin->get_session (db_plugin->cls))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to obtain database session!\n"); @@ -987,7 +985,7 @@ main (int argc, "wireformat to use, overrides WIREFORMAT option in [exchange] section", 1, &GNUNET_GETOPT_set_filename, &exchange_wireformat}, {'t', "test", NULL, - "run in test mode with temporary tables", 0, + "run in test mode and exit when idle", 0, &GNUNET_GETOPT_set_one, &test_mode}, GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), GNUNET_GETOPT_OPTION_END diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 11f2e1c9d..5f9f51422 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -80,11 +80,6 @@ struct TALER_MasterPublicKeyP TMH_master_public_key; */ struct TALER_EXCHANGEDB_Plugin *TMH_plugin; -/** - * Are we running in test mode? - */ -int TMH_test_mode; - /** * Default timeout in seconds for HTTP requests. */ @@ -466,9 +461,7 @@ exchange_serve_process_config () { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running in TEST mode! Database contents will not persist!\n"); - TMH_test_mode = GNUNET_YES; - TMH_plugin->create_tables (TMH_plugin->cls, - GNUNET_YES); + TMH_plugin->create_tables (TMH_plugin->cls); } { @@ -906,19 +899,6 @@ main (int argc, MHD_stop_daemon (mydaemon); break; } - - if (GNUNET_YES == TMH_test_mode) - { - struct TALER_EXCHANGEDB_Session *session; - - session = TMH_plugin->get_session (TMH_plugin->cls, - GNUNET_YES); - if (NULL == session) - GNUNET_break (0); - else - TMH_plugin->drop_temporary (TMH_plugin->cls, - session); - } TALER_EXCHANGEDB_plugin_unload (TMH_plugin); TMH_VALIDATION_done (); return (GNUNET_SYSERR == ret) ? 1 : 0; diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index 236df9e19..54e382f52 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -43,11 +43,6 @@ extern int TMH_exchange_connection_close; */ extern struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Are we running in test mode? - */ -extern int TMH_test_mode; - /** * Main directory with exchange data. */ diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 4b6b458ce..237a1aa7c 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -160,8 +160,7 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; int ret; - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -278,8 +277,7 @@ TMH_DB_execute_reserve_status (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_ReserveHistory *rh; int res; - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -524,8 +522,7 @@ TMH_DB_execute_reserve_withdraw (struct MHD_Connection *connection, GNUNET_CRYPTO_hash (blinded_msg, blinded_msg_len, &h_blind); - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -725,8 +722,7 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, int res; unsigned int i; - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -1237,8 +1233,7 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection, unsigned int j; unsigned int off; - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -1465,8 +1460,7 @@ TMH_DB_execute_refresh_link (struct MHD_Connection *connection, int res; unsigned int i; - if (NULL == (ctx.session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (ctx.session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -1528,8 +1522,7 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_Session *session; int ret; - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -1713,8 +1706,7 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_Session *session; struct TMH_WireDepositDetail *wdd; - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); @@ -1879,8 +1871,7 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, struct DepositWtidContext ctx; struct TALER_EXCHANGEDB_Session *session; - if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode))) + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls))) { GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c index e16d3a62e..2f5069d4a 100644 --- a/src/exchange/taler-exchange-httpd_keystate.c +++ b/src/exchange/taler-exchange-httpd_keystate.c @@ -155,7 +155,7 @@ denom_key_issue_to_json (const struct TALER_DenominationPublicKey *pk, "stamp_expire_withdraw", GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw)), "stamp_expire_deposit", - GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_spend)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_deposit)), "stamp_expire_legal", GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_legal)), "denom_pub", @@ -236,7 +236,7 @@ reload_keys_denom_iter (void *cls, return GNUNET_OK; } now = GNUNET_TIME_absolute_get (); - if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us < + if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit).abs_value_us < now.abs_value_us) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -250,8 +250,7 @@ reload_keys_denom_iter (void *cls, GNUNET_CRYPTO_hash_context_read (ctx->hash_context, &denom_key_hash, sizeof (struct GNUNET_HashCode)); - session = TMH_plugin->get_session (TMH_plugin->cls, - TMH_test_mode); + session = TMH_plugin->get_session (TMH_plugin->cls); if (NULL == session) return GNUNET_SYSERR; /* Try to insert DKI into DB until we succeed; note that if the DB @@ -749,7 +748,7 @@ TMH_KS_denomination_key_lookup (const struct TMH_KS_StateHandle *key_state, break; case TMH_KS_DKU_DEPOSIT: if (now.abs_value_us > - GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us) + GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit).abs_value_us) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Not returning DKI for %s, as time to spend coin has passed\n", diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index 7d1991754..d38d07906 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -285,8 +285,8 @@ shutdown_action (void *cls) GNUNET_OS_process_destroy (aggregator_proc); aggregator_proc = NULL; } - plugin->drop_temporary (plugin->cls, - session); + plugin->drop_tables (plugin->cls, + session); TALER_EXCHANGEDB_plugin_unload (plugin); plugin = NULL; } @@ -304,11 +304,9 @@ maint_child_death (void *cls) const struct GNUNET_DISK_FileHandle *pr; char c[16]; struct State *state; - const struct GNUNET_SCHEDULER_TaskContext *tc; child_death_task = NULL; pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); - tc = GNUNET_SCHEDULER_get_task_context (); GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c))); GNUNET_OS_process_wait (aggregator_proc); GNUNET_OS_process_destroy (aggregator_proc); @@ -1108,8 +1106,7 @@ run (void *cls) plugin = TALER_EXCHANGEDB_plugin_load (cfg); if (GNUNET_OK != - plugin->create_tables (plugin->cls, - GNUNET_YES)) + plugin->create_tables (plugin->cls)) { GNUNET_break (0); TALER_EXCHANGEDB_plugin_unload (plugin); @@ -1117,8 +1114,7 @@ run (void *cls) result = 77; return; } - session = plugin->get_session (plugin->cls, - GNUNET_YES); + session = plugin->get_session (plugin->cls); GNUNET_assert (NULL != session); fake_issue (&issue); dpk.rsa_public_key = coin_pub; diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index 83be82a23..fc87feea1 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -56,7 +56,6 @@ libtalerexchangedb_la_LDFLAGS = \ check_PROGRAMS = \ - test-exchangedb-deposits \ test-exchangedb-keyio \ test-exchangedb-postgres \ test-perf-taler-exchangedb \ @@ -65,17 +64,8 @@ check_PROGRAMS = \ AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; TESTS = \ test-exchangedb-postgres \ - test-perf-taler-exchangedb - -test_exchangedb_deposits_SOURCES = \ - test_exchangedb_deposits.c -test_exchangedb_deposits_LDADD = \ - libtalerexchangedb.la \ - $(top_srcdir)/src/util/libtalerutil.la \ - $(top_srcdir)/src/pq/libtalerpq.la \ - -lgnunetutil \ - -ljansson \ - -lpq + test-perf-taler-exchangedb \ + test-exchangedb-keyio test_exchangedb_keyio_SOURCES = \ test_exchangedb_keyio.c diff --git a/src/exchangedb/perf_taler_exchangedb_init.c b/src/exchangedb/perf_taler_exchangedb_init.c index 67ac56c77..2d018bdf0 100644 --- a/src/exchangedb/perf_taler_exchangedb_init.c +++ b/src/exchangedb/perf_taler_exchangedb_init.c @@ -66,7 +66,7 @@ PERF_TALER_EXCHANGEDB_denomination_init () &properties.master.eddsa_pub); properties.start = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get()); properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); - properties.expire_spend = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); + properties.expire_deposit = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); properties.expire_legal = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.1", &amount)); diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c b/src/exchangedb/perf_taler_exchangedb_interpreter.c index 78b58a5ae..cb805a0b3 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.c +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c @@ -1369,7 +1369,7 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) break; case PERF_TALER_EXCHANGEDB_CMD_NEW_SESSION: - state->session = state->plugin->get_session (state->plugin->cls, GNUNET_YES); + state->session = state->plugin->get_session (state->plugin->cls); break; case PERF_TALER_EXCHANGEDB_CMD_START_TRANSACTION: @@ -1816,8 +1816,7 @@ PERF_TALER_EXCHANGEDB_interpret (struct TALER_EXCHANGEDB_Plugin *db_plugin, ret = cmd_init (cmd); if (GNUNET_SYSERR == ret) return ret; - state.session = db_plugin->get_session (db_plugin->cls, - GNUNET_YES); + state.session = db_plugin->get_session (db_plugin->cls); GNUNET_assert (NULL != state.session); ret = interpret (&state); cmd_clean (cmd); @@ -1833,7 +1832,8 @@ PERF_TALER_EXCHANGEDB_interpret (struct TALER_EXCHANGEDB_Plugin *db_plugin, * @param init the commands to use for the database initialisation, * if #NULL the standard initialization is used * @param benchmark the commands for the benchmark - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure, #GNUNET_NO + * if we failed to init the database */ int PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name, @@ -1940,15 +1940,14 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error connectiong to the database\n"); - return ret; + return GNUNET_NO; } - ret = plugin->create_tables (plugin->cls, - GNUNET_YES); + ret = plugin->create_tables (plugin->cls); if (GNUNET_OK != ret) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error while creating the database architecture\n"); - return ret; + return GNUNET_NO; } /* * Running the initialization @@ -1958,7 +1957,7 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name, init = init_def; } ret = PERF_TALER_EXCHANGEDB_interpret (plugin, - init); + init); if (GNUNET_OK != ret) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1980,10 +1979,9 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name, { struct TALER_EXCHANGEDB_Session *session; - session = plugin->get_session (plugin->cls, - GNUNET_YES); - ret = plugin->drop_temporary (plugin->cls, - session); + session = plugin->get_session (plugin->cls); + ret = plugin->drop_tables (plugin->cls, + session); if (GNUNET_OK != ret) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.h b/src/exchangedb/perf_taler_exchangedb_interpreter.h index a83251c60..1c2659dd1 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.h +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.h @@ -467,7 +467,7 @@ /** * Get informations about a refresh session - * + * * @param _label the label of the command * @param _label_hash the label of the hash to search */ @@ -933,8 +933,8 @@ union PERF_TALER_EXCHANGEDB_CMD_Details */ const char *label_denom; unsigned int index_denom; - } insert_denomination; - + } insert_denomination; + /** * Extra data requiered by the #PERF_TALER_EXCHANGEDB_CMD_GET_DENOMINATION command */ @@ -1283,13 +1283,14 @@ struct PERF_TALER_EXCHANGEDB_Cmd * @param init the commands to use for the database initialisation, * if #NULL the standard initialization is used * @param benchmark the commands for the benchmark - * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure, + * #GNUNET_NO if we failed to init the database */ int PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name, - const char *configuration_file, - struct PERF_TALER_EXCHANGEDB_Cmd *init, - struct PERF_TALER_EXCHANGEDB_Cmd *benchmark); + const char *configuration_file, + struct PERF_TALER_EXCHANGEDB_Cmd *init, + struct PERF_TALER_EXCHANGEDB_Cmd *benchmark); /** @@ -1300,9 +1301,8 @@ PERF_TALER_EXCHANGEDB_run_benchmark (const char *benchmark_name, * @param cmd the commands to run */ int -PERF_TALER_EXCHANGEDB_interpret( - struct TALER_EXCHANGEDB_Plugin *db_plugin, - struct PERF_TALER_EXCHANGEDB_Cmd cmd[]); +PERF_TALER_EXCHANGEDB_interpret(struct TALER_EXCHANGEDB_Plugin *db_plugin, + struct PERF_TALER_EXCHANGEDB_Cmd cmd[]); /** diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index d69fa7d61..1cc64ce4d 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -29,15 +29,6 @@ #include "plugin_exchangedb_common.c" -/** - * For testing / experiments, we set the Postgres schema to - * #TALER_TEMP_SCHEMA_NAME so we can easily purge everything - * associated with a test. We *also* should use the database - * "talercheck" instead of "taler" for testing, but we're doing - * both: better safe than sorry. - */ -#define TALER_TEMP_SCHEMA_NAME "taler_temporary" - /** * Log a query error. * @@ -138,39 +129,48 @@ struct PostgresClosure -/** - * Set the given connection to use a temporary schema - * - * @param db the database connection - * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon error - */ -static int -set_temporary_schema (PGconn *db) -{ - SQLEXEC_(db, - "CREATE SCHEMA IF NOT EXISTS " TALER_TEMP_SCHEMA_NAME ";" - "SET search_path to " TALER_TEMP_SCHEMA_NAME ";"); - return GNUNET_OK; - SQLEXEC_fail: - return GNUNET_SYSERR; -} - /** - * Drop the temporary taler schema. This is only useful for testcases + * Drop all Taler tables. This should only be used by testcases. * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param session database session to use * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ static int -postgres_drop_temporary (void *cls, - struct TALER_EXCHANGEDB_Session *session) +postgres_drop_tables (void *cls, + struct TALER_EXCHANGEDB_Session *session) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Dropping temporary tables\n"); + "Dropping ALL tables\n"); SQLEXEC_ (session->conn, - "DROP SCHEMA " TALER_TEMP_SCHEMA_NAME " CASCADE;"); + "DROP TABLE IF EXISTS prewire;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS aggregation_tracking;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS deposits;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS refresh_out;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS refresh_commit_coin;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS refresh_commit_link;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS refresh_order;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS refresh_melts;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS refresh_sessions;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS known_coins;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS reserves_out;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS reserves_in;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS reserves;"); + SQLEXEC_ (session->conn, + "DROP TABLE IF EXISTS denominations;"); return GNUNET_OK; SQLEXEC_fail: return GNUNET_SYSERR; @@ -215,12 +215,10 @@ pq_notice_processor_cb (void *arg, * Create the necessary tables if they are not present * * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param temporary should we use a temporary schema * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ static int -postgres_create_tables (void *cls, - int temporary) +postgres_create_tables (void *cls) { struct PostgresClosure *pc = cls; PGconn *conn; @@ -239,12 +237,6 @@ postgres_create_tables (void *cls, PQsetNoticeProcessor (conn, &pq_notice_processor_cb, NULL); - if ( (GNUNET_YES == temporary) && - (GNUNET_SYSERR == set_temporary_schema (conn))) - { - PQfinish (conn); - return GNUNET_SYSERR; - } #define SQLEXEC(sql) SQLEXEC_(conn, sql); #define SQLEXEC_INDEX(sql) SQLEXEC_IGNORE_ERROR_(conn, sql); /* Denomination table for holding the publicly available information of @@ -258,7 +250,7 @@ postgres_create_tables (void *cls, ",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)" ",valid_from INT8 NOT NULL" ",expire_withdraw INT8 NOT NULL" - ",expire_spend INT8 NOT NULL" + ",expire_deposit INT8 NOT NULL" ",expire_legal INT8 NOT NULL" ",coin_val INT8 NOT NULL" /* value of this denom */ ",coin_frac INT4 NOT NULL" /* fractional value of this denom */ @@ -533,7 +525,7 @@ postgres_prepare (PGconn *db_conn) ",master_sig" ",valid_from" ",expire_withdraw" - ",expire_spend" + ",expire_deposit" ",expire_legal" ",coin_val" /* value of this denom */ ",coin_frac" /* fractional value of this denom */ @@ -563,7 +555,7 @@ postgres_prepare (PGconn *db_conn) ",master_sig" ",valid_from" ",expire_withdraw" - ",expire_spend" + ",expire_deposit" ",expire_legal" ",coin_val" /* value of this denom */ ",coin_frac" /* fractional value of this denom */ @@ -1200,13 +1192,10 @@ db_conn_destroy (void *cls) * Connect to the db if the connection does not exist yet. * * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param temporary #GNUNET_YES to use a temporary schema; #GNUNET_NO to use the - * database default one * @return the database connection, or NULL on error */ static struct TALER_EXCHANGEDB_Session * -postgres_get_session (void *cls, - int temporary) +postgres_get_session (void *cls) { struct PostgresClosure *pc = cls; PGconn *db_conn; @@ -1229,12 +1218,6 @@ postgres_get_session (void *cls, PQsetNoticeProcessor (db_conn, &pq_notice_processor_cb, NULL); - if ( (GNUNET_YES == temporary) && - (GNUNET_SYSERR == set_temporary_schema(db_conn)) ) - { - GNUNET_break (0); - return NULL; - } if (GNUNET_OK != postgres_prepare (db_conn)) { @@ -1382,7 +1365,7 @@ postgres_insert_denomination_info (void *cls, GNUNET_PQ_query_param_auto_from_type (&issue->signature), GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.start), GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_withdraw), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_spend), + GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_deposit), GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_legal), TALER_PQ_query_param_amount_nbo (&issue->properties.value), TALER_PQ_query_param_amount_nbo (&issue->properties.fee_withdraw), @@ -1478,8 +1461,8 @@ postgres_get_denomination_info (void *cls, &issue->properties.start), GNUNET_PQ_result_spec_absolute_time_nbo ("expire_withdraw", &issue->properties.expire_withdraw), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_spend", - &issue->properties.expire_spend), + GNUNET_PQ_result_spec_absolute_time_nbo ("expire_deposit", + &issue->properties.expire_deposit), GNUNET_PQ_result_spec_absolute_time_nbo ("expire_legal", &issue->properties.expire_legal), TALER_PQ_result_spec_amount_nbo ("coin", @@ -4243,7 +4226,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) plugin = GNUNET_new (struct TALER_EXCHANGEDB_Plugin); plugin->cls = pg; plugin->get_session = &postgres_get_session; - plugin->drop_temporary = &postgres_drop_temporary; + plugin->drop_tables = &postgres_drop_tables; plugin->create_tables = &postgres_create_tables; plugin->start = &postgres_start; plugin->commit = &postgres_commit; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 3bb9b9f2c..2ef7f5d72 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -137,7 +137,7 @@ create_denom_key_pair (unsigned int size, dki.issue.properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_HOURS)); - dki.issue.properties.expire_spend = GNUNET_TIME_absolute_hton + dki.issue.properties.expire_deposit = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 2))); @@ -172,9 +172,10 @@ static struct TALER_Amount fee_refresh; static struct TALER_Amount fee_refund; static struct TALER_Amount amount_with_fee; + static void -free_refresh_commit_coins_array(struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins, - unsigned int size) +free_refresh_commit_coins_array (struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins, + unsigned int size) { unsigned int cnt; struct TALER_EXCHANGEDB_RefreshCommitCoin *ccoin; @@ -282,6 +283,7 @@ test_refresh_commit_coins (struct TALER_EXCHANGEDB_Session *session, return ret; } + /** * Function to test melting of coins as part of a refresh session * @@ -658,21 +660,30 @@ run (void *cls) if (NULL == (plugin = TALER_EXCHANGEDB_plugin_load (cfg))) { - result = 1; + result = 77; return; } - if (GNUNET_OK != - plugin->create_tables (plugin->cls, - GNUNET_YES)) + if (NULL != + (session = plugin->get_session (plugin->cls))) { - result = 2; + if (GNUNET_OK != + plugin->drop_tables (plugin->cls, + session)) + { + result = 77; + goto drop; + } + } + if (GNUNET_OK != + plugin->create_tables (plugin->cls)) + { + result = 77; goto drop; } if (NULL == - (session = plugin->get_session (plugin->cls, - GNUNET_YES))) + (session = plugin->get_session (plugin->cls))) { - result = 3; + result = 77; goto drop; } RND_BLK (&reserve_pub); @@ -932,8 +943,8 @@ run (void *cls) rh = NULL; if (NULL != session) GNUNET_break (GNUNET_OK == - plugin->drop_temporary (plugin->cls, - session)); + plugin->drop_tables (plugin->cls, + session)); if (NULL != dkp) destroy_denom_key_pair (dkp); if (NULL != cbc.sig.rsa_signature) diff --git a/src/exchangedb/test_exchangedb_deposits.c b/src/exchangedb/test_exchangedb_deposits.c deleted file mode 100644 index 09c65b2b2..000000000 --- a/src/exchangedb/test_exchangedb_deposits.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014 GNUnet e.V. - - 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, If not, see -*/ -/** - * @file exchange/test_exchange_deposits.c - * @brief testcase for exchange deposits - * @author Sree Harsha Totakura - */ -#include "platform.h" -#include -#include -#include "taler_pq_lib.h" -#include "taler_exchangedb_lib.h" -#include "taler_exchangedb_plugin.h" - -#define EXCHANGE_CURRENCY "EUR" - -#define DB_URI "postgres:///taler" - -#define break_db_err(result) do { \ - GNUNET_break(0); \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Database failure: %s\n", PQresultErrorMessage (result)); \ - } while (0) - -/** - * Shorthand for exit jumps. - */ -#define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) - - -/** - * Should we not interact with a temporary table? - */ -static int persistent; - -/** - * Testcase result - */ -static int result; - -/** - * The plugin. - */ -static struct TALER_EXCHANGEDB_Plugin *plugin; - -/** - * Main function that will be run by the scheduler. - * - * @param cls closure - * @param args remaining command-line arguments - * @param cfgfile name of the configuration file used (for saving, can be NULL!) - * @param cfg configuration - */ -static void -run (void *cls, - char *const *args, - const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - static const char wire[] = "{" - "\"type\":\"SEPA\"," - "\"IBAN\":\"DE67830654080004822650\"," - "\"NAME\":\"GNUNET E.V\"," - "\"BIC\":\"GENODEF1SRL\"" - "}"; - struct TALER_EXCHANGEDB_Deposit *deposit; - uint64_t transaction_id; - struct TALER_EXCHANGEDB_Session *session; - - deposit = NULL; - EXITIF (NULL == (plugin = TALER_EXCHANGEDB_plugin_load (cfg))); - EXITIF (GNUNET_OK != - plugin->create_tables (plugin->cls, - ! persistent)); - session = plugin->get_session (plugin->cls, - ! persistent); - EXITIF (NULL == session); - deposit = GNUNET_malloc (sizeof (struct TALER_EXCHANGEDB_Deposit) + sizeof (wire)); - /* Makeup a random coin public key */ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - deposit, - sizeof (struct TALER_EXCHANGEDB_Deposit)); - /* Makeup a random 64bit transaction ID */ - transaction_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX); - deposit->transaction_id = GNUNET_htonll (transaction_id); - /* Random amount */ - deposit->amount_with_fee.value = - htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX)); - deposit->amount_with_fee.fraction = - htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX)); - GNUNET_assert (strlen (EXCHANGE_CURRENCY) < sizeof (deposit->amount_with_fee.currency)); - strcpy (deposit->amount_with_fee.currency, EXCHANGE_CURRENCY); - /* Copy wireformat */ - deposit->wire = json_loads (wire, 0, NULL); - EXITIF (GNUNET_OK != - plugin->insert_deposit (plugin->cls, - session, - deposit)); - EXITIF (GNUNET_OK != - plugin->have_deposit (plugin->cls, - session, - deposit)); - result = GNUNET_OK; - - EXITIF_exit: - GNUNET_free_non_null (deposit); - if (NULL != plugin) - { - TALER_EXCHANGEDB_plugin_unload (plugin); - plugin = NULL; - } -} - - -int -main (int argc, - char *const argv[]) -{ - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'T', "persist", NULL, - gettext_noop ("Use a persistent database table instead of a temporary one"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &persistent}, - GNUNET_GETOPT_OPTION_END - }; - - - persistent = GNUNET_NO; - result = GNUNET_SYSERR; - if (GNUNET_OK != - GNUNET_PROGRAM_run (argc, argv, - "test-exchange-deposits", - "testcase for exchange deposits", - options, &run, NULL)) - return 3; - return (GNUNET_OK == result) ? 0 : 1; -} diff --git a/src/exchangedb/test_perf_taler_exchangedb.c b/src/exchangedb/test_perf_taler_exchangedb.c index a4ec9591d..8f7aa55d5 100644 --- a/src/exchangedb/test_perf_taler_exchangedb.c +++ b/src/exchangedb/test_perf_taler_exchangedb.c @@ -35,6 +35,7 @@ #define NB_WITHDRAW_INIT 1 #define NB_WITHDRAW_SAVE 1 + /** * Allocate, copies and free all the data used in the interpreter * Used to check for memory leaks @@ -42,7 +43,8 @@ static void test_allocate () { - struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki, *dki_copy; + struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; + struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki_copy; struct PERF_TALER_EXCHANGEDB_Reserve *reserve, *reserve_copy; struct PERF_TALER_EXCHANGEDB_Coin *coin, *coin_copy; struct TALER_EXCHANGEDB_Deposit *deposit, *deposit_copy; @@ -68,6 +70,7 @@ test_allocate () PERF_TALER_EXCHANGEDB_deposit_free (deposit_copy); } + /** * Runs the performances tests for the exchange database * and logs the results using Gauger @@ -170,13 +173,15 @@ main (int argc, char ** argv) // End of deposit initialization PERF_TALER_EXCHANGEDB_INIT_CMD_END ("end"), }; - + test_allocate (); ret = PERF_TALER_EXCHANGEDB_run_benchmark ("test-perf-taler-exchangedb", - "./test-exchange-db-postgres.conf", - init, - benchmark); + "./test-exchange-db-postgres.conf", + init, + benchmark); if (GNUNET_SYSERR == ret) return 1; + if (GNUNET_NO == ret) + return 77; /* testcase skipped */ return 0; } diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 04f94e570..794051e26 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -95,14 +95,14 @@ struct TALER_EXCHANGE_DenomPublicKey /** * Timestamp indicating when coins of this denomination become invalid. */ - struct GNUNET_TIME_Absolute deposit_valid_until; + struct GNUNET_TIME_Absolute expire_deposit; /** * When do signatures with this denomination key become invalid? * After this point, these signatures cannot be used in (legal) * disputes anymore, as the Exchange is then allowed to destroy its side * of the evidence. @e expire_legal is expected to be significantly - * larger than @e expire_spend (by a year or more). + * larger than @e expire_deposit (by a year or more). */ struct GNUNET_TIME_Absolute expire_legal; diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index e364d6b95..ebcfe3757 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -205,8 +205,7 @@ struct TALER_EXCHANGEDB_ReserveHistory * merchant must either use a different public key or a different * transaction ID for the two transactions. The same coin must not * be used twice at the same merchant for the same transaction - * (as determined by transaction ID). (Note: we might want to - * fix #3819 and include at least h_contract as well.) + * (as determined by transaction ID). */ struct TALER_EXCHANGEDB_Deposit { @@ -317,12 +316,12 @@ struct TALER_EXCHANGEDB_Refund struct TALER_CoinPublicInfo coin; /** - * Public key of the merchant. + * Public key of the merchant. */ struct TALER_MerchantPublicKeyP merchant_pub; - + /** - * Signature from the merchant affirming the refund. + * Signature from the merchant affirming the refund. */ struct TALER_MerchantSignatureP merchant_sig; @@ -338,7 +337,7 @@ struct TALER_EXCHANGEDB_Refund * refunded. */ uint64_t transaction_id; - + /** * Merchant-generated REFUND transaction ID to detect duplicate * refunds. @@ -718,36 +717,31 @@ struct TALER_EXCHANGEDB_Plugin * Connect to the db if the connection does not exist yet. * * @param cls the @e cls of this struct with the plugin-specific state - * @param temporary #GNUNET_YES to use a temporary schema; #GNUNET_NO to use the - * database default one * @param the database connection, or NULL on error */ struct TALER_EXCHANGEDB_Session * - (*get_session) (void *cls, - int temporary); + (*get_session) (void *cls); /** - * Drop the temporary taler schema. This is only useful for testcases. + * Drop the Taler tables. This should only be used in testcases. * * @param cls the @e cls of this struct with the plugin-specific state * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ int - (*drop_temporary) (void *cls, - struct TALER_EXCHANGEDB_Session *db); + (*drop_tables) (void *cls, + struct TALER_EXCHANGEDB_Session *db); /** * Create the necessary tables if they are not present * * @param cls the @e cls of this struct with the plugin-specific state - * @param temporary should we use a temporary schema * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ int - (*create_tables) (void *cls, - int temporary); + (*create_tables) (void *cls); /** diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index f1586aa8c..4ce57b0f8 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -659,18 +659,18 @@ struct TALER_DenominationKeyValidityPS * exchange will refuse transactions involving this key as it will * "drop" the table with double-spending information (shortly after) * this time. Note that wallets should refresh coins significantly - * before this time to be on the safe side. @e expire_spend must be + * before this time to be on the safe side. @e expire_deposit must be * significantly larger than @e expire_withdraw (by months or even * years). */ - struct GNUNET_TIME_AbsoluteNBO expire_spend; + struct GNUNET_TIME_AbsoluteNBO expire_deposit; /** * When do signatures with this denomination key become invalid? * After this point, these signatures cannot be used in (legal) * disputes anymore, as the Exchange is then allowed to destroy its side * of the evidence. @e expire_legal is expected to be significantly - * larger than @e expire_spend (by a year or more). + * larger than @e expire_deposit (by a year or more). */ struct GNUNET_TIME_AbsoluteNBO expire_legal; @@ -762,18 +762,18 @@ struct TALER_ExchangeKeyValidityPS * exchange will refuse transactions involving this key as it will * "drop" the table with double-spending information (shortly after) * this time. Note that wallets should refresh coins significantly - * before this time to be on the safe side. @e expire_spend must be + * before this time to be on the safe side. @e expire_deposit must be * significantly larger than @e expire_withdraw (by months or even * years). */ - struct GNUNET_TIME_AbsoluteNBO expire_spend; + struct GNUNET_TIME_AbsoluteNBO expire_deposit; /** * When do signatures with this denomination key become invalid? * After this point, these signatures cannot be used in (legal) * disputes anymore, as the Exchange is then allowed to destroy its side * of the evidence. @e expire_legal is expected to be significantly - * larger than @e expire_spend (by a year or more). + * larger than @e expire_deposit (by a year or more). */ struct GNUNET_TIME_AbsoluteNBO expire_legal; diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 80e5aaa8f..da24a49b0 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -51,9 +51,9 @@ struct TestClosure struct GNUNET_CURL_Context *ctx; /** - * Handle to the bank task, or NULL. + * Scheduler context for running the @e ctx. */ - struct GNUNET_SCHEDULER_Task *bt; + struct GNUNET_CURL_RescheduleContext *rc; /** * Number of the account that the exchange has at the bank for @@ -132,76 +132,6 @@ struct TALER_WIRE_ExecuteHandle }; -/** - * Task that runs the bank's context's event loop with the GNUnet - * scheduler. - * - * @param cls our `struct TestClosure` - */ -static void -context_task (void *cls) -{ - struct TestClosure *tc = cls; - long timeout; - int max_fd; - fd_set read_fd_set; - fd_set write_fd_set; - fd_set except_fd_set; - struct GNUNET_NETWORK_FDSet *rs; - struct GNUNET_NETWORK_FDSet *ws; - struct GNUNET_TIME_Relative delay; - - tc->bt = NULL; - GNUNET_CURL_perform (tc->ctx); - max_fd = -1; - timeout = -1; - FD_ZERO (&read_fd_set); - FD_ZERO (&write_fd_set); - FD_ZERO (&except_fd_set); - GNUNET_CURL_get_select_info (tc->ctx, - &read_fd_set, - &write_fd_set, - &except_fd_set, - &max_fd, - &timeout); - if (timeout >= 0) - delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, - timeout); - else - delay = GNUNET_TIME_UNIT_FOREVER_REL; - rs = GNUNET_NETWORK_fdset_create (); - GNUNET_NETWORK_fdset_copy_native (rs, - &read_fd_set, - max_fd + 1); - ws = GNUNET_NETWORK_fdset_create (); - GNUNET_NETWORK_fdset_copy_native (ws, - &write_fd_set, - max_fd + 1); - tc->bt = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, - delay, - rs, - ws, - &context_task, - tc); - GNUNET_NETWORK_fdset_destroy (rs); - GNUNET_NETWORK_fdset_destroy (ws); -} - - -/** - * Run the bank task now. - * - * @param tc context for which we should initiate running the task - */ -static void -run_bt (struct TestClosure *tc) -{ - if (NULL != tc->bt) - GNUNET_SCHEDULER_cancel (tc->bt); - tc->bt = GNUNET_SCHEDULER_add_now (&context_task, - tc); -} - /** * Round amount DOWN to the amount that can be transferred via the wire @@ -751,7 +681,6 @@ test_execute_wire_transfer (void *cls, GNUNET_free (eh); return NULL; } - run_bt (tc); return eh; } @@ -831,7 +760,9 @@ libtaler_plugin_wire_test_init (void *cls) GNUNET_free (tc); return NULL; } - tc->ctx = GNUNET_CURL_init (); + tc->ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, + &tc->rc); + tc->rc = GNUNET_CURL_gnunet_rc_create (tc->ctx); if (NULL == tc->ctx) { GNUNET_break (0); @@ -867,16 +798,16 @@ libtaler_plugin_wire_test_done (void *cls) struct TALER_WIRE_Plugin *plugin = cls; struct TestClosure *tc = plugin->cls; - if (NULL != tc->bt) - { - GNUNET_SCHEDULER_cancel (tc->bt); - tc->bt = NULL; - } if (NULL != tc->ctx) { GNUNET_CURL_fini (tc->ctx); tc->ctx = NULL; } + if (NULL != tc->rc) + { + GNUNET_CURL_gnunet_rc_destroy (tc->rc); + tc->rc = NULL; + } GNUNET_free_non_null (tc->currency); GNUNET_free_non_null (tc->bank_uri); GNUNET_free (tc);