205 lines
7.6 KiB
Bash
205 lines
7.6 KiB
Bash
#!/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 |