From eee427d22ee56336658001a4a8609a96d067d726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Sierszen=CC=81?= Date: Thu, 10 Mar 2022 11:27:13 +0100 Subject: [PATCH 1/5] [SUREFIRE-2037] Allow for surefire-junit-platform's TestMethodFilter to support custom TestSources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit o Non-breaking change, introduces a new SPI and a new output artifact with the SPI interface, resolving test names from custom test sources Signed-off-by: Krzysztof Sierszeń --- pom.xml | 5 +- .../api/testset/TestListResolver.java | 12 +- .../surefire-junit-platform/pom.xml | 41 +++++ .../junitplatform/JUnitPlatformProvider.java | 148 +++++++++--------- .../junitplatform/MethodSelectorFactory.java | 44 ++++++ .../junitplatform/TestSelectorFactory.java | 102 ++++++++++++ ...hodFilter.java => TestSelectorFilter.java} | 33 ++-- ...surefire.junitplatform.TestSelectorFactory | 1 + .../junitplatform/JUnit47SuiteTest.java | 2 +- ...rTest.java => TestSelectorFilterTest.java} | 24 +-- 10 files changed, 301 insertions(+), 111 deletions(-) create mode 100644 surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java create mode 100644 surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java rename surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/{TestMethodFilter.java => TestSelectorFilter.java} (60%) create mode 100644 surefire-providers/surefire-junit-platform/src/main/resources/META-INF/services/org.apache.maven.surefire.junitplatform.TestSelectorFactory rename surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/{TestMethodFilterTest.java => TestSelectorFilterTest.java} (92%) diff --git a/pom.xml b/pom.xml index 40c562c890..7730b3a896 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ~ KIND, either express or implied. See the License for the ~ specific language governing permissions and limitations - ~ under the License. + ~ under the License. --> @@ -532,8 +532,7 @@ src/test/resources/**/* src/test/resources/**/*.css **/*.jj - src/main/resources/META-INF/services/org.apache.maven.surefire.api.provider.SurefireProvider - + src/main/resources/META-INF/services/** DEPENDENCIES .m2/** .m2 diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/testset/TestListResolver.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/testset/TestListResolver.java index f8ebb1bdbc..5135f8bf69 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/api/testset/TestListResolver.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/testset/TestListResolver.java @@ -195,13 +195,13 @@ public boolean shouldRun( Class testClass, String methodName ) /** * Returns {@code true} if satisfies {@code testClassFile} and {@code methodName} filter. * - * @param testClassFile format must be e.g. "my/package/MyTest.class" including class extension; or null - * @param methodName real test-method name; or null + * @param containerName format must be e.g. "my/package/MyTest.class" including class extension; or null + * @param selectorName real test-method name; or null */ @Override - public boolean shouldRun( String testClassFile, String methodName ) + public boolean shouldRun( String containerName, String selectorName ) { - if ( isEmpty() || isBlank( testClassFile ) && isBlank( methodName ) ) + if ( isEmpty() || isBlank( containerName ) && isBlank( selectorName ) ) { return true; } @@ -217,7 +217,7 @@ public boolean shouldRun( String testClassFile, String methodName ) { for ( ResolvedTest filter : getIncludedPatterns() ) { - if ( filter.matchAsInclusive( testClassFile, methodName ) ) + if ( filter.matchAsInclusive( containerName, selectorName ) ) { shouldRun = true; break; @@ -229,7 +229,7 @@ public boolean shouldRun( String testClassFile, String methodName ) { for ( ResolvedTest filter : getExcludedPatterns() ) { - if ( filter.matchAsExclusive( testClassFile, methodName ) ) + if ( filter.matchAsExclusive( containerName, selectorName ) ) { shouldRun = false; break; diff --git a/surefire-providers/surefire-junit-platform/pom.xml b/surefire-providers/surefire-junit-platform/pom.xml index 264e9a3417..c785b5f1c7 100644 --- a/surefire-providers/surefire-junit-platform/pom.xml +++ b/surefire-providers/surefire-junit-platform/pom.xml @@ -136,6 +136,47 @@ + + org.apache.maven.plugins + maven-jar-plugin + + + api-jar + package + + jar + + + api + + org/apache/maven/surefire/junitplatform/TestSelectorFactory.class + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.2.0 + + + api-jar + + attach-artifact + + + + + api + jar + ${project.build.directory}/${project.artifactId}-${project.version}-api.jar + + + + + + diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java index 92385e5fcd..c574aacb5b 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java @@ -19,37 +19,6 @@ * under the License. */ -import static java.util.Arrays.stream; -import static java.util.Collections.emptyMap; -import static java.util.Optional.empty; -import static java.util.Optional.of; -import static java.util.logging.Level.WARNING; -import static java.util.stream.Collectors.toList; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.EXCLUDE_JUNIT5_ENGINES_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.INCLUDE_JUNIT5_ENGINES_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_GROUPS_PROP; -import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture; -import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN; -import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE; -import static org.apache.maven.surefire.api.util.TestsToRun.fromClass; -import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank; -import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; -import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId; -import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; - -import java.io.IOException; -import java.io.StringReader; -import java.io.UncheckedIOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import java.util.logging.Logger; - import org.apache.maven.surefire.api.provider.AbstractProvider; import org.apache.maven.surefire.api.provider.ProviderParameters; import org.apache.maven.surefire.api.report.ReporterException; @@ -70,13 +39,47 @@ import org.junit.platform.launcher.TestIdentifier; import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; +import java.io.IOException; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; +import java.util.ServiceLoader; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import static java.util.Arrays.stream; +import static java.util.Collections.emptyMap; +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static java.util.logging.Level.WARNING; +import static java.util.stream.Collectors.toList; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.EXCLUDE_JUNIT5_ENGINES_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.INCLUDE_JUNIT5_ENGINES_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_GROUPS_PROP; +import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture; +import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN; +import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE; +import static org.apache.maven.surefire.api.util.TestsToRun.fromClass; +import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId; +import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; + /** * JUnit 5 Platform Provider. * * @since 2.22.0 */ -public class JUnitPlatformProvider - extends AbstractProvider +public class JUnitPlatformProvider extends AbstractProvider { static final String CONFIGURATION_PARAMETERS = "configurationParameters"; @@ -105,7 +108,7 @@ public JUnitPlatformProvider( ProviderParameters parameters ) public Iterable> getSuites() { try - { + { return scanClasspath(); } finally @@ -115,8 +118,7 @@ public Iterable> getSuites() } @Override - public RunResult invoke( Object forkTestSet ) - throws TestSetFailedException, ReporterException + public RunResult invoke( Object forkTestSet ) throws TestSetFailedException, ReporterException { ReporterFactory reporterFactory = parameters.getReporterFactory(); final RunResult runResult; @@ -132,7 +134,7 @@ public RunResult invoke( Object forkTestSet ) } else if ( forkTestSet instanceof Class ) { - invokeAllTests( fromClass( ( Class ) forkTestSet ), adapter ); + invokeAllTests( fromClass( (Class) forkTestSet ), adapter ); } else if ( forkTestSet == null ) { @@ -140,8 +142,7 @@ else if ( forkTestSet == null ) } else { - throw new IllegalArgumentException( - "Unexpected value of forkTestSet: " + forkTestSet ); + throw new IllegalArgumentException( "Unexpected value of forkTestSet: " + forkTestSet ); } } finally @@ -189,7 +190,7 @@ private void invokeAllTests( TestsToRun testsToRun, RunListenerAdapter adapter ) { // Replace the "discoveryRequest" so that it only specifies the failing tests LauncherDiscoveryRequest discoveryRequest = - buildLauncherDiscoveryRequestForRerunFailures( adapter ); + buildLauncherDiscoveryRequestForRerunFailures( adapter ); // Reset adapter's recorded failures and invoke the failed tests again adapter.reset(); launcher.execute( discoveryRequest, adapter ); @@ -212,37 +213,32 @@ private void execute( TestsToRun testsToRun, RunListenerAdapter adapter ) if ( testsToRun.allowEagerReading() ) { List selectors = new ArrayList<>(); - testsToRun.iterator() - .forEachRemaining( c -> selectors.add( selectClass( c.getName() ) ) ); + testsToRun.iterator().forEachRemaining( c -> selectors.add( selectClass( c.getName() ) ) ); - LauncherDiscoveryRequestBuilder builder = request() - .filters( filters ) - .configurationParameters( configurationParameters ) - .selectors( selectors ); + LauncherDiscoveryRequestBuilder builder = + request().filters( filters ).configurationParameters( configurationParameters ).selectors( selectors ); launcher.execute( builder.build(), adapter ); } else { - testsToRun.iterator() - .forEachRemaining( c -> - { - LauncherDiscoveryRequestBuilder builder = request() - .filters( filters ) - .configurationParameters( configurationParameters ) + testsToRun.iterator().forEachRemaining( c -> + { + LauncherDiscoveryRequestBuilder builder = + request().filters( filters ).configurationParameters( configurationParameters ) .selectors( selectClass( c.getName() ) ); - launcher.execute( builder.build(), adapter ); - } ); + launcher.execute( builder.build(), adapter ); + } ); } } - + private void closeLauncher() { if ( launcher instanceof AutoCloseable ) { try { - ( (AutoCloseable) launcher ).close(); + ( ( AutoCloseable ) launcher ).close(); } catch ( Exception e ) { @@ -253,8 +249,8 @@ private void closeLauncher() private LauncherDiscoveryRequest buildLauncherDiscoveryRequestForRerunFailures( RunListenerAdapter adapter ) { - LauncherDiscoveryRequestBuilder builder = request().filters( filters ).configurationParameters( - configurationParameters ); + LauncherDiscoveryRequestBuilder builder = + request().filters( filters ).configurationParameters( configurationParameters ); // Iterate over recorded failures for ( TestIdentifier identifier : new LinkedHashSet<>( adapter.getFailures().keySet() ) ) { @@ -263,33 +259,31 @@ private LauncherDiscoveryRequest buildLauncherDiscoveryRequestForRerunFailures( return builder.build(); } + private Collection loadSelectorFactories() + { + return StreamSupport.stream( ServiceLoader.load( TestSelectorFactory.class ).spliterator(), false ) + .collect( Collectors.toSet() ); + } + private Filter[] newFilters() { List> filters = new ArrayList<>(); - getPropertiesList( TESTNG_GROUPS_PROP ) - .map( TagFilter::includeTags ) - .ifPresent( filters::add ); + getPropertiesList( TESTNG_GROUPS_PROP ).map( TagFilter::includeTags ).ifPresent( filters::add ); - getPropertiesList( TESTNG_EXCLUDEDGROUPS_PROP ) - .map( TagFilter::excludeTags ) - .ifPresent( filters::add ); + getPropertiesList( TESTNG_EXCLUDEDGROUPS_PROP ).map( TagFilter::excludeTags ).ifPresent( filters::add ); TestListResolver testListResolver = parameters.getTestRequest().getTestListResolver(); if ( !testListResolver.isEmpty() ) { - filters.add( new TestMethodFilter( testListResolver ) ); + filters.add( new TestSelectorFilter( testListResolver, loadSelectorFactories() ) ); } - getPropertiesList( INCLUDE_JUNIT5_ENGINES_PROP ) - .map( EngineFilter::includeEngines ) - .ifPresent( filters::add ); + getPropertiesList( INCLUDE_JUNIT5_ENGINES_PROP ).map( EngineFilter::includeEngines ).ifPresent( filters::add ); - getPropertiesList( EXCLUDE_JUNIT5_ENGINES_PROP ) - .map( EngineFilter::excludeEngines ) - .ifPresent( filters::add ); + getPropertiesList( EXCLUDE_JUNIT5_ENGINES_PROP ).map( EngineFilter::excludeEngines ).ifPresent( filters::add ); - return filters.toArray( new Filter[ filters.size() ] ); + return filters.toArray( new Filter[0] ); } Filter[] getFilters() @@ -309,8 +303,7 @@ private Map newConfigurationParameters() Map result = new HashMap<>(); Properties props = new Properties(); props.load( reader ); - props.stringPropertyNames() - .forEach( key -> result.put( key, props.getProperty( key ) ) ); + props.stringPropertyNames().forEach( key -> result.put( key, props.getProperty( key ) ) ); return result; } catch ( IOException e ) @@ -328,9 +321,8 @@ private Optional> getPropertiesList( String key ) { String property = parameters.getProviderProperties().get( key ); return isBlank( property ) ? empty() - : of( stream( property.split( "[,]+" ) ) - .filter( StringUtils::isNotBlank ) - .map( String::trim ) - .collect( toList() ) ); + : of( stream( property.split( "[,]+" ) ) + .filter( StringUtils::isNotBlank ) + .map( String::trim ).collect( toList() ) ); } } diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java new file mode 100644 index 0000000000..83f5f599b4 --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java @@ -0,0 +1,44 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.MethodSource; + +class MethodSelectorFactory implements TestSelectorFactory +{ + @Override + public boolean supports( TestSource source ) + { + return source instanceof MethodSource; + } + + @Override + public String getContainerName( TestSource source ) + { + return ( ( MethodSource ) source ).getClassName(); + } + + @Override + public String getSelectorName( TestSource source ) + { + return ( ( MethodSource ) source ).getMethodName(); + } +} diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java new file mode 100644 index 0000000000..c38de4abab --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java @@ -0,0 +1,102 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.surefire.api.testset.TestListResolver; +import org.junit.platform.engine.TestSource; + +import java.util.Objects; + +/** + * A test selector factory used in combination with a {@link org.apache.maven.surefire.api.testset.TestListResolver} + * to determine whether a given {@link org.junit.platform.engine.TestSource} should be considered for running. + * + *

This is a service provider interface; clients may provide their own implementations + * that will be applied along the default {@link MethodSelectorFactory}

+ */ +public interface TestSelectorFactory +{ + + boolean supports( TestSource source ); + + String getContainerName( TestSource source ); + + String getSelectorName( TestSource source ); + + default boolean isClassContainer() + { + return true; + } + + default TestSelector createSelector( TestSource source ) + { + String containerName = getContainerName( source ); + return new TestSelector( + isClassContainer() ? TestListResolver.toClassFileName( containerName ) : containerName, + getSelectorName( source ) ); + } + + /** + * Represents a single test case selector + * (e.g. a fully-qualified class name + test-annotated method name) + */ + class TestSelector + { + private final String containerName; + private final String selectorName; + + public TestSelector( String containerName, String selectorName ) + { + this.containerName = containerName; + this.selectorName = selectorName; + } + + public String getContainerName() + { + return containerName; + } + + public String getSelectorName() + { + return selectorName; + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + TestSelector that = ( TestSelector ) o; + return containerName.equals( that.containerName ) && Objects.equals( selectorName, that.selectorName ); + } + + @Override + public int hashCode() + { + return Objects.hash( containerName, selectorName ); + } + } +} diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestMethodFilter.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFilter.java similarity index 60% rename from surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestMethodFilter.java rename to surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFilter.java index d766ffdd27..4513008619 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestMethodFilter.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFilter.java @@ -22,39 +22,48 @@ import org.apache.maven.surefire.api.testset.TestListResolver; import org.junit.platform.engine.FilterResult; import org.junit.platform.engine.TestDescriptor; -import org.junit.platform.engine.support.descriptor.MethodSource; +import org.junit.platform.engine.TestSource; import org.junit.platform.launcher.PostDiscoveryFilter; +import java.util.Collection; +import java.util.Optional; + /** * @since 2.22.0 */ -class TestMethodFilter +class TestSelectorFilter implements PostDiscoveryFilter { private final TestListResolver testListResolver; + private final Collection selectorFactories; - TestMethodFilter( TestListResolver testListResolver ) + TestSelectorFilter( TestListResolver testListResolver, Collection selectorFactories ) { this.testListResolver = testListResolver; + this.selectorFactories = selectorFactories; } @Override public FilterResult apply( TestDescriptor descriptor ) { boolean shouldRun = descriptor.getSource() - .filter( MethodSource.class::isInstance ) - .map( MethodSource.class::cast ) - .map( this::shouldRun ) - .orElse( true ); - + .flatMap( source -> resolveFactory( source ) + .map( factory -> factory.createSelector( source ) ) ) + .map( this::shouldRun ) + .orElse( true ); return FilterResult.includedIf( shouldRun ); } - private boolean shouldRun( MethodSource source ) + private boolean shouldRun( TestSelectorFactory.TestSelector selector ) + { + return this.testListResolver.shouldRun( selector.getContainerName(), selector.getSelectorName() ); + } + + private Optional resolveFactory( TestSource source ) { - String testClass = TestListResolver.toClassFileName( source.getClassName() ); - String testMethod = source.getMethodName(); - return this.testListResolver.shouldRun( testClass, testMethod ); + return selectorFactories.stream() + .filter( factory -> factory.supports( source ) ) + .findAny(); } } diff --git a/surefire-providers/surefire-junit-platform/src/main/resources/META-INF/services/org.apache.maven.surefire.junitplatform.TestSelectorFactory b/surefire-providers/surefire-junit-platform/src/main/resources/META-INF/services/org.apache.maven.surefire.junitplatform.TestSelectorFactory new file mode 100644 index 0000000000..f02d320f19 --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/main/resources/META-INF/services/org.apache.maven.surefire.junitplatform.TestSelectorFactory @@ -0,0 +1 @@ +org.apache.maven.surefire.junitplatform.MethodSelectorFactory diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnit47SuiteTest.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnit47SuiteTest.java index 7db25c9b20..1b4c8f3c13 100644 --- a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnit47SuiteTest.java +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnit47SuiteTest.java @@ -36,7 +36,7 @@ public static Test suite() TestSuite suite = new TestSuite(); suite.addTest( new JUnit4TestAdapter( JUnitPlatformProviderTest.class ) ); suite.addTest( new JUnit4TestAdapter( RunListenerAdapterTest.class ) ); - suite.addTest( new JUnit4TestAdapter( TestMethodFilterTest.class ) ); + suite.addTest( new JUnit4TestAdapter( TestSelectorFilterTest.class ) ); suite.addTest( new JUnit4TestAdapter( TestPlanScannerFilterTest.class ) ); return suite; } diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestMethodFilterTest.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestSelectorFilterTest.java similarity index 92% rename from surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestMethodFilterTest.java rename to surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestSelectorFilterTest.java index 33f14e9afd..32cbf07731 100644 --- a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestMethodFilterTest.java +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestSelectorFilterTest.java @@ -19,14 +19,6 @@ * under the License. */ -import static org.apache.maven.surefire.api.testset.TestListResolver.toClassFileName; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.lang.reflect.Method; - import org.apache.maven.surefire.api.testset.TestListResolver; import org.junit.Test; import org.junit.jupiter.engine.descriptor.ClassTestDescriptor; @@ -35,18 +27,28 @@ import org.junit.platform.engine.FilterResult; import org.junit.platform.engine.UniqueId; +import java.lang.reflect.Method; + +import static java.util.Collections.singletonList; +import static org.apache.maven.surefire.api.testset.TestListResolver.toClassFileName; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + /** - * Unit tests for {@link TestMethodFilter}. + * Unit tests for {@link TestSelectorFilter}. * * @since 2.22.0 */ -public class TestMethodFilterTest +public class TestSelectorFilterTest { private static final ConfigurationParameters CONFIG_PARAMS = mock( ConfigurationParameters.class ); private final TestListResolver resolver = mock( TestListResolver.class ); - private final TestMethodFilter filter = new TestMethodFilter( this.resolver ); + private final TestSelectorFilter filter + = new TestSelectorFilter( this.resolver, singletonList( new MethodSelectorFactory() ) ); @Test public void includesBasedOnTestListResolver() From 2ed1d7a300f7420e47c1b760b7e30286003146bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Sierszen=CC=81?= Date: Thu, 10 Mar 2022 15:08:31 +0100 Subject: [PATCH 2/5] [SUREFIRE-2037] Fixed javadoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Sierszeń --- .../maven/surefire/junitplatform/TestSelectorFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java index c38de4abab..01261970c9 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestSelectorFactory.java @@ -28,7 +28,7 @@ * A test selector factory used in combination with a {@link org.apache.maven.surefire.api.testset.TestListResolver} * to determine whether a given {@link org.junit.platform.engine.TestSource} should be considered for running. * - *

This is a service provider interface; clients may provide their own implementations + *

This is a service provider interface; clients may provide their own implementations * that will be applied along the default {@link MethodSelectorFactory}

*/ public interface TestSelectorFactory From b015befa286d386bcc9e267e70338b401ee12c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Sierszen=CC=81?= Date: Thu, 10 Mar 2022 16:54:58 +0100 Subject: [PATCH 3/5] Fixed SPI impl visibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Sierszeń --- .../maven/surefire/junitplatform/MethodSelectorFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java index 83f5f599b4..35b247f228 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java @@ -22,7 +22,7 @@ import org.junit.platform.engine.TestSource; import org.junit.platform.engine.support.descriptor.MethodSource; -class MethodSelectorFactory implements TestSelectorFactory +public class MethodSelectorFactory implements TestSelectorFactory { @Override public boolean supports( TestSource source ) From 318467a28349044ea09685f53bf0f35cccce9419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Sierszen=CC=81?= Date: Thu, 10 Mar 2022 16:59:22 +0100 Subject: [PATCH 4/5] [SUREFIRE-2037] Fixed javadoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Sierszeń --- .../maven/surefire/junitplatform/MethodSelectorFactory.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java index 35b247f228..6754d6e4d0 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/MethodSelectorFactory.java @@ -22,6 +22,9 @@ import org.junit.platform.engine.TestSource; import org.junit.platform.engine.support.descriptor.MethodSource; +/** + * The default implementation for {@link TestSelectorFactory}, recognizing instances of {@link MethodSource} + */ public class MethodSelectorFactory implements TestSelectorFactory { @Override From 8c2dac0c14b0bd940d52e59ffddfcdb8035631b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Sierszen=CC=81?= Date: Fri, 11 Mar 2022 19:04:04 +0100 Subject: [PATCH 5/5] [SUREFIRE-2037] Fixed formatting --- .../junitplatform/JUnitPlatformProvider.java | 140 ++++++++++-------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java index c574aacb5b..e27c0fd1d2 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java @@ -19,6 +19,41 @@ * under the License. */ +import static java.util.Arrays.stream; +import static java.util.Collections.emptyMap; +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static java.util.logging.Level.WARNING; +import static java.util.stream.Collectors.toList; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.EXCLUDE_JUNIT5_ENGINES_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.INCLUDE_JUNIT5_ENGINES_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP; +import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_GROUPS_PROP; +import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture; +import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN; +import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE; +import static org.apache.maven.surefire.api.util.TestsToRun.fromClass; +import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId; +import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; + +import java.io.IOException; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; +import java.util.ServiceLoader; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + import org.apache.maven.surefire.api.provider.AbstractProvider; import org.apache.maven.surefire.api.provider.ProviderParameters; import org.apache.maven.surefire.api.report.ReporterException; @@ -39,47 +74,13 @@ import org.junit.platform.launcher.TestIdentifier; import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; -import java.io.IOException; -import java.io.StringReader; -import java.io.UncheckedIOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import java.util.ServiceLoader; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import static java.util.Arrays.stream; -import static java.util.Collections.emptyMap; -import static java.util.Optional.empty; -import static java.util.Optional.of; -import static java.util.logging.Level.WARNING; -import static java.util.stream.Collectors.toList; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.EXCLUDE_JUNIT5_ENGINES_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.INCLUDE_JUNIT5_ENGINES_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP; -import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_GROUPS_PROP; -import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture; -import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN; -import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE; -import static org.apache.maven.surefire.api.util.TestsToRun.fromClass; -import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank; -import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; -import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId; -import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; - /** * JUnit 5 Platform Provider. * * @since 2.22.0 */ -public class JUnitPlatformProvider extends AbstractProvider +public class JUnitPlatformProvider + extends AbstractProvider { static final String CONFIGURATION_PARAMETERS = "configurationParameters"; @@ -118,7 +119,8 @@ public Iterable> getSuites() } @Override - public RunResult invoke( Object forkTestSet ) throws TestSetFailedException, ReporterException + public RunResult invoke( Object forkTestSet ) + throws TestSetFailedException, ReporterException { ReporterFactory reporterFactory = parameters.getReporterFactory(); final RunResult runResult; @@ -134,7 +136,7 @@ public RunResult invoke( Object forkTestSet ) throws TestSetFailedException, Rep } else if ( forkTestSet instanceof Class ) { - invokeAllTests( fromClass( (Class) forkTestSet ), adapter ); + invokeAllTests( fromClass( ( Class ) forkTestSet ), adapter ); } else if ( forkTestSet == null ) { @@ -142,7 +144,8 @@ else if ( forkTestSet == null ) } else { - throw new IllegalArgumentException( "Unexpected value of forkTestSet: " + forkTestSet ); + throw new IllegalArgumentException( + "Unexpected value of forkTestSet: " + forkTestSet ); } } finally @@ -190,7 +193,7 @@ private void invokeAllTests( TestsToRun testsToRun, RunListenerAdapter adapter ) { // Replace the "discoveryRequest" so that it only specifies the failing tests LauncherDiscoveryRequest discoveryRequest = - buildLauncherDiscoveryRequestForRerunFailures( adapter ); + buildLauncherDiscoveryRequestForRerunFailures( adapter ); // Reset adapter's recorded failures and invoke the failed tests again adapter.reset(); launcher.execute( discoveryRequest, adapter ); @@ -213,22 +216,27 @@ private void execute( TestsToRun testsToRun, RunListenerAdapter adapter ) if ( testsToRun.allowEagerReading() ) { List selectors = new ArrayList<>(); - testsToRun.iterator().forEachRemaining( c -> selectors.add( selectClass( c.getName() ) ) ); + testsToRun.iterator() + .forEachRemaining( c -> selectors.add( selectClass( c.getName() ) ) ); - LauncherDiscoveryRequestBuilder builder = - request().filters( filters ).configurationParameters( configurationParameters ).selectors( selectors ); + LauncherDiscoveryRequestBuilder builder = request() + .filters( filters ) + .configurationParameters( configurationParameters ) + .selectors( selectors ); launcher.execute( builder.build(), adapter ); } else { - testsToRun.iterator().forEachRemaining( c -> - { - LauncherDiscoveryRequestBuilder builder = - request().filters( filters ).configurationParameters( configurationParameters ) + testsToRun.iterator() + .forEachRemaining( c -> + { + LauncherDiscoveryRequestBuilder builder = request() + .filters( filters ) + .configurationParameters( configurationParameters ) .selectors( selectClass( c.getName() ) ); - launcher.execute( builder.build(), adapter ); - } ); + launcher.execute( builder.build(), adapter ); + } ); } } @@ -238,7 +246,7 @@ private void closeLauncher() { try { - ( ( AutoCloseable ) launcher ).close(); + ( (AutoCloseable) launcher ).close(); } catch ( Exception e ) { @@ -249,8 +257,8 @@ private void closeLauncher() private LauncherDiscoveryRequest buildLauncherDiscoveryRequestForRerunFailures( RunListenerAdapter adapter ) { - LauncherDiscoveryRequestBuilder builder = - request().filters( filters ).configurationParameters( configurationParameters ); + LauncherDiscoveryRequestBuilder builder = request().filters( filters ).configurationParameters( + configurationParameters ); // Iterate over recorded failures for ( TestIdentifier identifier : new LinkedHashSet<>( adapter.getFailures().keySet() ) ) { @@ -269,9 +277,13 @@ private Filter[] newFilters() { List> filters = new ArrayList<>(); - getPropertiesList( TESTNG_GROUPS_PROP ).map( TagFilter::includeTags ).ifPresent( filters::add ); + getPropertiesList( TESTNG_GROUPS_PROP ) + .map( TagFilter::includeTags ) + .ifPresent( filters::add ); - getPropertiesList( TESTNG_EXCLUDEDGROUPS_PROP ).map( TagFilter::excludeTags ).ifPresent( filters::add ); + getPropertiesList( TESTNG_EXCLUDEDGROUPS_PROP ) + .map( TagFilter::excludeTags ) + .ifPresent( filters::add ); TestListResolver testListResolver = parameters.getTestRequest().getTestListResolver(); if ( !testListResolver.isEmpty() ) @@ -279,11 +291,15 @@ private Filter[] newFilters() filters.add( new TestSelectorFilter( testListResolver, loadSelectorFactories() ) ); } - getPropertiesList( INCLUDE_JUNIT5_ENGINES_PROP ).map( EngineFilter::includeEngines ).ifPresent( filters::add ); + getPropertiesList( INCLUDE_JUNIT5_ENGINES_PROP ) + .map( EngineFilter::includeEngines ) + .ifPresent( filters::add ); - getPropertiesList( EXCLUDE_JUNIT5_ENGINES_PROP ).map( EngineFilter::excludeEngines ).ifPresent( filters::add ); + getPropertiesList( EXCLUDE_JUNIT5_ENGINES_PROP ) + .map( EngineFilter::excludeEngines ) + .ifPresent( filters::add ); - return filters.toArray( new Filter[0] ); + return filters.toArray( new Filter[ 0 ] ); } Filter[] getFilters() @@ -303,7 +319,8 @@ private Map newConfigurationParameters() Map result = new HashMap<>(); Properties props = new Properties(); props.load( reader ); - props.stringPropertyNames().forEach( key -> result.put( key, props.getProperty( key ) ) ); + props.stringPropertyNames() + .forEach( key -> result.put( key, props.getProperty( key ) ) ); return result; } catch ( IOException e ) @@ -321,8 +338,9 @@ private Optional> getPropertiesList( String key ) { String property = parameters.getProviderProperties().get( key ); return isBlank( property ) ? empty() - : of( stream( property.split( "[,]+" ) ) - .filter( StringUtils::isNotBlank ) - .map( String::trim ).collect( toList() ) ); + : of( stream( property.split( "[,]+" ) ) + .filter( StringUtils::isNotBlank ) + .map( String::trim ) + .collect( toList() ) ); } }