diff --git a/console/internal/auth/auth.go b/console/internal/auth/auth.go index 1b5a606..2f75662 100644 --- a/console/internal/auth/auth.go +++ b/console/internal/auth/auth.go @@ -25,10 +25,14 @@ type UserIdentity struct { Email string // email — опционально, для отображения в UI } -// NamespaceForSub вычисляет детерминированный K8s namespace из Sub: -// "fission-" + hex(SHA256(sub)[:8]) +// NamespaceForSub вычисляет детерминированный K8s namespace из Sub. +// Если sub начинается с "test-" → "fission-test-" + hex(SHA256(sub)[:8]) +// Иначе → "fission-" + hex(SHA256(sub)[:8]) func NamespaceForSub(sub string) string { h := sha256.Sum256([]byte(sub)) + if strings.HasPrefix(sub, "test-") { + return "fission-test-" + hex.EncodeToString(h[:8]) + } return "fission-" + hex.EncodeToString(h[:8]) } diff --git a/console/internal/fission/namespace.go b/console/internal/fission/namespace.go index 95c491d..f508e75 100644 --- a/console/internal/fission/namespace.go +++ b/console/internal/fission/namespace.go @@ -12,6 +12,7 @@ import ( "fmt" "log" "os" + "strings" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -37,16 +38,20 @@ import ( // (не ClusterRoleBinding) безопасен — даёт полный доступ только внутри NS. func SetupFissionNamespace(ctx context.Context, dyn dynamic.Interface, ns string) error { // 1. Namespace + labels := map[string]any{ + "managed-by": "fission-console", + "fission.io/managed": "true", // Layer 1: executor NSWatcher auto-discovers this NS + } + if strings.HasPrefix(ns, "fission-test-") { + labels["fission-console/env"] = "test" + } nsObj := &unstructured.Unstructured{ Object: map[string]any{ "apiVersion": "v1", "kind": "Namespace", "metadata": map[string]any{ - "name": ns, - "labels": map[string]any{ - "managed-by": "fission-console", - "fission.io/managed": "true", // Layer 1: executor NSWatcher auto-discovers this NS - }, + "name": ns, + "labels": labels, }, }, } diff --git a/scripts/cleanup_test_namespaces.sh b/scripts/cleanup_test_namespaces.sh index c5e47a5..bbf5ed3 100755 --- a/scripts/cleanup_test_namespaces.sh +++ b/scripts/cleanup_test_namespaces.sh @@ -16,13 +16,32 @@ kube_exec() { fi } +# Зеркало логики Go NamespaceForSub: +# sub начинается с "test-" → "fission-test-" + sha256[:8*2] +# иначе → "fission-" + sha256[:8*2] namespace_for_sub() { - printf '%s' "$1" | sha256sum | awk '{print "fission-" substr($1, 1, 16)}' + local sub="$1" + local hash + hash=$(printf '%s' "$sub" | sha256sum | awk '{print substr($1, 1, 16)}') + if [[ "$sub" == test-* ]]; then + echo "fission-test-${hash}" + else + echo "fission-${hash}" + fi } +# ⛔ АБСОЛЮТНЫЙ GUARD: удалять ТОЛЬКО namespace-ы вида fission-test-* +# Всё остальное — немедленный выход с ошибкой delete_ns() { local ns="$1" [ -n "$ns" ] || return 0 + + # ЖЁСТКАЯ ЗАЩИТА: только fission-test-* разрешено удалять + if [[ "$ns" != fission-test-* ]]; then + echo "⛔ ОТКАЗ: '$ns' не является тестовым namespace (должно начинаться с 'fission-test-')" >&2 + return 1 + fi + if [ "${KUBECTL_DIRECT:-0}" = "1" ]; then kubectl delete namespace "$ns" --wait=false >/dev/null 2>&1 || true else @@ -31,15 +50,16 @@ delete_ns() { echo "cleanup namespace: ${ns}" } -delete_all_console_managed() { +# --all-test: удалить все namespace-ы с лейблом fission-console/env=test +# (только fission-test-* по определению) +delete_all_test() { local ns_list if [ "${KUBECTL_DIRECT:-0}" = "1" ]; then - ns_list=$(kubectl get ns -l managed-by=fission-console -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null || true) + ns_list=$(kubectl get ns -l 'fission-console/env=test' --no-headers \ + -o custom-columns=":metadata.name" 2>/dev/null || true) else - ns_list=$(ssh "${SSH_ARGS[@]}" ' -set -e -kubectl get ns -l managed-by=fission-console -o jsonpath="{range .items[*]}{.metadata.name}{"\n"}{end}" 2>/dev/null || true -' ) + ns_list=$(ssh "${SSH_ARGS[@]}" \ + 'kubectl get ns -l "fission-console/env=test" --no-headers -o custom-columns=":metadata.name" 2>/dev/null || true') fi printf '%s\n' "$ns_list" | while IFS= read -r ns; do [ -n "$ns" ] || continue @@ -48,12 +68,12 @@ kubectl get ns -l managed-by=fission-console -o jsonpath="{range .items[*]}{.met } if [ "$#" -eq 0 ]; then - echo "usage: $0 SUB [SUB ...] | --all-console-managed" >&2 + echo "usage: $0 SUB [SUB ...] | --all-test" >&2 exit 1 fi -if [ "$1" = "--all-console-managed" ]; then - delete_all_console_managed +if [ "$1" = "--all-test" ]; then + delete_all_test exit 0 fi diff --git a/scripts/test_auth.sh b/scripts/test_auth.sh index 3aea09c..4a24ab7 100755 --- a/scripts/test_auth.sh +++ b/scripts/test_auth.sh @@ -11,7 +11,7 @@ source "${ROOT_DIR}/lib.sh" NS_CLEANUP_SCRIPT="${ROOT_DIR}/cleanup_test_namespaces.sh" RUN_ID=$(mk_run_id) -SUB="auth-test-${RUN_ID}@test.local" +SUB="test-auth-${RUN_ID}@test.local" cleanup() { if [ -x "$NS_CLEANUP_SCRIPT" ]; then diff --git a/scripts/test_functions_crud.sh b/scripts/test_functions_crud.sh index b561bfa..19291fb 100755 --- a/scripts/test_functions_crud.sh +++ b/scripts/test_functions_crud.sh @@ -9,7 +9,7 @@ source "${ROOT_DIR}/lib.sh" NS_CLEANUP_SCRIPT="${ROOT_DIR}/cleanup_test_namespaces.sh" RUN_ID=$(mk_run_id) -SUB="crud-${RUN_ID}@test.local" +SUB="test-crud-${RUN_ID}@test.local" cleanup() { if [ -x "$NS_CLEANUP_SCRIPT" ]; then @@ -31,14 +31,14 @@ echo "" echo ">>> CREATE: базовый nodejs → 201" R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ - -d "{\"name\":\"crud-fn-${RUN_ID}\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") + -d "{\"name\":\"t-crud-fn-${RUN_ID}\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") CODE=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') check_http "$CODE" "201" "CREATE nodejs → 201" FN_NAME=$(json_field "$BODY" name) FN_ROUTE=$(json_field "$BODY" route) FN_PKG=$(json_field "$BODY" package) -[ "$FN_NAME" = "crud-fn-${RUN_ID}" ] && pass "CREATE: name в ответе" || fail "CREATE: name='$FN_NAME'" +[ "$FN_NAME" = "t-crud-fn-${RUN_ID}" ] && pass "CREATE: name в ответе" || fail "CREATE: name='$FN_NAME'" printf '%s' "$FN_ROUTE" | grep -q '/' && pass "CREATE: route непустой" || fail "CREATE: route='$FN_ROUTE'" [ -n "$FN_PKG" ] && pass "CREATE: package непустой" || fail "CREATE: package пустой" @@ -46,7 +46,7 @@ echo "" echo ">>> CREATE: дубликат → 409" R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${SUB}" -H "Content-Type: application/json" \ - -d "{\"name\":\"crud-fn-${RUN_ID}\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") + -d "{\"name\":\"t-crud-fn-${RUN_ID}\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") check_http "$(echo "$R" | tail -1)" "409" "CREATE дубликат → 409" echo "" @@ -158,13 +158,13 @@ COUNT=$(json_len "$BODY") echo "" echo ">>> GET: /functions/{name} → 200" -R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/crud-fn-${RUN_ID}" \ +R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/t-crud-fn-${RUN_ID}" \ -H "X-Auth-Token: ${SUB}") CODE=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') -check_http "$CODE" "200" "GET /functions/crud-fn-${RUN_ID} → 200" +check_http "$CODE" "200" "GET /functions/t-crud-fn-${RUN_ID} → 200" GOT_NAME=$(json_field "$BODY" name) -[ "$GOT_NAME" = "crud-fn-${RUN_ID}" ] && pass "GET: name совпадает" || fail "GET: name='$GOT_NAME'" +[ "$GOT_NAME" = "t-crud-fn-${RUN_ID}" ] && pass "GET: name совпадает" || fail "GET: name='$GOT_NAME'" GOT_ENV=$(json_field "$BODY" environment) [ -n "$GOT_ENV" ] && pass "GET: environment непустой ($GOT_ENV)" || fail "GET: environment пустой" @@ -178,7 +178,7 @@ check_http "$(echo "$R" | tail -1)" "404" "GET несуществующая → echo "" echo ">>> DELETE: /functions/{name} → 200" -R=$(curl -s -w "\n%{http_code}" -X DELETE "${BASE}/functions/crud-fn-${RUN_ID}" \ +R=$(curl -s -w "\n%{http_code}" -X DELETE "${BASE}/functions/t-crud-fn-${RUN_ID}" \ -H "X-Auth-Token: ${SUB}") CODE=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') @@ -188,13 +188,13 @@ DELETED=$(json_field "$BODY" deleted) echo "" echo ">>> DELETE: повторное удаление → 404" -R=$(curl -s -w "\n%{http_code}" -X DELETE "${BASE}/functions/crud-fn-${RUN_ID}" \ +R=$(curl -s -w "\n%{http_code}" -X DELETE "${BASE}/functions/t-crud-fn-${RUN_ID}" \ -H "X-Auth-Token: ${SUB}") check_http "$(echo "$R" | tail -1)" "404" "DELETE повторное → 404" echo "" echo ">>> GET: после DELETE → 404" -R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/crud-fn-${RUN_ID}" \ +R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/t-crud-fn-${RUN_ID}" \ -H "X-Auth-Token: ${SUB}") check_http "$(echo "$R" | tail -1)" "404" "GET после DELETE → 404" diff --git a/scripts/test_invoke.sh b/scripts/test_invoke.sh index 95b1462..f2663cb 100755 --- a/scripts/test_invoke.sh +++ b/scripts/test_invoke.sh @@ -11,9 +11,9 @@ 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}" +SUB="test-livetest@test.local" +FN_NODE="t-node-fn-${RUN_ID}" +FN_PY="t-py-fn-${RUN_ID}" cleanup() { # Удаляем только конкретные функции через API, не весь namespace. diff --git a/scripts/test_isolation.sh b/scripts/test_isolation.sh index 202fe23..27293f5 100755 --- a/scripts/test_isolation.sh +++ b/scripts/test_isolation.sh @@ -9,8 +9,8 @@ source "${ROOT_DIR}/lib.sh" NS_CLEANUP_SCRIPT="${ROOT_DIR}/cleanup_test_namespaces.sh" RUN_ID=$(mk_run_id) -ALICE="alice-${RUN_ID}@test.local" -BOB="bob-${RUN_ID}@test.local" +ALICE="test-alice-${RUN_ID}@test.local" +BOB="test-bob-${RUN_ID}@test.local" cleanup() { if [ -x "$NS_CLEANUP_SCRIPT" ]; then @@ -32,43 +32,43 @@ echo "" echo ">>> Alice создаёт функцию" R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${ALICE}" -H "Content-Type: application/json" \ - -d "{\"name\":\"alice-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") -check_http "$(echo "$R" | tail -1)" "201" "Alice CREATE alice-fn → 201" + -d "{\"name\":\"t-alice-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") +check_http "$(echo "$R" | tail -1)" "201" "Alice CREATE t-alice-fn → 201" # ── Bob не может получить функцию Alice ────────────────────────────────────── echo "" -echo ">>> Bob GET alice-fn → 404" -R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/alice-fn" \ +echo ">>> Bob GET t-alice-fn → 404" +R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/t-alice-fn" \ -H "X-Auth-Token: ${BOB}") -check_http "$(echo "$R" | tail -1)" "404" "Bob GET alice-fn → 404" +check_http "$(echo "$R" | tail -1)" "404" "Bob GET t-alice-fn → 404" echo "" -echo ">>> Bob DELETE alice-fn → 404" -R=$(curl -s -w "\n%{http_code}" -X DELETE "${BASE}/functions/alice-fn" \ +echo ">>> Bob DELETE t-alice-fn → 404" +R=$(curl -s -w "\n%{http_code}" -X DELETE "${BASE}/functions/t-alice-fn" \ -H "X-Auth-Token: ${BOB}") -check_http "$(echo "$R" | tail -1)" "404" "Bob DELETE alice-fn → 404" +check_http "$(echo "$R" | tail -1)" "404" "Bob DELETE t-alice-fn → 404" echo "" -echo ">>> Bob PUT alice-fn/code → 404" -R=$(curl -s -w "\n%{http_code}" -X PUT "${BASE}/functions/alice-fn/code" \ +echo ">>> Bob PUT t-alice-fn/code → 404" +R=$(curl -s -w "\n%{http_code}" -X PUT "${BASE}/functions/t-alice-fn/code" \ -H "X-Auth-Token: ${BOB}" -H "Content-Type: application/json" \ -d '{"code":"module.exports = async () => ({ body: \"hacked\" });"}') -check_http "$(echo "$R" | tail -1)" "404" "Bob PUT alice-fn/code → 404" +check_http "$(echo "$R" | tail -1)" "404" "Bob PUT t-alice-fn/code → 404" echo "" -echo ">>> Bob INVOKE alice-fn → 404" -R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions/alice-fn/invoke" \ +echo ">>> Bob INVOKE t-alice-fn → 404" +R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/functions/t-alice-fn/invoke" \ -H "X-Auth-Token: ${BOB}" -H "Content-Type: application/json" -d '{}') -check_http "$(echo "$R" | tail -1)" "404" "Bob INVOKE alice-fn → 404" +check_http "$(echo "$R" | tail -1)" "404" "Bob INVOKE t-alice-fn → 404" # ── Alice убеждается что её функция цела ──────────────────────────────────── echo "" -echo ">>> Alice GET alice-fn → 200 (не повреждена)" -R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/alice-fn" \ +echo ">>> Alice GET t-alice-fn → 200 (не повреждена)" +R=$(curl -s -w "\n%{http_code}" "${BASE}/functions/t-alice-fn" \ -H "X-Auth-Token: ${ALICE}") -check_http "$(echo "$R" | tail -1)" "200" "Alice GET alice-fn → 200" +check_http "$(echo "$R" | tail -1)" "200" "Alice GET t-alice-fn → 200" # ── LIST изоляция ──────────────────────────────────────────────────────────── @@ -78,51 +78,51 @@ echo ">>> LIST изоляция: Alice и Bob видят только свои # Bob создаёт свою функцию curl -s -X POST "${BASE}/functions" \ -H "X-Auth-Token: ${BOB}" -H "Content-Type: application/json" \ - -d "{\"name\":\"bob-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}" > /dev/null + -d "{\"name\":\"t-bob-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}" > /dev/null sleep 1 ALICE_LIST=$(curl -s "${BASE}/functions" -H "X-Auth-Token: ${ALICE}") BOB_LIST=$(curl -s "${BASE}/functions" -H "X-Auth-Token: ${BOB}") -# Alice видит alice-fn но не bob-fn +# Alice видит t-alice-fn но не t-bob-fn ALICE_COUNT=$(json_len "$ALICE_LIST") ALICE_HAS_OWN=$(printf '%s' "$ALICE_LIST" | python3 -c " import json, sys try: fns = json.load(sys.stdin) - print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 'alice-fn')) + print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 't-t-alice-fn')) except: print(0)" 2>/dev/null) ALICE_HAS_BOB=$(printf '%s' "$ALICE_LIST" | python3 -c " import json, sys try: fns = json.load(sys.stdin) - print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 'bob-fn')) + print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 't-t-bob-fn')) except: print(0)" 2>/dev/null) -[ "${ALICE_HAS_OWN:-0}" -ge 1 ] && pass "Alice LIST содержит alice-fn" || fail "Alice LIST не содержит alice-fn (count=$ALICE_COUNT)" -[ "${ALICE_HAS_BOB:-0}" -eq 0 ] && pass "Alice LIST не содержит bob-fn" || fail "Alice LIST содержит bob-fn — УТЕЧКА ДАННЫХ!" +[ "${ALICE_HAS_OWN:-0}" -ge 1 ] && pass "Alice LIST содержит t-alice-fn" || fail "Alice LIST не содержит t-alice-fn (count=$ALICE_COUNT)" +[ "${ALICE_HAS_BOB:-0}" -eq 0 ] && pass "Alice LIST не содержит t-bob-fn" || fail "Alice LIST содержит t-bob-fn — УТЕЧКА ДАННЫХ!" -# Bob видит bob-fn но не alice-fn +# Bob видит t-bob-fn но не t-alice-fn BOB_HAS_OWN=$(printf '%s' "$BOB_LIST" | python3 -c " import json, sys try: fns = json.load(sys.stdin) - print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 'bob-fn')) + print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 't-t-bob-fn')) except: print(0)" 2>/dev/null) BOB_HAS_ALICE=$(printf '%s' "$BOB_LIST" | python3 -c " import json, sys try: fns = json.load(sys.stdin) - print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 'alice-fn')) + print(sum(1 for f in fns if f.get('metadata',{}).get('name','') == 't-t-alice-fn')) except: print(0)" 2>/dev/null) -[ "${BOB_HAS_OWN:-0}" -ge 1 ] && pass "Bob LIST содержит bob-fn" || fail "Bob LIST не содержит bob-fn" -[ "${BOB_HAS_ALICE:-0}" -eq 0 ] && pass "Bob LIST не содержит alice-fn" || fail "Bob LIST содержит alice-fn — УТЕЧКА ДАННЫХ!" +[ "${BOB_HAS_OWN:-0}" -ge 1 ] && pass "Bob LIST содержит t-bob-fn" || fail "Bob LIST не содержит t-bob-fn" +[ "${BOB_HAS_ALICE:-0}" -eq 0 ] && pass "Bob LIST не содержит t-alice-fn" || fail "Bob LIST содержит t-alice-fn — УТЕЧКА ДАННЫХ!" # ── Route изоляция ─────────────────────────────────────────────────────────── @@ -133,7 +133,7 @@ import json, sys try: fns = json.load(sys.stdin) for f in fns: - if f.get('metadata',{}).get('name','') == 'alice-fn': + if f.get('metadata',{}).get('name','') == 't-t-alice-fn': print(f.get('spec',{}).get('relativeurl','')) break except: @@ -144,15 +144,15 @@ import json, sys try: fns = json.load(sys.stdin) for f in fns: - if f.get('metadata',{}).get('name','') == 'bob-fn': + if f.get('metadata',{}).get('name','') == 't-t-bob-fn': print(f.get('spec',{}).get('relativeurl','')) break except: print('')" 2>/dev/null) # Проверяем через GET (возвращает route) -ALICE_GET=$(curl -s "${BASE}/functions/alice-fn" -H "X-Auth-Token: ${ALICE}") -BOB_GET=$(curl -s "${BASE}/functions/bob-fn" -H "X-Auth-Token: ${BOB}") +ALICE_GET=$(curl -s "${BASE}/functions/t-alice-fn" -H "X-Auth-Token: ${ALICE}") +BOB_GET=$(curl -s "${BASE}/functions/t-bob-fn" -H "X-Auth-Token: ${BOB}") ROUTE_A=$(json_field "$ALICE_GET" route) ROUTE_B=$(json_field "$BOB_GET" route) [ "$ROUTE_A" != "$ROUTE_B" ] && [ -n "$ROUTE_A" ] && [ -n "$ROUTE_B" ] \ diff --git a/scripts/test_stress.sh b/scripts/test_stress.sh index 51204ac..4fca7ed 100755 --- a/scripts/test_stress.sh +++ b/scripts/test_stress.sh @@ -13,17 +13,17 @@ NS_CLEANUP_SCRIPT="${ROOT_DIR}/cleanup_test_namespaces.sh" RUN_ID=$(mk_run_id) COUNT="${1:-8}" TMP=$(mktemp -d) -INVOKE_SUB="livetest@test.local" +INVOKE_SUB="test-livetest@test.local" INVOKE_COUNT=8 declare -a SUBS=() for i in $(seq 1 "$COUNT"); do - SUBS+=("stress-${RUN_ID}-u${i}@test.local") + SUBS+=("test-stress-${RUN_ID}-u${i}@test.local") done declare -a INVOKE_FNS=() for i in $(seq 1 "$INVOKE_COUNT"); do - INVOKE_FNS+=("sinv-${RUN_ID}-${i}") + INVOKE_FNS+=("t-sinv-${RUN_ID}-${i}") done cleanup() { diff --git a/scripts/test_ttl.sh b/scripts/test_ttl.sh index 18e0ac0..41587d0 100755 --- a/scripts/test_ttl.sh +++ b/scripts/test_ttl.sh @@ -10,7 +10,7 @@ source "${ROOT_DIR}/lib.sh" NS_CLEANUP_SCRIPT="${ROOT_DIR}/cleanup_test_namespaces.sh" RUN_ID=$(mk_run_id) -SUB="ttl-${RUN_ID}@test.local" +SUB="test-ttl-${RUN_ID}@test.local" cleanup() { if [ -x "$NS_CLEANUP_SCRIPT" ]; then @@ -32,7 +32,7 @@ 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\":\"nttl-fn\",\"language\":\"nodejs\",\"code\":$(printf '%s' "$JS_CODE" | json_escape)}") + -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'" @@ -77,7 +77,7 @@ 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\":\"badttl-fn\",\"language\":\"nodejs\",\"code\":\"x\",\"ttl\":\"${badttl}\"}") + -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 diff --git a/scripts/test_update.sh b/scripts/test_update.sh index d25b7e2..b93d14d 100755 --- a/scripts/test_update.sh +++ b/scripts/test_update.sh @@ -11,8 +11,8 @@ ROOT_DIR=$(cd "$(dirname "$0")" && pwd) source "${ROOT_DIR}/lib.sh" RUN_ID=$(mk_run_id) -SUB="livetest@test.local" -FN="upd-fn-${RUN_ID}" +SUB="test-livetest@test.local" +FN="t-upd-fn-${RUN_ID}" cleanup() { curl -s -X DELETE "${BASE}/functions/${FN}" -H "X-Auth-Token: ${SUB}" > /dev/null 2>&1 || true