기존 측정 데이터만으로 "경보가 터지기 전"을 보여주고, 위험 시 무엇을 할지 안내한다. 새 센서·ML·DB 스키마 변경 없음(폐쇄망 정합). 신규 php/forecast.php — 순수 계산 함수(DB·출력 없음, 단위테스트 용이): - dew_point_c(Magnus 이슬점), linear_trend(최소자승 회귀), threshold_eta_min (임계 도달 예상 분), headroom_state(여유 3단계), forecast_metric/freshness, risk_items(대응 섹션용 정규화 위험 목록). tests/forecast_test.php — 31 검사(이슬점 알려진값·회귀·ETA·여유·신선도·위험 엣지). config.php — FORECAST_*(지평/최소점/근접여유/급변 기준) + RESPONSE_PLAYBOOKS (상태별 대응 체크리스트) + RESPONSE_CONTACTS. 전부 config.local.php 오버라이드. dashboard.php — 센서별 최근점으로 예보 계산 → - 카드 예보줄(상시): 임계 여유·추세 ETA·이슬점 결로·변화율(근접/초과만 강조). - 대응 필요 섹션(위험 시만): 조건·ETA + 상태별 권장 조치 체크리스트 + 담당자. 기존 offline 판정을 단일 진실원으로 사용, 누수 노드 중복 없음. app.css — .forecast-chip(near/over 상태 3중 인코딩)·.response-panel·.playbook· .contact (토큰 기반, 라이트/다크 자동). run_tests.sh 에 forecast_test 등록. 검증: forecast_test 31/0, php -l clean(7페이지+forecast), 헤드리스 렌더 확인.
53 lines
2.1 KiB
Bash
53 lines
2.1 KiB
Bash
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# run_tests.sh - 전체 회귀 테스트 러너 (CI / 수동)
|
|
#
|
|
# 실행 대상:
|
|
# 1) PHP 단위/회귀 테스트 3종 (tests/*.php)
|
|
# 2) 펌웨어 호스트 패리티 (firmware/test/host/parity_test.py)
|
|
# - C↔Python↔PHP 서명 패리티(gcc/clang + php 가용 시 C 포함)
|
|
#
|
|
# php / python3 / gcc 가 없으면 해당 묶음을 SKIP 으로 *명확히* 보고한다(무성 스킵 금지).
|
|
# 하나라도 FAIL 이면 종료코드 1.
|
|
# =============================================================================
|
|
set -u
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
fail=0; ran=0; skipped=0
|
|
|
|
have() { command -v "$1" >/dev/null 2>&1; }
|
|
|
|
run_php() { # test_file
|
|
local f="$1"
|
|
if ! have php; then echo "SKIP (php 없음): ${f}"; skipped=$((skipped+1)); return; fi
|
|
echo "── php ${f}"
|
|
if php "${ROOT}/${f}"; then ran=$((ran+1)); else echo " FAIL: ${f}"; fail=1; fi
|
|
}
|
|
|
|
echo "=== 1) PHP 회귀 테스트 ==="
|
|
run_php tests/raw_body_signature_test.php
|
|
run_php tests/security_hardening_test.php
|
|
run_php tests/threshold_sms_test.php
|
|
run_php tests/chaos_drill.php # SMS 실패 주입 경로 드릴
|
|
run_php tests/forecast_test.php # 예보(이슬점/회귀/ETA/여유/신선도/위험) 순수함수
|
|
|
|
echo ""
|
|
echo "=== 2) 펌웨어 호스트 패리티 (C↔Python↔PHP) ==="
|
|
if have python3 && have php; then
|
|
echo "── python3 firmware/test/host/parity_test.py"
|
|
if ( cd "${ROOT}/firmware/test/host" && python3 parity_test.py ); then
|
|
ran=$((ran+1))
|
|
else
|
|
echo " FAIL: parity_test.py"; fail=1
|
|
fi
|
|
if ! have gcc && ! have cc && ! have clang; then
|
|
echo " NOTE: C 컴파일러 없음 — 위 패리티는 Python↔PHP 만 검증(C 서명 미컴파일)."
|
|
fi
|
|
else
|
|
echo "SKIP (python3/php 없음): firmware/test/host/parity_test.py"; skipped=$((skipped+1))
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== 요약: 실행 ${ran}, 스킵 ${skipped} ==="
|
|
if [ "${fail}" -ne 0 ]; then echo "결과: FAIL"; exit 1; fi
|
|
if [ "${ran}" -eq 0 ]; then echo "결과: NO-OP (실행된 테스트 없음 — php/python3 설치 필요)"; exit 0; fi
|
|
echo "결과: PASS"
|