View Javadoc
1   package org.apache.maven.surefire.its.jiras;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.it.VerificationException;
23  import org.apache.maven.surefire.its.fixture.OutputValidator;
24  import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
25  import org.apache.maven.surefire.its.fixture.SurefireLauncher;
26  import org.junit.Test;
27  
28  import java.util.ArrayList;
29  import java.util.Collections;
30  import java.util.Iterator;
31  import java.util.List;
32  
33  import static org.junit.Assert.assertThat;
34  import static org.hamcrest.core.Is.is;
35  import static org.hamcrest.core.AnyOf.anyOf;
36  
37  /**
38   * The purpose of this IT is to assert that the run order of test classes is according to the settings:<br>
39   *
40   * runOrder=balanced<br>
41   * parallel=classes<br>
42   * threadCount=2<br>
43   * perCoreThreadCount=false<br>
44   * <br>
45   * The list of tests should be reordered to (DTest, CTest, BTest, ATest) in the second run.
46   *
47   * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
48   * @see <a href="https://issues.apache.org/jira/browse/SUREFIRE-1098">SUREFIRE-1098</a>
49   * @since 2.18
50   */
51  public class Surefire1098BalancedRunOrderIT
52      extends SurefireJUnit4IntegrationTestCase
53  {
54  
55      @Test
56      public void reorderedParallelClasses()
57          throws VerificationException
58      {
59          SurefireLauncher launcher = unpack();
60  
61          launcher
62              // .runOrder( "balanced" ) call it in 3.x and remove it in surefire-1098-balanced-runorder/pom.xml
63              // as soon as there is prefix available "failsafe" and "surefire" in system property for this parameter.
64              .parallelClasses().threadCount( 2 ).disablePerCoreThreadCount()
65              .executeTest().verifyErrorFree( 4 );
66  
67          OutputValidator validator =
68              launcher
69                  // .runOrder( "balanced" ) call it in 3.x and remove it in surefire-1098-balanced-runorder/pom.xml
70                  // as soon as there is prefix available "failsafe" and "surefire" in system property for this parameter.
71                  .parallelClasses().threadCount( 2 ).disablePerCoreThreadCount()
72                  .executeTest().verifyErrorFree( 4 );
73  
74          List<String> log = printOnlyTestLines( validator );
75          assertThat( log.size(), is( 4 ) );
76          Collections.sort( log );
77          final int[] threadPoolIdsOfLongestTest = extractThreadPoolIds( log.get( 3 ) );
78          final int pool = threadPoolIdsOfLongestTest[0];
79          int thread = threadPoolIdsOfLongestTest[1];
80          assertThat( thread, anyOf( is( 1 ), is( 2 ) ) );
81          thread = thread == 1 ? 2 : 1;
82          // If the longest test class DTest is running in pool-2-thread-1, the others should run in pool-2-thread-2
83          // and vice versa.
84          assertThat( log.get( 0 ), is( testLine( "A", pool, thread ) ) );
85          assertThat( log.get( 1 ), is( testLine( "B", pool, thread ) ) );
86          assertThat( log.get( 2 ), is( testLine( "C", pool, thread ) ) );
87      }
88  
89      private SurefireLauncher unpack()
90      {
91          return unpack( "surefire-1098-balanced-runorder" );
92      }
93  
94      private static List<String> printOnlyTestLines( OutputValidator validator )
95          throws VerificationException
96      {
97          List<String> log = new ArrayList<>( validator.loadLogLines() );
98          for ( Iterator<String> it = log.iterator(); it.hasNext(); ) {
99              String line = it.next();
100             if ( !line.startsWith( "class jiras.surefire1098." ) ) {
101                 it.remove();
102             }
103         }
104         return log;
105     }
106 
107     private static int[] extractThreadPoolIds(String logLine)
108     {
109         //Example to parse "class jiras.surefire1098.DTest pool-2-thread-1" into {2, 1}.
110         String t = logLine.split( " " )[2];
111         String[] ids = t.split( "-" );
112         return new int[]{ Integer.parseInt( ids[1] ), Integer.parseInt( ids[3] )};
113     }
114 
115     private String testLine(String test, int pool, int thread)
116     {
117         return String.format( "class jiras.surefire1098.%sTest pool-%d-thread-%d", test, pool, thread );
118     }
119 }