Merge branch 'master' of git.taler.net:/var/git/exchange

This commit is contained in:
Jeff Burdges 2016-05-02 11:27:31 +02:00
commit 025fbdb41a
34 changed files with 800 additions and 1005 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -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.

View File

@ -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 \

View File

@ -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 <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_curl_lib.h>
#include <microhttpd.h>
/**
* 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);

View File

@ -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 <http://www.gnu.org/licenses/>
*/
/**
* @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 <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_curl_lib.h>
#include <microhttpd.h>
#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 */

View File

@ -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 <http://www.gnu.org/licenses/>
*/
/**
* @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 <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_curl_lib.h>
#include <microhttpd.h>
#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 */

View File

@ -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 <http://www.gnu.org/licenses/>
*/
/**
* @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 <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_curl_lib.h>
#include <microhttpd.h>
/**
* 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

View File

@ -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);

View File

@ -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;i<TALER_CNC_KAPPA;i++)
mcp.transfer_priv[i] = mc->transfer_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;i<TALER_CNC_KAPPA;i++)
mc->transfer_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

View File

@ -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);
}

View File

@ -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?

View File

@ -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;

View File

@ -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");

View File

@ -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");

View File

@ -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 =

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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.
*/

View File

@ -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);

View File

@ -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",

View File

@ -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;

View File

@ -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

View File

@ -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));

View File

@ -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,

View File

@ -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[]);
/**

View File

@ -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;

View File

@ -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)

View File

@ -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 <http://www.gnu.org/licenses/>
*/
/**
* @file exchange/test_exchange_deposits.c
* @brief testcase for exchange deposits
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/
#include "platform.h"
#include <libpq-fe.h>
#include <gnunet/gnunet_util_lib.h>
#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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
/**

View File

@ -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;

View File

@ -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);