#!/usr/bin/env bash set -euo pipefail # Run full test suite once (expanded), capture output, parse failed test files, rerun them once, and summarize. cd "$(dirname "$0")/.." TARGET_PATH="${1:-}" OUT="/tmp/flutter_test_$(date +%s).log" echo "[Full] flutter test -j 1 -r expanded ${TARGET_PATH:+-- $TARGET_PATH} (capturing to $OUT)" set +e if [ -n "$TARGET_PATH" ]; then flutter test -j 1 -r expanded "$TARGET_PATH" | tee "$OUT" else flutter test -j 1 -r expanded | tee "$OUT" fi status_full=${PIPESTATUS[0]} set -e # Strip ANSI escape codes for reliable parsing CLEAN_OUT="${OUT}.clean" if command -v perl >/dev/null 2>&1; then perl -pe 's/\e\[[0-9;]*[A-Za-z]//g' "$OUT" > "$CLEAN_OUT" || cp "$OUT" "$CLEAN_OUT" else # Fallback: naive removal sed -E 's/\x1B\[[0-9;]*[A-Za-z]//g' "$OUT" > "$CLEAN_OUT" || cp "$OUT" "$CLEAN_OUT" fi failed_files=() if [ "$status_full" -ne 0 ]; then # Extract lines with pattern: "/path/to/file.dart: " while IFS= read -r line; do # Attempt to extract the dart file path before the colon file=$(echo "$line" | sed -nE 's@^([^:]+\.dart):.*@\1@p') if [ -n "$file" ] && [ -f "$file" ]; then failed_files+=("$file") fi done < <(grep -E "^/.+\.dart: " "$CLEAN_OUT" | sort | uniq) # Fallback: no parsed files, try a full rerun once to check stability if [ ${#failed_files[@]} -eq 0 ]; then echo "[Info] Full run failed but no failed files parsed. Trying machine reporter to extract suites..." MACHINE_OUT="${OUT}.machine" set +e if [ -n "$TARGET_PATH" ]; then flutter test -j 1 --machine "$TARGET_PATH" > "$MACHINE_OUT" 2>/dev/null else flutter test -j 1 --machine > "$MACHINE_OUT" 2>/dev/null fi status_machine=$? set -e # Extract suitePath values (compatible with macOS bash) while IFS= read -r mf; do [ -f "$mf" ] && failed_files+=("$mf") done < <(grep -oE '"suitePath":"[^"]+\.dart"' "$MACHINE_OUT" | sed -E 's/\\\//g; s/"suitePath":"//; s/"$//' | sort | uniq) # If still none, perform a single full rerun as a flake check if [ ${#failed_files[@]} -eq 0 ]; then echo "[Info] Machine reporter also found no suites. Performing a full rerun once..." set +e if [ -n "$TARGET_PATH" ]; then flutter test -j 1 -r compact "$TARGET_PATH" else flutter test -j 1 -r compact fi status_rerun=$? set -e if [ "$status_rerun" -eq 0 ]; then echo "[Rerun] Full rerun passed. Treating as success due to flakiness." echo "========================================" echo "Full run status: FAILED (first) → PASSED (rerun)" echo "Log: $OUT" [ -f "$CLEAN_OUT" ] && echo "Clean log: $CLEAN_OUT" echo "========================================" exit 0 fi # Directory-scoped fallback: run each test file individually; if all pass, treat as success if [ -n "$TARGET_PATH" ] && [ -d "$TARGET_PATH" ]; then echo "[Info] Falling back to per-file runs under: $TARGET_PATH" per_pass=0 per_count=0 failed_list=() while IFS= read -r tf; do per_count=$((per_count+1)) echo "[Per-File $per_count] flutter test -j 1 -r compact \"$tf\"" if flutter test -j 1 -r compact "$tf"; then per_pass=$((per_pass+1)) else echo "[Per-File] FAILED: $tf" failed_list+=("$tf") fi done < <(find "$TARGET_PATH" -type f -name "*_test.dart" | sort) echo "Per-file summary: $per_pass/$per_count passed" if [ ${#failed_list[@]} -gt 0 ]; then echo "[Per-File] Failed files:" printf ' - %s\n' "${failed_list[@]}" echo "[Per-File] Rerunning failed files once more to check flakiness..." per_rerun_pass=0 per_rerun_count=${#failed_list[@]} for ff in "${failed_list[@]}"; do echo "[Per-File Rerun] flutter test -j 1 -r compact \"$ff\"" if flutter test -j 1 -r compact "$ff"; then per_rerun_pass=$((per_rerun_pass+1)) else echo "[Per-File Rerun] STILL FAIL: $ff" fi done echo "[Per-File Rerun] summary: $per_rerun_pass/$per_rerun_count passed" # 성공 누적 반영 per_pass=$((per_pass + per_rerun_pass)) fi if [ "$per_pass" -eq "$per_count" ] && [ "$per_count" -gt 0 ]; then echo "[Per-File] All tests passed when run individually. Treating as success due to flakiness." exit 0 fi fi fi fi fi repass=0 recount=0 if [ ${#failed_files[@]} -gt 0 ]; then echo "[Rerun] Failed files detected:" printf ' - %s\n' "${failed_files[@]}" for f in "${failed_files[@]}"; do recount=$((recount+1)) echo "[Rerun $recount] flutter test -j 1 -r compact \"$f\"" if flutter test -j 1 -r compact "$f"; then repass=$((repass+1)) fi done fi echo "========================================" echo "Full run status: $( [ "$status_full" -eq 0 ] && echo PASSED || echo FAILED )" if [ ${#failed_files[@]} -gt 0 ]; then echo "Rerun summary: $repass/$recount files passed on rerun" fi echo "Log: $OUT" if [ -f "$CLEAN_OUT" ]; then echo "Clean log: $CLEAN_OUT" fi echo "========================================" # Exit 0 if full run passed OR all rerun files passed if [ "$status_full" -eq 0 ]; then exit 0 fi if [ ${#failed_files[@]} -gt 0 ] && [ "$repass" -eq "$recount" ]; then exit 0 fi exit 1