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