Load tests

This commit is contained in:
2026-04-23 22:01:45 +03:00
parent 341f40a02a
commit dad178bd0d
3 changed files with 103 additions and 0 deletions

View File

@@ -160,6 +160,39 @@ test-all: eunit ## Запустить ВСЕ тесты (EUnit + API)
@echo " ВСЕ ТЕСТЫ ПРОЙДЕНЫ!"
@echo "========================================"
# ============================================================================
# LOAD TESTING
#3. Мониторинг во время нагрузочного теста
#Во время теста полезно следить за состоянием ноды:
#
#Через Docker (если приложение в контейнере):
#bash
#docker stats eventhub
#docker exec eventhub /app/bin/eventhub remote_console
#Внутри консоли Erlang можно выполнить:
#
#erlang
#observer:start(). % графический мониторинг
#recon:proc_count(5). % топ-5 процессов по памяти (если установлен recon)
# ============================================================================
tsung-test: ## Запустить нагрузочный тест Tsung
@echo "Запуск нагрузочного теста Tsung..."
@mkdir -p logs/tsung
@tsung -f test/tsung/eventhub_http.xml -l logs/tsung start
@echo "Отчёт: logs/tsung/*/report.html"
wrk-register: ## Нагрузочный тест регистрации (wrk2)
@wrk -t4 -c100 -d30s -t100 -s test/wrk/scripts/wrk_register.lua http://localhost:8080/v1/register
wrk-search: ## Нагрузочный тест поиска (wrk2)
@TOKEN=$$(curl -s -X POST http://localhost:8080/v1/register \
-H "Content-Type: application/json" \
-d '{"email":"wrktest@test.com","password":"pass"}' | \
grep -o '"token":"[^"]*"' | cut -d'"' -f4); \
wrk -t4 -c100 -d30s -R200 \
-H "Authorization: Bearer $$TOKEN" \
http://localhost:8080/v1/search?type=event\&q=test
# ============================================================================
# CODE QUALITY
# ============================================================================

View File

@@ -0,0 +1,64 @@
<?xml version="1.0"?>
<!DOCTYPE tsung SYSTEM "/usr/share/tsung/tsung-1.0.dtd">
<tsung loglevel="notice" version="1.0">
<clients>
<client host="localhost" use_controller_vm="true" maxusers="1000"/>
</clients>
<servers>
<server host="localhost" port="8080" type="tcp"/>
</servers>
<load>
<arrivalphase phase="1" duration="2" unit="minute">
<users interarrival="0.1" unit="second"/>
</arrivalphase>
</load>
<sessions>
<session name="eventhub_user" probability="100" type="ts_http">
<!-- 1. Регистрация -->
<request>
<dyn_variable name="token" re="&quot;token&quot;:&quot;(.+?)&quot;"/>
<http url="/v1/register" method="POST" content_type="application/json"
contents="{\&quot;email\&quot;: \&quot;loadtest_%%_ts_userid:server:ts_userid%%@example.com\&quot;, \&quot;password\&quot;: \&quot;testpassword123\&quot;}"/>
</request>
<!-- 2. Создание календаря -->
<request>
<dyn_variable name="calendar_id" re="&quot;id&quot;:&quot;(.+?)&quot;"/>
<http url="/v1/calendars" method="POST" content_type="application/json"
contents="{\&quot;title\&quot;: \&quot;Load Test Calendar\&quot;, \&quot;description\&quot;: \&quot;Tsung test\&quot;}">
<http_header name="Authorization" value="Bearer %%_token%%"/>
</http>
</request>
<!-- 3. Создание события -->
<request>
<dyn_variable name="event_id" re="&quot;id&quot;:&quot;(.+?)&quot;"/>
<http url="/v1/calendars/%%_calendar_id%%/events" method="POST" content_type="application/json"
contents="{\&quot;title\&quot;:\&quot;Tsung Event\&quot;,\&quot;start_time\&quot;:\&quot;2027-01-01T10:00:00Z\&quot;,\&quot;duration\&quot;:60,\&quot;capacity\&quot;:100}">
<http_header name="Authorization" value="Bearer %%_token%%"/>
</http>
</request>
<!-- 4. Запись на событие -->
<request>
<http url="/v1/events/%%_event_id%%/bookings" method="POST" content_type="application/json"
contents="{}">
<http_header name="Authorization" value="Bearer %%_token%%"/>
</http>
</request>
<!-- 5. Поиск -->
<request>
<http url="/v1/search?type=event&amp;q=Tsung" method="GET">
<http_header name="Authorization" value="Bearer %%_token%%"/>
</http>
</request>
<thinktime min="1" max="5" random="true"/>
</session>
</sessions>
</tsung>

View File

@@ -0,0 +1,6 @@
counter = 0
request = function()
counter = counter + 1
local body = string.format('{"email":"load%d@test.com","password":"pass"}', counter)
return wrk.format("POST", "/v1/register", {["Content-Type"]="application/json"}, body)
end