Skip to content

Commit

Permalink
Add support for additional configuration parameters resources (#3345)
Browse files Browse the repository at this point in the history
Introduce `@ConfigurationParametersResource` for `@Suite` classes and
`--config-resource` option for ConsoleLauncher that allow specifying
additional properties files on the classpath as sources of configuration
parameters.

Resolves #3340.

Co-authored-by: Marc Philipp <mail@marcphilipp.de>
  • Loading branch information
robinjhector and marcphilipp authored Jul 19, 2024
1 parent f272b99 commit be8ae70
Show file tree
Hide file tree
Showing 21 changed files with 319 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ repository on GitHub.
[[release-notes-5.11.0-RC1-junit-platform-new-features-and-improvements]]
==== New Features and Improvements

* Introduce `@ConfigurationParametersResource` for `@Suite` classes and
`--config-resource` option for ConsoleLauncher that allow specifying additional
properties files on the classpath as sources of configuration parameters.
* New `rootCause()` condition in `TestExecutionResultConditions` that matches if an
exception's _root_ cause matches all supplied conditions, for use with the
`EngineTestKit`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,12 @@ $ java -jar junit-platform-console-standalone-{platform-version}.jar <OPTIONS> \
--config=junit.platform.reporting.open.xml.enabled=true \
--config=junit.platform.reporting.output.dir=reports
----

Configuration parameters can also be set in a custom properties file supplied as a classpath resource
via the `--config-resource` option:

[source,console,subs=attributes+]
----
$ java -jar junit-platform-console-standalone-{platform-version}.jar <OPTIONS> \
--config-resource=configuration.properties
----
39 changes: 23 additions & 16 deletions documentation/src/docs/asciidoc/user-guide/running-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -939,25 +939,32 @@ parameters_ for the following use cases.
_Configuration Parameters_ are text-based key-value pairs that can be supplied to test
engines running on the JUnit Platform via one of the following mechanisms.

1. The `configurationParameter()` and `configurationParameters()` methods in the
`LauncherDiscoveryRequestBuilder` which is used to build a request supplied to the
<<launcher-api, `Launcher` API>>. When running tests via one of the tools provided
by the JUnit Platform you can specify configuration parameters as follows:
* <<running-tests-console-launcher,Console Launcher>>: use the `--config`
command-line option.
* <<running-tests-build-gradle-config-params,Gradle>>: use the
`systemProperty` or `systemProperties` DSL.
* <<running-tests-build-maven-config-params,Maven Surefire provider>>: use the
`configurationParameters` property.
2. JVM system properties.
3. 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.
1. The `configurationParameter()` and `configurationParameters()` methods in
`LauncherDiscoveryRequestBuilder` which
is used to build a request supplied to the <<launcher-api, Launcher API>>.
+
When running tests via one of the tools provided by the JUnit Platform you can specify
configuration parameters as follows:
* <<running-tests-console-launcher,Console Launcher>>: use the `--config` command-line
option.
* <<running-tests-build-gradle-config-params,Gradle>>: use the `systemProperty` or
`systemProperties` DSL.
* <<running-tests-build-maven-config-params,Maven Surefire provider>>: use the
`configurationParameters` property.
2. The `configurationParametersResources()` method in `LauncherDiscoveryRequestBuilder`.
+
When running tests via the <<running-tests-console-launcher,Console Launcher>> you can
specify custom configuration files using the `--config-resource` command-line option.
3. JVM system properties.
4. The JUnit Platform default configuration file: a file named `junit-platform.properties`
in the root of the class path that follows the syntax rules for Java `Properties`
files.

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.
Similarly, configuration parameters supplied via system properties take precedence over
those supplied via the configuration file.
precedence over those supplied via custom configuration files, system properties, and the
default configuration file. Similarly, configuration parameters supplied via system
properties take precedence over those supplied via the default configuration file.

[[running-tests-config-params-deactivation-pattern]]
==== Pattern Matching Syntax
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,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 @@ -274,4 +275,12 @@ public void setConfigurationParameters(Map<String, String> configurationParamete
this.configurationParameters = configurationParameters;
}

public List<String> getConfigurationParametersResources() {
return this.configurationParametersResources;
}

public TestDiscoveryOptions setConfigurationParametersResources(List<String> configurationParametersResources) {
this.configurationParametersResources = configurationParametersResources;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ static class RuntimeConfigurationOptions {
// Implementation note: the @Option annotation is on a setter method to allow validation.
private final Map<String, String> configurationParameters = new LinkedHashMap<>();

@Option(names = {
"--config-resource" }, paramLabel = "PATH", arity = "1", description = "Set configuration parameters for test discovery and execution via a classpath resource. This option can be repeated.")
private List<String> configurationParametersResources = new ArrayList<>();

@CommandLine.Spec
private CommandLine.Model.CommandSpec spec;

Expand Down Expand Up @@ -296,6 +300,7 @@ private void validateUnique(String key, String newValue) {

private void applyTo(TestDiscoveryOptions result) {
result.setAdditionalClasspathEntries(merge(additionalClasspathEntries, additionalClasspathEntries2));
result.setConfigurationParametersResources(configurationParametersResources);
result.setConfigurationParameters(configurationParameters);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ LauncherDiscoveryRequest toDiscoveryRequest(TestDiscoveryOptions options) {
requestBuilder.selectors(selectors);
addFilters(requestBuilder, options, selectors);
requestBuilder.configurationParameters(options.getConfigurationParameters());
requestBuilder.configurationParametersResources(
options.getConfigurationParametersResources().toArray(new String[0]));
return requestBuilder.build();
}

Expand Down
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -102,6 +103,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 +200,18 @@ public LauncherDiscoveryRequestBuilder configurationParameters(Map<String, Strin
return this;
}

/**
* Add all of the supplied configuration parameters resource files to the request.
* @param paths the classpath locations of the properties files
* never {@code null}
* @return this builder for method chaining
*/
public LauncherDiscoveryRequestBuilder configurationParametersResources(String... paths) {
Preconditions.notNull(paths, "property file paths must not be null");
Collections.addAll(configurationParametersResources, paths);
return this;
}

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

if (this.parentConfigurationParameters != null) {
Expand Down
Original file line number Diff line number Diff line change
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 @@ -107,6 +108,7 @@
* @see SuiteDisplayName
* @see org.junit.platform.suite.api.UseTechnicalNames UseTechnicalNames
* @see ConfigurationParameter
* @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
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* a test suite on the JUnit Platform.
*
* @since 1.8
* @see ConfigurationParametersResource
* @see DisableParentConfigurationParameters
* @see Suite
* @see org.junit.platform.runner.JUnitPlatform
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2015-2024 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 a
* {@linkplain Repeatable repeatable} annotation that specifies a configuration
* file in Java's properties format on the classpath to be added to the
* discovery request when running a test suite on the JUnit Platform.
*
* @since 1.11
* @see ConfigurationParameter
* @see DisableParentConfigurationParameters
* @see Suite
* @see org.junit.platform.runner.JUnitPlatform
* @see org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder#configurationParametersResources(String...)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
@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 value();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2015-2024 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.11
* @see ConfigurationParametersResource
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
@API(status = EXPERIMENTAL, since = "1.11")
public @interface ConfigurationParametersResources {

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@
/**
* Disable parent configuration parameters.
*
* <p>By default a suite discovers tests using the configuration parameters
* <p>By default, a suite discovers tests using the configuration parameters
* explicitly configured via {@link ConfigurationParameter @ConfigurationParameter}
* and the configuration parameters from the discovery request that was used to
* discover the suite.
* and {@link ConfigurationParametersResource} as well as the configuration
* parameters from the discovery request that was used to discover the suite.
*
* <p>Annotating a suite with this annotation disables the latter source so
* that only explicit configuration parameters are taken into account.
* that only explicit configuration parameters and resources are taken into
* account.
*
* @since 1.8
* @see ConfigurationParameter
* @see ConfigurationParametersResource
* @see Suite
*/
@Retention(RetentionPolicy.RUNTIME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
* @see ExcludeTags
* @see SuiteDisplayName
* @see ConfigurationParameter
* @see ConfigurationParametersResource
* @see DisableParentConfigurationParameters
* @see org.junit.platform.launcher.LauncherDiscoveryRequest
* @see org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,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 @@ -214,6 +215,11 @@ public SuiteLauncherDiscoveryRequestBuilder configurationParameters(Map<String,
return this;
}

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

/**
* Set the parent configuration parameters to use for the request.
*
Expand Down Expand Up @@ -295,6 +301,8 @@ public SuiteLauncherDiscoveryRequestBuilder applyConfigurationParametersFromSuit
// @formatter:off
findRepeatableAnnotations(suiteClass, ConfigurationParameter.class)
.forEach(configuration -> configurationParameter(configuration.key(), configuration.value()));
findRepeatableAnnotations(suiteClass, ConfigurationParametersResource.class)
.forEach(configResource -> configurationParametersResource(configResource.value()));
findAnnotation(suiteClass, DisableParentConfigurationParameters.class)
.ifPresent(__ -> this.enableParentConfigurationParameters = false);
// @formatter:on
Expand Down
Loading

0 comments on commit be8ae70

Please sign in to comment.