jenkinsci / code-coverage-api-plugin

Deprecated Jenkins Code Coverage Plugin
https://plugins.jenkins.io/code-coverage-api/
MIT License
111 stars 77 forks source link

Cobertura report problem with package name clash #396

Closed daiduongvo18 closed 1 year ago

daiduongvo18 commented 2 years ago

Jenkins and plugins versions report

Environment ```text Jenkins: 2.332.3 OS: Linux - 5.4.0-110-generic --- Office-365-Connector:4.17.0 ace-editor:1.1 ant:475.vf34069fef73c antisamy-markup-formatter:2.7 apache-httpcomponents-client-4-api:4.5.13-1.0 authentication-tokens:1.4 blueocean:1.25.5 blueocean-autofavorite:1.2.5 blueocean-bitbucket-pipeline:1.25.5 blueocean-commons:1.25.5 blueocean-config:1.25.5 blueocean-core-js:1.25.5 blueocean-dashboard:1.25.5 blueocean-display-url:2.4.1 blueocean-events:1.25.5 blueocean-git-pipeline:1.25.5 blueocean-github-pipeline:1.25.5 blueocean-i18n:1.25.5 blueocean-jwt:1.25.5 blueocean-personalization:1.25.5 blueocean-pipeline-api-impl:1.25.5 blueocean-pipeline-editor:1.25.5 blueocean-pipeline-scm-api:1.25.5 blueocean-rest:1.25.5 blueocean-rest-impl:1.25.5 blueocean-web:1.25.5 bootstrap4-api:4.6.0-5 bootstrap5-api:5.1.3-6 bouncycastle-api:2.26 branch-api:2.1046.v0ca_37783ecc5 build-timeout:1.20 caffeine-api:2.9.3-65.v6a_47d0f4d1fe checks-api:1.7.4 cloudbees-bitbucket-branch-source:765.v5a_2d6a_23c01d cloudbees-folder:6.722.v8165b_a_cf25e9 code-coverage-api:2.0.4 command-launcher:81.v9c2cb_cb_db_392 credentials:1087.1089.v2f1b_9a_b_040e4 credentials-binding:523.vd859a_4b_122e6 data-tables-api:1.11.4-4 display-url-api:2.3.6 docker-commons:1.19 docker-workflow:1.28 durable-task:496.va67c6f9eefa7 echarts-api:5.3.2-1 email-ext:2.88 favorite:2.4.1 font-awesome-api:6.0.0-1 forensics-api:1.13.0 git:4.11.3 git-client:3.11.0 git-server:1.11 github:1.34.3 github-api:1.303-400.v35c2d8258028 github-branch-source:1628.vb_2f51293cb_78 gradle:1.38 handlebars:3.0.8 handy-uri-templates-2-api:2.1.8-22.v77d5b_75e6953 htmlpublisher:1.30 jackson2-api:2.13.3-285.vc03c0256d517 javax-activation-api:1.2.0-3 javax-mail-api:1.6.2-6 jaxb:2.3.6-1 jdk-tool:1.5 jenkins-design-language:1.25.5 jjwt-api:0.11.2-71.v2722b_b_06a_2a_f jquery3-api:3.6.0-3 jsch:0.1.55.2 junit:1.63 ldap:2.9 lockable-resources:2.15 mailer:414.vcc4c33714601 matrix-auth:3.1.2 matrix-project:771.v574584b_39e60 momentjs:1.1.1 okhttp-api:4.9.3-105.vb96869f8ac3a pam-auth:1.8 pipeline-build-step:2.18 pipeline-github-lib:36.v4c01db_ca_ed16 pipeline-graph-analysis:195.v5812d95a_a_2f9 pipeline-input-step:448.v37cea_9a_10a_70 pipeline-milestone-step:101.vd572fef9d926 pipeline-model-api:2.2081.v3919681ffc1e pipeline-model-definition:2.2081.v3919681ffc1e pipeline-model-extensions:2.2081.v3919681ffc1e pipeline-rest-api:2.24 pipeline-stage-step:293.v200037eefcd5 pipeline-stage-tags-metadata:2.2081.v3919681ffc1e pipeline-stage-view:2.24 plain-credentials:1.8 plugin-util-api:2.16.0 popper-api:1.16.1-3 popper2-api:2.11.5-1 pubsub-light:1.16 resource-disposer:0.19 scm-api:608.vfa_f971c5a_a_e9 scm-filter-branch-pr:0.5.1 script-security:1172.v35f6a_0b_8207e snakeyaml-api:1.30.1 sonar:2.14 sse-gateway:1.25 ssh-agent:295.v9ca_a_1c7cc3a_a_ ssh-credentials:277.v95c2fec1c047 ssh-slaves:1.814.vc82988f54b_10 sshd:3.228.v4c9f9e652c86 structs:318.va_f3ccb_729b_71 timestamper:1.17 token-macro:293.v283932a_0a_b_49 trilead-api:1.57.v6e90e07157e1 variant:1.4 workflow-aggregator:578.vf9a_f99755f4a_ workflow-api:1153.vb_912c0e47fb_a_ workflow-basic-steps:948.v2c72a_091b_b_68 workflow-cps:2692.v76b_089ccd026 workflow-cps-global-lib:581.ve633085a_8a_87 workflow-durable-task-step:1139.v252a_e12e8463 workflow-job:1181.va_25d15548158 workflow-multibranch:712.vc169a_1387405 workflow-scm-step:400.v6b_89a_1317c9a_ workflow-step-api:625.vd896b_f445a_f8 workflow-support:820.vd1a_6cc65ef33 ws-cleanup:0.42 ```

