You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2018/05/05 22:33:06 UTC

[maven-surefire] branch 1383 created (now 0452ec7)

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a change to branch 1383
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git.


      at 0452ec7  [SUREFIRE-1383] dependenciesToScan Does Not Leverage Classpath Elements

This branch includes the following new commits:

     new 0452ec7  [SUREFIRE-1383] dependenciesToScan Does Not Leverage Classpath Elements

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
tibordigana@apache.org.

[maven-surefire] 01/01: [SUREFIRE-1383] dependenciesToScan Does Not Leverage Classpath Elements

Posted by ti...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch 1383
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit 0452ec73c8e46c96619e89a16e1d463c43081198
Author: Tibor17 <ti...@apache.org>
AuthorDate: Sun May 6 00:32:49 2018 +0200

    [SUREFIRE-1383] dependenciesToScan Does Not Leverage Classpath Elements
---
 .../plugin/surefire/AbstractSurefireMojo.java      |  53 +-
 .../plugin/surefire/util/DependencyScanner.java    |  50 +-
 .../maven/plugin/surefire/util/ScannerUtil.java    |   5 +
 .../maven/plugin/surefire/MojoMocklessTest.java    | 625 +++++++++++++++++++++
 .../surefire/util/DependenciesScannerTest.java     |   9 +-
 .../plugin/surefire/util/ScannerUtilTest.java}     |  38 +-
 .../org/apache/maven/surefire/JUnit4SuiteTest.java |   4 +
 .../maven/surefire/booter/SystemUtilsTest.java     |   4 +-
 .../Surefire1383ScanSessionDependenciesIT.java     |  42 +-
 .../src/test/resources/surefire-1383/pom.xml       |  45 ++
 .../test/resources/surefire-1383/runner/pom.xml    |  39 ++
 .../src/main/java/pkg/DynamicRunningTest.java      |  30 +-
 .../src/test/resources/surefire-1383/sut/pom.xml   |  56 ++
 .../apache/maven/surefire/junitcore/TestSet.java   |   8 +-
 14 files changed, 904 insertions(+), 104 deletions(-)

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 34f805a..d99cbac 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
@@ -115,9 +115,11 @@ import java.util.concurrent.ConcurrentHashMap;
 import static java.lang.Thread.currentThread;
 import static java.util.Arrays.asList;
 import static java.util.Collections.addAll;
+import static java.util.Collections.singletonList;
 import static java.util.Collections.singletonMap;
 import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
 import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
+import static org.apache.maven.plugin.surefire.util.DependencyScanner.filter;
 import static org.apache.maven.shared.utils.StringUtils.capitalizeFirstLetter;
 import static org.apache.maven.shared.utils.StringUtils.isEmpty;
 import static org.apache.maven.shared.utils.StringUtils.isNotBlank;
@@ -731,8 +733,11 @@ public abstract class AbstractSurefireMojo
      * List of dependencies to scan for test classes to include in the test run.
      * The child elements of this element must be &lt;dependency&gt; elements, and the
      * contents of each of these elements must be a string which follows the format:
-     *
+     * <br>
      * <i>groupId:artifactId</i>. For example: <i>org.acme:project-a</i>.
+     * <br>
+     * Since version 2.22.0 you can scan for test classes from a project
+     * dependency of your multi-module project.
      *
      * @since 2.15
      */
@@ -894,7 +899,13 @@ public abstract class AbstractSurefireMojo
         return scanner.scan();
     }
 
