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