test-revocation.sh (22727B)
1 #!/bin/bash 2 # 3 # This file is part of TALER 4 # Copyright (C) 2014-2022 Taler Systems SA 5 # 6 # TALER is free software; you can redistribute it and/or modify it under the 7 # terms of the GNU General Public License as published by the Free Software 8 # Foundation; either version 3, or (at your option) any later version. 9 # 10 # TALER is distributed in the hope that it will be useful, but WITHOUT ANY 11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License along with 15 # TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/license> 16 # 17 # Setup database which was generated from a exchange-wallet interaction 18 # with revocations and run the auditor against it. 19 # 20 # Check that the auditor report is as expected. 21 # 22 # shellcheck disable=SC2317 23 # 24 # Requires 'jq' tool and Postgres superuser rights! 25 set -eu 26 # set -x 27 28 # Set of numbers for all the testcases. 29 # When adding new tests, increase the last number: 30 ALL_TESTS=$(seq 0 4) 31 32 # $TESTS determines which tests we should run. 33 # This construction is used to make it easy to 34 # only run a subset of the tests. To only run a subset, 35 # pass the numbers of the tests to run as the FIRST 36 # argument to test-auditor.sh, i.e.: 37 # 38 # $ test-revocation.sh "1 3" 39 # 40 # to run tests 1 and 3 only. By default, all tests are run. 41 # 42 TESTS=${1:-$ALL_TESTS} 43 44 export TALER_AUDITOR_TOKEN="secret-token:D4CST1Z6AHN3RT03M0T9NSTF2QGHTB5ZD2D3RYZB4HAWG8SX0JEFWBXCKXZHMB7Y3Z7KVFW0B3XPXD5BHCFP8EB0R6CNH2KAWDWVET0" 45 # Make taler-auditor-httpd require the token the requests below send. 46 export TALER_AUDITOR_ACCESS_TOKEN="${TALER_AUDITOR_TOKEN}" 47 export TALER_AUDITOR_SALT="64S36D1N6RVKGC9J6CT3ADHQ70RK4CSM6MV3EE1H68SK8D9P6WW32CHK6GTKCDSR64S36D1N6RVKGC9J6CT3ADHQ70RK4CSM6MV3EE0" 48 49 # Global variable to run the auditor processes under valgrind 50 # VALGRIND=valgrind 51 VALGRIND="" 52 LOGLEVEL="INFO" 53 54 . setup.sh 55 56 # Cleanup to run whenever we exit 57 function cleanup() 58 { 59 if [ ! -z "${EPID:-}" ] 60 then 61 echo -n "Stopping exchange $EPID..." 62 kill -TERM "$EPID" 63 wait "$EPID" 64 echo " DONE" 65 unset EPID 66 fi 67 stop_libeufin 68 } 69 70 # Cleanup to run whenever we exit 71 function exit_cleanup() 72 { 73 echo "Running exit-cleanup" 74 if [ ! -z "${POSTGRES_PATH:-}" ] 75 then 76 echo "Stopping Postgres at ${POSTGRES_PATH}" 77 "${POSTGRES_PATH}/pg_ctl" \ 78 -D "$TMPDIR" \ 79 -l /dev/null \ 80 stop \ 81 &> /dev/null \ 82 || true 83 fi 84 cleanup 85 for n in $(jobs -p) 86 do 87 kill "$n" 2> /dev/null || true 88 done 89 wait 90 echo "DONE" 91 } 92 93 # Install cleanup handler (except for kill -9) 94 trap exit_cleanup EXIT 95 96 97 # Operations to run before the actual audit 98 function pre_audit () { 99 # Launch bank 100 echo -n "Launching bank " 101 export CONF 102 export MY_TMP_DIR 103 launch_libeufin 104 for n in $(seq 1 80) 105 do 106 echo -n "." 107 sleep 0.1 108 OK=1 109 wget http://localhost:8082/ \ 110 -o /dev/null \ 111 -O /dev/null \ 112 >/dev/null && break 113 OK=0 114 done 115 if [ 1 != "$OK" ] 116 then 117 exit_skip "Failed to launch libeufin-bank" 118 fi 119 echo " DONE" 120 if [ "${1:-no}" = "aggregator" ] 121 then 122 echo -n "Running exchange aggregator ... (config: $CONF)" 123 taler-exchange-aggregator \ 124 -L "$LOGLEVEL" \ 125 -t \ 126 -c "$CONF" \ 127 -y \ 128 2> "${MY_TMP_DIR}/aggregator.log" \ 129 || exit_fail "FAIL" 130 echo " DONE" 131 echo -n "Running exchange closer ..." 132 taler-exchange-closer \ 133 -L "$LOGLEVEL" \ 134 -t \ 135 -c "$CONF" \ 136 2> "${MY_TMP_DIR}/closer.log" \ 137 || exit_fail "FAIL" 138 echo " DONE" 139 echo -n "Running exchange transfer ..." 140 taler-exchange-transfer \ 141 -L "$LOGLEVEL" \ 142 -t \ 143 -c "$CONF" \ 144 2> "${MY_TMP_DIR}/transfer.log" \ 145 || exit_fail "FAIL" 146 echo " DONE" 147 fi 148 } 149 150 # actual audit run 151 function audit_only () { 152 # Run the auditor! 153 echo -n "Running audit(s) ... (conf is $CONF)" 154 155 # Restart so that first run is always fresh, and second one is incremental 156 taler-auditor-dbinit \ 157 -r \ 158 -c "$CONF" 159 # Each helper is run twice: the first run audits from scratch, the 160 # second one exercises the incremental path. Findings end up in the 161 # auditor database and are inspected via the auditor's REST API. 162 for helper in aggregation aml coins deposits reserves \ 163 wire-credit wire-debit purses transfer 164 do 165 for pass in "" "-inc" 166 do 167 $VALGRIND "taler-helper-auditor-${helper}" \ 168 -i \ 169 -L "$LOGLEVEL" \ 170 -c "$CONF" \ 171 -t \ 172 > "${MY_TMP_DIR}/test-audit-${helper}${pass}.out" \ 173 2> "${MY_TMP_DIR}/test-audit-${helper}${pass}.err" \ 174 || exit_fail "${helper} audit${pass} failed (see ${MY_TMP_DIR}/test-audit-${helper}${pass}.*)" 175 echo -n "." 176 done 177 done 178 echo " DONE" 179 } 180 181 182 function stop_auditor_httpd() { 183 if [ -n "${APID:-}" ] 184 then 185 echo -n "Stopping auditor $APID..." 186 kill -TERM "$APID" 187 wait "$APID" || true 188 echo "DONE" 189 unset APID 190 fi 191 } 192 193 194 function run_auditor_httpd() { 195 echo -n "Starting auditor..." 196 $VALGRIND taler-auditor-httpd \ 197 -c "${CONF}" \ 198 -L "$LOGLEVEL" \ 199 2> "${MY_TMP_DIR}/auditor-httpd.err" & 200 APID=$! 201 # Wait for auditor service to be available 202 for n in $(seq 1 50) 203 do 204 echo -n "." 205 sleep 0.2 206 wget "http://localhost:8083/config" \ 207 -o /dev/null \ 208 -O /dev/null \ 209 >/dev/null \ 210 || continue 211 break 212 done 213 echo "... DONE." 214 wget "http://localhost:8083/webui/" \ 215 -o /dev/null \ 216 -O /dev/null \ 217 >/dev/null \ 218 || exit_fail "Auditor WebUI is not available under /webui/" 219 } 220 221 222 function check_auditor_running() { 223 ARUNSTATUS=$(curl -Is http://localhost:8083/config | head -1) 224 if [ -n "${ARUNSTATUS:-}" ] 225 then 226 echo "Auditor running" 227 else 228 echo "Auditor not running, starting it" 229 run_auditor_httpd 230 fi 231 unset ARUNSTATUS 232 } 233 234 235 function call_endpoint() { 236 if [ -n "${2+x}" ] 237 then 238 curl -s \ 239 -H "Accept: application/json" \ 240 -H "Authorization: Bearer ${TALER_AUDITOR_TOKEN}" \ 241 -o "${MY_TMP_DIR}/${2}.json" \ 242 "localhost:8083/monitoring/${1}?limit=50&balance_key=${2}" 243 echo "endpoint ${1} called (with balance_key)... " 244 else 245 curl -s \ 246 -H "Accept: application/json" \ 247 -H "Authorization: Bearer ${TALER_AUDITOR_TOKEN}" \ 248 -o "${MY_TMP_DIR}/${1}.json" \ 249 "localhost:8083/monitoring/${1}?limit=50" 250 echo "endpoint ${1} called... " 251 fi 252 } 253 254 255 function check_balance() { 256 call_endpoint "balances" "$1" 257 BAL=$(jq -r .records[0].balance_value < "${MY_TMP_DIR}/${1}.json") 258 if [ "$BAL" != "$2" ] 259 then 260 exit_fail "$3 (got $BAL, wanted $2)" 261 fi 262 echo "PASS" 263 } 264 265 266 function check_not_balance() { 267 call_endpoint "balances" "$1" 268 BAL=$(jq -r .records[0].balance_value < "${MY_TMP_DIR}/${1}.json") 269 if [ "$BAL" = "$2" ] 270 then 271 exit_fail "$3 (got $BAL, wanted NOT $2)" 272 fi 273 echo "PASS" 274 } 275 276 277 function check_report() { 278 call_endpoint "$1" 279 VAL=$(jq -r .records[0].\"$2\" < "${MY_TMP_DIR}/${1}.json") 280 if [ "$VAL" != "$3" ] 281 then 282 exit_fail "$1::$2 (got $VAL, wanted $3)" 283 fi 284 echo "PASS" 285 } 286 287 288 function check_no_report() { 289 call_endpoint "$1" 290 jq -e .records[0] \ 291 < "${MY_TMP_DIR}/${1}.json" \ 292 > /dev/null \ 293 && exit_fail "Wanted empty report for $1, but got incidents" 294 echo "PASS" 295 } 296 297 298 function check_report_neg() { 299 call_endpoint "$1" 300 VAL=$(jq -r .records[0].\"$2\" < "${MY_TMP_DIR}/${1}.json") 301 if [ "$VAL" == "$3" ] 302 then 303 exit_fail "$1::$2 (got $VAL, wanted $3)" 304 fi 305 echo "PASS" 306 } 307 308 309 # Check that at least one entry of report $1 has field $2 set to $3. 310 function check_report_any() { 311 call_endpoint "$1" 312 jq -e --arg want "$3" "any(.records[]; .\"$2\" == \$want)" \ 313 < "${MY_TMP_DIR}/${1}.json" \ 314 > /dev/null \ 315 || exit_fail "$1::$2 (no entry with value $3)" 316 echo "PASS" 317 } 318 319 320 # Run audit process on current database, including report 321 # generation. Pass "aggregator" as $1 to run 322 # $ taler-exchange-aggregator 323 # before auditor (to trigger pending wire transfers). 324 function run_audit () { 325 pre_audit "${1:-no}" 326 audit_only 327 cleanup 328 echo " DONE" 329 } 330 331 332 # Do a full reload of the (original) database 333 function full_reload() 334 { 335 echo -n "Doing full reload of the database... " 336 stop_auditor_httpd 337 dropdb -f "$DB" 2> /dev/null || true 338 createdb -T template0 "$DB" \ 339 || exit_skip "could not create database $DB (at ${PGHOST:-})" 340 # Import pre-generated database, -q(ietly) using single (-1) transaction 341 psql -Aqt "$DB" \ 342 -q \ 343 -1 \ 344 -f "${BASEDB}.sql" \ 345 > /dev/null \ 346 || exit_skip "Failed to load database $DB from ${BASEDB}.sql" 347 echo "DONE" 348 } 349 350 351 function test_0() { 352 echo "===========0: normal run with aggregator===========" 353 run_audit aggregator 354 check_auditor_running 355 356 echo "Checking output" 357 # if an emergency was detected, that is a bug and we should fail 358 echo -n "Test for emergencies... " 359 check_no_report "emergencies" 360 echo -n "Test for emergencies by count... " 361 check_no_report "emergencies-by-count" 362 echo -n "Test for deposit confirmation problems... " 363 check_no_report "deposit-confirmations" 364 echo -n "Test for wire inconsistencies... " 365 check_no_report "denomination-key-validity-withdraw-inconsistencies" 366 check_no_report "wire-out-inconsistencies" 367 check_no_report "reserve-in-inconsistencies" 368 check_no_report "misattribution-in-inconsistencies" 369 check_no_report "row-inconsistencies" 370 check_no_report "row-minor-inconsistencies" 371 check_no_report "wire-format-inconsistencies" 372 373 # Just to test the endpoint and for logging ... 374 call_endpoint "balances" 375 376 echo -n "Testing bad sig loss balance... " 377 check_balance \ 378 "aggregation_total_bad_sig_loss" \ 379 "TESTKUDOS:0" \ 380 "Wrong total bad sig loss from aggregation" 381 echo -n "Testing coin irregular loss balances... " 382 check_balance \ 383 "coin_irregular_loss" \ 384 "TESTKUDOS:0" \ 385 "Wrong total bad sig loss from coins" 386 echo -n "Testing reserves bad sig loss balances... " 387 check_balance \ 388 "reserves_total_bad_sig_loss" \ 389 "TESTKUDOS:0" \ 390 "Wrong total bad sig loss from reserves" 391 392 echo -n "Test for bad incoming delta plus... " 393 check_balance \ 394 "total_bad_amount_in_plus" \ 395 "TESTKUDOS:0" \ 396 "Expected total wire in delta plus wrong" 397 echo -n "Test for bad incoming delta minus... " 398 check_balance \ 399 "total_bad_amount_in_minus" \ 400 "TESTKUDOS:0" \ 401 "Expected total wire in delta minus wrong" 402 echo -n "Test for aggregation wire out delta plus... " 403 check_balance \ 404 "aggregation_total_wire_out_delta_plus" \ 405 "TESTKUDOS:0" \ 406 "Expected total wire out delta plus wrong" 407 echo -n "Test for aggregation wire out delta minus... " 408 check_balance \ 409 "aggregation_total_wire_out_delta_minus" \ 410 "TESTKUDOS:0" \ 411 "Expected total wire out delta minus wrong" 412 echo -n "Test for misattribution amounts... " 413 check_balance \ 414 "total_misattribution_in" \ 415 "TESTKUDOS:0" \ 416 "Expected total misattribution in wrong" 417 418 echo -n "Checking for unexpected aggregation delta plus differences... " 419 check_balance \ 420 "aggregation_total_arithmetic_delta_plus" \ 421 "TESTKUDOS:0" \ 422 "Wrong arithmetic delta plus from aggregations" 423 echo -n "Checking for unexpected aggregation delta minus differences... " 424 check_balance \ 425 "aggregation_total_arithmetic_delta_minus" \ 426 "TESTKUDOS:0" \ 427 "Wrong arithmetic delta minus from aggregations" 428 echo -n "Checking for unexpected coin delta plus differences... " 429 check_balance \ 430 "coins_total_arithmetic_delta_plus" \ 431 "TESTKUDOS:0" \ 432 "Wrong arithmetic delta plus from coins" 433 echo -n "Checking for unexpected coin delta minus differences... " 434 check_balance \ 435 "coins_total_arithmetic_delta_minus" \ 436 "TESTKUDOS:0" \ 437 "Wrong arithmetic delta minus from coins" 438 echo -n "Checking for unexpected reserves delta plus... " 439 check_balance \ 440 "reserves_total_arithmetic_delta_plus" \ 441 "TESTKUDOS:0" \ 442 "Wrong arithmetic delta plus from reserves" 443 echo -n "Checking for unexpected reserves delta minus... " 444 check_balance \ 445 "reserves_total_arithmetic_delta_minus" \ 446 "TESTKUDOS:0" \ 447 "Wrong arithmetic delta minus from reserves" 448 449 echo -n "Checking for unexpected arithmetic inconsistencies... " 450 check_no_report "amount-arithmetic-inconsistencies" 451 452 # cannot easily undo aggregator, hence full reload 453 full_reload 454 } 455 456 457 # Run without aggregator, hence auditor should detect wire 458 # transfer lag! 459 function test_1() { 460 461 echo "===========1: normal run===========" 462 run_audit 463 check_auditor_running 464 465 echo "Checking output" 466 # if an emergency was detected, that is a bug and we should fail 467 echo -n "Test for emergencies... " 468 check_no_report "emergencies" 469 echo -n "Test for emergencies by count... " 470 check_no_report "emergencies-by-count" 471 472 echo -n "Test for wire inconsistencies... " 473 check_no_report "wire-out-inconsistencies" 474 check_no_report "reserve-in-inconsistencies" 475 check_no_report "misattribution-in-inconsistencies" 476 check_no_report "row-inconsistencies" 477 check_no_report "row-minor-inconsistencies" 478 check_no_report "wire-format-inconsistencies" 479 480 echo -n "Test for bad incoming delta plus... " 481 check_balance \ 482 "total_bad_amount_in_plus" \ 483 "TESTKUDOS:0" \ 484 "Expected total wire in delta plus wrong" 485 echo -n "Test for bad incoming delta minus... " 486 check_balance \ 487 "total_bad_amount_in_minus" \ 488 "TESTKUDOS:0" \ 489 "Expected total wire in delta minus wrong" 490 echo -n "Test for misattribution amounts... " 491 check_balance \ 492 "total_misattribution_in" \ 493 "TESTKUDOS:0" \ 494 "Expected total misattribution in wrong" 495 496 # Database was unmodified, no need to undo 497 echo "OK" 498 } 499 500 501 502 # Change recoup amount 503 function test_2() { 504 505 echo "===========2: recoup amount inconsistency===========" 506 echo "UPDATE exchange.recoup SET amount.val=5 WHERE recoup_uuid=1" | psql -Aqt "$DB" 507 508 run_audit 509 check_auditor_running 510 511 # Reserve balance is now wrong 512 echo -n "Testing reserve balance inconsistency detection... " 513 check_report \ 514 "reserve-balance-summary-wrong-inconsistencies" \ 515 "auditor_amount" "TESTKUDOS:3" 516 check_report \ 517 "reserve-balance-summary-wrong-inconsistencies" \ 518 "exchange_amount" "TESTKUDOS:0" 519 # Coin spent exceeded coin's value 520 echo -n "Testing coin arithmetic inconsistency detection... " 521 check_report \ 522 "amount-arithmetic-inconsistencies" \ 523 "auditor_amount" "TESTKUDOS:2" 524 check_report \ 525 "amount-arithmetic-inconsistencies" \ 526 "exchange_amount" "TESTKUDOS:5" 527 echo "OK" 528 529 # Undo database modification 530 echo "UPDATE exchange.recoup SET amount.val=2 WHERE recoup_uuid=1" | psql -Aqt "$DB" 531 full_reload 532 } 533 534 535 # Change recoup-refresh amount 536 function test_3() { 537 538 echo "===========3: recoup-refresh amount inconsistency===========" 539 echo "UPDATE exchange.recoup_refresh SET amount.val=5 WHERE recoup_refresh_uuid=1" | psql -Aqt "$DB" 540 541 run_audit 542 check_auditor_running 543 544 echo -n "Testing inconsistency detection... " 545 # Coin spent exceeded coin's value 546 check_balance \ 547 "coins_total_arithmetic_delta_minus" \ 548 "TESTKUDOS:5" \ 549 "Arithmetic delta minus amount is wrong" 550 check_balance \ 551 "coins_total_arithmetic_delta_plus" \ 552 "TESTKUDOS:0" \ 553 "Arithmetic delta plus amount is wrong" 554 echo "OK" 555 556 # Undo database modification 557 echo "UPDATE exchange.recoup_refresh SET amount.val=0 WHERE recoup_refresh_uuid=1" | psql -Aqt "$DB" 558 full_reload 559 } 560 561 562 # Void recoup-refresh entry by 'unrevoking' denomination 563 function test_4() { 564 565 echo "===========4: invalid recoup===========" 566 echo "DELETE FROM exchange.denomination_revocations;" | psql -Aqt "$DB" 567 568 run_audit 569 check_auditor_running 570 571 echo -n "Testing inconsistency detection... " 572 # Recoup of a denomination that was never revoked is not legitimate 573 check_report_neg \ 574 "bad-sig-losses" \ 575 "loss" "TESTKUDOS:0" 576 echo -n "Testing irregular loss balance... " 577 check_not_balance \ 578 "coin_irregular_loss" \ 579 "TESTKUDOS:0" \ 580 "Total bad sig losses are wrong" 581 echo -n "Testing row inconsistency table attribution... " 582 check_report_any \ 583 "row-inconsistencies" \ 584 "row_table" "recoup" 585 echo "OK" 586 587 # Undo database modification (can't easily undo DELETE, so full reload) 588 full_reload 589 } 590 591 592 593 594 # *************** Main test loop starts here ************** 595 596 597 # Run all the tests against the database given in $1. 598 # Sets $fail to 0 on success, non-zero on failure. 599 function check_with_database() 600 { 601 BASEDB="$1" 602 # Configuration file to use 603 CONF="$1.conf" 604 echo "Running test suite with database $BASEDB using configuration $CONF" 605 606 MASTER_PRIV_FILE="${BASEDB}.mpriv" 607 taler-exchange-config -f \ 608 -c "${CONF}" \ 609 -s exchange-offline \ 610 -o MASTER_PRIV_FILE \ 611 -V "${MASTER_PRIV_FILE}" 612 MASTER_PUB=$(gnunet-ecc -p "$MASTER_PRIV_FILE") 613 614 echo "MASTER PUB is ${MASTER_PUB} using file ${MASTER_PRIV_FILE}" 615 616 # Load database 617 full_reload 618 # Run test suite 619 fail=0 620 for i in $TESTS 621 do 622 "test_$i" 623 if [ 0 != "$fail" ] 624 then 625 break 626 fi 627 done 628 # echo "Cleanup (disabled, leaving database $DB behind)" 629 dropdb "$DB" 630 } 631 632 # If this script is not running as root, create 633 # the temporary directory structure for storage for postgres 634 # Will set PGHOST accordingly 635 function perform_dbinit() { 636 # Available directly in path? 637 INITDB_BIN=$(command -v initdb) || true 638 if [[ -n "$INITDB_BIN" ]]; then 639 echo "FOUND (in path) at $INITDB_BIN" 640 else 641 HAVE_INITDB=$(find /usr -name "initdb" | head -1 2> /dev/null | grep postgres) || exit_skip " MISSING" 642 echo "FOUND at " "$(dirname "$HAVE_INITDB")" 643 INITDB_BIN=$(echo "$HAVE_INITDB" | grep bin/initdb | grep postgres | sort -n | tail -n1) 644 fi 645 echo -n "Setting up Postgres DB" 646 POSTGRES_PATH=$(dirname "$INITDB_BIN") 647 TMPDIR="${MY_TMP_DIR}/postgres/" 648 mkdir -p "$TMPDIR" 649 echo -n "Setting up Postgres DB at $TMPDIR ..." 650 "$INITDB_BIN" \ 651 --no-sync \ 652 --auth=trust \ 653 -D "${TMPDIR}" \ 654 > "${MY_TMP_DIR}/postgres-dbinit.log" \ 655 2> "${MY_TMP_DIR}/postgres-dbinit.err" 656 echo " DONE" 657 mkdir "${TMPDIR}/sockets" 658 echo -n "Launching Postgres service at $POSTGRES_PATH" 659 cat - >> "$TMPDIR/postgresql.conf" <<EOF 660 unix_socket_directories='${TMPDIR}/sockets' 661 fsync=off 662 max_wal_senders=0 663 synchronous_commit=off 664 wal_level=minimal 665 listen_addresses='' 666 EOF 667 grep -v host \ 668 < "$TMPDIR/pg_hba.conf" \ 669 > "$TMPDIR/pg_hba.conf.new" 670 mv "$TMPDIR/pg_hba.conf.new" "$TMPDIR/pg_hba.conf" 671 "${POSTGRES_PATH}/pg_ctl" \ 672 -D "$TMPDIR" \ 673 -l /dev/null \ 674 start \ 675 > "${MY_TMP_DIR}/postgres-start.log" \ 676 2> "${MY_TMP_DIR}/postgres-start.err" 677 echo " DONE" 678 PGHOST="$TMPDIR/sockets" 679 export PGHOST 680 } 681 682 683 # *************** Main logic starts here ************** 684 685 # ####### Setup globals ###### 686 # Postgres database to use 687 DB=revoke-basedb 688 689 690 # test required commands exist 691 echo "Testing for jq" 692 jq -h > /dev/null || exit_skip "jq required" 693 echo "Testing for faketime" 694 faketime -h > /dev/null \ 695 || exit_skip "faketime required" 696 echo "Testing for libeufin-bank" 697 libeufin-bank --help \ 698 >/dev/null \ 699 2> /dev/null \ 700 </dev/null \ 701 || exit_skip "libeufin-bank required" 702 echo "Testing for taler-wallet-cli" 703 taler-wallet-cli -h \ 704 >/dev/null \ 705 </dev/null \ 706 2>/dev/null \ 707 || exit_skip "taler-wallet-cli required" 708 709 echo "Testing for taler-merchant-config" 710 taler-merchant-config -h > /dev/null || exit_skip "taler-merchant-config required" 711 echo "Testing for taler-merchant-httpd" 712 taler-merchant-httpd -h > /dev/null || exit_skip "taler-merchant-httpd required" 713 714 MY_TMP_DIR=$(mktemp -d /tmp/taler-auditor-basedbXXXXXX) 715 export MY_TMP_DIR 716 echo "Using $MY_TMP_DIR for logging and temporary data" 717 718 echo -n "Testing for Postgres " 719 [ $(id -u) == 0 ] || perform_dbinit 720 721 722 MYDIR="${MY_TMP_DIR}/basedb" 723 mkdir -p "${MYDIR}" 724 725 # Generating the reference database is by far the slowest part of this 726 # test. Set REUSE_BASEDB_DIR to the directory printed at the end of a 727 # previous run to audit that database again instead of regenerating it. 728 if [ -z "${REUSE_BASEDB_DIR+x}" ] 729 then 730 echo "Generating fresh database at $MYDIR" 731 set +e 732 faketime -f '-1 d' ./generate-revoke-basedb.sh "$MYDIR/$DB" 733 GENSTATUS=$? 734 set -e 735 if [ 77 = "$GENSTATUS" ] 736 then 737 # Prerequisite missing (currently: taler-wallet-cli does not 738 # implement the batch recoup protocol, see #9828); report as 739 # skipped, not as a failure. 740 echo "SKIPPING: could not generate the revocation database" 741 exit 77 742 fi 743 if [ 0 != "$GENSTATUS" ] 744 then 745 echo "Generation failed" 746 exit 1 747 fi 748 echo "To reuse this database in the future, use:" 749 echo "export REUSE_BASEDB_DIR=$MY_TMP_DIR" 750 else 751 echo "Reusing existing database from ${REUSE_BASEDB_DIR}" 752 cp -r "${REUSE_BASEDB_DIR}/basedb"/* "${MYDIR}/" 753 fi 754 755 check_with_database "$MYDIR/$DB" 756 if [ "x$fail" != "x0" ] 757 then 758 exit "$fail" 759 fi 760 761 if [ -z "${REUSE_BASEDB_DIR+x}" ] 762 then 763 echo "Run 'export REUSE_BASEDB_DIR=${MY_TMP_DIR}' to re-run tests against the same database" 764 fi 765 766 exit 0