diff --git a/README.md b/README.md index 08d8e23..ae81157 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,30 @@ Самый простой способ работы — через стандартный AWS CLI. +### Установка + +**Linux / macOS (pip):** +```bash +pip install awscli +``` + +**Linux (пакет):** +```bash +curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o awscliv2.zip +unzip awscliv2.zip && sudo ./aws/install +``` + +**macOS (brew):** +```bash +brew install awscli +``` + +**Windows:** скачайте установщик с https://aws.amazon.com/cli/ + +Проверка: `aws --version` + +### Настройка + ```bash export AWS_ACCESS_KEY_ID="SQSAK-test001-ae4dc8" export AWS_SECRET_ACCESS_KEY="J8mElXq8Nwww8iFRtGJCm8KfxM9XSTluTqS2A67xsEE" @@ -132,39 +156,51 @@ console.log(res.Messages[0].Body); --- -## Проверка работоспособности +## Тесты -В репозитории есть `quick_test.sh` — скрипт для быстрой проверки сервиса. +В репозитории три тестовых скрипта — от простого к сложному. -**Требования:** `curl`, `bash`. +### quick_test.sh — быстрая проверка + +**Требования:** `curl`, `bash` ```bash bash quick_test.sh ``` -Что проверяет: -1. Создание очереди -2. Очередь видна в списке -3. Отправка сообщения -4. Получение сообщения (тело совпадает) -5. Удаление очереди -6. Очередь исчезла из списка +Проверяет 6 базовых операций: создание очереди → список → отправка → получение → удаление → проверка удаления. -Ожидаемый вывод: +### hardcore_test.sh — полный тест (AWS CLI + curl) + +**Требования:** `aws cli`, `curl`, `bash` + +```bash +bash hardcore_test.sh ``` -=== SQS Quick Test === - ✅ Создание очереди - ✅ Очередь в списке - ✅ Отправка сообщения - ✅ Получение сообщения - ✅ Удаление очереди - ✅ Очередь удалена из списка +25 тестов в 8 группах: +- CRUD через AWS CLI и через curl +- Кросс-доставка: CLI отправляет → curl получает (и наоборот) +- Невалидный ввод: несуществующие очереди, пустые параметры, неизвестные команды +- Спецсимволы: JSON, XML-сущности, Unicode, эмодзи +- Visibility timeout: сообщение скрыто → снова доступно +- Множественная доставка: 10 сообщений без потерь +- Целостность: проверка MD5 -Результат: 6 OK / 0 FAIL -Всё работает! +### load_test.sh — нагрузочный тест + +**Требования:** `curl`, `bash` + +```bash +bash load_test.sh ``` +Замеряет производительность сервиса: +- Latency: средний/мин/макс для send и receive (20 замеров) +- Последовательный throughput: 50 сообщений подряд +- Параллельная работа: 5 воркеров × 20 сообщений одновременно +- Стресс-петля: непрерывная отправка и получение 30 секунд + --- ## Особенности diff --git a/hardcore_test.sh b/hardcore_test.sh new file mode 100644 index 0000000..ba71bee --- /dev/null +++ b/hardcore_test.sh @@ -0,0 +1,271 @@ +#!/bin/bash +# hardcore_test.sh — Полный тест SQS-сервиса (AWS CLI + curl) +# Проверяет: CRUD, невалидный ввод, спецсимволы, visibility, purge, MD5 +# Требования: aws cli (pip install awscli), curl, bash, python3 (для md5) +# Запуск: bash hardcore_test.sh + +set -euo pipefail + +# ═══════════════════════════════════════════ +# КОНФИГУРАЦИЯ — измените под свой тенант +# ═══════════════════════════════════════════ +SQS_ENDPOINT="https://sqs.kube5s.ru/sqs/test001" +export AWS_ACCESS_KEY_ID="SQSAK-test001-ae4dc8" +export AWS_SECRET_ACCESS_KEY="J8mElXq8Nwww8iFRtGJCm8KfxM9XSTluTqS2A67xsEE" +export AWS_DEFAULT_REGION="us-east-1" +EP="--endpoint-url ${SQS_ENDPOINT}" +AUTH="${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}" +VER="2012-11-05" +TS=$(date +%s) + +PASS=0; FAIL=0; TOTAL=0 + +check() { + TOTAL=$((TOTAL + 1)) + if echo "$2" | grep -q "$3"; then + PASS=$((PASS + 1)); echo " ✅ $1" + else + FAIL=$((FAIL + 1)); echo " ❌ $1" + echo " ожидалось: $3" + echo " получено: $(echo "$2" | head -2)" + fi +} + +check_not() { + TOTAL=$((TOTAL + 1)) + if echo "$2" | grep -q "$3"; then + FAIL=$((FAIL + 1)); echo " ❌ $1 (содержит '$3')" + else + PASS=$((PASS + 1)); echo " ✅ $1" + fi +} + +curl_sqs() { + curl -s --max-time 15 -u "$AUTH" "${SQS_ENDPOINT}?${1}&Version=${VER}" 2>&1 +} + +echo "╔═══════════════════════════════════════════════════════╗" +echo "║ SQS Hardcore Test — $(date '+%Y-%m-%d %H:%M:%S') ║" +echo "║ Endpoint: ${SQS_ENDPOINT} ║" +echo "║ Метод: AWS CLI + curl ║" +echo "╚═══════════════════════════════════════════════════════╝" +echo "" + +# Проверяем что aws cli доступен +if ! command -v aws &>/dev/null; then + echo "❌ aws cli не найден. Установите: pip install awscli" + echo " Подробнее: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" + exit 1 +fi + +# ═══════════════════════════════════════════ +echo "── 1. CRUD через AWS CLI ──" +# ═══════════════════════════════════════════ + +Q1="hc-cli-${TS}" + +# Создание +R=$(aws sqs create-queue --queue-name "$Q1" $EP --output text 2>&1) +check "CLI: создание очереди" "$R" "$Q1" +QURL="$R" + +# Список — очередь видна +R=$(aws sqs list-queues $EP --output text 2>&1) +check "CLI: очередь в списке" "$R" "$Q1" + +# Отправка +R=$(aws sqs send-message --queue-url "$QURL" --message-body "cli-test-msg" $EP --output json 2>&1) +check "CLI: отправка" "$R" "MessageId" + +# Получение +R=$(aws sqs receive-message --queue-url "$QURL" $EP --output json 2>&1) +check "CLI: получение" "$R" "cli-test-msg" + +# Атрибуты +R=$(aws sqs get-queue-attributes --queue-url "$QURL" --attribute-names All $EP --output json 2>&1) +check "CLI: атрибуты" "$R" "ApproximateNumberOfMessages\|Attributes" + +# Purge +aws sqs send-message --queue-url "$QURL" --message-body "to-purge" $EP >/dev/null 2>&1 +R=$(aws sqs purge-queue --queue-url "$QURL" $EP 2>&1 && echo "OK" || echo "FAIL") +check "CLI: purge" "$R" "OK" + +# Удаление +R=$(aws sqs delete-queue --queue-url "$QURL" $EP 2>&1 && echo "OK" || echo "FAIL") +check "CLI: удаление" "$R" "OK" + +# Проверка что удалилась +R=$(aws sqs list-queues $EP --output text 2>&1) +check_not "CLI: очередь исчезла" "$R" "$Q1" + +echo "" + +# ═══════════════════════════════════════════ +echo "── 2. CRUD через curl ──" +# ═══════════════════════════════════════════ + +Q2="hc-curl-${TS}" + +R=$(curl_sqs "Action=CreateQueue&QueueName=${Q2}") +check "curl: создание" "$R" "CreateQueueResult" + +R=$(curl_sqs "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${Q2}&MessageBody=curl-test") +check "curl: отправка" "$R" "MessageId" + +R=$(curl_sqs "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${Q2}") +check "curl: получение" "$R" "curl-test" + +R=$(curl_sqs "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${Q2}") +check "curl: удаление" "$R" "DeleteQueueResponse" + +echo "" + +# ═══════════════════════════════════════════ +echo "── 3. CLI отправляет → curl получает (и наоборот) ──" +# ═══════════════════════════════════════════ + +Q3="hc-cross-${TS}" +QURL3=$(aws sqs create-queue --queue-name "$Q3" $EP --output text 2>&1) + +# CLI → curl +aws sqs send-message --queue-url "$QURL3" --message-body "from-cli" $EP >/dev/null 2>&1 +R=$(curl_sqs "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${Q3}&MaxNumberOfMessages=10") +check "CLI→curl: сообщение доставлено" "$R" "from-cli" + +# curl → CLI +curl_sqs "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${Q3}&MessageBody=from-curl" >/dev/null +R=$(aws sqs receive-message --queue-url "$QURL3" $EP --output json 2>&1) +check "curl→CLI: сообщение доставлено" "$R" "from-curl" + +aws sqs delete-queue --queue-url "$QURL3" $EP >/dev/null 2>&1 +echo "" + +# ═══════════════════════════════════════════ +echo "── 4. Невалидный ввод ──" +# ═══════════════════════════════════════════ + +# Несуществующая очередь +R=$(aws sqs send-message --queue-url "${SQS_ENDPOINT}/test001/no-such-queue-${TS}" --message-body "x" $EP 2>&1 || true) +check "Несуществующая очередь" "$R" "NonExistentQueue\|error\|Error\|does not exist" + +# Пустое тело через curl +R=$(curl_sqs "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/no-such-queue-${TS}") +check "curl: без body" "$R" "Error\|MissingParameter\|must contain" + +# Неизвестный Action +R=$(curl_sqs "Action=DoSomethingWeird") +check "curl: неизвестный Action" "$R" "InvalidAction\|UnknownAction\|InvalidParameterValue\|Error" + +echo "" + +# ═══════════════════════════════════════════ +echo "── 5. Спецсимволы в сообщениях ──" +# ═══════════════════════════════════════════ + +Q5="hc-spec-${TS}" +QURL5=$(aws sqs create-queue --queue-name "$Q5" $EP --output text 2>&1) + +# JSON +aws sqs send-message --queue-url "$QURL5" --message-body '{"key":"value","num":42}' $EP >/dev/null 2>&1 +R=$(aws sqs receive-message --queue-url "$QURL5" $EP --output json 2>&1) +check "JSON в теле" "$R" "key" + +# XML-символы через curl +curl_sqs "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${Q5}&MessageBody=a%26b%3Cc%3Ed" >/dev/null +R=$(curl_sqs "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${Q5}") +check "XML спецсимволы (&<>)" "$R" "Body" + +# Unicode +aws sqs send-message --queue-url "$QURL5" --message-body "Привет мир 🚀" $EP >/dev/null 2>&1 +R=$(aws sqs receive-message --queue-url "$QURL5" $EP --output json 2>&1) +check "Unicode + эмодзи" "$R" "Привет\|мир" + +aws sqs delete-queue --queue-url "$QURL5" $EP >/dev/null 2>&1 +echo "" + +# ═══════════════════════════════════════════ +echo "── 6. Visibility timeout ──" +# ═══════════════════════════════════════════ + +Q6="hc-vis-${TS}" +QURL6=$(aws sqs create-queue --queue-name "$Q6" $EP --output text 2>&1) +aws sqs send-message --queue-url "$QURL6" --message-body "vis-test" $EP >/dev/null 2>&1 + +# Получаем с visibility=2 +R=$(aws sqs receive-message --queue-url "$QURL6" --visibility-timeout 2 $EP --output json 2>&1) +check "Receive с visibility" "$R" "vis-test" + +# Сразу повторно — пусто +R=$(aws sqs receive-message --queue-url "$QURL6" $EP --output json 2>&1) +check_not "Скрыто во время visibility" "$R" "vis-test" + +# Ждём 3 сек — снова доступно +sleep 3 +R=$(aws sqs receive-message --queue-url "$QURL6" $EP --output json 2>&1) +check "Снова доступно после timeout" "$R" "vis-test" + +aws sqs delete-queue --queue-url "$QURL6" $EP >/dev/null 2>&1 +echo "" + +# ═══════════════════════════════════════════ +echo "── 7. Множественные сообщения (10 шт) ──" +# ═══════════════════════════════════════════ + +Q7="hc-multi-${TS}" +QURL7=$(aws sqs create-queue --queue-name "$Q7" $EP --output text 2>&1) + +# Отправляем 10 +for i in $(seq 1 10); do + aws sqs send-message --queue-url "$QURL7" --message-body "msg-${i}" $EP >/dev/null 2>&1 +done + +# Получаем все +GOT=0 +for _ in $(seq 1 15); do + R=$(aws sqs receive-message --queue-url "$QURL7" --max-number-of-messages 10 $EP --output json 2>&1) + COUNT=$(echo "$R" | grep -c '"Body"' || true) + GOT=$((GOT + COUNT)) + [ "$COUNT" -eq 0 ] && break + [ "$GOT" -ge 10 ] && break +done + +TOTAL=$((TOTAL + 1)) +if [ "$GOT" -ge 10 ]; then + PASS=$((PASS + 1)); echo " ✅ Получены все 10 сообщений ($GOT)" +else + FAIL=$((FAIL + 1)); echo " ❌ Получено $GOT/10 сообщений" +fi + +aws sqs delete-queue --queue-url "$QURL7" $EP >/dev/null 2>&1 +echo "" + +# ═══════════════════════════════════════════ +echo "── 8. MD5 целостность ──" +# ═══════════════════════════════════════════ + +Q8="hc-md5-${TS}" +curl_sqs "Action=CreateQueue&QueueName=${Q8}" >/dev/null + +MSG="integrity-check-${TS}" +EXPECTED=$(echo -n "$MSG" | md5sum | awk '{print $1}') +R=$(curl_sqs "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${Q8}&MessageBody=${MSG}") +GOT_MD5=$(echo "$R" | grep -oP '(?<=)[^<]+' | head -1) + +TOTAL=$((TOTAL + 1)) +if [ "$EXPECTED" = "$GOT_MD5" ]; then + PASS=$((PASS + 1)); echo " ✅ MD5 совпадает ($EXPECTED)" +else + FAIL=$((FAIL + 1)); echo " ❌ MD5: ожидалось $EXPECTED, получено $GOT_MD5" +fi + +curl_sqs "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${Q8}" >/dev/null +echo "" + +# ═══════════════════════════════════════════ +echo "╔═══════════════════════════════════════════════════════╗" +echo "║ ИТОГО ║" +echo "╠═══════════════════════════════════════════════════════╣" +printf "║ Всего: %-3s ✅ PASS: %-3s ❌ FAIL: %-3s ║\n" "$TOTAL" "$PASS" "$FAIL" +echo "╚═══════════════════════════════════════════════════════╝" + +[ "$FAIL" -eq 0 ] && exit 0 || exit 1 diff --git a/load_test.sh b/load_test.sh new file mode 100644 index 0000000..5e758a1 --- /dev/null +++ b/load_test.sh @@ -0,0 +1,204 @@ +#!/bin/bash +# load_test.sh — Нагрузочный тест SQS-сервиса +# Замеряет: latency, throughput, параллельную работу +# Требования: curl, bash +# Запуск: bash load_test.sh + +set -euo pipefail + +# ═══════════════════════════════════════════ +# КОНФИГУРАЦИЯ — измените под свой тенант +# ═══════════════════════════════════════════ +SQS_ENDPOINT="https://sqs.kube5s.ru/sqs/test001" +AUTH="SQSAK-test001-ae4dc8:J8mElXq8Nwww8iFRtGJCm8KfxM9XSTluTqS2A67xsEE" +VER="2012-11-05" +TS=$(date +%s) +TMPDIR=$(mktemp -d /tmp/sqs-load-XXXXX) + +MESSAGES=50 # Сообщений в последовательном тесте +WORKERS=5 # Параллельных воркеров +MSGS_PER_WORKER=20 # Сообщений на воркер +STRESS_SEC=30 # Секунд стресс-теста + +ms_now() { date +%s%N | cut -b1-13; } + +call() { + curl -s --max-time 30 -u "$AUTH" "${SQS_ENDPOINT}?${1}&Version=${VER}" 2>&1 +} + +echo "╔═══════════════════════════════════════════════════════╗" +echo "║ SQS Load Test — $(date '+%Y-%m-%d %H:%M:%S') ║" +echo "║ Endpoint: ${SQS_ENDPOINT} ║" +echo "║ Параметры: ${MESSAGES} seq, ${WORKERS}×${MSGS_PER_WORKER} par, ${STRESS_SEC}s stress ║" +echo "╚═══════════════════════════════════════════════════════╝" +echo "" + +# ═══════════════════════════════════════════ +echo "── 1. Latency (20 замеров) ──" +# ═══════════════════════════════════════════ + +QL="lq-lat-${TS}" +call "Action=CreateQueue&QueueName=${QL}" >/dev/null + +TIMES=() +for i in $(seq 1 20); do + T1=$(ms_now) + call "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QL}&MessageBody=lat-${i}" >/dev/null + T2=$(ms_now) + TIMES+=( $((T2 - T1)) ) +done + +SUM=0; MIN=999999; MAX=0 +for t in "${TIMES[@]}"; do + SUM=$((SUM + t)) + [ "$t" -lt "$MIN" ] && MIN=$t + [ "$t" -gt "$MAX" ] && MAX=$t +done +AVG=$((SUM / ${#TIMES[@]})) +echo " SendMessage: avg=${AVG}ms min=${MIN}ms max=${MAX}ms" + +TIMES=() +for i in $(seq 1 20); do + T1=$(ms_now) + call "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QL}&MaxNumberOfMessages=1" >/dev/null + T2=$(ms_now) + TIMES+=( $((T2 - T1)) ) +done + +SUM=0; MIN=999999; MAX=0 +for t in "${TIMES[@]}"; do + SUM=$((SUM + t)) + [ "$t" -lt "$MIN" ] && MIN=$t + [ "$t" -gt "$MAX" ] && MAX=$t +done +AVG=$((SUM / ${#TIMES[@]})) +echo " ReceiveMessage: avg=${AVG}ms min=${MIN}ms max=${MAX}ms" + +call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QL}" >/dev/null +echo "" + +# ═══════════════════════════════════════════ +echo "── 2. Последовательный throughput (${MESSAGES} сообщений) ──" +# ═══════════════════════════════════════════ + +QS="lq-seq-${TS}" +call "Action=CreateQueue&QueueName=${QS}" >/dev/null + +T1=$(ms_now) +OK=0; ERR=0 +for i in $(seq 1 $MESSAGES); do + R=$(call "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QS}&MessageBody=seq-${i}") + if echo "$R" | grep -q "MessageId"; then OK=$((OK + 1)); else ERR=$((ERR + 1)); fi +done +T2=$(ms_now) +ELAPSED=$((T2 - T1)) +RPS=$(( OK * 1000 / (ELAPSED + 1) )) +echo " Send: ${OK} OK / ${ERR} ERR за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)" + +T1=$(ms_now) +GOT=0; EMPTY=0 +for _ in $(seq 1 $((MESSAGES + 30))); do + R=$(call "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QS}&MaxNumberOfMessages=10") + C=$(echo "$R" | grep -c "" || true) + if [ "$C" -gt 0 ]; then GOT=$((GOT + C)); else EMPTY=$((EMPTY + 1)); [ "$EMPTY" -ge 3 ] && break; fi + [ "$GOT" -ge "$MESSAGES" ] && break +done +T2=$(ms_now) +ELAPSED=$((T2 - T1)) +RPS=$(( GOT * 1000 / (ELAPSED + 1) )) +echo " Recv: ${GOT}/${MESSAGES} за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)" + +call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QS}" >/dev/null +echo "" + +# ═══════════════════════════════════════════ +echo "── 3. Параллельная отправка (${WORKERS} × ${MSGS_PER_WORKER}) ──" +# ═══════════════════════════════════════════ + +QP="lq-par-${TS}" +call "Action=CreateQueue&QueueName=${QP}" >/dev/null + +worker_send() { + local wid=$1; local ok=0 + for i in $(seq 1 $MSGS_PER_WORKER); do + R=$(curl -s --max-time 30 -u "$AUTH" "${SQS_ENDPOINT}?Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QP}&MessageBody=w${wid}-${i}&Version=${VER}" 2>&1) + echo "$R" | grep -q "MessageId" && ok=$((ok + 1)) + done + echo "$ok" > "${TMPDIR}/w-${wid}.ok" +} + +T1=$(ms_now) +for w in $(seq 1 $WORKERS); do worker_send $w & done +wait +T2=$(ms_now) +ELAPSED=$((T2 - T1)) + +TOT_OK=0 +for w in $(seq 1 $WORKERS); do + [ -f "${TMPDIR}/w-${w}.ok" ] && TOT_OK=$((TOT_OK + $(cat "${TMPDIR}/w-${w}.ok"))) +done +TOT=$((WORKERS * MSGS_PER_WORKER)) +RPS=$(( TOT_OK * 1000 / (ELAPSED + 1) )) +echo " Send: ${TOT_OK}/${TOT} за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)" + +# Параллельный receive +worker_recv() { + local wid=$1; local ok=0; local empty=0 + for _ in $(seq 1 $((MSGS_PER_WORKER + 10))); do + R=$(curl -s --max-time 30 -u "$AUTH" "${SQS_ENDPOINT}?Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QP}&MaxNumberOfMessages=10&Version=${VER}" 2>&1) + C=$(echo "$R" | grep -c "" || true) + if [ "$C" -gt 0 ]; then ok=$((ok + C)); else empty=$((empty + 1)); [ "$empty" -ge 3 ] && break; fi + done + echo "$ok" > "${TMPDIR}/r-${wid}.ok" +} + +T1=$(ms_now) +for w in $(seq 1 $WORKERS); do worker_recv $w & done +wait +T2=$(ms_now) +ELAPSED=$((T2 - T1)) + +TOT_RECV=0 +for w in $(seq 1 $WORKERS); do + [ -f "${TMPDIR}/r-${w}.ok" ] && TOT_RECV=$((TOT_RECV + $(cat "${TMPDIR}/r-${w}.ok"))) +done +RPS=$(( TOT_RECV * 1000 / (ELAPSED + 1) )) +echo " Recv: ${TOT_RECV}/${TOT} за $((ELAPSED/1000)).$((ELAPSED%1000))s (${RPS} msg/s)" + +call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QP}" >/dev/null +echo "" + +# ═══════════════════════════════════════════ +echo "── 4. Стресс-петля (${STRESS_SEC}s) ──" +# ═══════════════════════════════════════════ + +QX="lq-stress-${TS}" +call "Action=CreateQueue&QueueName=${QX}" >/dev/null + +SENT=0; RECV=0; ERRS=0 +T_END=$(($(date +%s) + STRESS_SEC)) + +while [ "$(date +%s)" -lt "$T_END" ]; do + R=$(call "Action=SendMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QX}&MessageBody=s-${SENT}") + if echo "$R" | grep -q "MessageId"; then SENT=$((SENT + 1)); else ERRS=$((ERRS + 1)); fi + + R=$(call "Action=ReceiveMessage&QueueUrl=${SQS_ENDPOINT}/test001/${QX}&MaxNumberOfMessages=10") + C=$(echo "$R" | grep -c "" || true) + RECV=$((RECV + C)) +done + +echo " Длительность: ${STRESS_SEC}s" +echo " Отправлено: ${SENT} ($(( SENT / (STRESS_SEC + 1) )) msg/s)" +echo " Получено: ${RECV} ($(( RECV / (STRESS_SEC + 1) )) msg/s)" +echo " Ошибки: ${ERRS}" + +call "Action=DeleteQueue&QueueUrl=${SQS_ENDPOINT}/test001/${QX}" >/dev/null +echo "" + +# ═══════════════════════════════════════════ +echo "╔═══════════════════════════════════════════════════════╗" +echo "║ НАГРУЗОЧНЫЙ ТЕСТ ЗАВЕРШЁН ║" +echo "║ $(date '+%Y-%m-%d %H:%M:%S') ║" +echo "╚═══════════════════════════════════════════════════════╝" + +rm -rf "$TMPDIR"