Repository: maven-surefire
Updated Branches:
  refs/heads/master af96520ef -> 5cb02c375


[SUREFIRE-1098] Fix runOrder=balanced is not working


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

Branch: refs/heads/master
Commit: 5cb02c3752a62c84d0d773f12ce57348aaa9bda7
Parents: af96520
Author: tibordigana <[email protected]>
Authored: Sun Sep 28 23:03:10 2014 +0200
Committer: tibordigana <[email protected]>
Committed: Tue Sep 30 19:07:51 2014 +0200

----------------------------------------------------------------------
 .../plugin/surefire/AbstractSurefireMojo.java   |  13 +-
 .../surefire/its/fixture/OutputValidator.java   |   7 ++
 .../jiras/Surefire1098BalancedRunOrderIT.java   | 119 +++++++++++++++++++
 .../surefire-1098-balanced-runorder/pom.xml     |  66 ++++++++++
 .../src/test/java/jiras/surefire1098/ATest.java |  34 ++++++
 .../src/test/java/jiras/surefire1098/BTest.java |  34 ++++++
 .../src/test/java/jiras/surefire1098/CTest.java |  34 ++++++
 .../src/test/java/jiras/surefire1098/DTest.java |  34 ++++++
 8 files changed, 333 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
----------------------------------------------------------------------
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 6115cf3..3d5e149 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
@@ -651,8 +651,8 @@ public abstract class AbstractSurefireMojo
      * <p/>
      * Failed first will run tests that failed on previous run first, as well 
as new tests for this run.
      * <p/>
-     * Balanced is only relevant with parallel=classes, and will try to 
optimize the run-order of the tests to
-     * make all tests complete at the same time, reducing the overall 
execution time.
+     * Balanced is only relevant with parallel=classes, and will try to 
optimize the run-order of the tests reducing
+     * the overall execution time. Initially a statistics file is created and 
every next test run will reorder classes.
      * <p/>
      * Note that the statistics are stored in a file named .surefire-XXXXXXXXX 
beside pom.xml, and should not
      * be checked into version control. The "XXXXX" is the SHA1 checksum of 
the entire surefire configuration,
@@ -938,18 +938,17 @@ public abstract class AbstractSurefireMojo
     {
         SurefireProperties effectiveProperties = setupProperties();
         ClassLoaderConfiguration classLoaderConfiguration = 
getClassLoaderConfiguration( isForking() );
-
+        provider.addProviderProperties();
         RunOrderParameters runOrderParameters =
             new RunOrderParameters( getRunOrder(), getStatisticsFileName( 
getConfigChecksum() ) );
 
-        final RunResult result;
         if ( isNotForking() )
         {
             createCopyAndReplaceForkNumPlaceholder( effectiveProperties, 1 
).copyToSystemProperties();
 
             InPluginVMSurefireStarter surefireStarter =
                 createInprocessStarter( provider, classLoaderConfiguration, 
runOrderParameters );
-            result = surefireStarter.runSuitesInProcess( scanResult );
+            return surefireStarter.runSuitesInProcess( scanResult );
         }
         else
         {
@@ -965,7 +964,7 @@ public abstract class AbstractSurefireMojo
                 ForkStarter forkStarter =
                     createForkStarter( provider, forkConfiguration, 
classLoaderConfiguration, runOrderParameters,
                                        getLog() );
-                result = forkStarter.run( effectiveProperties, scanResult );
+                return forkStarter.run( effectiveProperties, scanResult );
             }
             finally
             {
@@ -973,7 +972,6 @@ public abstract class AbstractSurefireMojo
                 cleanupForkConfiguration( forkConfiguration );
             }
         }
-        return result;
     }
 
 
@@ -1434,7 +1432,6 @@ public abstract class AbstractSurefireMojo
 
         try
         {
-            provider.addProviderProperties();
             // cache the provider lookup
             String providerName = provider.getProviderName();
             Classpath providerClasspath = ClasspathCache.getCachedClassPath( 
providerName );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
 
b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
index 14dfc47..11d3869 100644
--- 
a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
+++ 
b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
@@ -22,6 +22,7 @@ package org.apache.maven.surefire.its.fixture;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.util.Collection;
 import java.util.List;
 
 import org.apache.commons.io.FileUtils;
@@ -87,6 +88,12 @@ public class OutputValidator
         }
     }
 
