test(shared-sqs): add quick_test.sh (19 tests), extend hardcore_test.sh (groups 24-28, UI API)
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
# Изменено: 2026-04-09
|
||||
# Покрывает: Admin API, AWS CLI CRUD, awscurl CRUD, кросс-доставка,
|
||||
# изоляция тенантов, невалидный ввод, спецсимволы,
|
||||
# visibility timeout, batch, лимиты очередей, cleanup тенанта.
|
||||
# visibility timeout, batch, лимиты очередей, cleanup тенанта,
|
||||
# UI API (create/delete queue, send/peek/purge messages, изоляция).
|
||||
# Запуск: BASE_URL=https://qu.kube5s.ru ADMIN_TOKEN=... bash tests/hardcore_test.sh
|
||||
|
||||
set -uo pipefail
|
||||
@@ -899,12 +900,169 @@ sqs "$T1_AK" "$T1_SK" delete-queue --queue-url "$ENC_QURL" >/dev/null 2>&1 || tr
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── Cleanup: удаляем тестовых тенантов ──"
|
||||
echo "── 24. UI API — создание очереди через /ui/api ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
UI_T=$(admin_api POST /admin/tenants '{"name":"ui-test-'"$TS"'","max_queues":10}')
|
||||
UI_TID=$(echo "$UI_T" | jq -r '.id')
|
||||
UI_AK=$(echo "$UI_T" | jq -r '.access_key')
|
||||
UI_SK=$(echo "$UI_T" | jq -r '.secret_key')
|
||||
|
||||
# Создать очередь через UI API
|
||||
R=$(curl -s --max-time 15 -X POST "${BASE_URL}/ui/api/tenants/${UI_TID}/queues" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"ui-queue-1"}')
|
||||
check "UI API: создать очередь ui-queue-1 → имя" "$R" "ui-queue-1"
|
||||
|
||||
# Дубль — та же очередь, не ошибка (идемпотентно)
|
||||
R=$(curl -s --max-time 15 -X POST "${BASE_URL}/ui/api/tenants/${UI_TID}/queues" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"ui-queue-1"}')
|
||||
check "UI API: повторное создание — idempotent (нет 500)" "$R" "ui-queue-1|error"
|
||||
|
||||
# Список очередей через /ui/api содержит созданную
|
||||
R=$(curl -s --max-time 15 "${BASE_URL}/ui/api/tenants/${UI_TID}/queues")
|
||||
check "UI API: GET /queues содержит ui-queue-1" "$R" "ui-queue-1"
|
||||
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 25. UI API — отправка и peek сообщений ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
# Отправить сообщение через UI
|
||||
R=$(curl -s --max-time 15 -X POST \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-queue-1/messages" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"body":"hello-from-ui"}')
|
||||
check "UI API: send message → id" "$R" '"id"'
|
||||
check "UI API: send message → status sent" "$R" "sent"
|
||||
|
||||
# Отправить ещё одно
|
||||
curl -s --max-time 15 -X POST \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-queue-1/messages" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"body":"second-message"}' >/dev/null 2>&1
|
||||
|
||||
# Peek — должны видеть оба, без ReceiptHandle
|
||||
R=$(curl -s --max-time 15 \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-queue-1/messages")
|
||||
check "UI API: peek — hello-from-ui" "$R" "hello-from-ui"
|
||||
check "UI API: peek — second-message" "$R" "second-message"
|
||||
check_not "UI API: peek — НЕТ receipt_handle" "$R" "receipt_handle"
|
||||
|
||||
# Peek не даёт возможности ReceiveMessage через SQS (сообщения не зафиксированы)
|
||||
QURL_UI=$(sqs "$UI_AK" "$UI_SK" list-queues 2>&1 \
|
||||
| python3 -c "import sys,json; d=json.load(sys.stdin); urls=d.get('QueueUrls',[]); print(next((u for u in urls if 'ui-queue-1' in u),''))" 2>/dev/null || true)
|
||||
if [[ -n "$QURL_UI" ]]; then
|
||||
RECV_AFTER_PEEK=$(sqs "$UI_AK" "$UI_SK" receive-message --queue-url "$QURL_UI" 2>&1)
|
||||
check "UI API: peek не consumed — SQS receive-message видит сообщение" "$RECV_AFTER_PEEK" "hello-from-ui|Messages"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 26. UI API — purge очереди ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
R=$(curl -s --max-time 15 -X DELETE \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-queue-1/messages")
|
||||
check "UI API: purge → 200/204 (нет ошибки)" "$R" "^\s*$|purged|ok|{}"
|
||||
|
||||
# После purge peek должен вернуть пустой массив
|
||||
R=$(curl -s --max-time 15 \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-queue-1/messages")
|
||||
check_not "UI API: после purge peek пуст (нет hello-from-ui)" "$R" "hello-from-ui"
|
||||
|
||||
# Отправим ещё одно после purge — должно работать
|
||||
R=$(curl -s --max-time 15 -X POST \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-queue-1/messages" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"body":"after-purge"}')
|
||||
check "UI API: send после purge работает" "$R" '"id"'
|
||||
|
||||
R=$(curl -s --max-time 15 \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-queue-1/messages")
|
||||
check "UI API: peek после purge → after-purge" "$R" "after-purge"
|
||||
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 27. UI API — удаление очереди ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
# Создать ещё одну очередь чтобы удалить
|
||||
curl -s --max-time 15 -X POST "${BASE_URL}/ui/api/tenants/${UI_TID}/queues" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"ui-to-delete"}' >/dev/null 2>&1
|
||||
|
||||
R=$(curl -s --max-time 15 "${BASE_URL}/ui/api/tenants/${UI_TID}/queues")
|
||||
check "UI API: ui-to-delete создана" "$R" "ui-to-delete"
|
||||
|
||||
# Удалить
|
||||
HTTP=$(curl -s --max-time 15 -o /dev/null -w "%{http_code}" -X DELETE \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/ui-to-delete")
|
||||
if [[ "$HTTP" == "204" || "$HTTP" == "200" ]]; then
|
||||
PASS=$((PASS+1)); TOTAL=$((TOTAL+1))
|
||||
echo " ✅ UI API: DELETE /queues/ui-to-delete → HTTP $HTTP"
|
||||
else
|
||||
FAIL=$((FAIL+1)); TOTAL=$((TOTAL+1))
|
||||
echo " ❌ UI API: DELETE /queues/ui-to-delete → HTTP $HTTP"
|
||||
fi
|
||||
|
||||
R=$(curl -s --max-time 15 "${BASE_URL}/ui/api/tenants/${UI_TID}/queues")
|
||||
check_not "UI API: ui-to-delete больше не в списке" "$R" "ui-to-delete"
|
||||
|
||||
# Удаление несуществующей очереди → 404
|
||||
HTTP=$(curl -s --max-time 15 -o /dev/null -w "%{http_code}" -X DELETE \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/no-such-queue")
|
||||
if [[ "$HTTP" == "404" ]]; then
|
||||
PASS=$((PASS+1)); TOTAL=$((TOTAL+1))
|
||||
echo " ✅ UI API: DELETE несуществующей очереди → 404"
|
||||
else
|
||||
FAIL=$((FAIL+1)); TOTAL=$((TOTAL+1))
|
||||
echo " ❌ UI API: DELETE несуществующей очереди → HTTP $HTTP (ожидалось 404)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
echo "── 28. UI API — изоляция: чужой тенант недоступен ──"
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
# Создать второго тенанта и попробовать смотреть его очереди через UI API чужим ID
|
||||
UI_T2=$(admin_api POST /admin/tenants '{"name":"ui-other-'"$TS"'","max_queues":5}')
|
||||
UI_T2ID=$(echo "$UI_T2" | jq -r '.id')
|
||||
curl -s --max-time 15 -X POST "${BASE_URL}/ui/api/tenants/${UI_T2ID}/queues" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"secret-queue"}' >/dev/null 2>&1
|
||||
curl -s --max-time 15 -X POST \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_T2ID}/queues/secret-queue/messages" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"body":"secret-data"}' >/dev/null 2>&1
|
||||
|
||||
# T1 пытается peek очереди T2 — должен получить 404 (тенант не найден)
|
||||
HTTP=$(curl -s --max-time 15 -o /dev/null -w "%{http_code}" \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_T2ID}/queues/secret-queue/messages")
|
||||
# UI API публичный (без auth), но очередь принадлежит другому тенанту — данные не должны пересекаться
|
||||
# Проверяем что данные T2 недоступны через UI T1
|
||||
R=$(curl -s --max-time 15 "${BASE_URL}/ui/api/tenants/${UI_TID}/queues")
|
||||
check_not "UI API: T1 не видит очереди T2" "$R" "secret-queue"
|
||||
|
||||
R_T1_PEEK=$(curl -s --max-time 15 \
|
||||
"${BASE_URL}/ui/api/tenants/${UI_TID}/queues/secret-queue/messages")
|
||||
check "UI API: peek чужой очереди через ID T1 → 404/error" "$R_T1_PEEK" "not found|error|404"
|
||||
|
||||
# Cleanup UI тенантов
|
||||
admin_api DELETE "/admin/tenants/${UI_T2ID}" >/dev/null 2>&1 || true
|
||||
|
||||
echo ""
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
admin_api DELETE "/admin/tenants/${T1_ID}" >/dev/null 2>&1 || true
|
||||
admin_api DELETE "/admin/tenants/${T2_ID}" >/dev/null 2>&1 || true
|
||||
admin_api DELETE "/admin/tenants/${LIM_ID}" >/dev/null 2>&1 || true
|
||||
admin_api DELETE "/admin/tenants/${UI_TID}" >/dev/null 2>&1 || true
|
||||
# probe-test тенант (если оставался от предыдущих запусков)
|
||||
PROBE_ID=$(admin_api GET /admin/tenants 2>/dev/null | jq -r '.[] | select(.name=="probe-test") | .id' 2>/dev/null || true)
|
||||
[ -n "$PROBE_ID" ] && admin_api DELETE "/admin/tenants/${PROBE_ID}" >/dev/null 2>&1 || true
|
||||
|
||||
Reference in New Issue
Block a user