#!/usr/bin/env bash # tests/api_test.sh — программная проверка SQS API (как сервис используют приложения). # Не консоль: aws cli = тот же SDK-путь (Signature V4), что у boto3/aws-sdk-go и др. # # Использование: # AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... ./tests/api_test.sh set -u ENDPOINT="${ENDPOINT:-https://sqs.containerk8s.dev.nubes.ru}" REGION="${REGION:-us-east-1}" PASS=0; FAIL=0 ok() { PASS=$((PASS+1)); echo " ✅ $1"; } bad() { FAIL=$((FAIL+1)); echo " ❌ $1"; } json() { python3 -c "import sys,json; d=json.load(sys.stdin); print($1)" 2>/dev/null; } AWS=(aws --endpoint-url "$ENDPOINT" --region "$REGION") if [[ -z "${AWS_ACCESS_KEY_ID:-}" || -z "${AWS_SECRET_ACCESS_KEY:-}" ]]; then echo "Нужны AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY" exit 1 fi Q="api-test-$(date +%s)" QF="$Q.fifo" echo "== Базовая очередь ==" # ListQueues "${AWS[@]}" sqs list-queues >/dev/null 2>&1 && ok "ListQueues" || bad "ListQueues" # CreateQueue CQ=$("${AWS[@]}" sqs create-queue --queue-name "$Q" 2>&1) QUEUE_URL=$(echo "$CQ" | json 'd["QueueUrl"]') [[ -n "$QUEUE_URL" ]] && ok "CreateQueue" || bad "CreateQueue: $CQ" # GetQueueUrl — должен совпасть с URL из create-queue GUQ=$("${AWS[@]}" sqs get-queue-url --queue-name "$Q" 2>&1) GUQ_URL=$(echo "$GUQ" | json 'd["QueueUrl"]') [[ "$GUQ_URL" == "$QUEUE_URL" ]] && ok "GetQueueUrl" || bad "GetQueueUrl" # GetQueueAttributes (All) GQA=$("${AWS[@]}" sqs get-queue-attributes --queue-url "$QUEUE_URL" --attribute-names All 2>&1) echo "$GQA" | grep -qF '"VisibilityTimeout"' && ok "GetQueueAttributes" || bad "GetQueueAttributes: $GQA" # SetQueueAttributes (VisibilityTimeout=42) + проверка "${AWS[@]}" sqs set-queue-attributes --queue-url "$QUEUE_URL" --attributes VisibilityTimeout=42 >/dev/null 2>&1 \ && ok "SetQueueAttributes" || bad "SetQueueAttributes" GQA2=$("${AWS[@]}" sqs get-queue-attributes --queue-url "$QUEUE_URL" --attribute-names VisibilityTimeout 2>&1) echo "$GQA2" | grep -qF '"42"' && ok "SetQueueAttributes проверен (42)" || bad "VisibilityTimeout != 42" # SendMessage "${AWS[@]}" sqs send-message --queue-url "$QUEUE_URL" --message-body "single-msg" >/dev/null 2>&1 \ && ok "SendMessage" || bad "SendMessage" # SendMessageBatch (2 сообщения) SMB=$("${AWS[@]}" sqs send-message-batch --queue-url "$QUEUE_URL" \ --entries Id=1,MessageBody=batch-1 Id=2,MessageBody=batch-2 2>&1) echo "$SMB" | grep -qF '"Successful"' && ok "SendMessageBatch (2)" || bad "SendMessageBatch: $SMB" # ReceiveMessage (до 10) — должны прийти все 3 for i in 1 2 3 4 5; do RM=$("${AWS[@]}" sqs receive-message --queue-url "$QUEUE_URL" --max-number-of-messages 10 2>&1) N=$(echo "$RM" | json 'len(d.get("Messages", []))') [[ -n "$N" && "$N" -gt 0 ]] && break sleep 1 done N=$(echo "$RM" | json 'len(d.get("Messages", []))') [[ "$N" == "3" ]] && ok "ReceiveMessage (3 сообщения)" || bad "ReceiveMessage: получили $N" # ChangeMessageVisibility по первому handle. # visibility-timeout=5с (НЕ 1с): после истечения таймаута сообщение снова # видимо, а handle сбрасывается — delete по старому handle даёт # ReceiptHandleIsInvalid (корректная AWS-семантика). При 1с сетевые задержки # приводили к случайным FAIL теста. RH1=$(echo "$RM" | json 'd["Messages"][0]["ReceiptHandle"]') if [[ -n "$RH1" ]]; then "${AWS[@]}" sqs change-message-visibility --queue-url "$QUEUE_URL" --receipt-handle "$RH1" --visibility-timeout 5 >/dev/null 2>&1 \ && ok "ChangeMessageVisibility" || bad "ChangeMessageVisibility" fi # DeleteMessage (первое) + DeleteMessageBatch (остальные два) "${AWS[@]}" sqs delete-message --queue-url "$QUEUE_URL" --receipt-handle "$RH1" >/dev/null 2>&1 \ && ok "DeleteMessage" || bad "DeleteMessage" RH2=$(echo "$RM" | json 'd["Messages"][1]["ReceiptHandle"]') RH3=$(echo "$RM" | json 'd["Messages"][2]["ReceiptHandle"]') if [[ -n "$RH2" && -n "$RH3" ]]; then DMB=$("${AWS[@]}" sqs delete-message-batch --queue-url "$QUEUE_URL" \ --entries Id=1,ReceiptHandle="$RH2" Id=2,ReceiptHandle="$RH3" 2>&1) echo "$DMB" | grep -qF '"Successful"' && ok "DeleteMessageBatch (2)" || bad "DeleteMessageBatch: $DMB" fi # TagQueue / ListQueueTags / UntagQueue "${AWS[@]}" sqs tag-queue --queue-url "$QUEUE_URL" --tags env=test,owner=api-test >/dev/null 2>&1 \ && ok "TagQueue" || bad "TagQueue" LQT=$("${AWS[@]}" sqs list-queue-tags --queue-url "$QUEUE_URL" 2>&1) echo "$LQT" | grep -qF '"env"' && echo "$LQT" | grep -qF '"api-test"' && ok "ListQueueTags" || bad "ListQueueTags: $LQT" "${AWS[@]}" sqs untag-queue --queue-url "$QUEUE_URL" --tag-keys env owner >/dev/null 2>&1 \ && ok "UntagQueue" || bad "UntagQueue" # PurgeQueue "${AWS[@]}" sqs purge-queue --queue-url "$QUEUE_URL" >/dev/null 2>&1 \ && ok "PurgeQueue" || bad "PurgeQueue" # DeleteQueue "${AWS[@]}" sqs delete-queue --queue-url "$QUEUE_URL" >/dev/null 2>&1 \ && ok "DeleteQueue" || bad "DeleteQueue" echo "== FIFO-очередь ==" CFQ=$("${AWS[@]}" sqs create-queue --queue-name "$QF" --attributes FifoQueue=true 2>&1) FIFO_URL=$(echo "$CFQ" | json 'd["QueueUrl"]') [[ -n "$FIFO_URL" ]] && ok "CreateQueue (FIFO)" || bad "CreateQueue FIFO: $CFQ" "${AWS[@]}" sqs send-message --queue-url "$FIFO_URL" --message-body "fifo-msg" \ --message-group-id g1 --message-deduplication-id d1 >/dev/null 2>&1 \ && ok "SendMessage (FIFO)" || bad "SendMessage FIFO" RF=$("${AWS[@]}" sqs receive-message --queue-url "$FIFO_URL" --max-number-of-messages 1 2>&1) echo "$RF" | grep -qF '"fifo-msg"' && ok "ReceiveMessage (FIFO)" || bad "ReceiveMessage FIFO: $RF" RFH=$(echo "$RF" | json 'd["Messages"][0]["ReceiptHandle"]') [[ -n "$RFH" ]] && "${AWS[@]}" sqs delete-message --queue-url "$FIFO_URL" --receipt-handle "$RFH" >/dev/null 2>&1 \ && ok "DeleteMessage (FIFO)" || bad "DeleteMessage FIFO" "${AWS[@]}" sqs delete-queue --queue-url "$FIFO_URL" >/dev/null 2>&1 \ && ok "DeleteQueue (FIFO)" || bad "DeleteQueue FIFO" echo echo "Итог: PASS=$PASS FAIL=$FAIL" [[ $FAIL -eq 0 ]]