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 (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