test_template_limits.sh (6705B)
1 #!/usr/bin/env bash 2 # Exercise the startup limits around merchant templates and installed 3 # languages. The production defaults are intentionally tested at their real 4 # boundaries; the local stub keeps the run small in wall-clock time. 5 6 set -u 7 8 SRCDIR="${SRCDIR:-$(cd -- "$(dirname -- "$0")" && pwd)}" 9 BUILDDIR="${BUILDDIR:-$PWD}" 10 PAIVANA_HTTPD="${PAIVANA_HTTPD:-$BUILDDIR/../backend/paivana-httpd}" 11 PORT_BASE="${PAIVANA_PORT_BASE:-18400}" 12 # payment_backend_failure owns +120/+121 and Meson runs tests in parallel. 13 MERCHANT_PORT=$((PORT_BASE + 130)) 14 PAIVANA_PORT=$((PORT_BASE + 131)) 15 SCRATCH="$(mktemp -d -t paivana-template-limits.XXXXXX)" 16 STUB_PID="" 17 PAIVANA_PID="" 18 19 function cleanup() { 20 set +e 21 [ -n "$PAIVANA_PID" ] && kill -TERM "$PAIVANA_PID" 2>/dev/null 22 [ -n "$STUB_PID" ] && kill -TERM "$STUB_PID" 2>/dev/null 23 [ -n "$PAIVANA_PID" ] && wait "$PAIVANA_PID" 2>/dev/null 24 [ -n "$STUB_PID" ] && wait "$STUB_PID" 2>/dev/null 25 [ "${KEEP_TMP:-0}" = 1 ] || rm -rf "$SCRATCH" 26 } 27 trap cleanup EXIT 28 29 function fail() { 30 echo "FAIL: $*" >&2 31 tail -n 80 "$SCRATCH/paivana.log" >&2 2>/dev/null || true 32 tail -n 40 "$SCRATCH/stub.log" >&2 2>/dev/null || true 33 exit 1 34 } 35 36 function port_is_free() { 37 ! (exec 3<>"/dev/tcp/127.0.0.1/$1") 2>/dev/null 38 } 39 40 function wait_for_port() { 41 local port="$1" pid="$2" 42 for _ in $(seq 1 100); do 43 port_is_free "$port" || return 0 44 kill -0 "$pid" 2>/dev/null || return 1 45 sleep 0.05 46 done 47 return 1 48 } 49 50 function wait_for_exit() { 51 local pid="$1" 52 for _ in $(seq 1 100); do 53 kill -0 "$pid" 2>/dev/null || return 0 54 sleep 0.05 55 done 56 return 1 57 } 58 59 function stop_case() { 60 set +e 61 [ -n "$PAIVANA_PID" ] && kill -TERM "$PAIVANA_PID" 2>/dev/null 62 [ -n "$STUB_PID" ] && kill -TERM "$STUB_PID" 2>/dev/null 63 [ -n "$PAIVANA_PID" ] && wait "$PAIVANA_PID" 2>/dev/null 64 [ -n "$STUB_PID" ] && wait "$STUB_PID" 2>/dev/null 65 PAIVANA_PID="" 66 STUB_PID="" 67 set -u 68 } 69 70 PAYWALL_TEMPLATE="$BUILDDIR/../frontend/paywall.en.must" 71 [ -x "$PAIVANA_HTTPD" ] || { echo "SKIP: no paivana-httpd"; exit 77; } 72 [ -r "$PAYWALL_TEMPLATE" ] || { echo "SKIP: paywall template not built"; exit 77; } 73 command -v python3 >/dev/null || { echo "SKIP: no python3"; exit 77; } 74 port_is_free "$MERCHANT_PORT" || { echo "SKIP: port $MERCHANT_PORT busy"; exit 77; } 75 port_is_free "$PAIVANA_PORT" || { echo "SKIP: port $PAIVANA_PORT busy"; exit 77; } 76 77 mkdir -p "$SCRATCH/configd" "$SCRATCH/prefix/share/paivana/templates" 78 cp "$PAYWALL_TEMPLATE" "$SCRATCH/prefix/share/paivana/templates/" 79 # A visibly distinct second language lets the test verify that cache-key 80 # normalization reproduces the templating library's actual choice. 81 sed 's/<title>Payment Required<\/title>/<title>Zahlung Erforderlich<\/title>/' \ 82 "$PAYWALL_TEMPLATE" \ 83 >"$SCRATCH/prefix/share/paivana/templates/paywall.de.must" 84 export PAIVANA_BASE_CONFIG="$SCRATCH/configd" 85 export PAIVANA_PREFIX="$SCRATCH/prefix/" 86 87 cat >"$SCRATCH/paivana.conf" <<EOF 88 [paivana] 89 DESTINATION_BASE_URL = http://127.0.0.1:9/ 90 BASE_URL = http://127.0.0.1:$PAIVANA_PORT/ 91 MERCHANT_BACKEND_URL = http://127.0.0.1:$MERCHANT_PORT/ 92 MERCHANT_ACCESS_TOKEN = secret-token:stub 93 SECRET = template-limit-test 94 SERVE = tcp 95 BIND_TO = 127.0.0.1 96 PORT = $PAIVANA_PORT 97 EOF 98 99 function start_stub() { 100 local count="$1" padding="$2" delay="$3" 101 : >"$SCRATCH/stub.log" 102 PAIVANA_STUB_TEMPLATE_COUNT="$count" \ 103 PAIVANA_STUB_CONTRACT_PADDING="$padding" \ 104 PAIVANA_STUB_DETAIL_DELAY="$delay" \ 105 python3 "$SRCDIR/payment_backend_stub.py" "$MERCHANT_PORT" \ 106 >"$SCRATCH/stub.log" 2>&1 & 107 STUB_PID=$! 108 wait_for_port "$MERCHANT_PORT" "$STUB_PID" || fail "stub did not start" 109 } 110 111 function start_paivana() { 112 : >"$SCRATCH/paivana.log" 113 "$PAIVANA_HTTPD" -c "$SCRATCH/paivana.conf" -L DEBUG \ 114 >"$SCRATCH/paivana.log" 2>&1 & 115 PAIVANA_PID=$! 116 } 117 118 echo -n "template fetch concurrency is capped at eight ... " 119 start_stub 16 0 0.15 120 start_paivana 121 wait_for_port "$PAIVANA_PORT" "$PAIVANA_PID" || fail "16-template startup failed" 122 grep -q 'template detail concurrency 2' "$SCRATCH/stub.log" || \ 123 fail "template details were fetched serially instead of concurrently" 124 if grep -Eq 'template detail concurrency ([9]|[1-9][0-9]+)' "$SCRATCH/stub.log"; then 125 fail "more than eight template detail requests ran concurrently" 126 fi 127 echo "OK" 128 129 echo -n "Accept-Language variants normalize to the installed language ... " 130 for n in $(seq 1 40); do 131 curl -sS -H "Accept-Language: de, x-test-$n;q=0.1" \ 132 -o "$SCRATCH/paywall-$n.html" \ 133 "http://127.0.0.1:$PAIVANA_PORT/.well-known/paivana/templates/premium-0000" \ 134 || fail "paywall language request $n failed" 135 grep -q '<title>Zahlung Erforderlich</title>' "$SCRATCH/paywall-$n.html" || \ 136 fail "language request $n did not select the German template" 137 done 138 echo "OK" 139 stop_case 140 141 echo -n "a contract over one MiB is refused ... " 142 start_stub 1 1048576 0 143 start_paivana 144 wait_for_exit "$PAIVANA_PID" || fail "oversized-contract startup did not exit" 145 wait "$PAIVANA_PID" 2>/dev/null || true 146 PAIVANA_PID="" 147 grep -q 'exceeding the 1048576-byte' "$SCRATCH/paivana.log" || \ 148 fail "oversized contract had no limit diagnostic" 149 echo "OK" 150 stop_case 151 152 echo -n "more than 1024 discovered templates are refused before detail fetches ... " 153 start_stub 1025 0 0 154 start_paivana 155 wait_for_exit "$PAIVANA_PID" || fail "1025-template startup did not exit" 156 wait "$PAIVANA_PID" 2>/dev/null || true 157 PAIVANA_PID="" 158 grep -q 'exceeding the 1024-entry startup bound' "$SCRATCH/paivana.log" || \ 159 fail "discovery limit had no diagnostic" 160 if grep -q 'template detail concurrency' "$SCRATCH/stub.log"; then 161 fail "details were fetched after the discovery limit was exceeded" 162 fi 163 echo "OK" 164 stop_case 165 166 echo -n "more than 128 retained Paivana templates are refused ... " 167 start_stub 129 0 0 168 start_paivana 169 wait_for_exit "$PAIVANA_PID" || fail "129-template startup did not exit" 170 wait "$PAIVANA_PID" 2>/dev/null || true 171 PAIVANA_PID="" 172 grep -q 'more than 128 Paivana templates' "$SCRATCH/paivana.log" || \ 173 fail "retained-template limit had no diagnostic" 174 echo "OK" 175 stop_case 176 177 echo -n "more than 32 installed paywall languages are refused ... " 178 rm -f "$SCRATCH/prefix/share/paivana/templates/"* 179 for n in $(seq -w 0 32); do 180 cp "$PAYWALL_TEMPLATE" \ 181 "$SCRATCH/prefix/share/paivana/templates/paywall.l$n.must" 182 done 183 start_paivana 184 wait_for_exit "$PAIVANA_PID" || fail "33-language startup did not exit" 185 wait "$PAIVANA_PID" 2>/dev/null || true 186 PAIVANA_PID="" 187 grep -q 'More than 32 paywall languages' "$SCRATCH/paivana.log" || \ 188 fail "language limit had no diagnostic" 189 echo "OK" 190 191 echo "template startup limits: OK"