-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathgenerate_codecov.sh
More file actions
134 lines (107 loc) · 4.55 KB
/
Copy pathgenerate_codecov.sh
File metadata and controls
134 lines (107 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/bin/bash
set -euo pipefail
echo "==================================="
echo "[STEP 1] Installing dependencies"
echo "==================================="
# Update package list
sudo apt-get update
# Install LLVM (for llvm-profdata, llvm-cov)
if ! command -v llvm-profdata &>/dev/null; then
echo "[ACTION] Installing LLVM via apt"
sudo apt-get install -y llvm
fi
# Install lcov (provides lcov + genhtml)
if ! command -v genhtml &>/dev/null; then
echo "[ACTION] Installing lcov via apt"
sudo apt-get install -y lcov
fi
# Install Python plugin for LCOV export
if ! python -m pip show coverage-lcov &>/dev/null; then
echo "[ACTION] Installing coverage-lcov via pip"
python -m pip install coverage-lcov
fi
# Install LCOV → Cobertura converter (for ADO)
if ! python -m pip show lcov-cobertura &>/dev/null; then
echo "[ACTION] Installing lcov-cobertura via pip"
python -m pip install lcov-cobertura
fi
echo "==================================="
echo "[STEP 2] Running pytest with Python coverage"
echo "==================================="
# Cleanup old coverage
rm -f .coverage coverage.xml python-coverage.info cpp-coverage.info total.info
rm -rf htmlcov unified-coverage
# Run pytest with Python coverage (XML + HTML output)
python -m pytest -v \
--junitxml=test-results.xml \
--cov=mssql_python \
--cov-report=xml:coverage.xml \
--cov-report=html \
--capture=tee-sys \
--cache-clear
# Convert Python coverage to LCOV format (restrict to repo only)
echo "[ACTION] Converting Python coverage to LCOV"
coverage lcov -o python-coverage.info --include="mssql_python/*"
echo "==================================="
echo "[STEP 3] Processing C++ coverage (Clang/LLVM)"
echo "==================================="
# Merge raw profile data from pybind runs
if [ ! -f default.profraw ]; then
echo "[ERROR] default.profraw not found. Did you build with -fprofile-instr-generate?"
exit 1
fi
llvm-profdata merge -sparse default.profraw -o default.profdata
# Find the pybind .so file (Linux build)
PYBIND_SO=$(find mssql_python -name "*.so" | head -n 1)
if [ -z "$PYBIND_SO" ]; then
echo "[ERROR] Could not find pybind .so"
exit 1
fi
echo "[INFO] Using pybind module: $PYBIND_SO"
# Export C++ coverage, excluding Python headers, pybind11, system includes, and vendored deps
llvm-cov export "$PYBIND_SO" \
-instr-profile=default.profdata \
-ignore-filename-regex='(python3\.[0-9]+|cpython|pybind11|/usr/include/|/usr/lib/|build/_deps/)' \
--skip-functions \
-format=lcov > cpp-coverage.info
# Note: LCOV exclusion markers (LCOV_EXCL_LINE) are processed below
echo "==================================="
echo "[STEP 4] Merging Python + C++ coverage"
echo "==================================="
# Merge LCOV reports and filter LOG statements using --omit-lines
# The --omit-lines option excludes lines matching the regex from coverage
# Since we joined multi-line LOGs during build, they're now on single lines
echo "[ACTION] Merging Python and C++ coverage with LOG exclusion"
lcov -a python-coverage.info -a cpp-coverage.info -o total-unfiltered.info \
--omit-lines '\bLOG[A-Z_]*\s*\(' \
--ignore-errors inconsistent,corrupt
echo "[INFO] Coverage merged with LOG statements excluded"
# Defense-in-depth: drop any vendored third-party sources pulled in via CMake
# FetchContent (e.g. simdutf). The llvm-cov ignore-filename-regex above is the
# primary filter; this catches anything that slips through future deps.
echo "[ACTION] Removing vendored third-party sources from merged coverage"
lcov --remove total-unfiltered.info '*/build/_deps/*' -o total.info \
--ignore-errors inconsistent,unused
# Normalize paths so everything starts from mssql_python/
echo "[ACTION] Normalizing paths in LCOV report"
sed -i "s|$(pwd)/||g" total.info
# Generate full HTML report
echo "[ACTION] Generating HTML coverage report"
genhtml total.info \
--output-directory unified-coverage \
--quiet \
--title "Unified Coverage Report"
# Generate Cobertura XML (for Azure DevOps Code Coverage tab)
lcov_cobertura total.info --output coverage.xml
echo "==================================="
echo "[STEP 5] Cleanup"
echo "==================================="
# Restore original source files if they were backed up during coverage build
BACKUP_FILE="mssql_python/pybind/.source_backup_coverage.tar.gz"
if [ -f "$BACKUP_FILE" ]; then
echo "[ACTION] Restoring original source files from backup"
(cd mssql_python/pybind && tar -xzf .source_backup_coverage.tar.gz)
rm -f "$BACKUP_FILE"
echo "[INFO] Original source files restored"
fi
echo "[INFO] Coverage report generation complete"