112 lines
4.3 KiB
Bash
Executable File
112 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
||
set -euo pipefail
|
||
BASE="http://localhost:8000"
|
||
FRONT="http://localhost"
|
||
POSTGREST="http://localhost:3000"
|
||
|
||
echo "=== EMS Platform Smoke Test ==="
|
||
|
||
# 1. Health
|
||
echo -n "Health endpoint... "
|
||
curl -sf "$BASE/api/v1/health" | python3 -c "
|
||
import sys,json; d=json.load(sys.stdin)
|
||
assert d['status']=='ok', f'status={d[\"status\"]}'
|
||
assert d['db']=='ok', f'db={d[\"db\"]}'
|
||
print('OK')
|
||
"
|
||
|
||
# 2. Sites + první site_id (seed nemusí být vždy id=1)
|
||
echo -n "Sites endpoint... "
|
||
SITE_ID=$(curl -sf "$BASE/api/v1/sites" | python3 -c "
|
||
import sys,json; d=json.load(sys.stdin)
|
||
assert len(d)>0, 'no sites'
|
||
print(d[0]['id'])
|
||
")
|
||
echo "OK (site_id=$SITE_ID)"
|
||
|
||
# 3. Prices (dnes)
|
||
echo -n "Prices endpoint... "
|
||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/api/v1/sites/${SITE_ID}/prices")
|
||
[ "$STATUS" = "200" ] && echo "OK" || echo "WARN (HTTP $STATUS – ceny možná nejsou importovány)"
|
||
|
||
# 4. Plan current (může být 404 – bez plánu)
|
||
echo -n "Plan current... "
|
||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/api/v1/sites/${SITE_ID}/plan/current")
|
||
[ "$STATUS" = "200" ] && echo "OK (plán existuje)" || echo "OK (HTTP $STATUS – zatím žádný plán)"
|
||
|
||
# 5. Import cen OTE (zítra)
|
||
echo -n "OTE price import... "
|
||
RESULT=$(curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/prices/import" \
|
||
-H "Content-Type: application/json" 2>/dev/null) || RESULT=""
|
||
PRICES_EXPECTED=$(python3 -c "
|
||
from zoneinfo import ZoneInfo
|
||
from datetime import datetime
|
||
n = datetime.now(ZoneInfo('Europe/Prague'))
|
||
print(1 if (n.hour, n.minute) >= (14, 30) else 0)
|
||
")
|
||
if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d.get('slots_imported',0)>0" 2>/dev/null; then
|
||
echo "OK ($(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['slots_imported'])") slotů)"
|
||
elif [ "$PRICES_EXPECTED" = "1" ]; then
|
||
echo "WARN – OTE API možná nemá data pro zítřek nebo je nedostupné (po 14:30 Europe/Prague)"
|
||
else
|
||
echo "OK (před 14:30 Europe/Prague – D+1 ceny typicky ještě nejsou; import přeskočen bez WARN)"
|
||
fi
|
||
|
||
# 6. PV forecast
|
||
echo -n "PV forecast... "
|
||
RESULT=$(curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/forecast/run" 2>/dev/null) || RESULT=""
|
||
if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d.get('intervals_saved',0)>0" 2>/dev/null; then
|
||
echo "OK"
|
||
else
|
||
echo "WARN – forecast selhal (zkontroluj GPS souřadnice v seed datech)"
|
||
fi
|
||
|
||
# 7. Spustit plán (potřebuje ceny + forecast)
|
||
echo -n "Planning run... "
|
||
RESULT=$(curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/plan/run?type=daily" 2>/dev/null) || RESULT=""
|
||
if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d.get('run_id') is not None" 2>/dev/null; then
|
||
echo "OK (run_id=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['run_id'])"))"
|
||
else
|
||
echo "WARN – planning selhal: $RESULT"
|
||
fi
|
||
|
||
# 8. Přepnutí režimu a zpět (API + ověření přes PostgREST)
|
||
echo -n "Operating mode switch... "
|
||
curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/mode" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"mode":"PRESERVE","notes":"smoke test","valid_until":null}' >/dev/null || true
|
||
RESULT=$(curl -sf "${POSTGREST}/vw_site_status?site_id=eq.${SITE_ID}" 2>/dev/null) || RESULT=""
|
||
MODE=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['active_mode'])" 2>/dev/null) || MODE=""
|
||
if [ "$MODE" = "PRESERVE" ]; then
|
||
echo "OK"
|
||
else
|
||
echo "WARN (mode=$MODE)"
|
||
fi
|
||
curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/mode" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"mode":"AUTO","notes":"smoke test restore","valid_until":null}' >/dev/null || true
|
||
|
||
# 9. EV sessions endpoint
|
||
echo -n "EV sessions endpoint... "
|
||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||
"$BASE/api/v1/sites/${SITE_ID}/ev/sessions/active")
|
||
[ "$STATUS" = "200" ] && echo "OK (HTTP 200)" || echo "FAIL (HTTP $STATUS)"
|
||
|
||
# 10. Frontend dostupný
|
||
echo -n "Frontend (nginx)... "
|
||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$FRONT/")
|
||
[ "$STATUS" = "200" ] && echo "OK" || echo "FAIL (HTTP $STATUS)"
|
||
|
||
# 11. PostgREST přes nginx
|
||
echo -n "PostgREST přes nginx... "
|
||
if curl -sf "$FRONT/rest/vw_site_status?limit=1" | python3 -c "
|
||
import sys,json; d=json.load(sys.stdin); print(f'OK ({len(d)} rows)')
|
||
" 2>/dev/null; then
|
||
:
|
||
else
|
||
echo "WARN – PostgREST možná potřebuje anon roli"
|
||
fi
|
||
|
||
echo ""
|
||
echo "=== Smoke test dokončen ==="
|