paivana

HTTP paywall reverse proxy
Log | Files | Refs | Submodules | README | LICENSE

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"