Files
hakorune/tools/smokes/v2/run.sh

451 lines
12 KiB
Bash
Raw Normal View History

#!/bin/bash
# run.sh - スモークテストv2 単一エントリポイント
# Usage: ./run.sh --profile {quick|integration|full} [options]
set -euo pipefail
# スクリプトディレクトリ
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# デフォルト値
PROFILE="quick"
FORMAT="text"
JOBS=1
TIMEOUT=""
VERBOSE=false
DRY_RUN=false
FILTER=""
FORCE_CONFIG=""
# カラー定義
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly BOLD='\033[1m'
readonly NC='\033[0m'
# ログ関数
log_info() {
echo -e "${BLUE}[INFO]${NC} $*" >&2
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $*" >&2
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $*" >&2
}
log_error() {
echo -e "${RED}[ERROR]${NC} $*" >&2
}
log_header() {
echo -e "${BOLD}$*${NC}" >&2
}
# ヘルプ表示
show_help() {
cat << 'EOF'
Smoke Tests v2 - Nyash 2-Pillar Testing System
Usage:
./run.sh --profile PROFILE [options]
Profiles:
quick Development-time fast checks (1-2 min)
integration Basic VM ↔ LLVM parity checks (5-10 min)
full Complete matrix testing (15-30 min)
Options:
--profile PROFILE Test profile to run
--filter "PATTERN" Test filter (e.g., "boxes:string")
--format FORMAT Output format: text|json|junit
--jobs N Parallel execution count
--timeout SEC Timeout per test in seconds
--force-config CONFIG Force configuration: rust_vm_dynamic|llvm_static
--verbose Enable verbose output
--dry-run Show test list without execution
--help Show this help
Examples:
# Quick development check
./run.sh --profile quick
# Integration with filter
./run.sh --profile integration --filter "plugins:*"
# Full testing with JSON output
./run.sh --profile full --format json --jobs 4 --timeout 300
# Dry run to see what would be tested
./run.sh --profile integration --dry-run
Environment Variables:
SMOKES_FORCE_CONFIG Force specific configuration
SMOKES_PLUGIN_MODE Plugin mode: dynamic|static
CI CI environment detection
EOF
}
# 引数パース
parse_arguments() {
while [[ $# -gt 0 ]]; do
case $1 in
--profile)
PROFILE="$2"
shift 2
;;
--filter)
FILTER="$2"
shift 2
;;
--format)
FORMAT="$2"
shift 2
;;
--jobs)
JOBS="$2"
shift 2
;;
--timeout)
TIMEOUT="$2"
shift 2
;;
--force-config)
FORCE_CONFIG="$2"
shift 2
;;
--verbose)
VERBOSE=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
--help)
show_help
exit 0
;;
*)
log_error "Unknown option: $1"
show_help
exit 1
;;
esac
done
# プロファイル検証
case "$PROFILE" in
quick|integration|full|plugins)
;;
*)
log_error "Invalid profile: $PROFILE"
log_error "Valid profiles: quick, integration, full, plugins"
exit 1
;;
esac
# フォーマット検証
case "$FORMAT" in
text|json|junit)
;;
*)
log_error "Invalid format: $FORMAT"
log_error "Valid formats: text, json, junit"
exit 1
;;
esac
}
# 環境設定
setup_environment() {
log_info "Setting up environment for profile: $PROFILE"
# 共通ライブラリ読み込み
source "$SCRIPT_DIR/lib/test_runner.sh"
source "$SCRIPT_DIR/lib/plugin_manager.sh"
source "$SCRIPT_DIR/lib/result_checker.sh"
source "$SCRIPT_DIR/lib/preflight.sh"
# 設定読み込み
if [ -n "$FORCE_CONFIG" ]; then
export SMOKES_FORCE_CONFIG="$FORCE_CONFIG"
log_info "Forced configuration: $FORCE_CONFIG"
fi
source "$SCRIPT_DIR/configs/auto_detect.conf"
auto_configure "$PROFILE"
# プロファイル専用設定
export SMOKES_CURRENT_PROFILE="$PROFILE"
# コマンドライン引数の環境変数設定
if [ -n "$TIMEOUT" ]; then
export SMOKES_DEFAULT_TIMEOUT="$TIMEOUT"
fi
if [ "$VERBOSE" = true ]; then
export NYASH_CLI_VERBOSE=1
export SMOKES_LOG_LEVEL="debug"
fi
export SMOKES_PARALLEL_JOBS="$JOBS"
export SMOKES_OUTPUT_FORMAT="$FORMAT"
export SMOKES_TEST_FILTER="$FILTER"
# 作業ディレクトリ移動Nyashプロジェクトルートへ
cd "$SCRIPT_DIR/../../.."
log_info "Working directory: $(pwd)"
}
# プリフライトチェック
run_preflight() {
log_info "Running preflight checks..."
if ! preflight_all; then
log_error "Preflight checks failed"
log_error "Run with --verbose for detailed information"
exit 1
fi
log_success "Preflight checks passed"
}
# テストファイル検索
find_test_files() {
local profile_dir="$SCRIPT_DIR/profiles/$PROFILE"
local test_files=()
local have_llvm=0
if [ -x "./target/release/nyash" ] && ./target/release/nyash --version 2>/dev/null | grep -q "features.*llvm"; then
have_llvm=1
fi
if [ ! -d "$profile_dir" ]; then
log_error "Profile directory not found: $profile_dir"
exit 1
fi
# テストファイル検索
while IFS= read -r -d '' file; do
# フィルタ適用
if [ -n "$FILTER" ]; then
local relative_path
relative_path=$(realpath --relative-to="$profile_dir" "$file")
if ! echo "$relative_path" | grep -q "$FILTER"; then
continue
fi
fi
# LLVM未ビルド時は AST(LLVM) 系テストをスキップ
if [ $have_llvm -eq 0 ] && echo "$file" | grep -q "_ast\.sh$"; then
log_warn "Skipping (no LLVM): $file"
continue
fi
test_files+=("$file")
done < <(find "$profile_dir" -name "*.sh" -type f -print0)
printf '%s\n' "${test_files[@]}"
}
# 単一テスト実行
run_single_test() {
local test_file="$1"
local test_name
test_name=$(basename "$test_file" .sh)
if [ "$FORMAT" = "text" ]; then
echo -n "Running $test_name... "
fi
local start_time end_time duration exit_code
start_time=$(date +%s.%N)
# タイムアウト付きテスト実行
local timeout_cmd=""
if [ -n "${SMOKES_DEFAULT_TIMEOUT:-}" ]; then
timeout_cmd="timeout ${SMOKES_DEFAULT_TIMEOUT}"
fi
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
# 詳細ログ: 失敗時のみテイル表示
local log_file
log_file="/tmp/nyash_smoke_$(date +%s)_$$.log"
if $timeout_cmd bash "$test_file" >"$log_file" 2>&1; then
exit_code=0
else
exit_code=$?
fi
end_time=$(date +%s.%N)
duration=$(echo "$end_time - $start_time" | bc -l)
# 結果出力
case "$FORMAT" in
text)
if [ $exit_code -eq 0 ]; then
echo -e "${GREEN}PASS${NC} (${duration}s)"
else
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
echo -e "${RED}FAIL${NC} (exit=$exit_code, ${duration}s)"
echo -e "${YELLOW}[WARN]${NC} Test file: $test_file"
local TAIL_N="${SMOKES_NOTIFY_TAIL:-80}"
echo "----- LOG (tail -n $TAIL_N) -----"
tail -n "$TAIL_N" "$log_file" || true
echo "----- END LOG -----"
fi
;;
json)
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
local status_json
status_json=$([ $exit_code -eq 0 ] && echo "pass" || echo "fail")
echo "{\"name\":\"$test_name\",\"path\":\"$test_file\",\"status\":\"$status_json\",\"duration\":$duration,\"exit\":$exit_code}"
;;
junit)
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
# JUnit形式は後でまとめて出力pathも保持
echo "$test_name:$exit_code:$duration:$test_file" >> /tmp/junit_results.txt
;;
esac
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
# 後始末
rm -f "$log_file" 2>/dev/null || true
return $exit_code
}
# テスト実行
run_tests() {
local test_files
mapfile -t test_files < <(find_test_files)
if [ ${#test_files[@]} -eq 0 ]; then
log_warn "No test files found for profile: $PROFILE"
if [ -n "$FILTER" ]; then
log_warn "Filter applied: $FILTER"
fi
exit 0
fi
log_info "Found ${#test_files[@]} test files"
# Dry run
if [ "$DRY_RUN" = true ]; then
log_header "Test files that would be executed:"
for file in "${test_files[@]}"; do
echo " $(realpath --relative-to="$SCRIPT_DIR" "$file")"
done
exit 0
fi
# テスト実行開始
log_header "Starting $PROFILE profile tests"
local passed=0
local failed=0
local start_time
start_time=$(date +%s.%N)
# JSON形式の場合はヘッダー出力
if [ "$FORMAT" = "json" ]; then
echo '{"profile":"'$PROFILE'","tests":['
fi
# JUnit用ファイル初期化
if [ "$FORMAT" = "junit" ]; then
echo -n > /tmp/junit_results.txt
fi
# テスト実行
local first_test=true
for test_file in "${test_files[@]}"; do
if [ "$FORMAT" = "json" ] && [ "$first_test" = false ]; then
echo ","
fi
first_test=false
if run_single_test "$test_file"; then
passed=$((passed+1))
else
failed=$((failed+1))
# Fast fail モード
if [ "${SMOKES_FAST_FAIL:-0}" = "1" ]; then
log_warn "Fast fail enabled, stopping on first failure"
break
fi
fi
done
# 結果出力
local end_time total_duration
end_time=$(date +%s.%N)
total_duration=$(echo "$end_time - $start_time" | bc -l)
case "$FORMAT" in
text)
echo ""
log_header "Test Results Summary"
echo "Profile: $PROFILE"
echo "Total: $((passed + failed))"
echo "Passed: $passed"
echo "Failed: $failed"
echo "Duration: ${total_duration}s"
if [ $failed -eq 0 ]; then
log_success "All tests passed! ✨"
else
log_error "$failed test(s) failed"
fi
;;
json)
echo '],"summary":{"total":'$((passed + failed))',"passed":'$passed',"failed":'$failed',"duration":'$total_duration'}}'
;;
junit)
cat << EOF
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="smokes_$PROFILE" tests="$((passed + failed))" failures="$failed" time="$total_duration">
EOF
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
while IFS=':' read -r name exit_code duration path; do
if [ "$exit_code" = "0" ]; then
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
echo " <testcase name=\"$name\" time=\"$duration\" classname=\"$path\"/>"
else
feat: GC機能復活&VM整理&json_native調査完了 ## 🎉 ChatGPT×Claude協働成果 - ✅ **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活 - GCメトリクス追跡システム実装(alloc/collect/pause計測) - 3種類のGCモード対応(counting/mark_sweep/generational) - host_handles.rsでハンドル管理復活 - ✅ **VM整理とエイリアス追加**: 混乱していた名前を整理 - MirInterpreter = NyashVm = VM のエイリアス統一 - vm-legacyとインタープリターの違いを明確化 - 壊れていたvm.rsの互換性修復 - ✅ **スモークテスト整理**: v2構造でプラグイン/コア分離 - plugins/ディレクトリにプラグインテスト移動 - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加 - _ensure_fixture.shでプラグイン事前ビルド確認 ## 📊 json_native調査結果 - **現状**: 25%完成(配列/オブジェクトパース未実装) - **将来性**: 並行処理でyyjson超えの可能性大 - 100KB以上のJSONで2-10倍速の可能性 - Nyash ABI実装後はゼロコピー最適化 - **判断**: 現時点では置換不可、将来の大きな足場 ## 🔍 技術的発見 - vm-legacy = 完全なVM実装(GC付き)だった - MirInterpreter = 現在のRust VM(712行、Arc使用) - 200行簡易JSONは既に削除済み(存在しない) ChatGPT爆速修復×Claude詳細調査の完璧な協働! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 23:27:59 +09:00
echo " <testcase name=\"$name\" time=\"$duration\" classname=\"$path\"><failure message=\"exit=$exit_code\"/></testcase>"
fi
done < /tmp/junit_results.txt
echo "</testsuite>"
rm -f /tmp/junit_results.txt
;;
esac
# 終了コード
[ $failed -eq 0 ]
}
# メイン処理
main() {
# 引数パース
parse_arguments "$@"
# バナー表示
if [ "$FORMAT" = "text" ]; then
log_header "🔥 Nyash Smoke Tests v2 - 2-Pillar Testing System"
log_info "Profile: $PROFILE | Format: $FORMAT | Jobs: $JOBS"
if [ -n "$FILTER" ]; then
log_info "Filter: $FILTER"
fi
echo ""
fi
# 環境設定
setup_environment
# プリフライト
run_preflight
# テスト実行
run_tests
}
# エラーハンドリング
trap 'log_error "Script interrupted"; exit 130' INT TERM
# メイン実行
main "$@"