What Operating System are you using (both controller, and any agents involved in the problem)?

Docker image jenkinsci/blueocean:latest

Reproduction steps

  1. Step 1: generate Cobertura coverage report with PHPUnit version 9.5.20
  2. Step 2: publish the coverage report above
    Sample
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage line-rate="0.76829268292683" branch-rate="0" lines-covered="63" lines-valid="82" branches-covered="0" branches-valid="0" complexity="22" version="0.4" timestamp="1653406063">
  <sources>
    <source>/app/app/code/Invocare/InventoryBranch</source>
  </sources>
  <packages>
    <package name="" line-rate="0" branch-rate="0" complexity="0">
      <classes/>
    </package>
    <package name="" line-rate="1" branch-rate="0" complexity="1">
      <classes>
        <class name="Invocare\InventoryBranch\Model\Resolver\DataProvider\Branch" filename="Model/Resolver/DataProvider/Branch.php" line-rate="1" branch-rate="0" complexity="1">
          <methods>
            <method name="getData" signature="Magento\InventoryApi\Api\Data\SourceInterface $source" line-rate="1" branch-rate="0" complexity="1">
              <lines>
                <line number="34" hits="1"/>
                <line number="35" hits="1"/>
                <line number="36" 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="45" hits="1"/>
                <line number="46" hits="1"/>
                <line number="47" hits="1"/>
                <line number="49" hits="1"/>
                <line number="50" hits="1"/>
                <line number="51" hits="1"/>
                <line number="52" hits="1"/>
                <line number="53" hits="1"/>
                <line number="55" hits="1"/>
              </lines>
            </method>
          </methods>
          <lines>
            <line number="34" hits="1"/>
            <line number="35" hits="1"/>
            <line number="36" 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="45" hits="1"/>
            <line number="46" hits="1"/>
            <line number="47" hits="1"/>
            <line number="49" hits="1"/>
            <line number="50" hits="1"/>
            <line number="51" hits="1"/>
            <line number="52" hits="1"/>
            <line number="53" hits="1"/>
            <line number="55" hits="1"/>
          </lines>
        </class>
      </classes>
    </package>
    <package name="" line-rate="0.68" branch-rate="0" complexity="10">
      <classes>
        <class name="Invocare\InventoryBranch\Model\Resolver\IvcBranches" filename="Model/Resolver/IvcBranches.php" line-rate="0.68" branch-rate="0" complexity="10">
          <methods>
            <method name="__construct" signature="Invocare\InventoryBranch\Model\Resolver\DataProvider\Branch $branchDataProvider, Magento\InventoryApi\Api\SourceRepositoryInterface $sourceRepository, Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder" line-rate="1" branch-rate="0" complexity="1">
              <lines>
                <line number="51" hits="2"/>
                <line number="52" hits="2"/>
                <line number="53" hits="2"/>
              </lines>
            </method>
            <method name="resolve" signature="Magento\Framework\GraphQl\Config\Element\Field $field, $context, Magento\Framework\GraphQl\Schema\Type\ResolveInfo $info, array $value, array $args" line-rate="1" branch-rate="0" complexity="7">
              <lines>
                <line number="61" hits="3"/>
                <line number="62" hits="1"/>
                <line number="64" hits="2"/>
                <line number="65" hits="1"/>
                <line number="68" hits="1"/>
                <line number="70" hits="1"/>
                <line number="71" hits="1"/>
                <line number="72" hits="1"/>
                <line number="75" hits="1"/>
                <line number="76" hits="1"/>
                <line number="79" hits="1"/>
                <line number="81" hits="1"/>
                <line number="82" hits="1"/>
                <line number="83" hits="1"/>
              </lines>
            </method>
            <method name="getList" signature="array $filters, int $pageSize, int $currentPage" line-rate="0" branch-rate="0" complexity="2">
              <lines>
                <line number="100" hits="0"/>
                <line number="101" hits="0"/>
                <line number="102" hits="0"/>
                <line number="104" hits="0"/>
                <line number="107" hits="0"/>
                <line number="108" hits="0"/>
                <line number="109" hits="0"/>
                <line number="110" hits="0"/>
              </lines>
            </method>
          </methods>
          <lines>
            <line number="51" hits="2"/>
            <line number="52" hits="2"/>
            <line number="53" hits="2"/>
            <line number="61" hits="3"/>
            <line number="62" hits="1"/>
            <line number="64" hits="2"/>
            <line number="65" hits="1"/>
            <line number="68" hits="1"/>
            <line number="70" hits="1"/>
            <line number="71" hits="1"/>
            <line number="72" hits="1"/>
            <line number="75" hits="1"/>
            <line number="76" hits="1"/>
            <line number="79" hits="1"/>
            <line number="81" hits="1"/>
            <line number="82" hits="1"/>
            <line number="83" hits="1"/>
            <line number="100" hits="0"/>
            <line number="101" hits="0"/>
            <line number="102" hits="0"/>
            <line number="104" hits="0"/>
            <line number="107" hits="0"/>
            <line number="108" hits="0"/>
            <line number="109" hits="0"/>
            <line number="110" hits="0"/>
          </lines>
        </class>
      </classes>
    </package>
    <package name="" line-rate="1" branch-rate="0" complexity="3">
      <classes>
        <class name="Invocare\InventoryBranch\Plugin\InventoryAdminUi\SourceDataProvider\PopulateBranchExtensionAttributesPlugin" filename="Plugin/InventoryAdminUi/SourceDataProvider/PopulateBranchExtensionAttributesPlugin.php" line-rate="1" branch-rate="0" complexity="3">
          <methods>
            <method name="afterGetData" signature="Magento\InventoryAdminUi\Ui\DataProvider\SourceDataProvider $subject, array $result" line-rate="1" branch-rate="0" complexity="3">
              <lines>
                <line number="28" hits="2"/>
                <line number="29" hits="2"/>
                <line number="38" hits="2"/>
                <line number="39" hits="2"/>
                <line number="40" hits="1"/>
                <line number="41" hits="1"/>
                <line number="45" hits="2"/>
              </lines>
            </method>
          </methods>
          <lines>
            <line number="28" hits="2"/>
            <line number="29" hits="2"/>
            <line number="38" hits="2"/>
            <line number="39" hits="2"/>
            <line number="40" hits="1"/>
            <line number="41" hits="1"/>
            <line number="45" hits="2"/>
          </lines>
        </class>
      </classes>
    </package>
    <package name="" line-rate="0.63333333333333" branch-rate="0" complexity="8">
      <classes>
        <class name="Invocare\InventoryBranch\Plugin\InventoryApi\SourceRepository\SetBranchExtensionAttributesPlugin" filename="Plugin/InventoryApi/SourceRepository/SetBranchExtensionAttributesPlugin.php" line-rate="0.63333333333333" branch-rate="0" complexity="8">
          <methods>
            <method name="__construct" signature="Magento\InventoryApi\Api\Data\SourceExtensionInterfaceFactory $sourceExtensionFactory" line-rate="0" branch-rate="0" complexity="1">
              <lines>
                <line number="30" hits="0"/>
              </lines>
            </method>
            <method name="afterGet" signature="Magento\InventoryApi\Api\SourceRepositoryInterface $subject, Magento\InventoryApi\Api\Data\SourceInterface $source" line-rate="1" branch-rate="0" complexity="1">
              <lines>
                <line number="45" hits="1"/>
                <line number="46" hits="1"/>
              </lines>
            </method>
            <method name="beforeSave" signature="Magento\InventoryApi\Api\SourceRepositoryInterface $subject, Magento\InventoryApi\Api\Data\SourceInterface $source" line-rate="1" branch-rate="0" complexity="2">
              <lines>
                <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="67" hits="1"/>
                <line number="68" hits="1"/>
                <line number="69" hits="1"/>
                <line number="72" hits="1"/>
              </lines>
            </method>
            <method name="afterGetList" signature="Magento\InventoryApi\Api\SourceRepositoryInterface $subject, Magento\InventoryApi\Api\Data\SourceSearchResultsInterface $result" line-rate="1" branch-rate="0" complexity="2">
              <lines>
                <line number="89" hits="1"/>
                <line number="90" hits="1"/>
                <line number="92" hits="1"/>
                <line number="93" hits="1"/>
                <line number="94" hits="1"/>
                <line number="96" hits="1"/>
                <line number="97" hits="1"/>
              </lines>
            </method>
            <method name="setExtensionAttributes" signature="Magento\InventoryApi\Api\Data\SourceInterface $source" line-rate="0" branch-rate="0" complexity="2">
              <lines>
                <line number="107" hits="0"/>
                <line number="108" hits="0"/>
                <line number="109" hits="0"/>
                <line number="110" hits="0"/>
                <line number="111" hits="0"/>
                <line number="112" hits="0"/>
                <line number="113" hits="0"/>
                <line number="114" hits="0"/>
                <line number="115" hits="0"/>
                <line number="116" hits="0"/>
              </lines>
            </method>
          </methods>
          <lines>
            <line number="30" hits="0"/>
            <line number="45" hits="1"/>
            <line number="46" 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="67" hits="1"/>
            <line number="68" hits="1"/>
            <line number="69" hits="1"/>
            <line number="72" hits="1"/>
            <line number="89" hits="1"/>
            <line number="90" hits="1"/>
            <line number="92" hits="1"/>
            <line number="93" hits="1"/>
            <line number="94" hits="1"/>
            <line number="96" hits="1"/>
            <line number="97" hits="1"/>
            <line number="107" hits="0"/>
            <line number="108" hits="0"/>
            <line number="109" hits="0"/>
            <line number="110" hits="0"/>
            <line number="111" hits="0"/>
            <line number="112" hits="0"/>
            <line number="113" hits="0"/>
            <line number="114" hits="0"/>
            <line number="115" hits="0"/>
            <line number="116" hits="0"/>
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>

