dev: improved code coverage (jacoco) and static analyser (sonar) support (#11367):

* fixed code coverage data lost on failed tests;
* fixed code coverage report duplication and improved performance;
* fixed that sonar analyser can't see code coverage for some modules;
* added new aggregation module: Mage.Reports (used for code coverage report generation);
* reorganized pom and added additional instructions for jacoco and sonar usage;
This commit is contained in:
Oleg Agafonov 2023-10-30 09:19:12 +04:00 committed by GitHub
parent a191668b09
commit 3abdb72910
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 250 additions and 84 deletions

View file

@ -224,6 +224,7 @@
</build>
<properties>
<root.dir>${project.basedir}/..</root.dir>
<manifest.file>src/main/resources/META-INF/MANIFEST.MF</manifest.file>
</properties>

View file

@ -96,4 +96,8 @@
<finalName>mage-common</finalName>
</build>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -38,4 +38,8 @@
<finalName>mage-counter-plugin</finalName>
</build>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -19,4 +19,8 @@
<module>Mage.Counter.Plugin</module>
</modules>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

81
Mage.Reports/pom.xml Normal file
View file

@ -0,0 +1,81 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.50</version>
</parent>
<artifactId>mage-reports</artifactId>
<packaging>pom</packaging>
<name>Mage Reports</name>
<build>
<plugins>
<!--
JaCoCo Code Coverage support
Workaround to find modules dependencies (root pom file must contain all modules)
Original code: https://github.com/jacoco/jacoco/pull/1251#issuecomment-1061585625
Can be removed after jacoco implemented a transitive modules support, see https://github.com/jacoco/jacoco/issues/1241
-->
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>patch-maven-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
// add all modules to the dependencies to make Jacoco aggregate report work (without listing them manually)
// see https://github.com/jacoco/jacoco/issues/974
for (dependencyProject in session.getProjectDependencyGraph().getSortedProjects()) {
def dependency = new org.apache.maven.model.Dependency() as Object
dependency.setGroupId(dependencyProject.getGroupId())
dependency.setArtifactId(dependencyProject.getArtifactId())
dependency.setVersion(dependencyProject.getVersion())
dependency.setScope("compile")
project.getDependencies().add(dependency)
}
</source>
</configuration>
</execution>
</executions>
</plugin>
<!--
JaCoCo Code Coverage support
Agent must be injected for all modules (see parent), but real report generates here
-->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<!-- generate combined report (current and dependency modules) -->
<id>report-aggregate</id>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
<configuration>
<formats>${jacoco.formats}</formats>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -70,4 +70,8 @@
<finalName>mage-serverconsole</finalName>
</build>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -49,5 +49,7 @@
<finalName>mage-deck-constructed</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,5 +45,7 @@
<finalName>mage-deck-limited</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-game-brawlduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -44,6 +44,8 @@
<finalName>mage-game-brawlfreeforall</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-game-canadianhighlanderduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-game-commanderduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -44,6 +44,8 @@
<finalName>mage-game-freeforall</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -50,6 +50,8 @@
<finalName>mage-game-custompillaroftheparunsduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,5 +45,7 @@
<finalName>mage-game-freeforall</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-game-freeformcommanderduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -44,6 +44,8 @@
<finalName>mage-game-freeforall</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -51,6 +51,8 @@
<finalName>mage-game-freeformunlimitedcommander</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -44,7 +44,9 @@
<finalName>mage-game-momirduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -49,7 +49,9 @@
<finalName>mage-game-momir</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -50,6 +50,8 @@
<finalName>mage-game-oathbreakerduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-game-freeforall</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -44,6 +44,8 @@
<finalName>mage-game-freeforall</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -44,7 +44,9 @@
<finalName>mage-game-tinyleadersduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-game-twoplayerduel</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -50,6 +50,8 @@
<finalName>mage-player-ai-draft-bot</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -50,6 +50,8 @@
<finalName>mage-player-ai-ma</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -54,6 +54,8 @@
<finalName>mage-player-ai</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -54,6 +54,8 @@
<finalName>mage-player-ai-mcts</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -50,6 +50,8 @@
<finalName>mage-player-aiminimax</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -50,6 +50,8 @@
<finalName>mage-player-human</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-tournament-booster-draft</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-tournament-constructed</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -45,6 +45,8 @@
<finalName>mage-tournament-sealed</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/../..</root.dir>
</properties>
</project>

View file

@ -46,4 +46,8 @@
<module>Mage.Tournament.Sealed</module>
</modules>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -347,6 +347,8 @@
<finalName>mage-server</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -42,6 +42,8 @@
<finalName>mage-sets</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -139,6 +139,8 @@
<finalName>mage-tests</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -90,6 +90,8 @@
<finalName>mage-verify</finalName>
</build>
<properties/>
<properties>
<root.dir>${project.basedir}/..</root.dir>
</properties>
</project>

View file

@ -99,6 +99,7 @@
<!-- The properties below are added by following http://vlkan.com/blog/post/2015/11/27/maven-protobuf/ -->
<properties>
<root.dir>${project.basedir}/..</root.dir>
<!-- protobuf paths -->
<protobuf.input.directory>${project.basedir}/src/main/proto</protobuf.input.directory>
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>

97
pom.xml
View file

@ -2,6 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.50</version>
@ -9,6 +10,47 @@
<name>Mage Root</name>
<description>Mage Root POM</description>
<properties>
<!-- app: game must be able to run under java 8 -->
<java.version>1.8</java.version>
<root.dir>${project.basedir}</root.dir>
<!-- TODO: research and optimize version in modules (version change for modules and server configs must be changeable by one line instead perl script -->
<mage-version>1.4.50</mage-version>
<argLine>-Dfile.encoding=UTF-8</argLine>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
<!-- build: logs settings for maven tests and travis ci builds -->
<xmage.build.tests.treeViewRunnerShowAllLogs>false</xmage.build.tests.treeViewRunnerShowAllLogs>
<!--
report: code coverage tools (disabled by default)
Output file formats:
* exec-files - generates in any runs, can be used by IntelliJ IDEA in show coverage data dialog: ./module_name/target/jacoco.exec
* XML - used by sonar for analysis and upload: ./Mage.Reports/target/site/jacoco-aggregate/jacoco.xml
* HTML - used by devs for offline view: ./Mage.Reports/target/site/jacoco-aggregate/index.html
* CSV - for something else: ./Mage.Reports/target/site/jacoco-aggregate/jacoco.csv
How to generate execute stats and reports:
* for IDE or sonar usage: mvn install -Djacoco.formats=XML -Djacoco.skip=false -Dmaven.test.failure.ignore=true
* for offline report: mvn install -Djacoco.skip=false -Dmaven.test.failure.ignore=true
-->
<jacoco.formats>XML,HTML</jacoco.formats>
<jacoco.skip>true</jacoco.skip>
<!--
report: sonar settings for code static analysis and coverage report
Actual analys visible on https://sonarcloud.io/project/overview?id=magefree_mage
How to analyse and upload to the server (warning, it can takes 15+ hours):
1. Collect code coverage data in xml format (see jacoco above);
2. mvn -e sonar:sonar -Dsonar.projectKey=magefree_mage -Dsonar.organization=magefree -Dsonar.host.url=https://sonarcloud.io -Dsonar.token=xxx
-->
<sonar.coverage.jacoco.xmlReportPaths>${root.dir}/Mage.Reports/target/site/jacoco-aggregate/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
</properties>
<build>
<plugins>
<plugin>
@ -37,12 +79,14 @@
</configuration>
</plugin>
<!-- JaCoCo Code Coverage report generation -->
<!-- Examples: http://tdongsi.github.io/blog/2017/09/23/jacoco-in-maven-project/ -->
<!--
JaCoCo Code Coverage support
Agent must be injected for all modules, but real report generates in Mage.Reports
-->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<version>0.8.11</version>
<executions>
<execution>
<!-- prepare command line to inject in java agent (collect code executing stats) -->
@ -50,22 +94,6 @@
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<!-- generate current module's report -->
<id>generate-code-coverage-report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<!-- generate combined report (current and dependency modules) -->
<id>report-aggregate</id>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
@ -213,6 +241,7 @@
<module>Mage.Server.Console</module>
<module>Mage.Tests</module>
<module>Mage.Verify</module>
<module>Mage.Reports</module>
</modules>
<repositories>
@ -234,36 +263,6 @@
</repository>
</repositories>
<properties>
<!--
java.version dictates what version of Java to build for.
This sets the minimum java version required to run the game.
-->
<java.version>1.8</java.version>
<mage-version>1.4.50</mage-version>
<argLine>-Dfile.encoding=UTF-8</argLine>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
<!-- logs settings for maven tests and travis ci builds -->
<xmage.build.tests.treeViewRunnerShowAllLogs>false</xmage.build.tests.treeViewRunnerShowAllLogs>
<!--
JaCoCo code coverage disabled by default. If you need to generate
execute stats and reports then run tests by maven command
like "mvn install -Djacoco.skip=false".
Stats:
- load coverage data for IntelliJ IDEA from ./target/jacoco.exec
- web report in ./target/site/jacoco/index.html
- for sonar support see below
-->
<jacoco.skip>true</jacoco.skip>
<!-- Sonar settings for code coverage. Must be only one report for all modules (use report-aggregate goal report from JaCoCo) -->
<aggregate.report.dir>Mage.Verify/target/site/jacoco-aggregate/jacoco.xml</aggregate.report.dir>
<sonar.coverage.jacoco.xmlReportPaths>${project.basedir}/../${aggregate.report.dir}</sonar.coverage.jacoco.xmlReportPaths>
</properties>
<dependencies>
<!-- GLOBAL dependencies - used in all xmage modules (no need to add it to child modules) -->
<dependency>