test_exchange_api.c (45169B)
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 struct TALER_TESTING_Command recoup[] = { 912 /** 913 * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per 914 * config. 915 */ 916 CMD_TRANSFER_TO_EXCHANGE ( 917 "recoup-create-reserve-1", 918 "EUR:15.02"), 919 TALER_TESTING_cmd_check_bank_admin_transfer ( 920 "recoup-create-reserve-1-check", 921 "EUR:15.02", 922 cred.user42_payto, 923 cred.exchange_payto, 924 "recoup-create-reserve-1"), 925 /** 926 * Run wire-watch to trigger the reserve creation. 927 */ 928 CMD_EXEC_WIREWATCH ("wirewatch-4"), 929 /* Withdraw a 5 EUR coin, at fee of 1 ct */ 930 TALER_TESTING_cmd_withdraw_amount ( 931 "recoup-withdraw-coin-1", 932 "recoup-create-reserve-1", 933 "EUR:5", 934 0, /* age restriction off */ 935 MHD_HTTP_OK), 936 /* Withdraw a 10 EUR coin, at fee of 1 ct */ 937 TALER_TESTING_cmd_withdraw_amount ( 938 "recoup-withdraw-coin-1b", 939 "recoup-create-reserve-1", 940 "EUR:10", 941 0, /* age restriction off */ 942 MHD_HTTP_OK), 943 /* melt 10 EUR coin to get 5 EUR refreshed coin */ 944 TALER_TESTING_cmd_melt ( 945 "recoup-melt-coin-1b", 946 "recoup-withdraw-coin-1b", 947 MHD_HTTP_OK, 948 "EUR:5", 949 NULL), 950 TALER_TESTING_cmd_melt_reveal ( 951 "recoup-reveal-coin-1b", 952 "recoup-melt-coin-1b", 953 MHD_HTTP_OK), 954 /* Revoke both 5 EUR coins */ 955 TALER_TESTING_cmd_revoke ( 956 "revoke-0-EUR:5", 957 MHD_HTTP_OK, 958 "recoup-withdraw-coin-1", 959 config_file), 960 /* Recoup coin to reserve */ 961 TALER_TESTING_cmd_recoup ( 962 "recoup-1", 963 MHD_HTTP_OK, 964 "recoup-withdraw-coin-1", 965 "EUR:5"), 966 /* Check the money is back with the reserve */ 967 TALER_TESTING_cmd_status ( 968 "recoup-reserve-status-1", 969 "recoup-create-reserve-1", 970 "EUR:5.0", 971 MHD_HTTP_OK), 972 /* Recoup-refresh coin to 10 EUR coin */ 973 TALER_TESTING_cmd_recoup_refresh ( 974 "recoup-1b", 975 MHD_HTTP_OK, 976 "recoup-reveal-coin-1b", 977 "recoup-melt-coin-1b", 978 "EUR:5"), 979 /* melt 10 EUR coin *again* to get 1 EUR refreshed coin */ 980 TALER_TESTING_cmd_melt ( 981 "recoup-remelt-coin-1a", 982 "recoup-withdraw-coin-1b", 983 MHD_HTTP_OK, 984 "EUR:1", 985 NULL), 986 TALER_TESTING_cmd_melt_reveal ( 987 "recoup-reveal-coin-1a", 988 "recoup-remelt-coin-1a", 989 MHD_HTTP_OK), 990 /* Try melting for more than the residual value to provoke an error */ 991 TALER_TESTING_cmd_melt ( 992 "recoup-remelt-coin-1b", 993 "recoup-withdraw-coin-1b", 994 MHD_HTTP_OK, 995 "EUR:1", 996 NULL), 997 TALER_TESTING_cmd_melt ( 998 "recoup-remelt-coin-1c", 999 "recoup-withdraw-coin-1b", 1000 MHD_HTTP_OK, 1001 "EUR:1", 1002 NULL), 1003 TALER_TESTING_cmd_melt ( 1004 "recoup-remelt-coin-1d", 1005 "recoup-withdraw-coin-1b", 1006 MHD_HTTP_OK, 1007 "EUR:1", 1008 NULL), 1009 TALER_TESTING_cmd_melt ( 1010 "recoup-remelt-coin-1e", 1011 "recoup-withdraw-coin-1b", 1012 MHD_HTTP_OK, 1013 "EUR:1", 1014 NULL), 1015 TALER_TESTING_cmd_melt ( 1016 "recoup-remelt-coin-1f", 1017 "recoup-withdraw-coin-1b", 1018 MHD_HTTP_OK, 1019 "EUR:1", 1020 NULL), 1021 TALER_TESTING_cmd_melt ( 1022 "recoup-remelt-coin-1g", 1023 "recoup-withdraw-coin-1b", 1024 MHD_HTTP_OK, 1025 "EUR:1", 1026 NULL), 1027 TALER_TESTING_cmd_melt ( 1028 "recoup-remelt-coin-1h", 1029 "recoup-withdraw-coin-1b", 1030 MHD_HTTP_OK, 1031 "EUR:1", 1032 NULL), 1033 TALER_TESTING_cmd_melt ( 1034 "recoup-remelt-coin-1i", 1035 "recoup-withdraw-coin-1b", 1036 MHD_HTTP_OK, 1037 "EUR:1", 1038 NULL), 1039 TALER_TESTING_cmd_melt ( 1040 "recoup-remelt-coin-1b-failing", 1041 "recoup-withdraw-coin-1b", 1042 MHD_HTTP_CONFLICT, 1043 "EUR:1", 1044 NULL), 1045 /* Re-withdraw from this reserve */ 1046 TALER_TESTING_cmd_withdraw_amount ( 1047 "recoup-withdraw-coin-2", 1048 "recoup-create-reserve-1", 1049 "EUR:1", 1050 0, /* age restriction off */ 1051 MHD_HTTP_OK), 1052 /** 1053 * This withdrawal will test the logic to create a "recoup" 1054 * element to insert into the reserve's history. 1055 */ 1056 TALER_TESTING_cmd_withdraw_amount ( 1057 "recoup-withdraw-coin-2-over", 1058 "recoup-create-reserve-1", 1059 "EUR:10", 1060 0, /* age restriction off */ 1061 MHD_HTTP_CONFLICT), 1062 TALER_TESTING_cmd_status ( 1063 "recoup-reserve-status-2", 1064 "recoup-create-reserve-1", 1065 "EUR:3.99", 1066 MHD_HTTP_OK), 1067 /* These commands should close the reserve because 1068 * the aggregator is given a config file that overrides 1069 * the reserve expiration time (making it now-ish) */ 1070 CMD_TRANSFER_TO_EXCHANGE ("short-lived-reserve", 1071 "EUR:5.01"), 1072 TALER_TESTING_cmd_check_bank_admin_transfer ( 1073 "check-short-lived-reserve", 1074 "EUR:5.01", 1075 cred.user42_payto, 1076 cred.exchange_payto, 1077 "short-lived-reserve"), 1078 TALER_TESTING_cmd_exec_wirewatch2 ( 1079 "short-lived-aggregation", 1080 config_file_expire_reserve_now, 1081 "exchange-account-2"), 1082 TALER_TESTING_cmd_exec_closer ( 1083 "close-reserves", 1084 config_file_expire_reserve_now, 1085 "EUR:5", 1086 "EUR:0.01", 1087 "short-lived-reserve"), 1088 TALER_TESTING_cmd_exec_transfer ( 1089 "close-reserves-transfer", 1090 config_file_expire_reserve_now), 1091 1092 TALER_TESTING_cmd_status ( 1093 "short-lived-status", 1094 "short-lived-reserve", 1095 "EUR:0", 1096 MHD_HTTP_OK), 1097 TALER_TESTING_cmd_withdraw_amount ( 1098 "expired-withdraw", 1099 "short-lived-reserve", 1100 "EUR:1", 1101 0, /* age restriction off */ 1102 MHD_HTTP_CONFLICT), 1103 TALER_TESTING_cmd_check_bank_transfer ( 1104 "check_bank_short-lived_reimburse", 1105 cred.exchange_url, 1106 "EUR:5", 1107 cred.exchange_payto, 1108 cred.user42_payto), 1109 /* Fill reserve with EUR:2.02, as withdraw fee is 1 ct per 1110 * config, then withdraw two coin, partially spend one, and 1111 * then have the rest paid back. Check deposit of other coin 1112 * fails. Do not use EUR:5 here as the EUR:5 coin was 1113 * revoked and we did not bother to create a new one... */ 1114 CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-2", 1115 "EUR:2.02"), 1116 TALER_TESTING_cmd_check_bank_admin_transfer ( 1117 "ck-recoup-create-reserve-2", 1118 "EUR:2.02", 1119 cred.user42_payto, 1120 cred.exchange_payto, 1121 "recoup-create-reserve-2"), 1122 /* Make previous command effective. */ 1123 CMD_EXEC_WIREWATCH ("wirewatch-5"), 1124 /* Withdraw a 1 EUR coin, at fee of 1 ct */ 1125 TALER_TESTING_cmd_withdraw_amount ( 1126 "recoup-withdraw-coin-2a", 1127 "recoup-create-reserve-2", 1128 "EUR:1", 1129 0, /* age restriction off */ 1130 MHD_HTTP_OK), 1131 /* Withdraw a 1 EUR coin, at fee of 1 ct */ 1132 TALER_TESTING_cmd_withdraw_amount ( 1133 "recoup-withdraw-coin-2b", 1134 "recoup-create-reserve-2", 1135 "EUR:1", 1136 0, /* age restriction off */ 1137 MHD_HTTP_OK), 1138 TALER_TESTING_cmd_deposit ( 1139 "recoup-deposit-partial", 1140 "recoup-withdraw-coin-2a", 1141 0, 1142 cred.user42_payto, 1143 "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}", 1144 GNUNET_TIME_UNIT_ZERO, 1145 "EUR:0.5", 1146 MHD_HTTP_OK), 1147 TALER_TESTING_cmd_revoke ( 1148 "revoke-1-EUR:1", 1149 MHD_HTTP_OK, 1150 "recoup-withdraw-coin-2a", 1151 config_file), 1152 /* Check recoup is failing for the coin with the reused coin key 1153 (fails either because of denomination conflict (RSA) or 1154 double-spending (CS))*/ 1155 TALER_TESTING_cmd_recoup ( 1156 "recoup-2x", 1157 MHD_HTTP_CONFLICT, 1158 "withdraw-coin-1x", 1159 "EUR:1"), 1160 TALER_TESTING_cmd_recoup ( 1161 "recoup-2", 1162 MHD_HTTP_OK, 1163 "recoup-withdraw-coin-2a", 1164 "EUR:0.5"), 1165 /* Idempotency of recoup (withdrawal variant) */ 1166 TALER_TESTING_cmd_recoup ( 1167 "recoup-2b", 1168 MHD_HTTP_OK, 1169 "recoup-withdraw-coin-2a", 1170 "EUR:0.5"), 1171 TALER_TESTING_cmd_deposit ( 1172 "recoup-deposit-revoked", 1173 "recoup-withdraw-coin-2b", 1174 0, 1175 cred.user42_payto, 1176 "{\"items\":[{\"name\":\"gnu ice cream\",\"value\":1}]}", 1177 GNUNET_TIME_UNIT_ZERO, 1178 "EUR:1", 1179 MHD_HTTP_GONE), 1180 /* Test deposit fails after recoup, with proof in recoup */ 1181 1182 /* Note that, the exchange will never return the coin's transaction 1183 * history with recoup data, as we get a 410 on the DK! */ 1184 TALER_TESTING_cmd_deposit ( 1185 "recoup-deposit-partial-after-recoup", 1186 "recoup-withdraw-coin-2a", 1187 0, 1188 cred.user42_payto, 1189 "{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}", 1190 GNUNET_TIME_UNIT_ZERO, 1191 "EUR:0.5", 1192 MHD_HTTP_GONE), 1193 /* Test that revoked coins cannot be withdrawn */ 1194 CMD_TRANSFER_TO_EXCHANGE ( 1195 "recoup-create-reserve-3", 1196 "EUR:1.01"), 1197 TALER_TESTING_cmd_check_bank_admin_transfer ( 1198 "check-recoup-create-reserve-3", 1199 "EUR:1.01", 1200 cred.user42_payto, 1201 cred.exchange_payto, 1202 "recoup-create-reserve-3"), 1203 CMD_EXEC_WIREWATCH ("wirewatch-6"), 1204 TALER_TESTING_cmd_withdraw_amount ( 1205 "recoup-withdraw-coin-3-revoked", 1206 "recoup-create-reserve-3", 1207 "EUR:1", 1208 0, /* age restriction off */ 1209 MHD_HTTP_GONE), 1210 /* check that we are empty before the rejection test */ 1211 TALER_TESTING_cmd_check_bank_empty ("check-empty-again"), 1212 1213 TALER_TESTING_cmd_end () 1214 }; 1215 1216 /** 1217 * Test batch withdrawal plus spending. 1218 */ 1219 struct TALER_TESTING_Command batch_withdraw[] = { 1220 /** 1221 * Move money to the exchange's bank account. 1222 */ 1223 CMD_TRANSFER_TO_EXCHANGE ( 1224 "create-batch-reserve-1", 1225 "EUR:6.03"), 1226 TALER_TESTING_cmd_reserve_poll ( 1227 "poll-batch-reserve-1", 1228 "create-batch-reserve-1", 1229 "EUR:6.03", 1230 GNUNET_TIME_UNIT_MINUTES, 1231 MHD_HTTP_OK), 1232 TALER_TESTING_cmd_check_bank_admin_transfer ( 1233 "check-create-batch-reserve-1", 1234 "EUR:6.03", 1235 cred.user42_payto, 1236 cred.exchange_payto, 1237 "create-batch-reserve-1"), 1238 /* 1239 * Make a reserve exist, according to the previous 1240 * transfer. 1241 */ 1242 CMD_EXEC_WIREWATCH ("wirewatch-batch-1"), 1243 TALER_TESTING_cmd_reserve_poll_finish ( 1244 "finish-poll-batch-reserve-1", 1245 GNUNET_TIME_UNIT_SECONDS, 1246 "poll-batch-reserve-1"), 1247 /** 1248 * Withdraw EUR:5 AND EUR:1. 1249 */ 1250 TALER_TESTING_cmd_batch_withdraw ( 1251 "batch-withdraw-coin-1", 1252 "create-batch-reserve-1", 1253 MHD_HTTP_OK, 1254 "EUR:5", 1255 "EUR:1", 1256 NULL), 1257 /** 1258 * Check the reserve is (almost) depleted. 1259 */ 1260 TALER_TESTING_cmd_status ( 1261 "status-batch-1", 1262 "create-batch-reserve-1", 1263 "EUR:0.01", 1264 MHD_HTTP_OK), 1265 TALER_TESTING_cmd_reserve_history ( 1266 "history-batch-1", 1267 "create-batch-reserve-1", 1268 "EUR:0.01", 1269 MHD_HTTP_OK), 1270 /* the same coin twice in one batch is a malformed request */ 1271 TALER_TESTING_cmd_batch_deposit ( 1272 "batch-deposit-duplicate-coin", 1273 cred.user42_payto, 1274 "{\"items\":[{\"name\":\"double ice cream\",\"value\":1}]}", 1275 GNUNET_TIME_UNIT_ZERO, 1276 MHD_HTTP_BAD_REQUEST, 1277 "batch-withdraw-coin-1#0", 1278 "EUR:1", 1279 "batch-withdraw-coin-1#0", 1280 "EUR:1", 1281 NULL), 1282 /** 1283 * Spend the coins. 1284 */ 1285 TALER_TESTING_cmd_batch_deposit ( 1286 "batch-deposit-1", 1287 cred.user42_payto, 1288 "{\"items\":[{\"name\":\"final ice cream\",\"value\":5}]}", 1289 GNUNET_TIME_UNIT_ZERO, 1290 MHD_HTTP_OK, 1291 "batch-withdraw-coin-1#0", 1292 "EUR:5", 1293 "batch-withdraw-coin-1#1", 1294 "EUR:1", 1295 NULL), 1296 TALER_TESTING_cmd_coin_history ( 1297 "coin-history-batch-1", 1298 "batch-withdraw-coin-1#0", 1299 "EUR:0.0", 1300 MHD_HTTP_OK), 1301 TALER_TESTING_cmd_end () 1302 }; 1303 1304 1305 #define RESERVE_OPEN_CLOSE_CHUNK 4 1306 #define RESERVE_OPEN_CLOSE_ITERATIONS 3 1307 1308 struct TALER_TESTING_Command reserve_open_close[(RESERVE_OPEN_CLOSE_ITERATIONS 1309 * RESERVE_OPEN_CLOSE_CHUNK) 1310 + 1]; 1311 1312 (void) cls; 1313 for (unsigned int i = 0; 1314 i < RESERVE_OPEN_CLOSE_ITERATIONS; 1315 i++) 1316 { 1317 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 0] 1318 = CMD_TRANSFER_TO_EXCHANGE ("reserve-open-close-key", 1319 "EUR:20"); 1320 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 1] 1321 = TALER_TESTING_cmd_exec_wirewatch2 ("reserve-open-close-wirewatch", 1322 config_file_expire_reserve_now, 1323 "exchange-account-2"); 1324 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 2] 1325 = TALER_TESTING_cmd_exec_closer ("reserve-open-close-aggregation", 1326 config_file_expire_reserve_now, 1327 "EUR:19.99", 1328 "EUR:0.01", 1329 "reserve-open-close-key"); 1330 reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 3] 1331 = TALER_TESTING_cmd_status ("reserve-open-close-status", 1332 "reserve-open-close-key", 1333 "EUR:0", 1334 MHD_HTTP_OK); 1335 } 1336 reserve_open_close[RESERVE_OPEN_CLOSE_ITERATIONS * RESERVE_OPEN_CLOSE_CHUNK] 1337 = TALER_TESTING_cmd_end (); 1338 1339 { 1340 struct TALER_TESTING_Command commands[] = { 1341 TALER_TESTING_cmd_run_fakebank ("run-fakebank", 1342 cred.cfg, 1343 "exchange-account-2"), 1344 TALER_TESTING_cmd_system_start ("start-taler", 1345 config_file, 1346 "-e", 1347 NULL), 1348 TALER_TESTING_cmd_get_exchange ("get-exchange", 1349 cred.cfg, 1350 NULL, 1351 true, 1352 true), 1353 TALER_TESTING_cmd_batch ("withdraw", 1354 withdraw), 1355 TALER_TESTING_cmd_batch ("spend", 1356 spend), 1357 TALER_TESTING_cmd_batch ("refresh", 1358 refresh), 1359 TALER_TESTING_cmd_batch ("withdraw-age", 1360 withdraw_age), 1361 TALER_TESTING_cmd_batch ("spend-age", 1362 spend_age), 1363 TALER_TESTING_cmd_batch ("refresh-age", 1364 refresh_age), 1365 TALER_TESTING_cmd_batch ("track", 1366 track), 1367 TALER_TESTING_cmd_batch ("unaggregation", 1368 unaggregation), 1369 TALER_TESTING_cmd_batch ("aggregation", 1370 aggregation), 1371 TALER_TESTING_cmd_batch ("refund", 1372 refund), 1373 TALER_TESTING_cmd_batch ("batch-withdraw", 1374 batch_withdraw), 1375 TALER_TESTING_cmd_batch ("recoup", 1376 recoup), 1377 TALER_TESTING_cmd_batch ("reserve-open-close", 1378 reserve_open_close), 1379 /* End the suite. */ 1380 TALER_TESTING_cmd_end () 1381 }; 1382 1383 TALER_TESTING_run (is, 1384 commands); 1385 } 1386 } 1387 1388 1389 int 1390 main (int argc, 1391 char *const *argv) 1392 { 1393 (void) argc; 1394 { 1395 char *cipher; 1396 1397 cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); 1398 GNUNET_assert (NULL != cipher); 1399 uses_cs = (0 == strcmp (cipher, 1400 "cs")); 1401 GNUNET_asprintf (&config_file, 1402 "test_exchange_api-%s.conf", 1403 cipher); 1404 GNUNET_asprintf (&config_file_expire_reserve_now, 1405 "test_exchange_api_expire_reserve_now-%s.conf", 1406 cipher); 1407 GNUNET_free (cipher); 1408 } 1409 return TALER_TESTING_main (argv, 1410 "INFO", 1411 config_file, 1412 "exchange-account-2", 1413 TALER_TESTING_BS_FAKEBANK, 1414 &cred, 1415 &run, 1416 NULL); 1417 } 1418 1419 1420 /* end of test_exchange_api.c */