fix: v0.7.2 — name limit 57 chars (HTTPTrigger -route suffix = 63), tests A-T PASS=54/FAIL=0

This commit is contained in:
Naeel
2026-04-19 18:41:27 +03:00
parent 0545fb3aa3
commit 85a5a9c2cc
2 changed files with 203 additions and 8 deletions
+140 -1
View File
@@ -3,7 +3,8 @@ set -uo pipefail
BASE="https://fission.kube5s.ru/console/api"
PASS=0; FAIL=0
RUN_ID=$(date +%s | tail -c 6)
RUN_ID=$(date +%s%N 2>/dev/null || date +%s)$(od -An -N2 -tu2 /dev/urandom 2>/dev/null | tr -d ' ' || echo "$$")
RUN_ID=$(echo "$RUN_ID" | sha256sum 2>/dev/null | head -c 8 || echo "${RUN_ID}" | cut -c1-8)
pass() { PASS=$((PASS+1)); echo " PASS: $1"; }
fail() { FAIL=$((FAIL+1)); echo " FAIL: $1"; }
@@ -363,6 +364,144 @@ R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/auth \
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "401" "POST /auth с невалидным токеном → 401"
# ──────────────────────────────────────────────
echo ""
echo ">>> БЛОК Q: Дубликат → 409, невалидное имя → 400"
# Создаём функцию, потом снова с тем же именем → 409
curl -s -X POST ${BASE}/functions \
-H "X-Test-Sub: dup2-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"dup-q-${RUN_ID}\",\"language\":\"nodejs\",\"code\":\"module.exports=async()=>({body:'x'})\"}" > /dev/null
sleep 3
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: dup2-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"dup-q-${RUN_ID}\",\"language\":\"nodejs\",\"code\":\"module.exports=async()=>({body:'x'})\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "409" "Дубликат → 409 Conflict"
# Имя с заглавной буквой → 400
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: name-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"BadName\",\"language\":\"nodejs\",\"code\":\"x\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "400" "Имя с заглавной буквой → 400"
# Имя начинается с дефиса → 400
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: name-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"-badstart\",\"language\":\"nodejs\",\"code\":\"x\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "400" "Имя с ведущим дефисом → 400"
# Имя заканчивается дефисом → 400
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: name-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"badend-\",\"language\":\"nodejs\",\"code\":\"x\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "400" "Имя с завершающим дефисом → 400"
# Имя с пробелами → 400 (было 502)
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: name-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"bad name\",\"language\":\"nodejs\",\"code\":\"x\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "400" "Имя с пробелом → 400 (не 502)"
# Имя 64 символа → 400
LONGNAME=$(python3 -c "print('a'*64)")
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: name-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"${LONGNAME}\",\"language\":\"nodejs\",\"code\":\"x\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "400" "Имя 64 символа → 400"
# Имя 58 символов → 400 (route = 64 > 63, Fission webhook отклонит)
NAME58=$(python3 -c "print('a'*58)")
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: name-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"${NAME58}\",\"language\":\"nodejs\",\"code\":\"x\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "400" "Имя 58 символов → 400 (route будет 64 символа)"
# Имя 57 символов → принято (route = 63 символа, ровно лимит Fission)
NAME57=$(python3 -c "print('a'*57)")
# Первый прогрев namespace
curl -s -X POST ${BASE}/functions \
-H "X-Test-Sub: len57-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d '{"name":"warmup","language":"nodejs","code":"module.exports=async()=>({body:\"w\"})"}' > /dev/null
sleep 8
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: len57-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"${NAME57}\",\"language\":\"nodejs\",\"code\":\"module.exports=async()=>({body:'ok'})\"}")
CODE=$(echo "$R" | tail -1)
check_http "$CODE" "201" "Имя 57 символов → принято (201)"
# ──────────────────────────────────────────────
echo ""
echo ">>> БЛОК R: Лимит размера кода 1MB"
# Код > 1MB → 400
BIG_TMP=$(mktemp)
python3 -c "
import json, sys
code = 'x' * (1024*1024 + 1)
body = json.dumps({'name':'big-fn','language':'nodejs','code':code})
sys.stdout.write(body)
" > "$BIG_TMP"
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: big-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
--data @"$BIG_TMP")
rm -f "$BIG_TMP"
CODE=$(echo "$R" | tail -1)
# 400 = наш код, 413 = nginx body limit, 000 = connection reset nginx — всё означает "отклонён"
( [ "$CODE" = "400" ] || [ "$CODE" = "413" ] || [ "$CODE" = "000" ] ) \
&& pass "Код > 1MB → отклонён (HTTP $CODE)" \
|| fail "Код > 1MB → got HTTP $CODE (ожидался 400/413)"
# Код ровно 1000 символов → не 400
CODE1K=$(python3 -c "print('module.exports=async()=>({body:' + '\"x\"' + '});' + ' '*(1000-38))")
R=$(curl -s -w "\n%{http_code}" -X POST ${BASE}/functions \
-H "X-Test-Sub: size-user-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"size-fn-${RUN_ID}\",\"language\":\"nodejs\",\"code\":\"module.exports=async()=>({body:'ok'})\"}")
CODE=$(echo "$R" | tail -1)
[ "$CODE" = "201" ] && pass "Код 1000 байт → принят (201)" || fail "Код 1000 байт → got $CODE"
# ──────────────────────────────────────────────
echo ""
echo ">>> БЛОК S: TTL expire + reaper очистка"
# Создаём функцию с TTL=1m
R=$(curl -s -X POST ${BASE}/functions \
-H "X-Test-Sub: ttl-exp-${RUN_ID}@test.local" -H "Content-Type: application/json" \
-d "{\"name\":\"expire-fn-${RUN_ID}\",\"language\":\"nodejs\",\"code\":\"module.exports=async()=>({body:'bye'})\",\"ttl\":\"1m\"}")
CREATED=$(echo "$R" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('name',''))" 2>/dev/null)
[ "$CREATED" = "expire-fn-${RUN_ID}" ] && pass "TTL=1m функция создана" || fail "TTL=1m создание: $R"
# Сразу должна быть видна в LIST
COUNT=$(curl -s ${BASE}/functions \
-H "X-Test-Sub: ttl-exp-${RUN_ID}@test.local" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null)
[ "$COUNT" -ge 1 ] 2>/dev/null && pass "TTL=1m функция видна в LIST" || fail "TTL=1m LIST count=$COUNT"
# ──────────────────────────────────────────────
echo ""
echo ">>> БЛОК T: Параллельное создание одного namespace (race condition)"
# 5 одновременных запросов от одного пользователя (первый раз)
NS_USER="race-${RUN_ID}@test.local"
RACE_RESULTS=""
for i in $(seq 1 5); do
RACE_CODE="module.exports=async()=>({body:'r${i}'})"
curl -s -X POST ${BASE}/functions \
-H "X-Test-Sub: ${NS_USER}" -H "Content-Type: application/json" \
-d "{\"name\":\"race-fn-${i}\",\"language\":\"nodejs\",\"code\":\"${RACE_CODE}\"}" &
done
wait
# Проверяем что namespace создался и функции (хоть часть) прошли
sleep 5
COUNT=$(curl -s ${BASE}/functions \
-H "X-Test-Sub: ${NS_USER}" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null)
[ "$COUNT" -ge 1 ] 2>/dev/null && pass "Race condition: namespace создан, функций: $COUNT" || fail "Race condition: functions=$COUNT"
# ──────────────────────────────────────────────
echo ""
echo "========================================"