diff --git a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/LifecycleSmokeTestPlugin.java b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/LifecycleSmokeTestPlugin.java index 7db1410..6a3d9ea 100644 --- a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/LifecycleSmokeTestPlugin.java +++ b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/LifecycleSmokeTestPlugin.java @@ -16,7 +16,9 @@ package org.springframework.lifecycle.gradle; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.stream.Stream; @@ -51,6 +53,8 @@ import org.springframework.lifecycle.gradle.tasks.StartApplication; import org.springframework.lifecycle.gradle.tasks.StartJvmApplication; import org.springframework.lifecycle.gradle.tasks.StopApplication; +import static org.springframework.lifecycle.gradle.dsl.LifecycleSmokeTestExtension.*; + /** * {@link Plugin} for a lifecycle smoke test project. Configures an {@code appTest} source * set and tasks for running the contained tests against the application running on the @@ -103,16 +107,21 @@ public class LifecycleSmokeTestPlugin implements Plugin { configureTests(project); configureKotlin(project, javaExtension); Provider smokeTestProvider = project.provider(() -> { - boolean runTests = false; - boolean runAppTests = false; - if (!javaExtension.getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME).getAllSource().isEmpty()) { - runTests = true; + boolean runTests = !javaExtension.getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME).getAllSource().isEmpty(); + boolean runAppTests = !appTest.getAllSource().isEmpty(); + List expectedToFail = new ArrayList<>(); + if (extension.getAppTest().getOutcome().get() == Outcome.FAILURE) { + expectedToFail.add("appTest"); } - if (!appTest.getAllSource().isEmpty()) { - runAppTests = true; + if (extension.getCheckpointRestoreAppTest().getOutcome().get() == Outcome.FAILURE) { + expectedToFail.add("checkpointRestoreAppTest"); } + if (extension.getTest().getOutcome().get() == Outcome.FAILURE) { + expectedToFail.add("test"); + } + return new SmokeTest(project.getName(), project.getParent().getName(), project.getPath(), runTests, - runAppTests); + runAppTests, expectedToFail); }); TaskProvider describeSmokeTest = project.getTasks() .register("describeSmokeTest", DescribeSmokeTest.class); diff --git a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/dsl/LifecycleSmokeTestExtension.java b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/dsl/LifecycleSmokeTestExtension.java index 8de268b..6fd2857 100644 --- a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/dsl/LifecycleSmokeTestExtension.java +++ b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/dsl/LifecycleSmokeTestExtension.java @@ -18,7 +18,9 @@ package org.springframework.lifecycle.gradle.dsl; import javax.inject.Inject; +import org.gradle.api.Action; import org.gradle.api.Project; +import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; /** @@ -33,10 +35,21 @@ public class LifecycleSmokeTestExtension { private final Property checkpointEvent; + private final Expectation appTest; + + private final Expectation checkpointRestoreAppTest; + + private final Expectation test; + + @Inject public LifecycleSmokeTestExtension(Project project) { - this.webApplication = project.getObjects().property(Boolean.class); - this.checkpointEvent = project.getObjects().property(String.class); + ObjectFactory objects = project.getObjects(); + this.webApplication = objects.property(Boolean.class); + this.checkpointEvent = objects.property(String.class); + this.appTest = objects.newInstance(Expectation.class, project); + this.checkpointRestoreAppTest = objects.newInstance(Expectation.class, project); + this.test = objects.newInstance(Expectation.class, project); } /** @@ -55,4 +68,78 @@ public class LifecycleSmokeTestExtension { return this.checkpointEvent; } + /** + * Expectations for {@code appTest}. + */ + public Expectation getAppTest() { + return this.appTest; + } + + /** + * Configure expectations for {@code appTest}. + */ + public void appTest(Action action) { + action.execute(this.appTest); + } + + /** + * Expectations for {@code checkpointRestoreAppTest}. + */ + public Expectation getCheckpointRestoreAppTest() { + return this.checkpointRestoreAppTest; + } + + /** + * Configure expectations for {@code checkpointRestoreAppTest}. + */ + public void checkpointRestoreAppTest(Action action) { + action.execute(this.checkpointRestoreAppTest); + } + + /** + * Expectations for {@code test}. + */ + public Expectation getTest() { + return this.test; + } + + /** + * Configure expectations for {@code test}. + */ + public void test(Action action) { + action.execute(this.test); + } + + public static class Expectation { + private final Property outcome; + @Inject + public Expectation(Project project) { + this.outcome = project.getObjects().property(Outcome.class); + this.outcome.convention(Outcome.SUCCESS); + } + /** + * The expected outcome. + */ + public Property getOutcome() { + return this.outcome; + } + /** + * Note that expected outcome is failure + */ + public void expectedToFail(Action action) { + this.outcome.set(Outcome.FAILURE); + } + } + public static enum Outcome { + /** + * The expected outcome is failure. + */ + FAILURE, + /** + * The expected outcome is success. + */ + SUCCESS + } + + } diff --git a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/DescribeSmokeTest.java b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/DescribeSmokeTest.java index 70fa250..f9af976 100644 --- a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/DescribeSmokeTest.java +++ b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/DescribeSmokeTest.java @@ -59,6 +59,7 @@ public abstract class DescribeSmokeTest extends DefaultTask { properties.add("path=" + smokeTest.path()); properties.add("group=" + smokeTest.group()); properties.add("name=" + smokeTest.name()); + properties.add("expectedToFail=" + String.join(",", smokeTest.expectedToFail())); Files.write(propertiesFile.toPath(), properties); } diff --git a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/SmokeTest.java b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/SmokeTest.java index 3a8fa65..924637b 100644 --- a/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/SmokeTest.java +++ b/gradle/plugins/lifecycle-smoke-test-plugin/src/main/java/org/springframework/lifecycle/gradle/tasks/SmokeTest.java @@ -17,6 +17,7 @@ package org.springframework.lifecycle.gradle.tasks; import java.io.Serializable; +import java.util.List; import java.util.Properties; /** @@ -30,11 +31,6 @@ import java.util.Properties; * @param appTests whether the smoke test contains any app tests */ public record SmokeTest(String name, String group, String path, boolean tests, - boolean appTests) implements Serializable { - - SmokeTest(Properties properties) { - this(properties.getProperty("name"), properties.getProperty("group"), properties.getProperty("path"), - Boolean.valueOf(properties.getProperty("tests")), Boolean.valueOf(properties.getProperty("appTests"))); - } + boolean appTests, List expectedToFail) implements Serializable { }