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