View Javadoc
1   package org.apache.maven.surefire.booter;
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.surefire.shared.io.FileUtils;
23  import org.junit.Test;
24  
25  import java.io.File;
26  import java.io.FileInputStream;
27  import java.io.InputStream;
28  import java.lang.management.ManagementFactory;
29  import java.lang.management.ThreadInfo;
30  import java.lang.management.ThreadMXBean;
31  import java.nio.charset.StandardCharsets;
32  import java.util.ArrayList;
33  import java.util.Collection;
34  import java.util.concurrent.ScheduledExecutorService;
35  import java.util.concurrent.ScheduledThreadPoolExecutor;
36  import java.util.concurrent.Semaphore;
37  import java.util.concurrent.TimeUnit;
38  
39  import static java.nio.charset.StandardCharsets.UTF_8;
40  import static org.fest.assertions.Assertions.assertThat;
41  import static org.powermock.reflect.Whitebox.invokeMethod;
42  
43  /**
44   * Tests for {@link ForkedBooter}.
45   */
46  @SuppressWarnings( "checkstyle:magicnumber" )
47  public class ForkedBooterTest
48  {
49      @Test
50      public void shouldGenerateThreadDump() throws Exception
51      {
52          Collection<String> threadNames = new ArrayList<>();
53          ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
54          for ( ThreadInfo threadInfo : threadMXBean.getThreadInfo( threadMXBean.getAllThreadIds(), 100 ) )
55          {
56              threadNames.add( threadInfo.getThreadName() );
57          }
58  
59          String dump = invokeMethod( ForkedBooter.class, "generateThreadDump" );
60  
61          for ( String threadName : threadNames )
62          {
63              assertThat( dump )
64                      .contains( "\"" + threadName + "\"" );
65          }
66  
67          assertThat( dump )
68                  .contains( "   java.lang.Thread.State: " )
69                  .contains( "        at " );
70      }
71  
72      @Test
73      public void shouldFindCurrentProcessName() throws Exception
74      {
75          String process = ManagementFactory.getRuntimeMXBean().getName();
76          String expected = invokeMethod( ForkedBooter.class, "getProcessName" );
77          assertThat( process ).isEqualTo( expected );
78      }
79  
80      @Test
81      public void shouldNotBeDebugMode() throws Exception
82      {
83          boolean expected = invokeMethod( ForkedBooter.class, "isDebugging" );
84          assertThat( expected ).isFalse();
85      }
86  
87      @Test
88      public void shouldReadSurefireProperties() throws Exception
89      {
90          File target = new File( System.getProperty( "user.dir", "target" ) );
91          File tmpDir = new File( target, "ForkedBooterTest.1" );
92          assertThat( tmpDir.mkdirs() )
93                  .isTrue();
94  
95          try
96          {
97              try ( InputStream is = invokeMethod( ForkedBooter.class, "createSurefirePropertiesIfFileExists",
98                      tmpDir.getCanonicalPath(), "surefire.properties" ) )
99              {
100                 assertThat( is )
101                         .isNull();
102             }
103 
104             File props = new File( tmpDir, "surefire.properties" );
105 
106             assertThat( props.createNewFile() )
107                     .isTrue();
108 
109             FileUtils.write( props, "key=value", UTF_8 );
110 
111             try ( InputStream is2 = invokeMethod( ForkedBooter.class, "createSurefirePropertiesIfFileExists",
112                     tmpDir.getCanonicalPath(), "surefire.properties" ) )
113             {
114                 assertThat( is2 )
115                         .isNotNull()
116                         .isInstanceOf( FileInputStream.class );
117 
118                 byte[] propsContent = new byte[20];
119                 int length = is2.read( propsContent );
120 
121                 assertThat( new String( propsContent, 0, length ) )
122                         .isEqualTo( "key=value" );
123             }
124         }
125         finally
126         {
127             FileUtils.deleteDirectory( tmpDir );
128         }
129     }
130 
131     @Test
132     public void shouldCreateScheduler() throws Exception
133     {
134         ScheduledExecutorService scheduler = null;
135         try
136         {
137             scheduler = invokeMethod( ForkedBooter.class, "createPingScheduler" );
138             assertThat( scheduler )
139                     .isNotNull();
140         }
141         finally
142         {
143             if ( scheduler != null )
144             {
145                 scheduler.shutdownNow();
146             }
147         }
148     }
149 
150     @Test( timeout = 10_000 )
151     public void testBarrier1() throws Exception
152     {
153         Semaphore semaphore = new Semaphore( 2 );
154         boolean acquiredOnePermit = invokeMethod( ForkedBooter.class, "acquireOnePermit", semaphore, 30_000L );
155 
156         assertThat( acquiredOnePermit ).isTrue();
157         assertThat( semaphore.availablePermits() ).isEqualTo( 1 );
158     }
159 
160     @Test
161     public void testBarrier2() throws Exception
162     {
163         Semaphore semaphore = new Semaphore( 0 );
164         Thread.currentThread().interrupt();
165         try
166         {
167             boolean acquiredOnePermit = invokeMethod( ForkedBooter.class, "acquireOnePermit", semaphore, 30_000L );
168 
169             assertThat( acquiredOnePermit ).isTrue();
170             assertThat( semaphore.availablePermits() ).isEqualTo( 0 );
171         }
172         finally
173         {
174             assertThat( Thread.interrupted() ).isFalse();
175         }
176     }
177 
178     @Test
179     public void testScheduler() throws Exception
180     {
181         ScheduledThreadPoolExecutor executor = invokeMethod( ForkedBooter.class, "createPingScheduler" );
182         executor.shutdown();
183         assertThat( executor.getCorePoolSize() ).isEqualTo( 1 );
184         assertThat( executor.getKeepAliveTime( TimeUnit.SECONDS ) ).isEqualTo( 3L );
185         assertThat( executor.getMaximumPoolSize() ).isEqualTo( 2 );
186     }
187 
188     @Test
189     public void testIsDebug() throws Exception
190     {
191         boolean isDebug = invokeMethod( ForkedBooter.class, "isDebugging" );
192         assertThat( isDebug ).isFalse();
193     }
194 
195     @Test
196     public void testPropsNotExist() throws Exception
197     {
198         String target = System.getProperty( "user.dir" );
199         String file = "not exists";
200         InputStream is = invokeMethod( ForkedBooter.class, "createSurefirePropertiesIfFileExists", target, file );
201         assertThat( is ).isNull();
202     }
203 
204     @Test
205     public void testPropsExist() throws Exception
206     {
207         File props = File.createTempFile( "surefire", ".properties" );
208         String target = props.getParent();
209         String file = props.getName();
210         FileUtils.write( props, "Hi", StandardCharsets.US_ASCII );
211         try ( InputStream is =
212                       invokeMethod( ForkedBooter.class, "createSurefirePropertiesIfFileExists", target, file ) )
213         {
214             assertThat( is ).isNotNull();
215             byte[] data = new byte[5];
216             int bytes = is.read( data );
217             assertThat( bytes ).isEqualTo( 2 );
218             assertThat( data[0] ).isEqualTo( (byte) 'H' );
219             assertThat( data[1] ).isEqualTo( (byte) 'i' );
220         }
221     }
222 
223     @Test
224     public void testThreadDump() throws Exception
225     {
226         String threads = invokeMethod( ForkedBooter.class, "generateThreadDump" );
227         assertThat( threads )
228                 .isNotNull();
229         assertThat( threads )
230                 .contains( "\"main\"" )
231                 .contains( "java.lang.Thread.State: RUNNABLE" );
232     }
233 }