test_exchange_api.c (44849B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014--2022 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.c 21 * @brief testcase to test exchange's HTTP API interface 22 * @author Sree Harsha Totakura <sreeharsha@totakura.in> 23 * @author Christian Grothoff 24 * @author Marcello Stanisci 25 */ 26 #include "taler/taler_util.h" 27 #include "taler/taler_signatures.h" 28 #include "taler/taler_json_lib.h" 29 #include <gnunet/gnunet_util_lib.h> 30 #include <gnunet/gnunet_testing_lib.h> 31 #include <microhttpd.h> 32 #include "taler/taler_bank_service.h" 33 #include "taler/taler_testing_lib.h" 34 #include "taler/taler_extensions.h" 35 36 /** 37 * Configuration file we use. One (big) configuration is used 38 * for the various components for this test. 39 */ 40 static char *config_file; 41 42 /** 43 * Special configuration file to use when we want reserves 44 * to expire 'immediately'. 45 */ 46 static char *config_file_expire_reserve_now; 47 48 /** 49 * Our credentials. 50 */ 51 static struct TALER_TESTING_Credentials cred; 52 53 /** 54 * Some tests behave differently when using CS as we cannot 55 * reuse the coin private key for different denominations 56 * due to the derivation of it with the /csr values. Hence 57 * some tests behave differently in CS mode, hence this 58 * flag. 59 */ 60 static bool uses_cs; 61 62 /** 63 * Execute the taler-exchange-wirewatch command with 64 * our configuration file. 65 * 66 * @param label label to use for the command. 67 */ 68 #define CMD_EXEC_WIREWATCH(label) \ 69 TALER_TESTING_cmd_exec_wirewatch2 (label, config_file, \ 70 "exchange-account-2") 71 72 /** 73 * Execute the taler-exchange-aggregator, closer and transfer commands with 74 * our configuration file. 75 * 76 * @param label label to use for the command. 77 */ 78 #define CMD_EXEC_AGGREGATOR(label) \ 79 TALER_TESTING_cmd_sleep ("sleep-before-aggregator", 2), \ 80 TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \ 81 TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file) 82 83 84 /** 85 * Run wire transfer of funds from some user's account to the 86 * exchange. 87 * 88 * @param label label to use for the command. 89 * @param amount amount to transfer, i.e. "EUR:1" 90 */ 91 #define CMD_TRANSFER_TO_EXCHANGE(label,amount) \ 92 TALER_TESTING_cmd_admin_add_incoming (label, amount, \ 93 &cred.ba, \ 94 cred.user42_payto) 95 96 /** 97 * Main function that will tell the interpreter what commands to 98 * run. 99 * 100 * @param cls closure 101 * @param is interpreter we use to run commands 102 */ 103 static void 104 run (void *cls, 105 struct TALER_TESTING_Interpreter *is) 106 { 107 /** 108 * Test withdrawal plus spending. 109 */ 110 struct TALER_TESTING_Command withdraw[] = { 111 /** 112 * Move money to the exchange's bank account. 113 */ 114 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1", 115 "EUR:6.02"), 116 TALER_TESTING_cmd_reserve_poll ("poll-reserve-1", 117 "create-reserve-1", 118 "EUR:6.02", 119 GNUNET_TIME_UNIT_MINUTES, 120 MHD_HTTP_OK), 121 TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1", 122 "EUR:6.02", 123 cred.user42_payto, 124 cred.exchange_payto, 125 "create-reserve-1"), 126 /** 127 * Make a reserve exist, according to the previous 128 * transfer. 129 */ 130 CMD_EXEC_WIREWATCH ("wirewatch-1"), 131 TALER_TESTING_cmd_reserve_poll_finish ("finish-poll-reserve-1", 132 GNUNET_TIME_relative_multiply ( 133 GNUNET_TIME_UNIT_SECONDS, 134 2), 135 "poll-reserve-1"), 136 /** 137 * Withdraw EUR:5. 138 */ 139 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1", 140 "create-reserve-1", 141 "EUR:5", 142 0, /* age restriction off */ 143 MHD_HTTP_OK), 144 /** 145 * Idempotent withdrawal. Note that in the case of CS, this is _not_ 146 * idempotent because the blinding nonces still differ, so instead, 147 * it is an overcharging of the reserve. 148 */ 149 TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1-idem", 150 "create-reserve-1", 151 "EUR:5", 152 0, /* age restriction off */ 153 "withdraw-coin-1", 154 (uses_cs) 155 ? MHD_HTTP_CONFLICT 156 : MHD_HTTP_OK), 157 /** 158 * Withdraw EUR:1 using the SAME private coin key as for the previous coin 159 * (in violation of the specification, to be detected on spending!). 160 * However, note that this does NOT work with 'CS', as for a different 161 * denomination we get different R0/R1 values from the exchange, and 162 * thus will generate a different coin private key as R0/R1 are hashed 163 * into the coin priv. So here, we fail to 'reuse' the key due to the 164 * cryptographic construction! 165 */ 166 TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x", 167 "create-reserve-1", 168 "EUR:1", 169 0, /* age restriction off */ 170 "withdraw-coin-1", 171 MHD_HTTP_OK), 172 /** 173 * Check the reserve is depleted. 174 */ 175 TALER_TESTING_cmd_status ("status-1", 176 "create-reserve-1", 177 "EUR:0", 178 MHD_HTTP_OK), 179 /* 180 * Try to overdraw. 181 */ 182 TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2", 183 "create-reserve-1", 184 "EUR:5", 185 0, /* age restriction off */ 186 MHD_HTTP_CONFLICT), 187 TALER_TESTING_cmd_end () 188 }; 189 190 struct TALER_TESTING_Command spend[] = { 191 /** 192 * Spend the coin. 193 */ 194 TALER_TESTING_cmd_set_var ( 195 "account-priv", 196 TALER_TESTING_cmd_deposit ( 197 "deposit-simple-fail-kyc", 198 "withdraw-coin-1", 199 0, 200 cred.user42_payto, 201 "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", 202 GNUNET_TIME_UNIT_ZERO, 203 "EUR:5", 204 MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)), 205 TALER_TESTING_cmd_admin_add_kycauth ( 206 "kyc-auth-transfer", 207 "EUR:0.01", 208 &cred.ba, 209 cred.user42_payto, 210 "deposit-simple-fail-kyc"), 211 CMD_EXEC_WIREWATCH ( 212 "import-kyc-account-withdraw"), 213 TALER_TESTING_cmd_deposit_replay ( 214 "deposit-simple", 215 "deposit-simple-fail-kyc", 216 MHD_HTTP_OK), 217 TALER_TESTING_cmd_deposit_replay ( 218 "deposit-simple-replay-1", 219 "deposit-simple", 220 MHD_HTTP_OK), 221 TALER_TESTING_cmd_sleep ( 222 "sleep-before-deposit-replay", 223 1), 224 TALER_TESTING_cmd_deposit_replay ( 225 "deposit-simple-replay-2", 226 "deposit-simple", 227 MHD_HTTP_OK), 228 /* This creates a conflict, as we have the same coin public key (reuse!), 229 but different denomination public keys (which is not allowed). 230 However, note that this does NOT work with 'CS', as for a different 231 denomination we get different R0/R1 values from the exchange, and 232 thus will generate a different coin private key as R0/R1 are hashed 233 into the coin priv. So here, we fail to 'reuse' the key due to the 234 cryptographic construction! */ 235 TALER_TESTING_cmd_deposit ( 236 "deposit-reused-coin-key-failure", 237 "withdraw-coin-1x", 238 0, 239 cred.user42_payto, 240 "{\"items\":[{\"name\":\"conflicting ice cream\",\"value\":1}]}", 241 GNUNET_TIME_UNIT_ZERO, 242 "EUR:1", 243 uses_cs 244 ? MHD_HTTP_OK 245 : MHD_HTTP_CONFLICT), 246 /** 247 * Try to double spend using different wire details. 248 */ 249 TALER_TESTING_cmd_admin_add_kycauth ( 250 "kyc-auth-transfer-2", 251 "EUR:0.01", 252 &cred.ba, 253 cred.user43_payto, 254 "deposit-simple-fail-kyc"), 255 CMD_EXEC_WIREWATCH ( 256 "import-kyc-account-1"), 257 TALER_TESTING_cmd_deposit ( 258 "deposit-double-1", 259 "withdraw-coin-1", 260 0, 261 cred.user43_payto, 262 "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", 263 GNUNET_TIME_UNIT_ZERO, 264 "EUR:5", 265 MHD_HTTP_CONFLICT), 266 /* Try to double spend using a different transaction id. 267 * The test needs the contract terms to differ. This 268 * is currently the case because of the "timestamp" field, 269 * which is set automatically by #TALER_TESTING_cmd_deposit(). 270 * This could theoretically fail if at some point a deposit 271 * command executes in less than 1 ms. */ 272 TALER_TESTING_cmd_deposit ( 273 "deposit-double-1", 274 "withdraw-coin-1", 275 0, 276 cred.user43_payto, 277 "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", 278 GNUNET_TIME_UNIT_ZERO, 279 "EUR:5", 280 MHD_HTTP_CONFLICT), 281 /** 282 * Try to double spend with different proposal. 283 */ 284 TALER_TESTING_cmd_deposit ( 285 "deposit-double-2", 286 "withdraw-coin-1", 287 0, 288 cred.user43_payto, 289 "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}", 290 GNUNET_TIME_UNIT_ZERO, 291 "EUR:5", 292 MHD_HTTP_CONFLICT), 293 TALER_TESTING_cmd_end () 294 }; 295 296 struct TALER_TESTING_Command refresh[] = { 297 /** 298 * Try to melt the coin that shared the private key with another 299 * coin (should fail). Note that in the CS-case, we fail also 300 * with MHD_HTTP_CONFLICT, but for a different reason: here it 301 * is not a denomination conflict, but a double-spending conflict. 302 */ 303 TALER_TESTING_cmd_melt ( 304 "refresh-melt-reused-coin-key-failure", 305 "withdraw-coin-1x", 306 MHD_HTTP_CONFLICT, 307 NULL), 308 309 /* Fill reserve with EUR:5, 1ct is for fees. */ 310 CMD_TRANSFER_TO_EXCHANGE ( 311 "refresh-create-reserve-1", 312 "EUR:5.01"), 313 TALER_TESTING_cmd_check_bank_admin_transfer ( 314 "ck-refresh-create-reserve-1", 315 "EUR:5.01", 316 cred.user42_payto, 317 cred.exchange_payto, 318 "refresh-create-reserve-1"), 319 /** 320 * Make previous command effective. 321 */ 322 CMD_EXEC_WIREWATCH ("wirewatch-2"), 323 /** 324 * Withdraw EUR:5. 325 */ 326 TALER_TESTING_cmd_withdraw_amount ( 327 "refresh-withdraw-coin-1", 328 "refresh-create-reserve-1", 329 "EUR:5", 330 0, /* age restriction off */ 331 MHD_HTTP_OK), 332 /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin 333 * (in full) (merchant would receive EUR:0.99 due to 1 ct 334 * deposit fee) 335 */ 336 TALER_TESTING_cmd_deposit ( 337 "refresh-deposit-partial", 338 "refresh-withdraw-coin-1", 339 0, 340 cred.user42_payto, 341 "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}", 342 GNUNET_TIME_UNIT_ZERO, 343 "EUR:1", 344 MHD_HTTP_OK), 345 /** 346 * Melt the rest of the coin's value 347 * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ 348 TALER_TESTING_cmd_melt_double ( 349 "refresh-melt-1", 350 "refresh-withdraw-coin-1", 351 MHD_HTTP_OK, 352 NULL), 353 /** 354 * Complete (successful) melt operation, and 355 * withdraw the coins 356 */ 357 TALER_TESTING_cmd_melt_reveal ( 358 "refresh-reveal-1", 359 "refresh-melt-1", 360 MHD_HTTP_OK), 361 /** 362 * Do it again to check idempotency 363 */ 364 TALER_TESTING_cmd_melt_reveal ( 365 "refresh-reveal-1-idempotency", 366 "refresh-melt-1", 367 MHD_HTTP_OK), 368 /** 369 * Try to spend a refreshed EUR:1 coin 370 */ 371 TALER_TESTING_cmd_deposit ( 372 "refresh-deposit-refreshed-1a", 373 "refresh-reveal-1-idempotency", 374 0, 375 cred.user42_payto, 376 "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}", 377 GNUNET_TIME_UNIT_ZERO, 378 "EUR:1", 379 MHD_HTTP_OK), 380 /** 381 * Try to spend a refreshed EUR:0.1 coin 382 */ 383 TALER_TESTING_cmd_deposit ( 384 "refresh-deposit-refreshed-1b", 385 "refresh-reveal-1", 386 3, 387 cred.user43_payto, 388 "{\"items\":[{\"name\":\"cheap ice cream\",\"value\":3}]}", 389 GNUNET_TIME_UNIT_ZERO, 390 "EUR:0.1", 391 MHD_HTTP_OK), 392 /* Test running a failing melt operation (same operation 393 * again must fail) */ 394 TALER_TESTING_cmd_melt ( 395 "refresh-melt-failing", 396 "refresh-withdraw-coin-1", 397 MHD_HTTP_CONFLICT, 398 NULL), 399 /* Test running a failing melt operation (on a coin that 400 was itself revealed and subsequently deposited) */ 401 TALER_TESTING_cmd_melt ( 402 "refresh-melt-failing-2", 403 "refresh-reveal-1", 404 MHD_HTTP_CONFLICT, 405 NULL), 406 407 TALER_TESTING_cmd_end () 408 }; 409 410 /** 411 * Test withdrawal with age restriction. Success is expected, so it MUST be 412 * called _after_ TALER_TESTING_cmd_exec_offline_sign_extensions is called, 413 * i. e. age restriction is activated in the exchange! 414 * 415 * FIXME[oec]: create a test that tries to withdraw coins with age restriction but 416 * (expectedly) fails because the exchange doesn't support age restriction 417 * yet. 418 */ 419 struct TALER_TESTING_Command withdraw_age[] = { 420 /** 421 * Move money to the exchange's bank account. 422 */ 423 CMD_TRANSFER_TO_EXCHANGE ( 424 "create-reserve-age", 425 "EUR:6.01"), 426 TALER_TESTING_cmd_check_bank_admin_transfer ( 427 "check-create-reserve-age", 428 "EUR:6.01", 429 cred.user42_payto, 430 cred.exchange_payto, 431 "create-reserve-age"), 432 /** 433 * Make a reserve exist, according to the previous 434 * transfer. 435 */ 436 CMD_EXEC_WIREWATCH ("wirewatch-age"), 437 /** 438 * Withdraw EUR:5. 439 */ 440 TALER_TESTING_cmd_withdraw_amount ( 441 "withdraw-coin-age-1", 442 "create-reserve-age", 443 "EUR:5", 444 13, 445 MHD_HTTP_OK), 446 447 TALER_TESTING_cmd_end () 448 }; 449 450 struct TALER_TESTING_Command spend_age[] = { 451 /** 452 * Spend the coin. 453 */ 454 TALER_TESTING_cmd_deposit ( 455 "deposit-simple-age", 456 "withdraw-coin-age-1", 457 0, 458 cred.user42_payto, 459 "{\"items\":[{\"name\":\"unique ice cream\",\"value\":1}]}", 460 GNUNET_TIME_UNIT_ZERO, 461 "EUR:4.99", 462 MHD_HTTP_OK), 463 TALER_TESTING_cmd_deposit_replay ( 464 "deposit-simple-replay-age", 465 "deposit-simple-age", 466 MHD_HTTP_OK), 467 TALER_TESTING_cmd_deposit_replay ( 468 "deposit-simple-replay-age-1", 469 "deposit-simple-age", 470 MHD_HTTP_OK), 471 TALER_TESTING_cmd_sleep ( 472 "sleep-before-age-deposit-replay", 473 1), 474 TALER_TESTING_cmd_deposit_replay ( 475 "deposit-simple-replay-age-2", 476 "deposit-simple-age", 477 MHD_HTTP_OK), 478 TALER_TESTING_cmd_end () 479 }; 480 481 struct TALER_TESTING_Command track[] = { 482 /* Try resolving a deposit's WTID, as we never triggered 483 * execution of transactions, the answer should be that 484 * the exchange knows about the deposit, but has no WTID yet. 485 */ 486 TALER_TESTING_cmd_deposits_get ( 487 "deposit-wtid-found", 488 "deposit-simple", 489 0, 490 MHD_HTTP_ACCEPTED, 491 NULL), 492 /* Try resolving a deposit's WTID for a failed deposit. 493 * As the deposit failed, the answer should be that the 494 * exchange does NOT know about the deposit. 495 */ 496 TALER_TESTING_cmd_deposits_get ( 497 "deposit-wtid-failing", 498 "deposit-double-2", 499 0, 500 MHD_HTTP_NOT_FOUND, 501 NULL), 502 /* Try resolving an undefined (all zeros) WTID; this 503 * should fail as obviously the exchange didn't use that 504 * WTID value for any transaction. 505 */ 506 TALER_TESTING_cmd_track_transfer_empty ( 507 "wire-deposit-failing", 508 NULL, 509 MHD_HTTP_NOT_FOUND), 510 /* Run transfers. */ 511 CMD_EXEC_AGGREGATOR ("run-aggregator"), 512 /** 513 * Check all the transfers took place. 514 */ 515 TALER_TESTING_cmd_check_bank_transfer ( 516 "check_bank_transfer-42-aggregate", 517 cred.exchange_url, 518 /* In case of CS, one transaction above succeeded that 519 failed for RSA, hence we get a larger amount here */ 520 uses_cs ? "EUR:14.91" : "EUR:13.92", 521 cred.exchange_payto, 522 cred.user42_payto), 523 TALER_TESTING_cmd_check_bank_transfer ( 524 "check_bank_transfer-43-aggregate", 525 cred.exchange_url, 526 "EUR:0.17", 527 cred.exchange_payto, 528 cred.user43_payto), 529 TALER_TESTING_cmd_check_bank_empty ("check_bank_empty"), 530 TALER_TESTING_cmd_deposits_get ( 531 "deposit-wtid-ok", 532 "deposit-simple", 533 0, 534 MHD_HTTP_OK, 535 "check_bank_transfer-42-aggregate"), 536 TALER_TESTING_cmd_track_transfer ( 537 "wire-deposit-success-bank", 538 "check_bank_transfer-42-aggregate", 539 MHD_HTTP_OK, 540 uses_cs ? "EUR:14.91" : "EUR:13.92", 541 "EUR:0.01"), 542 TALER_TESTING_cmd_track_transfer ( 543 "wire-deposits-success-wtid", 544 "check_bank_transfer-43-aggregate", 545 MHD_HTTP_OK, 546 "EUR:0.17", 547 "EUR:0.01"), 548 TALER_TESTING_cmd_end () 549 }; 550 551 /** 552 * This block checks whether a wire deadline 553 * very far in the future does NOT get aggregated now. 554 */ 555 struct TALER_TESTING_Command unaggregation[] = { 556 TALER_TESTING_cmd_check_bank_empty ("far-future-aggregation-a"), 557 CMD_TRANSFER_TO_EXCHANGE ( 558 "create-reserve-unaggregated", 559 "EUR:5.01"), 560 /* "consume" reserve creation transfer. */ 561 TALER_TESTING_cmd_check_bank_admin_transfer ( 562 "check-create-reserve-unaggregated", 563 "EUR:5.01", 564 cred.user42_payto, 565 cred.exchange_payto, 566 "create-reserve-unaggregated"), 567 CMD_EXEC_WIREWATCH ("wirewatch-unaggregated"), 568 TALER_TESTING_cmd_withdraw_amount ( 569 "withdraw-coin-unaggregated", 570 "create-reserve-unaggregated", 571 "EUR:5", 572 0, /* age restriction off */ 573 MHD_HTTP_OK), 574 TALER_TESTING_cmd_deposit ( 575 "deposit-unaggregated", 576 "withdraw-coin-unaggregated", 577 0, 578 cred.user43_payto, 579 "{\"items\":[{\"name\":\"different ice cream\",\"value\":1}]}", 580 GNUNET_TIME_relative_multiply ( 581 GNUNET_TIME_UNIT_YEARS, 582 3000), 583 "EUR:5", 584 MHD_HTTP_OK), 585 CMD_EXEC_AGGREGATOR ("aggregation-attempt"), 586 587 TALER_TESTING_cmd_check_bank_empty ( 588 "far-future-aggregation-b"), 589 590 TALER_TESTING_cmd_end () 591 }; 592 593 struct TALER_TESTING_Command refresh_age[] = { 594 /* Fill reserve with EUR:5, 1ct is for fees. */ 595 CMD_TRANSFER_TO_EXCHANGE ( 596 "refresh-create-reserve-age-1", 597 "EUR:6.01"), 598 TALER_TESTING_cmd_check_bank_admin_transfer ( 599 "ck-refresh-create-reserve-age-1", 600 "EUR:6.01", 601 cred.user42_payto, 602 cred.exchange_payto, 603 "refresh-create-reserve-age-1"), 604 /** 605 * Make previous command effective. 606 */ 607 CMD_EXEC_WIREWATCH ("wirewatch-age-2"), 608 /** 609 * Withdraw EUR:7 with age restriction for age 13. 610 */ 611 TALER_TESTING_cmd_withdraw_amount ( 612 "refresh-withdraw-coin-age-1", 613 "refresh-create-reserve-age-1", 614 "EUR:5", 615 13, 616 MHD_HTTP_OK), 617 /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin 618 * (in full) (merchant would receive EUR:0.99 due to 1 ct 619 * deposit fee) 620 */ 621 TALER_TESTING_cmd_deposit ( 622 "refresh-deposit-partial-age", 623 "refresh-withdraw-coin-age-1", 624 0, 625 cred.user42_payto, 626 "{\"items\":[{\"name\":\"special ice cream\",\"value\":\"EUR:1\"}]}", 627 GNUNET_TIME_UNIT_ZERO, 628 "EUR:1", 629 MHD_HTTP_OK), 630 /** 631 * Melt the rest of the coin's value 632 * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */ 633 TALER_TESTING_cmd_melt_double ( 634 "refresh-melt-age-1", 635 "refresh-withdraw-coin-age-1", 636 MHD_HTTP_OK, 637 NULL), 638 /** 639 * Complete (successful) melt operation, and 640 * withdraw the coins 641 */ 642 TALER_TESTING_cmd_melt_reveal ( 643 "refresh-reveal-age-1", 644 "refresh-melt-age-1", 645 MHD_HTTP_OK), 646 /** 647 * Do it again to check idempotency 648 */ 649 TALER_TESTING_cmd_melt_reveal ( 650 "refresh-reveal-age-1-idempotency", 651 "refresh-melt-age-1", 652 MHD_HTTP_OK), 653 /** 654 * Try to spend a refreshed EUR:1 coin 655 */ 656 TALER_TESTING_cmd_deposit ( 657 "refresh-deposit-refreshed-age-1a", 658 "refresh-reveal-age-1-idempotency", 659 0, 660 cred.user42_payto, 661 "{\"items\":[{\"name\":\"garlic ice cream\",\"value\":3}]}", 662 GNUNET_TIME_UNIT_ZERO, 663 "EUR:1", 664 MHD_HTTP_OK), 665 /** 666 * Try to spend a refreshed EUR:0.1 coin 667 */ 668 TALER_TESTING_cmd_deposit ( 669 "refresh-deposit-refreshed-age-1b", 670 "refresh-reveal-age-1", 671 3, 672 cred.user43_payto, 673 "{\"items\":[{\"name\":\"spicy ice cream\",\"value\":3}]}", 674 GNUNET_TIME_UNIT_ZERO, 675 "EUR:0.1", 676 MHD_HTTP_OK), 677 /* Test running a failing melt operation (same operation 678 * again must fail) */ 679 TALER_TESTING_cmd_melt ( 680 "refresh-melt-failing-age", 681 "refresh-withdraw-coin-age-1", 682 MHD_HTTP_CONFLICT, 683 NULL), 684 /* Test running a failing melt operation (on a coin that 685 was itself revealed and subsequently deposited) */ 686 TALER_TESTING_cmd_melt ( 687 "refresh-melt-failing-age-2", 688 "refresh-reveal-age-1", 689 MHD_HTTP_CONFLICT, 690 NULL), 691 TALER_TESTING_cmd_end () 692 }; 693 694 /** 695 * This block exercises the aggretation logic by making two payments 696 * to the same merchant. 697 */ 698 struct TALER_TESTING_Command aggregation[] = { 699 CMD_TRANSFER_TO_EXCHANGE ("create-reserve-aggtest", 700 "EUR:5.01"), 701 /* "consume" reserve creation transfer. */ 702 TALER_TESTING_cmd_check_bank_admin_transfer ( 703 "check-create-reserve-aggtest", 704 "EUR:5.01", 705 cred.user42_payto, 706 cred.exchange_payto, 707 "create-reserve-aggtest"), 708 CMD_EXEC_WIREWATCH ("wirewatch-aggtest"), 709 TALER_TESTING_cmd_withdraw_amount ( 710 "withdraw-coin-aggtest", 711 "create-reserve-aggtest", 712 "EUR:5", 713 0, /* age restriction off */ 714 MHD_HTTP_OK), 715 TALER_TESTING_cmd_deposit ( 716 "deposit-aggtest-1", 717 "withdraw-coin-aggtest", 718 0, 719 cred.user43_payto, 720 "{\"items\":[{\"name\":\"cinamon ice cream\",\"value\":1}]}", 721 GNUNET_TIME_UNIT_ZERO, 722 "EUR:2", 723 MHD_HTTP_OK), 724 TALER_TESTING_cmd_deposit_with_ref ( 725 "deposit-aggtest-2", 726 "withdraw-coin-aggtest", 727 0, 728 cred.user43_payto, 729 "{\"items\":[{\"name\":\"foo bar\",\"value\":1}]}", 730 GNUNET_TIME_UNIT_ZERO, 731 "EUR:2", 732 MHD_HTTP_OK, 733 "deposit-aggtest-1"), 734 CMD_EXEC_AGGREGATOR ("aggregation-aggtest"), 735 TALER_TESTING_cmd_check_bank_transfer ( 736 "check-bank-transfer-aggtest", 737 cred.exchange_url, 738 "EUR:3.97", 739 cred.exchange_payto, 740 cred.user43_payto), 741 TALER_TESTING_cmd_check_bank_empty ("check-bank-empty-aggtest"), 742 TALER_TESTING_cmd_end () 743 }; 744 745 struct TALER_TESTING_Command refund[] = { 746 /** 747 * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per 748 * config. 749 */ 750 CMD_TRANSFER_TO_EXCHANGE ( 751 "create-reserve-r1", 752 "EUR:5.01"), 753 TALER_TESTING_cmd_check_bank_admin_transfer ( 754 "check-create-reserve-r1", 755 "EUR:5.01", 756 cred.user42_payto, 757 cred.exchange_payto, 758 "create-reserve-r1"), 759 /** 760 * Run wire-watch to trigger the reserve creation. 761 */ 762 CMD_EXEC_WIREWATCH ("wirewatch-3"), 763 /* Withdraw a 5 EUR coin, at fee of 1 ct */ 764 TALER_TESTING_cmd_withdraw_amount ( 765 "withdraw-coin-r1", 766 "create-reserve-r1", 767 "EUR:5", 768 0, /* age restriction off */ 769 MHD_HTTP_OK), 770 /** 771 * Spend 5 EUR of the 5 EUR coin (in full) (merchant would 772 * receive EUR:4.99 due to 1 ct deposit fee) 773 */ 774 TALER_TESTING_cmd_deposit ( 775 "deposit-refund-1", 776 "withdraw-coin-r1", 777 0, 778 cred.user42_payto, 779 "{\"items\":[{\"name\":\"blue ice cream\",\"value\":\"EUR:5\"}]}", 780 GNUNET_TIME_UNIT_MINUTES, 781 "EUR:5", 782 MHD_HTTP_OK), 783 /** 784 * Run transfers. Should do nothing as refund deadline blocks it 785 */ 786 CMD_EXEC_AGGREGATOR ("run-aggregator-refund"), 787 /* Check that aggregator didn't do anything, as expected. 788 * Note, this operation takes two commands: one to "flush" 789 * the preliminary transfer (used to withdraw) from the 790 * fakebank and the second to actually check there are not 791 * other transfers around. */ 792 TALER_TESTING_cmd_check_bank_empty ("check_bank_transfer-pre-refund"), 793 TALER_TESTING_cmd_refund_with_id ( 794 "refund-ok", 795 MHD_HTTP_OK, 796 "EUR:3", 797 "deposit-refund-1", 798 3), 799 TALER_TESTING_cmd_refund_with_id ( 800 "refund-ok-double", 801 MHD_HTTP_OK, 802 "EUR:3", 803 "deposit-refund-1", 804 3), 805 /* Previous /refund(s) had id == 0. */ 806 TALER_TESTING_cmd_refund_with_id ( 807 "refund-conflicting", 808 MHD_HTTP_CONFLICT, 809 "EUR:5", 810 "deposit-refund-1", 811 1), 812 TALER_TESTING_cmd_deposit ( 813 "deposit-refund-insufficient-refund", 814 "withdraw-coin-r1", 815 0, 816 cred.user42_payto, 817 "{\"items\":[{\"name\":\"fruit ice cream\",\"value\":\"EUR:4\"}]}", 818 GNUNET_TIME_UNIT_MINUTES, 819 "EUR:4", 820 MHD_HTTP_CONFLICT), 821 TALER_TESTING_cmd_refund_with_id ( 822 "refund-ok-increase", 823 MHD_HTTP_OK, 824 "EUR:2", 825 "deposit-refund-1", 826 2), 827 /** 828 * Spend 4.99 EUR of the refunded 4.99 EUR coin (1ct gone 829 * due to refund) (merchant would receive EUR:4.98 due to 830 * 1 ct deposit fee) */ 831 TALER_TESTING_cmd_deposit ( 832 "deposit-refund-2", 833 "withdraw-coin-r1", 834 0, 835 cred.user42_payto, 836 "{\"items\":[{\"name\":\"more ice cream\",\"value\":\"EUR:5\"}]}", 837 GNUNET_TIME_UNIT_ZERO, 838 "EUR:4.99", 839 MHD_HTTP_OK), 840 /** 841 * Run transfers. This will do the transfer as refund deadline 842 * was 0 843 */ 844 CMD_EXEC_AGGREGATOR ("run-aggregator-3"), 845 /** 846 * Check that deposit did run. 847 */ 848 TALER_TESTING_cmd_check_bank_transfer ( 849 "check_bank_transfer-pre-refund", 850 cred.exchange_url, 851 "EUR:4.97", 852 cred.exchange_payto, 853 cred.user42_payto), 854 /** 855 * Run failing refund, as past deadline & aggregation. 856 */ 857 TALER_TESTING_cmd_refund ( 858 "refund-fail", 859 MHD_HTTP_GONE, 860 "EUR:4.99", 861 "deposit-refund-2"), 862 TALER_TESTING_cmd_check_bank_empty ("check-empty-after-refund"), 863 /** 864 * Test refunded coins are never executed, even past 865 * refund deadline 866 */ 867 CMD_TRANSFER_TO_EXCHANGE ( 868 "create-reserve-rb", 869 "EUR:5.01"), 870 TALER_TESTING_cmd_check_bank_admin_transfer ( 871 "check-create-reserve-rb", 872 "EUR:5.01", 873 cred.user42_payto, 874 cred.exchange_payto, 875 "create-reserve-rb"), 876 CMD_EXEC_WIREWATCH ("wirewatch-rb"), 877 TALER_TESTING_cmd_withdraw_amount ( 878 "withdraw-coin-rb", 879 "create-reserve-rb", 880 "EUR:5", 881 0, /* age restriction off */ 882 MHD_HTTP_OK), 883 TALER_TESTING_cmd_deposit ( 884 "deposit-refund-1b", 885 "withdraw-coin-rb", 886 0, 887 cred.user42_payto, 888 "{\"items\":[{\"name\":\"purple ice cream\",\"value\":\"EUR:5\"}]}", 889 GNUNET_TIME_UNIT_ZERO, 890 "EUR:5", 891 MHD_HTTP_OK), 892 /** 893 * Trigger refund (before aggregator had a chance to execute 894 * deposit, even though refund deadline was zero). 895 */ 896 TALER_TESTING_cmd_refund ( 897 "refund-ok-fast", 898 MHD_HTTP_OK, 899 "EUR:5", 900 "deposit-refund-1b"), 901 /** 902 * Run transfers. This will do the transfer as refund deadline 903 * was 0, except of course because the refund succeeded, the 904 * transfer should no longer be done. 905 */ 906 CMD_EXEC_AGGREGATOR ("run-aggregator-3b"), 907 /* check that aggregator didn't do anything, as expected */ 908 TALER_TESTING_cmd_check_bank_empty ("check-refund-fast-not-run"), 909 TALER_TESTING_cmd_end () 910 }; 911 912 #if FIXME_9828 913 struct TALER_TESTING_Command recoup[] = { 914 /** 915 * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per 916 * config. 917 */ 918 CMD_TRANSFER_TO_EXCHANGE ( 919 "recoup-create-reserve-1", 920 "EUR:15.02"), 921 TALER_TESTING_cmd_check_bank_admin_transfer ( 922 "recoup-create-reserve-1-check", 923 "EUR:15.02", 924 cred.user42_payto, 925 cred.exchange_payto, 926 "recoup-create-reserve-1"), 927 /** 928 * Run wire-watch to trigger the reserve creation. 929 */ 930 CMD_EXEC_WIREWATCH ("wirewatch-4"), 931 /* Withdraw a 5 EUR coin, at fee of 1 ct */ 932 TALER_TESTING_cmd_withdraw_amount ( 933 "recoup-withdraw-coin-1", 934 "recoup-create-reserve-1", 935 "EUR:5", 936 0, /* age restriction off */ 937 MHD_HTTP_OK), 938 /* Withdraw a 10 EUR coin, at fee of 1 ct */ 939 TALER_TESTING_cmd_withdraw_amount ( 940 "recoup-withdraw-coin-1b", 941 "recoup-create-reserve-1", 942 "EUR:10", 943 0, /* age restriction off */ 944 MHD_HTTP_OK), 945 /* melt 10 EUR coin to get 5 EUR refreshed coin */ 946 TALER_TESTING_cmd_melt ( 947 "recoup-melt-coin-1b", 948 "recoup-withdraw-coin-1b", 949 MHD_HTTP_OK, 950 "EUR:5", 951 NULL), 952 TALER_TESTING_cmd_melt_reveal ( 953 "recoup-reveal-coin-1b", 954 "recoup-melt-coin-1b", 955 MHD_HTTP_OK), 956 /* Revoke both 5 EUR coins */ 957 TALER_TESTING_cmd_revoke ( 958 "revoke-0-EUR:5", 959 MHD_HTTP_OK, 960 "recoup-withdraw-coin-1", 961 config_file), 962 /* Recoup coin to reserve */ 963 TALER_TESTING_cmd_recoup ( 964 "recoup-1", 965 MHD_HTTP_OK, 966 "recoup-withdraw-coin-1", 967 "EUR:5"), 968 /* Check the money is back with the reserve */ 969 TALER_TESTING_cmd_status ( 970 "recoup-reserve-status-1", 971 "recoup-create-reserve-1", 972 "EUR:5.0", 973 MHD_HTTP_OK), 974 /* Recoup-refresh coin to 10 EUR coin */ 975 TALER_TESTING_cmd_recoup_refresh ( 976 "recoup-1b", 977 MHD_HTTP_OK, 978 "recoup-reveal-coin-1b", 979 "recoup-melt-coin-1b", 980 "EUR:5"), 981 /* melt 10 EUR coin *again* to get 1 EUR refreshed coin */ 982 TALER_TESTING_cmd_melt ( 983 "recoup-remelt-coin-1a", 984 "recoup-withdraw-coin-1b", 985 MHD_HTTP_OK, 986 "EUR:1", 987 NULL), 988 TALER_TESTING_cmd_melt_reveal ( 989 "recoup-reveal-coin-1a", 990 "recoup-remelt-coin-1a", 991 MHD_HTTP_OK), 992 /* Try melting for more than the residual value to provoke an error */ 993 TALER_TESTING_cmd_melt ( 994 "recoup-remelt-coin-1b", 995 "recoup-withdraw-coin-1b", 996 MHD_HTTP_OK, 997 "EUR:1", 998 NULL), 999 TALER_TESTING_cmd_melt ( 1000 "recoup-remelt-coin-1c", 1001 "recoup-withdraw-coin-1b", 1002 MHD_HTTP_OK, 1003 "EUR:1", 1004 NULL), 1005 TALER_TESTING_cmd_melt ( 1006 "recoup-remelt-coin-1d", 1007 "recoup-withdraw-coin-1b", 1008 MHD_HTTP_OK, 1009 "EUR:1", 1010 NULL), 1011 TALER_TESTING_cmd_melt ( 1012 "recoup-remelt-coin-1e", 1013 "recoup-withdraw-coin-1b", 1014 MHD_HTTP_OK, 1015 "EUR:1", 1016 NULL), 1017 TALER_TESTING_cmd_melt ( 1018 "recoup-remelt-coin-1f", 1019 "recoup-withdraw-coin-1b", 1020 MHD_HTTP_OK, 1021 "EUR:1", 1022 NULL), 1023 TALER_TESTING_cmd_melt ( 1024 "recoup-remelt-coin-1g", 1025 "recoup-withdraw-coin-1b", 1026 MHD_HTTP_OK, 1027 "EUR:1", 1028 NULL), 1029 TALER_TESTING_cmd_melt ( 1030 "recoup-remelt-coin-1h", 1031 "recoup-withdraw-coin-1b", 1032 MHD_HTTP_OK, 1033 "EUR:1", 1034 NULL), 1035 TALER_TESTING_cmd_melt ( 1036 "recoup-remelt-coin-1i", 1037 "recoup-withdraw-coin-1b", 1038 MHD_HTTP_OK, 1039 "EUR:1", 1040 NULL), 1041 TALER_TESTING_cmd_melt ( 1042 "recoup-remelt-coin-1b-failing", 1043 "recoup-withdraw-coin-1b", 1044 MHD_HTTP_CONFLICT, 1045 "EUR:1", 1046 NULL), 1047 /* Re-withdraw from this reserve */ 1048 TALER_TESTING_cmd_withdraw_amount ( 1049 "recoup-withdraw-coin-2", 1050 "recoup-create-reserve-1", 1051 "EUR:1", 1052 0, /* age restriction off */ 1053 MHD_HTTP_OK), 1054 /** 1055 * This withdrawal will test the logic to create a "recoup" 1056 * element to insert into the reserve's history. 1057 */ 1058 TALER_TESTING_cmd_withdraw_amount ( 1059 "recoup-withdraw-coin-2-over", 1060 "recoup-create-reserve-1", 1061 "EUR:10", 1062 0, /* age restriction off */ 1063 MHD_HTTP_CONFLICT), 1064 TALER_TESTING_cmd_status ( 1065 "recoup-reserve-status-2", 1066 "recoup-create-reserve-1", 1067 "EUR:3.99", 1068 MHD_HTTP_OK), 1069 /* These commands should close the reserve because 1070 * the aggregator is given a config file that overrides 1071 * the reserve expiration time (making it now-ish) */ 1072 CMD_TRANSFER_TO_EXCHANGE ("short-lived-reserve", 1073 "EUR:5.01"), 1074 TALER_TESTING_cmd_check_bank_admin_transfer ( 1075 "check-short-lived-reserve", 1076 "EUR:5.01", 1077 cred.user42_payto, 1078 cred.exchange_payto, 1079 "short-lived-reserve"), 1080 TALER_TESTING_cmd_exec_wirewatch2 ( 1081 "short-lived-aggregation", 1082 config_file_expire_reserve_now, 1083 "exchange-account-2"), 1084 TALER_TESTING_cmd_exec_closer ( 1085 "close-reserves", 1086 config_file_expire_reserve_now, 1087 "EUR:5", 1088 "EUR:0.01", 1089 "short-lived-reserve"), 1090 TALER_TESTING_cmd_exec_transfer ( 1091 "close-reserves-transfer", 1092 config_file_expire_reserve_now), 1093 1094 TALER_TESTING_cmd_status ( 1095 "short-lived-status", 1096 "short-lived-reserve", 1097 "EUR:0", 1098 MHD_HTTP_OK), 1099 TALER_TESTING_cmd_withdraw_amount ( 1100 "expired-withdraw", 1101 "short-lived-reserve", 1102 "EUR:1", 1103 0, /* age restriction off */ 1104 MHD_HTTP_CONFLICT), 1105 TALER_TESTING_cmd_check_bank_transfer ( 1106 "check_bank_short-lived_reimburse", 1107 cred.exchange_url, 1108 "EUR:5", 1109 cred.exchange_payto, 1110 cred.user42_payto), 1111 /* Fill reserve with EUR:2.02, as withdraw fee is 1 ct per 1112 * config, then withdraw two coin, partially spend one, and 1113 * then have the rest paid back. Check deposit of other coin 1114 * fails. Do not use EUR:5 here as the EUR:5 coin was 1115 * revoked and we did not bother to create a new one... */ 1116 CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-2", 1117 "EUR:2.02"), 1118 TALER_TESTING_cmd_check_bank_admin_transfer ( 1119 "ck-recoup-create-reserve-2", 1120 "EUR:2.02", 1121 cred.user42_payto, 1122 cred.exchange_payto, 1123 "recoup-create-reserve-2"), 1124 /* Make previous command effective. */ 1125 CMD_EXEC_WIREWATCH ("wirewatch-5"), 1126 /* Withdraw a 1 EUR coin, at fee of 1 ct */ 1127 TALER_TESTING_cmd_withdraw_amount ( 1128 "recoup-withdraw-coin-2a", 1129 "recoup-create-reserve-2", 1130 "EUR:1", 1131 0, /* age restriction off */ 1132 MHD_HTTP_OK), 1133 /* Withdraw a 1 EUR coin, at fee of 1 ct */ 1134 TALER_TESTING_cmd_withdraw_amount ( 1135 "recoup-withdraw-coin-2b", 1136 "recoup-create-reserve-2", 1137 "EUR:1", 1138 0, /* age restriction off */ 1139 MHD_HTTP_OK), 1140 TALER_TESTING_cmd_deposit ( 1141 "recoup-deposit-partial", 1142 "recoup-withdraw-coin-2a", 1143 0, 1144 cred.user42_payto, 1145 "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}", 1146 GNUNET_TIME_UNIT_ZERO, 1147 "EUR:0.5", 1148 MHD_HTTP_OK), 1149 TALER_TESTING_cmd_revoke ( 1150 "revoke-1-EUR:1", 1151 MHD_HTTP_OK, 1152 "recoup-withdraw-coin-2a", 1153 config_file), 1154 /* Check recoup is failing for the coin with the reused coin key 1155 (fails either because of denomination conflict (RSA) or 1156 double-spending (CS))*/ 1157 TALER_TESTING_cmd_recoup ( 1158 "recoup-2x", 1159 MHD_HTTP_CONFLICT, 1160 "withdraw-coin-1x", 1161 "EUR:1"), 1162 TALER_TESTING_cmd_recoup ( 1163 "recoup-2", 1164 MHD_HTTP_OK, 1165 "recoup-withdraw-coin-2a", 1166 "EUR:0.5"), 1167 /* Idempotency of recoup (withdrawal variant) */ 1168 TALER_TESTING_cmd_recoup ( 1169 "recoup-2b", 1170 MHD_HTTP_OK, 1171 "recoup-withdraw-coin-2a", 1172 "EUR:0.5"), 1173 TALER_TESTING_cmd_deposit ( 1174 "recoup-deposit-revoked", 1175 "recoup-withdraw-coin-2b", 1176 0, 1177 cred.user42_payto, 1178 "{\"items\":[{\"name\":\"gnu ice cream\",\"value\":1}]}", 1179 GNUNET_TIME_UNIT_ZERO, 1180 "EUR:1", 1181 MHD_HTTP_GONE), 1182 /* Test deposit fails after recoup, with proof in recoup */ 1183 1184 /* Note that, the exchange will never return the coin's transaction 1185 * history with recoup data, as we get a 410 on the DK! */ 1186 TALER_TESTING_cmd_deposit ( 1187 "recoup-deposit-partial-after-recoup", 1188 "recoup-withdraw-coin-2a", 1189 0, 1190 cred.user42_payto, 1191 "{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}", 1192 GNUNET_TIME_UNIT_ZERO, 1193 "EUR:0.5", 1194 MHD_HTTP_GONE), 1195 /* Test that revoked coins cannot be withdrawn */ 1196 CMD_TRANSFER_TO_EXCHANGE ( 1197 "recoup-create-reserve-3", 1198 "EUR:1.01"), 1199 TALER_TESTING_cmd_check_bank_admin_transfer ( 1200 "check-recoup-create-reserve-3", 1201 "EUR:1.01", 1202 cred.user42_payto, 1203 cred.exchange_payto, 1204 "recoup-create-reserve-3"), 1205 CMD_EXEC_WIREWATCH ("wirewatch-6"), 1206 TALER_TESTING_cmd_withdraw_amount ( 1207 "recoup-withdraw-coin-3-revoked", 1208 "recoup-create-reserve-3", 1209 "EUR:1", 1210 0, /* age restriction off */ 1211 MHD_HTTP_GONE), 1212 /* check that we are empty before the rejection test */ 1213 TALER_TESTING_cmd_check_bank_empty ("check-empty-again"), 1214 1215 TALER_TESTING_cmd_end () 1216 }; 1217 #endif 1218 1219 /** 1220 * Test batch withdrawal plus spending. 1221 */ 1222 struct TALER_TESTING_Command batch_withdraw[] = { 1223 /** 1224 * Move money to the exchange's bank account. 1225 */ 1226 CMD_TRANSFER_TO_EXCHANGE ( 1227 "create-batch-reserve-1", 1228 "EUR:6.03"), 1229 TALER_TESTING_cmd_reserve_poll ( 1230 "poll-batch-reserve-1", 1231 "create-batch-reserve-1", 1232 "EUR:6.03", 1233 GNUNET_TIME_UNIT_MINUTES, 1234 MHD_HTTP_OK), 1235 TALER_TESTING_cmd_check_bank_admin_transfer ( 1236 "check-create-batch-reserve-1", 1237 "EUR:6.03", 1238 cred.user42_payto, 1239 cred.exchange_payto, 1240 "create-batch-reserve-1"), 1241 /* 1242 * Make a reserve exist, according to the previous 1243 * transfer. 1244 */ 1245 CMD_EXEC_WIREWATCH ("wirewatch-batch-1"), 1246 TALER_TESTING_cmd_reserve_poll_finish ( 1247 "finish-poll-batch-reserve-1", 1248 GNUNET_TIME_UNIT_SECONDS, 1249 "poll-batch-reserve-1"), 1250 /** 1251 * Withdraw EUR:5 AND EUR:1. 1252 */ 1253 TALER_TESTING_cmd_batch_withdraw ( 1254 "batch-withdraw-coin-1", 1255 "create-batch-reserve-1", 1256 MHD_HTTP_OK, 1257 "EUR:5", 1258 "EUR:1", 1259 NULL), 1260 /** 1261 * Check the reserve is (almost) depleted. 1262 */ 1263 TALER_TESTING_cmd_status ( 1264 "status-batch-1", 1265 "create-batch-reserve-1", 1266 "EUR:0.01", 1267 MHD_HTTP_OK), 1268 TALER_TESTING_cmd_reserve_history ( 1269 "history-batch-1", 1270 "create-batch-reserve-1", 1271 "EUR:0.01", 1272 MHD_HTTP_OK), 1273 /** 1274 * Spend the coins. 1275 */ 1276 TALER_TESTING_cmd_batch_deposit ( 1277 "batch-deposit-1", 1278 cred.user42_payto, 1279 "{\"items\":[{\"name\":\"final ice cream\",\"value\":5}]}", 1280 GNUNET_TIME_UNIT_ZERO, 1281 MHD_HTTP_OK, 1282 "batch-withdraw-coin-1#0", 1283 "EUR:5", 1284 "batch-withdraw-coin-1#1", 1285 "EUR:1", 1286 NULL), 1287 TALER_TESTING_cmd_coin_history ( 1288 "coin-history-batch-1", 1289 "batch-withdraw-coin-1#0", 1290 "EUR:0.0", 1291 MHD_HTTP_OK), 1292 TALER_TESTING_cmd_end () 1293 }; 1294 1295 1296 #define RESERVE_OPEN_CLOSE_CHUNK 4 1297 #define RESERVE_OPEN_CLOSE_ITERATIONS 3 1298 1299 struct TALER_TESTING_Command reserve_open_close[(RESERVE_OPEN_CLOSE_ITERATIONS 1300 * RESERVE_OPEN_CLOSE_CHUNK) 1301 + 1]; 1302 1303 (void) cls; 1304 for (unsigned int i = 0; 1305 i < RESERVE_OPEN_CLOSE_ITERATIONS; 1306 i++) 1307 { 1308 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 0] 1309 = CMD_TRANSFER_TO_EXCHANGE ("reserve-open-close-key", 1310 "EUR:20"); 1311 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 1] 1312 = TALER_TESTING_cmd_exec_wirewatch2 ("reserve-open-close-wirewatch", 1313 config_file_expire_reserve_now, 1314 "exchange-account-2"); 1315 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 2] 1316 = TALER_TESTING_cmd_exec_closer ("reserve-open-close-aggregation", 1317 config_file_expire_reserve_now, 1318 "EUR:19.99", 1319 "EUR:0.01", 1320 "reserve-open-close-key"); 1321 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 3] 1322 = TALER_TESTING_cmd_status ("reserve-open-close-status", 1323 "reserve-open-close-key", 1324 "EUR:0", 1325 MHD_HTTP_OK); 1326 } 1327 reserve_open_close[RESERVE_OPEN_CLOSE_ITERATIONS * RESERVE_OPEN_CLOSE_CHUNK] 1328 = TALER_TESTING_cmd_end (); 1329 1330 { 1331 struct TALER_TESTING_Command commands[] = { 1332 TALER_TESTING_cmd_run_fakebank ("run-fakebank", 1333 cred.cfg, 1334 "exchange-account-2"), 1335 TALER_TESTING_cmd_system_start ("start-taler", 1336 config_file, 1337 "-e", 1338 NULL), 1339 TALER_TESTING_cmd_get_exchange ("get-exchange", 1340 cred.cfg, 1341 NULL, 1342 true, 1343 true), 1344 TALER_TESTING_cmd_batch ("withdraw", 1345 withdraw), 1346 TALER_TESTING_cmd_batch ("spend", 1347 spend), 1348 TALER_TESTING_cmd_batch ("refresh", 1349 refresh), 1350 TALER_TESTING_cmd_batch ("withdraw-age", 1351 withdraw_age), 1352 TALER_TESTING_cmd_batch ("spend-age", 1353 spend_age), 1354 TALER_TESTING_cmd_batch ("refresh-age", 1355 refresh_age), 1356 TALER_TESTING_cmd_batch ("track", 1357 track), 1358 TALER_TESTING_cmd_batch ("unaggregation", 1359 unaggregation), 1360 TALER_TESTING_cmd_batch ("aggregation", 1361 aggregation), 1362 TALER_TESTING_cmd_batch ("refund", 1363 refund), 1364 TALER_TESTING_cmd_batch ("batch-withdraw", 1365 batch_withdraw), 1366 #if FIXME_9828 1367 TALER_TESTING_cmd_batch ("recoup", 1368 recoup), 1369 #endif 1370 TALER_TESTING_cmd_batch ("reserve-open-close", 1371 reserve_open_close), 1372 /* End the suite. */ 1373 TALER_TESTING_cmd_end () 1374 }; 1375 1376 TALER_TESTING_run (is, 1377 commands); 1378 } 1379 } 1380 1381 1382 int 1383 main (int argc, 1384 char *const *argv) 1385 { 1386 (void) argc; 1387 { 1388 char *cipher; 1389 1390 cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); 1391 GNUNET_assert (NULL != cipher); 1392 uses_cs = (0 == strcmp (cipher, 1393 "cs")); 1394 GNUNET_asprintf (&config_file, 1395 "test_exchange_api-%s.conf", 1396 cipher); 1397 GNUNET_asprintf (&config_file_expire_reserve_now, 1398 "test_exchange_api_expire_reserve_now-%s.conf", 1399 cipher); 1400 GNUNET_free (cipher); 1401 } 1402 return TALER_TESTING_main (argv, 1403 "INFO", 1404 config_file, 1405 "exchange-account-2", 1406 TALER_TESTING_BS_FAKEBANK, 1407 &cred, 1408 &run, 1409 NULL); 1410 } 1411 1412 1413 /* end of test_exchange_api.c */