Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for configuration parameters resources #3345

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions documentation/src/docs/asciidoc/user-guide/running-tests.adoc
Expand Up @@ -895,13 +895,16 @@ engines running on the JUnit Platform via one of the following mechanisms.
`systemProperty` or `systemProperties` DSL.
* <<running-tests-build-maven-config-params,Maven Surefire provider>>: use the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new --config-resource option should also be included in this bullet point listing, below the --config discussion or incorporated into that discussion about the Console Launcher.

`configurationParameters` property.
2. JVM system properties.
3. The JUnit Platform configuration file: a file named `junit-platform.properties` in the
2. The `configurationParametersResource()` and `configurationParametersResources()`
methods in the `LauncherDiscoveryRequestBuilder` which are used to select a `.properties`
file on the classpath with configuration parameters.
Comment on lines +898 to +900
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. The `configurationParametersResource()` and `configurationParametersResources()`
methods in the `LauncherDiscoveryRequestBuilder` which are used to select a `.properties`
file on the classpath with configuration parameters.
2. The `configurationParametersResources()` method in the `LauncherDiscoveryRequestBuilder`
which is used to specify one or more Java `Properties` files in the class path that
provide configuration parameters.

The configurationParametersResource() method no longer exists -- right?

3. JVM system properties.
4. The JUnit Platform configuration file: a file named `junit-platform.properties` in the
root of the class path that follows the syntax rules for a Java `Properties` file.

NOTE: Configuration parameters are looked up in the exact order defined above.
Consequently, configuration parameters supplied directly to the `Launcher` take
precedence over those supplied via system properties and the configuration file.
precedence over those supplied via system properties, the specified properties files, and the platform configuration file.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
precedence over those supplied via system properties, the specified properties files, and the platform configuration file.
precedence over those supplied via system properties, custom properties files, and the platform configuration file.

Also, please wrap lines in Asciidoc files at 90 characters.

Similarly, configuration parameters supplied via system properties take precedence over
those supplied via the configuration file.

