Skip to content

LauncherConfig does not effectively use system properties due to LauncherConfig.DEFAULT and unpopulated ConfigurationParameters context #4543

@GAATTC0

Description

@GAATTC0

Issue Description:
In JUnit Platform LauncherFactory , the no-argument LauncherFactory.create() method directly uses LauncherConfig.DEFAULT. This LauncherConfig.DEFAULT instance has its auto-registration booleans (e.g., testExecutionListenerAutoRegistrationEnabled) hardcoded to true within LauncherConfig.Builder and is not initialized based on values from an externally populated ConfigurationParameters instance.

This means directly invoking LauncherFactory.openSession() or LauncherFactory.create()(I tried both IDEA and gradle, they all use the LauncherFactory.openSession() and cannot modify) cannot effectively use system properties to control these common listener configuration aspects, as the necessary LauncherConfig booleans are predetermined and the ConfigurationParameters context used for deactivation isn't populated from external sources by LauncherFactory itself.

a simple code discribe:

public class LauncherFactory {

    // IDEA or Gradle etc., start LauncherSession use this method
    public static LauncherSession openSession() throws PreconditionViolationException {
        return openSession(LauncherConfig.DEFAULT);
    }

    @API(status = STABLE, since = "1.10")
    public static LauncherSession openSession(LauncherConfig config) throws PreconditionViolationException {
        // here can we set system property to affect `testExecutionListenerAutoRegistrationEnabled`
        LauncherConfigurationParameters configurationParameters = LauncherConfigurationParameters.builder().build();
        return new DefaultLauncherSession(collectLauncherInterceptors(configurationParameters),
                () -> createLauncherSessionListener(config), () -> createDefaultLauncher(config, configurationParameters));
    }

    private static DefaultLauncher createDefaultLauncher(LauncherConfig config,
                                                         LauncherConfigurationParameters configurationParameters) {
        // ...
        registerTestExecutionListeners(config, launcher, configurationParameters);
        return launcher;
    }

    private static void registerTestExecutionListeners(LauncherConfig config, Launcher launcher,
                                                       LauncherConfigurationParameters configurationParameters) {
        // this always return true:
        if (config.isTestExecutionListenerAutoRegistrationEnabled()) {
            loadAndFilterTestExecutionListeners(configurationParameters).forEach(
                    launcher::registerTestExecutionListeners);
        }
        config.getAdditionalTestExecutionListeners().forEach(launcher::registerTestExecutionListeners);
    }

    private static Stream<TestExecutionListener> loadAndFilterTestExecutionListeners(
            ConfigurationParameters configurationParameters) {
        // this `DEACTIVATE_LISTENERS_PATTERN_PROPERTY_NAME` can be read from system properties
        String deactivatedListenersPattern = configurationParameters.get(
                DEACTIVATE_LISTENERS_PATTERN_PROPERTY_NAME).orElse(null);
        // ...
    }
}

Suggested Solution:
1.Enhance LauncherFactory.create() (no-arg version): Instead of directly using LauncherConfig.DEFAULT, this method could internally:

  • Create a ConfigurationParameters instance that is populated from standard sources (e.g., system properties, junit-platform.properties via a mechanism similar to LauncherConfigurationParametersAdapter).
  • Use this populated ConfigurationParameters instance to build a LauncherConfig (e.g., by passing relevant string values from it to LauncherConfig.builder().enableTestExecutionListenerAutoRegistration(converter.toBoolean(params.get(...))), etc.).
  • This newly built LauncherConfig would then be passed to create(LauncherConfig config).
  • The populated ConfigurationParameters instance (or one derived from it) should also be the one used by loadAndFilterTestExecutionListeners.
    2.Modify LauncherConfig.DEFAULT's initialization: LauncherConfig.DEFAULT could be initialized (lazily or at static init time) with a LauncherConfig instance that is built by consulting a globally accessible, pre-populated ConfigurationParameters instance (which itself loads from system properties, etc.). This would make LauncherConfig.DEFAULT inherently reflect external configuration. This might be a more breaking change.

this can helps people who use the IDEA or gradle integrated test runner to control behavior in LauncherConfig

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions