release 1.15.0: CHF fake-incoming ladder (23 rungs to 50k)
devtesting runs a log-spaced amount ladder up to CHF:50000 after the baseline plumbing probe. Each rung uses geniban debit funding. Defaults DEVTESTING_LADDER=1 STEPS=23 MAX=50000; stage RUN_TIMEOUT example 1800s.
This commit is contained in:
parent
8f3d221e02
commit
25cb8216b3
7 changed files with 257 additions and 65 deletions
|
|
@ -433,7 +433,10 @@ Taler Operations **rusty** host (`taler-devtesting` forced command):
|
||||||
```
|
```
|
||||||
|
|
||||||
Needs SSH to `devtesting@rusty.taler-ops.ch` (Host `taler-rusty-devtesting`).
|
Needs SSH to `devtesting@rusty.taler-ops.ch` (Host `taler-rusty-devtesting`).
|
||||||
Probes: CLI help, `geniban` (CH IBAN), `fake-incoming` CHF to exchange credit
|
Probes: CLI help, `geniban` (CH IBAN / synthetic debit funding), baseline `fake-incoming`,
|
||||||
|
optional **amount ladder** (`DEVTESTING_LADDER=1`, default **23** rungs up to **CHF:50000**).
|
||||||
|
Each rung reuses geniban debit payto so volume covers the max rung without a real bank withdraw.
|
||||||
|
`fake-incoming` CHF to exchange credit
|
||||||
IBAN. A nexus bounce *missing reserve public key* is **OK** for the plumbing
|
IBAN. A nexus bounce *missing reserve public key* is **OK** for the plumbing
|
||||||
probe (no real wallet reserve required).
|
probe (no real wallet reserve required).
|
||||||
|
|
||||||
|
|
|
||||||
3
TESTS.md
3
TESTS.md
|
|
@ -202,4 +202,5 @@ Always use `printf --` friendly plain headers when colour is off (leading `---`
|
||||||
| **devtesting.cli-** | SSH to rusty · `taler-devtesting` CLI |
|
| **devtesting.cli-** | SSH to rusty · `taler-devtesting` CLI |
|
||||||
| **devtesting.geniban-** | synthetic CH IBAN |
|
| **devtesting.geniban-** | synthetic CH IBAN |
|
||||||
| **devtesting.credit-payto-** | exchange credit IBAN for nexus |
|
| **devtesting.credit-payto-** | exchange credit IBAN for nexus |
|
||||||
| **devtesting.fake-incoming-** | CHF IN via nexus; bounce missing reserve pub = plumbing OK |
|
| **devtesting.fake-incoming-** / **baseline-** | CHF IN via nexus; bounce missing reserve pub = plumbing OK |
|
||||||
|
| **devtesting.ladder-** | CHF fake-incoming amount ladder (default 23 rungs → CHF:50000; synthetic geniban debit each rung) |
|
||||||
|
|
|
||||||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
1.14.0
|
1.15.0
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.8.0`). File `VERSION` omits the `v` pre
|
||||||
|
|
||||||
| Tag | Date (UTC) | Notes |
|
| Tag | Date (UTC) | Notes |
|
||||||
|-----|------------|--------|
|
|-----|------------|--------|
|
||||||
|
| **v1.15.0** | 2026-07-19 | **Feature:** CHF **fake-incoming amount ladder** in `devtesting` (`DEVTESTING_LADDER=1`, default **23** log-spaced rungs **CHF:0.01 → CHF:50000**); synthetic geniban debit funds each rung; baseline plumbing probe kept. |
|
||||||
| **v1.14.0** | 2026-07-19 | **Feature:** SUMMARY box rows are **colour-distinct** (per-severity badge + tinted background + bold counts; verdict-coloured header); HTML mon pages style `sum-ok` / `sum-warn` / `sum-err` / … panels the same way. |
|
| **v1.14.0** | 2026-07-19 | **Feature:** SUMMARY box rows are **colour-distinct** (per-severity badge + tinted background + bold counts; verdict-coloured header); HTML mon pages style `sum-ok` / `sum-warn` / `sum-err` / … panels the same way. |
|
||||||
| **v1.13.13** | 2026-07-19 | **Bugfix:** progress estimate for **devtesting** / fake-franken is 8 (happy-path numbered checks), not 10 — avoids mid-run 42/48 then end snap 46/46. |
|
| **v1.13.13** | 2026-07-19 | **Bugfix:** progress estimate for **devtesting** / fake-franken is 8 (happy-path numbered checks), not 10 — avoids mid-run 42/48 then end snap 46/46. |
|
||||||
| **v1.13.12** | 2026-07-19 | **Bugfix:** SUMMARY chrome (`[ WARN ] 2`, `warnings only`, OK/ERROR counts without `#NNN`) is **meta**, not warn/error — sticky counts + warn filter no longer double SUMMARY rows; filter context skips blank lines. |
|
| **v1.13.12** | 2026-07-19 | **Bugfix:** SUMMARY chrome (`[ WARN ] 2`, `warnings only`, OK/ERROR counts without `#NNN`) is **meta**, not warn/error — sticky counts + warn filter no longer double SUMMARY rows; filter context skips blank lines. |
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,21 @@
|
||||||
#
|
#
|
||||||
# Probes:
|
# Probes:
|
||||||
# 1) CLI reachable (fake-incoming --help)
|
# 1) CLI reachable (fake-incoming --help)
|
||||||
# 2) geniban → Swiss IBAN
|
# 2) geniban → Swiss IBAN (debit side — “enough money” is synthetic per rung)
|
||||||
# 3) fake-incoming CHF amount to exchange credit IBAN (nexus IN)
|
# 3) baseline fake-incoming CHF:1.00 (plumbing)
|
||||||
# Bounce "missing reserve public key" = plumbing OK (no real wallet reserve)
|
# 4) optional amount ladder: DEVTESTING_LADDER=1 (default) — 23 rungs up to 50k CHF
|
||||||
# Full credit needs a real reserve pub as --subject (optional later)
|
|
||||||
#
|
#
|
||||||
# Env:
|
# Env:
|
||||||
# DEVTESTING_SSH default taler-rusty-devtesting (or user@host)
|
# DEVTESTING_SSH default taler-rusty-devtesting (or user@host)
|
||||||
# DEVTESTING_AMOUNT default CHF:1.00
|
# DEVTESTING_AMOUNT baseline amount (default CHF:1.00)
|
||||||
# DEVTESTING_CREDIT_PAYTO exchange IBAN payto (auto from EXCHANGE_PUBLIC/keys if empty)
|
# DEVTESTING_CREDIT_PAYTO exchange IBAN payto
|
||||||
# DEVTESTING_EXCHANGE_IBAN fallback CH6808573105529100001 (TOPS CHF exchange)
|
# DEVTESTING_EXCHANGE_IBAN fallback CH6808573105529100001 (TOPS CHF exchange)
|
||||||
# DEVTESTING_SKIP=1 skip phase
|
# DEVTESTING_LADDER 1 (default) run amount ladder; 0 = baseline only
|
||||||
# SKIP_SSH=1 skip (same as other SSH phases)
|
# DEVTESTING_LADDER_STEPS default 23
|
||||||
|
# DEVTESTING_LADDER_MAX default 50000 (CHF major units)
|
||||||
|
# DEVTESTING_LADDER_MIN default 0.01
|
||||||
|
# DEVTESTING_LADDER_STOP_ON_FAIL 1 (default) stop ladder on hard fail; 0 = continue
|
||||||
|
# DEVTESTING_SKIP=1 skip phase
|
||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
ROOT=$(cd "$(dirname "$0")" && pwd)
|
ROOT=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
|
@ -37,8 +40,13 @@ fi
|
||||||
: "${DEVTESTING_SSH:=}"
|
: "${DEVTESTING_SSH:=}"
|
||||||
: "${DEVTESTING_AMOUNT:=CHF:1.00}"
|
: "${DEVTESTING_AMOUNT:=CHF:1.00}"
|
||||||
: "${DEVTESTING_EXCHANGE_IBAN:=CH6808573105529100001}"
|
: "${DEVTESTING_EXCHANGE_IBAN:=CH6808573105529100001}"
|
||||||
|
: "${DEVTESTING_LADDER:=1}"
|
||||||
|
: "${DEVTESTING_LADDER_STEPS:=23}"
|
||||||
|
: "${DEVTESTING_LADDER_MAX:=50000}"
|
||||||
|
: "${DEVTESTING_LADDER_MIN:=0.01}"
|
||||||
|
: "${DEVTESTING_LADDER_STOP_ON_FAIL:=1}"
|
||||||
: "${SSH_CONNECT_TIMEOUT:=8}"
|
: "${SSH_CONNECT_TIMEOUT:=8}"
|
||||||
: "${SSH_CMD_TIMEOUT:=45}"
|
: "${SSH_CMD_TIMEOUT:=60}"
|
||||||
|
|
||||||
ssh_dt() {
|
ssh_dt() {
|
||||||
# Prefer Host alias; fall back to explicit user@host if config missing
|
# Prefer Host alias; fall back to explicit user@host if config missing
|
||||||
|
|
@ -61,8 +69,57 @@ ssh_dt() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Run one fake-incoming. Sets globals: FI_RC FI_FLAT FI_STATUS
|
||||||
|
# FI_STATUS: ok_bounce | ok_in | ok_cli | fail_ssh | fail_creditor | fail_nexus | fail_other
|
||||||
|
run_fake_incoming() {
|
||||||
|
local amount="$1" subject="$2" credit="$3" debit="$4"
|
||||||
|
local fi_out
|
||||||
|
FI_RC=0
|
||||||
|
FI_FLAT=""
|
||||||
|
FI_STATUS="fail_other"
|
||||||
|
fi_out=$(ssh_dt fake-incoming \
|
||||||
|
--amount "${amount}" \
|
||||||
|
--subject "${subject}" \
|
||||||
|
--credit-payto "${credit}" \
|
||||||
|
--debit-payto "${debit}" 2>&1) || FI_RC=$?
|
||||||
|
FI_FLAT=$(printf '%s' "$fi_out" | tr '\n' ' ')
|
||||||
|
|
||||||
|
if printf '%s' "$FI_FLAT" | grep -qiE 'Permission denied|Connection refused|Could not resolve|No such command'; then
|
||||||
|
FI_STATUS=fail_ssh
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if printf '%s' "$FI_FLAT" | grep -qiE 'Creditor must be the exchange'; then
|
||||||
|
FI_STATUS=fail_creditor
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if printf '%s' "$FI_FLAT" | grep -qiE 'Missing amount|unable to read secrets|CalledProcessError'; then
|
||||||
|
if ! printf '%s' "$FI_FLAT" | grep -qE 'libeufin-nexus - IN .* CHF'; then
|
||||||
|
FI_STATUS=fail_nexus
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if printf '%s' "$FI_FLAT" | grep -qE 'libeufin-nexus - IN .* CHF:[0-9]'; then
|
||||||
|
if printf '%s' "$FI_FLAT" | grep -qiE 'bounced.*missing reserve public key'; then
|
||||||
|
FI_STATUS=ok_bounce
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if printf '%s' "$FI_FLAT" | grep -qiE 'bounced'; then
|
||||||
|
FI_STATUS=ok_bounce
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
FI_STATUS=ok_in
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [ "$FI_RC" -eq 0 ] && printf '%s' "$FI_FLAT" | grep -qi 'Faking incoming CHF'; then
|
||||||
|
FI_STATUS=ok_cli
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
FI_STATUS=fail_other
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
set_group cli
|
set_group cli
|
||||||
info "ssh" "DEVTESTING_SSH=${DEVTESTING_SSH} amount=${DEVTESTING_AMOUNT}"
|
info "ssh" "DEVTESTING_SSH=${DEVTESTING_SSH} baseline=${DEVTESTING_AMOUNT} ladder=${DEVTESTING_LADDER} steps=${DEVTESTING_LADDER_STEPS} max=CHF:${DEVTESTING_LADDER_MAX}"
|
||||||
|
|
||||||
help_out=$(ssh_dt fake-incoming --help 2>&1) || true
|
help_out=$(ssh_dt fake-incoming --help 2>&1) || true
|
||||||
if printf '%s' "$help_out" | grep -q 'fake-incoming'; then
|
if printf '%s' "$help_out" | grep -q 'fake-incoming'; then
|
||||||
|
|
@ -77,7 +134,7 @@ set_group geniban
|
||||||
iban_out=$(ssh_dt geniban 2>&1) || true
|
iban_out=$(ssh_dt geniban 2>&1) || true
|
||||||
iban=$(printf '%s\n' "$iban_out" | grep -E '^CH[0-9A-Z]+$' | tail -1 || true)
|
iban=$(printf '%s\n' "$iban_out" | grep -E '^CH[0-9A-Z]+$' | tail -1 || true)
|
||||||
if [ -n "$iban" ]; then
|
if [ -n "$iban" ]; then
|
||||||
ok "geniban" "synthetic IBAN $iban"
|
ok "geniban" "synthetic IBAN $iban (debit / “withdraw” side for each rung)"
|
||||||
else
|
else
|
||||||
fail "geniban" "expected CH… IBAN" "$(printf '%s' "$iban_out" | tr '\n' ' ' | head -c 160)"
|
fail "geniban" "expected CH… IBAN" "$(printf '%s' "$iban_out" | tr '\n' ' ' | head -c 160)"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -92,55 +149,174 @@ if [ -z "$credit_payto" ]; then
|
||||||
fi
|
fi
|
||||||
ok "credit-payto" "$credit_payto"
|
ok "credit-payto" "$credit_payto"
|
||||||
|
|
||||||
# Subject: not a real reserve — nexus should bounce missing reserve public key
|
|
||||||
# (proves CHF fake-incoming path). Real reserve pub would credit wirewatch.
|
|
||||||
subject="mon-fake-franken-$(date -u +%Y%m%d%H%M%S)-$$"
|
|
||||||
debit_payto="payto://iban/${iban}?receiver-name=MonDevTest"
|
debit_payto="payto://iban/${iban}?receiver-name=MonDevTest"
|
||||||
|
ts_base=$(date -u +%Y%m%d%H%M%S)
|
||||||
|
|
||||||
set_group fake-incoming
|
# --- baseline plumbing probe ---
|
||||||
|
set_group baseline
|
||||||
|
subject="mon-fake-franken-${ts_base}-base-$$"
|
||||||
info "fake-incoming" "amount=${DEVTESTING_AMOUNT} subject=${subject}"
|
info "fake-incoming" "amount=${DEVTESTING_AMOUNT} subject=${subject}"
|
||||||
fi_rc=0
|
if run_fake_incoming "$DEVTESTING_AMOUNT" "$subject" "$credit_payto" "$debit_payto"; then
|
||||||
fi_out=$(ssh_dt fake-incoming \
|
case "$FI_STATUS" in
|
||||||
--amount "${DEVTESTING_AMOUNT}" \
|
ok_bounce)
|
||||||
--subject "${subject}" \
|
ok "fake-incoming" "CHF IN accepted by nexus · bounce/missing reserve pub — plumbing OK"
|
||||||
--credit-payto "${credit_payto}" \
|
info "note" "use real reserve pub as --subject for wirewatch credit (not required for mon probe)"
|
||||||
--debit-payto "${debit_payto}" 2>&1) || fi_rc=$?
|
;;
|
||||||
|
ok_in) ok "fake-incoming" "CHF IN recorded by nexus (no bounce line)" ;;
|
||||||
# Normalize multi-line for matching
|
ok_cli) ok "fake-incoming" "CLI completed CHF fake-incoming" ;;
|
||||||
fi_flat=$(printf '%s' "$fi_out" | tr '\n' ' ')
|
*) ok "fake-incoming" "status=${FI_STATUS}" ;;
|
||||||
|
esac
|
||||||
if printf '%s' "$fi_flat" | grep -qiE 'Permission denied|Connection refused|Could not resolve|No such command'; then
|
|
||||||
fail "fake-incoming" "SSH/CLI failure" "$(printf '%s' "$fi_flat" | head -c 200)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if printf '%s' "$fi_flat" | grep -qiE 'Creditor must be the exchange'; then
|
|
||||||
fail "fake-incoming" "wrong credit IBAN (not exchange)" "$(printf '%s' "$fi_flat" | head -c 220)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if printf '%s' "$fi_flat" | grep -qiE 'Missing amount|unable to read secrets|CalledProcessError'; then
|
|
||||||
# secrets warn alone is soft if we still see IN line
|
|
||||||
if ! printf '%s' "$fi_flat" | grep -qE 'libeufin-nexus - IN .* CHF'; then
|
|
||||||
fail "fake-incoming" "nexus rejected request" "$(printf '%s' "$fi_flat" | head -c 220)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if printf '%s' "$fi_flat" | grep -qE 'libeufin-nexus - IN .* CHF:[0-9]'; then
|
|
||||||
if printf '%s' "$fi_flat" | grep -qiE 'bounced.*missing reserve public key'; then
|
|
||||||
ok "fake-incoming" "CHF IN accepted by nexus · bounced (no reserve pub) — fake-franken plumbing OK"
|
|
||||||
info "note" "use real reserve pub as --subject for wirewatch credit (not required for mon probe)"
|
|
||||||
elif printf '%s' "$fi_flat" | grep -qiE 'bounced'; then
|
|
||||||
warn "fake-incoming" "CHF IN bounced (other reason)" "$(printf '%s' "$fi_flat" | grep -oiE 'bounced[^ ]* [^ ]*' | head -c 160)"
|
|
||||||
else
|
|
||||||
ok "fake-incoming" "CHF IN recorded by nexus (no bounce line)"
|
|
||||||
fi
|
|
||||||
elif [ "$fi_rc" -eq 0 ] && printf '%s' "$fi_flat" | grep -qi 'Faking incoming CHF'; then
|
|
||||||
ok "fake-incoming" "CLI completed CHF fake-incoming"
|
|
||||||
else
|
else
|
||||||
fail "fake-incoming" "no CHF IN line from nexus" "rc=${fi_rc} $(printf '%s' "$fi_flat" | head -c 200)"
|
case "$FI_STATUS" in
|
||||||
exit 1
|
fail_ssh)
|
||||||
|
fail "fake-incoming" "SSH/CLI failure" "$(printf '%s' "$FI_FLAT" | head -c 200)"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
fail_creditor)
|
||||||
|
fail "fake-incoming" "wrong credit IBAN (not exchange)" "$(printf '%s' "$FI_FLAT" | head -c 220)"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
fail_nexus)
|
||||||
|
fail "fake-incoming" "nexus rejected request" "$(printf '%s' "$FI_FLAT" | head -c 220)"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
fail "fake-incoming" "no CHF IN line from nexus" "rc=${FI_RC} $(printf '%s' "$FI_FLAT" | head -c 200)"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- CHF amount ladder (fake-incoming rungs) ---
|
||||||
|
if [ "${DEVTESTING_LADDER}" = "1" ]; then
|
||||||
|
set_group ladder
|
||||||
|
section "devtesting · CHF fake-incoming ladder (→ ${DEVTESTING_LADDER_MAX})"
|
||||||
|
|
||||||
|
LADDER_FILE=$(mktemp "${TMPDIR:-/tmp}/devtesting-ladder.XXXXXX")
|
||||||
|
python3 - <<'PY' "${DEVTESTING_LADDER_MAX}" "${DEVTESTING_LADDER_STEPS}" "${DEVTESTING_LADDER_MIN}" "$LADDER_FILE"
|
||||||
|
import math, sys
|
||||||
|
from decimal import Decimal, ROUND_HALF_UP
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
max_amt = Decimal(sys.argv[1])
|
||||||
|
steps = max(1, int(sys.argv[2]))
|
||||||
|
min_amt = Decimal(sys.argv[3])
|
||||||
|
out = Path(sys.argv[4])
|
||||||
|
if min_amt <= 0:
|
||||||
|
min_amt = Decimal("0.01")
|
||||||
|
if min_amt >= max_amt:
|
||||||
|
min_amt = max_amt / Decimal(1000)
|
||||||
|
# CHF: 2 decimal places
|
||||||
|
q2 = Decimal("0.01")
|
||||||
|
|
||||||
|
def quant(v: Decimal) -> Decimal:
|
||||||
|
if v < min_amt:
|
||||||
|
v = min_amt
|
||||||
|
return v.quantize(q2, rounding=ROUND_HALF_UP)
|
||||||
|
|
||||||
|
def fmt(v: Decimal) -> str:
|
||||||
|
q = quant(v)
|
||||||
|
if q == q.to_integral():
|
||||||
|
return str(int(q))
|
||||||
|
return format(q, "f")
|
||||||
|
|
||||||
|
if steps == 1:
|
||||||
|
amts = [quant(max_amt)]
|
||||||
|
elif steps == 2:
|
||||||
|
amts = [quant(min_amt), quant(max_amt)]
|
||||||
|
else:
|
||||||
|
# Exactly `steps` log-spaced rungs from min → max (includes both ends).
|
||||||
|
# Guarantees max rung = DEVTESTING_LADDER_MAX (“enough” volume at the top).
|
||||||
|
amts = []
|
||||||
|
lo, hi = float(min_amt), float(max_amt)
|
||||||
|
if hi <= lo:
|
||||||
|
hi = lo * 10
|
||||||
|
for i in range(steps):
|
||||||
|
if steps == 1:
|
||||||
|
v = max_amt
|
||||||
|
else:
|
||||||
|
t = i / (steps - 1)
|
||||||
|
v = Decimal(str(math.exp(math.log(lo) + t * (math.log(hi) - math.log(lo)))))
|
||||||
|
amts.append(quant(v))
|
||||||
|
amts[0] = quant(min_amt)
|
||||||
|
amts[-1] = quant(max_amt)
|
||||||
|
# enforce strictly increasing
|
||||||
|
for i in range(1, len(amts)):
|
||||||
|
if amts[i] <= amts[i - 1]:
|
||||||
|
amts[i] = quant(amts[i - 1] + min_amt)
|
||||||
|
amts[-1] = quant(max_amt)
|
||||||
|
if amts[-1] <= amts[-2]:
|
||||||
|
# last-but-one squeezed; leave max exact and drop collision by nudging previous
|
||||||
|
amts[-2] = quant(max(amts[-3] + min_amt if len(amts) > 2 else min_amt, max_amt - Decimal(1)))
|
||||||
|
if amts[-2] >= amts[-1]:
|
||||||
|
amts[-2] = quant(amts[-1] - min_amt)
|
||||||
|
|
||||||
|
lines = ["CHF:%s" % fmt(a) for a in amts]
|
||||||
|
out.write_text("\n".join(lines) + "\n")
|
||||||
|
PY
|
||||||
|
n_rungs=$(grep -cE '^CHF:' "$LADDER_FILE" || echo 0)
|
||||||
|
ladder_sum=$(python3 -c '
|
||||||
|
from decimal import Decimal
|
||||||
|
s=Decimal(0)
|
||||||
|
for ln in open("'"$LADDER_FILE"'"):
|
||||||
|
ln=ln.strip()
|
||||||
|
if not ln: continue
|
||||||
|
s += Decimal(ln.split(":",1)[-1])
|
||||||
|
print(s)
|
||||||
|
' 2>/dev/null || echo "?")
|
||||||
|
|
||||||
|
info "ladder plan" "steps=${n_rungs} max=CHF:${DEVTESTING_LADDER_MAX} min=CHF:${DEVTESTING_LADDER_MIN} sum≈CHF:${ladder_sum} (synthetic debit geniban each rung)"
|
||||||
|
info "ladder funding" "each rung uses geniban debit payto — no real bank withdraw; volume covers max rung CHF:${DEVTESTING_LADDER_MAX}"
|
||||||
|
|
||||||
|
LADDER_OK=0
|
||||||
|
LADDER_FAIL=0
|
||||||
|
LADDER_WARN=0
|
||||||
|
rung=0
|
||||||
|
while IFS= read -r amt || [ -n "$amt" ]; do
|
||||||
|
[ -n "$amt" ] || continue
|
||||||
|
rung=$((rung + 1))
|
||||||
|
subject="mon-fake-ladder-${ts_base}-r${rung}-$$"
|
||||||
|
info "rung ${rung}/${n_rungs}" "amount=${amt} subject=${subject}"
|
||||||
|
if run_fake_incoming "$amt" "$subject" "$credit_payto" "$debit_payto"; then
|
||||||
|
case "$FI_STATUS" in
|
||||||
|
ok_bounce)
|
||||||
|
ok "rung ${rung}" "${amt} · nexus IN + bounce (plumbing OK)"
|
||||||
|
LADDER_OK=$((LADDER_OK + 1))
|
||||||
|
;;
|
||||||
|
ok_in)
|
||||||
|
ok "rung ${rung}" "${amt} · nexus IN recorded"
|
||||||
|
LADDER_OK=$((LADDER_OK + 1))
|
||||||
|
;;
|
||||||
|
ok_cli)
|
||||||
|
ok "rung ${rung}" "${amt} · CLI ok"
|
||||||
|
LADDER_OK=$((LADDER_OK + 1))
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
warn "rung ${rung}" "${amt} · status=${FI_STATUS}"
|
||||||
|
LADDER_WARN=$((LADDER_WARN + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
fail "rung ${rung}" "${amt} · ${FI_STATUS}" "$(printf '%s' "$FI_FLAT" | head -c 180)"
|
||||||
|
LADDER_FAIL=$((LADDER_FAIL + 1))
|
||||||
|
if [ "${DEVTESTING_LADDER_STOP_ON_FAIL}" = "1" ]; then
|
||||||
|
warn "ladder stop" "DEVTESTING_LADDER_STOP_ON_FAIL=1 after rung ${rung}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done <"$LADDER_FILE"
|
||||||
|
rm -f "$LADDER_FILE"
|
||||||
|
|
||||||
|
info "ladder summary" "ok=${LADDER_OK} warn=${LADDER_WARN} fail=${LADDER_FAIL} / planned=${n_rungs} · max=CHF:${DEVTESTING_LADDER_MAX}"
|
||||||
|
if [ "$LADDER_FAIL" -gt 0 ] && [ "$LADDER_OK" -eq 0 ]; then
|
||||||
|
fail "ladder" "all rungs failed"
|
||||||
|
elif [ "$LADDER_FAIL" -gt 0 ]; then
|
||||||
|
warn "ladder" "partial failures fail=${LADDER_FAIL} ok=${LADDER_OK}"
|
||||||
|
else
|
||||||
|
ok "ladder complete" "ok=${LADDER_OK} through max CHF:${DEVTESTING_LADDER_MAX}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
info "ladder" "skipped (DEVTESTING_LADDER=0)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
info "done" "devtesting fake-franken probe finished"
|
info "done" "devtesting fake-franken probe finished"
|
||||||
|
|
|
||||||
8
host-agent/env/mytops-stage.env.example
vendored
8
host-agent/env/mytops-stage.env.example
vendored
|
|
@ -18,7 +18,8 @@ SKIP_SSH=1
|
||||||
LOCAL_STACK=0
|
LOCAL_STACK=0
|
||||||
INSIDE_PODMAN=0
|
INSIDE_PODMAN=0
|
||||||
CONTINUE_ON_ERROR=1
|
CONTINUE_ON_ERROR=1
|
||||||
RUN_TIMEOUT=600
|
# ladder needs wall time (23× fake-incoming SSH)
|
||||||
|
RUN_TIMEOUT=1800
|
||||||
STRICT_EXIT=1
|
STRICT_EXIT=1
|
||||||
MONPAGES_REQUIRE_PUBLIC=1
|
MONPAGES_REQUIRE_PUBLIC=1
|
||||||
MONPAGES_INVENTORY=job
|
MONPAGES_INVENTORY=job
|
||||||
|
|
@ -32,4 +33,9 @@ CHECK_LANDING=0
|
||||||
# rusty devtesting (SSH Host taler-rusty-devtesting → devtesting@rusty.taler-ops.ch)
|
# rusty devtesting (SSH Host taler-rusty-devtesting → devtesting@rusty.taler-ops.ch)
|
||||||
DEVTESTING_SSH=taler-rusty-devtesting
|
DEVTESTING_SSH=taler-rusty-devtesting
|
||||||
DEVTESTING_AMOUNT=CHF:1.00
|
DEVTESTING_AMOUNT=CHF:1.00
|
||||||
|
# CHF fake-incoming amount ladder (23 rungs → 50k)
|
||||||
|
DEVTESTING_LADDER=1
|
||||||
|
DEVTESTING_LADDER_STEPS=23
|
||||||
|
DEVTESTING_LADDER_MAX=50000
|
||||||
|
DEVTESTING_LADDER_MIN=0.01
|
||||||
# DEVTESTING_SKIP=1
|
# DEVTESTING_SKIP=1
|
||||||
|
|
|
||||||
|
|
@ -448,9 +448,14 @@ _progress_estimate_phase() {
|
||||||
;;
|
;;
|
||||||
mattermost) n=25 ;;
|
mattermost) n=25 ;;
|
||||||
mail) n=40 ;;
|
mail) n=40 ;;
|
||||||
# Happy path: ssh + cli + geniban + credit-payto + fake-incoming×2 + note + done ≈ 8
|
# baseline ~8 + ladder rungs (default 23 × ~2 lines) + summary
|
||||||
# (was 10 → mid-run 42/48 then snap 46/46 after last phase)
|
devtesting|franken|fake-franken|fake_franken)
|
||||||
devtesting|franken|fake-franken|fake_franken) n=8 ;;
|
n=8
|
||||||
|
if [ "${DEVTESTING_LADDER:-1}" != "0" ]; then
|
||||||
|
_ls="${DEVTESTING_LADDER_STEPS:-23}"
|
||||||
|
n=$((8 + _ls * 2 + 6))
|
||||||
|
fi
|
||||||
|
;;
|
||||||
*) n=15 ;;
|
*) n=15 ;;
|
||||||
esac
|
esac
|
||||||
printf '%s' "$n"
|
printf '%s' "$n"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue