From 9d92ee61fc3cef0f5e969c9fc440b4c3fc4e1d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Mon, 7 Aug 2023 15:07:58 +0200 Subject: [PATCH] Displayed standard error to see checkpoint errors Closes gh-13 --- .../cr/smoketest/support/Output.java | 35 ++++++++++++++----- .../support/assertj/OutputAssert.java | 8 ++--- .../support/junit/ApplicationUnderTest.java | 2 +- .../support/junit/AwaitApplication.java | 22 ++++++++---- .../cr/gradle/CrSmokeTestPlugin.java | 2 ++ 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/Output.java b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/Output.java index f742947..9f7f7d9 100644 --- a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/Output.java +++ b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/Output.java @@ -26,18 +26,31 @@ import java.util.List; * Output from an application. * * @author Andy Wilkinson + * @author Sebastien Deleuze */ public class Output { - private final Path path; + private final Path outputPath; - private Output(Path path) { - this.path = path; + private final Path errorPath; + + private Output(Path outputPath, Path errorPath) { + this.outputPath = outputPath; + this.errorPath = errorPath; } - public List lines() { + public List outputLines() { try { - return Files.readAllLines(this.path); + return Files.readAllLines(this.outputPath); + } + catch (IOException ex) { + throw new RuntimeException(); + } + } + + public List errorLines() { + try { + return Files.readAllLines(this.errorPath); } catch (IOException ex) { throw new RuntimeException(); @@ -45,13 +58,19 @@ public class Output { } public static Output current() { - String property = System.getProperty("org.springframework.cr.smoketest.standard-output"); - if (property == null) { + String outputProperty = System.getProperty("org.springframework.cr.smoketest.standard-output"); + if (outputProperty == null) { throw new IllegalStateException( "Standard output is not available as org.springframework.cr.smoketest.standard-output " + "system property has not been set"); } - return new Output(new File(property).toPath()); + String errorProperty = System.getProperty("org.springframework.cr.smoketest.standard-error"); + if (errorProperty == null) { + throw new IllegalStateException( + "Standard error is not available as org.springframework.cr.smoketest.standard-error " + + "system property has not been set"); + } + return new Output(new File(outputProperty).toPath(), new File(errorProperty).toPath()); } } diff --git a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/assertj/OutputAssert.java b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/assertj/OutputAssert.java index 58d9317..2e48902 100644 --- a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/assertj/OutputAssert.java +++ b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/assertj/OutputAssert.java @@ -41,7 +41,7 @@ public class OutputAssert extends AbstractAssert { * @return {@code this} for fluent API */ public OutputAssert hasSingleLineContaining(String contents) { - List lines = this.actual.lines(); + List lines = this.actual.outputLines(); List matchingLines = lines.stream().filter((line) -> line.contains(contents)).toList(); if (matchingLines.size() != 1) { throwAssertionError( @@ -57,7 +57,7 @@ public class OutputAssert extends AbstractAssert { * @return {@code this} for fluent API */ public OutputAssert hasLineContaining(String contents) { - List lines = this.actual.lines(); + List lines = this.actual.outputLines(); Optional matchingLines = lines.stream().filter((line) -> line.contains(contents)).findAny(); if (matchingLines.isEmpty()) { throwAssertionError(new BasicErrorMessageFactory( @@ -72,7 +72,7 @@ public class OutputAssert extends AbstractAssert { * @return {@code this} for fluent API */ public OutputAssert hasLineMatching(String regex) { - List lines = this.actual.lines(); + List lines = this.actual.outputLines(); Optional matchingLines = lines.stream().filter((line) -> line.matches(regex)).findAny(); if (matchingLines.isEmpty()) { throwAssertionError(new BasicErrorMessageFactory( @@ -87,7 +87,7 @@ public class OutputAssert extends AbstractAssert { * @return {@code this} for fluent API */ public OutputAssert hasNoLinesContaining(String contents) { - List lines = this.actual.lines(); + List lines = this.actual.outputLines(); boolean noMatch = lines.stream().noneMatch((line) -> line.contains(contents)); if (!noMatch) { throwAssertionError(new BasicErrorMessageFactory( diff --git a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/ApplicationUnderTest.java b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/ApplicationUnderTest.java index be2a7b5..07048f0 100644 --- a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/ApplicationUnderTest.java +++ b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/ApplicationUnderTest.java @@ -49,7 +49,7 @@ final class ApplicationUnderTest { List portPatterns = List.of(Pattern.compile("Tomcat started on port ([0-9]+)"), Pattern.compile("Netty started on port ([0-9]+)"), Pattern.compile("Jetty started on port ([0-9]+)"), Pattern.compile("Undertow started on port ([0-9]+)")); - List lines = Output.current().lines(); + List lines = Output.current().outputLines(); for (String line : lines) { for (Pattern portPattern : portPatterns) { Matcher matcher = portPattern.matcher(line); diff --git a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/AwaitApplication.java b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/AwaitApplication.java index 9379876..cb7e524 100644 --- a/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/AwaitApplication.java +++ b/cr-smoke-test-support/src/main/java/org/springframework/cr/smoketest/support/junit/AwaitApplication.java @@ -45,27 +45,35 @@ class AwaitApplication implements BeforeAllCallback { public void beforeAll(ExtensionContext context) throws Exception { Output output = Output.current(); long end = Instant.now().plus(START_TIMEOUT).toEpochMilli(); - List lines = null; + List outputLines = null; while (System.currentTimeMillis() < end) { - lines = output.lines(); - for (String line : lines) { + outputLines = output.outputLines(); + for (String line : outputLines) { if (this.APPLICATION_STARTED.matcher(line).find() || this.APPLICATION_RE_STARTED.matcher(line).find()) { return; } } } StringBuilder message = new StringBuilder( - "Started log message was not detected within " + START_TIMEOUT.getSeconds() + "s in output:"); - message.append("\n\n"); - if (lines == null || lines.isEmpty()) { + "Started log message was not detected within " + START_TIMEOUT.getSeconds() + "s:."); + message.append("\n\nStandard output:\n"); + if (outputLines == null || outputLines.isEmpty()) { message.append("<< none >>"); } else { - for (String line : lines) { + for (String line : outputLines) { message.append(line + "\n"); } } message.append("\n"); + List errorLines = output.errorLines(); + if (!errorLines.isEmpty()) { + message.append("\nStandard error:\n"); + for (String line : errorLines) { + message.append(line + "\n"); + } + message.append("\n"); + } System.err.println(message.toString()); throw new IllegalStateException(message.toString()); } diff --git a/gradle/plugins/cr-smoke-test-plugin/src/main/java/org/springframework/cr/gradle/CrSmokeTestPlugin.java b/gradle/plugins/cr-smoke-test-plugin/src/main/java/org/springframework/cr/gradle/CrSmokeTestPlugin.java index 4b84e07..be56c9f 100644 --- a/gradle/plugins/cr-smoke-test-plugin/src/main/java/org/springframework/cr/gradle/CrSmokeTestPlugin.java +++ b/gradle/plugins/cr-smoke-test-plugin/src/main/java/org/springframework/cr/gradle/CrSmokeTestPlugin.java @@ -275,6 +275,8 @@ public class CrSmokeTestPlugin implements Plugin { .withPropertyName("applicationBinary"); task.systemProperty("org.springframework.cr.smoketest.standard-output", startTask.get().getOutputFile().get().getAsFile().getAbsolutePath()); + task.systemProperty("org.springframework.cr.smoketest.standard-error", + startTask.get().getErrorFile().get().getAsFile().getAbsolutePath()); task.finalizedBy(stopTask); task.setDescription("Runs the app test suite against the " + type.description + " application."); task.setGroup(JavaBasePlugin.VERIFICATION_GROUP);