Expected Results

Report data contain all packages

Actual Results

Report data contain only the last package.

Anything else?

If the packages' names are the same, only the last package is processed. Similar issue https://github.com/jenkinsci/code-coverage-api-plugin/issues/80. PHPUnit always generate Cobertura report with empty package name.

jhoffland commented 1 year ago

Did you (already) find a way to visualize a by PHPUnit generated coverage report in Jenkins?

uhafner commented 1 year ago

We are currently rewriting all parsers. The new implementation has no problem with the example report here (see https://github.com/uhafner/coverage-model/blob/main/src/test/resources/cobertura.xml) as far as I can tell. It will still take some time until this will be part of the Jenkins plugins though.

daiduongvo18 commented 1 year ago

Hi @jhoffland This is my workaround. I uses the line number as the package name.

awk \'{gsub("package name=\\"\\"","package name=\\""NR"\\"",$0);print}\' dev/tests/unit/report/cobertura-coverage.xml > dev/tests/unit/report/cobertura-coverage.xml.tmp
mv dev/tests/unit/report/cobertura-coverage.xml.tmp dev/tests/unit/report/cobertura-coverage.xml
uhafner commented 1 year ago

The new step recordCoverage is now in beta testing, can you please check if this release helps to solve this issue? Please note that the syntax of the step is totally new and cannot be combined with existing results.