[SUREFIRE-1209] rerunFailingTestsCount does not run failed tests if forkCount 
and surefire-junit47 is used


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/63963d67
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/63963d67
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/63963d67

Branch: refs/heads/master
Commit: 63963d6761cd7d716ed306f4f12b5a75d3657595
Parents: 57662e5
Author: Tibor17 <tibo...@lycos.com>
Authored: Sat Dec 19 15:44:12 2015 +0100
Committer: Tibor17 <tibo...@lycos.com>
Committed: Sat Dec 19 16:02:54 2015 +0100

----------------------------------------------------------------------
 .../apt/examples/rerun-failing-tests.apt.vm     |  5 ++
 .../maven/surefire/booter/CommandReader.java    | 16 +++-
 .../apache/maven/surefire/util/TestsToRun.java  | 23 +++++-
 .../maven/surefire/util/TestsToRunTest.java     | 21 +++++
 .../maven/surefire/booter/LazyTestsToRun.java   | 38 ++++++++-
 .../surefire/booter/CommandReaderTest.java      | 85 ++++++++++++++++++--
 .../jiras/Surefire1209RerunAndForkCountIT.java  |  1 +
 .../surefire-1209-rerun-and-forkcount/pom.xml   | 81 +++++++++++++++++++
 .../src/test/java/pkg/ATest.java                | 45 +++++++++++
 .../src/test/java/pkg/BTest.java                | 42 ++++++++++
 .../src/test/java/pkg/CTest.java                | 35 ++++++++
 .../src/test/java/pkg/DTest.java                | 35 ++++++++
 .../src/test/java/pkg/ETest.java                | 31 +++++++
 .../surefire/junitcore/JUnitCoreWrapper.java    | 18 +++--
 14 files changed, 458 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/maven-surefire-plugin/src/site/apt/examples/rerun-failing-tests.apt.vm
----------------------------------------------------------------------
diff --git 
a/maven-surefire-plugin/src/site/apt/examples/rerun-failing-tests.apt.vm 
b/maven-surefire-plugin/src/site/apt/examples/rerun-failing-tests.apt.vm
index 4c51d8c..effd7b4 100644
--- a/maven-surefire-plugin/src/site/apt/examples/rerun-failing-tests.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/rerun-failing-tests.apt.vm
@@ -134,3 +134,8 @@ mvn -D${thisPlugin.toLowerCase()}.rerunFailingTestsCount=2 
test
 
   In the xml report, the running time of a failing test with re-runs will be 
the running time of the
   <<first failing run>>.
+
+* Re-run execution in JUnit Providers
+
+  The provider <<<surefire-junit4>>> executes individual test class and 
consequently re-runs failed tests.
+  The provider <<<surefire-junit47>>> executes all test classes and re-runs 
failed tests afterwards.

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
----------------------------------------------------------------------
diff --git 
a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
 
b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
index 330fd8d..2bb4504 100644
--- 
a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
+++ 
b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
@@ -78,6 +78,8 @@ public final class CommandReader
 
     private volatile Shutdown shutdown;
 
