add remote benchmarking

This commit is contained in:
Florian Dold 2018-08-19 00:49:16 +02:00
parent 624a9ac6dc
commit 96e047b186
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
6 changed files with 357 additions and 172 deletions

View File

@ -32,6 +32,10 @@ lookahead_sign = 12 h
[exchangedb-postgres]
config = "postgres:///talercheck"
[benchmark-remote-exchange]
host = localhost
dir = /home/dold/repos/taler/exchange/src/benchmark
[account-2]
# What is the bank account (with the "Taler Bank" demo system)?
URL = "payto://x-taler-bank/localhost:8082/2"

View File

@ -1,5 +1,5 @@
{
"url": "payto://x-taler-bank/localhost:8082/2",
"salt": "121B05SK5B4P0ZXQ748G3HCXA35W3QYQ6KP799TEMSJSVYHCG5CNZWY2CYD5RN4QHYBFWM1M8973W3X9PBKW78D49QV4D7NT7PEE040",
"master_sig": "WJWQBR8M0M9CENCBZVRDT2D6YMCD1AYN1JS54KX0Q7VRMS163800GP25871Y96T0TPF1SN1CPR6TE3KG4VZXW8HJPENVC8PAK01S218"
"salt": "S6DM52Z465K13EBEK5GRPT5WWK36EY7GHADJMFS7DB9WGXW6385FWXXHR325VYETCN63SS21AV6ZT77H7VZ8KY9G1QPPKKSMAG6GE98",
"master_sig": "NPPB20YYYP2BEHSZGKCTKJH217FFSQC38P1Z6TCDQ55DHXFPV1XAHCY8Z0PEJXJJ0AAR7MMPXAE8RS1W6G72E8715PS2DC5WT5WJ42R"
}

View File

