testing_api_misc.c (11601B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2018-2024 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 * @file testing/testing_api_misc.c 21 * @brief non-command functions useful for writing tests 22 * @author Christian Grothoff 23 */ 24 #include "taler/platform.h" 25 #include <gnunet/gnunet_util_lib.h> 26 #include "taler/taler_testing_lib.h" 27 #include "taler/taler_fakebank_lib.h" 28 29 30 bool 31 TALER_TESTING_has_in_name (const char *prog, 32 const char *marker) 33 { 34 size_t name_pos; 35 size_t pos; 36 37 if (! prog || ! marker) 38 return false; 39 40 pos = 0; 41 name_pos = 0; 42 while (prog[pos]) 43 { 44 if ('/' == prog[pos]) 45 name_pos = pos + 1; 46 pos++; 47 } 48 if (name_pos == pos) 49 return true; 50 return (NULL != strstr (prog + name_pos, 51 marker)); 52 } 53 54 55 enum GNUNET_GenericReturnValue 56 TALER_TESTING_get_credentials ( 57 const char *cfg_file, 58 const char *exchange_account_section, 59 enum TALER_TESTING_BankSystem bs, 60 struct TALER_TESTING_Credentials *ua) 61 { 62 unsigned long long port; 63 struct TALER_FullPayto exchange_payto_uri; 64 65 ua->cfg = GNUNET_CONFIGURATION_create (TALER_EXCHANGE_project_data ()); 66 if (GNUNET_OK != 67 GNUNET_CONFIGURATION_load (ua->cfg, 68 cfg_file)) 69 { 70 GNUNET_break (0); 71 GNUNET_CONFIGURATION_destroy (ua->cfg); 72 return GNUNET_SYSERR; 73 } 74 if (0 != 75 strncasecmp (exchange_account_section, 76 "exchange-account-", 77 strlen ("exchange-account-"))) 78 { 79 GNUNET_break (0); 80 return GNUNET_SYSERR; 81 } 82 if (GNUNET_OK != 83 GNUNET_CONFIGURATION_get_value_string ( 84 ua->cfg, 85 exchange_account_section, 86 "PAYTO_URI", 87 &exchange_payto_uri.full_payto)) 88 { 89 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 90 exchange_account_section, 91 "PAYTO_URI"); 92 return GNUNET_SYSERR; 93 } 94 if (GNUNET_OK != 95 GNUNET_CONFIGURATION_get_value_number (ua->cfg, 96 "bank", 97 "HTTP_PORT", 98 &port)) 99 { 100 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 101 "bank", 102 "HTTP_PORT"); 103 return GNUNET_SYSERR; 104 } 105 { 106 char *csn; 107 108 GNUNET_asprintf (&csn, 109 "exchange-accountcredentials-%s", 110 &exchange_account_section[strlen ("exchange-account-")]); 111 if (GNUNET_OK != 112 TALER_BANK_auth_parse_cfg (ua->cfg, 113 csn, 114 &ua->ba)) 115 { 116 GNUNET_break (0); 117 GNUNET_free (csn); 118 return GNUNET_SYSERR; 119 } 120 GNUNET_free (csn); 121 } 122 { 123 char *csn; 124 125 GNUNET_asprintf (&csn, 126 "admin-accountcredentials-%s", 127 &exchange_account_section[strlen ("exchange-account-")]); 128 if (GNUNET_OK != 129 TALER_BANK_auth_parse_cfg (ua->cfg, 130 csn, 131 &ua->ba_admin)) 132 { 133 GNUNET_break (0); 134 GNUNET_free (csn); 135 return GNUNET_SYSERR; 136 } 137 GNUNET_free (csn); 138 } 139 if (GNUNET_OK != 140 GNUNET_CONFIGURATION_get_value_string (ua->cfg, 141 "exchange", 142 "BASE_URL", 143 &ua->exchange_url)) 144 { 145 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 146 "exchange", 147 "BASE_URL"); 148 return GNUNET_SYSERR; 149 } 150 if (GNUNET_OK != 151 GNUNET_CONFIGURATION_get_value_string (ua->cfg, 152 "auditor", 153 "BASE_URL", 154 &ua->auditor_url)) 155 { 156 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 157 "auditor", 158 "BASE_URL"); 159 return GNUNET_SYSERR; 160 } 161 162 switch (bs) 163 { 164 case TALER_TESTING_BS_FAKEBANK: 165 ua->exchange_payto 166 = exchange_payto_uri; 167 ua->user42_payto.full_payto 168 = GNUNET_strdup ("payto://x-taler-bank/localhost/42?receiver-name=42"); 169 ua->user43_payto.full_payto 170 = GNUNET_strdup ("payto://x-taler-bank/localhost/43?receiver-name=43"); 171 ua->user44_payto.full_payto 172 = GNUNET_strdup ("payto://x-taler-bank/localhost/44?receiver-name=44"); 173 break; 174 case TALER_TESTING_BS_IBAN: 175 ua->exchange_payto 176 = exchange_payto_uri; 177 ua->user42_payto.full_payto 178 = GNUNET_strdup ( 179 "payto://iban/SANDBOXX/FR7630006000011234567890189?receiver-name=User42"); 180 ua->user43_payto.full_payto 181 = GNUNET_strdup ( 182 "payto://iban/SANDBOXX/GB33BUKB20201555555555?receiver-name=User43"); 183 ua->user44_payto.full_payto 184 = GNUNET_strdup ( 185 "payto://iban/SANDBOXX/NL05RABO5361965189?receiver-name=User44"); 186 break; 187 } 188 return GNUNET_OK; 189 } 190 191 192 json_t * 193 TALER_TESTING_make_wire_details (struct TALER_FullPayto payto) 194 { 195 struct TALER_WireSaltP salt; 196 197 /* salt must be constant for aggregation tests! */ 198 memset (&salt, 199 47, 200 sizeof (salt)); 201 return GNUNET_JSON_PACK ( 202 TALER_JSON_pack_full_payto ("payto_uri", 203 payto), 204 GNUNET_JSON_pack_data_auto ("salt", 205 &salt)); 206 } 207 208 209 /** 210 * Remove @a option directory from @a section in @a cfg. 211 * 212 * @return #GNUNET_OK on success 213 */ 214 static enum GNUNET_GenericReturnValue 215 remove_dir (const struct GNUNET_CONFIGURATION_Handle *cfg, 216 const char *section, 217 const char *option) 218 { 219 char *dir; 220 221 if (GNUNET_OK != 222 GNUNET_CONFIGURATION_get_value_filename (cfg, 223 section, 224 option, 225 &dir)) 226 { 227 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 228 section, 229 option); 230 return GNUNET_SYSERR; 231 } 232 if (GNUNET_YES == 233 GNUNET_DISK_directory_test (dir, 234 GNUNET_NO)) 235 GNUNET_break (GNUNET_OK == 236 GNUNET_DISK_directory_remove (dir)); 237 GNUNET_free (dir); 238 return GNUNET_OK; 239 } 240 241 242 enum GNUNET_GenericReturnValue 243 TALER_TESTING_cleanup_files_cfg ( 244 void *cls, 245 const struct GNUNET_CONFIGURATION_Handle *cfg) 246 { 247 char *dir; 248 249 (void) cls; 250 if (GNUNET_OK != 251 GNUNET_CONFIGURATION_get_value_filename (cfg, 252 "exchange-offline", 253 "SECM_TOFU_FILE", 254 &dir)) 255 { 256 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 257 "exchange-offline", 258 "SECM_TOFU_FILE"); 259 return GNUNET_SYSERR; 260 } 261 if ( (0 != unlink (dir)) && 262 (ENOENT != errno) ) 263 { 264 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 265 "unlink", 266 dir); 267 GNUNET_free (dir); 268 return GNUNET_SYSERR; 269 } 270 GNUNET_free (dir); 271 if (GNUNET_OK != 272 remove_dir (cfg, 273 "taler-exchange-secmod-eddsa", 274 "KEY_DIR")) 275 return GNUNET_SYSERR; 276 if (GNUNET_OK != 277 remove_dir (cfg, 278 "taler-exchange-secmod-rsa", 279 "KEY_DIR")) 280 return GNUNET_SYSERR; 281 return GNUNET_OK; 282 } 283 284 285 const struct TALER_EXCHANGE_DenomPublicKey * 286 TALER_TESTING_find_pk ( 287 const struct TALER_EXCHANGE_Keys *keys, 288 const struct TALER_Amount *amount, 289 bool age_restricted) 290 { 291 struct GNUNET_TIME_Timestamp now; 292 struct TALER_EXCHANGE_DenomPublicKey *pk; 293 char *str; 294 295 now = GNUNET_TIME_timestamp_get (); 296 for (unsigned int i = 0; i<keys->num_denom_keys; i++) 297 { 298 pk = &keys->denom_keys[i]; 299 if ( (0 == TALER_amount_cmp (amount, 300 &pk->value)) && 301 (GNUNET_TIME_timestamp_cmp (now, 302 >=, 303 pk->valid_from)) && 304 (GNUNET_TIME_timestamp_cmp (now, 305 <, 306 pk->withdraw_valid_until)) && 307 (age_restricted == (0 != pk->key.age_mask.bits)) ) 308 return pk; 309 } 310 /* do 2nd pass to check if expiration times are to blame for 311 * failure */ 312 str = TALER_amount_to_string (amount); 313 for (unsigned int i = 0; i<keys->num_denom_keys; i++) 314 { 315 pk = &keys->denom_keys[i]; 316 if ( (0 == TALER_amount_cmp (amount, 317 &pk->value)) && 318 (GNUNET_TIME_timestamp_cmp (now, 319 <, 320 pk->valid_from) || 321 GNUNET_TIME_timestamp_cmp (now, 322 >, 323 pk->withdraw_valid_until) ) && 324 (age_restricted == (0 != pk->key.age_mask.bits)) ) 325 { 326 GNUNET_log 327 (GNUNET_ERROR_TYPE_WARNING, 328 "Have denomination key for `%s', but with wrong" 329 " expiration range %llu vs [%llu,%llu)\n", 330 str, 331 (unsigned long long) now.abs_time.abs_value_us, 332 (unsigned long long) pk->valid_from.abs_time.abs_value_us, 333 (unsigned long long) pk->withdraw_valid_until.abs_time.abs_value_us); 334 GNUNET_free (str); 335 return NULL; 336 } 337 } 338 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 339 "No denomination key for amount %s found\n", 340 str); 341 GNUNET_free (str); 342 return NULL; 343 } 344 345 346 int 347 TALER_TESTING_wait_httpd_ready (const char *base_url) 348 { 349 char *wget_cmd; 350 unsigned int iter; 351 352 GNUNET_asprintf (&wget_cmd, 353 "wget -q -t 1 -T 1 %s -o /dev/null -O /dev/null", 354 base_url); // make sure ends with '/' 355 /* give child time to start and bind against the socket */ 356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 357 "Waiting for HTTP service to be ready (check with: %s)\n", 358 wget_cmd); 359 iter = 0; 360 do 361 { 362 if (10 == iter) 363 { 364 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 365 "Failed to launch HTTP service (or `wget')\n"); 366 GNUNET_free (wget_cmd); 367 return 77; 368 } 369 sleep (1); 370 iter++; 371 } 372 while (0 != system (wget_cmd)); 373 GNUNET_free (wget_cmd); 374 return 0; 375 } 376 377 378 enum GNUNET_GenericReturnValue 379 TALER_TESTING_url_port_free (const char *url) 380 { 381 const char *port; 382 long pnum; 383 384 port = strrchr (url, 385 (unsigned char) ':'); 386 if (NULL == port) 387 pnum = 80; 388 else 389 pnum = strtol (port + 1, NULL, 10); 390 if (GNUNET_OK != 391 GNUNET_NETWORK_test_port_free (IPPROTO_TCP, 392 pnum)) 393 { 394 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 395 "Port %u not available.\n", 396 (unsigned int) pnum); 397 return GNUNET_SYSERR; 398 } 399 return GNUNET_OK; 400 }