+    private int iteratedCount;
+
     public static CommandReader getReader()
     {
         final CommandReader reader = READER;
@@ -166,7 +168,16 @@ public final class CommandReader
     }
 
     /**
+     * @return test classes which have been retrieved by {@link 
CommandReader#getIterableClasses(PrintStream)}.
+     */
+    Iterator<String> iterated()
+    {
+        return testClasses.subList( 0, iteratedCount ).iterator();
+    }
+
+    /**
      * The iterator can be used only in one Thread.
+     * Two simultaneous instances are not allowed for sake of only one {@link 
#nextCommandNotifier}.
      *
      * @param originalOutStream original stream in current JVM process
      * @return Iterator with test classes lazily loaded as commands from the 
main process
@@ -241,7 +252,7 @@ public final class CommandReader
 
         private String clazz;
 
-        private int nextQueueIndex = 0;
+        private int nextQueueIndex;
 
         private ClassesIterator( PrintStream originalOutStream )
         {
@@ -297,6 +308,7 @@ public final class CommandReader
                     return;
                 }
                 clazz = CommandReader.this.testClasses.get( nextQueueIndex++ );
+                CommandReader.this.iteratedCount = nextQueueIndex;
             }
 
             if ( CommandReader.this.isStopped() )
@@ -319,7 +331,7 @@ public final class CommandReader
 
         private boolean isEndSymbolAt( int index )
         {
-            return CommandReader.this.isQueueFull() && index == 
CommandReader.this.testClasses.size();
+            return CommandReader.this.isQueueFull() && 1 + index == 
CommandReader.this.testClasses.size();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java
----------------------------------------------------------------------
diff --git 
a/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java 
b/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java
index 9bbf630..0255645 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java
@@ -23,10 +23,13 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Set;
 import org.apache.maven.surefire.testset.TestSetFailedException;
 
+import static java.lang.Math.max;
+
 /**
  * Contains all the tests that have been found according to specified 
include/exclude
  * specification for a given surefire run.
@@ -35,10 +38,12 @@ import 
org.apache.maven.surefire.testset.TestSetFailedException;
  */
 public class TestsToRun implements Iterable<Class<?>>
 {
-    private final Set<Class<?>> locatedClasses;
+    private final List<Class<?>> locatedClasses;
 
     private volatile boolean finished;
 
+    private int iteratedCount;
+
     /**
      * Constructor
      *
@@ -46,7 +51,7 @@ public class TestsToRun implements Iterable<Class<?>>
      */
     public TestsToRun( Set<Class<?>> locatedClasses )
     {
-        this.locatedClasses = Collections.unmodifiableSet( locatedClasses );
+        this.locatedClasses = new ArrayList<Class<?>>( locatedClasses );
     }
 
     public static TestsToRun fromClass( Class<?> clazz )
@@ -56,6 +61,14 @@ public class TestsToRun implements Iterable<Class<?>>
     }
 
     /**
+     * @return test classes which have been retrieved by {@link 
TestsToRun#iterator()}.
+     */
+    public Iterator<Class<?>> iterated()
+    {
+        return locatedClasses.subList( 0, iteratedCount ).iterator();
+    }
+
+    /**
      * Returns an iterator over the located java.lang.Class objects
      *
      * @return an unmodifiable iterator
@@ -72,6 +85,8 @@ public class TestsToRun implements Iterable<Class<?>>
 
         private Boolean finishCurrentIteration;
 
+        private int iteratedCount;
+
         public boolean hasNext()
         {
             popMarker();
@@ -86,7 +101,9 @@ public class TestsToRun implements Iterable<Class<?>>
                 {
                     throw new NoSuchElementException();
                 }
-                return it.next();
+                Class<?> nextTest = it.next();
+                TestsToRun.this.iteratedCount = max( ++iteratedCount, 
TestsToRun.this.iteratedCount );
+                return nextTest;
             }
             finally
             {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-api/src/test/java/org/apache/maven/surefire/util/TestsToRunTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-api/src/test/java/org/apache/maven/surefire/util/TestsToRunTest.java 
b/surefire-api/src/test/java/org/apache/maven/surefire/util/TestsToRunTest.java
index ea3226a..0041056 100644
--- 
a/surefire-api/src/test/java/org/apache/maven/surefire/util/TestsToRunTest.java
+++ 
b/surefire-api/src/test/java/org/apache/maven/surefire/util/TestsToRunTest.java
@@ -89,6 +89,27 @@ public class TestsToRunTest
         assertEquals( null, testsToRun.getClassByName( 
"org.apache.maven.surefire.util.TestsToRunTest$T3" ) );
     }
 
+    public void testTwoIterators()
+    {
+        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
+        classes.add( T1.class );
+        classes.add( T2.class );
+        TestsToRun testsToRun = new TestsToRun( classes );
+
+        Iterator<Class<?>> it1 = testsToRun.iterator();
+
+        assertEquals( it1.next(), T1.class );
+        assertTrue( it1.hasNext() );
+
+        Iterator<Class<?>> it2 = testsToRun.iterated();
+
+        assertEquals( it1.next(), T2.class );
+        assertFalse( it1.hasNext() );
+
+        assertEquals( it2.next(), T1.class );
+        assertFalse( it1.hasNext() );
+    }
+
     class T1
     {
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
----------------------------------------------------------------------
diff --git 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
index 3a2eb26..2b75732 100644
--- 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
+++ 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
@@ -69,8 +69,7 @@ final class LazyTestsToRun
 
         public Class<?> next()
         {
-            String clazz = it.next();
-            return loadClass( Thread.currentThread().getContextClassLoader(), 
clazz );
+            return findClass( it.next() );
         }
 
         public void remove()
@@ -80,6 +79,15 @@ final class LazyTestsToRun
     }
 
     /**
+     * @return test classes which have been retrieved by {@link 
TestsToRun#iterator()}.
+     */
+    @Override
+    public Iterator<Class<?>> iterated()
+    {
+        return newWeakIterator();
+    }
+
+    /**
      * The iterator can be used only in one Thread.
      * {@inheritDoc}
      * @see org.apache.maven.surefire.util.TestsToRun#iterator()
@@ -106,4 +114,30 @@ final class LazyTestsToRun
     {
         return false;
     }
+
+    private static Class<?> findClass( String clazz )
+    {
+        return loadClass( Thread.currentThread().getContextClassLoader(), 
clazz );
+    }
+
+    /**
+     * @return snapshot of tests upon constructs of {@link 
CommandReader#iterated() iterator}.
+     * Therefore weakly consistent while {@link LazyTestsToRun#iterator()} is 
being iterated.
+     */
+    private static Iterator<Class<?>> newWeakIterator()
+    {
+        final Iterator<String> it = getReader().iterated();
+        return new Iterator<Class<?>>()
+        {
+            public boolean hasNext()
+            {
+                return it.hasNext();
+            }
+
+            public Class<?> next()
+            {
+                return findClass( it.next() );
+            }
+        };
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
 
b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
index 5284974..b731dc0 100644
--- 
a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
+++ 
b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
@@ -38,6 +38,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.FutureTask;
 import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
 
 import static 
org.apache.maven.surefire.util.internal.StringUtils.FORK_STREAM_CHARSET_NAME;
 import static org.junit.Assert.assertFalse;
@@ -45,6 +46,7 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.fest.assertions.Assertions.assertThat;
 
 /**
  * Testing singleton {@code MasterProcessReader} in multiple class loaders.
@@ -59,6 +61,18 @@ public class CommandReaderTest
     private InputStream realInputStream;
     private CommandReader reader;
 
+    static class A {
+    }
+
+    static class B {
+    }
+
+    static class C {
+    }
+
+    static class D {
+    }
+
     @Before
     public void init()
         throws UnsupportedEncodingException
@@ -80,8 +94,7 @@ public class CommandReaderTest
     @Test
     public void readJustOneClass() throws Exception
     {
-        Iterator<String> it = reader.getIterableClasses( new PrintStream( new 
ByteArrayOutputStream() ) )
-            .iterator();
+        Iterator<String> it = reader.getIterableClasses( nul() ).iterator();
         assertTrue( it.hasNext() );
         assertThat( it.next(), is( getClass().getName() ) );
         reader.stop();
@@ -97,6 +110,50 @@ public class CommandReaderTest
         }
     }
 
+    @Test
+    public void manyClasses() throws Exception
+    {
+        Iterator<String> it1 = reader.getIterableClasses( nul() ).iterator();
+        assertThat( it1.next(), is( getClass().getName() ) );
+        addTestToPipeline( A.class.getName() );
+        assertThat( it1.next(), is( A.class.getName() ) );
+        addTestToPipeline( B.class.getName() );
+        assertThat( it1.next(), is( B.class.getName() ) );
+        addTestToPipeline( C.class.getName() );
+        assertThat( it1.next(), is( C.class.getName() ) );
+        addEndOfPipeline();
+        addTestToPipeline( D.class.getName() );
+        assertFalse( it1.hasNext() );
+    }
+
+    @Test
+    public void twoIterators() throws Exception
+    {
+        Iterator<String> it1 = reader.getIterableClasses( nul() ).iterator();
+
+        assertThat( it1.next(), is( getClass().getName() ) );
+        addTestToPipeline( A.class.getName() );
+        assertThat( it1.next(), is( A.class.getName() ) );
+        addTestToPipeline( B.class.getName() );
+
+        TimeUnit.MILLISECONDS.sleep( 200 ); // give the test chance to fail
+
+        Iterator<String> it2 = reader.iterated();
+
+        assertThat( it1.next(), is( B.class.getName() ) );
+        addTestToPipeline( C.class.getName() );
+
+        assertThat( it2.hasNext(), is( true ) );
+        assertThat( it2.next(), is( getClass().getName() ) );
+        assertThat( it2.hasNext(), is( true ) );
+        assertThat( it2.next(), is( A.class.getName() ) );
+        assertThat( it2 ).isEmpty();
+
+        assertThat( it1.next(), is( C.class.getName() ) );
+        addEndOfPipeline();
+        assertThat( it1 ).isEmpty();
+    }
+
     @Test( expected = NoSuchElementException.class )
     public void stopBeforeReadInThread()
         throws Throwable
@@ -105,8 +162,7 @@ public class CommandReaderTest
         {
             public void run()
             {
-                Iterator<String> it = reader.getIterableClasses( new 
PrintStream( new ByteArrayOutputStream() ) )
-                    .iterator();
+                Iterator<String> it = reader.getIterableClasses( nul() 
).iterator();
                 assertThat( it.next(), is( CommandReaderTest.class.getName() ) 
);
             }
         };
@@ -133,8 +189,7 @@ public class CommandReaderTest
         {
             public void run()
             {
-                Iterator<String> it = reader.getIterableClasses( new 
PrintStream( new ByteArrayOutputStream() ) )
-                    .iterator();
+                Iterator<String> it = reader.getIterableClasses( nul() 
).iterator();
                 assertThat( it.next(), is( CommandReaderTest.class.getName() ) 
);
                 counter.countDown();
                 assertThat( it.next(), is( 
PropertiesWrapperTest.class.getName() ) );
@@ -196,4 +251,22 @@ public class CommandReaderTest
             blockingStream.add( buffer.get() );
         }
     }
+
+    private void addEndOfPipeline()
+            throws UnsupportedEncodingException
+    {
+        ByteBuffer buffer = ByteBuffer.allocate( 8 )
+                .putInt( MasterProcessCommand.TEST_SET_FINISHED.getId() )
+                .putInt( 0 );
+        buffer.rewind();
+        for ( ; buffer.hasRemaining(); )
+        {
+            blockingStream.add( buffer.get() );
+        }
+    }
+
+    private static PrintStream nul()
+    {
+        return new PrintStream( new ByteArrayOutputStream() );
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1209RerunAndForkCountIT.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1209RerunAndForkCountIT.java
 
b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1209RerunAndForkCountIT.java
new file mode 100644
index 0000000..90108d1
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1209RerunAndForkCountIT.java
@@ -0,0 +1 @@
+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.it.VerificationException;
import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
import org
 .apache.maven.surefire.its.fixture.SurefireLauncher;
import org.junit.Test;

/**
 * @author <a href="mailto:tibordig...@apache.org";>Tibor Digana (tibor17)</a>
 * @see {@linkplain https://jira.codehaus.org/browse/SUREFIRE-1209}
 * @since 2.19
 */
public class Surefire1209RerunAndForkCountIT
        extends SurefireJUnit4IntegrationTestCase
{
    @Test
    public void reusableForks()
            throws VerificationException
    {
        unpack().executeTest()
                .assertTestSuiteResults( 5, 0, 0, 0, 4 );
    }

    @Test
    public void notReusableForks()
            throws VerificationException
    {
        unpack().reuseForks( false )
                .executeTest()
                .assertTestSuiteResults( 5, 0, 0, 0, 4 );
    }

    private SurefireLauncher unpack()
    {
        return unpack( "surefire-1209-rerun-and-forkcount" );
    }
}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/pom.xml
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/pom.xml
 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/pom.xml
new file mode 100644
index 0000000..2e10ed5
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/pom.xml
@@ -0,0 +1,81 @@
+<?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.apache.maven.plugins.surefire</groupId>
+    <artifactId>jiras-surefire-1209</artifactId>
+    <version>1.0</version>
+
+    <url>http://maven.apache.org</url>
+
+    <developers>
+        <developer>
+            <id>tibordigana</id>
+            <name>Tibor Digaňa (tibor17)</name>
+            <email>tibordig...@apache.org</email>
+            <roles>
+                <role>PMC</role>
+            </roles>
+            <timezone>Europe/Bratislava</timezone>
+        </developer>
+    </developers>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${surefire.version}</version>
+                <configuration>
+                    <forkCount>2</forkCount>
+                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.maven.surefire</groupId>
+                        <artifactId>surefire-junit47</artifactId>
+                        <version>${surefire.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ATest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ATest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ATest.java
new file mode 100644
index 0000000..cbe3f6f
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ATest.java
@@ -0,0 +1,45 @@
+package pkg;
+
+/*
+ * 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.Test;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+public class ATest
+{
+    private static int count;
+
+    @Test
+    public void testA()
+            throws Exception
+    {
+        MILLISECONDS.sleep( 500 );
+        if ( count++ != 2 )
+        {
+            throw new RuntimeException( "assert \"foo\" == \"bar\"\n"
+                                                + "             |\n"
+                                                + "             false"
+            );
+        }
+        SECONDS.sleep( 5 );
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/BTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/BTest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/BTest.java
new file mode 100644
index 0000000..f44d396
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/BTest.java
@@ -0,0 +1,42 @@
+package pkg;
+
+/*
+ * 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.Test;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+public class BTest
+{
+
+    private static int count;
+
+    @Test
+    public void testB()
+            throws InterruptedException
+    {
+        SECONDS.sleep( 2 );
+        if ( count++ != 2 )
+        {
+            throw new RuntimeException();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/CTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/CTest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/CTest.java
new file mode 100644
index 0000000..e51a29d
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/CTest.java
@@ -0,0 +1,35 @@
+package pkg;
+
+/*
+ * 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.Test;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class CTest
+{
+    @Test
+    public void testC()
+            throws InterruptedException
+    {
+        MILLISECONDS.sleep( 500 );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/DTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/DTest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/DTest.java
new file mode 100644
index 0000000..85bc666
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/DTest.java
@@ -0,0 +1,35 @@
+package pkg;
+
+/*
+ * 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.Test;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class DTest
+{
+    @Test
+    public void testD()
+            throws InterruptedException
+    {
+        MILLISECONDS.sleep( 500 );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ETest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ETest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ETest.java
new file mode 100644
index 0000000..a74e734
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1209-rerun-and-forkcount/src/test/java/pkg/ETest.java
@@ -0,0 +1,31 @@
+package pkg;
+
+/*
+ * 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.Test;
+
+public class ETest
+{
+    @Test
+    public void test()
+            throws InterruptedException
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/63963d67/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
----------------------------------------------------------------------
diff --git 
a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
 
b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
index 5c33716..83d06c5 100644
--- 
a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
+++ 
b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
@@ -36,6 +36,7 @@ import org.junit.runner.notification.StoppedByUserException;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.Queue;
 
 import static 
org.apache.maven.surefire.common.junit4.JUnit4Reflector.createDescription;
@@ -66,10 +67,16 @@ final class JUnitCoreWrapper
     void execute( TestsToRun testsToRun, Filter filter )
         throws TestSetFailedException
     {
-        execute( testsToRun, Collections.<RunListener>emptyList(), filter );
+        execute( testsToRun, true, Collections.<RunListener>emptyList(), 
filter );
     }
 
     void execute( TestsToRun testsToRun, Collection<RunListener> listeners, 
Filter filter )
+            throws TestSetFailedException
+    {
+        execute( testsToRun, false, listeners, filter );
+    }
+
+    private void execute( TestsToRun testsToRun, boolean useIterated, 
Collection<RunListener> listeners, Filter filter )
         throws TestSetFailedException
     {
         if ( testsToRun.allowEagerReading() )
@@ -78,7 +85,7 @@ final class JUnitCoreWrapper
         }
         else
         {
-            executeLazy( testsToRun, filter, listeners );
+            executeLazy( testsToRun, useIterated, filter, listeners );
         }
     }
 
@@ -101,13 +108,14 @@ final class JUnitCoreWrapper
         createRequestAndRun( filter, computer, junitCore.withReportedTests( 
tests ), tests );
     }
 
-    private void executeLazy( TestsToRun testsToRun, Filter filter, 
Collection<RunListener> listeners )
+    private void executeLazy( TestsToRun testsToRun, boolean useIterated, 
Filter filter,
+                              Collection<RunListener> listeners )
         throws TestSetFailedException
     {
         JUnitCore junitCore = createJUnitCore( notifier, listeners );
-        // in order to support LazyTestsToRun, the iterator must be used
-        for ( Class<?> clazz : testsToRun )
+        for ( Iterator<Class<?>> it = useIterated ? testsToRun.iterated() : 
testsToRun.iterator(); it.hasNext(); )
         {
+            Class<?> clazz = it.next();
             Computer computer = createComputer();
             createRequestAndRun( filter, computer, 
junitCore.withReportedTests( clazz ), clazz );
         }

Reply via email to