@ -100,6 +100,27 @@ struct Account
};
/**
* What mode should the benchmark run in?
*/
enum BenchmarkMode {
/**
* Run as client (with fakebank), also starts a remote exchange.
*/
MODE_CLIENT = 1,
/**
* Run the the exchange.
*/
MODE_EXCHANGE = 2,
/**
* Run both, for a local benchmark.
*/
MODE_BOTH = 3,
};
/**
* Hold information regarding which bank has the exchange account.
*/
@ -146,6 +167,16 @@ static char *loglev;
*/
static char *logfile;
/**
* Benchmarking mode (run as client, exchange, both) as string.
*/
static char *mode_str;
/**
* Benchmarking mode (run as client, exchange, both).
*/
static enum BenchmarkMode mode;
/**
* Config filename.
*/
@ -156,6 +187,16 @@ static char *cfg_filename;
*/
static char *currency;
/**
* Remote host that runs the exchange.
*/
static char *remote_host;
/**
* Remote benchmarking directory.
*/
static char *remote_dir;
/**
* Convenience macros to allocate all the currency-dependant
* strings; note that the argument list of the macro is ignored.
@ -163,19 +204,6 @@ static char *currency;
* where it is called.
*/
#define ALLOCATE_AMOUNTS(...) \
char *AMOUNT_5; \
char *AMOUNT_4; \
char *AMOUNT_1; \
\
GNUNET_asprintf (&AMOUNT_5, \
"%s:5", \
currency); \
GNUNET_asprintf (&AMOUNT_4, \
"%s:4", \
currency); \
GNUNET_asprintf (&AMOUNT_1, \
"%s:1", \
currency);
/**
* Decide which exchange account is going to be
@ -190,7 +218,7 @@ pick_exchange_account_cb (void *cls,
const char *section)
{
if (0 == strncasecmp ("account-",
section,
section,
strlen ("account-")))
{
const char **s = cls;
@ -332,17 +360,21 @@ run (void *cls,
[howmany_reserves * (1 + /* Withdraw block */
howmany_coins) + /* All units */
1 /* End CMD */];
char *AMOUNT_5;
char *AMOUNT_4;
char *AMOUNT_1;
GNUNET_asprintf (&AMOUNT_5, "%s:5", currency);
GNUNET_asprintf (&AMOUNT_4, "%s:4", currency);
GNUNET_asprintf (&AMOUNT_1, "%s:1", currency);
ALLOCATE_AMOUNTS
(AMOUNT_5,
AMOUNT_4,
AMOUNT_1);
GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (currency, &total_reserve_amount));
total_reserve_amount.value = 5 * howmany_coins;
total_reserve_amount.fraction = 0;
strncpy (total_reserve_amount.currency,
currency,
TALER_CURRENCY_LEN);
GNUNET_asprintf (&withdraw_fee_str,
"%s:0.1",
@ -535,117 +567,215 @@ parallel_benchmark (TALER_TESTING_Main main_cb,
const char *config_file,
const char *exchange_url)
{
int result;
int result = GNUNET_OK;
pid_t cpids[howmany_clients];
pid_t fakebank;
pid_t fakebank = -1;
int wstatus;
struct GNUNET_OS_Process *exchanged;
struct GNUNET_OS_Process *wirewatch;
struct GNUNET_OS_Process *exchanged = NULL;
struct GNUNET_OS_Process *wirewatch = NULL;
struct GNUNET_OS_Process *exchange_slave = NULL;
/* start fakebank */
fakebank = fork ();
if (0 == fakebank)
if ( (MODE_CLIENT == mode) || (MODE_BOTH == mode) )
{
GNUNET_SCHEDULER_run (&launch_fakebank,
exchange_bank_account.bank_base_url);
exit (0);
}
if (-1 == fakebank)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"fork");
return GNUNET_SYSERR;
/* start fakebank */
fakebank = fork ();
if (0 == fakebank)
{
GNUNET_SCHEDULER_run (&launch_fakebank,
exchange_bank_account.bank_base_url);
exit (0);
}
if (-1 == fakebank)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"fork");
return GNUNET_SYSERR;
}
}
/* start exchange */
exchanged = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-exchange-httpd",
"taler-exchange-httpd",
"-c", config_file,
"-i",
"-C",
NULL);
if (NULL == exchanged)
if ( (MODE_EXCHANGE == mode) || (MODE_BOTH == mode) )
{
kill (fakebank,
SIGTERM);
waitpid (fakebank,
&wstatus,
0);
return 77;
/* start exchange */
exchanged = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-exchange-httpd",
"taler-exchange-httpd",
"-c", config_file,
"-i",
"-C",
NULL);
if ( (NULL == exchanged) && (MODE_BOTH == mode) )
{
GNUNET_assert (-1 != fakebank);
kill (fakebank,
SIGTERM);
waitpid (fakebank,
&wstatus,
0);
return 77;
}
/* start exchange wirewatch */
wirewatch = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-exchange-wirewatch",
"taler-exchange-wirewatch",
"-c", config_file,
NULL);
if (NULL == wirewatch)
{
GNUNET_OS_process_kill (exchanged,
SIGTERM);
if (MODE_BOTH == mode)
{
GNUNET_assert (-1 != fakebank);
kill (fakebank,
SIGTERM);
waitpid (fakebank,
&wstatus,
0);
}
GNUNET_OS_process_destroy (exchanged);
return 77;
}
}
/* start exchange */
wirewatch = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-exchange-wirewatch",
"taler-exchange-wirewatch",
"-c", config_file,
NULL);
if (NULL == wirewatch)
if (MODE_CLIENT == mode)
{
GNUNET_OS_process_kill (exchanged,
SIGTERM);
kill (fakebank,
SIGTERM);
GNUNET_OS_process_wait (exchanged);
GNUNET_OS_process_destroy (exchanged);
waitpid (fakebank,
&wstatus,
0);
return 77;
char *remote_cmd;
GNUNET_asprintf (&remote_cmd,
("cd '%s'; "
"taler-exchange-benchmark --mode=exchange -c '%s'"),
remote_dir,
config_file);
printf ("remote command: %s\n", remote_cmd);
exchange_slave = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"ssh",
"ssh",
/* Don't ask for pw/passphrase, rather fail */
"-oBatchMode=yes",
remote_host,
remote_cmd,
NULL);
GNUNET_free (remote_cmd);
}
/* We always wait for the exchange, no matter if it's running locally or
remotely */
if (0 != TALER_TESTING_wait_exchange_ready (exchange_url))
{
GNUNET_OS_process_kill (exchanged,
SIGTERM);
kill (fakebank,
SIGTERM);
if ( (MODE_BOTH == mode) || (MODE_CLIENT == mode))
{
GNUNET_assert (-1 != fakebank);
kill (fakebank,
SIGTERM);
waitpid (fakebank,
&wstatus,
0);
}
GNUNET_OS_process_wait (exchanged);
GNUNET_OS_process_destroy (exchanged);
waitpid (fakebank,
&wstatus,
0);
return 77;
}
sleep (1); /* make sure fakebank process is ready before continuing */
if ( (MODE_CLIENT == mode) || (MODE_BOTH == mode) )
{
sleep (1); /* make sure fakebank process is ready before continuing */
start_time = GNUNET_TIME_absolute_get ();
result = GNUNET_OK;
for (unsigned int i=0;i<howmany_clients;i++)
{
if (0 == (cpids[i] = fork ()))
start_time = GNUNET_TIME_absolute_get ();
result = GNUNET_OK;
for (unsigned int i=0;i<howmany_clients;i++)
{
/* I am the child, do the work! */
result = TALER_TESTING_setup
(run,
NULL,
cfg_filename,
exchanged);
if (GNUNET_OK != result)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failure in child process test suite!\n");
if (GNUNET_OK == result)
exit (0);
else
exit (1);
if (0 == (cpids[i] = fork ()))
{
/* I am the child, do the work! */
result = TALER_TESTING_setup
(run,
NULL,
cfg_filename,
exchanged,
GNUNET_YES);
if (GNUNET_OK != result)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failure in child process test suite!\n");
if (GNUNET_OK == result)
exit (0);
else
exit (1);
}
if (-1 == cpids[i])
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"fork");
howmany_clients = i;
result = GNUNET_SYSERR;
break;
}
/* fork() success, continue starting more processes! */
}
if (-1 == cpids[i])
/* collect all children */
for (unsigned int i=0;i<howmany_clients;i++)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"fork");
howmany_clients = i;
result = GNUNET_SYSERR;
break;
waitpid (cpids[i],
&wstatus,
0);
if ( (! WIFEXITED (wstatus)) ||
(0 != WEXITSTATUS (wstatus)) )
{
GNUNET_break (0);
result = GNUNET_SYSERR;
}
}
/* fork() success, continue starting more processes! */
}
/* collect all children */
for (unsigned int i=0;i<howmany_clients;i++)
/* Wait for our master to die or to tell us to die */
if (MODE_EXCHANGE == mode)
getchar ();
if (MODE_CLIENT == mode)
{
waitpid (cpids[i],
GNUNET_assert (NULL != exchange_slave);
GNUNET_OS_process_kill (exchange_slave, SIGTERM);
GNUNET_OS_process_destroy (exchange_slave);
}
if ( (MODE_EXCHANGE == mode) || (MODE_BOTH == mode) )
{
GNUNET_assert (NULL != wirewatch);
GNUNET_assert (NULL != exchanged);
/* stop wirewatch */
GNUNET_break (0 ==
GNUNET_OS_process_kill (wirewatch,
SIGTERM));
GNUNET_break (GNUNET_OK ==
GNUNET_OS_process_wait (wirewatch));
GNUNET_OS_process_destroy (wirewatch);
/* stop exchange */
GNUNET_break (0 ==
GNUNET_OS_process_kill (exchanged,
SIGTERM));
GNUNET_break (GNUNET_OK ==
GNUNET_OS_process_wait (exchanged));
GNUNET_OS_process_destroy (exchanged);
}
if ( (MODE_CLIENT == mode) || (MODE_BOTH == mode) )
{
/* stop fakebank */
GNUNET_assert (-1 != fakebank);
if (0 != kill (fakebank,
SIGTERM))
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"kill");
waitpid (fakebank,
&wstatus,
0);
if ( (! WIFEXITED (wstatus)) ||
@ -655,35 +785,6 @@ parallel_benchmark (TALER_TESTING_Main main_cb,
result = GNUNET_SYSERR;
}
}
/* stop wirewatch */
GNUNET_break (0 ==
GNUNET_OS_process_kill (wirewatch,
SIGTERM));
GNUNET_break (GNUNET_OK ==
GNUNET_OS_process_wait (wirewatch));
GNUNET_OS_process_destroy (wirewatch);
/* stop exchange */
GNUNET_break (0 ==
GNUNET_OS_process_kill (exchanged,
SIGTERM));
GNUNET_break (GNUNET_OK ==
GNUNET_OS_process_wait (exchanged));
GNUNET_OS_process_destroy (exchanged);
/* stop fakebank */
if (0 != kill (fakebank,
SIGTERM))
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"kill");
waitpid (fakebank,
&wstatus,
0);
if ( (! WIFEXITED (wstatus)) ||
(0 != WEXITSTATUS (wstatus)) )
{
GNUNET_break (0);
result = GNUNET_SYSERR;
}
return result;
}
@ -700,7 +801,6 @@ main (int argc,
char *const *argv)
{
char *exchange_url;
struct GNUNET_OS_Process *compute_wire_response;
struct GNUNET_CONFIGURATION_Handle *cfg;
struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_mandatory
@ -723,6 +823,11 @@ main (int argc,
"NRESERVES",
"How many reserves per client we should create",
&howmany_reserves),
GNUNET_GETOPT_option_string ('m',
"mode",
"MODE",
"run as exchange, clients or both",
&mode_str),
GNUNET_GETOPT_option_string ('l',
"logfile",
"LF",
@ -745,6 +850,19 @@ main (int argc,
GNUNET_log_setup ("taler-exchange-benchmark",
NULL == loglev ? "INFO" : loglev,
logfile);
if (NULL == mode_str)
mode = MODE_BOTH;
else if (0 == strcmp (mode_str, "exchange"))
mode = MODE_EXCHANGE;
else if (0 == strcmp (mode_str, "client"))
mode = MODE_CLIENT;
else if (0 == strcmp (mode_str, "both"))
mode = MODE_BOTH;
else
{
TALER_LOG_ERROR ("Unknown mode given: '%s'\n", mode_str);
return BAD_CONFIG_FILE;
}
cfg = GNUNET_CONFIGURATION_create ();
if (GNUNET_OK !=
GNUNET_CONFIGURATION_load (cfg,
@ -793,31 +911,76 @@ main (int argc,
(TALER_EC_NONE == parse_payto (exchange_payto_url,
&exchange_bank_account));
}
if ( (MODE_EXCHANGE == mode) || (MODE_BOTH == mode) )
{
struct GNUNET_OS_Process *compute_wire_response;
compute_wire_response = GNUNET_OS_start_process
(GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-exchange-wire",
"taler-exchange-wire",
"-c", cfg_filename,
NULL);
if (NULL == compute_wire_response)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to run `taler-exchange-wire`,"
" is your PATH correct?\n");
return GNUNET_NO;
}
GNUNET_OS_process_wait (compute_wire_response);
GNUNET_OS_process_destroy (compute_wire_response);
GNUNET_assert
(GNUNET_OK == TALER_TESTING_prepare_exchange
(cfg_filename,
&exchange_url));
}
else
{
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"exchange",
"BASE_URL",
&exchange_url))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchange",
"base_url");
GNUNET_CONFIGURATION_destroy (cfg);
return BAD_CONFIG_FILE;
}
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"benchmark-remote-exchange",
"host",
&remote_host))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"benchmark-remote-exchange",
"host");
GNUNET_CONFIGURATION_destroy (cfg);
return BAD_CONFIG_FILE;
}
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"benchmark-remote-exchange",
"dir",
&remote_dir))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"benchmark-remote-exchange",
"dir");
GNUNET_CONFIGURATION_destroy (cfg);
return BAD_CONFIG_FILE;
}
}
GNUNET_CONFIGURATION_destroy (cfg);
compute_wire_response = GNUNET_OS_start_process
(GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-exchange-wire",
"taler-exchange-wire",
"-c", cfg_filename,
NULL);
if (NULL == compute_wire_response)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to run `taler-exchange-wire`,"
" is your PATH correct?\n");
return GNUNET_NO;
}
GNUNET_OS_process_wait (compute_wire_response);
GNUNET_OS_process_destroy (compute_wire_response);
GNUNET_assert
/* Takes care of dropping all tables. */
(GNUNET_OK == TALER_TESTING_prepare_exchange
(cfg_filename,
&exchange_url));
result = parallel_benchmark (&run,
NULL,
cfg_filename,

View File

@ -477,7 +477,8 @@ TALER_TESTING_setup_with_exchange (TALER_TESTING_Main main_cb,
result = TALER_TESTING_setup (main_cb,
main_cb_cls,
config_filename,
exchanged);
exchanged,
GNUNET_YES);
GNUNET_break (0 ==
GNUNET_OS_process_kill (exchanged,
SIGTERM));

View File

@ -405,11 +405,18 @@ maint_child_death (void *cls)
if (GNUNET_OK == is->reload_keys)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Triggering key state reload at exchange\n");
GNUNET_break (0 == GNUNET_OS_process_kill
(is->exchanged, SIGUSR1));
sleep (5); /* make sure signal was received and processed */
if (NULL == is->exchanged)
{
GNUNET_break (0);
}
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Triggering key state reload at exchange\n");
GNUNET_break (0 == GNUNET_OS_process_kill
(is->exchanged, SIGUSR1));
sleep (5); /* make sure signal was received and processed */
}
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@ -669,6 +676,8 @@ main_wrapper_exchange_connect (void *cls)
* signal to it, for example to let it know to reload the
* key state.. if NULL, the interpreter will run without
* trying to connect to the exchange first.
* @param exchange_connect GNUNET_YES if the test should connect
* to the exchange, GNUNET_NO otherwise
* @return #GNUNET_OK if all is okay, != #GNUNET_OK otherwise.
* non-GNUNET_OK codes are #GNUNET_SYSERR most of the
* times.
@ -677,7 +686,8 @@ int
TALER_TESTING_setup (TALER_TESTING_Main main_cb,
void *main_cb_cls,
const char *config_filename,
struct GNUNET_OS_Process *exchanged)
struct GNUNET_OS_Process *exchanged,
int exchange_connect)
{
struct TALER_TESTING_Interpreter is;
struct MainContext main_ctx = {
@ -709,7 +719,7 @@ TALER_TESTING_setup (TALER_TESTING_Main main_cb,
/* Blocking */
if (NULL != exchanged)
if (GNUNET_YES == exchange_connect)
GNUNET_SCHEDULER_run (&main_wrapper_exchange_connect,
&main_ctx);
else

View File

@ -464,6 +464,7 @@ typedef void
(*TALER_TESTING_Main)(void *cls,
struct TALER_TESTING_Interpreter *is);
/**
* Install signal handlers plus schedules the main wrapper
* around the "run" method.
@ -473,16 +474,22 @@ typedef void
* @param main_cb_cls a closure for "run", typically NULL.
* @param config_filename configuration filename.
* @param exchanged exchange process handle: will be put in the
* state as some commands - e.g. revoke - need to signal it,
* for example to let it know to reload the key state.
*
* @return FIXME: not sure what 'is.result' is at this stage.
* state as some commands - e.g. revoke - need to send
* signal to it, for example to let it know to reload the
* key state.. if NULL, the interpreter will run without
* trying to connect to the exchange first.
* @param exchange_connect GNUNET_YES if the test should connect
* to the exchange, GNUNET_NO otherwise
* @return #GNUNET_OK if all is okay, != #GNUNET_OK otherwise.
* non-GNUNET_OK codes are #GNUNET_SYSERR most of the
* times.
*/
int
TALER_TESTING_setup (TALER_TESTING_Main main_cb,
void *main_cb_cls,
const char *config_filename,
struct GNUNET_OS_Process *exchanged);
struct GNUNET_OS_Process *exchanged,
int exchange_connect);
/**