add hardcore_test, load_test, update README with AWS CLI install + test descriptions
This commit is contained in:
@@ -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 секунд
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Особенности
|
## Особенности
|
||||||
|
|||||||
@@ -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
@@ -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"
|
||||||
Reference in New Issue
Block a user