-    private DefaultScanResult scanDependencies()
+    @SuppressWarnings( "unchecked" )
+    List<Artifact> getProjectTestArtifacts()
+    {
+        return project.getTestArtifacts();
+    }
+
+    DefaultScanResult scanDependencies() throws MojoFailureException
     {
         if ( getDependenciesToScan() == null )
         {
@@ -904,16 +915,40 @@ public abstract class AbstractSurefireMojo
         {
             try
             {
-                // @TODO noinspection unchecked, check MavenProject 3.x for Generics in surefire:3.0
-                @SuppressWarnings( "unchecked" )
-                List<File> dependenciesToScan =
-                    DependencyScanner.filter( project.getTestArtifacts(), asList( getDependenciesToScan() ) );
-                DependencyScanner scanner = new DependencyScanner( dependenciesToScan, getIncludedAndExcludedTests() );
-                return scanner.scan();
+                DefaultScanResult result = null;
+
+                List<Artifact> dependenciesToScan =
+                        filter( getProjectTestArtifacts(), asList( getDependenciesToScan() ) );
+
+                for ( Artifact artifact : dependenciesToScan )
+                {
+                    String type = artifact.getType();
+                    File out = artifact.getFile();
+                    if ( out == null || !out.exists()
+                            || !( "jar".equals( type ) || out.isDirectory() || out.getName().endsWith( ".jar" ) ) )
+                    {
+                        continue;
+                    }
+
+                    if ( out.isFile() )
+                    {
+                        DependencyScanner scanner =
+                                new DependencyScanner( singletonList( out ), getIncludedAndExcludedTests() );
+                        result = result == null ? scanner.scan() : result.append( scanner.scan() );
+                    }
+                    else if ( out.isDirectory() )
+                    {
+                        DirectoryScanner scanner =
+                                new DirectoryScanner( out, getIncludedAndExcludedTests() );
+                        result = result == null ? scanner.scan() : result.append( scanner.scan() );
+                    }
+                }
+
+                return result;
             }
             catch ( Exception e )
             {
-                throw new RuntimeException( e );
+                throw new MojoFailureException( e.getLocalizedMessage(), e );
             }
         }
     }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
index 9faf8e6..5f76433 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
@@ -20,6 +20,7 @@ package org.apache.maven.plugin.surefire.util;
  */
 
 import static org.apache.maven.plugin.surefire.util.ScannerUtil.convertJarFileResourceToJavaClassName;
+import static org.apache.maven.plugin.surefire.util.ScannerUtil.isJavaClassFile;
 
 import java.io.File;
 import java.io.IOException;
@@ -60,13 +61,16 @@ public class DependencyScanner
         Set<String> classes = new LinkedHashSet<String>();
         for ( File artifact : dependenciesToScan )
         {
-            try
+            if ( artifact != null && artifact.isFile() && artifact.getName().endsWith( ".jar" ) )
             {
-                scanArtifact( artifact, filter, classes );
-            }
-            catch ( IOException e )
-            {
-                throw new MojoExecutionException( "Could not scan dependency " + artifact.toString(), e );
+                try
+                {
+                    scanArtifact( artifact, filter, classes );
+                }
+                catch ( IOException e )
+                {
+                    throw new MojoExecutionException( "Could not scan dependency " + artifact.toString(), e );
+                }
             }
         }
         return new DefaultScanResult( new ArrayList<String>( classes ) );
@@ -75,34 +79,32 @@ public class DependencyScanner
     private static void scanArtifact( File artifact, TestFilter<String, String> filter, Set<String> classes )
         throws IOException
     {
-        if ( artifact != null && artifact.isFile() )
+        JarFile jar = null;
+        try
         {
-            JarFile jar = null;
-            try
+            jar = new JarFile( artifact );
+            for ( Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); )
             {
-                jar = new JarFile( artifact );
-                for ( Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); )
+                JarEntry entry = entries.nextElement();
+                String path = entry.getName();
+                if ( !entry.isDirectory() && isJavaClassFile( path ) && filter.shouldRun( path, null ) )
                 {
-                    JarEntry entry = entries.nextElement();
-                    if ( filter.shouldRun( entry.getName(), null ) )
-                    {
-                        classes.add( convertJarFileResourceToJavaClassName( entry.getName() ) );
-                    }
+                    classes.add( convertJarFileResourceToJavaClassName( path ) );
                 }
             }
-            finally
+        }
+        finally
+        {
+            if ( jar != null )
             {
-                if ( jar != null )
-                {
-                    jar.close();
-                }
+                jar.close();
             }
         }
     }
 
-    public static List<File> filter( List<Artifact> artifacts, List<String> groupArtifactIds )
+    public static List<Artifact> filter( List<Artifact> artifacts, List<String> groupArtifactIds )
     {
-        List<File> matches = new ArrayList<File>();
+        List<Artifact> matches = new ArrayList<Artifact>();
         if ( groupArtifactIds == null || artifacts == null )
         {
             return matches;
@@ -120,7 +122,7 @@ public class DependencyScanner
                 if ( artifact.getGroupId().matches( groupArtifact[0] )
                     && artifact.getArtifactId().matches( groupArtifact[1] ) )
                 {
-                    matches.add( artifact.getFile() );
+                    matches.add( artifact );
                 }
             }
         }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
index 9989176..8073907 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
@@ -41,6 +41,11 @@ final class ScannerUtil
         return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
     }
 
+    public static boolean isJavaClassFile( String file )
+    {
+        return file.endsWith( ".class" );
+    }
+
     @Deprecated
     @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
     {
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
new file mode 100644
index 0000000..91589a2
--- /dev/null
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
@@ -0,0 +1,625 @@
+package org.apache.maven.plugin.surefire;
+
+/*
+ * 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.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.versioning.VersionRange;
+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.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class MojoMocklessTest
+{
+    @Test
+    public void scanDependenciesShouldReturnNull()
+            throws MojoFailureException
+    {
+        Mojo mojo = new Mojo( null, null );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullAfterMissingBuildArtifact()
+            throws MojoFailureException
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "jar", null, handler );
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullWithWAR()
+            throws MojoFailureException
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "war", null, handler );
+        testDeps.setFile( new File( new File( "target" ), "a-1.0.war" ) );
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullWithExistingWAR()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "war", null, handler );
+        File artifactFile = File.createTempFile( "surefire", ".war" );
+        testDeps.setFile( artifactFile );
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnClassWithExistingTestJAR()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "test-jar", null, handler );
+
+        File artifactFile = File.createTempFile( "surefire", ".jar" );
+        testDeps.setFile( artifactFile );
+        ZipOutputStream os = new ZipOutputStream( new FileOutputStream( artifactFile ) );
+        os.putNextEntry( new ZipEntry( "pkg/" ) );
+        os.closeEntry();
+        os.putNextEntry( new ZipEntry( "pkg/MyTest.class" ) );
+        os.closeEntry();
+        os.finish();
+        os.close();
+
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isFalse();
+
+        assertThat( result.getClasses() )
+                .contains( "pkg.MyTest" );
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullWithEmptyTestJAR()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "jar", null, handler );
+
+        File artifactFile = File.createTempFile( "surefire", ".jar" );
+        testDeps.setFile( artifactFile );
+        ZipOutputStream os = new ZipOutputStream( new FileOutputStream( artifactFile ) );
+        os.putNextEntry( new ZipEntry( "pkg/" ) );
+        os.closeEntry();
+        os.finish();
+        os.close();
+
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isTrue();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnClassWithDirectory()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "test-jar", null, handler );
+
+        File artifactFile = File.createTempFile( "surefire", "-classes" );
+        String classDir = artifactFile.getCanonicalPath();
+        assertThat( artifactFile.delete() ).isTrue();
+        File classes = new File( classDir );
+        assertThat( classes.mkdir() ).isTrue();
+
+        testDeps.setFile( classes );
+
+        assertThat( new File( classes, "AnotherTest.class" ).createNewFile() )
+                .isTrue();
+
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isFalse();
+
+        assertThat( result.getClasses() )
+                .contains( "AnotherTest" );
+    }
+
+    @Test
+    public void scanMultipleDependencies()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDep1 = new DefaultArtifact( "g", "x", version, "compile", "jar", null, handler );
+
+        File artifactFile1 = File.createTempFile( "surefire", "-classes" );
+        String classDir = artifactFile1.getCanonicalPath();
+        assertThat( artifactFile1.delete() ).isTrue();
+        File classes = new File( classDir );
+        assertThat( classes.mkdir() ).isTrue();
+
+        testDep1.setFile( classes );
+
+        assertThat( new File( classes, "AnotherTest.class" ).createNewFile() )
+                .isTrue();
+
+        Artifact testDep2 = new DefaultArtifact( "g", "a", version, "test", "jar", null, handler );
+        File artifactFile2 = File.createTempFile( "surefire", ".jar" );
+        testDep2.setFile( artifactFile2 );
+        ZipOutputStream os = new ZipOutputStream( new FileOutputStream( artifactFile2 ) );
+        os.putNextEntry( new ZipEntry( "pkg/" ) );
+        os.closeEntry();
+        os.putNextEntry( new ZipEntry( "pkg/MyTest.class" ) );
+        os.closeEntry();
+        os.finish();
+        os.close();
+
+        List<Artifact> projectTestArtifacts = asList( testDep1, testDep2 );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isFalse();
+
+        assertThat( result.getClasses() )
+                .hasSize( 1 );
+
+        assertThat( result.getClasses() )
+                .contains( "pkg.MyTest" );
+    }
+
+    private final static class Mojo
+            extends AbstractSurefireMojo
+    {
+        private final List<Artifact> projectTestArtifacts;
+        private final String[] dependenciesToScan;
+
+        Mojo( List<Artifact> projectTestArtifacts, String[] dependenciesToScan )
+        {
+            this.projectTestArtifacts = projectTestArtifacts;
+            this.dependenciesToScan = dependenciesToScan;
+        }
+
+        @Override
+        protected String getPluginName()
+        {
+            return null;
+        }
+
+        @Override
+        protected int getRerunFailingTestsCount()
+        {
+            return 0;
+        }
+
+        @Override
+        public boolean isSkipTests()
+        {
+            return false;
+        }
+
+        @Override
+        public void setSkipTests( boolean skipTests )
+        {
+
+        }
+
+        @Override
+        public boolean isSkipExec()
+        {
+            return false;
+        }
+
+        @Override
+        public void setSkipExec( boolean skipExec )
+        {
+
+        }
+
+        @Override
+        public boolean isSkip()
+        {
+            return false;
+        }
+
+        @Override
+        public void setSkip( boolean skip )
+        {
+
+        }
+
+        @Override
+        public File getBasedir()
+        {
+            return null;
+        }
+
+        @Override
+        public void setBasedir( File basedir )
+        {
+
+        }
+
+        @Override
+        public File getTestClassesDirectory()
+        {
+            return null;
+        }
+
+        @Override
+        public void setTestClassesDirectory( File testClassesDirectory )
+        {
+
+        }
+
+        @Override
+        public File getClassesDirectory()
+        {
+            return null;
+        }
+
+        @Override
+        public void setClassesDirectory( File classesDirectory )
+        {
+
+        }
+
+        @Override
+        public File getReportsDirectory()
+        {
+            return null;
+        }
+
+        @Override
+        public void setReportsDirectory( File reportsDirectory )
+        {
+
+        }
+
+        @Override
+        public String getTest()
+        {
+            return null;
+        }
+
+        @Override
+        public void setTest( String test )
+        {
+
+        }
+
+        @Override
+        public List<String> getIncludes()
+        {
+            return null;
+        }
+
+        @Override
+        public File getIncludesFile()
+        {
+            return null;
+        }
+
+        @Override
+        public void setIncludes( List<String> includes )
+        {
+
+        }
+
+        @Override
+        public boolean isPrintSummary()
+        {
+            return false;
+        }
+
+        @Override
+        public void setPrintSummary( boolean printSummary )
+        {
+
+        }
+
+        @Override
+        public String getReportFormat()
+        {
+            return null;
+        }
+
+        @Override
+        public void setReportFormat( String reportFormat )
+        {
+
+        }
+
+        @Override
+        public boolean isUseFile()
+        {
+            return false;
+        }
+
+        @Override
+        public void setUseFile( boolean useFile )
+        {
+
+        }
+
+        @Override
+        public String getDebugForkedProcess()
+        {
+            return null;
+        }
+
+        @Override
+        public void setDebugForkedProcess( String debugForkedProcess )
+        {
+
+        }
+
+        @Override
+        public int getForkedProcessTimeoutInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
+        {
+
+        }
+
+        @Override
+        public int getForkedProcessExitTimeoutInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setForkedProcessExitTimeoutInSeconds( int forkedProcessTerminationTimeoutInSeconds )
+        {
+
+        }
+
+        @Override
+        public double getParallelTestsTimeoutInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
+        {
+
+        }
+
+        @Override
+        public double getParallelTestsTimeoutForcedInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
+        {
+
+        }
+
+        @Override
+        public boolean isUseSystemClassLoader()
+        {
+            return false;
+        }
+
+        @Override
+        public void setUseSystemClassLoader( boolean useSystemClassLoader )
+        {
+
+        }
+
+        @Override
+        public boolean isUseManifestOnlyJar()
+        {
+            return false;
+        }
+
+        @Override
+        public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
+        {
+
+        }
+
+        @Override
+        public String getEncoding()
+        {
+            return null;
+        }
+
+        @Override
+        public void setEncoding( String encoding )
+        {
+
+        }
+
+        @Override
+        public Boolean getFailIfNoSpecifiedTests()
+        {
+            return null;
+        }
+
+        @Override
+        public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
+        {
+
+        }
+
+        @Override
+        public int getSkipAfterFailureCount()
+        {
+            return 0;
+        }
+
+        @Override
+        public String getShutdown()
+        {
+            return null;
+        }
+
+        @Override
+        public File getExcludesFile()
+        {
+            return null;
+        }
+
+        @Override
+        protected List<File> suiteXmlFiles()
+        {
+            return null;
+        }
+
+        @Override
+        protected boolean hasSuiteXmlFiles()
+        {
+            return false;
+        }
+
+        @Override
+        public File[] getSuiteXmlFiles()
+        {
+            return new File[0];
+        }
+
+        @Override
+        public void setSuiteXmlFiles( File[] suiteXmlFiles )
+        {
+
+        }
+
+        @Override
+        public String getRunOrder()
+        {
+            return null;
+        }
+
+        @Override
+        public void setRunOrder( String runOrder )
+        {
+
+        }
+
+        @Override
+        public String[] getDependenciesToScan()
+        {
+            return dependenciesToScan;
+        }
+
+        @Override
+        protected void handleSummary( RunResult summary, Exception firstForkException )
+                throws MojoExecutionException, MojoFailureException
+        {
+
+        }
+
+        @Override
+        protected boolean isSkipExecution()
+        {
+            return false;
+        }
+
+        @Override
+        protected String[] getDefaultIncludes()
+        {
+            return new String[0];
+        }
+
+        @Override
+        protected String getReportSchemaLocation()
+        {
+            return null;
+        }
+
+        @Override
+        protected Artifact getMojoArtifact()
+        {
+            return null;
+        }
+
+        @Override
+        List<Artifact> getProjectTestArtifacts()
+        {
+            return projectTestArtifacts;
+        }
+    }
+}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
index c8dd436..b9335d6 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
@@ -56,9 +56,14 @@ public class DependenciesScannerTest
         include.add( "**/*A.java" );
         List<String> exclude = new ArrayList<String>();
 
+        List<File> dependenciesToScan = new ArrayList<File>();
+        for ( Artifact a : DependencyScanner.filter( Collections.singletonList( artifact ), scanDependencies ) )
+        {
+            dependenciesToScan.add( a.getFile() );
+        }
+
         DependencyScanner scanner =
-            new DependencyScanner( DependencyScanner.filter( Collections.singletonList( artifact ), scanDependencies ),
-                                   new TestListResolver( include, exclude ) );
+            new DependencyScanner( dependenciesToScan, new TestListResolver( include, exclude ) );
 
         ScanResult classNames = scanner.scan();
         assertNotNull( classNames );
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/ScannerUtilTest.java
similarity index 50%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
copy to maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/ScannerUtilTest.java
index 9989176..066a715 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/ScannerUtilTest.java
@@ -19,31 +19,37 @@ package org.apache.maven.plugin.surefire.util;
  * under the License.
  */
 
-import org.apache.commons.lang3.StringUtils;
-import javax.annotation.Nonnull;
+import org.junit.Test;
 
-final class ScannerUtil
+import static org.fest.assertions.Assertions.assertThat;
+
+/**
+ * Unit test for {@link ScannerUtil}
+ */
+public class ScannerUtilTest
 {
 
-    private ScannerUtil()
+    @Test
+    public void shouldConvertJarFileResourceToJavaClassName()
     {
-        throw new IllegalStateException( "not instantiable constructor" );
-    }
+        String className = ScannerUtil.convertJarFileResourceToJavaClassName( "org/apache/pkg/MyService.class" );
 
-    @Deprecated
-    private static final String FS = System.getProperty( "file.separator" );
+        assertThat( className )
+                .isEqualTo( "org.apache.pkg.MyService" );
 
-    @Deprecated
-    private static final boolean IS_NON_UNIX_FS = ( !FS.equals( "/" ) );
+        className = ScannerUtil.convertJarFileResourceToJavaClassName( "META-INF/MANIFEST.MF" );
 
-    @Nonnull public static String convertJarFileResourceToJavaClassName( @Nonnull String test )
-    {
-        return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
+        assertThat( className )
+                .isEqualTo( "META-INF.MANIFEST.MF" );
     }
 
-    @Deprecated
-    @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
+    @Test
+    public void shouldBeClassFile()
     {
-        return ( IS_NON_UNIX_FS ? path.replace( "/", FS ) : path );
+        assertThat( ScannerUtil.isJavaClassFile( "META-INF/MANIFEST.MF" ) )
+                .isFalse();
+
+        assertThat( ScannerUtil.isJavaClassFile( "org/apache/pkg/MyService.class" ) )
+                .isTrue();
     }
 }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
index bd99abc..728cef3 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
@@ -25,6 +25,7 @@ import junit.framework.TestCase;
 import junit.framework.TestSuite;
 import org.apache.maven.plugin.surefire.AbstractSurefireMojoJava7PlusTest;
 import org.apache.maven.plugin.surefire.AbstractSurefireMojoTest;
+import org.apache.maven.plugin.surefire.MojoMocklessTest;
 import org.apache.maven.plugin.surefire.SurefireHelperTest;
 import org.apache.maven.plugin.surefire.SurefireReflectorTest;
 import org.apache.maven.plugin.surefire.SurefirePropertiesTest;
@@ -42,6 +43,7 @@ import org.apache.maven.plugin.surefire.report.WrappedReportEntryTest;
 import org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest;
 import org.apache.maven.plugin.surefire.util.DependenciesScannerTest;
 import org.apache.maven.plugin.surefire.util.DirectoryScannerTest;
+import org.apache.maven.plugin.surefire.util.ScannerUtilTest;
 import org.apache.maven.plugin.surefire.util.SpecificFileFilterTest;
 import org.apache.maven.surefire.report.ConsoleOutputFileReporterTest;
 import org.apache.maven.surefire.report.FileReporterTest;
@@ -91,6 +93,8 @@ public class JUnit4SuiteTest extends TestCase
         {
             suite.addTest( new JUnit4TestAdapter( AbstractSurefireMojoJava7PlusTest.class ) );
         }
+        suite.addTest( new JUnit4TestAdapter( ScannerUtilTest.class ) );
+        suite.addTest( new JUnit4TestAdapter( MojoMocklessTest.class ) );
         return suite;
     }
 }
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
index 5120cb5..a957d06 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
@@ -299,13 +299,13 @@ public class SystemUtilsTest
     {
 
         @Test
-        public void shouldBeDifferentJdk9() throws IOException
+        public void shouldBeDifferentJdk9()
         {
             testIsJava9AtLeast( new File( System.getProperty( "java.home" ) ) );
         }
 
         @Test
-        public void shouldBeSameJdk9() throws IOException
+        public void shouldBeSameJdk9()
         {
             // PowerMockJUnit44RunnerDelegateImpl does not work with Assumptions: assumeFalse
             if ( !JAVA_RECENT.atLeast( JAVA_9 ) )
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1383ScanSessionDependenciesIT.java
similarity index 50%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
copy to surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1383ScanSessionDependenciesIT.java
index 9989176..b9ea215 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1383ScanSessionDependenciesIT.java
@@ -1,4 +1,4 @@
-package org.apache.maven.plugin.surefire.util;
+package org.apache.maven.surefire.its.jiras;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,31 +19,25 @@ package org.apache.maven.plugin.surefire.util;
  * under the License.
  */
 
-import org.apache.commons.lang3.StringUtils;
-import javax.annotation.Nonnull;
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.apache.maven.surefire.its.fixture.SurefireLauncher;
+import org.junit.Test;
 
-final class ScannerUtil
+/**
+ * @author <a href="mailto:owen.farrell@gmail.com">Owen Farrell (owenfarrell)</a>
+ * @see <a href="https://issues.apache.org/jira/browse/SUREFIRE-1383">SUREFIRE-1383</a>
+ * @since 2.20.1
+ */
+public class Surefire1383ScanSessionDependenciesIT
+        extends SurefireJUnit4IntegrationTestCase
 {
-
-    private ScannerUtil()
-    {
-        throw new IllegalStateException( "not instantiable constructor" );
-    }
-
-    @Deprecated
-    private static final String FS = System.getProperty( "file.separator" );
-
-    @Deprecated
-    private static final boolean IS_NON_UNIX_FS = ( !FS.equals( "/" ) );
-
-    @Nonnull public static String convertJarFileResourceToJavaClassName( @Nonnull String test )
-    {
-        return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
-    }
-
-    @Deprecated
-    @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
+    @Test
+    public void test() throws VerificationException
     {
-        return ( IS_NON_UNIX_FS ? path.replace( "/", FS ) : path );
+        SurefireLauncher launcher = unpack( "surefire-1383" );
+        launcher.executeTest();
+        launcher.getSubProjectValidator( "sut" )
+                .assertTestSuiteResults( 1, 0, 0, 0 );
     }
 }
diff --git a/surefire-its/src/test/resources/surefire-1383/pom.xml b/surefire-its/src/test/resources/surefire-1383/pom.xml
new file mode 100644
index 0000000..1b4b7c3
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1383/pom.xml
@@ -0,0 +1,45 @@
+<?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>
+    
+    <parent>
+        <groupId>org.apache.maven.surefire</groupId>
+        <artifactId>it-parent</artifactId>
+        <version>1.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.apache.maven.plugins.surefire</groupId>
+    <artifactId>surefire-1383</artifactId>
+    <version>1.0</version>
+    <packaging>pom</packaging>
+    <modules>
+        <module>runner</module>
+        <module>sut</module>
+    </modules>
+
+    <properties>
+        <maven.compiler.source>1.5</maven.compiler.source>
+        <maven.compiler.target>1.5</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+</project>
diff --git a/surefire-its/src/test/resources/surefire-1383/runner/pom.xml b/surefire-its/src/test/resources/surefire-1383/runner/pom.xml
new file mode 100644
index 0000000..eaad1a0
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1383/runner/pom.xml
@@ -0,0 +1,39 @@
+<?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>
+    
+    <parent>
+        <groupId>org.apache.maven.plugins.surefire</groupId>
+        <artifactId>surefire-1383</artifactId>
+        <version>1.0</version>
+    </parent>
+    
+    <artifactId>surefire-1383-runner</artifactId>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>6.11</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/surefire-its/src/test/resources/surefire-1383/runner/src/main/java/pkg/DynamicRunningTest.java
similarity index 50%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
copy to surefire-its/src/test/resources/surefire-1383/runner/src/main/java/pkg/DynamicRunningTest.java
index 9989176..1b37af5 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/surefire-its/src/test/resources/surefire-1383/runner/src/main/java/pkg/DynamicRunningTest.java
@@ -1,5 +1,4 @@
-package org.apache.maven.plugin.surefire.util;
-
+package pkg;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,31 +18,16 @@ package org.apache.maven.plugin.surefire.util;
  * under the License.
  */
 
-import org.apache.commons.lang3.StringUtils;
-import javax.annotation.Nonnull;
+import org.testng.annotations.Test;
 
-final class ScannerUtil
+@Test
+public class DynamicRunningTest
 {
 
-    private ScannerUtil()
-    {
-        throw new IllegalStateException( "not instantiable constructor" );
-    }
-
-    @Deprecated
-    private static final String FS = System.getProperty( "file.separator" );
-
-    @Deprecated
-    private static final boolean IS_NON_UNIX_FS = ( !FS.equals( "/" ) );
-
-    @Nonnull public static String convertJarFileResourceToJavaClassName( @Nonnull String test )
+    public void shouldRun()
     {
-        return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
+        // Test runners such as this one may dynamically invoke other frameworks such as Cucumber, Selenium, etc.
+        // The actual operation is not relevant to the issue.
     }
 
-    @Deprecated
-    @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
-    {
-        return ( IS_NON_UNIX_FS ? path.replace( "/", FS ) : path );
-    }
 }
diff --git a/surefire-its/src/test/resources/surefire-1383/sut/pom.xml b/surefire-its/src/test/resources/surefire-1383/sut/pom.xml
new file mode 100644
index 0000000..2a31ad7
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1383/sut/pom.xml
@@ -0,0 +1,56 @@
+<?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>
+    
+    <parent>
+        <groupId>org.apache.maven.plugins.surefire</groupId>
+        <artifactId>surefire-1383</artifactId>
+        <version>1.0</version>
+    </parent>
+    
+    <artifactId>surefire-1383-sut</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>surefire-1383-runner</artifactId>
+            <version>${project.version}</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>
+                    <dependenciesToScan>
+                        <param>${project.groupId}:surefire-1383-runner</param>
+                    </dependenciesToScan>
+                    <failIfNoTests>true</failIfNoTests>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java
index 9371b51..184d32e 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java
@@ -70,13 +70,13 @@ public class TestSet
 
                 target.testSetStarting( report );
 
-                long startTile = 0;
+                long startTime = 0;
                 long endTime = 0;
                 for ( TestMethod testMethod : testMethods )
                 {
-                    if ( startTile == 0 || testMethod.getStartTime() < startTile )
+                    if ( startTime == 0 || testMethod.getStartTime() < startTime )
                     {
-                        startTile = testMethod.getStartTime();
+                        startTime = testMethod.getStartTime();
                     }
 
                     if ( endTime == 0 || testMethod.getEndTime() > endTime )
@@ -87,7 +87,7 @@ public class TestSet
                     testMethod.replay( target );
                 }
 
-                int elapsed = (int) ( endTime - startTile );
+                int elapsed = (int) ( endTime - startTime );
 
                 report = createReportEntryCompleted( elapsed );
 

-- 
To stop receiving notification emails like this one, please contact
tibordigana@apache.org.