|
|
#!/usr/bin/env bash
|
|
|
# test2.sh - Lab2(IR生成)批量测试脚本
|
|
|
|
|
|
set -u
|
|
|
set -o pipefail
|
|
|
|
|
|
RED='\033[0;31m'
|
|
|
GREEN='\033[0;32m'
|
|
|
YELLOW='\033[1;33m'
|
|
|
BLUE='\033[0;34m'
|
|
|
NC='\033[0m'
|
|
|
|
|
|
TEST_ROOT="./test"
|
|
|
OUTPUT_DIR="./lab2_results"
|
|
|
COMPILER="./build/bin/compiler"
|
|
|
VERIFY_SCRIPT="./scripts/verify_ir.sh"
|
|
|
VERBOSE=false
|
|
|
FORCE=false
|
|
|
RUN_EXEC=false
|
|
|
MAX_CASES=0
|
|
|
INCLUDE_TEST_CASE=false
|
|
|
|
|
|
show_help() {
|
|
|
cat << 'EOF'
|
|
|
用法: ./test2.sh [选项]
|
|
|
|
|
|
说明:
|
|
|
批量执行 Lab2(IR 生成)测试。
|
|
|
默认会递归扫描 ./test 下所有 .sy 文件(自动跳过 test_result 目录),
|
|
|
并调用 scripts/verify_ir.sh 逐个生成 .ll。
|
|
|
|
|
|
选项:
|
|
|
-d, --dir DIR 测试根目录 (默认: ./test)
|
|
|
-o, --output DIR 输出目录 (默认: ./lab2_results)
|
|
|
-c, --compiler FILE 编译器路径 (默认: ./build/bin/compiler)
|
|
|
-s, --script FILE verify_ir脚本路径 (默认: ./scripts/verify_ir.sh)
|
|
|
-r, --run 生成 IR 后继续 llc/clang 运行校验
|
|
|
-f, --force 强制重跑(覆盖已有 .ll)
|
|
|
-v, --verbose 显示详细日志
|
|
|
-m, --max N 最多执行 N 个用例(0 表示不限制)
|
|
|
--include-test-case 额外包含 test/test_case 下用例(默认不包含)
|
|
|
-h, --help 显示帮助
|
|
|
|
|
|
示例:
|
|
|
./test2.sh
|
|
|
./test2.sh -r
|
|
|
./test2.sh -d ./test -o ./lab2_results -f -v
|
|
|
./test2.sh --max 20
|
|
|
./test2.sh --include-test-case
|
|
|
EOF
|
|
|
}
|
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
case "$1" in
|
|
|
-d|--dir)
|
|
|
TEST_ROOT="$2"
|
|
|
shift 2
|
|
|
;;
|
|
|
-o|--output)
|
|
|
OUTPUT_DIR="$2"
|
|
|
shift 2
|
|
|
;;
|
|
|
-c|--compiler)
|
|
|
COMPILER="$2"
|
|
|
shift 2
|
|
|
;;
|
|
|
-s|--script)
|
|
|
VERIFY_SCRIPT="$2"
|
|
|
shift 2
|
|
|
;;
|
|
|
-r|--run)
|
|
|
RUN_EXEC=true
|
|
|
shift
|
|
|
;;
|
|
|
-f|--force)
|
|
|
FORCE=true
|
|
|
shift
|
|
|
;;
|
|
|
-v|--verbose)
|
|
|
VERBOSE=true
|
|
|
shift
|
|
|
;;
|
|
|
-m|--max)
|
|
|
MAX_CASES="$2"
|
|
|
shift 2
|
|
|
;;
|
|
|
--include-test-case)
|
|
|
INCLUDE_TEST_CASE=true
|
|
|
shift
|
|
|
;;
|
|
|
-h|--help)
|
|
|
show_help
|
|
|
exit 0
|
|
|
;;
|
|
|
*)
|
|
|
echo -e "${RED}错误: 未知选项 $1${NC}"
|
|
|
show_help
|
|
|
exit 1
|
|
|
;;
|
|
|
esac
|
|
|
done
|
|
|
|
|
|
if [[ ! -d "$TEST_ROOT" ]]; then
|
|
|
echo -e "${RED}错误: 测试目录不存在: $TEST_ROOT${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
if [[ ! -x "$COMPILER" ]]; then
|
|
|
echo -e "${RED}错误: 编译器不可执行: $COMPILER${NC}"
|
|
|
echo -e "${YELLOW}提示: 请先构建: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build -j \"\$(nproc)\"${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
if [[ ! -x "$VERIFY_SCRIPT" ]]; then
|
|
|
echo -e "${RED}错误: verify脚本不可执行: $VERIFY_SCRIPT${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
if ! [[ "$MAX_CASES" =~ ^[0-9]+$ ]]; then
|
|
|
echo -e "${RED}错误: --max 需要非负整数${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
LOG_FILE="$OUTPUT_DIR/lab2_batch.log"
|
|
|
FAIL_FILE="$OUTPUT_DIR/failed_cases.txt"
|
|
|
: > "$LOG_FILE"
|
|
|
: > "$FAIL_FILE"
|
|
|
|
|
|
echo "Lab2 批量测试日志 - $(date)" >> "$LOG_FILE"
|
|
|
echo "TEST_ROOT=$TEST_ROOT" >> "$LOG_FILE"
|
|
|
echo "OUTPUT_DIR=$OUTPUT_DIR" >> "$LOG_FILE"
|
|
|
echo "RUN_EXEC=$RUN_EXEC FORCE=$FORCE MAX_CASES=$MAX_CASES" >> "$LOG_FILE"
|
|
|
echo "================================================" >> "$LOG_FILE"
|
|
|
|
|
|
mapfile -d '' -t CASES < <(find "$TEST_ROOT" -type f -name '*.sy' \
|
|
|
\( -path "$TEST_ROOT/testdata/*" -o -path "$TEST_ROOT/testdata2022/*" -o -path "$TEST_ROOT/testdata2024/*" \) \
|
|
|
-print0 | sort -z)
|
|
|
|
|
|
if [[ "$INCLUDE_TEST_CASE" = true ]]; then
|
|
|
mapfile -d '' -t EXTRA_CASES < <(find "$TEST_ROOT" -type f -name '*.sy' \
|
|
|
-path "$TEST_ROOT/test_case/*" \
|
|
|
-print0 | sort -z)
|
|
|
CASES+=("${EXTRA_CASES[@]}")
|
|
|
fi
|
|
|
|
|
|
TOTAL_FOUND=${#CASES[@]}
|
|
|
if [[ $TOTAL_FOUND -eq 0 ]]; then
|
|
|
echo -e "${YELLOW}未找到任何 .sy 用例,请检查目录: $TEST_ROOT${NC}"
|
|
|
exit 0
|
|
|
fi
|
|
|
|
|
|
TOTAL=0
|
|
|
SUCCESS=0
|
|
|
FAILED=0
|
|
|
SKIPPED=0
|
|
|
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
|
echo -e "${BLUE}Lab2 批量测试开始${NC}"
|
|
|
echo -e "${BLUE}测试根目录: $TEST_ROOT${NC}"
|
|
|
echo -e "${BLUE}找到用例数: $TOTAL_FOUND${NC}"
|
|
|
echo -e "${BLUE}输出目录: $OUTPUT_DIR${NC}"
|
|
|
echo -e "${BLUE}运行校验: $RUN_EXEC${NC}"
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
|
|
|
|
for file in "${CASES[@]}"; do
|
|
|
if [[ $MAX_CASES -gt 0 && $TOTAL -ge $MAX_CASES ]]; then
|
|
|
break
|
|
|
fi
|
|
|
|
|
|
rel_path="${file#$TEST_ROOT/}"
|
|
|
filename="$(basename "$file")"
|
|
|
base_name="${filename%.sy}"
|
|
|
rel_dir="$(dirname "$rel_path")"
|
|
|
case_out_dir="$OUTPUT_DIR/$rel_dir"
|
|
|
out_ll="$case_out_dir/$base_name.ll"
|
|
|
|
|
|
TOTAL=$((TOTAL + 1))
|
|
|
|
|
|
if [[ "$FORCE" = false && -s "$out_ll" ]]; then
|
|
|
SKIPPED=$((SKIPPED + 1))
|
|
|
if [[ "$VERBOSE" = true ]]; then
|
|
|
echo -e "${YELLOW}[$TOTAL] 跳过: $rel_path (已存在)${NC}"
|
|
|
else
|
|
|
echo -ne "${YELLOW}[$TOTAL] $filename ... ${NC}"
|
|
|
echo -e "${YELLOW}跳过${NC}"
|
|
|
fi
|
|
|
echo "[SKIPPED] $file" >> "$LOG_FILE"
|
|
|
continue
|
|
|
fi
|
|
|
|
|
|
mkdir -p "$case_out_dir"
|
|
|
|
|
|
if [[ "$VERBOSE" = true ]]; then
|
|
|
echo -e "${YELLOW}[$TOTAL] 测试: $rel_path${NC}"
|
|
|
else
|
|
|
echo -ne "${YELLOW}[$TOTAL] $filename ... ${NC}"
|
|
|
fi
|
|
|
|
|
|
if [[ "$RUN_EXEC" = true ]]; then
|
|
|
"$VERIFY_SCRIPT" "$file" "$case_out_dir" --run >> "$LOG_FILE" 2>&1
|
|
|
code=$?
|
|
|
else
|
|
|
"$VERIFY_SCRIPT" "$file" "$case_out_dir" >> "$LOG_FILE" 2>&1
|
|
|
code=$?
|
|
|
fi
|
|
|
|
|
|
if [[ $code -eq 0 ]]; then
|
|
|
SUCCESS=$((SUCCESS + 1))
|
|
|
if [[ "$VERBOSE" = true ]]; then
|
|
|
echo -e "${GREEN}✓ 成功: $case_out_dir/$base_name.ll${NC}"
|
|
|
else
|
|
|
echo -e "${GREEN}成功${NC}"
|
|
|
fi
|
|
|
echo "[SUCCESS] $file" >> "$LOG_FILE"
|
|
|
else
|
|
|
FAILED=$((FAILED + 1))
|
|
|
echo "$file" >> "$FAIL_FILE"
|
|
|
if [[ "$VERBOSE" = true ]]; then
|
|
|
echo -e "${RED}✗ 失败: $rel_path${NC}"
|
|
|
else
|
|
|
echo -e "${RED}失败${NC}"
|
|
|
fi
|
|
|
echo "[FAILED] $file (exit=$code)" >> "$LOG_FILE"
|
|
|
fi
|
|
|
done
|
|
|
|
|
|
RATE="0.00"
|
|
|
if [[ $TOTAL -gt 0 ]]; then
|
|
|
RATE=$(awk -v s="$SUCCESS" -v t="$TOTAL" 'BEGIN { printf "%.2f", (s*100.0)/t }')
|
|
|
fi
|
|
|
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
|
echo -e "${BLUE}Lab2 批量测试完成${NC}"
|
|
|
echo -e "${BLUE}执行用例: $TOTAL${NC}"
|
|
|
echo -e "${GREEN}成功: $SUCCESS${NC}"
|
|
|
echo -e "${RED}失败: $FAILED${NC}"
|
|
|
echo -e "${YELLOW}跳过: $SKIPPED${NC}"
|
|
|
echo -e "${BLUE}成功率: ${RATE}%${NC}"
|
|
|
echo -e "${BLUE}日志: $LOG_FILE${NC}"
|
|
|
if [[ $FAILED -gt 0 ]]; then
|
|
|
echo -e "${RED}失败清单: $FAIL_FILE${NC}"
|
|
|
fi
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
|
|
|
|
exit 0
|