首页 > 解决方案 > 生成报告时JaCoCo中的竞争条件合并?

问题描述

所以这就是同事称为“薛定谔错误”的东西——它工作得很好,直到有人指出。有些东西发生了变化,现在错误就在那里。并且改回来没有帮助 - 错误仍然存​​在:-/

在我们的 Maven 项目中,我们使用 JaCoCo 进行代码覆盖(maven-jacoco-plugin 版本 0.8.7)。Surefire 插件(2.22.2 版)正在进行单元测试,failsave(3.0.0-M5 版)正在进行集成测试。

这是我们的 POM:

<plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${maven-jacoco-plugin.version}</version>
                <executions>
                    <execution>
                        <id>before-unit-test-execution</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${project.build.directory}/jacoco-output/jacoco-unit-tests.exec</destFile>
                            <propertyName>surefire.jacoco.args</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>after-unit-test-execution</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/jacoco-output/jacoco-unit-tests.exec</dataFile>
                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-unit-test-coverage-report
                            </outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>before-integration-test-execution</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${project.build.directory}/jacoco-output/jacoco-integration-tests.exec</destFile>
                            <propertyName>failsafe.jacoco.args</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>after-integration-test-execution</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/jacoco-output/jacoco-integration-tests.exec</dataFile>
                            <outputDirectory>
                                ${project.reporting.outputDirectory}/jacoco-integration-test-coverage-report
                            </outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>merge-unit-and-integration</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>merge</goal>
                        </goals>
                        <configuration>
                            <fileSets>
                                <fileSet>
                                    <directory>${project.build.directory}/jacoco-output/</directory>
                                    <includes>
                                        <include>jacoco-integration-tests.exec</include>
                                        <include>jacoco-unit-tests.exec</include>
<!--                                        <include>*.exec</include>-->
                                    </includes>
                                </fileSet>
                            </fileSets>
                            <destFile>${project.build.directory}/jacoco-output/merged.exec</destFile>
                        </configuration>
                    </execution>
                    <execution>
                        <id>create-merged-report</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/jacoco-output/merged.exec</dataFile>
                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-merged-test-coverage-report
                            </outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>check</id>
                        <goals>
                            <!-- check is bound to the verify phase by default -->
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/jacoco-output/merged.exec</dataFile>
                            <rules>
                                <rule>
                                    <element>CLASS</element>
                                    <excludes>
                                        <exclude>*Test</exclude>
                                        <exclude>configuration/*</exclude>
                                    </excludes>
                                    <limits>
                                        <limit>
                                            <counter>LINE</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>${jacoco.min.line.coverage}</minimum>
                                        </limit>
                                        <limit>
                                            <counter>BRANCH</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>${jacoco.min.branch.coverage}</minimum>
                                        </limit>
                                    </limits>
                                </rule>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

在两者之间,您会看到注释部分 - 那是改变的部分。

现在这有时会抛出 EOFException(仅在本地运行时 - 而不是在 Gitlab CI/CD 管道上执行时)。有问题的文件是“jacoco-integration-tests.exec”。查找该文件显示,它尚未完成写入。它比文件夹中的其他文件(“jacoco-unit-tests.exec”)小得多。

由于这个错误不是可靠地产生的(在我删除目标文件夹后它工作正常)我们怀疑一些竞争条件正在发生。好像 JaCoCo 仍在编写该集成测试文件,然后下一步已经想要访问它并且崩溃了。但我真的不知道,这方面的信息很难获得。少,如何解决。

有谁知道这个错误来自哪里以及如何修复它?非常感谢。

标签: race-conditionjacocojacoco-maven-plugineofexception

解决方案


Caused by: java.io.EOFException
at java.io.DataInputStream.readByte (DataInputStream.java:272)
at org.jacoco.core.internal.data.CompactDataInput.readBooleanArray (CompactDataInput.java:64)
at org.jacoco.core.data.ExecutionDataReader.readExecutionData (ExecutionDataReader.java:150)
at org.jacoco.core.data.ExecutionDataReader.readBlock (ExecutionDataReader.java:116)
at org.jacoco.core.data.ExecutionDataReader.read (ExecutionDataReader.java:93)
at org.jacoco.core.tools.ExecFileLoader.load (ExecFileLoader.java:60)
at org.jacoco.core.tools.ExecFileLoader.load (ExecFileLoader.java:74)
at org.jacoco.maven.ReportSupport.loadExecutionData (ReportSupport.java:83)
at org.jacoco.maven.ReportMojo.loadExecutionData (ReportMojo.java:61)
at org.jacoco.maven.AbstractReportMojo.executeReport (AbstractReportMojo.java:191)
at org.jacoco.maven.AbstractReportMojo.execute (AbstractReportMojo.java:180)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)

我希望这足以继续下去。雅可可 0.8.7、Windows 10、JDK 11.0.11。它生成 jacoco.exec 文件,但在创建 html 报告时失败。


推荐阅读