#!/usr/bin/env bash # test_invoke.sh — тестирует вызов функций: # NodeJS и Python: create → wait cold start → invoke → проверка тела. # Invoke несуществующей функции → 404. # ВАЖНО: использует livetest@test.local — прогретый namespace в kube кластере. # Для новых namespace fission router требует перезапуска (watchedNamespaces). set -uo pipefail ROOT_DIR=$(cd "$(dirname "$0")" && pwd) source "${ROOT_DIR}/lib.sh" RUN_ID=$(mk_run_id) # Используем прогретый namespace — fission router его знает. SUB="livetest@test.local" FN_NODE="node-fn-${RUN_ID}" FN_PY="py-fn-${RUN_ID}" cleanup() { # Удаляем только конкретные функции через API, не весь namespace. for fn in "$FN_NODE" "$FN_PY"; do curl -s -X DELETE "${BASE}/functions/${fn}" -H "X-Auth-Token: ${SUB}" > /dev/null 2>&1 || true done } trap cleanup EXIT echo "" echo "========================================" echo " test_invoke.sh run=$RUN_ID" echo "========================================" # ── Invoke несуществующей ───────────────────────────────────────────────── echo "" echo ">>> INVOKE несуществующей функции → 404" R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions/no-such-fn-xyz-${RUN_ID}/invoke" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" -d '{}') check_http "$(echo "$R" | tail -1)" "404" "INVOKE несуществующей → 404" # ── NodeJS ──────────────────────────────────────────────────────────────────── echo "" echo ">>> NodeJS: create + invoke" JS_CODE='module.exports = async function(ctx) { return { status: 200, body: "node-invoke-ok" }; }' R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ -d "{\"name\":\"${FN_NODE}\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") check_http "$(echo "$R" | tail -1)" "201" "NodeJS CREATE → 201" if wait_invoke "$SUB" "$FN_NODE" "node-invoke-ok" 12 5; then pass "NodeJS invoke → 200, тело содержит node-invoke-ok" else fail "NodeJS invoke не стабилизировался за 60s" fi # Второй вызов — проверяем что работает warm path R=$(curl -s --max-time 30 -X POST "${BASE}/functions/${FN_NODE}/invoke" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" -d '{}') STATUS=$(json_field "$R" status) [ "$STATUS" = "200" ] && pass "NodeJS второй invoke → 200 (warm)" || fail "NodeJS второй invoke → status=$STATUS" # ── Python ─────────────────────────────────────────────────────────────────── echo "" echo ">>> Python: create + invoke" PY_CODE=$(printf 'def main():\n return "py-invoke-ok", 200' | json_escape) R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ -d "{\"name\":\"${FN_PY}\",\"language\":\"python\",\"code\":${PY_CODE}}") check_http "$(echo "$R" | tail -1)" "201" "Python CREATE → 201" if wait_invoke "$SUB" "$FN_PY" "py-invoke-ok" 15 5; then pass "Python invoke → 200, тело содержит py-invoke-ok" else fail "Python invoke не стабилизировался за 75s" fi # ── Invoke возвращает корректные поля ───────────────────────────────────────── echo "" echo ">>> Invoke response fields" R=$(curl -s --max-time 30 -X POST "${BASE}/functions/${FN_NODE}/invoke" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" -d '{}') STATUS=$(json_field "$R" status) LATENCY=$(json_field "$R" latency_ms) RAW=$(json_field "$R" response_raw) [ "$STATUS" = "200" ] && pass "invoke.status = 200" || fail "invoke.status = $STATUS" printf '%s' "$LATENCY" | grep -qE '^[0-9]+$' && pass "invoke.latency_ms = $LATENCY ms" || fail "invoke.latency_ms не число: $LATENCY" [ -n "$RAW" ] && pass "invoke.response_raw непустой" || fail "invoke.response_raw пустой" print_summary