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