remove old tests, superseded by the JS-based harness
This commit is contained in:
parent
e9ed3b1867
commit
db65f0a206
3
integrationtests/.gitignore
vendored
3
integrationtests/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
*.log
|
|
||||||
*-prod.conf
|
|
||||||
*.wallet.json
|
|
@ -1,229 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
function setup_config() {
|
|
||||||
echo -n "Testing for taler-bank-manage"
|
|
||||||
taler-bank-manage -h >/dev/null </dev/null || exit_skip " MISSING"
|
|
||||||
echo " FOUND"
|
|
||||||
echo -n "Testing for taler-wallet-cli"
|
|
||||||
taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING"
|
|
||||||
echo " FOUND"
|
|
||||||
echo -n "Testing for taler-merchant-httpd"
|
|
||||||
# TODO "taler-merchant-httpd -v" should not return an error
|
|
||||||
[[ "$(taler-merchant-httpd -v)" =~ "taler-merchant-httpd v" ]] || exit_skip " MISSING"
|
|
||||||
echo " FOUND"
|
|
||||||
bc -v >/dev/null </dev/null || exit_error "Please install bc"
|
|
||||||
|
|
||||||
trap shutdown_services EXIT
|
|
||||||
|
|
||||||
SCRIPT_NAME=$1
|
|
||||||
|
|
||||||
# Where do we write the result?
|
|
||||||
export BASEDB=${1:-"auditor-${SCRIPT_NAME}db"}
|
|
||||||
|
|
||||||
# Name of the Postgres database we will use for the script.
|
|
||||||
# Will be dropped, do NOT use anything that might be used
|
|
||||||
# elsewhere
|
|
||||||
export TARGET_DB=taler-auditor-${SCRIPT_NAME}db
|
|
||||||
|
|
||||||
# Configuration file will be edited, so we create one
|
|
||||||
# from the template.
|
|
||||||
export CONF=test-${SCRIPT_NAME}.conf
|
|
||||||
cp template.conf "$CONF"
|
|
||||||
|
|
||||||
export LOG=test-${SCRIPT_NAME}.log
|
|
||||||
rm "$LOG" 2>/dev/null || true
|
|
||||||
|
|
||||||
export WALLET_DB=wallet-${SCRIPT_NAME}.json
|
|
||||||
rm "$WALLET_DB" 2>/dev/null || true
|
|
||||||
|
|
||||||
# Clean up
|
|
||||||
DATA_DIR=$(taler-config -f -c "$CONF" -s PATHS -o TALER_HOME)
|
|
||||||
rm -rf "$DATA_DIR" || true
|
|
||||||
|
|
||||||
# reset database
|
|
||||||
dropdb "$TARGET_DB" >/dev/null 2>/dev/null || true
|
|
||||||
createdb "$TARGET_DB" || exit_skip "Could not create database $TARGET_DB"
|
|
||||||
|
|
||||||
# obtain key configuration data
|
|
||||||
MASTER_PRIV_FILE=$(taler-config -f -c "$CONF" -s EXCHANGE -o MASTER_PRIV_FILE)
|
|
||||||
MASTER_PRIV_DIR=$(dirname "$MASTER_PRIV_FILE")
|
|
||||||
mkdir -p "$MASTER_PRIV_DIR"
|
|
||||||
gnunet-ecc -g1 "$MASTER_PRIV_FILE" >/dev/null
|
|
||||||
MASTER_PUB=$(gnunet-ecc -p "$MASTER_PRIV_FILE")
|
|
||||||
EXCHANGE_URL=$(taler-config -c "$CONF" -s EXCHANGE -o BASE_URL)
|
|
||||||
MERCHANT_PORT=$(taler-config -c "$CONF" -s MERCHANT -o PORT)
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
MERCHANT_URL=http://localhost:${MERCHANT_PORT}/
|
|
||||||
BANK_PORT=$(taler-config -c "$CONF" -s BANK -o HTTP_PORT)
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
BANK_URL=http://localhost:${BANK_PORT}/
|
|
||||||
AUDITOR_URL=http://localhost:8083/
|
|
||||||
|
|
||||||
# patch configuration
|
|
||||||
taler-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY -V "$MASTER_PUB"
|
|
||||||
taler-config -c "$CONF" -s merchant-exchange-default -o MASTER_KEY -V "$MASTER_PUB"
|
|
||||||
taler-config -c "$CONF" -s exchangedb-postgres -o CONFIG -V "postgres:///$TARGET_DB"
|
|
||||||
taler-config -c "$CONF" -s auditordb-postgres -o CONFIG -V "postgres:///$TARGET_DB"
|
|
||||||
taler-config -c "$CONF" -s merchantdb-postgres -o CONFIG -V "postgres:///$TARGET_DB"
|
|
||||||
taler-config -c "$CONF" -s bank -o database -V "postgres:///$TARGET_DB"
|
|
||||||
}
|
|
||||||
|
|
||||||
function setup_services() {
|
|
||||||
# setup exchange
|
|
||||||
echo "Setting up exchange"
|
|
||||||
taler-exchange-dbinit -c "$CONF"
|
|
||||||
taler-exchange-wire -c "$CONF" 2>taler-exchange-wire.log
|
|
||||||
taler-exchange-keyup -L INFO -c "$CONF" -o e2a.dat 2>taler-exchange-keyup.log
|
|
||||||
|
|
||||||
# setup auditor
|
|
||||||
echo "Setting up auditor"
|
|
||||||
taler-auditor-dbinit -c "$CONF"
|
|
||||||
taler-auditor-exchange -c "$CONF" -m "$MASTER_PUB" -u "$EXCHANGE_URL"
|
|
||||||
taler-auditor-sign -c "$CONF" -u $AUDITOR_URL -r e2a.dat -o a2e.dat -m "$MASTER_PUB"
|
|
||||||
rm -f e2a.dat
|
|
||||||
|
|
||||||
# provide auditor's signature to exchange
|
|
||||||
ABD=$(taler-config -c "$CONF" -s EXCHANGEDB -o AUDITOR_BASE_DIR -f)
|
|
||||||
mkdir -p "$ABD"
|
|
||||||
mv a2e.dat "$ABD"
|
|
||||||
}
|
|
||||||
|
|
||||||
function launch_services() {
|
|
||||||
# Launch services
|
|
||||||
echo "Launching services"
|
|
||||||
taler-bank-manage-testing "$CONF" "postgres:///$TARGET_DB" serve-http &>bank-"$SCRIPT_NAME".log &
|
|
||||||
taler-exchange-httpd -c "$CONF" 2>taler-exchange-httpd.log &
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
EXCHANGE_PID=$!
|
|
||||||
taler-merchant-httpd -c "$CONF" -L INFO 2>taler-merchant-httpd.log &
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
MERCHANT_PID=$!
|
|
||||||
taler-exchange-wirewatch -c "$CONF" 2>taler-exchange-wirewatch.log &
|
|
||||||
taler-auditor-httpd -c "$CONF" 2>taler-auditor-httpd.log &
|
|
||||||
}
|
|
||||||
|
|
||||||
function wait_for_services() {
|
|
||||||
# Wait for bank to be available (usually the slowest)
|
|
||||||
for _ in $(seq 1 50); do
|
|
||||||
echo -n "."
|
|
||||||
sleep 0.2
|
|
||||||
OK=0
|
|
||||||
wget "$BANK_URL" -o /dev/null -O /dev/null >/dev/null || continue
|
|
||||||
OK=1
|
|
||||||
break
|
|
||||||
done
|
|
||||||
if [ 1 != $OK ]; then
|
|
||||||
exit_skip "Failed to launch bank"
|
|
||||||
fi
|
|
||||||
# Wait for all other services to be available
|
|
||||||
for _ in $(seq 1 50); do
|
|
||||||
echo -n "."
|
|
||||||
sleep 0.1
|
|
||||||
OK=0
|
|
||||||
wget "$EXCHANGE_URL" -o /dev/null -O /dev/null >/dev/null || continue
|
|
||||||
wget "$MERCHANT_URL" -o /dev/null -O /dev/null >/dev/null || continue
|
|
||||||
wget "$AUDITOR_URL" -o /dev/null -O /dev/null >/dev/null || continue
|
|
||||||
OK=1
|
|
||||||
break
|
|
||||||
done
|
|
||||||
if [ 1 != $OK ]; then
|
|
||||||
shutdown_services
|
|
||||||
exit_skip "Failed to launch services"
|
|
||||||
fi
|
|
||||||
echo " DONE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Configure merchant instances
|
|
||||||
function configure_merchant() {
|
|
||||||
json='
|
|
||||||
{
|
|
||||||
"id": "default",
|
|
||||||
"name": "GNU Taler Merchant",
|
|
||||||
"payto_uris": ["payto://x-taler-bank/test_merchant"],
|
|
||||||
"address": {},
|
|
||||||
"jurisdiction": {},
|
|
||||||
"default_max_wire_fee": "TESTKUDOS:1",
|
|
||||||
"default_wire_fee_amortization": 3,
|
|
||||||
"default_max_deposit_fee": "TESTKUDOS:1",
|
|
||||||
"default_wire_transfer_delay": {"d_ms": "forever"},
|
|
||||||
"default_pay_delay": {"d_ms": "forever"}
|
|
||||||
}
|
|
||||||
'
|
|
||||||
curl -v -XPOST --data "$json" "${MERCHANT_URL}private/instances"
|
|
||||||
}
|
|
||||||
|
|
||||||
function normal_start_and_wait() {
|
|
||||||
setup_config "$1"
|
|
||||||
setup_services
|
|
||||||
launch_services
|
|
||||||
wait_for_services
|
|
||||||
configure_merchant
|
|
||||||
}
|
|
||||||
|
|
||||||
# provide the service URL as first parameter
|
|
||||||
function wait_for_service() {
|
|
||||||
for _ in $(seq 1 50); do
|
|
||||||
echo -n "."
|
|
||||||
sleep 0.1
|
|
||||||
wget "$1" -o /dev/null -O /dev/null >/dev/null || continue
|
|
||||||
echo " DONE"
|
|
||||||
break
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_balance() {
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" balance 2>>"$LOG"
|
|
||||||
}
|
|
||||||
|
|
||||||
function assert_less_than() {
|
|
||||||
AMOUNT_1=${1//TESTKUDOS:/}
|
|
||||||
AMOUNT_2=${2//TESTKUDOS:/}
|
|
||||||
if (($(echo "$AMOUNT_1 >= $AMOUNT_2" | bc -l))); then
|
|
||||||
exit_error "$1 is not lower than $2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function assert_greater_than() {
|
|
||||||
AMOUNT_1=${1//TESTKUDOS:/}
|
|
||||||
AMOUNT_2=${2//TESTKUDOS:/}
|
|
||||||
if (($(echo "$AMOUNT_1 <= $AMOUNT_2" | bc -l))); then
|
|
||||||
exit_error "$1 is not greater than $2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function assert_equal() {
|
|
||||||
[[ "$1" == "$2" ]] || exit_error "$1 is not equal to $2"
|
|
||||||
}
|
|
||||||
|
|
||||||
function shutdown_services() {
|
|
||||||
echo "Shutting down services"
|
|
||||||
jobs -p | xargs --no-run-if-empty kill || true
|
|
||||||
wait
|
|
||||||
|
|
||||||
# clean up
|
|
||||||
echo "Final clean up"
|
|
||||||
dropdb "$TARGET_DB" >/dev/null 2>/dev/null || true
|
|
||||||
|
|
||||||
rm "$WALLET_DB" 2>/dev/null || true
|
|
||||||
|
|
||||||
rm -rf "$DATA_DIR" || true
|
|
||||||
rm "$CONF"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Exit, with status code "skip" (no 'real' failure)
|
|
||||||
function exit_skip() {
|
|
||||||
echo "$1"
|
|
||||||
exit 77
|
|
||||||
}
|
|
||||||
|
|
||||||
function exit_error() {
|
|
||||||
echo -e "\033[0;31mError: $1\033[0m"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function exit_success() {
|
|
||||||
echo -e "\033[0;32mSUCCESS \o/\033[0m"
|
|
||||||
exit 0
|
|
||||||
}
|
|
@ -1,227 +0,0 @@
|
|||||||
[exchange]
|
|
||||||
KEYDIR = ${TALER_DATA_HOME}/exchange/live-keys/
|
|
||||||
REVOCATION_DIR = ${TALER_DATA_HOME}/exchange/revocations/
|
|
||||||
MAX_KEYS_CACHING = forever
|
|
||||||
DB = postgres
|
|
||||||
MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv
|
|
||||||
SERVE = tcp
|
|
||||||
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
|
||||||
UNIXPATH_MODE = 660
|
|
||||||
PORT = 8081
|
|
||||||
BASE_URL = http://localhost:8081/
|
|
||||||
SIGNKEY_DURATION = 4 weeks
|
|
||||||
LEGAL_DURATION = 2 years
|
|
||||||
LOOKAHEAD_SIGN = 32 weeks 1 day
|
|
||||||
LOOKAHEAD_PROVIDE = 4 weeks 1 day
|
|
||||||
|
|
||||||
[merchant]
|
|
||||||
SERVE = tcp
|
|
||||||
PORT = 9966
|
|
||||||
UNIXPATH = ${TALER_RUNTIME_DIR}/merchant.http
|
|
||||||
UNIXPATH_MODE = 660
|
|
||||||
DEFAULT_WIRE_FEE_AMORTIZATION = 1
|
|
||||||
DB = postgres
|
|
||||||
WIREFORMAT = default
|
|
||||||
# Set very low, so we can be sure that the database generated
|
|
||||||
# will contain wire transfers "ready" for the aggregator.
|
|
||||||
WIRE_TRANSFER_DELAY = 1 minute
|
|
||||||
DEFAULT_PAY_DEADLINE = 1 day
|
|
||||||
DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1
|
|
||||||
KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv
|
|
||||||
DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10
|
|
||||||
|
|
||||||
# Ensure that merchant reports EVERY deposit confirmation to auditor
|
|
||||||
FORCE_AUDIT = YES
|
|
||||||
|
|
||||||
[instance-default]
|
|
||||||
KEYFILE = ${TALER_DATA_HOME}/merchant/default.priv
|
|
||||||
NAME = Merchant Inc.
|
|
||||||
TIP_EXCHANGE = http://localhost:8081/
|
|
||||||
# TODO necessary to specify a different key here?
|
|
||||||
TIP_RESERVE_PRIV_FILENAME = ${TALER_DATA_HOME}/merchant/default.priv
|
|
||||||
|
|
||||||
[auditor]
|
|
||||||
DB = postgres
|
|
||||||
AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv
|
|
||||||
SERVE = tcp
|
|
||||||
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
|
||||||
UNIXPATH_MODE = 660
|
|
||||||
PORT = 8083
|
|
||||||
AUDITOR_URL = http://localhost:8083/
|
|
||||||
TINY_AMOUNT = TESTKUDOS:0.01
|
|
||||||
|
|
||||||
[PATHS]
|
|
||||||
TALER_HOME = ${PWD}/generate_auditordb_home/
|
|
||||||
TALER_DATA_HOME = $TALER_HOME/.local/share/taler/
|
|
||||||
TALER_CONFIG_HOME = $TALER_HOME/.config/taler/
|
|
||||||
TALER_CACHE_HOME = $TALER_HOME/.cache/taler/
|
|
||||||
TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/taler-system-runtime/
|
|
||||||
|
|
||||||
[bank]
|
|
||||||
DATABASE = postgres:///taler-auditor-basedb
|
|
||||||
MAX_DEBT = TESTKUDOS:50.0
|
|
||||||
MAX_DEBT_BANK = TESTKUDOS:100000.0
|
|
||||||
HTTP_PORT = 8082
|
|
||||||
SUGGESTED_EXCHANGE = http://localhost:8081/
|
|
||||||
SUGGESTED_EXCHANGE_PAYTO = payto://x-taler-bank/localhost/2
|
|
||||||
ALLOW_REGISTRATIONS = YES
|
|
||||||
|
|
||||||
[exchangedb]
|
|
||||||
AUDITOR_BASE_DIR = ${TALER_DATA_HOME}/auditors/
|
|
||||||
WIREFEE_BASE_DIR = ${TALER_DATA_HOME}/exchange/wirefees/
|
|
||||||
IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
|
|
||||||
LEGAL_RESERVE_EXPIRATION_TIME = 7 years
|
|
||||||
|
|
||||||
[exchange_keys]
|
|
||||||
signkey_duration = 4 weeks
|
|
||||||
legal_duration = 2 years
|
|
||||||
lookahead_sign = 32 weeks 1 day
|
|
||||||
lookahead_provide = 4 weeks 1 day
|
|
||||||
|
|
||||||
[taler]
|
|
||||||
CURRENCY = TESTKUDOS
|
|
||||||
CURRENCY_ROUND_UNIT = TESTKUDOS:0.01
|
|
||||||
|
|
||||||
[exchange-account-1]
|
|
||||||
WIRE_RESPONSE = ${TALER_DATA_HOME}/exchange/account-1.json
|
|
||||||
PAYTO_URI = payto://x-taler-bank/localhost/Exchange
|
|
||||||
enable_debit = yes
|
|
||||||
enable_credit = yes
|
|
||||||
WIRE_GATEWAY_URL = "http://localhost:8082/taler-wire-gateway/Exchange/"
|
|
||||||
WIRE_GATEWAY_AUTH_METHOD = basic
|
|
||||||
USERNAME = Exchange
|
|
||||||
PASSWORD = x
|
|
||||||
|
|
||||||
[merchant-account-merchant]
|
|
||||||
PAYTO_URI = payto://x-taler-bank/localhost/42
|
|
||||||
WIRE_RESPONSE = ${TALER_CONFIG_HOME}/merchant/account-3.json
|
|
||||||
HONOR_default = YES
|
|
||||||
ACTIVE_default = YES
|
|
||||||
|
|
||||||
[fees-x-taler-bank]
|
|
||||||
wire-fee-2020 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2020 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2021 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2021 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2022 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2022 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2023 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2023 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2024 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2024 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2025 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2025 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2026 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2026 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2027 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2027 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2028 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2028 = TESTKUDOS:0.01
|
|
||||||
|
|
||||||
[merchant-instance-wireformat-default]
|
|
||||||
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/tutorial.json
|
|
||||||
|
|
||||||
[merchant-exchange-default]
|
|
||||||
EXCHANGE_BASE_URL = http://localhost:8081/
|
|
||||||
CURRENCY = TESTKUDOS
|
|
||||||
|
|
||||||
[payments-generator]
|
|
||||||
currency = TESTKUDOS
|
|
||||||
instance = default
|
|
||||||
bank = http://localhost:8082/
|
|
||||||
merchant = http://localhost:9966/
|
|
||||||
exchange_admin = http://localhost:18080/
|
|
||||||
exchange-admin = http://localhost:18080/
|
|
||||||
exchange = http://localhost:8081/
|
|
||||||
|
|
||||||
[coin_kudos_ct_1]
|
|
||||||
value = TESTKUDOS:0.01
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.01
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_ct_10]
|
|
||||||
value = TESTKUDOS:0.10
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_1]
|
|
||||||
value = TESTKUDOS:1
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.02
|
|
||||||
fee_deposit = TESTKUDOS:0.02
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_2]
|
|
||||||
value = TESTKUDOS:2
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.03
|
|
||||||
fee_deposit = TESTKUDOS:0.03
|
|
||||||
fee_refresh = TESTKUDOS:0.04
|
|
||||||
fee_refund = TESTKUDOS:0.02
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_4]
|
|
||||||
value = TESTKUDOS:4
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.03
|
|
||||||
fee_deposit = TESTKUDOS:0.03
|
|
||||||
fee_refresh = TESTKUDOS:0.04
|
|
||||||
fee_refund = TESTKUDOS:0.02
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_5]
|
|
||||||
value = TESTKUDOS:5
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_8]
|
|
||||||
value = TESTKUDOS:8
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.05
|
|
||||||
fee_deposit = TESTKUDOS:0.02
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.04
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_10]
|
|
||||||
value = TESTKUDOS:10
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[benchmark]
|
|
||||||
BANK_DETAILS = bank_details.json
|
|
||||||
MERCHANT_DETAILS = merchant_details.json
|
|
@ -1,13 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to generate the basic database for auditor
|
|
||||||
# testing from a 'correct' interaction between exchange,
|
|
||||||
# wallet and merchant.
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "base"
|
|
||||||
|
|
||||||
# run wallet CLI
|
|
||||||
echo "Running wallet"
|
|
||||||
taler-wallet-cli testing integrationtest -e "$EXCHANGE_URL" -m "$MERCHANT_URL" -b "$BANK_URL"
|
|
||||||
|
|
||||||
exit_success
|
|
@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to check that the wallet automatically refreshes coins for they expire
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "coin-expiration"
|
|
||||||
|
|
||||||
echo "Withdraw TESTKUDOS"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing withdraw -e "$EXCHANGE_URL" -b "$BANK_URL" -a "TESTKUDOS:10" >>"$LOG" 2>>"$LOG"
|
|
||||||
echo "Balance after withdrawal: $(get_balance)"
|
|
||||||
|
|
||||||
# TODO time-travel to check that wallet actually refreshed coin before expiration
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" advanced dump-coins
|
|
||||||
|
|
||||||
exit_success
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to check that Uris are properly handled when used a second time
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "double-link"
|
|
||||||
|
|
||||||
echo "Getting pay taler:// Uri"
|
|
||||||
PAY_URI=$(taler-wallet-cli testing gen-pay-uri -m "$MERCHANT_URL" -k sandbox -a "TESTKUDOS:1" -s "foo" | grep -E -o 'taler://.*')
|
|
||||||
echo "Trying to pay without balance"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri --yes "$PAY_URI" 2>&1 | grep -q "insufficient balance" || exit_error "not reporting insufficient balance"
|
|
||||||
echo "Withdrawing"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing withdraw -e "$EXCHANGE_URL" -b "$BANK_URL" -a "TESTKUDOS:10" > /dev/null
|
|
||||||
echo "Trying to pay again, should work this time"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri --yes "$PAY_URI" > /dev/null
|
|
||||||
echo "Trying to pay what was paid already should throw error"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri --yes "$PAY_URI" 2>&1 | grep -q "already paid" || exit_error "not reporting already paid"
|
|
||||||
echo "Already paid properly detected"
|
|
||||||
|
|
||||||
exit_success
|
|
@ -1,22 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to check that the wallet can not double spend coins and handles this error well
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "double-spend"
|
|
||||||
|
|
||||||
echo "Withdraw TESTKUDOS"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing withdraw -e "$EXCHANGE_URL" -b "$BANK_URL" -a "TESTKUDOS:10" >/dev/null
|
|
||||||
# Copy wallet database before spending coins
|
|
||||||
cp "$WALLET_DB" "$WALLET_DB.bak"
|
|
||||||
echo "Spend all the money"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" testing test-pay -m "$MERCHANT_URL" -k sandbox -a "TESTKUDOS:9.5" -s "foo"
|
|
||||||
echo "New balance: $(get_balance)"
|
|
||||||
# Restore old wallet database
|
|
||||||
mv "$WALLET_DB.bak" "$WALLET_DB"
|
|
||||||
echo "Balance after getting old coins back: $(get_balance)"
|
|
||||||
echo "Try to double-spend"
|
|
||||||
# TODO this should probably fail more gracefully
|
|
||||||
# "exchange_reply: { hint: 'insufficient funds', code: 1200 }
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" testing test-pay -m "$MERCHANT_URL" -k sandbox -a "TESTKUDOS:9.5" -s "foo"
|
|
||||||
|
|
||||||
exit_success
|
|
@ -1,178 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to test revocation.
|
|
||||||
#
|
|
||||||
# Requires the wallet CLI to be installed and in the path. Furthermore, the
|
|
||||||
# user running this script must be Postgres superuser and be allowed to
|
|
||||||
# create/drop databases.
|
|
||||||
# Also the jq utility needs to be installed
|
|
||||||
|
|
||||||
echo -n "Testing for jq"
|
|
||||||
jq --version >/dev/null </dev/null || exit_skip " MISSING"
|
|
||||||
echo " FOUND"
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
setup_config "recoup"
|
|
||||||
|
|
||||||
TMP_DIR=$(mktemp -d revocation-tmp-XXXXXX)
|
|
||||||
|
|
||||||
taler-config -c "$CONF" -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/"
|
|
||||||
taler-config -c "$CONF" -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/"
|
|
||||||
|
|
||||||
setup_services
|
|
||||||
launch_services
|
|
||||||
wait_for_services
|
|
||||||
|
|
||||||
# run wallet CLI
|
|
||||||
echo "Running wallet"
|
|
||||||
taler-wallet-cli --wallet-db=$WALLET_DB --no-throttle \
|
|
||||||
testing withdraw \
|
|
||||||
-e $EXCHANGE_URL \
|
|
||||||
-b $BANK_URL \
|
|
||||||
-a TESTKUDOS:8
|
|
||||||
|
|
||||||
|
|
||||||
export coins=$(taler-wallet-cli --wallet-db=$WALLET_DB advanced dump-coins)
|
|
||||||
|
|
||||||
# Find coin we want to revoke
|
|
||||||
export rc=$(echo "$coins" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:2"))][0] | .coin_pub')
|
|
||||||
# Find the denom
|
|
||||||
export rd=$(echo "$coins" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:2"))][0] | .denom_pub_hash')
|
|
||||||
echo "Revoking denomination ${rd} (to affect coin ${rc})"
|
|
||||||
# Find all other coins, which will be suspended
|
|
||||||
export susp=$(echo "$coins" | jq --arg rc "$rc" '[.coins[] | select(.coin_pub != $rc) | .coin_pub]')
|
|
||||||
|
|
||||||
# Do the revocation
|
|
||||||
taler-exchange-keyup -o e2a2.dat -c $CONF -r $rd
|
|
||||||
taler-auditor-sign -c $CONF -u $AUDITOR_URL -r e2a2.dat -o a2e2.dat -m $MASTER_PUB
|
|
||||||
rm e2a2.dat
|
|
||||||
mv a2e2.dat $ABD
|
|
||||||
|
|
||||||
# Restart the exchange...
|
|
||||||
kill -SIGUSR1 $EXCHANGE_PID
|
|
||||||
sleep 1 # Give exchange time to re-scan data
|
|
||||||
echo "Restarted the exchange post revocation"
|
|
||||||
|
|
||||||
# Now we suspend the other coins, so later we will pay with the recouped coin
|
|
||||||
taler-wallet-cli --wallet-db=$WALLET_DB advanced suspend-coins "$susp"
|
|
||||||
|
|
||||||
# Update exchange /keys so recoup gets scheduled
|
|
||||||
taler-wallet-cli --wallet-db=$WALLET_DB exchanges update \
|
|
||||||
-f $EXCHANGE_URL
|
|
||||||
|
|
||||||
# Block until scheduled operations are done
|
|
||||||
taler-wallet-cli --wallet-db=$WALLET_DB run-until-done
|
|
||||||
|
|
||||||
# Now we buy something, only the coins resulting from recouped will be
|
|
||||||
# used, as other ones are suspended
|
|
||||||
taler-wallet-cli --wallet-db=$WALLET_DB testing test-pay \
|
|
||||||
-m $MERCHANT_URL -k sandbox \
|
|
||||||
-a "TESTKUDOS:1" -s "foo"
|
|
||||||
taler-wallet-cli --wallet-db=$WALLET_DB run-until-done
|
|
||||||
|
|
||||||
echo "Purchase with recoup'ed coin (via reserve) done"
|
|
||||||
|
|
||||||
# Find coin we want to refresh, then revoke
|
|
||||||
export rrc=$(echo "$coins" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:5"))][0] | .coin_pub')
|
|
||||||
# Find the denom
|
|
||||||
export zombie_denom=$(echo "$coins" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:5"))][0] | .denom_pub_hash')
|
|
||||||
|
|
||||||
echo "Will refresh coin ${rrc} of denomination ${zombie_denom}"
|
|
||||||
# Find all other coins, which will be suspended
|
|
||||||
export susp=$(echo "$coins" | jq --arg rrc "$rrc" '[.coins[] | select(.coin_pub != $rrc) | .coin_pub]')
|
|
||||||
|
|
||||||
export rrc
|
|
||||||
export zombie_denom
|
|
||||||
|
|
||||||
# Travel into the future! (must match DURATION_WITHDRAW option)
|
|
||||||
export TIMETRAVEL="--timetravel=604800000000"
|
|
||||||
|
|
||||||
echo "Launching exchange 1 week in the future"
|
|
||||||
kill -TERM $EXCHANGE_PID
|
|
||||||
taler-exchange-httpd $TIMETRAVEL -c $CONF 2> taler-exchange-httpd.log &
|
|
||||||
export EXCHANGE_PID=$!
|
|
||||||
|
|
||||||
# Wait for exchange to be available
|
|
||||||
for n in `seq 1 50`
|
|
||||||
do
|
|
||||||
echo -n "."
|
|
||||||
sleep 0.1
|
|
||||||
OK=0
|
|
||||||
# exchange
|
|
||||||
wget http://localhost:8081/ -o /dev/null -O /dev/null >/dev/null || continue
|
|
||||||
OK=1
|
|
||||||
break
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Refreshing coin $rrc"
|
|
||||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB advanced force-refresh "$rrc"
|
|
||||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB run-until-done
|
|
||||||
|
|
||||||
# Update our list of the coins
|
|
||||||
export coins=$(taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB advanced dump-coins)
|
|
||||||
|
|
||||||
# Find resulting refreshed coin
|
|
||||||
export freshc=$(echo "$coins" | jq -r --arg rrc "$rrc" \
|
|
||||||
'[.coins[] | select((.refresh_parent_coin_pub == $rrc) and .denom_value == "TESTKUDOS:0.1")][0] | .coin_pub'
|
|
||||||
)
|
|
||||||
|
|
||||||
# Find the denom of freshc
|
|
||||||
export fresh_denom=$(echo "$coins" | jq -r --arg rrc "$rrc" \
|
|
||||||
'[.coins[] | select((.refresh_parent_coin_pub == $rrc) and .denom_value == "TESTKUDOS:0.1")][0] | .denom_pub_hash'
|
|
||||||
)
|
|
||||||
|
|
||||||
echo "Coin ${freshc} of denomination ${fresh_denom} is the result of the refresh"
|
|
||||||
|
|
||||||
# Find all other coins, which will be suspended
|
|
||||||
export susp=$(echo "$coins" | jq --arg freshc "$freshc" '[.coins[] | select(.coin_pub != $freshc) | .coin_pub]')
|
|
||||||
|
|
||||||
|
|
||||||
# Do the revocation of freshc
|
|
||||||
echo "Revoking ${fresh_denom} (to affect coin ${freshc})"
|
|
||||||
taler-exchange-keyup -c $CONF -o e2a3.dat -r $fresh_denom
|
|
||||||
taler-auditor-sign -c $CONF -u $AUDITOR_URL -r e2a3.dat -o a2e3.dat -m $MASTER_PUB
|
|
||||||
rm e2a3.dat
|
|
||||||
mv a2e3.dat $ABD
|
|
||||||
|
|
||||||
# Restart the exchange...
|
|
||||||
kill -SIGUSR1 $EXCHANGE_PID
|
|
||||||
sleep 1 # give exchange time to re-scan data
|
|
||||||
|
|
||||||
|
|
||||||
# Now we suspend the other coins, so later we will pay with the recouped coin
|
|
||||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB advanced suspend-coins "$susp"
|
|
||||||
|
|
||||||
# Update exchange /keys so recoup gets scheduled
|
|
||||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB exchanges update \
|
|
||||||
-f $EXCHANGE_URL
|
|
||||||
|
|
||||||
# Block until scheduled operations are done
|
|
||||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB run-until-done
|
|
||||||
|
|
||||||
echo "Restarting merchant (so new keys are known)"
|
|
||||||
kill -TERM $MERCHANT_PID
|
|
||||||
taler-merchant-httpd -c $CONF -L INFO 2> taler-merchant-httpd.log &
|
|
||||||
MERCHANT_PID=$!
|
|
||||||
# Wait for merchant to be again available
|
|
||||||
for n in `seq 1 50`
|
|
||||||
do
|
|
||||||
echo -n "."
|
|
||||||
sleep 0.1
|
|
||||||
OK=0
|
|
||||||
# merchant
|
|
||||||
wget http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue
|
|
||||||
OK=1
|
|
||||||
break
|
|
||||||
done
|
|
||||||
|
|
||||||
# Now we buy something, only the coins resulting from recoup+refresh will be
|
|
||||||
# used, as other ones are suspended
|
|
||||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB testing test-pay \
|
|
||||||
-m $MERCHANT_URL -k sandbox \
|
|
||||||
-a "TESTKUDOS:0.02" -s "bar"
|
|
||||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB run-until-done
|
|
||||||
|
|
||||||
echo "SUCCESS: Bought something with refresh-recouped coin"
|
|
||||||
|
|
||||||
rm -r "$TMP_DIR"
|
|
||||||
|
|
||||||
exit 0
|
|
@ -1,26 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to check that the wallet can handle refund URIs and actually process the refund
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "refund"
|
|
||||||
|
|
||||||
echo "Withdraw TESTKUDOS"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing withdraw -e "$EXCHANGE_URL" -b "$BANK_URL" -a "TESTKUDOS:10" >>"$LOG" 2>>"$LOG"
|
|
||||||
BALANCE_1=$(get_balance)
|
|
||||||
echo "Balance after withdrawal: $BALANCE_1"
|
|
||||||
REFUND_URI=$(taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing gen-refund-uri \
|
|
||||||
-m "$MERCHANT_URL" -k sandbox \
|
|
||||||
-s "first refund" -a "TESTKUDOS:8" -r "TESTKUDOS:2" 2>>"$LOG" | grep -E -m 1 -o "taler://refund.*insecure=1")
|
|
||||||
BALANCE_2=$(get_balance)
|
|
||||||
echo "Balance after payment: $BALANCE_2"
|
|
||||||
assert_less_than "$BALANCE_2" "$BALANCE_1"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" balance 2>>"$LOG"
|
|
||||||
echo "Handling refund: $REFUND_URI"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri "$REFUND_URI" 2>"$LOG"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" run-until-done 2>>"$LOG" >>"$LOG"
|
|
||||||
BALANCE_3=$(get_balance)
|
|
||||||
echo "Balance after first refund: $BALANCE_3"
|
|
||||||
assert_greater_than "$BALANCE_3" "$BALANCE_2"
|
|
||||||
# TODO how to test second refund for same purchase?
|
|
||||||
|
|
||||||
exit_success
|
|
@ -1,47 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to check that the wallet retries operations when services are not reachable
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "retries"
|
|
||||||
|
|
||||||
# TODO try withdrawal when bank is down
|
|
||||||
|
|
||||||
echo "Withdraw TESTKUDOS"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing withdraw -e "$EXCHANGE_URL" -b "$BANK_URL" -a "TESTKUDOS:10" 2>>"$LOG" >>"$LOG"
|
|
||||||
BALANCE_1=$(get_balance)
|
|
||||||
echo "Balance after withdrawal: $BALANCE_1"
|
|
||||||
echo "Getting pay taler:// Uri"
|
|
||||||
PAY_URI=$(taler-wallet-cli testing gen-pay-uri -m "$MERCHANT_URL" -k sandbox -a "TESTKUDOS:1" -s "foo" | grep -E -o 'taler://.*')
|
|
||||||
echo "Trying to pay with exchange down, will fail"
|
|
||||||
kill "$EXCHANGE_PID" && sleep 1
|
|
||||||
ps -p "$EXCHANGE_PID" >"$LOG" && exit_error "exchange still alive"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri --yes "$PAY_URI" 2>>"$LOG" >>"$LOG" && exit_error "could pay with exchange down"
|
|
||||||
echo "Re-launching exchange"
|
|
||||||
taler-exchange-httpd -c "$CONF" 2>taler-exchange-httpd.log &
|
|
||||||
EXCHANGE_PID=$!
|
|
||||||
echo -n "Wait for exchange to start"
|
|
||||||
wait_for_service "$EXCHANGE_URL"
|
|
||||||
echo "Retrying operations with exchange up"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" run-until-done 2>>"$LOG" >>"$LOG"
|
|
||||||
BALANCE_2=$(get_balance)
|
|
||||||
echo "Balance after re-tried payment: $BALANCE_2"
|
|
||||||
assert_less_than "$BALANCE_2" "$BALANCE_1"
|
|
||||||
|
|
||||||
echo "Getting pay taler:// Uri"
|
|
||||||
PAY_URI=$(taler-wallet-cli testing gen-pay-uri -m "$MERCHANT_URL" -k sandbox -a "TESTKUDOS:1" -s "foo" | grep -E -o 'taler://.*')
|
|
||||||
echo "Trying to pay with merchant down, will fail"
|
|
||||||
kill "$MERCHANT_PID" && sleep 1
|
|
||||||
ps -p "$MERCHANT_PID" >"$LOG" && exit_error "merchant still alive"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri --yes "$PAY_URI" 2>>"$LOG" >>"$LOG" && exit_error "could pay with merchant down"
|
|
||||||
echo "Re-launching merchant"
|
|
||||||
taler-merchant-httpd -c "$CONF" -L INFO 2>taler-merchant-httpd.log &
|
|
||||||
MERCHANT_PID=$!
|
|
||||||
echo -n "Wait for merchant to start"
|
|
||||||
wait_for_service "$MERCHANT_URL"
|
|
||||||
echo "Retrying payment with merchant up"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri --yes "$PAY_URI" 2>>"$LOG" >>"$LOG"
|
|
||||||
BALANCE_3=$(get_balance)
|
|
||||||
echo "Balance after re-tried payment: $BALANCE_3"
|
|
||||||
assert_less_than "$BALANCE_3" "$BALANCE_2"
|
|
||||||
|
|
||||||
exit_success
|
|
@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to check that the wallet can handle tip URIs and actually process the tips
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "tip"
|
|
||||||
|
|
||||||
# TODO fund exchange tipping reserve: 404 tipping reserve unknown at exchange
|
|
||||||
TIP_URI=$(taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing gen-tip-uri \
|
|
||||||
-m "$MERCHANT_URL" -k sandbox -a "TESTKUDOS:5" 2>>"$LOG" | grep -E -m 1 -o "taler://tip.*insecure=1")
|
|
||||||
echo -n "Balance after tip: "
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" balance 2>>"$LOG"
|
|
||||||
echo "Handling tip: $TIP_URI"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle handle-uri "$TIP_URI" 2>"$LOG"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" run-until-done 2>>"$LOG" >>"$LOG"
|
|
||||||
echo -n "Balance after first tip: "
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" balance 2>>"$LOG"
|
|
||||||
|
|
||||||
exit_success
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script to check that the wallet does a withdrawal correctly
|
|
||||||
|
|
||||||
source "common.sh"
|
|
||||||
normal_start_and_wait "withdrawal"
|
|
||||||
|
|
||||||
echo "Withdraw 5 TESTKUDOS"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing withdraw -e "$EXCHANGE_URL" -b "$BANK_URL" -a "TESTKUDOS:5" >>"$LOG" 2>>"$LOG"
|
|
||||||
BALANCE_1=$(get_balance)
|
|
||||||
assert_equal "$BALANCE_1" "TESTKUDOS:4.84"
|
|
||||||
echo "Balance after withdrawal: $BALANCE_1"
|
|
||||||
|
|
||||||
echo "Withdraw 10 TESTKUDOS"
|
|
||||||
taler-wallet-cli --wallet-db="$WALLET_DB" --no-throttle testing withdraw -e "$EXCHANGE_URL" -b "$BANK_URL" -a "TESTKUDOS:10" >>"$LOG" 2>>"$LOG"
|
|
||||||
BALANCE_2=$(get_balance)
|
|
||||||
assert_equal "$BALANCE_2" "TESTKUDOS:14.66"
|
|
||||||
echo "Balance after withdrawal: $BALANCE_2"
|
|
||||||
|
|
||||||
exit_success
|
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
__pycache__
|
|
@ -1,23 +0,0 @@
|
|||||||
import json
|
|
||||||
|
|
||||||
from taler.util.amount import Amount
|
|
||||||
|
|
||||||
|
|
||||||
def check_single_balance(
|
|
||||||
balances,
|
|
||||||
available,
|
|
||||||
pending_in=Amount.parse("TESTKUDOS:0"),
|
|
||||||
pending_out=Amount.parse("TESTKUDOS:0"),
|
|
||||||
):
|
|
||||||
assert len(balances) == 1
|
|
||||||
assert Amount.parse(balances[0]["available"]) == available
|
|
||||||
assert Amount.parse(balances[0]["pendingIncoming"]) == pending_in
|
|
||||||
assert Amount.parse(balances[0]["pendingOutgoing"]) == pending_out
|
|
||||||
|
|
||||||
|
|
||||||
def json_to_amount(d):
|
|
||||||
return Amount(d["currency"], d["value"], d["fraction"])
|
|
||||||
|
|
||||||
|
|
||||||
def print_json(obj):
|
|
||||||
print(json.dumps(obj, indent=2))
|
|
@ -1,87 +0,0 @@
|
|||||||
import os
|
|
||||||
import secrets
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from subprocess import run
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from .taler_service import TalerService
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class BankUser:
|
|
||||||
username: str
|
|
||||||
password: str
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class WithdrawUriResponse:
|
|
||||||
taler_withdraw_uri: str
|
|
||||||
withdrawal_id: str
|
|
||||||
|
|
||||||
|
|
||||||
class Bank(TalerService):
|
|
||||||
|
|
||||||
def __init__(self, config, watcher_getter, request):
|
|
||||||
super().__init__(config, watcher_getter, request)
|
|
||||||
|
|
||||||
# get localhost port and store bank URL
|
|
||||||
r = run(["taler-config", "-c", config.conf, "-s", "BANK", "-o", "HTTP_PORT"],
|
|
||||||
check=True, text=True, capture_output=True)
|
|
||||||
self.url = "http://localhost:%s/" % r.stdout.rstrip()
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
db = "postgres:///%s" % self.config.db
|
|
||||||
log_path = os.path.join(self.config.tmpdir, "bank.log")
|
|
||||||
log_file = open(log_path, 'w')
|
|
||||||
self.watcher_getter(
|
|
||||||
name='taler-bank-manage-testing',
|
|
||||||
arguments=[self.config.conf, db, 'serve-http'],
|
|
||||||
checker=self.test_process,
|
|
||||||
kwargs=dict(stderr=log_file, stdout=log_file),
|
|
||||||
request=self.request, # Needed for the correct execution order of finalizers
|
|
||||||
)
|
|
||||||
|
|
||||||
def close_log():
|
|
||||||
log_file.close()
|
|
||||||
|
|
||||||
self.request.addfinalizer(close_log)
|
|
||||||
|
|
||||||
def register_random_user(self):
|
|
||||||
username = f"testuser-{secrets.token_hex(10)}"
|
|
||||||
password = f"testpw-{secrets.token_hex(10)}"
|
|
||||||
requests.post(
|
|
||||||
f"{self.url}testing/register",
|
|
||||||
json=dict(username=username, password=password)
|
|
||||||
)
|
|
||||||
return BankUser(username, password)
|
|
||||||
|
|
||||||
def generate_withdraw_uri(self, bankuser, amount):
|
|
||||||
auth = (bankuser.username, bankuser.password)
|
|
||||||
resp = requests.post(
|
|
||||||
f"{self.url}accounts/{bankuser.username}/withdrawals",
|
|
||||||
json=dict(amount=amount),
|
|
||||||
auth=auth
|
|
||||||
)
|
|
||||||
rj = resp.json()
|
|
||||||
return WithdrawUriResponse(
|
|
||||||
taler_withdraw_uri=rj["taler_withdraw_uri"],
|
|
||||||
withdrawal_id=rj["withdrawal_id"],
|
|
||||||
)
|
|
||||||
|
|
||||||
def confirm_withdrawal(self, bank_user, withdrawal_id):
|
|
||||||
auth = (bank_user.username, bank_user.password)
|
|
||||||
requests.post(
|
|
||||||
f"{self.url}accounts/{bank_user.username}/withdrawals/{withdrawal_id}/confirm",
|
|
||||||
auth=auth
|
|
||||||
)
|
|
||||||
|
|
||||||
# Alternative way to check if the bank came up.
|
|
||||||
# Testing the URL has the issue that on the CI, django keeps closing the connection.
|
|
||||||
@staticmethod
|
|
||||||
def test_process():
|
|
||||||
for p in psutil.process_iter(['name', 'cmdline']):
|
|
||||||
if p.info["name"] == "uwsgi" and p.info["cmdline"][-1] == "talerbank.wsgi":
|
|
||||||
return True
|
|
||||||
return False
|
|
@ -1,62 +0,0 @@
|
|||||||
import logging
|
|
||||||
import os
|
|
||||||
from shutil import copyfile
|
|
||||||
from subprocess import run
|
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
|
|
||||||
def __init__(self, request, tmpdir, worker_id):
|
|
||||||
self.tmpdir = tmpdir.strpath
|
|
||||||
self.data_home = os.path.join(self.tmpdir, 'data')
|
|
||||||
|
|
||||||
# workaround for https://github.com/pytest-dev/pytest-services/issues/37
|
|
||||||
logger = logging.getLogger(
|
|
||||||
'[{worker_id}] {name}'.format(name="pytest_services.log", worker_id=worker_id))
|
|
||||||
logger.handlers.clear()
|
|
||||||
|
|
||||||
# copy config file from template
|
|
||||||
self.conf = tmpdir.join("test.conf").strpath
|
|
||||||
template = os.path.join(os.path.dirname(__file__), 'template.ini')
|
|
||||||
copyfile(template, self.conf)
|
|
||||||
|
|
||||||
# set TALER_HOME base dir
|
|
||||||
config_cmd = ["taler-config", "-c", self.conf]
|
|
||||||
run(config_cmd + ["-s", "PATHS", "-o", "TALER_HOME", "-V", self.tmpdir], check=True)
|
|
||||||
|
|
||||||
# get path of exchange private key file and create key pair
|
|
||||||
config_cmd = ["taler-config", "-c", self.conf]
|
|
||||||
r = run(config_cmd + ["-f", "-s", "EXCHANGE", "-o", "MASTER_PRIV_FILE"],
|
|
||||||
capture_output=True, check=True, text=True)
|
|
||||||
master_priv_file = r.stdout.rstrip()
|
|
||||||
master_priv_dir = os.path.dirname(master_priv_file)
|
|
||||||
os.makedirs(master_priv_dir)
|
|
||||||
run(["gnunet-ecc", "-g1", master_priv_file], check=True, capture_output=True)
|
|
||||||
r = run(["gnunet-ecc", "-p", master_priv_file], check=True, capture_output=True, text=True)
|
|
||||||
self.master_pub = r.stdout.rstrip()
|
|
||||||
|
|
||||||
# write exchange public key into config
|
|
||||||
run(config_cmd + ["-s", "exchange",
|
|
||||||
"-o", "MASTER_PUBLIC_KEY",
|
|
||||||
"-V", self.master_pub], check=True)
|
|
||||||
run(config_cmd + ["-s", "merchant-exchange-default",
|
|
||||||
"-o", "MASTER_KEY",
|
|
||||||
"-V", self.master_pub], check=True)
|
|
||||||
|
|
||||||
# write DB name into config
|
|
||||||
self.db = "test-db"
|
|
||||||
db_uri = "postgres:///" + self.db
|
|
||||||
run(config_cmd + ["-s", "exchangedb-postgres", "-o", "CONFIG", "-V", db_uri], check=True)
|
|
||||||
run(config_cmd + ["-s", "auditordb-postgres", "-o", "CONFIG", "-V", db_uri], check=True)
|
|
||||||
run(config_cmd + ["-s", "merchantdb-postgres", "-o", "CONFIG", "-V", db_uri], check=True)
|
|
||||||
run(config_cmd + ["-s", "bank", "-o", "database", "-V", db_uri], check=True)
|
|
||||||
|
|
||||||
# create new DB
|
|
||||||
run(["dropdb", self.db], capture_output=True)
|
|
||||||
run(["createdb", self.db], check=True)
|
|
||||||
|
|
||||||
# drop DB when test ends
|
|
||||||
def finalize():
|
|
||||||
run(["dropdb", self.db], capture_output=True)
|
|
||||||
|
|
||||||
request.addfinalizer(finalize)
|
|
@ -1,53 +0,0 @@
|
|||||||
import os
|
|
||||||
from subprocess import run
|
|
||||||
|
|
||||||
from .taler_service import TalerService
|
|
||||||
|
|
||||||
|
|
||||||
class Exchange(TalerService):
|
|
||||||
|
|
||||||
def __init__(self, config, watcher_getter, request):
|
|
||||||
super().__init__(config, watcher_getter, request)
|
|
||||||
|
|
||||||
# get own URL from config
|
|
||||||
r = run(["taler-config", "-c", config.conf, "-s", "EXCHANGE", "-o", "BASE_URL"],
|
|
||||||
check=True, text=True, capture_output=True)
|
|
||||||
self.url = r.stdout.rstrip()
|
|
||||||
|
|
||||||
# get and create directory for terms of service
|
|
||||||
r = run(["taler-config", "-c", config.conf, "-s", "EXCHANGE", "-o", "TERMS_DIR"],
|
|
||||||
check=True, text=True, capture_output=True)
|
|
||||||
self.terms_dir = r.stdout.rstrip().replace("${TALER_DATA_HOME}", config.data_home)
|
|
||||||
terms_dir_en = os.path.join(self.terms_dir, 'en')
|
|
||||||
os.makedirs(terms_dir_en)
|
|
||||||
|
|
||||||
# get eTag and create ToS file for it
|
|
||||||
r = run(["taler-config", "-c", config.conf, "-s", "EXCHANGE", "-o", "TERMS_ETAG"],
|
|
||||||
check=True, text=True, capture_output=True)
|
|
||||||
self.terms_etag = r.stdout.rstrip()
|
|
||||||
self.tos = "ToS Foo Bar\n"
|
|
||||||
with open(os.path.join(terms_dir_en, "%s.txt" % self.terms_etag), 'w') as f:
|
|
||||||
f.write(self.tos)
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
run(["taler-exchange-dbinit", "-c", self.config.conf], check=True)
|
|
||||||
run(["taler-exchange-wire", "-c", self.config.conf], check=True)
|
|
||||||
run(["taler-exchange-keyup", "-c", self.config.conf,
|
|
||||||
"-L", "INFO",
|
|
||||||
"-o", os.path.join(self.config.tmpdir, "e2a.dat")
|
|
||||||
], check=True, capture_output=True)
|
|
||||||
log_path = os.path.join(self.config.tmpdir, "exchange.log")
|
|
||||||
self.watcher_getter(
|
|
||||||
name='taler-exchange-httpd',
|
|
||||||
arguments=['-c', self.config.conf, '-l', log_path],
|
|
||||||
checker=self.test_url,
|
|
||||||
request=self.request, # Needed for the correct execution order of finalizers
|
|
||||||
)
|
|
||||||
# the wirewatch is needed for interaction with the bank
|
|
||||||
log_wirewatch_path = os.path.join(self.config.tmpdir, "exchange-wirewatch.log")
|
|
||||||
self.watcher_getter(
|
|
||||||
name='taler-exchange-wirewatch',
|
|
||||||
arguments=['-c', self.config.conf, '-l', log_wirewatch_path],
|
|
||||||
checker=lambda: True, # no need to wait for this to come up
|
|
||||||
request=self.request, # Needed for the correct execution order of finalizers
|
|
||||||
)
|
|
@ -1,66 +0,0 @@
|
|||||||
import os
|
|
||||||
from subprocess import run
|
|
||||||
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from .taler_service import TalerService
|
|
||||||
|
|
||||||
|
|
||||||
class Merchant(TalerService):
|
|
||||||
|
|
||||||
def __init__(self, config, watcher_getter, request):
|
|
||||||
super().__init__(config, watcher_getter, request)
|
|
||||||
|
|
||||||
# get localhost port and store merchant URL
|
|
||||||
r = run(["taler-config", "-c", config.conf, "-s", "MERCHANT", "-o", "PORT"],
|
|
||||||
check=True, text=True, capture_output=True)
|
|
||||||
self.url = "http://localhost:%s/" % r.stdout.rstrip()
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
log_path = os.path.join(self.config.tmpdir, "merchant.log")
|
|
||||||
self.watcher_getter(
|
|
||||||
name='taler-merchant-httpd',
|
|
||||||
arguments=['-c', self.config.conf, '-L', 'INFO', '-l', log_path],
|
|
||||||
checker=self.test_url,
|
|
||||||
request=self.request, # Needed for the correct execution order of finalizers
|
|
||||||
)
|
|
||||||
|
|
||||||
def create_instance(self, instance="default", name="GNU Taler Merchant"):
|
|
||||||
body = {
|
|
||||||
"id": instance,
|
|
||||||
"name": name,
|
|
||||||
"payto_uris": ["payto://x-taler-bank/test_merchant"],
|
|
||||||
"address": {},
|
|
||||||
"jurisdiction": {},
|
|
||||||
"default_max_wire_fee": "TESTKUDOS:1",
|
|
||||||
"default_wire_fee_amortization": 3,
|
|
||||||
"default_max_deposit_fee": "TESTKUDOS:1",
|
|
||||||
"default_wire_transfer_delay": {"d_ms": "forever"},
|
|
||||||
"default_pay_delay": {"d_ms": "forever"}
|
|
||||||
}
|
|
||||||
r = requests.post(self.url + "private/instances", json=body)
|
|
||||||
r.raise_for_status()
|
|
||||||
|
|
||||||
def create_order(self, amount, instance="default", summary="Test Order",
|
|
||||||
fulfillment_url="taler://fulfillment-success/Enjoy+your+ice+cream!"):
|
|
||||||
body = {
|
|
||||||
"order": {
|
|
||||||
"amount": amount,
|
|
||||||
"summary": summary,
|
|
||||||
"fulfillment_url": fulfillment_url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r = requests.post("{}instances/{}/private/orders".format(self.url, instance), json=body)
|
|
||||||
r.raise_for_status()
|
|
||||||
return r.json()
|
|
||||||
|
|
||||||
def check_payment(self, order_id, instance="default"):
|
|
||||||
r = requests.get("{}instances/{}/private/orders/{}".format(self.url, instance, order_id))
|
|
||||||
r.raise_for_status()
|
|
||||||
return r.json()
|
|
||||||
|
|
||||||
def gen_pay_uri(self, amount, instance="default", summary="Test Order",
|
|
||||||
fulfillment_url="taler://fulfillment-success/Enjoy+your+ice+cream!"):
|
|
||||||
order = self.create_order(amount, instance, summary, fulfillment_url)
|
|
||||||
response = self.check_payment(order["order_id"], instance)
|
|
||||||
return response["taler_pay_uri"]
|
|
@ -1,18 +0,0 @@
|
|||||||
import requests
|
|
||||||
from requests.exceptions import ConnectionError
|
|
||||||
|
|
||||||
|
|
||||||
class TalerService:
|
|
||||||
|
|
||||||
def __init__(self, config, watcher_getter, request):
|
|
||||||
self.config = config
|
|
||||||
self.watcher_getter = watcher_getter
|
|
||||||
self.request = request
|
|
||||||
|
|
||||||
def test_url(self):
|
|
||||||
try:
|
|
||||||
requests.get(self.url, timeout=3)
|
|
||||||
except ConnectionError as e:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
@ -1,228 +0,0 @@
|
|||||||
[exchange]
|
|
||||||
KEYDIR = ${TALER_DATA_HOME}/exchange/live-keys/
|
|
||||||
REVOCATION_DIR = ${TALER_DATA_HOME}/exchange/revocations/
|
|
||||||
MAX_KEYS_CACHING = forever
|
|
||||||
DB = postgres
|
|
||||||
MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv
|
|
||||||
SERVE = tcp
|
|
||||||
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
|
||||||
UNIXPATH_MODE = 660
|
|
||||||
PORT = 8081
|
|
||||||
BASE_URL = http://localhost:8081/
|
|
||||||
SIGNKEY_DURATION = 4 weeks
|
|
||||||
LEGAL_DURATION = 2 years
|
|
||||||
LOOKAHEAD_SIGN = 32 weeks 1 day
|
|
||||||
LOOKAHEAD_PROVIDE = 4 weeks 1 day
|
|
||||||
TERMS_ETAG = test_etag
|
|
||||||
TERMS_DIR = ${TALER_DATA_HOME}/exchange/terms
|
|
||||||
|
|
||||||
[merchant]
|
|
||||||
SERVE = tcp
|
|
||||||
PORT = 9966
|
|
||||||
UNIXPATH = ${TALER_RUNTIME_DIR}/merchant.http
|
|
||||||
UNIXPATH_MODE = 660
|
|
||||||
DEFAULT_WIRE_FEE_AMORTIZATION = 1
|
|
||||||
DB = postgres
|
|
||||||
WIREFORMAT = default
|
|
||||||
# Set very low, so we can be sure that the database generated
|
|
||||||
# will contain wire transfers "ready" for the aggregator.
|
|
||||||
WIRE_TRANSFER_DELAY = 1 minute
|
|
||||||
DEFAULT_PAY_DEADLINE = 1 day
|
|
||||||
DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1
|
|
||||||
KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv
|
|
||||||
DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10
|
|
||||||
|
|
||||||
# Ensure that merchant reports EVERY deposit confirmation to auditor
|
|
||||||
FORCE_AUDIT = YES
|
|
||||||
|
|
||||||
[instance-default]
|
|
||||||
KEYFILE = ${TALER_DATA_HOME}/merchant/default.priv
|
|
||||||
NAME = Merchant Inc.
|
|
||||||
TIP_EXCHANGE = http://localhost:8081/
|
|
||||||
# TODO necessary to specify a different key here?
|
|
||||||
TIP_RESERVE_PRIV_FILENAME = ${TALER_DATA_HOME}/merchant/default.priv
|
|
||||||
|
|
||||||
[auditor]
|
|
||||||
DB = postgres
|
|
||||||
AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv
|
|
||||||
SERVE = tcp
|
|
||||||
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
|
||||||
UNIXPATH_MODE = 660
|
|
||||||
PORT = 8083
|
|
||||||
AUDITOR_URL = http://localhost:8083/
|
|
||||||
TINY_AMOUNT = TESTKUDOS:0.01
|
|
||||||
|
|
||||||
[PATHS]
|
|
||||||
TALER_DATA_HOME = $TALER_HOME/data/
|
|
||||||
TALER_CONFIG_HOME = $TALER_HOME/config/
|
|
||||||
TALER_CACHE_HOME = $TALER_HOME/cache/
|
|
||||||
TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/taler-system-runtime/
|
|
||||||
|
|
||||||
[bank]
|
|
||||||
DATABASE = postgres:///taler-auditor-basedb
|
|
||||||
MAX_DEBT = TESTKUDOS:50.0
|
|
||||||
MAX_DEBT_BANK = TESTKUDOS:100000.0
|
|
||||||
HTTP_PORT = 8082
|
|
||||||
SUGGESTED_EXCHANGE = http://localhost:8081/
|
|
||||||
SUGGESTED_EXCHANGE_PAYTO = payto://x-taler-bank/localhost/2
|
|
||||||
ALLOW_REGISTRATIONS = YES
|
|
||||||
|
|
||||||
[exchangedb]
|
|
||||||
AUDITOR_BASE_DIR = ${TALER_DATA_HOME}/auditors/
|
|
||||||
WIREFEE_BASE_DIR = ${TALER_DATA_HOME}/exchange/wirefees/
|
|
||||||
IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
|
|
||||||
LEGAL_RESERVE_EXPIRATION_TIME = 7 years
|
|
||||||
|
|
||||||
[exchange_keys]
|
|
||||||
signkey_duration = 4 weeks
|
|
||||||
legal_duration = 2 years
|
|
||||||
lookahead_sign = 32 weeks 1 day
|
|
||||||
lookahead_provide = 4 weeks 1 day
|
|
||||||
|
|
||||||
[taler]
|
|
||||||
CURRENCY = TESTKUDOS
|
|
||||||
CURRENCY_ROUND_UNIT = TESTKUDOS:0.01
|
|
||||||
|
|
||||||
[exchange-account-1]
|
|
||||||
WIRE_RESPONSE = ${TALER_DATA_HOME}/exchange/account-1.json
|
|
||||||
PAYTO_URI = payto://x-taler-bank/localhost/Exchange
|
|
||||||
enable_debit = yes
|
|
||||||
enable_credit = yes
|
|
||||||
WIRE_GATEWAY_URL = "http://localhost:8082/taler-wire-gateway/Exchange/"
|
|
||||||
WIRE_GATEWAY_AUTH_METHOD = basic
|
|
||||||
USERNAME = Exchange
|
|
||||||
PASSWORD = x
|
|
||||||
|
|
||||||
[merchant-account-merchant]
|
|
||||||
PAYTO_URI = payto://x-taler-bank/localhost/42
|
|
||||||
WIRE_RESPONSE = ${TALER_CONFIG_HOME}/merchant/account-3.json
|
|
||||||
HONOR_default = YES
|
|
||||||
ACTIVE_default = YES
|
|
||||||
|
|
||||||
[fees-x-taler-bank]
|
|
||||||
wire-fee-2020 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2020 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2021 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2021 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2022 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2022 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2023 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2023 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2024 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2024 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2025 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2025 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2026 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2026 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2027 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2027 = TESTKUDOS:0.01
|
|
||||||
wire-fee-2028 = TESTKUDOS:0.01
|
|
||||||
closing-fee-2028 = TESTKUDOS:0.01
|
|
||||||
|
|
||||||
[merchant-instance-wireformat-default]
|
|
||||||
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/merchant/wire/tutorial.json
|
|
||||||
|
|
||||||
[merchant-exchange-default]
|
|
||||||
EXCHANGE_BASE_URL = http://localhost:8081/
|
|
||||||
CURRENCY = TESTKUDOS
|
|
||||||
|
|
||||||
[payments-generator]
|
|
||||||
currency = TESTKUDOS
|
|
||||||
instance = default
|
|
||||||
bank = http://localhost:8082/
|
|
||||||
merchant = http://localhost:9966/
|
|
||||||
exchange_admin = http://localhost:18080/
|
|
||||||
exchange-admin = http://localhost:18080/
|
|
||||||
exchange = http://localhost:8081/
|
|
||||||
|
|
||||||
[coin_kudos_ct_1]
|
|
||||||
value = TESTKUDOS:0.01
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.01
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_ct_10]
|
|
||||||
value = TESTKUDOS:0.10
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_1]
|
|
||||||
value = TESTKUDOS:1
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.02
|
|
||||||
fee_deposit = TESTKUDOS:0.02
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_2]
|
|
||||||
value = TESTKUDOS:2
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.03
|
|
||||||
fee_deposit = TESTKUDOS:0.03
|
|
||||||
fee_refresh = TESTKUDOS:0.04
|
|
||||||
fee_refund = TESTKUDOS:0.02
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_4]
|
|
||||||
value = TESTKUDOS:4
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.03
|
|
||||||
fee_deposit = TESTKUDOS:0.03
|
|
||||||
fee_refresh = TESTKUDOS:0.04
|
|
||||||
fee_refund = TESTKUDOS:0.02
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_5]
|
|
||||||
value = TESTKUDOS:5
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_8]
|
|
||||||
value = TESTKUDOS:8
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.05
|
|
||||||
fee_deposit = TESTKUDOS:0.02
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.04
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[coin_kudos_10]
|
|
||||||
value = TESTKUDOS:10
|
|
||||||
duration_withdraw = 7 days
|
|
||||||
duration_spend = 2 years
|
|
||||||
duration_legal = 3 years
|
|
||||||
fee_withdraw = TESTKUDOS:0.01
|
|
||||||
fee_deposit = TESTKUDOS:0.01
|
|
||||||
fee_refresh = TESTKUDOS:0.03
|
|
||||||
fee_refund = TESTKUDOS:0.01
|
|
||||||
rsa_keysize = 1024
|
|
||||||
|
|
||||||
[benchmark]
|
|
||||||
BANK_DETAILS = bank_details.json
|
|
||||||
MERCHANT_DETAILS = merchant_details.json
|
|
@ -1,51 +0,0 @@
|
|||||||
import json
|
|
||||||
import os
|
|
||||||
from subprocess import run
|
|
||||||
|
|
||||||
|
|
||||||
class Wallet:
|
|
||||||
|
|
||||||
def __init__(self, config):
|
|
||||||
self.db = os.path.join(config.tmpdir, "wallet-db.json")
|
|
||||||
self.arg_db = "--wallet-db=%s" % self.db
|
|
||||||
self.log_path = os.path.join(config.tmpdir, "wallet.log")
|
|
||||||
|
|
||||||
def cmd(self, command, request=None):
|
|
||||||
if request is None:
|
|
||||||
request = dict()
|
|
||||||
request = json.dumps(request)
|
|
||||||
r = run(["taler-wallet-cli", self.arg_db, "api", command, request],
|
|
||||||
timeout=10, text=True, capture_output=True)
|
|
||||||
self.write_to_log(r.stderr)
|
|
||||||
if r.returncode != 0:
|
|
||||||
print(r)
|
|
||||||
assert r.returncode == 0
|
|
||||||
json_r = json.loads(r.stdout)
|
|
||||||
if json_r["type"] != "response" or "result" not in json_r:
|
|
||||||
print(json_r)
|
|
||||||
assert json_r["type"] == "response"
|
|
||||||
return json_r["result"]
|
|
||||||
|
|
||||||
def testing_withdraw(self, amount, exchange_url, bank_url):
|
|
||||||
r = run(["taler-wallet-cli", self.arg_db, "--no-throttle", "testing", "withdraw",
|
|
||||||
"-a", amount,
|
|
||||||
"-e", exchange_url,
|
|
||||||
"-b", bank_url
|
|
||||||
], timeout=10, check=True, text=True, capture_output=True)
|
|
||||||
self.write_to_log(r.stderr)
|
|
||||||
|
|
||||||
def run_pending(self):
|
|
||||||
r = run(["taler-wallet-cli", self.arg_db, "run-pending"],
|
|
||||||
timeout=10, check=True, text=True, capture_output=True)
|
|
||||||
self.write_to_log(r.stderr)
|
|
||||||
return r.stdout.rstrip()
|
|
||||||
|
|
||||||
def run_until_done(self):
|
|
||||||
r = run(["taler-wallet-cli", self.arg_db, "run-until-done"],
|
|
||||||
timeout=10, check=True, text=True, capture_output=True)
|
|
||||||
self.write_to_log(r.stderr)
|
|
||||||
return r.stdout.rstrip()
|
|
||||||
|
|
||||||
def write_to_log(self, data):
|
|
||||||
with open(self.log_path, "a") as f:
|
|
||||||
f.write(data)
|
|
@ -1,38 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from tests.components.bank import Bank
|
|
||||||
from tests.components.config import Config
|
|
||||||
from tests.components.exchange import Exchange
|
|
||||||
from tests.components.merchant import Merchant
|
|
||||||
from tests.components.wallet import Wallet
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def config(watcher_getter, request, tmpdir, worker_id):
|
|
||||||
return Config(request, tmpdir, worker_id)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def exchange(watcher_getter, request, config):
|
|
||||||
exchange = Exchange(config, watcher_getter, request)
|
|
||||||
exchange.start()
|
|
||||||
return exchange
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def bank(watcher_getter, request, config):
|
|
||||||
bank = Bank(config, watcher_getter, request)
|
|
||||||
bank.start()
|
|
||||||
return bank
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def merchant(watcher_getter, request, config):
|
|
||||||
merchant = Merchant(config, watcher_getter, request)
|
|
||||||
merchant.start()
|
|
||||||
return merchant
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def wallet(watcher_getter, config):
|
|
||||||
return Wallet(config)
|
|
@ -1,4 +0,0 @@
|
|||||||
pytest==5.4.*
|
|
||||||
pytest-services==2.1.*
|
|
||||||
taler-util==0.6.*
|
|
||||||
psutil==5.7.*
|
|
@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
|
|
||||||
def test_exchanges(exchange, wallet):
|
|
||||||
# list of exchanges is initially empty
|
|
||||||
result = wallet.cmd("listExchanges")
|
|
||||||
assert not result["exchanges"]
|
|
||||||
|
|
||||||
# adding an exchange works
|
|
||||||
result = wallet.cmd("addExchange", {"exchangeBaseUrl": exchange.url})
|
|
||||||
assert not result # result is empty
|
|
||||||
|
|
||||||
# list includes added exchange
|
|
||||||
result = wallet.cmd("listExchanges")
|
|
||||||
e = result["exchanges"][0]
|
|
||||||
assert e["exchangeBaseUrl"] == exchange.url
|
|
||||||
assert e["currency"] == "TESTKUDOS"
|
|
||||||
assert len(e["paytoUris"]) >= 1
|
|
@ -1,11 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
from tests import print_json
|
|
||||||
|
|
||||||
|
|
||||||
def test_payments(exchange, bank, merchant, wallet):
|
|
||||||
merchant.create_instance()
|
|
||||||
pay_uri = merchant.gen_pay_uri("TESTKUDOS:2")
|
|
||||||
|
|
||||||
# TODO fix
|
|
||||||
result = wallet.cmd("preparePay", {"talerPayUri": pay_uri})
|
|
||||||
print_json(result)
|
|
@ -1,156 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
from taler.util.amount import Amount
|
|
||||||
|
|
||||||
from tests import check_single_balance
|
|
||||||
|
|
||||||
|
|
||||||
def test_withdrawal(exchange, bank, wallet):
|
|
||||||
bank_user = bank.register_random_user()
|
|
||||||
|
|
||||||
# assert that we start with no transactions
|
|
||||||
result = wallet.cmd("getTransactions")
|
|
||||||
assert not result["transactions"]
|
|
||||||
|
|
||||||
# test withdrawal
|
|
||||||
amount_raw = Amount.parse("TESTKUDOS:5")
|
|
||||||
wallet.testing_withdraw(amount_raw.stringify(), exchange.url, bank.url)
|
|
||||||
|
|
||||||
# check that balance is correct
|
|
||||||
result = wallet.cmd("getBalances")
|
|
||||||
amount_effective = Amount("TESTKUDOS", 4, 84000000)
|
|
||||||
check_single_balance(result["balances"], amount_effective)
|
|
||||||
|
|
||||||
# assert that withdrawal shows up properly in transactions
|
|
||||||
result = wallet.cmd("getTransactions")
|
|
||||||
assert len(result["transactions"]) == 1
|
|
||||||
transaction = result["transactions"][0]
|
|
||||||
assert transaction["type"] == "withdrawal"
|
|
||||||
assert Amount.parse(transaction["amountEffective"]) == amount_effective
|
|
||||||
assert Amount.parse(transaction["amountRaw"]) == amount_raw
|
|
||||||
assert transaction["exchangeBaseUrl"] == exchange.url
|
|
||||||
assert not transaction["pending"]
|
|
||||||
withdrawal_details = transaction["withdrawalDetails"]
|
|
||||||
assert withdrawal_details["type"] == "manual-transfer"
|
|
||||||
payto_list = ["payto://x-taler-bank/localhost/Exchange"]
|
|
||||||
assert withdrawal_details["exchangePaytoUris"] == payto_list
|
|
||||||
|
|
||||||
# get a withdrawal URI
|
|
||||||
bank_uri_resp = bank.generate_withdraw_uri(bank_user, "TESTKUDOS:5")
|
|
||||||
uri = bank_uri_resp.taler_withdraw_uri
|
|
||||||
assert uri.startswith("taler+http://withdraw")
|
|
||||||
|
|
||||||
# get withdrawal details from URI
|
|
||||||
result = wallet.cmd("getWithdrawalDetailsForUri", {"talerWithdrawUri": uri})
|
|
||||||
assert Amount.parse(result["amount"]) == amount_raw
|
|
||||||
assert result["defaultExchangeBaseUrl"] == exchange.url
|
|
||||||
assert len(result["possibleExchanges"]) == 1
|
|
||||||
assert result["possibleExchanges"][0]["exchangeBaseUrl"] == exchange.url
|
|
||||||
assert result["possibleExchanges"][0]["currency"] == "TESTKUDOS"
|
|
||||||
assert result["possibleExchanges"][0]["paytoUris"] == payto_list
|
|
||||||
|
|
||||||
# check withdrawal details for amount
|
|
||||||
request = {"exchangeBaseUrl": exchange.url, "amount": amount_raw.stringify()}
|
|
||||||
result = wallet.cmd("getWithdrawalDetailsForAmount", request)
|
|
||||||
assert Amount.parse(result["amountRaw"]) == amount_raw
|
|
||||||
assert Amount.parse(result["amountEffective"]) == amount_effective
|
|
||||||
assert result["paytoUris"] == payto_list
|
|
||||||
assert not result["tosAccepted"]
|
|
||||||
|
|
||||||
# get ToS
|
|
||||||
result = wallet.cmd("getExchangeTos", {"exchangeBaseUrl": exchange.url})
|
|
||||||
assert result["currentEtag"] == exchange.terms_etag
|
|
||||||
assert result["tos"] == exchange.tos
|
|
||||||
|
|
||||||
# accept ToS
|
|
||||||
request = {"exchangeBaseUrl": exchange.url, "etag": exchange.terms_etag}
|
|
||||||
wallet.cmd("setExchangeTosAccepted", request)
|
|
||||||
|
|
||||||
# check that ToS are now shown as accepted
|
|
||||||
request = {"exchangeBaseUrl": exchange.url, "amount": amount_raw.stringify()}
|
|
||||||
result = wallet.cmd("getWithdrawalDetailsForAmount", request)
|
|
||||||
assert result["tosAccepted"]
|
|
||||||
|
|
||||||
# accept withdrawal
|
|
||||||
request = {"exchangeBaseUrl": exchange.url, "talerWithdrawUri": uri}
|
|
||||||
result = wallet.cmd("acceptBankIntegratedWithdrawal", request)
|
|
||||||
assert result["confirmTransferUrl"].startswith(bank.url + "confirm-withdrawal/")
|
|
||||||
confirm_url = result["confirmTransferUrl"]
|
|
||||||
|
|
||||||
# Let the wallet do its work. At this point, the bank-integrated
|
|
||||||
# withdrawal won't have succeeded yet, as it's not confirmed at the bank side.
|
|
||||||
wallet.run_pending()
|
|
||||||
|
|
||||||
# check that balance is correct
|
|
||||||
result = wallet.cmd("getBalances")
|
|
||||||
check_single_balance(result["balances"], amount_effective, amount_effective)
|
|
||||||
|
|
||||||
# assert that 2nd withdrawal shows up properly in transactions
|
|
||||||
result = wallet.cmd("getTransactions")
|
|
||||||
assert len(result["transactions"]) == 2
|
|
||||||
transaction = result["transactions"][0]
|
|
||||||
assert transaction["type"] == "withdrawal"
|
|
||||||
assert Amount.parse(transaction["amountEffective"]) == amount_effective
|
|
||||||
assert Amount.parse(transaction["amountRaw"]) == amount_raw
|
|
||||||
assert transaction["exchangeBaseUrl"] == exchange.url
|
|
||||||
assert transaction["pending"]
|
|
||||||
withdrawal_details = transaction["withdrawalDetails"]
|
|
||||||
assert withdrawal_details["type"] == "taler-bank-integration-api"
|
|
||||||
assert not withdrawal_details["confirmed"]
|
|
||||||
assert withdrawal_details["bankConfirmationUrl"] == confirm_url
|
|
||||||
|
|
||||||
# new withdrawal is newer than old one
|
|
||||||
timestamp0 = result["transactions"][0]["timestamp"]["t_ms"]
|
|
||||||
timestamp1 = result["transactions"][1]["timestamp"]["t_ms"]
|
|
||||||
assert timestamp0 > timestamp1
|
|
||||||
|
|
||||||
# now we actually confirm the withdrawal
|
|
||||||
bank.confirm_withdrawal(bank_user, bank_uri_resp.withdrawal_id)
|
|
||||||
# It might take some time until the exchange knows about the reserve,
|
|
||||||
# so we'll try until it works.
|
|
||||||
wallet.run_until_done()
|
|
||||||
|
|
||||||
# check that balance is correct
|
|
||||||
result = wallet.cmd("getBalances")
|
|
||||||
check_single_balance(
|
|
||||||
result["balances"], Amount.parse("TESTKUDOS:9.68"), Amount.parse("TESTKUDOS:0"),
|
|
||||||
)
|
|
||||||
|
|
||||||
# check that transaction is no longer pending, but confirmed
|
|
||||||
result = wallet.cmd("getTransactions")
|
|
||||||
assert len(result["transactions"]) == 2
|
|
||||||
transaction = result["transactions"][1] # TODO this transaction should be at the top now
|
|
||||||
assert transaction["type"] == "withdrawal"
|
|
||||||
assert not transaction["pending"]
|
|
||||||
assert transaction["withdrawalDetails"]["confirmed"]
|
|
||||||
|
|
||||||
# one more manual withdrawal
|
|
||||||
request = {"exchangeBaseUrl": exchange.url, "amount": amount_raw.stringify()}
|
|
||||||
result = wallet.cmd("acceptManualWithdrawal", request)
|
|
||||||
assert len(result["exchangePaytoUris"]) == 1
|
|
||||||
result["exchangePaytoUris"][0].startswith(payto_list[0])
|
|
||||||
|
|
||||||
# check that balance is correct
|
|
||||||
result = wallet.cmd("getBalances")
|
|
||||||
check_single_balance(
|
|
||||||
result["balances"], amount_effective + amount_effective, amount_effective
|
|
||||||
)
|
|
||||||
|
|
||||||
# assert that 3nd withdrawal shows up properly in transactions
|
|
||||||
result = wallet.cmd("getTransactions")
|
|
||||||
assert len(result["transactions"]) == 3
|
|
||||||
transaction = result["transactions"][0]
|
|
||||||
assert transaction["type"] == "withdrawal"
|
|
||||||
assert Amount.parse(transaction["amountEffective"]) == amount_effective
|
|
||||||
assert Amount.parse(transaction["amountRaw"]) == amount_raw
|
|
||||||
assert transaction["exchangeBaseUrl"] == exchange.url
|
|
||||||
assert transaction["pending"]
|
|
||||||
withdrawal_details = transaction["withdrawalDetails"]
|
|
||||||
assert withdrawal_details["type"] == "manual-transfer"
|
|
||||||
assert len(withdrawal_details["exchangePaytoUris"]) == 1
|
|
||||||
assert withdrawal_details["exchangePaytoUris"][0].startswith(payto_list[0])
|
|
||||||
|
|
||||||
# last withdrawal is newest
|
|
||||||
timestamp3 = transaction["timestamp"]["t_ms"]
|
|
||||||
assert timestamp3 > timestamp0
|
|
||||||
assert timestamp3 > timestamp1
|
|
Loading…
Reference in New Issue
Block a user