#!/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/pm_threshold_test.php # PMS7003 미세먼지(PM2.5/PM10) 임계 판정 run_php tests/cooldown_episode_test.php # 에피소드 인지 쿨다운(복구 후 재발 누락 회귀) run_php tests/ingest_reject_log_test.php # 수집 거부 출처 로그(IP·로그인젝션 방지) 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"