Hi SonarQube-Team,
I'm a bit lost with an issue that started occurring recently in our analyses. I'd appreciate any hints!
Our system:
- SonarQube Server 5.3
- c# plugin 4.4
- Git source code repository
- SonarQube Scanner for MSBuild 1.1
- Code coverage using OpenCover
After upgrading to SonarQube 5.3 and using the MSBuild Scanner, we are facing c# code analysis failures like this one:
ERROR: Error during Sonar runner execution
org.sonar.runner.impl.RunnerException: Unable to execute Sonar
at org.sonar.runner.impl.BatchLauncher$1.delegateExecution(BatchLauncher.java:91)
at org.sonar.runner.impl.BatchLauncher$1.run(BatchLauncher.java:75)
at java.security.AccessController.doPrivileged(Native Method)
at org.sonar.runner.impl.BatchLauncher.doExecute(BatchLauncher.java:69)
at org.sonar.runner.impl.BatchLauncher.execute(BatchLauncher.java:50)
at org.sonar.runner.api.EmbeddedRunner.doExecute(EmbeddedRunner.java:102)
at org.sonar.runner.api.Runner.execute(Runner.java:100)
at org.sonar.runner.Main.executeTask(Main.java:70)
at org.sonar.runner.Main.execute(Main.java:59)
at org.sonar.runner.Main.main(Main.java:53)
Caused by: java.lang.IllegalStateException: Can't create measure for line 38 for file 'XY' with 37 lines
at org.sonar.batch.sensor.coverage.CoverageExclusions.validateMaxLine(CoverageExclusions.java:158)
at org.sonar.batch.sensor.coverage.CoverageExclusions.validate(CoverageExclusions.java:129)
at org.sonar.batch.deprecated.DeprecatedSensorContext.saveMeasure(DeprecatedSensorContext.java:204)
at org.sonar.plugins.dotnet.tests.CoverageReportImportSensor.analyze(CoverageReportImportSensor.java:78)
This is an excerpt of the part inside our code coverage report that seems to be causing the failure. Notice the attributes "fileid" changing inside that listing of sequence points.
<Method someattributes>
<Summary SOMESUMMARY/>
<MetadataToken>100664043</MetadataToken>
<Name>System.Void SOMEMETHOD::.ctor()</Name>
<FileRef uid="11618" />
<SequencePoints>
<SequencePoint vc="1" uspid="902191" ordinal="0" offset="0" sl="8" sc="9" el="8" ec="68" bec="0" bev="0" fileid="11618" />
<SequencePoint vc="1" uspid="902192" ordinal="1" offset="7" sl="32" sc="15" el="32" ec="76" bec="0" bev="0" fileid="11619" />
<SequencePoint vc="1" uspid="902193" ordinal="2" offset="17" sl="33" sc="9" el="33" ec="10" bec="0" bev="0" fileid="11619" />
<SequencePoint vc="1" uspid="902194" ordinal="3" offset="18" sl="34" sc="13" el="34" ec="35" bec="0" bev="0" fileid="11619" />
<SequencePoint vc="1" uspid="902195" ordinal="4" offset="25" sl="35" sc="13" el="35" ec="106" bec="0" bev="0" fileid="11619" />
<SequencePoint vc="1" uspid="902196" ordinal="5" offset="48" sl="37" sc="13" el="37" ec="128" bec="0" bev="0" fileid="11619" />
<SequencePoint vc="1" uspid="902197" ordinal="6" offset="76" sl="38" sc="13" el="38" ec="149" bec="0" bev="0" fileid="11619" />
<SequencePoint vc="1" uspid="902198" ordinal="7" offset="104" sl="39" sc="9" el="39" ec="10" bec="0" bev="0" fileid="11619" />
</SequencePoints>
<BranchPoints />
<MethodPoint xsi:type="SequencePoint" vc="1" uspid="902191" ordinal="0" offset="0" sl="8" sc="9" el="8" ec="68" bec="0" bev="0" fileid="11618" />
</Method>
The method being analysed here is the constructor of a partial class in file with fileid="11619" inheriting from a partial class in another file with fileid="11618"
So, the sequence actually calls into another file. OpenCover seems to resolve this properly (as you can see by the changing fileids in the sequence listing)
The failure described above now occurs only for those situations where the file being called has fewer lines than the file the sequence started in.
In the case shown above, the starting file (11619) has some 200 lines whereas the file being called (11618) has 37 lines only. Parsing of the coverage report works fine until the line with sl="38" is reached.
If I manually remove these calls or if I manually change the "FileRef" parameter to the larger file, the analysis works just fine.
In defense of OpenCover: If I parse that report with ReportGenerator, for example, the report is parsed fine and coverage information on those parts of the code seems reasonable as well.
So my hypothesis is that there is something wrong with the way the "
org.sonar.batch.sensor.coverage.CoverageExclusions.validateMaxLine" is calculated.
Maybe it does not take into account the fact that there are multiple files with a different number of lines involved?
Well, I hope this is helpful to you. I would really appreciate any inputs you could give me.
Thanks!