+    public Collection<String> loadLogLines()
+        throws VerificationException
+    {
+        return verifier.loadFile( verifier.getBasedir(), 
verifier.getLogFileName(), false );
+    }
+
     public List<String> loadFile( File file, Charset charset )
     {
         //noinspection unchecked

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1098BalancedRunOrderIT.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1098BalancedRunOrderIT.java
 
b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1098BalancedRunOrderIT.java
new file mode 100644
index 0000000..e93921b
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1098BalancedRunOrderIT.java
@@ -0,0 +1,119 @@
+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.OutputValidator;
+import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.apache.maven.surefire.its.fixture.SurefireLauncher;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.AnyOf.anyOf;
+
+/**
+ * The purpose of this IT is to assert that the run order of test classes is 
according to the settings:<p/>
+ *
+ * runOrder=balanced<p/>
+ * parallel=classes<p/>
+ * threadCount=2<p/>
+ * perCoreThreadCount=false<p/>
+ * <p/>
+ * The list of tests should be reordered to (DTest, CTest, BTest, ATest) in 
the second run.
+ *
+ * @author <a href="mailto:[email protected]";>Tibor Digana (tibor17)</a>
+ * @see {@linkplain https://jira.codehaus.org/browse/SUREFIRE-1098}
+ * @since 2.18
+ */
+public class Surefire1098BalancedRunOrderIT
+    extends SurefireJUnit4IntegrationTestCase
+{
+
+    @Test
+    public void reorderedParallelClasses()
+        throws VerificationException
+    {
+        SurefireLauncher launcher = unpack();
+
+        launcher
+            // .runOrder( "balanced" ) call it in 3.x and remove it in 
surefire-1098-balanced-runorder/pom.xml
+            // as soon as there is prefix available "failsafe" and "surefire" 
in system property for this parameter.
+            .parallelClasses().threadCount( 2 ).disablePerCoreThreadCount()
+            .executeTest().verifyErrorFree( 4 );
+
+        OutputValidator validator =
+            launcher
+                // .runOrder( "balanced" ) call it in 3.x and remove it in 
surefire-1098-balanced-runorder/pom.xml
+                // as soon as there is prefix available "failsafe" and 
"surefire" in system property for this parameter.
+                .parallelClasses().threadCount( 2 ).disablePerCoreThreadCount()
+                .executeTest().verifyErrorFree( 4 );
+
+        List<String> log = printOnlyTestLines( validator );
+        assertThat( log.size(), is( 4 ) );
+        Collections.sort( log );
+        final int[] threadPoolIdsOfLongestTest = extractThreadPoolIds( 
log.get( 3 ) );
+        final int pool = threadPoolIdsOfLongestTest[0];
+        int thread = threadPoolIdsOfLongestTest[1];
+        assertThat( thread, anyOf( is( 1 ), is( 2 ) ) );
+        thread = thread == 1 ? 2 : 1;
+        // If the longest test class DTest is running in pool-2-thread-1, the 
others should run in pool-2-thread-2
+        // and vice versa.
+        assertThat( log.get( 0 ), is( testLine( "A", pool, thread ) ) );
+        assertThat( log.get( 1 ), is( testLine( "B", pool, thread ) ) );
+        assertThat( log.get( 2 ), is( testLine( "C", pool, thread ) ) );
+    }
+
+    private SurefireLauncher unpack()
+    {
+        return unpack( "surefire-1098-balanced-runorder" );
+    }
+
+    private static List<String> printOnlyTestLines( OutputValidator validator )
+        throws VerificationException
+    {
+        List<String> log = new ArrayList<String>( validator.loadLogLines() );
+        for ( Iterator<String> it = log.iterator(); it.hasNext(); ) {
+            String line = it.next();
+            if ( !line.startsWith( "class jiras.surefire1098." ) ) {
+                it.remove();
+            }
+        }
+        return log;
+    }
+
+    private static int[] extractThreadPoolIds(String logLine)
+    {
+        //Example to parse "class jiras.surefire1098.DTest pool-2-thread-1" 
into {2, 1}.
+        String t = logLine.split( " " )[2];
+        String[] ids = t.split( "-" );
+        return new int[]{ Integer.parseInt( ids[1] ), Integer.parseInt( ids[3] 
)};
+    }
+
+    private String testLine(String test, int pool, int thread)
+    {
+        return String.format( "class jiras.surefire1098.%sTest 
pool-%d-thread-%d", test, pool, thread );
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/pom.xml
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/pom.xml
 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/pom.xml
new file mode 100644
index 0000000..db4d4a7
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/pom.xml
@@ -0,0 +1,66 @@
+<?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/maven-v4_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>jiras-surefire-1098</artifactId>
+  <version>1.0</version>
+  <url>http://maven.apache.org</url>
+  <contributors>
+    <contributor>
+      <name>Tibor Digana (tibor17)</name>
+      <email>[email protected]</email>
+      <timezone>+1</timezone>
+    </contributor>
+  </contributors>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.7</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.5.1</version>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <runOrder>balanced</runOrder>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/ATest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/ATest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/ATest.java
new file mode 100644
index 0000000..bcacf89
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/ATest.java
@@ -0,0 +1,34 @@
+package jiras.surefire1098;
+
+/*
+ * 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 java.util.concurrent.TimeUnit;
+
+public final class ATest {
+
+    @Test
+    public void someMethod() throws InterruptedException {
+        System.out.println(getClass() + " " + 
Thread.currentThread().getName());
+        TimeUnit.SECONDS.sleep(1);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/BTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/BTest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/BTest.java
new file mode 100644
index 0000000..a9a52b8
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/BTest.java
@@ -0,0 +1,34 @@
+package jiras.surefire1098;
+
+/*
+ * 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 java.util.concurrent.TimeUnit;
+
+public final class BTest {
+
+    @Test
+    public void someMethod() throws InterruptedException {
+        System.out.println(getClass() + " " + 
Thread.currentThread().getName());
+        TimeUnit.SECONDS.sleep(2);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/CTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/CTest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/CTest.java
new file mode 100644
index 0000000..63e4e0f
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/CTest.java
@@ -0,0 +1,34 @@
+package jiras.surefire1098;
+
+/*
+ * 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 java.util.concurrent.TimeUnit;
+
+public final class CTest {
+
+    @Test
+    public void someMethod() throws InterruptedException {
+        System.out.println(getClass() + " " + 
Thread.currentThread().getName());
+        TimeUnit.SECONDS.sleep(4);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5cb02c37/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/DTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/DTest.java
 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/DTest.java
new file mode 100644
index 0000000..a97640e
--- /dev/null
+++ 
b/surefire-integration-tests/src/test/resources/surefire-1098-balanced-runorder/src/test/java/jiras/surefire1098/DTest.java
@@ -0,0 +1,34 @@
+package jiras.surefire1098;
+
+/*
+ * 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 java.util.concurrent.TimeUnit;
+
+public final class DTest {
+
+    @Test
+    public void someMethod() throws InterruptedException {
+        System.out.println(getClass() + " " + 
Thread.currentThread().getName());
+        TimeUnit.SECONDS.sleep(8);
+    }
+
+}

Reply via email to