From cea57d9ab2e95215bf81ad8055198486d808e028 Mon Sep 17 00:00:00 2001 From: Jose Date: Tue, 28 Sep 2021 09:56:29 +0200 Subject: [PATCH] Allow to use a custom application.properties per test scenario By default, the test framework will use the `application.properties` file at `src/main/resources` folder. The service interface provides multiple methods to add properties at test scope only: - `service.withProperties(path)` - `service.withProperty(key, value)` If you want to use a different application properties file for all the tests, you can add the `application.properties` file at `src/test/resources` and the test framework will use this instead. Moreover, if you want to select a concrete application properties file for a single test scenario, then you can configure your Quarkus application using: ```java @QuarkusScenario public class PingPongResourceIT { @QuarkusApplication(properties = "my-custom-properties.properties") static final RestService pingpong = new RestService(); } ``` This option is available also for Dev Mode, Remote Dev mode and remote git applications, and works for JVM, Native, OpenShift and Kubernetes. | Note that the test framework does not support the usage of YAML files yet [#240](https://github.com/quarkus-qe/quarkus-test-framework/issues/240) --- README.md | 24 +++++++++++++++++++ ...ingCustomPropertiesPingPongResourceIT.java | 22 +++++++++++++++++ ...ingCustomPropertiesPingPongResourceIT.java | 22 +++++++++++++++++ ...ingCustomPropertiesPingPongResourceIT.java | 9 +++++++ .../src/test/resources/custom.properties | 1 + .../services/DevModeQuarkusApplication.java | 5 ++++ .../GitRepositoryQuarkusApplication.java | 5 ++++ .../test/services/QuarkusApplication.java | 5 ++++ .../RemoteDevModeQuarkusApplication.java | 5 ++++ ...rkusApplicationManagedResourceBuilder.java | 1 + ...rkusApplicationManagedResourceBuilder.java | 1 + ...rkusApplicationManagedResourceBuilder.java | 1 + ...rkusApplicationManagedResourceBuilder.java | 24 ++++++++++++------- ...rkusApplicationManagedResourceBuilder.java | 1 + .../java/io/quarkus/test/utils/FileUtils.java | 3 ++- .../quarkus/test/utils/PropertiesUtils.java | 5 ++-- ...hiftQuarkusApplicationManagedResource.java | 4 +--- 17 files changed, 123 insertions(+), 15 deletions(-) create mode 100644 examples/pingpong/src/test/java/io/quarkus/qe/ComputedValuesUsingCustomPropertiesPingPongResourceIT.java create mode 100644 examples/pingpong/src/test/java/io/quarkus/qe/DevModeComputedValuesUsingCustomPropertiesPingPongResourceIT.java create mode 100644 examples/pingpong/src/test/java/io/quarkus/qe/OpenShiftUsingExtensionComputedValuesUsingCustomPropertiesPingPongResourceIT.java create mode 100644 examples/pingpong/src/test/resources/custom.properties diff --git a/README.md b/README.md index dd98c49ac..54d6646dd 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,30 @@ public class PingPongResourceIT { As seen in the above example, everything is bounded to a Service object that will contain everything needed to interact with our resources. +### Application properties + +By default, the test framework will use the `application.properties` file at `src/main/resources` folder. The service interface provides multiple methods to add properties at test scope only: +- `service.withProperties(path)` +- `service.withProperty(key, value)` + +If you want to use a different application properties file for all the tests, you can add the `application.properties` file at `src/test/resources` and the test framework will use this instead. + +Moreover, if you want to select a concrete application properties file for a single test scenario, then you can configure your Quarkus application using: + +```java +@QuarkusScenario +public class PingPongResourceIT { + + // Now, the application will use the file `my-custom-properties.properties` instead of the `application.properties` + @QuarkusApplication(properties = "my-custom-properties.properties") + static final RestService pingpong = new RestService(); +} +``` + +This option is available also for Dev Mode, Remote Dev mode and remote git applications, and works for JVM, Native, OpenShift and Kubernetes. + +| Note that the test framework does not support the usage of YAML files yet [#240](https://github.com/quarkus-qe/quarkus-test-framework/issues/240) + ### Forced Dependencies We can also specify dependencies that are not part of the pom.xml by doing: diff --git a/examples/pingpong/src/test/java/io/quarkus/qe/ComputedValuesUsingCustomPropertiesPingPongResourceIT.java b/examples/pingpong/src/test/java/io/quarkus/qe/ComputedValuesUsingCustomPropertiesPingPongResourceIT.java new file mode 100644 index 000000000..957c0d085 --- /dev/null +++ b/examples/pingpong/src/test/java/io/quarkus/qe/ComputedValuesUsingCustomPropertiesPingPongResourceIT.java @@ -0,0 +1,22 @@ +package io.quarkus.qe; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.QuarkusApplication; + +@QuarkusScenario +public class ComputedValuesUsingCustomPropertiesPingPongResourceIT { + + @QuarkusApplication(properties = "custom.properties") + static final RestService pingpong = new RestService(); + + @Test + public void shouldGetComputedValuesFromCustomPropertiesFile() { + assertEquals("C", pingpong.getProperty("property.exists.only.in.custom.properties").get()); + } + +} diff --git a/examples/pingpong/src/test/java/io/quarkus/qe/DevModeComputedValuesUsingCustomPropertiesPingPongResourceIT.java b/examples/pingpong/src/test/java/io/quarkus/qe/DevModeComputedValuesUsingCustomPropertiesPingPongResourceIT.java new file mode 100644 index 000000000..a1473d0fc --- /dev/null +++ b/examples/pingpong/src/test/java/io/quarkus/qe/DevModeComputedValuesUsingCustomPropertiesPingPongResourceIT.java @@ -0,0 +1,22 @@ +package io.quarkus.qe; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@QuarkusScenario +public class DevModeComputedValuesUsingCustomPropertiesPingPongResourceIT { + + @DevModeQuarkusApplication(properties = "custom.properties") + static final RestService pingpong = new RestService(); + + @Test + public void shouldGetComputedValuesFromCustomPropertiesFile() { + assertEquals("C", pingpong.getProperty("property.exists.only.in.custom.properties").get()); + } + +} diff --git a/examples/pingpong/src/test/java/io/quarkus/qe/OpenShiftUsingExtensionComputedValuesUsingCustomPropertiesPingPongResourceIT.java b/examples/pingpong/src/test/java/io/quarkus/qe/OpenShiftUsingExtensionComputedValuesUsingCustomPropertiesPingPongResourceIT.java new file mode 100644 index 000000000..a96a9fe2e --- /dev/null +++ b/examples/pingpong/src/test/java/io/quarkus/qe/OpenShiftUsingExtensionComputedValuesUsingCustomPropertiesPingPongResourceIT.java @@ -0,0 +1,9 @@ +package io.quarkus.qe; + +import io.quarkus.test.scenarios.OpenShiftDeploymentStrategy; +import io.quarkus.test.scenarios.OpenShiftScenario; + +@OpenShiftScenario(deployment = OpenShiftDeploymentStrategy.UsingOpenShiftExtension) +public class OpenShiftUsingExtensionComputedValuesUsingCustomPropertiesPingPongResourceIT + extends ComputedValuesUsingCustomPropertiesPingPongResourceIT { +} diff --git a/examples/pingpong/src/test/resources/custom.properties b/examples/pingpong/src/test/resources/custom.properties new file mode 100644 index 000000000..fc2363dfc --- /dev/null +++ b/examples/pingpong/src/test/resources/custom.properties @@ -0,0 +1 @@ +property.exists.only.in.custom.properties=C diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/DevModeQuarkusApplication.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/DevModeQuarkusApplication.java index 1f39e2de5..4210ca8d3 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/DevModeQuarkusApplication.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/DevModeQuarkusApplication.java @@ -11,6 +11,11 @@ // By default, it will load all the classes in the classpath. Class[] classes() default {}; + /** + * @return the properties file to use to configure the Quarkus application. + */ + String properties() default "application.properties"; + /** * Enable GRPC configuration. This property will map the gPRC service to a random port. */ diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/GitRepositoryQuarkusApplication.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/GitRepositoryQuarkusApplication.java index c252c4ce5..01dda9935 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/GitRepositoryQuarkusApplication.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/GitRepositoryQuarkusApplication.java @@ -17,4 +17,9 @@ String mavenArgs() default "-DskipTests=true -DskipITs=true -Dquarkus.platform.version=${QUARKUS_VERSION}"; boolean devMode() default false; + + /** + * @return the properties file to use to configure the Quarkus application. + */ + String properties() default "application.properties"; } diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/QuarkusApplication.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/QuarkusApplication.java index 26a41381e..894df3418 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/QuarkusApplication.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/QuarkusApplication.java @@ -16,6 +16,11 @@ Class builder() default ProdQuarkusApplicationManagedResourceBuilder.class; + /** + * @return the properties file to use to configure the Quarkus application. + */ + String properties() default "application.properties"; + /** * Add forced dependencies. */ diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/RemoteDevModeQuarkusApplication.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/RemoteDevModeQuarkusApplication.java index 5cdada4a8..d8703df0c 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/RemoteDevModeQuarkusApplication.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/RemoteDevModeQuarkusApplication.java @@ -9,4 +9,9 @@ @Retention(RetentionPolicy.RUNTIME) public @interface RemoteDevModeQuarkusApplication { String password() default "qe"; + + /** + * @return the properties file to use to configure the Quarkus application. + */ + String properties() default "application.properties"; } diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/DevModeQuarkusApplicationManagedResourceBuilder.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/DevModeQuarkusApplicationManagedResourceBuilder.java index 7c4a64317..425b4dcd6 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/DevModeQuarkusApplicationManagedResourceBuilder.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/DevModeQuarkusApplicationManagedResourceBuilder.java @@ -16,6 +16,7 @@ public class DevModeQuarkusApplicationManagedResourceBuilder extends QuarkusAppl public void init(Annotation annotation) { DevModeQuarkusApplication metadata = (DevModeQuarkusApplication) annotation; initAppClasses(metadata.classes()); + setPropertiesFile(metadata.properties()); setGrpcEnabled(metadata.grpc()); } diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/GitRepositoryQuarkusApplicationManagedResourceBuilder.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/GitRepositoryQuarkusApplicationManagedResourceBuilder.java index a615baa91..2a42ef7a0 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/GitRepositoryQuarkusApplicationManagedResourceBuilder.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/GitRepositoryQuarkusApplicationManagedResourceBuilder.java @@ -57,6 +57,7 @@ public void init(Annotation annotation) { mavenArgs = metadata.mavenArgs(); devMode = metadata.devMode(); initAppClasses(new Class[0]); + setPropertiesFile(metadata.properties()); } @Override diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/ProdQuarkusApplicationManagedResourceBuilder.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/ProdQuarkusApplicationManagedResourceBuilder.java index 6118e0c11..18b20df05 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/ProdQuarkusApplicationManagedResourceBuilder.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/ProdQuarkusApplicationManagedResourceBuilder.java @@ -49,6 +49,7 @@ protected Path getArtifact() { @Override public void init(Annotation annotation) { QuarkusApplication metadata = (QuarkusApplication) annotation; + setPropertiesFile(metadata.properties()); setSslEnabled(metadata.ssl()); setGrpcEnabled(metadata.grpc()); initAppClasses(metadata.classes()); diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/QuarkusApplicationManagedResourceBuilder.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/QuarkusApplicationManagedResourceBuilder.java index bad529330..008f8433c 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/QuarkusApplicationManagedResourceBuilder.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/QuarkusApplicationManagedResourceBuilder.java @@ -53,6 +53,7 @@ public abstract class QuarkusApplicationManagedResourceBuilder implements Manage private List forcedDependencies = Collections.emptyList(); private boolean requiresCustomBuild = false; private ServiceContext context; + private String propertiesFile = APPLICATION_PROPERTIES; private boolean sslEnabled = false; private boolean grpcEnabled = false; private Map propertiesSnapshot; @@ -67,6 +68,10 @@ protected void setContext(ServiceContext context) { this.context = context; } + protected void setPropertiesFile(String propertiesFile) { + this.propertiesFile = propertiesFile; + } + protected boolean isSslEnabled() { return sslEnabled; } @@ -100,7 +105,7 @@ public String getComputedProperty(String name) { Path applicationProperties = getComputedApplicationProperties(); if (!Files.exists(applicationProperties)) { // computed properties have not been propagated yet, we use the one from src/main/resources - applicationProperties = RESOURCES_FOLDER.resolve(APPLICATION_PROPERTIES); + applicationProperties = RESOURCES_FOLDER.resolve(propertiesFile); } if (!Files.exists(applicationProperties)) { @@ -179,22 +184,23 @@ protected Path getResourcesApplicationFolder() { return getApplicationFolder(); } - private Path getComputedApplicationProperties() { + protected Path getComputedApplicationProperties() { return getResourcesApplicationFolder().resolve(APPLICATION_PROPERTIES); } private void createComputedApplicationProperties() { - Path applicationProperties = getComputedApplicationProperties(); + Path sourceApplicationProperties = getResourcesApplicationFolder().resolve(propertiesFile); + Path generatedApplicationProperties = getResourcesApplicationFolder().resolve(APPLICATION_PROPERTIES); Map map = new HashMap<>(); - // Put the original application properties - if (Files.exists(applicationProperties)) { - map.putAll(PropertiesUtils.toMap(applicationProperties)); + // Add the content of the source application properties into the auto-generated application.properties + if (Files.exists(sourceApplicationProperties)) { + map.putAll(PropertiesUtils.toMap(sourceApplicationProperties)); } - // Then put the build properties + // Then add the service properties map.putAll(context.getOwner().getProperties()); - // Then replace the application properties - PropertiesUtils.fromMap(map, applicationProperties); + // Then overwrite the application properties with the generated application.properties + PropertiesUtils.fromMap(map, generatedApplicationProperties); } private boolean isBuildProperty(String name) { diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/RemoteDevModeQuarkusApplicationManagedResourceBuilder.java b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/RemoteDevModeQuarkusApplicationManagedResourceBuilder.java index 6fb237dfc..7294d2858 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/RemoteDevModeQuarkusApplicationManagedResourceBuilder.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/services/quarkus/RemoteDevModeQuarkusApplicationManagedResourceBuilder.java @@ -48,6 +48,7 @@ public class RemoteDevModeQuarkusApplicationManagedResourceBuilder extends Artif public void init(Annotation annotation) { RemoteDevModeQuarkusApplication metadata = (RemoteDevModeQuarkusApplication) annotation; liveReloadPassword = metadata.password(); + setPropertiesFile(metadata.properties()); } @Override diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/utils/FileUtils.java b/quarkus-test-core/src/main/java/io/quarkus/test/utils/FileUtils.java index ffb87d270..b1eb2a650 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/utils/FileUtils.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/utils/FileUtils.java @@ -1,5 +1,6 @@ package io.quarkus.test.utils; +import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.junit.jupiter.api.Assertions.fail; import java.io.File; @@ -53,7 +54,7 @@ public static String loadFile(String file) { fail("Could not load file " + file + " . Caused by " + e.getMessage()); } - return null; + return EMPTY; } public static void recreateDirectory(Path folder) { diff --git a/quarkus-test-core/src/main/java/io/quarkus/test/utils/PropertiesUtils.java b/quarkus-test-core/src/main/java/io/quarkus/test/utils/PropertiesUtils.java index 02c3715cf..4604c5893 100644 --- a/quarkus-test-core/src/main/java/io/quarkus/test/utils/PropertiesUtils.java +++ b/quarkus-test-core/src/main/java/io/quarkus/test/utils/PropertiesUtils.java @@ -7,6 +7,7 @@ import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collections; import java.util.Map; import java.util.Properties; @@ -53,7 +54,7 @@ public static Map toMap(String propertiesFile) { fail("Could not load map from system resource. Caused by " + e); } - return null; + return Collections.emptyMap(); } public static Map toMap(Path path) { @@ -63,7 +64,7 @@ public static Map toMap(Path path) { fail("Could not load map from path. Caused by " + e); } - return null; + return Collections.emptyMap(); } public static Map toMap(InputStream is) { diff --git a/quarkus-test-openshift/src/main/java/io/quarkus/test/services/quarkus/ExtensionOpenShiftQuarkusApplicationManagedResource.java b/quarkus-test-openshift/src/main/java/io/quarkus/test/services/quarkus/ExtensionOpenShiftQuarkusApplicationManagedResource.java index 08a4b3ecb..c772df9f5 100644 --- a/quarkus-test-openshift/src/main/java/io/quarkus/test/services/quarkus/ExtensionOpenShiftQuarkusApplicationManagedResource.java +++ b/quarkus-test-openshift/src/main/java/io/quarkus/test/services/quarkus/ExtensionOpenShiftQuarkusApplicationManagedResource.java @@ -42,8 +42,6 @@ public class ExtensionOpenShiftQuarkusApplicationManagedResource private static final String QUARKUS_KUBERNETES_DEPLOYMENT_TARGET = "quarkus.kubernetes.deployment-target"; private static final String KNATIVE = "knative"; - private static final String APPLICATION_PROPERTIES_PATH = "src/main/resources/application.properties"; - public ExtensionOpenShiftQuarkusApplicationManagedResource(ProdQuarkusApplicationManagedResourceBuilder model) { super(model); } @@ -84,7 +82,7 @@ private void copyBuildPropertiesIntoAppFolder() { return; } - Path applicationPropertiesPath = model.getContext().getServiceFolder().resolve(APPLICATION_PROPERTIES_PATH); + Path applicationPropertiesPath = model.getComputedApplicationProperties(); if (Files.exists(applicationPropertiesPath)) { buildProperties.putAll(PropertiesUtils.toMap(applicationPropertiesPath)); }