SonarQube Version: 10.4.1, Community Edition
Deployment: Docker
Hi,
I am trying to measure the coverage of my Python project. For this I am using gitlab ci, where first the coverage report is created, and then the sonar scanner analyses the branch.
Extract of gitlab-ci.yml
coverage-backend:
image:
name: python:3.10
entrypoint:
- "/usr/bin/env"
stage: test
only:
- dev
services:
- name: git.tensor-olympus.com:5050/tensor-solutions/hephaestus:database
alias: db
script:
- cp backend/.env-template backend/.env
- pip3 install -r backend/requirements.txt
- coverage run -m pytest -v backend/tests/
- coverage xml -o "reports/coverage.xml"
artifacts:
paths:
- reports/coverage.xml
allow_failure: false
sonarqube-dev:
stage: analyze
only:
- dev
image:
name: sonarsource/sonar-scanner-cli:5.0
entrypoint: [""]
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner -Dsonar.projectVersion=$CI_COMMIT_SHA -Dsonar.branch.name=dev
allow_failure: true
I doublechecked the gitlab artefacts and I can say that the coverage report is there and there are defenity some lines covered.
coverage.xml
<?xml version="1.0" ?>
<coverage version="7.3.2" timestamp="1718369581211" lines-valid="626" lines-covered="427" line-rate="0.6821" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
<!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.3.2 -->
<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
<sources>
<source>/builds/iVeDjymz/0/censored/censored</source>
</sources>
<packages>
<package name="backend" line-rate="0.7681" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/__init__.py" complexity="0" line-rate="0.9231" branch-rate="0">
<methods/>
<lines>
<line number="7" hits="1"/>
<line number="9" hits="1"/>
<line number="10" hits="1"/>
<line number="12" hits="1"/>
<line number="14" hits="1"/>
<line number="16" hits="1"/>
<line number="17" hits="1"/>
<line number="18" hits="1"/>
<line number="19" hits="1"/>
<line number="25" hits="1"/>
<line number="27" hits="1"/>
<line number="28" hits="0"/>
<line number="30" hits="1"/>
</lines>
</class>
<class name="config.py" filename="backend/config.py" complexity="0" line-rate="0.6875" branch-rate="0">
<methods/>
<lines>
<line number="3" hits="1"/>
<line number="4" hits="1"/>
<line number="7" hits="1"/>
<line number="42" hits="1"/>
<line number="52" hits="1"/>
<line number="53" hits="0"/>
<line number="54" hits="1"/>
<line number="55" hits="0"/>
<line number="56" hits="1"/>
<line number="57" hits="0"/>
<line number="58" hits="1"/>
<line number="59" hits="0"/>
<line number="60" hits="1"/>
<line number="61" hits="0"/>
<line number="62" hits="1"/>
<line number="63" hits="0"/>
<line number="64" hits="1"/>
<line number="65" hits="0"/>
<line number="67" hits="1"/>
<line number="68" hits="0"/>
<line number="69" hits="1"/>
<line number="70" hits="0"/>
<line number="71" hits="1"/>
<line number="72" hits="0"/>
<line number="73" hits="1"/>
<line number="74" hits="0"/>
<line number="75" hits="1"/>
<line number="76" hits="0"/>
<line number="78" hits="1"/>
<line number="79" hits="0"/>
<line number="81" hits="1"/>
<line number="82" hits="0"/>
<line number="83" hits="1"/>
<line number="84" hits="0"/>
<line number="86" hits="1"/>
<line number="89" hits="1"/>
<line number="90" hits="1"/>
<line number="91" hits="1"/>
<line number="92" hits="1"/>
<line number="93" hits="1"/>
<line number="96" hits="1"/>
<line number="97" hits="1"/>
<line number="98" hits="1"/>
<line number="99" hits="1"/>
<line number="100" hits="1"/>
<line number="101" hits="1"/>
<line number="102" hits="1"/>
<line number="104" hits="1"/>
</lines>
</class>
<class name="extensions.py" filename="backend/extensions.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines>
<line number="3" hits="1"/>
<line number="4" hits="1"/>
<line number="5" hits="1"/>
<line number="6" hits="1"/>
<line number="8" hits="1"/>
<line number="9" hits="1"/>
<line number="10" hits="1"/>
<line number="11" hits="1"/>
</lines>
</class>
</classes>
</package>
<package name="backend.models" line-rate="0.7828" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/models/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
<class name="helper.py" filename="backend/models/helper.py" complexity="0" line-rate="0.5476" branch-rate="0">
<methods/>
<lines>
<line number="3" hits="1"/>
<line number="4" hits="1"/>
<line number="5" hits="1"/>
<line number="8" hits="1"/>
<line number="16" hits="1"/>
<line number="18" hits="1"/>
<line number="21" hits="1"/>
<line number="24" hits="1"/>
<line number="25" hits="1"/>
<line number="26" hits="1"/>
<line number="27" hits="1"/>
<line number="28" hits="1"/>
<line number="31" hits="1"/>
<line number="32" hits="1"/>
<line number="35" hits="1"/>
<line number="38" hits="1"/>
<line number="39" hits="1"/>
<line number="40" hits="1"/>
<line number="43" hits="1"/>
<line number="55" hits="1"/>
<line number="64" hits="0"/>
<line number="65" hits="0"/>
<line number="67" hits="1"/>
<line number="81" hits="0"/>
<line number="82" hits="0"/>
<line number="83" hits="0"/>
<line number="84" hits="0"/>
<line number="88" hits="1"/>
<line number="102" hits="0"/>
<line number="103" hits="0"/>
<line number="104" hits="0"/>
<line number="105" hits="0"/>
<line number="106" hits="0"/>
<line number="107" hits="0"/>
<line number="108" hits="0"/>
<line number="109" hits="0"/>
<line number="112" hits="1"/>
<line number="126" hits="0"/>
<line number="127" hits="0"/>
<line number="128" hits="0"/>
<line number="131" hits="0"/>
<line number="132" hits="0"/>
</lines>
</class>
<class name="tool_jobs.py" filename="backend/models/tool_jobs.py" complexity="0" line-rate="0.8485" branch-rate="0">
<methods/>
<lines>
<line number="16" hits="1"/>
<line number="17" hits="1"/>
<line number="18" hits="1"/>
<line number="19" hits="1"/>
<line number="20" hits="1"/>
<line number="22" hits="1"/>
<line number="23" hits="1"/>
<line number="24" hits="1"/>
<line number="27" hits="1"/>
<line number="62" hits="1"/>
<line number="63" hits="1"/>
<line number="66" hits="1"/>
<line number="67" hits="1"/>
<line number="71" hits="1"/>
<line number="77" hits="1"/>
<line number="78" hits="1"/>
<line number="79" hits="1"/>
<line number="81" hits="1"/>
<line number="85" hits="1"/>
<line number="86" hits="1"/>
<line number="87" hits="1"/>
<line number="88" hits="1"/>
<line number="89" hits="1"/>
<line number="91" hits="1"/>
<line number="100" hits="1"/>
<line number="102" hits="1"/>
<line number="115" hits="1"/>
<line number="116" hits="0"/>
<line number="117" hits="0"/>
<line number="120" hits="1"/>
<line number="130" hits="1"/>
<line number="133" hits="1"/>
<line number="135" hits="1"/>
<line number="137" hits="1"/>
<line number="139" hits="0"/>
<line number="142" hits="1"/>
<line number="143" hits="1"/>
<line number="144" hits="1"/>
<line number="146" hits="1"/>
<line number="148" hits="1"/>
<line number="149" hits="0"/>
<line number="152" hits="1"/>
<line number="153" hits="1"/>
<line number="154" hits="1"/>
<line number="156" hits="1"/>
<line number="158" hits="1"/>
<line number="159" hits="0"/>
<line number="162" hits="1"/>
<line number="163" hits="1"/>
<line number="164" hits="1"/>
<line number="170" hits="1"/>
<line number="173" hits="1"/>
<line number="174" hits="1"/>
<line number="180" hits="1"/>
<line number="183" hits="1"/>
<line number="185" hits="1"/>
<line number="194" hits="0"/>
<line number="196" hits="1"/>
<line number="209" hits="0"/>
<line number="210" hits="0"/>
<line number="211" hits="0"/>
<line number="214" hits="1"/>
<line number="215" hits="1"/>
<line number="216" hits="1"/>
<line number="218" hits="1"/>
<line number="219" hits="0"/>
</lines>
</class>
<class name="tools.py" filename="backend/models/tools.py" complexity="0" line-rate="0.8676" branch-rate="0">
<methods/>
<lines>
<line number="15" hits="1"/>
<line number="16" hits="1"/>
<line number="17" hits="1"/>
<line number="18" hits="1"/>
<line number="19" hits="1"/>
<line number="20" hits="1"/>
<line number="21" hits="1"/>
<line number="24" hits="1"/>
<line number="25" hits="1"/>
<line number="26" hits="1"/>
<line number="27" hits="1"/>
<line number="28" hits="1"/>
<line number="29" hits="1"/>
<line number="30" hits="1"/>
<line number="31" hits="1"/>
<line number="32" hits="1"/>
<line number="33" hits="1"/>
<line number="35" hits="1"/>
<line number="36" hits="1"/>
<line number="41" hits="1"/>
<line number="42" hits="1"/>
<line number="44" hits="1"/>
<line number="53" hits="1"/>
<line number="55" hits="1"/>
<line number="68" hits="1"/>
<line number="69" hits="0"/>
<line number="70" hits="0"/>
<line number="73" hits="1"/>
<line number="74" hits="1"/>
<line number="75" hits="1"/>
<line number="76" hits="1"/>
<line number="78" hits="1"/>
<line number="79" hits="1"/>
<line number="80" hits="1"/>
<line number="82" hits="1"/>
<line number="83" hits="0"/>
<line number="86" hits="1"/>
<line number="87" hits="1"/>
<line number="88" hits="1"/>
<line number="89" hits="1"/>
<line number="102" hits="1"/>
<line number="103" hits="1"/>
<line number="104" hits="1"/>
<line number="106" hits="1"/>
<line number="107" hits="0"/>
<line number="110" hits="1"/>
<line number="111" hits="1"/>
<line number="112" hits="1"/>
<line number="115" hits="1"/>
<line number="116" hits="1"/>
<line number="117" hits="1"/>
<line number="118" hits="1"/>
<line number="119" hits="1"/>
<line number="120" hits="1"/>
<line number="125" hits="1"/>
<line number="127" hits="1"/>
<line number="136" hits="0"/>
<line number="138" hits="1"/>
<line number="151" hits="0"/>
<line number="152" hits="0"/>
<line number="153" hits="0"/>
<line number="156" hits="1"/>
<line number="157" hits="1"/>
<line number="158" hits="1"/>
<line number="160" hits="1"/>
<line number="161" hits="1"/>
<line number="163" hits="1"/>
<line number="164" hits="0"/>
</lines>
</class>
<class name="user.py" filename="backend/models/user.py" complexity="0" line-rate="0.7727" branch-rate="0">
<methods/>
<lines>
<line number="15" hits="1"/>
<line number="17" hits="1"/>
<line number="18" hits="1"/>
<line number="21" hits="1"/>
<line number="22" hits="1"/>
<line number="23" hits="1"/>
<line number="24" hits="1"/>
<line number="25" hits="1"/>
<line number="26" hits="1"/>
<line number="28" hits="1"/>
<line number="29" hits="1"/>
<line number="35" hits="1"/>
<line number="44" hits="0"/>
<line number="46" hits="1"/>
<line number="59" hits="0"/>
<line number="60" hits="0"/>
<line number="61" hits="0"/>
<line number="64" hits="1"/>
<line number="65" hits="1"/>
<line number="66" hits="1"/>
<line number="68" hits="1"/>
<line number="69" hits="0"/>
</lines>
</class>
</classes>
</package>
<package name="backend.services" line-rate="1" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/services/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
</classes>
</package>
<package name="backend.services.scheduler" line-rate="1" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/services/scheduler/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
<class name="scheduler.py" filename="backend/services/scheduler/scheduler.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines>
<line number="6" hits="1"/>
<line number="10" hits="1"/>
<line number="11" hits="1"/>
<line number="13" hits="1"/>
<line number="14" hits="1"/>
<line number="15" hits="1"/>
<line number="16" hits="1"/>
<line number="17" hits="1"/>
<line number="20" hits="1"/>
<line number="30" hits="1"/>
<line number="31" hits="1"/>
<line number="33" hits="1"/>
<line number="45" hits="1"/>
<line number="46" hits="1"/>
<line number="51" hits="1"/>
<line number="52" hits="1"/>
<line number="55" hits="1"/>
<line number="56" hits="1"/>
<line number="57" hits="1"/>
<line number="60" hits="1"/>
<line number="62" hits="1"/>
<line number="76" hits="1"/>
<line number="83" hits="1"/>
<line number="84" hits="1"/>
<line number="85" hits="1"/>
<line number="86" hits="1"/>
<line number="88" hits="1"/>
<line number="97" hits="1"/>
</lines>
</class>
</classes>
</package>
<package name="backend.services.scheduler.slurm" line-rate="0.4696" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/services/scheduler/slurm/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
<class name="slurm_control.py" filename="backend/services/scheduler/slurm/slurm_control.py" complexity="0" line-rate="0.3297" branch-rate="0">
<methods/>
<lines>
<line number="5" hits="1"/>
<line number="12" hits="1"/>
<line number="13" hits="1"/>
<line number="14" hits="1"/>
<line number="16" hits="1"/>
<line number="17" hits="1"/>
<line number="20" hits="1"/>
<line number="23" hits="1"/>
<line number="37" hits="1"/>
<line number="38" hits="1"/>
<line number="39" hits="1"/>
<line number="40" hits="1"/>
<line number="41" hits="1"/>
<line number="42" hits="1"/>
<line number="43" hits="1"/>
<line number="44" hits="1"/>
<line number="46" hits="1"/>
<line number="55" hits="0"/>
<line number="56" hits="0"/>
<line number="57" hits="0"/>
<line number="61" hits="0"/>
<line number="62" hits="0"/>
<line number="67" hits="0"/>
<line number="71" hits="0"/>
<line number="72" hits="0"/>
<line number="74" hits="1"/>
<line number="90" hits="0"/>
<line number="92" hits="0"/>
<line number="93" hits="0"/>
<line number="94" hits="0"/>
<line number="98" hits="0"/>
<line number="99" hits="0"/>
<line number="101" hits="0"/>
<line number="105" hits="0"/>
<line number="107" hits="0"/>
<line number="109" hits="1"/>
<line number="125" hits="0"/>
<line number="126" hits="0"/>
<line number="127" hits="0"/>
<line number="128" hits="0"/>
<line number="129" hits="0"/>
<line number="131" hits="0"/>
<line number="135" hits="0"/>
<line number="136" hits="0"/>
<line number="138" hits="1"/>
<line number="152" hits="0"/>
<line number="157" hits="1"/>
<line number="172" hits="0"/>
<line number="178" hits="1"/>
<line number="192" hits="0"/>
<line number="197" hits="1"/>
<line number="211" hits="0"/>
<line number="216" hits="1"/>
<line number="231" hits="0"/>
<line number="232" hits="0"/>
<line number="234" hits="0"/>
<line number="235" hits="0"/>
<line number="238" hits="0"/>
<line number="239" hits="0"/>
<line number="241" hits="1"/>
<line number="255" hits="0"/>
<line number="256" hits="0"/>
<line number="257" hits="0"/>
<line number="258" hits="0"/>
<line number="259" hits="0"/>
<line number="261" hits="1"/>
<line number="275" hits="0"/>
<line number="276" hits="0"/>
<line number="277" hits="0"/>
<line number="278" hits="0"/>
<line number="279" hits="0"/>
<line number="281" hits="1"/>
<line number="290" hits="0"/>
<line number="292" hits="0"/>
<line number="296" hits="1"/>
<line number="307" hits="0"/>
<line number="308" hits="0"/>
<line number="310" hits="1"/>
<line number="323" hits="0"/>
<line number="324" hits="0"/>
<line number="326" hits="0"/>
<line number="327" hits="0"/>
<line number="328" hits="0"/>
<line number="329" hits="0"/>
<line number="330" hits="0"/>
<line number="331" hits="0"/>
<line number="333" hits="1"/>
<line number="346" hits="0"/>
<line number="347" hits="0"/>
<line number="348" hits="0"/>
<line number="349" hits="0"/>
</lines>
</class>
<class name="slurm_script_generator.py" filename="backend/services/scheduler/slurm/slurm_script_generator.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines>
<line number="5" hits="1"/>
<line number="12" hits="1"/>
<line number="13" hits="1"/>
<line number="14" hits="1"/>
<line number="17" hits="1"/>
<line number="51" hits="1"/>
<line number="58" hits="1"/>
<line number="61" hits="1"/>
<line number="62" hits="1"/>
<line number="63" hits="1"/>
<line number="64" hits="1"/>
<line number="65" hits="1"/>
<line number="66" hits="1"/>
<line number="69" hits="1"/>
<line number="70" hits="1"/>
<line number="71" hits="1"/>
<line number="72" hits="1"/>
<line number="73" hits="1"/>
<line number="76" hits="1"/>
<line number="78" hits="1"/>
<line number="87" hits="1"/>
<line number="88" hits="1"/>
<line number="110" hits="1"/>
<line number="111" hits="1"/>
</lines>
</class>
</classes>
</package>
<package name="backend.tests" line-rate="1" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/tests/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
</classes>
</package>
<package name="backend.tests.services" line-rate="1" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/tests/services/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
</classes>
</package>
<package name="backend.tests.services.scheduler" line-rate="0.9351" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/tests/services/scheduler/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
<class name="test_scheduler.py" filename="backend/tests/services/scheduler/test_scheduler.py" complexity="0" line-rate="0.9351" branch-rate="0">
<methods/>
<lines>
<line number="1" hits="1"/>
<line number="2" hits="1"/>
<line number="4" hits="1"/>
<line number="5" hits="1"/>
<line number="6" hits="1"/>
<line number="7" hits="1"/>
<line number="8" hits="1"/>
<line number="11" hits="1"/>
<line number="13" hits="1"/>
<line number="14" hits="1"/>
<line number="15" hits="1"/>
<line number="16" hits="1"/>
<line number="17" hits="1"/>
<line number="18" hits="1"/>
<line number="19" hits="1"/>
<line number="21" hits="1"/>
<line number="22" hits="1"/>
<line number="25" hits="1"/>
<line number="28" hits="1"/>
<line number="35" hits="1"/>
<line number="37" hits="1"/>
<line number="38" hits="1"/>
<line number="39" hits="1"/>
<line number="41" hits="1"/>
<line number="42" hits="1"/>
<line number="45" hits="1"/>
<line number="48" hits="1"/>
<line number="49" hits="1"/>
<line number="52" hits="1"/>
<line number="54" hits="1"/>
<line number="55" hits="1"/>
<line number="56" hits="1"/>
<line number="58" hits="1"/>
<line number="59" hits="1"/>
<line number="62" hits="1"/>
<line number="65" hits="1"/>
<line number="66" hits="1"/>
<line number="69" hits="1"/>
<line number="71" hits="1"/>
<line number="72" hits="1"/>
<line number="73" hits="1"/>
<line number="74" hits="1"/>
<line number="75" hits="1"/>
<line number="76" hits="1"/>
<line number="77" hits="1"/>
<line number="79" hits="1"/>
<line number="80" hits="1"/>
<line number="81" hits="1"/>
<line number="84" hits="1"/>
<line number="87" hits="1"/>
<line number="88" hits="1"/>
<line number="92" hits="1"/>
<line number="93" hits="1"/>
<line number="96" hits="1"/>
<line number="101" hits="1"/>
<line number="103" hits="1"/>
<line number="104" hits="1"/>
<line number="105" hits="1"/>
<line number="106" hits="1"/>
<line number="107" hits="1"/>
<line number="108" hits="1"/>
<line number="109" hits="1"/>
<line number="111" hits="1"/>
<line number="112" hits="1"/>
<line number="113" hits="1"/>
<line number="116" hits="1"/>
<line number="119" hits="1"/>
<line number="120" hits="1"/>
<line number="122" hits="1"/>
<line number="123" hits="1"/>
<line number="126" hits="1"/>
<line number="131" hits="1"/>
<line number="132" hits="0"/>
<line number="133" hits="0"/>
<line number="134" hits="0"/>
<line number="135" hits="0"/>
<line number="136" hits="0"/>
</lines>
</class>
</classes>
</package>
<package name="backend.tests.services.scheduler.slurm" line-rate="0.4599" branch-rate="0" complexity="0">
<classes>
<class name="__init__.py" filename="backend/tests/services/scheduler/slurm/__init__.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines/>
</class>
<class name="test_slurm_control.py" filename="backend/tests/services/scheduler/slurm/test_slurm_control.py" complexity="0" line-rate="0.3039" branch-rate="0">
<methods/>
<lines>
<line number="6" hits="1"/>
<line number="13" hits="1"/>
<line number="14" hits="1"/>
<line number="15" hits="1"/>
<line number="17" hits="1"/>
<line number="18" hits="1"/>
<line number="20" hits="1"/>
<line number="23" hits="1"/>
<line number="24" hits="1"/>
<line number="51" hits="1"/>
<line number="52" hits="1"/>
<line number="53" hits="1"/>
<line number="55" hits="0"/>
<line number="56" hits="0"/>
<line number="59" hits="0"/>
<line number="62" hits="0"/>
<line number="63" hits="0"/>
<line number="66" hits="0"/>
<line number="67" hits="0"/>
<line number="69" hits="0"/>
<line number="74" hits="1"/>
<line number="75" hits="1"/>
<line number="76" hits="1"/>
<line number="78" hits="0"/>
<line number="81" hits="0"/>
<line number="82" hits="0"/>
<line number="85" hits="0"/>
<line number="86" hits="0"/>
<line number="87" hits="0"/>
<line number="88" hits="0"/>
<line number="91" hits="1"/>
<line number="92" hits="1"/>
<line number="93" hits="1"/>
<line number="95" hits="0"/>
<line number="98" hits="0"/>
<line number="99" hits="0"/>
<line number="102" hits="0"/>
<line number="103" hits="0"/>
<line number="104" hits="0"/>
<line number="105" hits="0"/>
<line number="108" hits="1"/>
<line number="109" hits="1"/>
<line number="110" hits="1"/>
<line number="112" hits="0"/>
<line number="115" hits="0"/>
<line number="118" hits="0"/>
<line number="119" hits="0"/>
<line number="122" hits="0"/>
<line number="127" hits="1"/>
<line number="128" hits="1"/>
<line number="129" hits="1"/>
<line number="131" hits="0"/>
<line number="134" hits="0"/>
<line number="137" hits="0"/>
<line number="138" hits="0"/>
<line number="139" hits="0"/>
<line number="140" hits="0"/>
<line number="143" hits="0"/>
<line number="148" hits="1"/>
<line number="149" hits="1"/>
<line number="150" hits="1"/>
<line number="152" hits="0"/>
<line number="153" hits="0"/>
<line number="154" hits="0"/>
<line number="155" hits="0"/>
<line number="156" hits="0"/>
<line number="159" hits="0"/>
<line number="162" hits="0"/>
<line number="163" hits="0"/>
<line number="164" hits="0"/>
<line number="165" hits="0"/>
<line number="166" hits="0"/>
<line number="167" hits="0"/>
<line number="168" hits="0"/>
<line number="169" hits="0"/>
<line number="172" hits="0"/>
<line number="173" hits="0"/>
<line number="178" hits="1"/>
<line number="179" hits="1"/>
<line number="180" hits="1"/>
<line number="182" hits="0"/>
<line number="183" hits="0"/>
<line number="186" hits="0"/>
<line number="187" hits="0"/>
<line number="190" hits="0"/>
<line number="191" hits="0"/>
<line number="194" hits="0"/>
<line number="198" hits="0"/>
<line number="199" hits="0"/>
<line number="200" hits="0"/>
<line number="205" hits="1"/>
<line number="206" hits="0"/>
<line number="207" hits="0"/>
<line number="208" hits="0"/>
<line number="209" hits="0"/>
<line number="210" hits="0"/>
<line number="211" hits="0"/>
<line number="212" hits="0"/>
<line number="213" hits="0"/>
<line number="214" hits="0"/>
<line number="215" hits="0"/>
<line number="216" hits="0"/>
</lines>
</class>
<class name="test_slurm_script_generator.py" filename="backend/tests/services/scheduler/slurm/test_slurm_script_generator.py" complexity="0" line-rate="0.9143" branch-rate="0">
<methods/>
<lines>
<line number="6" hits="1"/>
<line number="12" hits="1"/>
<line number="13" hits="1"/>
<line number="15" hits="1"/>
<line number="16" hits="1"/>
<line number="17" hits="1"/>
<line number="18" hits="1"/>
<line number="19" hits="1"/>
<line number="22" hits="1"/>
<line number="24" hits="1"/>
<line number="25" hits="1"/>
<line number="27" hits="1"/>
<line number="50" hits="1"/>
<line number="51" hits="1"/>
<line number="52" hits="1"/>
<line number="53" hits="1"/>
<line number="56" hits="1"/>
<line number="58" hits="1"/>
<line number="59" hits="1"/>
<line number="60" hits="1"/>
<line number="61" hits="1"/>
<line number="63" hits="1"/>
<line number="64" hits="1"/>
<line number="66" hits="1"/>
<line number="67" hits="1"/>
<line number="68" hits="1"/>
<line number="69" hits="1"/>
<line number="72" hits="1"/>
<line number="75" hits="1"/>
<line number="78" hits="1"/>
<line number="79" hits="1"/>
<line number="82" hits="1"/>
<line number="83" hits="0"/>
<line number="84" hits="0"/>
<line number="85" hits="0"/>
</lines>
</class>
</classes>
</package>
<package name="backend.tools" line-rate="1" branch-rate="0" complexity="0">
<classes>
<class name="config.py" filename="backend/tools/config.py" complexity="0" line-rate="1" branch-rate="0">
<methods/>
<lines>
<line number="1" hits="1"/>
<line number="3" hits="1"/>
</lines>
</class>
</classes>
</package>
</packages>
</coverage>
I have also added the reports path to the sonar-project.properties file.
sonar-project.properties
sonar.projectKey=censored
sonar.qualitygate.wait=true
sonar.verbose=true
sonar.python.coverage.reportPaths=reports/coverage.xml
sonar.python.ruff.reportPaths=reports/ruff-report.json
sonar.eslint.reportPaths=reports/eslint-report.json
sonar.typescript.lcov.reportPaths=reports/lcov.info
sonar.coverage.exclusions=**\*spec.ts
#sonar.tests=frontend/src
#sonar.test.inclusions=frontend/**/*.spec.ts
To double-check that this was the correct path and that the Python coverage analysis was taking place, I also checked the logs.
sonar runner logs extract
12:54:49.564 INFO: The Python analyzer was able to leverage cached data from previous analyses for 0 out of 53 files. These files were not parsed.
12:54:49.564 INFO: Sensor Python Sensor [python] (done) | time=2263ms
12:54:49.564 INFO: Sensor Cobertura Sensor for Python coverage [python]
12:54:49.564 DEBUG: Using pattern 'reports/coverage.xml' to find reports
12:54:49.581 INFO: Python test coverage
12:54:49.582 INFO: Parsing report '/builds/ky9phFW7/0/censored/censored/reports/coverage.xml'
12:54:49.616 INFO: Sensor Cobertura Sensor for Python coverage [python] (done) | time=52ms
As you can see, the coverage report is found and the analysis is executed successfully without any error message. However, there is still not a single line covered in sonarqube.
As you can see, I also did a similar configuration for the angular part of the project. Everything works fine there.
Do you know why the coverage for the Python part of the project is still at 0% or do you have any idea what could be wrong here? I would be grateful for any advice
Thanks!