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

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

XMLWordPrintable

    • 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.

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

              Created:
              Updated: