exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

test-revocation.sh (22573B)


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