This is an automated email from the ASF dual-hosted git repository. tibordigana pushed a commit to branch release/2.22.3 in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
commit f5aeff8e2ee79d321e3acc1a25779d1bdd439d62 Author: tibordigana <tibordig...@apache.org> AuthorDate: Fri Apr 8 17:37:49 2022 +0200 [SUREFIRE-1964] Support for method filtering on excludesFile and includesFile committers: Ildefonso Montero, Tibor Digaňa Add the implementation and integration tests Add some unit tests Add some javadoc to includesFile and excludesFile --- .../maven/plugin/failsafe/IntegrationTestMojo.java | 14 +++ .../plugin/surefire/AbstractSurefireMojo.java | 127 +++++++++++++-------- .../maven/plugin/surefire/MojoMocklessTest.java | 6 + .../maven/plugin/surefire/SurefirePlugin.java | 16 ++- .../its/AbstractTestMultipleMethodPatterns.java | 3 +- .../maven/surefire/its/jiras/Surefire1964IT.java | 55 +++++++++ .../test/resources/surefire-1964/exclusions.txt | 1 + .../test/resources/surefire-1964/inclusions.txt | 1 + .../src/test/resources/surefire-1964/pom.xml | 58 ++++++++++ .../src/test/java/pkg/ExcludedTest.java | 12 ++ .../src/test/java/pkg/FilterTest.java | 24 ++++ 11 files changed, 268 insertions(+), 49 deletions(-) diff --git a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java index 51414cf75..1ddc8eec5 100644 --- a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java +++ b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java @@ -322,6 +322,13 @@ public class IntegrationTestMojo * **{@literal /}NotIncludedByDefault.java * %regex[.*IT.*|.*Not.*] * </code></pre> + * <br> + * Since 2.22.3, method filtering support is provided in the inclusions file as well, example: + * <pre><code> + * pkg.SomeIT#testMethod + * </code></pre> + * + * @since 2.13 */ @Parameter( property = "failsafe.includesFile" ) private File includesFile; @@ -335,6 +342,13 @@ public class IntegrationTestMojo * **{@literal /}DontRunIT.* * %regex[.*IT.*|.*Not.*] * </code></pre> + * <br> + * Since 2.22.3, method filtering support is provided in the exclusions file as well, example: + * <pre><code> + * pkg.SomeIT#testMethod + * </code></pre> + * + * @since 2.13 */ @Parameter( property = "failsafe.excludesFile" ) private File excludesFile; diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java index 2aa6dd405..9881cb747 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java @@ -861,6 +861,11 @@ public abstract class AbstractSurefireMojo } } + void setLogger( Logger logger ) + { + this.logger = logger; + } + @Nonnull protected final PluginConsoleLogger getConsoleLogger() { @@ -1939,78 +1944,110 @@ public abstract class AbstractSurefireMojo } } - private void maybeAppendList( List<String> base, List<String> list ) + @Nonnull + private List<String> getExcludedScanList() + throws MojoFailureException { - if ( list != null ) - { - base.addAll( list ); - } + return getExcludeList( true ); + } + + @Nonnull + private List<String> getExcludeList() + throws MojoFailureException + { + return getExcludeList( false ); } - @Nonnull private List<String> getExcludeList() + /** + * Computes a merge list of test exclusions. + * Used only in {@link #getExcludeList()} and {@link #getExcludedScanList()}. + * @param asScanList true if dependency or directory scanner + * @return list of patterns + * @throws MojoFailureException if the excludes breaks a pattern format + */ + @Nonnull + private List<String> getExcludeList( boolean asScanList ) throws MojoFailureException { - List<String> actualExcludes = null; + List<String> excludes; if ( isSpecificTestSpecified() ) { - actualExcludes = Collections.emptyList(); + excludes = Collections.emptyList(); } else { - if ( getExcludesFile() != null ) + excludes = new ArrayList<String>(); + if ( asScanList ) { - actualExcludes = readListFromFile( getExcludesFile() ); + if ( getExcludes() != null ) + { + excludes.addAll( getExcludes() ); + } + checkMethodFilterInIncludesExcludes( excludes ); } - if ( actualExcludes == null ) - { - actualExcludes = getExcludes(); - } - else + if ( getExcludesFile() != null ) { - maybeAppendList( actualExcludes, getExcludes() ); + excludes.addAll( readListFromFile( getExcludesFile() ) ); } - checkMethodFilterInIncludesExcludes( actualExcludes ); - - if ( actualExcludes == null || actualExcludes.isEmpty() ) + if ( asScanList && excludes.isEmpty() ) { - actualExcludes = Collections.singletonList( getDefaultExcludes() ); + excludes = singletonList( getDefaultExcludes() ); } } - return filterNulls( actualExcludes ); + return filterNulls( excludes ); } + @Nonnull + private List<String> getIncludedScanList() + throws MojoFailureException + { + return getIncludeList( true ); + } + + @Nonnull private List<String> getIncludeList() throws MojoFailureException { - List<String> includes = null; + return getIncludeList( false ); + } + + /** + * Computes a merge list of test inclusions. + * Used only in {@link #getIncludeList()} and {@link #getIncludedScanList()}. + * @param asScanList true if dependency or directory scanner + * @return list of patterns + * @throws MojoFailureException if the includes breaks a pattern format + */ + @Nonnull + private List<String> getIncludeList( boolean asScanList ) + throws MojoFailureException + { + final List<String> includes = new ArrayList<String>(); if ( isSpecificTestSpecified() ) { - includes = new ArrayList<String>(); addAll( includes, split( getTest(), "," ) ); } else { - if ( getIncludesFile() != null ) + if ( asScanList ) { - includes = readListFromFile( getIncludesFile() ); + if ( getIncludes() != null ) + { + includes.addAll( getIncludes() ); + } + checkMethodFilterInIncludesExcludes( includes ); } - if ( includes == null ) - { - includes = getIncludes(); - } - else + if ( getIncludesFile() != null ) { - maybeAppendList( includes, getIncludes() ); + includes.addAll( readListFromFile( getIncludesFile() ) ); } - checkMethodFilterInIncludesExcludes( includes ); - - if ( includes == null || includes.isEmpty() ) + if ( asScanList && includes.isEmpty() ) { - includes = asList( getDefaultIncludes() ); + addAll( includes, getDefaultIncludes() ); } } @@ -2020,16 +2057,12 @@ public abstract class AbstractSurefireMojo private void checkMethodFilterInIncludesExcludes( Iterable<String> patterns ) throws MojoFailureException { - if ( patterns != null ) + for ( String pattern : patterns ) { - for ( String pattern : patterns ) + if ( pattern != null && pattern.contains( "#" ) ) { - if ( pattern != null && pattern.contains( "#" ) ) - { - throw new MojoFailureException( "Method filter prohibited in " - + "includes|excludes|includesFile|excludesFile parameter: " - + pattern ); - } + throw new MojoFailureException( "Method filter prohibited in includes|excludes parameter: " + + pattern ); } } } @@ -2039,16 +2072,18 @@ public abstract class AbstractSurefireMojo { if ( includedExcludedTests == null ) { - includedExcludedTests = new TestListResolver( getIncludeList(), getExcludeList() ); + includedExcludedTests = new TestListResolver( getIncludedScanList(), getExcludedScanList() ); + getConsoleLogger().debug( "Resolved included and excluded patterns: " + includedExcludedTests ); } return includedExcludedTests; } public TestListResolver getSpecificTests() + throws MojoFailureException { if ( specificTests == null ) { - specificTests = new TestListResolver( getTest() ); + specificTests = new TestListResolver( getIncludeList(), getExcludeList() ); } return specificTests; } @@ -2554,7 +2589,7 @@ public abstract class AbstractSurefireMojo if ( filteredArtifact != null ) { filter = new ExcludesArtifactFilter( - Collections.singletonList( filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId() ) ); + singletonList( filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId() ) ); } Artifact originatingArtifact = getArtifactFactory().createBuildArtifact( "dummy", "dummy", "1.0", "jar" ); diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java index 91589a2f6..2ecfdae84 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java @@ -28,6 +28,7 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.surefire.suite.RunResult; import org.apache.maven.surefire.util.DefaultScanResult; +import org.codehaus.plexus.logging.Logger; import org.junit.Test; import java.io.File; @@ -39,6 +40,7 @@ import java.util.zip.ZipOutputStream; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; public class MojoMocklessTest { @@ -121,6 +123,7 @@ public class MojoMocklessTest List<Artifact> projectTestArtifacts = singletonList( testDeps ); String[] dependenciesToScan = { "g:a" }; Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan ); + mojo.setLogger( mock( Logger.class ) ); DefaultScanResult result = mojo.scanDependencies(); assertThat( result ) @@ -152,6 +155,7 @@ public class MojoMocklessTest List<Artifact> projectTestArtifacts = singletonList( testDeps ); String[] dependenciesToScan = { "g:a" }; Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan ); + mojo.setLogger( mock( Logger.class ) ); DefaultScanResult result = mojo.scanDependencies(); assertThat( result ) @@ -183,6 +187,7 @@ public class MojoMocklessTest List<Artifact> projectTestArtifacts = singletonList( testDeps ); String[] dependenciesToScan = { "g:a" }; Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan ); + mojo.setLogger( mock( Logger.class ) ); DefaultScanResult result = mojo.scanDependencies(); assertThat( result ) @@ -228,6 +233,7 @@ public class MojoMocklessTest List<Artifact> projectTestArtifacts = asList( testDep1, testDep2 ); String[] dependenciesToScan = { "g:a" }; Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan ); + mojo.setLogger( mock( Logger.class ) ); DefaultScanResult result = mojo.scanDependencies(); assertThat( result ) diff --git a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java index 09a566144..bef35e2c4 100644 --- a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java +++ b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java @@ -302,6 +302,13 @@ public class SurefirePlugin * **{@literal /}NotIncludedByDefault.java * %regex[.*Test.*|.*Not.*] * </code></pre> + * <br> + * Since 2.22.3, method filtering support is provided in the inclusions file as well, example: + * <pre><code> + * pkg.SomeTest#testMethod + * </code></pre> + * + * @since 2.13 */ @Parameter( property = "surefire.includesFile" ) private File includesFile; @@ -314,6 +321,13 @@ public class SurefirePlugin * **{@literal /}DontRunTest.* * %regex[.*Test.*|.*Not.*] * </code></pre> + * + * Since 2.22.3, method filtering support is provided in the exclusions file as well, example: + * <pre><code> + * pkg.SomeTest#testMethod + * </code></pre> + * + * @since 2.13 */ @Parameter( property = "surefire.excludesFile" ) private File excludesFile; @@ -394,7 +408,7 @@ public class SurefirePlugin final Map<String, Artifact> pluginArtifactMap = getPluginArtifactMap(); return pluginArtifactMap.get( "org.apache.maven.plugins:maven-surefire-plugin" ); } - + // now for the implementation of the field accessors @Override diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/AbstractTestMultipleMethodPatterns.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/AbstractTestMultipleMethodPatterns.java index 01932facf..679df4df8 100644 --- a/surefire-its/src/test/java/org/apache/maven/surefire/its/AbstractTestMultipleMethodPatterns.java +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/AbstractTestMultipleMethodPatterns.java @@ -477,7 +477,6 @@ public abstract class AbstractTestMultipleMethodPatterns prepare( pattern ) .failNever() .executeTest() - .verifyTextInLog( "Method filter prohibited in includes|excludes|includesFile|excludesFile parameter: " - + pattern ); + .verifyTextInLog( "Method filter prohibited in includes|excludes parameter: " + pattern ); } } diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1964IT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1964IT.java new file mode 100644 index 000000000..62f60d25c --- /dev/null +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1964IT.java @@ -0,0 +1,55 @@ +package org.apache.maven.surefire.its.jiras; + +/* + * 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.its.fixture.SurefireJUnit4IntegrationTestCase; +import org.junit.Test; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +/** + * + */ +public class Surefire1964IT extends SurefireJUnit4IntegrationTestCase +{ + @Test + public void shouldFilterTests() throws Exception + { + unpack( "surefire-1964" ) + .executeTest() + .assertTestSuiteResults( 1 ) + .assertThatLogLine( containsString( "executed testXYZ" ), is( 1 ) ) + .assertThatLogLine( containsString( "executed testABC" ), is( 0 ) ) + .assertThatLogLine( containsString( "executed dontRun" ), is( 0 ) ); + } + + @Test + public void shouldFilterTestsInPluginProcess() throws Exception + { + unpack( "surefire-1964" ) + .forkCount( 0 ) + .executeTest() + .assertTestSuiteResults( 1 ) + .assertThatLogLine( containsString( "executed testXYZ" ), is( 1 ) ) + .assertThatLogLine( containsString( "executed testABC" ), is( 0 ) ) + .assertThatLogLine( containsString( "executed dontRun" ), is( 0 ) ); + } +} diff --git a/surefire-its/src/test/resources/surefire-1964/exclusions.txt b/surefire-its/src/test/resources/surefire-1964/exclusions.txt new file mode 100644 index 000000000..5bacad2ca --- /dev/null +++ b/surefire-its/src/test/resources/surefire-1964/exclusions.txt @@ -0,0 +1 @@ +FilterTest#testABC \ No newline at end of file diff --git a/surefire-its/src/test/resources/surefire-1964/inclusions.txt b/surefire-its/src/test/resources/surefire-1964/inclusions.txt new file mode 100644 index 000000000..50077e4c4 --- /dev/null +++ b/surefire-its/src/test/resources/surefire-1964/inclusions.txt @@ -0,0 +1 @@ +FilterTest#test* \ No newline at end of file diff --git a/surefire-its/src/test/resources/surefire-1964/pom.xml b/surefire-its/src/test/resources/surefire-1964/pom.xml new file mode 100644 index 000000000..8f3ba2938 --- /dev/null +++ b/surefire-its/src/test/resources/surefire-1964/pom.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.example</groupId> + <artifactId>maven-surefire-excludefiles</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <maven.compiler.source>${java.specification.version}</maven.compiler.source> + <maven.compiler.target>${java.specification.version}</maven.compiler.target> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.2</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + <configuration> + <includesFile>inclusions.txt</includesFile> + <excludesFile>exclusions.txt</excludesFile> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/surefire-its/src/test/resources/surefire-1964/src/test/java/pkg/ExcludedTest.java b/surefire-its/src/test/resources/surefire-1964/src/test/java/pkg/ExcludedTest.java new file mode 100644 index 000000000..b871231ef --- /dev/null +++ b/surefire-its/src/test/resources/surefire-1964/src/test/java/pkg/ExcludedTest.java @@ -0,0 +1,12 @@ +package pkg; + +import org.junit.Test; + +public class ExcludedTest +{ + @Test + public void dontRun() + { + System.out.println( "executed dontRun" ); + } +} diff --git a/surefire-its/src/test/resources/surefire-1964/src/test/java/pkg/FilterTest.java b/surefire-its/src/test/resources/surefire-1964/src/test/java/pkg/FilterTest.java new file mode 100644 index 000000000..d93eca929 --- /dev/null +++ b/surefire-its/src/test/resources/surefire-1964/src/test/java/pkg/FilterTest.java @@ -0,0 +1,24 @@ +package pkg; + +import org.junit.Test; + +public class FilterTest +{ + @Test + public void testABC() + { + System.out.println( "executed testABC" ); + } + + @Test + public void dontRun() + { + System.out.println( "executed dontRun" ); + } + + @Test + public void testXYZ() + { + System.out.println( "executed testXYZ" ); + } +}