LCOV - code coverage report
Current view: top level - testing - testing_api_helpers_exchange.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 195 338 57.7 %
Date: 2021-08-30 06:43:37 Functions: 17 19 89.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2018-2020 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify
       6             :   it under the terms of the GNU General Public License as
       7             :   published by the Free Software Foundation; either version 3, or
       8             :   (at your option) any later version.
       9             : 
      10             :   TALER is distributed in the hope that it will be useful, but
      11             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :   GNU General Public License for more details.
      14             : 
      15             :   You should have received a copy of the GNU General Public
      16             :   License along with TALER; see the file COPYING.  If not, see
      17             :   <http://www.gnu.org/licenses/>
      18             : */
      19             : 
      20             : /**
      21             :  * @file testing/testing_api_helpers_exchange.c
      22             :  * @brief helper functions
      23             :  * @author Christian Grothoff
      24             :  * @author Marcello Stanisci
      25             :  */
      26             : #include "platform.h"
      27             : #include "taler_json_lib.h"
      28             : #include <gnunet/gnunet_curl_lib.h>
      29             : #include "taler_signatures.h"
      30             : #include "taler_testing_lib.h"
      31             : 
      32             : 
      33             : void
      34           9 : TALER_TESTING_cleanup_files (const char *config_name)
      35             : {
      36           9 :   if (GNUNET_OK !=
      37           9 :       GNUNET_CONFIGURATION_parse_and_run (config_name,
      38             :                                           &TALER_TESTING_cleanup_files_cfg,
      39             :                                           NULL))
      40           0 :     exit (77);
      41           9 : }
      42             : 
      43             : 
      44             : /**
      45             :  * Remove @a option directory from @a section in @a cfg.
      46             :  *
      47             :  * @return #GNUNET_OK on success
      48             :  */
      49             : static enum GNUNET_GenericReturnValue
      50          18 : remove_dir (const struct GNUNET_CONFIGURATION_Handle *cfg,
      51             :             const char *section,
      52             :             const char *option)
      53             : {
      54             :   char *dir;
      55             : 
      56          18 :   if (GNUNET_OK !=
      57          18 :       GNUNET_CONFIGURATION_get_value_filename (cfg,
      58             :                                                section,
      59             :                                                option,
      60             :                                                &dir))
      61             :   {
      62           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
      63             :                                section,
      64             :                                option);
      65           0 :     return GNUNET_SYSERR;
      66             :   }
      67          18 :   if (GNUNET_YES ==
      68          18 :       GNUNET_DISK_directory_test (dir,
      69             :                                   GNUNET_NO))
      70          12 :     GNUNET_break (GNUNET_OK ==
      71             :                   GNUNET_DISK_directory_remove (dir));
      72          18 :   GNUNET_free (dir);
      73          18 :   return GNUNET_OK;
      74             : }
      75             : 
      76             : 
      77             : int
      78           9 : TALER_TESTING_cleanup_files_cfg (void *cls,
      79             :                                  const struct GNUNET_CONFIGURATION_Handle *cfg)
      80             : {
      81             :   char *dir;
      82             : 
      83           9 :   if (GNUNET_OK !=
      84           9 :       GNUNET_CONFIGURATION_get_value_filename (cfg,
      85             :                                                "exchange-offline",
      86             :                                                "SECM_TOFU_FILE",
      87             :                                                &dir))
      88             :   {
      89           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
      90             :                                "exchange-offline",
      91             :                                "SECM_TOFU_FILE");
      92           0 :     return GNUNET_SYSERR;
      93             :   }
      94           9 :   if ( (0 != unlink (dir)) &&
      95           4 :        (ENOENT != errno) )
      96             :   {
      97           0 :     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
      98             :                               "unlink",
      99             :                               dir);
     100           0 :     GNUNET_free (dir);
     101           0 :     return GNUNET_SYSERR;
     102             :   }
     103           9 :   GNUNET_free (dir);
     104           9 :   if (GNUNET_OK !=
     105           9 :       remove_dir (cfg,
     106             :                   "taler-exchange-secmod-eddsa",
     107             :                   "KEY_DIR"))
     108           0 :     return GNUNET_SYSERR;
     109           9 :   if (GNUNET_OK !=
     110           9 :       remove_dir (cfg,
     111             :                   "taler-exchange-secmod-rsa",
     112             :                   "KEY_DIR"))
     113           0 :     return GNUNET_SYSERR;
     114           9 :   return GNUNET_OK;
     115             : }
     116             : 
     117             : 
     118             : int
     119           9 : TALER_TESTING_run_auditor_exchange (const char *config_filename,
     120             :                                     const char *exchange_master_pub,
     121             :                                     const char *exchange_base_url,
     122             :                                     int do_remove)
     123             : {
     124             :   struct GNUNET_OS_Process *proc;
     125             :   enum GNUNET_OS_ProcessStatusType type;
     126             :   unsigned long code;
     127             : 
     128           9 :   TALER_LOG_DEBUG ("Add exchange (%s,%s) to the auditor\n",
     129             :                    exchange_base_url,
     130             :                    exchange_master_pub);
     131             : 
     132           9 :   proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
     133             :                                   NULL, NULL, NULL,
     134             :                                   "taler-auditor-exchange",
     135             :                                   "taler-auditor-exchange",
     136             :                                   "-c", config_filename,
     137             :                                   "-u", exchange_base_url,
     138             :                                   "-m", exchange_master_pub,
     139             :                                   (GNUNET_YES == do_remove)
     140             :                                   ? "-r"
     141             :                                   : NULL,
     142             :                                   NULL);
     143           9 :   if (NULL == proc)
     144             :   {
     145           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     146             :                 "Failed to run `taler-auditor-exchange`, is your PATH correct?\n");
     147           0 :     return GNUNET_SYSERR;
     148             :   }
     149           9 :   GNUNET_assert (GNUNET_OK ==
     150             :                  GNUNET_OS_process_wait_status (proc,
     151             :                                                 &type,
     152             :                                                 &code));
     153           9 :   GNUNET_OS_process_destroy (proc);
     154           9 :   if ( (0 != code) ||
     155           9 :        (GNUNET_OS_PROCESS_EXITED != type) )
     156             :   {
     157           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     158             :                 "taler-auditor-exchange terminated with error (%d/%d)\n",
     159             :                 (int) type,
     160             :                 (int) code);
     161           0 :     return GNUNET_SYSERR;
     162             :   }
     163           9 :   return GNUNET_OK;
     164             : }
     165             : 
     166             : 
     167             : int
     168           9 : TALER_TESTING_exchange_db_reset (const char *config_filename)
     169             : {
     170             :   struct GNUNET_OS_Process *proc;
     171             :   enum GNUNET_OS_ProcessStatusType type;
     172             :   unsigned long code;
     173             : 
     174           9 :   proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
     175             :                                   NULL, NULL, NULL,
     176             :                                   "taler-exchange-dbinit",
     177             :                                   "taler-exchange-dbinit",
     178             :                                   "-c", config_filename,
     179             :                                   "-r",
     180             :                                   NULL);
     181           9 :   if (NULL == proc)
     182             :   {
     183           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     184             :                 "Failed to run `taler-exchange-dbinit`, is your PATH correct?\n");
     185           0 :     return GNUNET_NO;
     186             :   }
     187           9 :   if (GNUNET_SYSERR ==
     188           9 :       GNUNET_OS_process_wait_status (proc,
     189             :                                      &type,
     190             :                                      &code))
     191             :   {
     192           0 :     GNUNET_break (0);
     193           0 :     GNUNET_OS_process_destroy (proc);
     194           0 :     return GNUNET_SYSERR;
     195             :   }
     196           9 :   GNUNET_OS_process_destroy (proc);
     197           9 :   if ( (type == GNUNET_OS_PROCESS_EXITED) &&
     198           9 :        (0 != code) )
     199             :   {
     200           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     201             :                 "Failed to setup (exchange) database, exit code %d\n",
     202             :                 (int) code);
     203           0 :     return GNUNET_NO;
     204             :   }
     205           9 :   if ( (type != GNUNET_OS_PROCESS_EXITED) ||
     206           9 :        (0 != code) )
     207             :   {
     208           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     209             :                 "Unexpected error (%d/%d) running `taler-exchange-dbinit'!\n",
     210             :                 (int) type,
     211             :                 (int) code);
     212           0 :     return GNUNET_SYSERR;
     213             :   }
     214           9 :   return GNUNET_OK;
     215             : }
     216             : 
     217             : 
     218             : int
     219           9 : TALER_TESTING_auditor_db_reset (const char *config_filename)
     220             : {
     221             :   struct GNUNET_OS_Process *proc;
     222             :   enum GNUNET_OS_ProcessStatusType type;
     223             :   unsigned long code;
     224             : 
     225           9 :   proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
     226             :                                   NULL, NULL, NULL,
     227             :                                   "taler-auditor-dbinit",
     228             :                                   "taler-auditor-dbinit",
     229             :                                   "-c", config_filename,
     230             :                                   "-R",
     231             :                                   NULL);
     232           9 :   if (NULL == proc)
     233             :   {
     234           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     235             :                 "Failed to run `taler-auditor-dbinit`, is your PATH correct?\n");
     236           0 :     return GNUNET_NO;
     237             :   }
     238           9 :   if (GNUNET_SYSERR ==
     239           9 :       GNUNET_OS_process_wait_status (proc,
     240             :                                      &type,
     241             :                                      &code))
     242             :   {
     243           0 :     GNUNET_break (0);
     244           0 :     GNUNET_OS_process_destroy (proc);
     245           0 :     return GNUNET_SYSERR;
     246             :   }
     247           9 :   GNUNET_OS_process_destroy (proc);
     248           9 :   if ( (type == GNUNET_OS_PROCESS_EXITED) &&
     249           9 :        (0 != code) )
     250             :   {
     251           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     252             :                 "Failed to setup (auditor) database, exit code %d\n",
     253             :                 (int) code);
     254           0 :     return GNUNET_NO;
     255             :   }
     256           9 :   if ( (type != GNUNET_OS_PROCESS_EXITED) ||
     257           9 :        (0 != code) )
     258             :   {
     259           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     260             :                 "Unexpected error (%d/%d) running `taler-auditor-dbinit'!\n",
     261             :                 (int) type,
     262             :                 (int) code);
     263           0 :     return GNUNET_SYSERR;
     264             :   }
     265           9 :   return GNUNET_OK;
     266             : }
     267             : 
     268             : 
     269             : /**
     270             :  * Type of closure for
     271             :  * #sign_keys_for_exchange.
     272             :  */
     273             : struct SignInfo
     274             : {
     275             :   /**
     276             :    * Members will be set to the exchange configuration.
     277             :    */
     278             :   struct TALER_TESTING_ExchangeConfiguration *ec;
     279             : 
     280             :   /**
     281             :    * Name of the configuration file to use.
     282             :    */
     283             :   const char *config_filename;
     284             : 
     285             :   /**
     286             :    * Did we reset the database?
     287             :    */
     288             :   int db_reset;
     289             : };
     290             : 
     291             : 
     292             : /**
     293             :  * Sign the keys for an exchange given configuration @a cfg.
     294             :  * The information to be signed must be in a file "auditor.in".
     295             :  *
     296             :  * @param[in,out] cls a `struct SignInfo` with further parameters
     297             :  * @param cfg configuration to use
     298             :  * @return #GNUNET_OK on success
     299             :  */
     300             : static int
     301           9 : sign_keys_for_exchange (void *cls,
     302             :                         const struct GNUNET_CONFIGURATION_Handle *cfg)
     303             : {
     304           9 :   struct SignInfo *si = cls;
     305             :   char *exchange_master_pub;
     306             :   int ret;
     307             : 
     308           9 :   if (GNUNET_OK !=
     309           9 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     310             :                                              "exchange",
     311             :                                              "BASE_URL",
     312           9 :                                              &si->ec->exchange_url))
     313             :   {
     314           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
     315             :                                "exchange",
     316             :                                "BASE_URL");
     317           0 :     si->ec->exchange_url = NULL;
     318           0 :     return GNUNET_NO;
     319             :   }
     320           9 :   if (GNUNET_OK !=
     321           9 :       TALER_TESTING_url_port_free (si->ec->exchange_url))
     322             :   {
     323           0 :     GNUNET_free (si->ec->exchange_url);
     324           0 :     si->ec->exchange_url = NULL;
     325           0 :     return GNUNET_NO;
     326             :   }
     327           9 :   if (GNUNET_OK !=
     328           9 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     329             :                                              "auditor",
     330             :                                              "BASE_URL",
     331           9 :                                              &si->ec->auditor_url))
     332             :   {
     333           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
     334             :                                "auditor",
     335             :                                "BASE_URL");
     336           0 :     GNUNET_free (si->ec->exchange_url);
     337           0 :     si->ec->exchange_url = NULL;
     338           0 :     si->ec->auditor_url = NULL;
     339           0 :     return GNUNET_SYSERR;
     340             :   }
     341           9 :   if (GNUNET_OK !=
     342           9 :       TALER_TESTING_url_port_free (si->ec->auditor_url))
     343             :   {
     344           0 :     ret = GNUNET_NO;
     345           0 :     goto fail;
     346             :   }
     347           9 :   if (GNUNET_OK !=
     348           9 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     349             :                                              "exchange",
     350             :                                              "MASTER_PUBLIC_KEY",
     351             :                                              &exchange_master_pub))
     352             :   {
     353           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     354             :                                "exchange",
     355             :                                "MASTER_PUBLIC_KEY");
     356           0 :     ret = GNUNET_SYSERR;
     357           0 :     goto fail;
     358             :   }
     359           9 :   if ( (GNUNET_OK !=
     360           9 :         TALER_TESTING_run_auditor_exchange (si->config_filename,
     361             :                                             exchange_master_pub,
     362           9 :                                             si->ec->exchange_url,
     363           0 :                                             GNUNET_NO)) &&
     364           0 :        (GNUNET_YES == si->db_reset) )
     365             :   {
     366           0 :     ret = GNUNET_NO;
     367           0 :     goto fail;
     368             :   }
     369           9 :   GNUNET_free (exchange_master_pub);
     370           9 :   return GNUNET_OK;
     371           0 : fail:
     372           0 :   GNUNET_free (si->ec->exchange_url);
     373           0 :   GNUNET_free (si->ec->auditor_url);
     374           0 :   si->ec->exchange_url = NULL;
     375           0 :   si->ec->auditor_url = NULL;
     376           0 :   return ret;
     377             : }
     378             : 
     379             : 
     380             : /**
     381             :  * Prepare launching an exchange.  Checks that the configured
     382             :  * port is available, runs taler-exchange-dbinit.  Does NOT
     383             :  * launch the exchange process itself.
     384             :  *
     385             :  * @param config_filename configuration file to use
     386             :  * @param reset_db should we reset the database?
     387             :  * @param[out] ec will be set to the exchange configuration data
     388             :  * @return #GNUNET_OK on success, #GNUNET_NO if test should be
     389             :  *         skipped, #GNUNET_SYSERR on test failure
     390             :  */
     391             : int
     392           9 : TALER_TESTING_prepare_exchange (const char *config_filename,
     393             :                                 int reset_db,
     394             :                                 struct TALER_TESTING_ExchangeConfiguration *ec)
     395             : {
     396           9 :   struct SignInfo si = {
     397             :     .config_filename = config_filename,
     398             :     .ec = ec,
     399             :     .db_reset = reset_db
     400             :   };
     401             : 
     402           9 :   if (GNUNET_YES == reset_db)
     403             :   {
     404           9 :     if (GNUNET_OK !=
     405           9 :         TALER_TESTING_exchange_db_reset (config_filename))
     406           0 :       return GNUNET_NO;
     407           9 :     if (GNUNET_OK !=
     408           9 :         TALER_TESTING_auditor_db_reset (config_filename))
     409           0 :       return GNUNET_NO;
     410             :   }
     411           9 :   if (GNUNET_OK !=
     412           9 :       GNUNET_CONFIGURATION_parse_and_run (config_filename,
     413             :                                           &sign_keys_for_exchange,
     414             :                                           &si))
     415           0 :     return GNUNET_NO;
     416           9 :   return GNUNET_OK;
     417             : }
     418             : 
     419             : 
     420             : /**
     421             :  * Find denomination key matching the given amount.
     422             :  *
     423             :  * @param keys array of keys to search
     424             :  * @param amount coin value to look for
     425             :  * @return NULL if no matching key was found
     426             :  */
     427             : const struct TALER_EXCHANGE_DenomPublicKey *
     428          79 : TALER_TESTING_find_pk (const struct TALER_EXCHANGE_Keys *keys,
     429             :                        const struct TALER_Amount *amount)
     430             : {
     431             :   struct GNUNET_TIME_Absolute now;
     432             :   struct TALER_EXCHANGE_DenomPublicKey *pk;
     433             :   char *str;
     434             : 
     435          79 :   now = GNUNET_TIME_absolute_get ();
     436        1485 :   for (unsigned int i = 0; i<keys->num_denom_keys; i++)
     437             :   {
     438        1485 :     pk = &keys->denom_keys[i];
     439        1485 :     if ( (0 == TALER_amount_cmp (amount,
     440        1485 :                                  &pk->value)) &&
     441         316 :          (now.abs_value_us >= pk->valid_from.abs_value_us) &&
     442          79 :          (now.abs_value_us <
     443          79 :           pk->withdraw_valid_until.abs_value_us) )
     444          79 :       return pk;
     445             :   }
     446             :   /* do 2nd pass to check if expiration times are to blame for
     447             :    * failure */
     448           0 :   str = TALER_amount_to_string (amount);
     449           0 :   for (unsigned int i = 0; i<keys->num_denom_keys; i++)
     450             :   {
     451           0 :     pk = &keys->denom_keys[i];
     452           0 :     if ( (0 == TALER_amount_cmp (amount,
     453           0 :                                  &pk->value)) &&
     454           0 :          ( (now.abs_value_us < pk->valid_from.abs_value_us) ||
     455           0 :            (now.abs_value_us >
     456           0 :             pk->withdraw_valid_until.abs_value_us) ) )
     457             :     {
     458           0 :       GNUNET_log
     459             :         (GNUNET_ERROR_TYPE_WARNING,
     460             :         "Have denomination key for `%s', but with wrong"
     461             :         " expiration range %llu vs [%llu,%llu)\n",
     462             :         str,
     463             :         (unsigned long long) now.abs_value_us,
     464             :         (unsigned long long) pk->valid_from.abs_value_us,
     465             :         (unsigned long long)
     466             :         pk->withdraw_valid_until.abs_value_us);
     467           0 :       GNUNET_free (str);
     468           0 :       return NULL;
     469             :     }
     470             :   }
     471           0 :   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     472             :               "No denomination key for amount %s found\n",
     473             :               str);
     474           0 :   GNUNET_free (str);
     475           0 :   return NULL;
     476             : }
     477             : 
     478             : 
     479             : int
     480           9 : TALER_TESTING_wait_exchange_ready (const char *base_url)
     481             : {
     482             :   char *wget_cmd;
     483             :   unsigned int iter;
     484             : 
     485           9 :   GNUNET_asprintf (&wget_cmd,
     486             :                    "wget -q -t 1 -T 1 %sseed -o /dev/null -O /dev/null",
     487             :                    base_url); // make sure ends with '/'
     488             :   /* give child time to start and bind against the socket */
     489           9 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     490             :               "Waiting for `taler-exchange-httpd` service to be ready (check with: %s)\n",
     491             :               wget_cmd);
     492           9 :   iter = 0;
     493             :   do
     494             :   {
     495           9 :     if (10 == iter)
     496             :     {
     497           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     498             :                   "Failed to launch `taler-exchange-httpd` service (or `wget')\n");
     499           0 :       GNUNET_free (wget_cmd);
     500           0 :       return 77;
     501             :     }
     502           9 :     sleep (1);
     503           9 :     iter++;
     504             :   }
     505           9 :   while (0 != system (wget_cmd));
     506           9 :   GNUNET_free (wget_cmd);
     507           9 :   return 0;
     508             : }
     509             : 
     510             : 
     511             : int
     512           0 : TALER_TESTING_wait_httpd_ready (const char *base_url)
     513             : {
     514             :   char *wget_cmd;
     515             :   unsigned int iter;
     516             : 
     517           0 :   GNUNET_asprintf (&wget_cmd,
     518             :                    "wget -q -t 1 -T 1 %s -o /dev/null -O /dev/null",
     519             :                    base_url); // make sure ends with '/'
     520             :   /* give child time to start and bind against the socket */
     521           0 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     522             :               "Waiting for HTTP service to be ready (check with: %s)\n",
     523             :               wget_cmd);
     524           0 :   iter = 0;
     525             :   do
     526             :   {
     527           0 :     if (10 == iter)
     528             :     {
     529           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     530             :                   "Failed to launch HTTP service (or `wget')\n");
     531           0 :       GNUNET_free (wget_cmd);
     532           0 :       return 77;
     533             :     }
     534           0 :     sleep (1);
     535           0 :     iter++;
     536             :   }
     537           0 :   while (0 != system (wget_cmd));
     538           0 :   GNUNET_free (wget_cmd);
     539           0 :   return 0;
     540             : }
     541             : 
     542             : 
     543             : /**
     544             :  * Wait for the auditor to have started. Waits for at
     545             :  * most 10s, after that returns 77 to indicate an error.
     546             :  *
     547             :  * @param base_url what URL should we expect the auditor
     548             :  *        to be running at
     549             :  * @return 0 on success
     550             :  */
     551             : int
     552           2 : TALER_TESTING_wait_auditor_ready (const char *base_url)
     553             : {
     554             :   char *wget_cmd;
     555             :   unsigned int iter;
     556             : 
     557           2 :   GNUNET_asprintf (&wget_cmd,
     558             :                    "wget -q -t 1 -T 1 %sversion -o /dev/null -O /dev/null",
     559             :                    base_url); // make sure ends with '/'
     560             :   /* give child time to start and bind against the socket */
     561           2 :   fprintf (stderr,
     562             :            "Waiting for `taler-auditor-httpd' to be ready at %s\n",
     563             :            base_url);
     564           2 :   iter = 0;
     565             :   do
     566             :   {
     567           2 :     if (10 == iter)
     568             :     {
     569           0 :       fprintf (stderr,
     570             :                "Failed to launch `taler-auditor-httpd' (or `wget')\n");
     571           0 :       GNUNET_free (wget_cmd);
     572           0 :       return 77;
     573             :     }
     574           2 :     fprintf (stderr, ".\n");
     575           2 :     sleep (1);
     576           2 :     iter++;
     577             :   }
     578           2 :   while (0 != system (wget_cmd));
     579           2 :   GNUNET_free (wget_cmd);
     580           2 :   return 0;
     581             : }
     582             : 
     583             : 
     584             : int
     585           8 : TALER_TESTING_setup_with_exchange (TALER_TESTING_Main main_cb,
     586             :                                    void *main_cb_cls,
     587             :                                    const char *config_file)
     588             : {
     589           8 :   struct TALER_TESTING_SetupContext setup_ctx = {
     590             :     .config_filename = config_file,
     591             :     .main_cb = main_cb,
     592             :     .main_cb_cls = main_cb_cls
     593             :   };
     594             :   int result;
     595             : 
     596             :   result =
     597           8 :     GNUNET_CONFIGURATION_parse_and_run (config_file,
     598             :                                         &TALER_TESTING_setup_with_exchange_cfg,
     599             :                                         &setup_ctx);
     600           8 :   if (GNUNET_OK != result)
     601           0 :     return result;
     602           8 :   return GNUNET_OK;
     603             : }
     604             : 
     605             : 
     606             : /**
     607             :  * Stop taler-exchange-crypto helpers.
     608             :  *
     609             :  * @param[in] helpers the process handles.
     610             :  */
     611             : static void
     612           9 : stop_helpers (struct GNUNET_OS_Process *helpers[2])
     613             : {
     614          27 :   for (unsigned int i = 0; i<2; i++)
     615             :   {
     616          18 :     if (NULL == helpers[i])
     617           0 :       continue;
     618          18 :     GNUNET_break (0 ==
     619             :                   GNUNET_OS_process_kill (helpers[i],
     620             :                                           SIGTERM));
     621          18 :     GNUNET_break (GNUNET_OK ==
     622             :                   GNUNET_OS_process_wait (helpers[i]));
     623          18 :     GNUNET_OS_process_destroy (helpers[i]);
     624             :   }
     625           9 : }
     626             : 
     627             : 
     628             : /**
     629             :  * Start taler-exchange-crypto helpers.
     630             :  *
     631             :  * @param config_filename configuration file to use
     632             :  * @param[out] helpers where to store the process handles.
     633             :  */
     634             : static int
     635           9 : start_helpers (const char *config_filename,
     636             :                struct GNUNET_OS_Process *helpers[2])
     637             : {
     638             :   char *dir;
     639             :   const struct GNUNET_OS_ProjectData *pd;
     640             : 
     641           9 :   pd = GNUNET_OS_project_data_get ();
     642           9 :   GNUNET_OS_init (TALER_project_data_default ());
     643           9 :   dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_BINDIR);
     644           9 :   GNUNET_OS_init (pd);
     645           9 :   if (NULL == dir)
     646             :   {
     647           0 :     GNUNET_break (0);
     648           0 :     return GNUNET_SYSERR;
     649             :   }
     650             :   {
     651             :     char *fn;
     652             : 
     653           9 :     GNUNET_asprintf (&fn,
     654             :                      "%s/%s",
     655             :                      dir,
     656             :                      "taler-exchange-secmod-eddsa");
     657           9 :     helpers[0] = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
     658             :                                           NULL, NULL, NULL,
     659             :                                           fn,
     660             :                                           "taler-exchange-secmod-eddsa",
     661             :                                           "-c", config_filename,
     662             :                                           "-L", "INFO",
     663             :                                           NULL);
     664           9 :     GNUNET_free (fn);
     665             :   }
     666             :   {
     667             :     char *fn;
     668             : 
     669           9 :     GNUNET_asprintf (&fn,
     670             :                      "%s/%s",
     671             :                      dir,
     672             :                      "taler-exchange-secmod-rsa");
     673           9 :     helpers[1] = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
     674             :                                           NULL, NULL, NULL,
     675             :                                           fn,
     676             :                                           "taler-exchange-secmod-rsa",
     677             :                                           "-c", config_filename,
     678             :                                           "-L", "INFO",
     679             :                                           NULL);
     680           9 :     GNUNET_free (fn);
     681             :   }
     682           9 :   GNUNET_free (dir);
     683           9 :   if ( (NULL == helpers[0]) ||
     684           9 :        (NULL == helpers[1]) )
     685             :   {
     686           0 :     stop_helpers (helpers);
     687           0 :     return GNUNET_SYSERR;
     688             :   }
     689           9 :   return GNUNET_OK;
     690             : }
     691             : 
     692             : 
     693             : int
     694           9 : TALER_TESTING_setup_with_exchange_cfg (
     695             :   void *cls,
     696             :   const struct GNUNET_CONFIGURATION_Handle *cfg)
     697             : {
     698           9 :   const struct TALER_TESTING_SetupContext *setup_ctx = cls;
     699             :   struct GNUNET_OS_Process *exchanged;
     700             :   struct GNUNET_OS_Process *helpers[2];
     701             :   unsigned long long port;
     702             :   char *serve;
     703             :   char *base_url;
     704             :   int result;
     705             : 
     706           9 :   if (GNUNET_OK !=
     707           9 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     708             :                                              "exchange",
     709             :                                              "SERVE",
     710             :                                              &serve))
     711             :   {
     712           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     713             :                                "exchange",
     714             :                                "SERVE");
     715           0 :     return GNUNET_NO;
     716             :   }
     717             : 
     718           9 :   if (0 == strcmp ("tcp", serve))
     719             :   {
     720           9 :     if (GNUNET_OK !=
     721           9 :         GNUNET_CONFIGURATION_get_value_number (cfg,
     722             :                                                "exchange",
     723             :                                                "PORT",
     724             :                                                &port))
     725             :     {
     726           0 :       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     727             :                                  "exchange",
     728             :                                  "PORT");
     729           0 :       GNUNET_free (serve);
     730           0 :       return GNUNET_NO;
     731             :     }
     732             : 
     733           9 :     if (GNUNET_OK !=
     734           9 :         GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
     735           9 :                                        (uint16_t) port))
     736             :     {
     737           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     738             :                   "Required port %llu not available, skipping.\n",
     739             :                   port);
     740           0 :       GNUNET_free (serve);
     741           0 :       return GNUNET_NO;
     742             :     }
     743             :   }
     744           9 :   GNUNET_free (serve);
     745           9 :   if (GNUNET_OK !=
     746           9 :       start_helpers (setup_ctx->config_filename,
     747             :                      helpers))
     748             :   {
     749           0 :     GNUNET_break (0);
     750           0 :     return 77;
     751             :   }
     752           9 :   exchanged = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
     753             :                                        NULL, NULL, NULL,
     754             :                                        "taler-exchange-httpd",
     755             :                                        "taler-exchange-httpd",
     756             :                                        "-a", /* some tests may need timetravel */
     757             :                                        "-c", setup_ctx->config_filename,
     758             :                                        NULL);
     759           9 :   if (NULL == exchanged)
     760             :   {
     761           0 :     GNUNET_break (0);
     762           0 :     stop_helpers (helpers);
     763           0 :     return 77;
     764             :   }
     765           9 :   if (GNUNET_OK !=
     766           9 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     767             :                                              "exchange",
     768             :                                              "BASE_URL",
     769             :                                              &base_url))
     770             :   {
     771           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     772             :                                "exchange",
     773             :                                "BASE_URL");
     774           0 :     stop_helpers (helpers);
     775           0 :     return GNUNET_NO;
     776             :   }
     777             : 
     778           9 :   if (0 != TALER_TESTING_wait_exchange_ready (base_url))
     779             :   {
     780           0 :     GNUNET_free (base_url);
     781           0 :     stop_helpers (helpers);
     782           0 :     GNUNET_break (0 ==
     783             :                   GNUNET_OS_process_kill (exchanged,
     784             :                                           SIGTERM));
     785           0 :     GNUNET_break (GNUNET_OK ==
     786             :                   GNUNET_OS_process_wait (exchanged));
     787           0 :     GNUNET_OS_process_destroy (exchanged);
     788           0 :     return 77;
     789             :   }
     790           9 :   GNUNET_free (base_url);
     791             : 
     792             :   /* NOTE: this call blocks.  */
     793           9 :   result = TALER_TESTING_setup (setup_ctx->main_cb,
     794             :                                 setup_ctx->main_cb_cls,
     795             :                                 cfg,
     796             :                                 exchanged,
     797             :                                 GNUNET_YES);
     798           9 :   GNUNET_break (0 ==
     799             :                 GNUNET_OS_process_kill (exchanged,
     800             :                                         SIGTERM));
     801           9 :   GNUNET_break (GNUNET_OK ==
     802             :                 GNUNET_OS_process_wait (exchanged));
     803           9 :   GNUNET_OS_process_destroy (exchanged);
     804           9 :   stop_helpers (helpers);
     805           9 :   return result;
     806             : }
     807             : 
     808             : 
     809             : int
     810           1 : TALER_TESTING_setup_with_auditor_and_exchange_cfg (
     811             :   void *cls,
     812             :   const struct GNUNET_CONFIGURATION_Handle *cfg)
     813             : {
     814           1 :   const struct TALER_TESTING_SetupContext *setup_ctx = cls;
     815             :   struct GNUNET_OS_Process *auditord;
     816             :   unsigned long long port;
     817             :   char *serve;
     818             :   char *base_url;
     819             :   int result;
     820             : 
     821           1 :   if (GNUNET_OK !=
     822           1 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     823             :                                              "auditor",
     824             :                                              "SERVE",
     825             :                                              &serve))
     826             :   {
     827           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     828             :                                "auditor",
     829             :                                "SERVE");
     830           0 :     return GNUNET_NO;
     831             :   }
     832             : 
     833           1 :   if (0 == strcmp ("tcp", serve))
     834             :   {
     835           1 :     if (GNUNET_OK !=
     836           1 :         GNUNET_CONFIGURATION_get_value_number (cfg,
     837             :                                                "auditor",
     838             :                                                "PORT",
     839             :                                                &port))
     840             :     {
     841           0 :       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     842             :                                  "auditor",
     843             :                                  "PORT");
     844           0 :       GNUNET_free (serve);
     845           0 :       return GNUNET_NO;
     846             :     }
     847             : 
     848           1 :     if (GNUNET_OK !=
     849           1 :         GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
     850           1 :                                        (uint16_t) port))
     851             :     {
     852           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     853             :                   "Required port %llu not available, skipping.\n",
     854             :                   port);
     855           0 :       GNUNET_free (serve);
     856           0 :       return GNUNET_NO;
     857             :     }
     858             :   }
     859           1 :   GNUNET_free (serve);
     860           1 :   auditord = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
     861             :                                       NULL, NULL, NULL,
     862             :                                       "taler-auditor-httpd",
     863             :                                       "taler-auditor-httpd",
     864             :                                       "-c", setup_ctx->config_filename,
     865             :                                       NULL);
     866             : 
     867           1 :   if (GNUNET_OK !=
     868           1 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     869             :                                              "auditor",
     870             :                                              "BASE_URL",
     871             :                                              &base_url))
     872             :   {
     873           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     874             :                                "auditor",
     875             :                                "BASE_URL");
     876           0 :     return GNUNET_NO;
     877             :   }
     878             : 
     879           1 :   if (0 != TALER_TESTING_wait_auditor_ready (base_url))
     880             :   {
     881           0 :     GNUNET_free (base_url);
     882           0 :     GNUNET_break (0 ==
     883             :                   GNUNET_OS_process_kill (auditord,
     884             :                                           SIGTERM));
     885           0 :     GNUNET_break (GNUNET_OK ==
     886             :                   GNUNET_OS_process_wait (auditord));
     887           0 :     GNUNET_OS_process_destroy (auditord);
     888           0 :     return 77;
     889             :   }
     890           1 :   GNUNET_free (base_url);
     891             : 
     892             :   /* NOTE: this call blocks.  */
     893           1 :   result = TALER_TESTING_setup_with_exchange_cfg ((void *) setup_ctx,
     894             :                                                   cfg);
     895           1 :   GNUNET_break (0 ==
     896             :                 GNUNET_OS_process_kill (auditord,
     897             :                                         SIGTERM));
     898           1 :   GNUNET_break (GNUNET_OK ==
     899             :                 GNUNET_OS_process_wait (auditord));
     900           1 :   GNUNET_OS_process_destroy (auditord);
     901           1 :   return result;
     902             : }
     903             : 
     904             : 
     905             : int
     906           0 : TALER_TESTING_setup_with_auditor_and_exchange (TALER_TESTING_Main main_cb,
     907             :                                                void *main_cb_cls,
     908             :                                                const char *config_file)
     909             : {
     910           0 :   struct TALER_TESTING_SetupContext setup_ctx = {
     911             :     .config_filename = config_file,
     912             :     .main_cb = main_cb,
     913             :     .main_cb_cls = main_cb_cls
     914             :   };
     915             : 
     916           0 :   return GNUNET_CONFIGURATION_parse_and_run (
     917             :     config_file,
     918             :     &TALER_TESTING_setup_with_auditor_and_exchange_cfg,
     919             :     &setup_ctx);
     920             : }
     921             : 
     922             : 
     923             : int
     924          27 : TALER_TESTING_url_port_free (const char *url)
     925             : {
     926             :   const char *port;
     927             :   long pnum;
     928             : 
     929          27 :   port = strrchr (url,
     930             :                   (unsigned char) ':');
     931          27 :   if (NULL == port)
     932           0 :     pnum = 80;
     933             :   else
     934          27 :     pnum = strtol (port + 1, NULL, 10);
     935          27 :   if (GNUNET_OK !=
     936          27 :       GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
     937             :                                      pnum))
     938             :   {
     939           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     940             :                 "Port %u not available.\n",
     941             :                 (unsigned int) pnum);
     942           0 :     return GNUNET_SYSERR;
     943             :   }
     944          27 :   return GNUNET_OK;
     945             : }
     946             : 
     947             : 
     948             : /* end of testing_api_helpers_exchange.c */

Generated by: LCOV version 1.14