diff options
-rw-r--r-- | src/benchmark/benchmark.conf | 4 | ||||
-rw-r--r-- | src/benchmark/exchange_benchmark_home/.config/taler/account-2.json | 4 | ||||
-rw-r--r-- | src/benchmark/taler-exchange-benchmark.c | 477 | ||||
-rw-r--r-- | src/exchange-lib/testing_api_helpers.c | 3 | ||||
-rw-r--r-- | src/exchange-lib/testing_api_loop.c | 24 | ||||
-rw-r--r-- | src/include/taler_testing_lib.h | 17 |
6 files changed, 357 insertions, 172 deletions
diff --git a/src/benchmark/benchmark.conf b/src/benchmark/benchmark.conf index 045cc0a27..a160cc1cd 100644 --- a/src/benchmark/benchmark.conf +++ b/src/benchmark/benchmark.conf @@ -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" diff --git a/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json b/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json index a99f114f0..ff4a4a25a 100644 --- a/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json +++ b/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json @@ -1,5 +1,5 @@ { "url": "payto://x-taler-bank/localhost:8082/2", - "salt": "121B05SK5B4P0ZXQ748G3HCXA35W3QYQ6KP799TEMSJSVYHCG5CNZWY2CYD5RN4QHYBFWM1M8973W3X9PBKW78D49QV4D7NT7PEE040", - "master_sig": "WJWQBR8M0M9CENCBZVRDT2D6YMCD1AYN1JS54KX0Q7VRMS163800GP25871Y96T0TPF1SN1CPR6TE3KG4VZXW8HJPENVC8PAK01S218" + "salt": "S6DM52Z465K13EBEK5GRPT5WWK36EY7GHADJMFS7DB9WGXW6385FWXXHR325VYETCN63SS21AV6ZT77H7VZ8KY9G1QPPKKSMAG6GE98", + "master_sig": "NPPB20YYYP2BEHSZGKCTKJH217FFSQC38P1Z6TCDQ55DHXFPV1XAHCY8Z0PEJXJJ0AAR7MMPXAE8RS1W6G72E8715PS2DC5WT5WJ42R" }
\ No newline at end of file diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 58cff7714..ed923cd3b 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -101,6 +101,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. */ static struct Account exchange_bank_account; @@ -147,6 +168,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. */ static char *cfg_filename; @@ -157,25 +188,22 @@ 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. * It is kept as a way to make the macro more auto-descriptive * 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 */ - - start_time = GNUNET_TIME_absolute_get (); - result = GNUNET_OK; - for (unsigned int i=0;i<howmany_clients;i++) + if ( (MODE_CLIENT == mode) || (MODE_BOTH == mode) ) { - if (0 == (cpids[i] = fork ())) + 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++) { - /* 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) + { + 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) ) { - waitpid (cpids[i], + 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)); } - 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) + 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 { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to run `taler-exchange-wire`," - " is your PATH correct?\n"); - return GNUNET_NO; + 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_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)); + + GNUNET_CONFIGURATION_destroy (cfg); + result = parallel_benchmark (&run, NULL, cfg_filename, diff --git a/src/exchange-lib/testing_api_helpers.c b/src/exchange-lib/testing_api_helpers.c index bcdb44305..2e2f10e68 100644 --- a/src/exchange-lib/testing_api_helpers.c +++ b/src/exchange-lib/testing_api_helpers.c @@ -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)); diff --git a/src/exchange-lib/testing_api_loop.c b/src/exchange-lib/testing_api_loop.c index 9d777dfa4..43d0ecc87 100644 --- a/src/exchange-lib/testing_api_loop.c +++ b/src/exchange-lib/testing_api_loop.c @@ -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 diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 8db59ee45..0db27d0e6 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -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); /** |