/* This file is part of TALER Copyright (C) 2014-2018 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see */ /** * @file exchange/test_exchange_api_new.c * @brief testcase to test exchange's HTTP API interface * @author Sree Harsha Totakura * @author Christian Grothoff */ #include "platform.h" #include "taler_util.h" #include "taler_signatures.h" #include "taler_exchange_service.h" #include "taler_json_lib.h" #include #include #include "taler_bank_service.h" #include "taler_fakebank_lib.h" #include "taler_testing_lib.h" /** * Is the configuration file is set to include wire format 'test'? */ #define WIRE_TEST 1 /** * Is the configuration file is set to include wire format 'sepa'? */ #define WIRE_SEPA 1 /** * Account number of the exchange at the bank. */ #define EXCHANGE_ACCOUNT_NO 2 /** * Handle to access the exchange. */ // static struct TALER_EXCHANGE_Handle *exchange; /** * Pipe used to communicate child death via signal. */ static struct GNUNET_DISK_PipeHandle *sigpipe; /** * Handle to the exchange process. */ static struct GNUNET_OS_Process *exchanged; /** * Handle to our fakebank. */ static struct TALER_FAKEBANK_Handle *fakebank; /** * Function run when the test terminates (good or bad). * Cleans up our state. * * @param cls NULL */ static void do_shutdown (void *cls) { if (NULL != fakebank) { TALER_FAKEBANK_stop (fakebank); fakebank = NULL; } } /** * Main function that will tell the interpreter what to do. * * @param cls closure */ static void run (void *cls, struct TALER_TESTING_Interpreter *is) { struct TALER_TESTING_Command commands[] = { TALER_TESTING_cmd_fakebank_transfer ("create-reserve-1", "EUR:5.01", 42, EXCHANGE_ACCOUNT_NO, "user42", "pass42"), TALER_TESTING_cmd_end () }; fakebank = TALER_FAKEBANK_start (8082); TALER_TESTING_run (is, commands); GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); } /** * Signal handler called for SIGCHLD. Triggers the * respective handler by writing to the trigger pipe. */ static void sighandler_child_death () { static char c; int old_errno = errno; /* back-up errno */ GNUNET_break (1 == GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_WRITE), &c, sizeof (c))); errno = old_errno; /* restore errno */ } /** * Remove files from previous runs */ static void cleanup_files () { struct GNUNET_CONFIGURATION_Handle *cfg; char *dir; cfg = GNUNET_CONFIGURATION_create (); if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, "test_exchange_api.conf")) { GNUNET_break (0); GNUNET_CONFIGURATION_destroy (cfg); exit (77); } GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, "exchange", "keydir", &dir)); if (GNUNET_YES == GNUNET_DISK_directory_test (dir, GNUNET_NO)) GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (dir)); GNUNET_free (dir); GNUNET_CONFIGURATION_destroy (cfg); } int main (int argc, char * const *argv) { struct GNUNET_OS_Process *proc; struct GNUNET_SIGNAL_Context *shc_chld; enum GNUNET_OS_ProcessStatusType type; unsigned long code; unsigned int iter; int result; /* These might get in the way... */ unsetenv ("XDG_DATA_HOME"); unsetenv ("XDG_CONFIG_HOME"); GNUNET_log_setup ("test-exchange-api", "INFO", NULL); if (GNUNET_OK != GNUNET_NETWORK_test_port_free (IPPROTO_TCP, 8081)) { fprintf (stderr, "Required port %u not available, skipping.\n", 8081); return 77; } if (GNUNET_OK != GNUNET_NETWORK_test_port_free (IPPROTO_TCP, 8082)) { fprintf (stderr, "Required port %u not available, skipping.\n", 8082); return 77; } cleanup_files (); proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, "taler-exchange-keyup", "taler-exchange-keyup", "-c", "test_exchange_api.conf", "-o", "auditor.in", NULL); if (NULL == proc) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to run `taler-exchange-keyup`, is your PATH correct?\n"); return 77; } GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, "taler-auditor-sign", "taler-auditor-sign", "-c", "test_exchange_api.conf", "-u", "http://auditor/", "-m", "98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG", "-r", "auditor.in", "-o", "test_exchange_api_home/.local/share/taler/auditors/auditor.out", NULL); if (NULL == proc) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to run `taler-exchange-keyup`, is your PATH correct?\n"); return 77; } GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, "taler-exchange-dbinit", "taler-exchange-dbinit", "-c", "test_exchange_api.conf", "-r", NULL); if (NULL == proc) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to run `taler-exchange-dbinit`, is your PATH correct?\n"); return 77; } if (GNUNET_SYSERR == GNUNET_OS_process_wait_status (proc, &type, &code)) { GNUNET_break (0); GNUNET_OS_process_destroy (proc); return 1; } GNUNET_OS_process_destroy (proc); if ( (type == GNUNET_OS_PROCESS_EXITED) && (0 != code) ) { fprintf (stderr, "Failed to setup database\n"); return 77; } if ( (type != GNUNET_OS_PROCESS_EXITED) || (0 != code) ) { fprintf (stderr, "Unexpected error running `taler-exchange-dbinit'!\n"); return 1; } exchanged = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, "taler-exchange-httpd", "taler-exchange-httpd", "-c", "test_exchange_api.conf", "-i", NULL); /* give child time to start and bind against the socket */ fprintf (stderr, "Waiting for `taler-exchange-httpd' to be ready"); iter = 0; do { if (10 == iter) { fprintf (stderr, "Failed to launch `taler-exchange-httpd' (or `wget')\n"); GNUNET_OS_process_kill (exchanged, SIGTERM); GNUNET_OS_process_wait (exchanged); GNUNET_OS_process_destroy (exchanged); return 77; } fprintf (stderr, "."); sleep (1); iter++; } while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/keys -o /dev/null -O /dev/null")); fprintf (stderr, "\n"); sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); GNUNET_assert (NULL != sigpipe); shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); result = TALER_TESTING_setup (&run, NULL); GNUNET_SIGNAL_handler_uninstall (shc_chld); shc_chld = NULL; GNUNET_DISK_pipe_close (sigpipe); GNUNET_break (0 == GNUNET_OS_process_kill (exchanged, SIGTERM)); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (exchanged)); GNUNET_OS_process_destroy (exchanged); return (GNUNET_OK == result) ? 0 : 1; }