add hardcore_test, load_test, update README with AWS CLI install + test descriptions

This commit is contained in:
Naeel
2026-04-09 09:00:51 +03:00
parent 8282a6cc0a
commit 5815d12ba2
3 changed files with 531 additions and 20 deletions
+56 -20
View File
@@ -18,6 +18,30 @@
Самый простой способ работы — через стандартный AWS CLI. Самый простой способ работы — через стандартный 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 ```bash
export AWS_ACCESS_KEY_ID="SQSAK-test001-ae4dc8" export AWS_ACCESS_KEY_ID="SQSAK-test001-ae4dc8"
export AWS_SECRET_ACCESS_KEY="J8mElXq8Nwww8iFRtGJCm8KfxM9XSTluTqS2A67xsEE" 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
bash quick_test.sh bash quick_test.sh
``` ```
Что проверяет: Проверяет 6 базовых операций: создание очереди → список → отправка → получение → удаление → проверка удаления.
1. Создание очереди
2. Очередь видна в списке
3. Отправка сообщения
4. Получение сообщения (тело совпадает)
5. Удаление очереди
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 секунд
--- ---
## Особенности ## Особенности
+271
View File
@@ -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 '(?<=<MD5OfMessageBody>)[^<]+' | 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
+204
View File
@@ -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 "<Message>" || 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 "<Message>" || 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 "<Message>" || 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"