Expand Down
Expand Up @@ -66,6 +66,7 @@ public class TestDiscoveryOptions {
private List<String> includedTagExpressions = emptyList();
private List<String> excludedTagExpressions = emptyList();

private List<String> configurationParametersResources = emptyList();
private Map<String, String> configurationParameters = emptyMap();

public boolean isScanModulepath() {
Expand Down Expand Up @@ -262,4 +263,12 @@ public void setConfigurationParameters(Map<String, String> configurationParamete
this.configurationParameters = configurationParameters;
}

public List<String> getConfigurationParametersResources() {
return configurationParametersResources;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return configurationParametersResources;
return this.configurationParametersResources;

}

public TestDiscoveryOptions setConfigurationParametersResources(List<String> configurationParametersResources) {
this.configurationParametersResources = configurationParametersResources;
return this;
}
}
Expand Up @@ -54,6 +54,7 @@ LauncherDiscoveryRequest toDiscoveryRequest(TestDiscoveryOptions options) {
requestBuilder.selectors(selectors);
addFilters(requestBuilder, options, selectors);
requestBuilder.configurationParameters(options.getConfigurationParameters());
requestBuilder.configurationParametersResources(options.getConfigurationParametersResources());
return requestBuilder.build();
}

Expand Down
Expand Up @@ -29,6 +29,7 @@
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
import org.junit.platform.commons.util.ClassLoaderUtils;
import org.junit.platform.commons.util.CollectionUtils;
import org.junit.platform.commons.util.Preconditions;
import org.junit.platform.commons.util.ToStringBuilder;
import org.junit.platform.engine.ConfigurationParameters;
Expand Down Expand Up @@ -93,6 +94,7 @@ public String toString() {
static final class Builder {

private final Map<String, String> explicitParameters = new HashMap<>();
private final List<String> configResources = new ArrayList<>();
private boolean implicitProvidersEnabled = true;
private String configFileName = ConfigurationParameters.CONFIG_FILE_NAME;
private ConfigurationParameters parentConfigurationParameters;
Expand All @@ -106,6 +108,12 @@ Builder explicitParameters(Map<String, String> parameters) {
return this;
}

Builder configurationResources(List<String> configResources) {
Preconditions.notNull(configResources, "configResources must not be null");
this.configResources.addAll(configResources);
return this;
}

Builder enableImplicitProviders(boolean enabled) {
this.implicitProvidersEnabled = enabled;
return this;
Expand All @@ -129,6 +137,9 @@ LauncherConfigurationParameters build() {
parameterProviders.add(ParameterProvider.explicit(explicitParameters));
}

CollectionUtils.forEachInReverseOrder(configResources,
configResource -> parameterProviders.add(ParameterProvider.propertiesFile(configResource)));

if (parentConfigurationParameters != null) {
parameterProviders.add(ParameterProvider.inherited(parentConfigurationParameters));
}
Expand Down
Expand Up @@ -102,6 +102,7 @@ public final class LauncherDiscoveryRequestBuilder {
private final List<DiscoveryFilter<?>> discoveryFilters = new ArrayList<>();
private final List<PostDiscoveryFilter> postDiscoveryFilters = new ArrayList<>();
private final Map<String, String> configurationParameters = new HashMap<>();
private final List<String> configurationParametersResources = new ArrayList<>();
private final List<LauncherDiscoveryListener> discoveryListeners = new ArrayList<>();
private boolean implicitConfigurationParametersEnabled = true;
private ConfigurationParameters parentConfigurationParameters;
Expand Down Expand Up @@ -198,6 +199,30 @@ public LauncherDiscoveryRequestBuilder configurationParameters(Map<String, Strin
return this;
}

/**
* Add the supplied configuration parameters resource file to the request.
* @param propertiesFile the classpath location of the properties file
* never {@code null}
* @return this builder for method chaining
*/
public LauncherDiscoveryRequestBuilder configurationParametersResource(String propertiesFile) {
Preconditions.notNull(propertiesFile, "properties file must not be null");
configurationParametersResources.add(propertiesFile);
return this;
}

/**
* Add all of the supplied configuration parameters resource files to the request.
* @param propertiesFiles the classpath locations of the properties files
* never {@code null}
* @return this builder for method chaining
*/
public LauncherDiscoveryRequestBuilder configurationParametersResources(List<String> propertiesFiles) {
robinjhector marked this conversation as resolved.
Show resolved Hide resolved
Preconditions.notNull(propertiesFiles, "properties files must not be null");
propertiesFiles.forEach(this::configurationParametersResource);
return this;
}

/**
* Set the parent configuration parameters to use for the request.
*
Expand Down Expand Up @@ -296,6 +321,7 @@ public LauncherDiscoveryRequest build() {
private LauncherConfigurationParameters buildLauncherConfigurationParameters() {
Builder builder = LauncherConfigurationParameters.builder() //
.explicitParameters(this.configurationParameters) //
.configurationResources(this.configurationParametersResources) //
.enableImplicitProviders(this.implicitConfigurationParametersEnabled);

if (parentConfigurationParameters != null) {
Expand Down
Expand Up @@ -30,6 +30,7 @@
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.ConfigurationParametersResource;
import org.junit.platform.suite.api.ExcludeClassNamePatterns;
import org.junit.platform.suite.api.ExcludeEngines;
import org.junit.platform.suite.api.ExcludePackages;
Expand Down Expand Up @@ -105,6 +106,7 @@
* @see SuiteDisplayName
* @see org.junit.platform.suite.api.UseTechnicalNames UseTechnicalNames
* @see ConfigurationParameter
* @see ConfigurationParametersResource ConfigurationParametersResource
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @see ConfigurationParametersResource ConfigurationParametersResource
* @see ConfigurationParametersResource

* @deprecated since 1.8, in favor of the {@link Suite @Suite} support provided by
* the {@code junit-platform-suite-engine} module; to be removed in JUnit Platform 2.0
*/
Expand Down
@@ -0,0 +1,51 @@
/*
* Copyright 2015-2023 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package org.junit.platform.suite.api;

import static org.apiguardian.api.API.Status.EXPERIMENTAL;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.apiguardian.api.API;

/**
* {@code @ConfigurationParametersResource} is an annotation that specifies
* a configuration file in property format to be added to the discovery request when running
* a test suite on the JUnit Platform.
*
* @since 1.11
* @see DisableParentConfigurationParameters
* @see Suite
* @see org.junit.platform.runner.JUnitPlatform
* @see org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder#configurationParameter(String, String)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @see org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder#configurationParameter(String, String)

This method no longer exists -- right?

*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
// TODO: Before PR merge, change to STABLE/MAINTAINED
// TODO: Is version 1.11 correct?
robinjhector marked this conversation as resolved.
Show resolved Hide resolved
@API(status = EXPERIMENTAL, since = "1.11")
@Repeatable(ConfigurationParametersResources.class)
public @interface ConfigurationParametersResource {

/**
* The classpath location for the desired properties file; never {@code null} or blank.
*/
String resource();
robinjhector marked this conversation as resolved.
Show resolved Hide resolved

}
@@ -0,0 +1,50 @@
/*
* Copyright 2015-2023 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package org.junit.platform.suite.api;

import static org.apiguardian.api.API.Status.EXPERIMENTAL;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.apiguardian.api.API;

/**
* {@code @ConfigurationParametersResources} is a container for one or more
* {@link ConfigurationParametersResource @ConfigurationParametersResource} declarations.
*
* <p>Note, however, that use of the {@code @ConfigurationParametersResources} container
* is completely optional since {@code @ConfigurationParametersResource} is a
* {@linkplain java.lang.annotation.Repeatable repeatable} annotation.
*
* @since 1.8
* @see ConfigurationParametersResource
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
// TODO: Before PR merge, change to STABLE/MAINTAINED
// TODO: Is version 1.11 correct?
@API(status = EXPERIMENTAL, since = "1.11")
public @interface ConfigurationParametersResources {

/**
* An array of one or more {@link ConfigurationParametersResource @ConfigurationParameterResource}
* declarations.
*/
ConfigurationParametersResource[] value();

}
Expand Up @@ -45,6 +45,7 @@
import org.junit.platform.launcher.TagFilter;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.ConfigurationParametersResource;
import org.junit.platform.suite.api.DisableParentConfigurationParameters;
import org.junit.platform.suite.api.ExcludeClassNamePatterns;
import org.junit.platform.suite.api.ExcludeEngines;
Expand Down Expand Up @@ -115,6 +116,11 @@ public SuiteLauncherDiscoveryRequestBuilder configurationParameters(Map<String,
return this;
}

public SuiteLauncherDiscoveryRequestBuilder configurationParametersResource(String resourceFile) {
delegate.configurationParametersResource(resourceFile);
return this;
}

public SuiteLauncherDiscoveryRequestBuilder parentConfigurationParameters(
ConfigurationParameters parentConfigurationParameters) {
this.parentConfigurationParameters = parentConfigurationParameters;
Expand All @@ -133,6 +139,8 @@ public SuiteLauncherDiscoveryRequestBuilder suite(Class<?> suiteClass) {
// @formatter:off
findRepeatableAnnotations(suiteClass, ConfigurationParameter.class)
.forEach(configuration -> configurationParameter(configuration.key(), configuration.value()));
findRepeatableAnnotations(suiteClass, ConfigurationParametersResource.class)
.forEach(configResource -> configurationParametersResource(configResource.resource()));
findAnnotation(suiteClass, DisableParentConfigurationParameters.class)
.ifPresent(__ -> enableParentConfigurationParameters = false);
findAnnotationValues(suiteClass, ExcludeClassNamePatterns.class, ExcludeClassNamePatterns::value)
Expand Down
Expand Up @@ -313,6 +313,48 @@ void multipleConfigurationParametersAddedByMap_areStoredInDiscoveryRequest() {
assertThat(configParams.get("key1")).contains("value1");
assertThat(configParams.get("key2")).contains("value2");
}

@Test
void configurationParametersResource_areStoredInDiscoveryRequest() {
// @formatter:off
var discoveryRequest = request()
.configurationParametersResource("config-test.properties")
.build();
// @formatter:on

var configParams = discoveryRequest.getConfigurationParameters();
assertThat(configParams.get("com.example.prop.first")).contains("first value");
assertThat(configParams.get("com.example.prop.second")).contains("second value");
assertThat(configParams.get("com.example.prop.third")).contains("third value");
}

@Test
void configurationParametersResource_explicitConfigParametersOverrideResource() {
// @formatter:off
var discoveryRequest = request()
.configurationParametersResource("config-test.properties")
.configurationParameter("com.example.prop.first", "first value override")
.build();
// @formatter:on

var configParams = discoveryRequest.getConfigurationParameters();
assertThat(configParams.get("com.example.prop.first")).contains("first value override");
assertThat(configParams.get("com.example.prop.second")).contains("second value");
}

@Test
void configurationParametersResource_lastDeclaredResourceFileWins() {
// @formatter:off
var discoveryRequest = request()
.configurationParametersResource("config-test.properties")
.configurationParametersResource("config-test-override.properties")
.build();
// @formatter:on

var configParams = discoveryRequest.getConfigurationParameters();
assertThat(configParams.get("com.example.prop.first")).contains("first value from override file");
assertThat(configParams.get("com.example.prop.second")).contains("second value");
}
}

@Nested
Expand Down
Expand Up @@ -52,6 +52,8 @@
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.PostDiscoveryFilter;
import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.ConfigurationParametersResource;
import org.junit.platform.suite.api.ConfigurationParametersResources;
import org.junit.platform.suite.api.DisableParentConfigurationParameters;
import org.junit.platform.suite.api.ExcludeClassNamePatterns;
import org.junit.platform.suite.api.ExcludeEngines;
Expand Down Expand Up @@ -86,6 +88,48 @@ class Suite {
assertEquals(Optional.of("*"), parameter);
}

@Test
void configurationParametersResource() {
@ConfigurationParametersResource(resource = "config-test.properties")
class Suite {
}

LauncherDiscoveryRequest request = builder.suite(Suite.class).build();
ConfigurationParameters configuration = request.getConfigurationParameters();
Optional<String> parameter = configuration.get("com.example.prop.first");
assertEquals(Optional.of("first value"), parameter);
}

@Test
void configurationParametersResources() {
@ConfigurationParametersResources({ @ConfigurationParametersResource(resource = "config-test.properties"),
@ConfigurationParametersResource(resource = "config-test-override.properties") })
robinjhector marked this conversation as resolved.
Show resolved Hide resolved
class Suite {
}

LauncherDiscoveryRequest request = builder.suite(Suite.class).build();
ConfigurationParameters configuration = request.getConfigurationParameters();
Optional<String> parameterOne = configuration.get("com.example.prop.first");
assertEquals(Optional.of("first value from override file"), parameterOne);
Optional<String> parameterTwo = configuration.get("com.example.prop.second");
assertEquals(Optional.of("second value"), parameterTwo);
}

@Test
void configurationParametersResource_explicitParametersTakePrecedence() {
@ConfigurationParametersResource(resource = "config-test.properties")
@ConfigurationParameter(key = "com.example.prop.first", value = "first value from explicit parameter")
class Suite {
}

LauncherDiscoveryRequest request = builder.suite(Suite.class).build();
ConfigurationParameters configuration = request.getConfigurationParameters();
Optional<String> parameterOne = configuration.get("com.example.prop.first");
assertEquals(Optional.of("first value from explicit parameter"), parameterOne);
Optional<String> parameterTwo = configuration.get("com.example.prop.second");
assertEquals(Optional.of("second value"), parameterTwo);
}

@Test
void excludeClassNamePatterns() {
class TestCase {
Expand Down
@@ -0,0 +1,2 @@
# Used in tests, don't delete me
com.example.prop.first=first value from override file
4 changes: 4 additions & 0 deletions platform-tests/src/test/resources/config-test.properties
@@ -0,0 +1,4 @@
# Used in tests, don't delete me
com.example.prop.first=first value
com.example.prop.second=second value
com.example.prop.third=third value