diff --git a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
index ed39cc90ae..fac986b395 100644
--- a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
+++ b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
@@ -64,6 +64,7 @@ public final class FailsafeSummaryXmlUtils {
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ + " %d\n"
+ " %s\n"
+ "";
@@ -84,12 +85,16 @@ public static RunResult toRunResult(File failsafeSummaryXml) throws Exception {
String skipped = xpath.evaluate("/failsafe-summary/skipped", root);
String failureMessage = xpath.evaluate("/failsafe-summary/failureMessage", root);
String timeout = xpath.evaluate("/failsafe-summary/@timeout", root);
+ String flakes = xpath.evaluate("/failsafe-summary/flakes", root);
return new RunResult(
parseInt(completed),
parseInt(errors),
parseInt(failures),
parseInt(skipped),
+ // FIXME Backwards compatability: to be replaced with parseInt in a future release
+ // synchronize with maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xsd
+ isBlank(flakes) ? 0 : parseInt(flakes),
isBlank(failureMessage) ? null : unescapeXml(failureMessage),
parseBoolean(timeout));
}
@@ -107,6 +112,7 @@ public static void fromRunResultToFile(RunResult fromRunResult, File toFailsafeS
fromRunResult.getErrors(),
fromRunResult.getFailures(),
fromRunResult.getSkipped(),
+ fromRunResult.getFlakes(),
msg);
Files.write(
diff --git a/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java b/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
index 1bd4145bc1..80d3eeaa41 100644
--- a/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
+++ b/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
@@ -19,12 +19,17 @@
package org.apache.maven.plugin.failsafe;
import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+import java.util.Locale;
import org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils;
import org.apache.maven.surefire.api.suite.RunResult;
import org.apache.maven.surefire.api.util.SureFireFileManager;
import org.junit.Test;
+import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
/**
@@ -64,6 +69,49 @@ public void testSkipped() throws Exception {
writeReadCheck(new RunResult(3, 2, 1, 0, null, true));
}
+ @Test
+ public void testFlakes() throws Exception {
+ writeReadCheck(new RunResult(3, 2, 1, 0, 2, null, true));
+ }
+
+ @Test
+ public void testLegacyDeserialization() throws Exception {
+ File legacySummary = SureFireFileManager.createTempFile("failsafe", "test");
+ String legacyFailsafeSummaryXmlTemplate = "\n"
+ + "\n"
+ + " %d\n"
+ + " %d\n"
+ + " %d\n"
+ + " %d\n"
+ + " %s\n"
+ + "";
+ String xml = format(Locale.ROOT, legacyFailsafeSummaryXmlTemplate, 0, false, 3, 2, 1, 0, "msg");
+ Files.write(
+ legacySummary.toPath(),
+ xml.getBytes(StandardCharsets.UTF_8),
+ StandardOpenOption.CREATE,
+ StandardOpenOption.TRUNCATE_EXISTING,
+ StandardOpenOption.WRITE);
+
+ // When the failsafe-summary.xml does not contain the element, it should be considered as 0.
+ RunResult expected = new RunResult(3, 2, 1, 0, 0, null, false);
+ RunResult actual = FailsafeSummaryXmlUtils.toRunResult(legacySummary);
+
+ assertThat(actual.getCompletedCount()).isEqualTo(expected.getCompletedCount());
+
+ assertThat(actual.getErrors()).isEqualTo(expected.getErrors());
+
+ assertThat(actual.getFailures()).isEqualTo(expected.getFailures());
+
+ assertThat(actual.getSkipped()).isEqualTo(expected.getSkipped());
+
+ assertThat(actual.getFlakes()).isEqualTo(expected.getFlakes());
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
@Test
public void testAppendSerialization() throws Exception {
RunResult simpleAggregate = getSimpleAggregate();
diff --git a/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xsd b/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xsd
index c412ec59e9..b81565234b 100644
--- a/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xsd
+++ b/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xsd
@@ -25,6 +25,7 @@
+
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/suite/RunResult.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/suite/RunResult.java
index 8be1df1d04..545e7ab447 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/suite/RunResult.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/suite/RunResult.java
@@ -202,6 +202,9 @@ public boolean equals(Object o) {
if (skipped != runResult.skipped) {
return false;
}
+ if (flakes != runResult.flakes) {
+ return false;
+ }
if (timeout != runResult.timeout) {
return false;
}
@@ -218,6 +221,7 @@ public int hashCode() {
result = 31 * result + errors;
result = 31 * result + failures;
result = 31 * result + skipped;
+ result = 31 * result + flakes;
result = 31 * result + (failure != null ? failure.hashCode() : 0);
result = 31 * result + (timeout ? 1 : 0);
return result;