Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-72895

recordCoverage failed with java.lang.IllegalArgumentException: Cannot merge coverage information

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • coverage-model
    • None
    • Jenkins 2.426.3; Coverage Plugin 1.13.0

      java.lang.IllegalArgumentException: Cannot merge coverage information for line 39 in [FILE] DataPlayerWidget.tsx <0>
      	at edu.hm.hafner.coverage.FileNode.mergeCounters(FileNode.java:164)
      	at edu.hm.hafner.coverage.FileNode.mergeNode(FileNode.java:136)
      	at edu.hm.hafner.coverage.Node.lambda$mergeNode$17(Node.java:745)
      	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
      	at edu.hm.hafner.coverage.Node.mergeNode(Node.java:741)
      	at edu.hm.hafner.coverage.Node.lambda$mergeNode$17(Node.java:745)
      	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
      	at edu.hm.hafner.coverage.Node.mergeNode(Node.java:741)
      	at edu.hm.hafner.coverage.Node.merge(Node.java:720)
      	at java.base/java.util.stream.ReduceOps$2ReducingSink.accept(ReduceOps.java:123)
      	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
      	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
      	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
      	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
      	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
      	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      	at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:558)
      	at edu.hm.hafner.coverage.Node.merge(Node.java:687)
      	at io.jenkins.plugins.coverage.metrics.steps.CoverageRecorder.aggregateResults(CoverageRecorder.java:523)
      	at io.jenkins.plugins.coverage.metrics.steps.CoverageRecorder.perform(CoverageRecorder.java:413)
      	at io.jenkins.plugins.coverage.metrics.steps.CoverageRecorder.perform(CoverageRecorder.java:402)
      	at io.jenkins.plugins.coverage.metrics.steps.CoverageStep$Execution.run(CoverageStep.java:365)
      	at io.jenkins.plugins.coverage.metrics.steps.CoverageStep$Execution.run(CoverageStep.java:333)
      	at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
      	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
      	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
      	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
      	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
      	at java.base/java.lang.Thread.run(Thread.java:829)
      

      This build is running both Jest and Cypress tests. Coverage results are originally created in Istanbul's JSON format, then converted to Cobertura using nyc. The number of branches for condition-coverage attributes can differ between the two, and Coverage Plugin is failing to merge them.

      Heavily truncated, output from nyc looks like

      Jest:

      <coverage lines-valid="34206" lines-covered="26794" line-rate="0.7833" branches-valid="13748" branches-covered="9773" branch-rate="0.7108" timestamp="1710203429645" complexity="0" version="0.1">
        <sources>
          <source>
            /var/lib/jenkins/workspace/feature_DMAS-79190-cypress-split
          </source>
        </sources>
        <packages>
          ...
          <package name="domain.AppComponents.Dashboard" line-rate="0.9664" branch-rate="0.8937">
            ...
            <class name="DataPlayerWidget.tsx" filename="src/domain/AppComponents/Dashboard/DataPlayerWidget.tsx" line-rate="0.25" branch-rate="0">
              <methods>
                <method name="(anonymous_0)" hits="0" signature="()V">
                  <lines>
                    <line number="25" hits="0"/>
                  </lines>
                </method>
              </methods>
              <lines>
                <line number="25" hits="5" branch="false"/>
                <line number="39" hits="0" branch="true" condition-coverage="0% (0/2)"/>
                <line number="40" hits="0" branch="false"/>
                <line number="53" hits="0" branch="false"/>
              </lines>
            </class>
            ...
          </package>
          ...
        </packages>
      </coverage>
      

      Cypress:

      <coverage lines-valid="16792" lines-covered="9482" line-rate="0.5646" branches-valid="6512" branches-covered="2888" branch-rate="0.4434" timestamp="1710205408329" complexity="0" version="0.1">
        <sources>
          <source>
            /var/lib/jenkins/workspace/feature_DMAS-79190-cypress-split
          </source>
        </sources>
        <packages>
          ...
          <package name="domain.AppComponents.Dashboard" line-rate="0.5257000000000001" branch-rate="0.4964">
            <classes>
              ...
              <class name="DataPlayerWidget.tsx" filename="src/domain/AppComponents/Dashboard/DataPlayerWidget.tsx" line-rate="0.25" branch-rate="0">
                <methods>
                  <method name="(anonymous_0)" hits="0" signature="()V">
                    <lines>
                      <line number="25" hits="0"/>
                    </lines>
                  </method>
                </methods>
                <lines>
                  <line number="25" hits="5" branch="false"/>
                  <line number="39" hits="0" branch="true" condition-coverage="0% (0/1)"/>
                  <line number="40" hits="0" branch="false"/>
                  <line number="53" hits="0" branch="false"/>
                </lines>
              </class>
              ...
            </classes>
            ...
          </package>
        </packages>
      </coverage>
      

      It goes without saying that nyc's output is incorrect, but that tool hasn't had a commit since 2020 and I don't have much expectation that they're going to fix the issue. It would be valuable for us if Coverage Plugin could perform a best guess merge of invalid results instead of failing.

      For now, we've switched back to the deprecated Cobertura Plugin, which is able to merge the two files.

          [JENKINS-72895] recordCoverage failed with java.lang.IllegalArgumentException: Cannot merge coverage information

          Patrick Conley created issue -
          Ulli Hafner made changes -
          Component/s New: coverage-model [ 29124 ]
          Component/s Original: coverage-plugin [ 29223 ]
          Patrick Conley made changes -
          Attachment New: cobertura-coverage.png [ 62333 ]
          Ulli Hafner made changes -
          Resolution New: Fixed [ 1 ]
          Status Original: Open [ 1 ] New: Resolved [ 5 ]
          Ulli Hafner made changes -
          Resolution Original: Fixed [ 1 ]
          Status Original: Resolved [ 5 ] New: Reopened [ 4 ]

            drulli Ulli Hafner
            pconley Patrick Conley
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: