#!/usr/bin/env bash # test_ttl.sh — тестирует TTL функций: # CREATE с TTL → expires_at присутствует в ответе # CREATE без TTL → expires_at отсутствует # Невалидный TTL → 400 до создания объектов в k8s set -uo pipefail ROOT_DIR=$(cd "$(dirname "$0")" && pwd) source "${ROOT_DIR}/lib.sh" NS_CLEANUP_SCRIPT="${ROOT_DIR}/cleanup_test_namespaces.sh" RUN_ID=$(mk_run_id) SUB="test-ttl-${RUN_ID}@test.local" cleanup() { if [ -x "$NS_CLEANUP_SCRIPT" ]; then KUBECTL_DIRECT=1 "$NS_CLEANUP_SCRIPT" "$SUB" >/dev/null 2>&1 || true fi } trap cleanup EXIT echo "" echo "========================================" echo " test_ttl.sh run=$RUN_ID" echo "========================================" JS_CODE='module.exports = async function() { return { status: 200, body: "ok" }; }' # ── Без TTL ────────────────────────────────────────────────────────────────── echo "" echo ">>> CREATE без TTL → expires_at отсутствует" R=$(curl -s -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ -d "{\"name\":\"t-nttl-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") CODE_HTTP=$(printf '%s' "$R" | python3 -c "import sys; lines=sys.stdin.read().split('\n'); print(lines[-1] if lines else '')" 2>/dev/null || echo "?") EXPIRES=$(json_field "$R" expires_at) [ -z "$EXPIRES" ] && pass "CREATE без TTL: expires_at отсутствует" || fail "CREATE без TTL: expires_at='$EXPIRES'" # ── С TTL=15m ──────────────────────────────────────────────────────────────── echo "" echo ">>> CREATE с TTL=15m → expires_at присутствует" R=$(curl -s -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ -d "{\"name\":\"ttl15m-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape),\"ttl\":\"15m\"}") EXPIRES=$(json_field "$R" expires_at) [ -n "$EXPIRES" ] && pass "CREATE TTL=15m: expires_at=$EXPIRES" || fail "CREATE TTL=15m: expires_at пустой" # expires_at должен быть RFC3339 printf '%s' "$EXPIRES" | grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}T' && pass "expires_at формат RFC3339" || fail "expires_at не RFC3339: $EXPIRES" # ── С TTL=1h ───────────────────────────────────────────────────────────────── echo "" echo ">>> CREATE с TTL=1h → expires_at присутствует" R=$(curl -s -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ -d "{\"name\":\"ttl1h-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape),\"ttl\":\"1h\"}") EXPIRES=$(json_field "$R" expires_at) [ -n "$EXPIRES" ] && pass "CREATE TTL=1h: expires_at=$EXPIRES" || fail "CREATE TTL=1h: expires_at пустой" # ── С TTL=2d ───────────────────────────────────────────────────────────────── echo "" echo ">>> CREATE с TTL=2d → expires_at присутствует" R=$(curl -s -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ -d "{\"name\":\"ttl2d-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape),\"ttl\":\"2d\"}") EXPIRES=$(json_field "$R" expires_at) [ -n "$EXPIRES" ] && pass "CREATE TTL=2d: expires_at=$EXPIRES" || fail "CREATE TTL=2d: expires_at пустой" # ── Невалидный TTL ─────────────────────────────────────────────────────────── echo "" echo ">>> CREATE TTL невалидный → 400 (без создания объектов)" for badttl in "99z" "abc" "0d" "-1h" ""; do if [ -z "$badttl" ]; then continue; fi R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ -d "{\"name\":\"t-badttl-fn\",\"language\":\"nodejs\",\"code\":\"x\",\"ttl\":\"${badttl}\"}") CODE=$(echo "$R" | tail -1) [ "$CODE" = "400" ] && pass "TTL='$badttl' → 400" || fail "TTL='$badttl' → got $CODE" done # ── expires_at в LIST response ─────────────────────────────────────────────── echo "" echo ">>> LIST: функция с TTL видна в списке" LIST=$(curl -s "${BASE}/functions" -H "X-Auth-Token: ${SUB}") COUNT=$(json_len "$LIST") [ "${COUNT:-0}" -ge 3 ] && pass "LIST: видно ≥3 функции (2 с TTL, 1 без)" || fail "LIST: count=$COUNT" print_summary