Files
Alicho/tests/scripts/generate_coverage.sh
2025-10-28 10:27:49 +08:00

205 lines
7.6 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ================================================================================================
# Audio Backend - 测试覆盖率报告生成脚本
# ================================================================================================
# 描述: 生成项目的代码覆盖率报告基于gcov和lcov
# ================================================================================================
# 设置颜色输出
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色
# 脚本所在的目录路径
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# 项目根目录
ROOT_DIR="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")"
# 构建目录
BUILD_DIR="$ROOT_DIR/build"
# 测试结果目录
TEST_RESULTS_DIR="$ROOT_DIR/test-results"
# 覆盖率报告目录
COVERAGE_DIR="$TEST_RESULTS_DIR/coverage"
# 打印脚本信息
echo -e "${BLUE}=========================================================${NC}"
echo -e "${BLUE} 音频后端测试覆盖率报告生成脚本 ${NC}"
echo -e "${BLUE}=========================================================${NC}"
echo -e "${YELLOW}项目根目: ${ROOT_DIR}${NC}"
echo -e "${YELLOW}覆盖率报目录: ${COVERAGE_DIR}${NC}"
echo ""
# 确保覆盖率报告目录存在
mkdir -p "$COVERAGE_DIR"
# 检查lcov是否安装
if ! command -v lcov &> /dev/null; then
echo -e "${RED}错误: lcov 未安装。请安装 lcov 工具后重试。${NC}"
echo -e "可以使用以下命安装: sudo apt-get install lcov (Ubuntu/Debian)"
exit 1
fi
# 检查gcov是否安装
if ! command -v gcov &> /dev/null; then
echo -e "${RED}错误: gcov 未安装。请安装 gcov 工具后重试。${NC}"
echo -e "gcov 通常随 gcc 一起安装: sudo apt-get install gcc (Ubuntu/Debian)"
exit 1
fi
# 检查构建目录是否存在
if [ ! -d "$BUILD_DIR" ]; then
echo -e "${RED}错误: 构建目录不存在。请确保项目已经以覆盖率模式构建。${NC}"
echo -e "可以使用以下命构建项目: cmake -DENABLE_COVERAGE=ON .. && make"
exit 1
fi
echo -e "${BLUE}开始生成覆盖率报告...${NC}"
# 重置覆盖率计数器
echo -e "重置覆盖率计数..."
lcov --zerocounters --directory "$BUILD_DIR"
lcov --capture --initial --directory "$BUILD_DIR" --output-file "$COVERAGE_DIR/base.info"
# 运行单元测试以生成覆盖率数据
echo -e "运行单元测试以成覆盖率数据..."
"$SCRIPT_DIR/run_unit_tests.sh" > /dev/null 2>&1
test_result=$?
if [ $test_result -ne 0 ]; then
echo -e "${YELLOW}警告: 单元测试运行失败。覆盖率数据可能不完整。${NC}"
fi
# 收集覆盖率数据
echo -e "收集覆盖率数据..."
lcov --capture --directory "$BUILD_DIR" --output-file "$COVERAGE_DIR/test.info"
lcov --add-tracefile "$COVERAGE_DIR/base.info" --add-tracefile "$COVERAGE_DIR/test.info" \
--output-file "$COVERAGE_DIR/total.info"
# 过滤掉第三方库和测试代码
echo -e "过滤覆盖率数据..."
lcov --remove "$COVERAGE_DIR/total.info" \
"/usr/include/*" \
"/usr/local/include/*" \
"*/third_party/*" \
"*/tests/*" \
"*/googletest/*" \
--output-file "$COVERAGE_DIR/filtered.info"
# 生成HTML报告
echo -e "生成HTML覆盖率报告..."
genhtml --output-directory "$COVERAGE_DIR/html" \
--title "音频后端代码覆率报告" \
--legend --demangle-cpp \
"$COVERAGE_DIR/filtered.info"
if [ $? -ne 0 ]; then
echo -e "${RED}错误: 无法生成HTML覆盖报告。${NC}"
exit 1
fi
# 生成覆盖率摘要
echo -e "生成覆盖率摘要..."
lcov --summary "$COVERAGE_DIR/filtered.info" > "$COVERAGE_DIR/summary.txt" 2>&1
# 提取覆盖率数据
LINES_PERCENT=$(grep -oP 'lines\.*: \K[0-9.]+%' "$COVERAGE_DIR/summary.txt" | sed 's/%//')
FUNCTIONS_PERCENT=$(grep -oP 'functions\.*: \K[0-9.]+%' "$COVERAGE_DIR/summary.txt" | sed 's/%//')
BRANCHES_PERCENT=$(grep -oP 'branches\.*: \K[0-9.]+%' "$COVERAGE_DIR/summary.txt" | sed 's/%//')
# 检查覆盖率目标
LINES_TARGET=80.0
FUNCTIONS_TARGET=80.0
BRANCHES_TARGET=70.0
LINES_RESULT="${GREEN}${NC}"
FUNCTIONS_RESULT="${GREEN}通过${NC}"
BRANCHES_RESULT="${GREEN}通过${NC}"
if (( $(echo "$LINES_PERCENT < $LINES_TARGET" | bc -l) )); then
LINES_RESULT="${RED}未达标${NC}"
fi
if (( $(echo "$FUNCTIONS_PERCENT < $FUNCTIONS_TARGET" | bc -l) )); then
FUNCTIONS_RESULT="${RED}未达标${NC}"
fi
if (( $(echo "$BRANCHES_PERCENT < $BRANCHES_TARGET" | bc -l) )); then
BRANCHES_RESULT="${RED}未达标${NC}"
fi
# 打印覆盖率结果
echo -e "${BLUE}=========================================================${NC}"
echo -e "${BLUE} 覆盖率报告汇总 ${NC}"
echo -e "${BLUE}=========================================================${NC}"
echo -e "行覆盖率: ${LINES_PERCENT}% (目标: ${LINES_TARGET}%) - ${LINES_RESULT}"
echo -e "函数覆盖率: ${FUNCTIONS_PERCENT}% (目标: ${FUNCTIONS_TARGET}%) - ${FUNCTIONS_RESULT}"
echo -e "分支覆盖率: ${BRANCHES_PERCENT}% (目标: ${BRANCHES_TARGET}%) - ${BRANCHES_RESULT}"
echo ""
echo -e "详细HTML报告已生成到: ${YELLOW}${COVERAGE_DIR}/html/index.html${NC}"
echo ""
# 生成简单的覆盖率图标
BADGE_DIR="$COVERAGE_DIR/badges"
mkdir -p "$BADGE_DIR"
# 生成SVG覆盖率徽章
generate_badge() {
local title=$1
local percent=$2
local filename=$3
local color="red"
if (( $(echo "$percent >= 90.0" | bc -l) )); then
color="brightgreen"
elif (( $(echo "$percent >= 80.0" | bc -l) )); then
color="green"
elif (( $(echo "$percent >= 70.0" | bc -l) )); then
color="yellowgreen"
elif (( $(echo "$percent >= 60.0" | bc -l) )); then
color="yellow"
elif (( $(echo "$percent >= 50.0" | bc -l) )); then
color="orange"
fi
cat > "$BADGE_DIR/$filename" << EOF
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120" height="20" role="img">
<linearGradient id="s" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="r">
<rect width="120" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#r)">
<rect width="70" height="20" fill="#555"/>
<rect x="70" width="50" height="20" fill="#$color"/>
<rect width="120" height="20" fill="url(#s)"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
<text aria-hidden="true" x="350" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="600">$title</text>
<text x="350" y="140" transform="scale(.1)" fill="#fff" textLength="600">$title</text>
<text aria-hidden="true" x="950" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">$percent%</text>
<text x="950" y="140" transform="scale(.1)" fill="#fff" textLength="430">$percent%</text>
</g>
</svg>
EOF
}
generate_badge "行覆盖率" "$LINES_PERCENT" "line-coverage.svg"
generate_badge "函数覆盖率" "$FUNCTIONS_PERCENT" "function-coverage.svg"
generate_badge "分支覆盖率" "$BRANCHES_PERCENT" "branch-coverage.svg"
echo -e "覆盖率徽章已生到: ${YELLOW}${BADGE_DIR}${NC}"
echo ""
# 检查是否满足覆盖率要求
if (( $(echo "$LINES_PERCENT >= $LINES_TARGET" | bc -l) )) &&
(( $(echo "$FUNCTIONS_PERCENT >= $FUNCTIONS_TARGET" | bc -l) )) &&
(( $(echo "$BRANCHES_PERCENT >= $BRANCHES_TARGET" | bc -l) )); then
echo -e "${GREEN}覆盖率目达成!${NC}"
exit 0
else
echo -e "${YELLOW}覆盖率未目标!${NC}"
exit 0 # 不将覆盖率不足视为错误,但会发出警告
fi