o2o-negosium-original/backend/run_local_locust.sh
민헌 23cb8291bc chore(backend): 로컬 실행/부하테스트 스크립트 추가
- run_local_server.sh / run_local_locust.sh / run_local_pgwatch.sh (대화형, 메뉴 선택 방식)
- loadtest: self-register 방식 locustfile (가상 유저가 on_start 에서 계정 생성 → login/me/refresh)
- locust 스크립트가 부하용 공급사 보장·이전 부하계정/토큰 정리·LOAD_SUPPLIER_ID 주입을 자동 처리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:17:37 +09:00

89 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# 로컬 부하테스트(locust) 실행 (대화형). 실행하면 파일/시드/방식을 골라 입력한다.
# loadtest/ 아래 locust 파일이 늘어나도 목록에서 선택만 하면 된다.
#
set -euo pipefail
cd "$(dirname "$0")" # backend/
VENV=".venv"
LOCUST="$VENV/bin/locust"
HOST="${LOCUST_HOST:-http://localhost:9300}"
# 시드용 DB 접속 (local 기본값, 환경변수로 override 가능)
PGHOST="${PGHOST:-127.0.0.1}"
PGPORT="${PGPORT:-5432}"
PGUSER="${PGUSER:-postgres}"
PGDATABASE="${PGDATABASE:-negosium_db}"
# locust 설치 보장
if [[ ! -x "$LOCUST" ]]; then
echo "[setup] locust 설치..."
"$VENV/bin/python" -m pip install -q locust
fi
# 1) locust 파일 선택
FILES=()
while IFS= read -r f; do
FILES+=("$f")
done < <(ls -1 loadtest/*.py 2>/dev/null | grep -v __pycache__ || true)
if [[ ${#FILES[@]} -eq 0 ]]; then
echo "[error] loadtest/ 에 locust 파일이 없습니다."
exit 1
fi
echo "── locust 파일 선택 ──"
i=1
for f in "${FILES[@]}"; do
echo " $i) ${f#loadtest/}"
i=$((i + 1))
done
read -rp "선택 [1]: " fsel
fsel="${fsel:-1}"
FILE="${FILES[$((fsel - 1))]:-}"
if [[ -z "$FILE" ]]; then
echo "[error] 잘못된 선택: $fsel"
exit 1
fi
# 2) 부하용 공급사 1건 보장 → supplier_id 를 LOAD_SUPPLIER_ID 로 넘긴다.
# 유저는 사전 시드하지 않고 locust on_start 에서 self-register 한다(tbl 방식).
# (없으면 만들고, 있으면 그대로 사용 = get-or-create)
LOAD_SUPPLIER_ID="$(psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d "$PGDATABASE" -t -A -c "
WITH ex AS (
SELECT supplier_id FROM partner.suppliers WHERE name='부하테스트공급사' AND deleted=false LIMIT 1
), ins AS (
INSERT INTO partner.suppliers (supplier_id, company_id, user_id, name)
SELECT gen_random_uuid(), gen_random_uuid(), gen_random_uuid(), '부하테스트공급사'
WHERE NOT EXISTS (SELECT 1 FROM ex)
RETURNING supplier_id
)
SELECT supplier_id FROM ins UNION ALL SELECT supplier_id FROM ex LIMIT 1;
" 2>/dev/null | tr -d '[:space:]')"
if [[ -z "$LOAD_SUPPLIER_ID" ]]; then
echo "[error] 부하용 공급사 supplier_id 를 확보하지 못했습니다 (DB 접속/스키마 확인)."
exit 1
fi
# 이전 실행에서 self-register 로 쌓인 계정/토큰 정리(누적 방지). 공급사 행은 재사용하므로 남긴다.
psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d "$PGDATABASE" -q \
-c "DELETE FROM supplier.supplier_user_tokens WHERE su_id IN (SELECT su_id FROM supplier.supplier_users WHERE id LIKE 'load_user_%');
DELETE FROM supplier.supplier_users WHERE id LIKE 'load_user_%';" >/dev/null 2>&1 || true
echo "[info] 부하용 공급사 supplier_id=$LOAD_SUPPLIER_ID (유저는 self-register, 이전 부하계정 정리됨)"
# 3) 실행 방식 선택
echo "── 실행 방식 ──"
echo " 1) 웹 UI (브라우저에서 사용자 수 조절, http://localhost:8089)"
echo " 2) 헤드리스 (값 입력)"
read -rp "선택 [1]: " mode
mode="${mode:-1}"
if [[ "$mode" == "2" ]]; then
read -rp "동시 사용자 수 [50]: " VU; VU="${VU:-50}"
read -rp "초당 증가 수 [10]: " RATE; RATE="${RATE:-10}"
read -rp "지속 시간(예 30s/2m) [1m]: " DUR; DUR="${DUR:-1m}"
echo "[run] $FILE headless -u $VU -r $RATE -t $DUR (host=$HOST)"
exec env LOAD_SUPPLIER_ID="$LOAD_SUPPLIER_ID" "$LOCUST" -f "$FILE" --host "$HOST" --headless -u "$VU" -r "$RATE" -t "$DUR"
else
echo "[run] $FILE 웹 UI → http://localhost:8089 (host=$HOST)"
exec env LOAD_SUPPLIER_ID="$LOAD_SUPPLIER_ID" "$LOCUST" -f "$FILE" --host "$HOST"
fi