@@ -88,8 +88,8 @@ stages:
88
88
89
89
- bash : |
90
90
set -e
91
- case "$(python -c 'import sys; print(sys.platform)') " in
92
- linux )
91
+ case "$AGENT_OS " in
92
+ Linux )
93
93
echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries
94
94
sudo apt update
95
95
sudo apt install --no-install-recommends \
@@ -103,6 +103,7 @@ stages:
103
103
gir1.2-gtk-3.0 \
104
104
graphviz \
105
105
inkscape \
106
+ lcov \
106
107
libcairo2 \
107
108
libgirepository-1.0-1 \
108
109
lmodern \
@@ -116,13 +117,13 @@ stages:
116
117
texlive-pictures \
117
118
texlive-xetex
118
119
;;
119
- darwin )
120
+ Darwin )
120
121
brew install --cask xquartz
121
122
brew install ccache ffmpeg imagemagick mplayer ninja pkg-config
122
123
brew tap homebrew/cask-fonts
123
124
brew install font-noto-sans-cjk-sc
124
125
;;
125
- win32 )
126
+ Windows_NT )
126
127
choco install ninja
127
128
;;
128
129
*)
@@ -139,8 +140,26 @@ stages:
139
140
displayName: 'Install dependencies with pip'
140
141
141
142
- bash : |
143
+ case "$AGENT_OS" in
144
+ Linux)
145
+ export CPPFLAGS='--coverage -fprofile-abs-path'
146
+ ;;
147
+ Darwin)
148
+ export CPPFLAGS='-fprofile-instr-generate=default.%m.profraw'
149
+ export CPPFLAGS="$CPPFLAGS -fcoverage-mapping"
150
+ ;;
151
+ Windows_NT)
152
+ CONFIG='--config-settings=setup-args=--vsenv'
153
+ CONFIG="$CONFIG --config-settings=setup-args=-Dcpp_link_args=-PROFILE"
154
+ CONFIG="$CONFIG --config-settings=setup-args=-Dbuildtype=debug"
155
+ ;;
156
+ *)
157
+ exit 1
158
+ ;;
159
+ esac
160
+
142
161
python -m pip install \
143
- --no-build-isolation --config-settings=setup-args="--vsenv" \
162
+ --no-build-isolation $CONFIG \
144
163
--verbose --editable .[dev] ||
145
164
[[ "$PYTHON_VERSION" = 'Pre' ]]
146
165
displayName: "Install self"
@@ -152,12 +171,109 @@ stages:
152
171
displayName : ' print pip'
153
172
154
173
- bash : |
155
- PYTHONFAULTHANDLER=1 python -m pytest --junitxml=junit/test-results.xml -raR --maxfail=50 --timeout=300 --durations=25 --cov-report= --cov=lib -n 2 ||
174
+ set -e
175
+ if [[ "$AGENT_OS" == 'Windows_NT' ]]; then
176
+ SESSION_ID=$(python -c "import uuid; print(uuid.uuid4(), end='')")
177
+ echo "Coverage session ID: ${SESSION_ID}"
178
+ VS=$(ls -d /c/Program\ Files*/Microsoft\ Visual\ Studio/*/Enterprise)
179
+ echo "Visual Studio: ${VS}"
180
+ DIR="$VS/Common7/IDE/Extensions/Microsoft/CodeCoverage.Console"
181
+ if [[ -d $DIR ]]; then
182
+ # This is for MSVC 2022 (on windows-latest).
183
+ TOOL="$DIR/Microsoft.CodeCoverage.Console.exe"
184
+ for f in build/cp*/src/*.pyd; do
185
+ echo $f
186
+ echo "=============================="
187
+ "$TOOL" instrument $f --session-id $SESSION_ID \
188
+ --log-level Verbose --log-file instrument.log
189
+ cat instrument.log
190
+ rm instrument.log
191
+ done
192
+ echo "Starting $TOOL in server mode"
193
+ "$TOOL" collect \
194
+ --session-id $SESSION_ID --server-mode \
195
+ --output-format cobertura --output extensions.xml \
196
+ --log-level Verbose --log-file extensions.log &
197
+ VS_VER=2022
198
+ else
199
+ DIR="$VS"/Team\ Tools/Dynamic\ Code\ Coverage\ Tools/amd64
200
+ if [[ -d $DIR ]]; then
201
+ # This is for MSVC 2019 (on windows-2019).
202
+ VSINSTR="$VS"/Team\ Tools/Performance\ Tools/vsinstr.exe
203
+ for f in build/cp*/src/*.pyd; do
204
+ "$VSINSTR" $f -Verbose -Coverage
205
+ done
206
+ TOOL="$DIR/CodeCoverage.exe"
207
+ cat > extensions.config << EOF
208
+ <CodeCoverage>
209
+ <CollectFromChildProcesses>true</CollectFromChildProcesses>
210
+ <ModulePaths>
211
+ <Include>
212
+ <ModulePath>.*\\.*\.pyd</ModulePath>
213
+ </Include>
214
+ </ModulePaths>
215
+ </CodeCoverage>
216
+ EOF
217
+ echo "Starting $TOOL in server mode"
218
+ "$TOOL" collect \
219
+ -config:extensions.config -session:$SESSION_ID \
220
+ -output:extensions.coverage -verbose &
221
+ echo "Started $TOOL"
222
+ VS_VER=2019
223
+ fi
224
+ fi
225
+ echo "##vso[task.setvariable variable=VS_COVERAGE_TOOL]$TOOL"
226
+ fi
227
+ PYTHONFAULTHANDLER=1 python -m pytest -raR -n 2 \
228
+ --maxfail=50 --timeout=300 --durations=25 \
229
+ --junitxml=junit/test-results.xml --cov-report=xml --cov=lib ||
156
230
[[ "$PYTHON_VERSION" = 'Pre' ]]
231
+ if [[ -n $SESSION_ID ]]; then
232
+ if [[ $VS_VER == 2022 ]]; then
233
+ "$TOOL" shutdown $SESSION_ID
234
+ echo "Coverage collection log"
235
+ echo "======================="
236
+ cat extensions.log
237
+ else
238
+ "$TOOL" shutdown -session:$SESSION_ID
239
+ fi
240
+ fi
157
241
displayName: 'pytest'
158
242
159
243
- bash : |
160
- bash <(curl -s https://codecov.io/bash) -f "!*.gcov" -X gcov
244
+ case "$AGENT_OS" in
245
+ Linux)
246
+ lcov --rc lcov_branch_coverage=1 --capture --directory . \
247
+ --output-file coverage.info
248
+ lcov --rc lcov_branch_coverage=1 --output-file coverage.info \
249
+ --extract coverage.info $PWD/src/'*' $PWD/lib/'*'
250
+ lcov --rc lcov_branch_coverage=1 --list coverage.info
251
+ find . -name '*.gc*' -delete
252
+ ;;
253
+ Darwin)
254
+ xcrun llvm-profdata merge -sparse default.*.profraw \
255
+ -o default.profdata
256
+ xcrun llvm-cov export -format="lcov" build/*/src/*.so \
257
+ -instr-profile default.profdata > info.lcov
258
+ ;;
259
+ Windows_NT)
260
+ if [[ -f extensions.coverage ]]; then
261
+ # For MSVC 2019.
262
+ "$VS_COVERAGE_TOOL" analyze -output:extensions.xml \
263
+ -include_skipped_functions -include_skipped_modules \
264
+ extensions.coverage
265
+ rm extensions.coverage
266
+ fi
267
+ ;;
268
+ *)
269
+ exit 1
270
+ ;;
271
+ esac
272
+ displayName: 'Filter C coverage'
273
+ - bash : |
274
+ bash <(curl -s https://codecov.io/bash) \
275
+ -n "$PYTHON_VERSION $AGENT_OS" \
276
+ -f 'coverage.xml' -f 'extensions.xml'
161
277
displayName: 'Upload to codecov.io'
162
278
163
279
- task : PublishTestResults@2
0 commit comments