test_exchange_api_twisted.c (10671B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2023 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/test_exchange_api_twisted.c 21 * @brief testcase to test exchange's HTTP API interface 22 * @author Marcello Stanisci 23 * @author Sree Harsha Totakura <sreeharsha@totakura.in> 24 * @author Christian Grothoff 25 */ 26 #include "platform.h" 27 #include "taler/taler_util.h" 28 #include "taler/taler_signatures.h" 29 #include "taler/taler_json_lib.h" 30 #include <gnunet/gnunet_util_lib.h> 31 #include <gnunet/gnunet_testing_lib.h> 32 #include <microhttpd.h> 33 #include "taler/taler_bank_service.h" 34 #include "taler/taler_testing_lib.h" 35 #include "taler/taler_twister_testing_lib.h" 36 #include <taler/taler_twister_service.h> 37 38 /** 39 * Configuration file we use. One (big) configuration is used 40 * for the various components for this test. 41 */ 42 static char *config_file; 43 44 /** 45 * Our credentials. 46 */ 47 static struct TALER_TESTING_Credentials cred; 48 49 /** 50 * (real) Twister URL. Used at startup time to check if it runs. 51 */ 52 static char *twister_url; 53 54 /** 55 * Twister process. 56 */ 57 static struct GNUNET_Process *twisterd; 58 59 60 /** 61 * Execute the taler-exchange-wirewatch command with 62 * our configuration file. 63 * 64 * @param label label to use for the command. 65 */ 66 static struct TALER_TESTING_Command 67 CMD_EXEC_WIREWATCH (const char *label) 68 { 69 return TALER_TESTING_cmd_exec_wirewatch2 (label, 70 config_file, 71 "exchange-account-2"); 72 } 73 74 75 /** 76 * Run wire transfer of funds from some user's account to the 77 * exchange. 78 * 79 * @param label label to use for the command. 80 * @param amount amount to transfer, i.e. "EUR:1" 81 * @param url exchange_url 82 */ 83 static struct TALER_TESTING_Command 84 CMD_TRANSFER_TO_EXCHANGE (const char *label, 85 const char *amount) 86 { 87 return TALER_TESTING_cmd_admin_add_incoming (label, 88 amount, 89 &cred.ba, 90 cred.user42_payto); 91 } 92 93 94 /** 95 * Main function that will tell the interpreter what commands to 96 * run. 97 * 98 * @param cls closure 99 */ 100 static void 101 run (void *cls, 102 struct TALER_TESTING_Interpreter *is) 103 { 104 /** 105 * This batch aims to trigger the 409 Conflict 106 * response from a refresh-reveal operation. 107 */ 108 struct TALER_TESTING_Command refresh_409_conflict[] = { 109 CMD_TRANSFER_TO_EXCHANGE ( 110 "refresh-create-reserve", 111 "EUR:5.01"), 112 /** 113 * Make previous command effective. 114 */ 115 CMD_EXEC_WIREWATCH ("wirewatch"), 116 /** 117 * Withdraw EUR:5. 118 */ 119 TALER_TESTING_cmd_withdraw_amount ( 120 "refresh-withdraw-coin", 121 "refresh-create-reserve", 122 "EUR:5", 123 0, /* age restriction off */ 124 MHD_HTTP_OK), 125 TALER_TESTING_cmd_set_var ( 126 "account-priv", 127 TALER_TESTING_cmd_deposit ( 128 "refresh-deposit-partial-fail-kyc", 129 "refresh-withdraw-coin", 130 0, 131 cred.user42_payto, 132 "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", 133 GNUNET_TIME_UNIT_ZERO, 134 "EUR:1", 135 MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), 136 TALER_TESTING_cmd_admin_add_kycauth ( 137 "kyc-auth-transfer", 138 "EUR:0.01", 139 &cred.ba, 140 cred.user42_payto, 141 "refresh-deposit-partial-fail-kyc"), 142 CMD_EXEC_WIREWATCH ( 143 "import-kyc-account-withdraw"), 144 TALER_TESTING_cmd_deposit ( 145 "refresh-deposit-partial", 146 "refresh-withdraw-coin", 147 0, 148 cred.user42_payto, 149 "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", 150 GNUNET_TIME_UNIT_ZERO, 151 "EUR:1", 152 MHD_HTTP_OK), 153 /** 154 * Melt the rest of the coin's value 155 * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ 156 TALER_TESTING_cmd_melt ( 157 "refresh-melt", 158 "refresh-withdraw-coin", 159 MHD_HTTP_OK, 160 NULL), 161 #if FIXME_409_CONFLICT 162 /* Trigger 409 Conflict. */ 163 TALER_TESTING_cmd_flip_upload ( 164 "flip-upload", 165 config_file, 166 "transfer_privs.0"), 167 168 TALER_TESTING_cmd_melt_reveal ( 169 "refresh-(flipped-)reveal", 170 "refresh-melt", 171 MHD_HTTP_CONFLICT), 172 #endif 173 TALER_TESTING_cmd_end () 174 }; 175 #pragma message "conflict test must be adjusted to new melt/reveal API" 176 177 178 /** 179 * NOTE: not all CMDs actually need the twister, 180 * so it may be better to move those into the "main" 181 * lib test suite. 182 */ 183 struct TALER_TESTING_Command refund[] = { 184 CMD_TRANSFER_TO_EXCHANGE ( 185 "create-reserve-r1", 186 "EUR:5.01"), 187 CMD_EXEC_WIREWATCH ("wirewatch-r1"), 188 TALER_TESTING_cmd_withdraw_amount ( 189 "withdraw-coin-r1", 190 "create-reserve-r1", 191 "EUR:5", 192 0, /* age restriction off */ 193 MHD_HTTP_OK), 194 TALER_TESTING_cmd_deposit ( 195 "deposit-refund-1", 196 "withdraw-coin-r1", 197 0, 198 cred.user42_payto, 199 "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:5\"}]}", 200 GNUNET_TIME_UNIT_MINUTES, 201 "EUR:5", 202 MHD_HTTP_OK), 203 TALER_TESTING_cmd_refund ("refund-currency-mismatch", 204 MHD_HTTP_BAD_REQUEST, 205 "USD:5", 206 "deposit-refund-1"), 207 TALER_TESTING_cmd_flip_upload ("flip-upload", 208 config_file, 209 "merchant_sig"), 210 TALER_TESTING_cmd_refund ("refund-bad-sig", 211 MHD_HTTP_FORBIDDEN, 212 "EUR:5", 213 "deposit-refund-1"), 214 /* This next deposit CMD is only used to provide a 215 * good merchant signature to the next (failing) refund 216 * operations. */ 217 TALER_TESTING_cmd_deposit ( 218 "deposit-refund-to-fail", 219 "withdraw-coin-r1", 220 0, /* coin index. */ 221 cred.user42_payto, 222 /* This parameter will make any comparison about 223 h_contract_terms fail, when /refund will be handled. 224 So in other words, this is h_contract mismatch. */ 225 "{\"items\":[{\"name\":\"ice skate\",\"value\":\"EUR:5\"}]}", 226 GNUNET_TIME_UNIT_MINUTES, 227 "EUR:5", 228 MHD_HTTP_CONFLICT), 229 TALER_TESTING_cmd_refund ("refund-deposit-not-found", 230 MHD_HTTP_NOT_FOUND, 231 "EUR:5", 232 "deposit-refund-to-fail"), 233 TALER_TESTING_cmd_refund ("refund-insufficient-funds", 234 MHD_HTTP_CONFLICT, 235 "EUR:50", 236 "deposit-refund-1"), 237 TALER_TESTING_cmd_end () 238 }; 239 240 #if 0 241 /** 242 * Test that we don't get errors when the keys from the exchange 243 * are out of date. 244 */ 245 struct TALER_TESTING_Command expired_keys[] = { 246 TALER_TESTING_cmd_modify_header_dl ( 247 "modify-expiration", 248 config_file, 249 MHD_HTTP_HEADER_EXPIRES, 250 "Wed, 19 Jan 586524 08:01:49 GMT"), 251 TALER_TESTING_cmd_check_keys_pull_all_keys ( 252 "check-keys-expiration-0", 253 2), 254 /** 255 * Run some normal commands after this to make sure everything is fine. 256 */ 257 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-r2", 258 "EUR:55.01"), 259 CMD_EXEC_WIREWATCH ("wirewatch-r2"), 260 TALER_TESTING_cmd_withdraw_amount ( 261 "withdraw-coin-r2", 262 "create-reserve-r2", 263 "EUR:5", 264 0, /* age restriction off */ 265 MHD_HTTP_OK), 266 TALER_TESTING_cmd_end () 267 }; 268 #endif 269 270 struct TALER_TESTING_Command commands[] = { 271 TALER_TESTING_cmd_run_fakebank ("run-fakebank", 272 cred.cfg, 273 "exchange-account-2"), 274 TALER_TESTING_cmd_system_start ("start-taler", 275 config_file, 276 "-e", 277 NULL), 278 TALER_TESTING_cmd_get_exchange ("get-exchange", 279 cred.cfg, 280 NULL, 281 true, 282 true), 283 TALER_TESTING_cmd_batch ( 284 "refresh-reveal-409-conflict", 285 refresh_409_conflict), 286 TALER_TESTING_cmd_batch ( 287 "refund", 288 refund), 289 #if 0 290 TALER_TESTING_cmd_batch ("expired-keys", 291 expired_keys), 292 #endif 293 TALER_TESTING_cmd_end () 294 }; 295 296 (void) cls; 297 TALER_TESTING_run (is, 298 commands); 299 } 300 301 302 /** 303 * Kill, wait, and destroy convenience function. 304 * 305 * @param[in] process process to purge. 306 */ 307 static void 308 purge_process (struct GNUNET_Process *process) 309 { 310 GNUNET_break (GNUNET_OK == 311 GNUNET_process_kill (process, 312 SIGINT)); 313 GNUNET_break (GNUNET_OK == 314 GNUNET_process_wait (process, 315 true, 316 NULL, 317 NULL)); 318 GNUNET_process_destroy (process); 319 } 320 321 322 int 323 main (int argc, 324 char *const *argv) 325 { 326 int ret; 327 328 (void) argc; 329 { 330 char *cipher; 331 332 cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); 333 GNUNET_assert (NULL != cipher); 334 GNUNET_asprintf (&config_file, 335 "test_exchange_api_twisted-%s.conf", 336 cipher); 337 GNUNET_free (cipher); 338 } 339 /* FIXME: introduce commands for twister! */ 340 twister_url = TALER_TWISTER_prepare_twister (config_file); 341 if (NULL == twister_url) 342 return 77; 343 twisterd = TALER_TWISTER_run_twister (config_file); 344 if (NULL == twisterd) 345 return 77; 346 ret = TALER_TESTING_main (argv, 347 "INFO", 348 config_file, 349 "exchange-account-2", 350 TALER_TESTING_BS_FAKEBANK, 351 &cred, 352 &run, 353 NULL); 354 purge_process (twisterd); 355 GNUNET_free (twister_url); 356 return ret; 357 } 358 359 360 /* end of test_exchange_api_twisted.c */