View Javadoc
1   package org.apache.maven.plugin.surefire.booterclient;
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 junit.framework.Assert;
23  import junit.framework.TestCase;
24  import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.NotifiableTestStream;
25  import org.apache.maven.plugin.surefire.booterclient.output.ForkClient;
26  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
27  import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
28  import org.apache.maven.surefire.booter.ForkedChannelEncoder;
29  import org.apache.maven.surefire.booter.ForkingRunListener;
30  import org.apache.maven.surefire.report.CategorizedReportEntry;
31  import org.apache.maven.surefire.report.ConsoleOutputReceiver;
32  import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
33  import org.apache.maven.surefire.report.ReportEntry;
34  import org.apache.maven.surefire.report.ReporterException;
35  import org.apache.maven.surefire.report.RunListener;
36  import org.apache.maven.surefire.report.SimpleReportEntry;
37  import org.apache.maven.surefire.report.StackTraceWriter;
38  import org.apache.maven.surefire.report.TestSetReportEntry;
39  import org.hamcrest.MatcherAssert;
40  
41  import java.io.ByteArrayOutputStream;
42  import java.io.IOException;
43  import java.io.PrintStream;
44  import java.util.Collections;
45  import java.util.List;
46  import java.util.Map;
47  import java.util.concurrent.atomic.AtomicBoolean;
48  
49  import static org.hamcrest.Matchers.is;
50  
51  /**
52   * @author Kristian Rosenvold
53   */
54  @SuppressWarnings( "checkstyle:magicnumber" )
55  public class ForkingRunListenerTest
56      extends TestCase
57  {
58      private final ByteArrayOutputStream content, anotherContent;
59  
60      private final PrintStream printStream, anotherPrintStream;
61  
62      public ForkingRunListenerTest()
63      {
64          content = new ByteArrayOutputStream();
65          printStream = new PrintStream( content );
66  
67          anotherContent = new ByteArrayOutputStream();
68          anotherPrintStream = new PrintStream( anotherContent );
69      }
70  
71      private void reset()
72      {
73          printStream.flush();
74          content.reset();
75      }
76  
77      public void testSetStarting()
78          throws ReporterException, IOException
79      {
80          final StandardTestRun standardTestRun = new StandardTestRun();
81          TestSetReportEntry expected = createDefaultReportEntry();
82          standardTestRun.run().testSetStarting( expected );
83          standardTestRun.assertExpected( MockReporter.SET_STARTING, expected );
84      }
85  
86      public void testSetCompleted()
87          throws ReporterException, IOException
88      {
89          final StandardTestRun standardTestRun = new StandardTestRun();
90          TestSetReportEntry expected = createDefaultReportEntry();
91          standardTestRun.run().testSetCompleted( expected );
92          standardTestRun.assertExpected( MockReporter.SET_COMPLETED, expected );
93      }
94  
95      public void testStarting()
96          throws ReporterException, IOException
97      {
98          final StandardTestRun standardTestRun = new StandardTestRun();
99          ReportEntry expected = createDefaultReportEntry();
100         standardTestRun.run().testStarting( expected );
101         standardTestRun.assertExpected( MockReporter.TEST_STARTING, expected );
102     }
103 
104     public void testSucceded()
105         throws ReporterException, IOException
106     {
107         final StandardTestRun standardTestRun = new StandardTestRun();
108         ReportEntry expected = createDefaultReportEntry();
109         standardTestRun.run().testSucceeded( expected );
110         standardTestRun.assertExpected( MockReporter.TEST_SUCCEEDED, expected );
111     }
112 
113     public void testFailed()
114         throws ReporterException, IOException
115     {
116         final StandardTestRun standardTestRun = new StandardTestRun();
117         ReportEntry expected = createReportEntryWithStackTrace();
118         standardTestRun.run().testFailed( expected );
119         standardTestRun.assertExpected( MockReporter.TEST_FAILED, expected );
120     }
121 
122     public void testFailedWithCommaInMessage()
123         throws ReporterException, IOException
124     {
125         final StandardTestRun standardTestRun = new StandardTestRun();
126         ReportEntry expected = createReportEntryWithSpecialMessage( "We, the people" );
127         standardTestRun.run().testFailed( expected );
128         standardTestRun.assertExpected( MockReporter.TEST_FAILED, expected );
129     }
130 
131     public void testFailedWithUnicodeEscapeInMessage()
132         throws ReporterException, IOException
133     {
134         final StandardTestRun standardTestRun = new StandardTestRun();
135         ReportEntry expected = createReportEntryWithSpecialMessage( "We, \\u0177 people" );
136         standardTestRun.run().testFailed( expected );
137         standardTestRun.assertExpected( MockReporter.TEST_FAILED, expected );
138     }
139 
140     public void testFailure()
141         throws ReporterException, IOException
142     {
143         final StandardTestRun standardTestRun = new StandardTestRun();
144         ReportEntry expected = createDefaultReportEntry();
145         standardTestRun.run().testError( expected );
146         standardTestRun.assertExpected( MockReporter.TEST_ERROR, expected );
147     }
148 
149     public void testSkipped()
150         throws ReporterException, IOException
151     {
152         final StandardTestRun standardTestRun = new StandardTestRun();
153         ReportEntry expected = createDefaultReportEntry();
154         standardTestRun.run().testSkipped( expected );
155         standardTestRun.assertExpected( MockReporter.TEST_SKIPPED, expected );
156     }
157 
158     public void testAssumptionFailure()
159         throws ReporterException, IOException
160     {
161         final StandardTestRun standardTestRun = new StandardTestRun();
162         ReportEntry expected = createDefaultReportEntry();
163         standardTestRun.run().testAssumptionFailure( expected );
164         standardTestRun.assertExpected( MockReporter.TEST_ASSUMPTION_FAIL, expected );
165     }
166 
167     public void testConsole()
168         throws ReporterException, IOException
169     {
170         final StandardTestRun standardTestRun = new StandardTestRun();
171         ConsoleLogger directConsoleReporter = (ConsoleLogger) standardTestRun.run();
172         directConsoleReporter.info( "HeyYou" );
173         standardTestRun.assertExpected( MockReporter.CONSOLE_INFO, "HeyYou" );
174     }
175 
176     public void testConsoleOutput()
177         throws ReporterException, IOException
178     {
179         final StandardTestRun standardTestRun = new StandardTestRun();
180         ConsoleOutputReceiver directConsoleReporter = (ConsoleOutputReceiver) standardTestRun.run();
181         directConsoleReporter.writeTestOutput( "HeyYou", false, true );
182         standardTestRun.assertExpected( MockReporter.STDOUT, "HeyYou" );
183     }
184 
185     public void testSystemProperties()
186         throws ReporterException, IOException
187     {
188         final StandardTestRun standardTestRun = new StandardTestRun();
189         standardTestRun.run();
190 
191         reset();
192         createForkingRunListener();
193 
194         TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
195         NullConsoleLogger log = new NullConsoleLogger();
196         ForkClient forkStreamClient =
197                 new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, new AtomicBoolean(), 1 );
198 
199         forkStreamClient.consumeMultiLineContent( ":maven:surefire:std:out:sys-prop:normal-run:UTF-8:azE=:djE="
200                 + "\n:maven:surefire:std:out:sys-prop:normal-run:UTF-8:azI=:djI=" );
201 
202         MatcherAssert.assertThat( forkStreamClient.getTestVmSystemProperties().size(), is( 2 ) );
203     }
204 
205     public void testMultipleEntries()
206         throws ReporterException, IOException
207     {
208         final StandardTestRun standardTestRun = new StandardTestRun();
209         standardTestRun.run();
210 
211         reset();
212         RunListener forkingReporter = createForkingRunListener();
213 
214         TestSetReportEntry reportEntry = createDefaultReportEntry();
215         forkingReporter.testSetStarting( reportEntry );
216         forkingReporter.testStarting( reportEntry );
217         forkingReporter.testSucceeded( reportEntry );
218         forkingReporter.testSetCompleted( reportEntry );
219 
220         TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
221         NullConsoleLogger log = new NullConsoleLogger();
222         ForkClient forkStreamClient =
223                 new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null, 1 );
224 
225         forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
226 
227         final MockReporter reporter = (MockReporter) forkStreamClient.getReporter();
228         final List<String> events = reporter.getEvents();
229         assertEquals( MockReporter.SET_STARTING, events.get( 0 ) );
230         assertEquals( MockReporter.TEST_STARTING, events.get( 1 ) );
231         assertEquals( MockReporter.TEST_SUCCEEDED, events.get( 2 ) );
232         assertEquals( MockReporter.SET_COMPLETED, events.get( 3 ) );
233     }
234 
235     public void test2DifferentChannels()
236         throws ReporterException, IOException
237     {
238         reset();
239         ReportEntry expected = createDefaultReportEntry();
240         final SimpleReportEntry secondExpected = createAnotherDefaultReportEntry();
241 
242         new ForkingRunListener( new ForkedChannelEncoder( printStream ), false )
243                 .testStarting( expected );
244 
245         new ForkingRunListener( new ForkedChannelEncoder( anotherPrintStream ), false )
246                 .testSkipped( secondExpected );
247 
248         TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
249         NotifiableTestStream notifiableTestStream = new MockNotifiableTestStream();
250         NullConsoleLogger log = new NullConsoleLogger();
251 
252         ForkClient forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log, null, 1 );
253         forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
254 
255         MockReporter reporter = (MockReporter) forkStreamClient.getReporter();
256         Assert.assertEquals( MockReporter.TEST_STARTING, reporter.getFirstEvent() );
257         Assert.assertEquals( expected, reporter.getFirstData() );
258         Assert.assertEquals( 1, reporter.getEvents().size() );
259 
260         forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log, null, 2 );
261         forkStreamClient.consumeMultiLineContent( anotherContent.toString( "UTF-8" ) );
262         MockReporter reporter2 = (MockReporter) forkStreamClient.getReporter();
263         Assert.assertEquals( MockReporter.TEST_SKIPPED, reporter2.getFirstEvent() );
264         Assert.assertEquals( secondExpected, reporter2.getFirstData() );
265         Assert.assertEquals( 1, reporter2.getEvents().size() );
266     }
267 
268     // Todo: Test weird characters
269 
270     private SimpleReportEntry createDefaultReportEntry( Map<String, String> sysProps )
271     {
272         return new SimpleReportEntry( "com.abc.TestClass", null, "testMethod", null, null, 22, sysProps );
273     }
274 
275     private SimpleReportEntry createDefaultReportEntry()
276     {
277         return createDefaultReportEntry( Collections.<String, String>emptyMap() );
278     }
279 
280     private SimpleReportEntry createAnotherDefaultReportEntry()
281     {
282         return new SimpleReportEntry( "com.abc.AnotherTestClass", null, "testAnotherMethod", null, 42 );
283     }
284 
285     private SimpleReportEntry createReportEntryWithStackTrace()
286     {
287         try
288         {
289             throw new RuntimeException();
290         }
291         catch ( RuntimeException e )
292         {
293             StackTraceWriter stackTraceWriter =
294                 new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
295             return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
296         }
297     }
298 
299     private SimpleReportEntry createReportEntryWithSpecialMessage( String message )
300     {
301         try
302         {
303             throw new RuntimeException( message );
304         }
305         catch ( RuntimeException e )
306         {
307             StackTraceWriter stackTraceWriter =
308                 new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
309             return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
310         }
311     }
312 
313     private RunListener createForkingRunListener()
314     {
315         return new ForkingRunListener( new ForkedChannelEncoder( printStream ), false );
316     }
317 
318     private class StandardTestRun
319     {
320         private MockReporter reporter;
321 
322         public RunListener run()
323             throws ReporterException
324         {
325             reset();
326             return createForkingRunListener();
327         }
328 
329         public void clientReceiveContent()
330             throws ReporterException, IOException
331         {
332             TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
333             NullConsoleLogger log = new NullConsoleLogger();
334             final ForkClient forkStreamClient =
335                     new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null, 1 );
336             forkStreamClient.consumeMultiLineContent( content.toString( ) );
337             reporter = (MockReporter) forkStreamClient.getReporter();
338         }
339 
340         public String getFirstEvent()
341         {
342             return reporter.getEvents().get( 0 );
343         }
344 
345         public ReportEntry getFirstData()
346         {
347             return (ReportEntry) reporter.getData().get( 0 );
348         }
349 
350         private void assertExpected( String actionCode, ReportEntry expected )
351             throws IOException, ReporterException
352         {
353             clientReceiveContent();
354             assertEquals( actionCode, getFirstEvent() );
355             final ReportEntry firstData = getFirstData();
356             assertEquals( expected.getSourceName(), firstData.getSourceName() );
357             assertEquals( expected.getName(), firstData.getName() );
358             //noinspection deprecation
359             assertEquals( expected.getElapsed(), firstData.getElapsed() );
360             assertEquals( expected.getGroup(), firstData.getGroup() );
361             if ( expected.getStackTraceWriter() != null )
362             {
363                 //noinspection ThrowableResultOfMethodCallIgnored
364                 assertEquals( expected.getStackTraceWriter().getThrowable().getLocalizedMessage(),
365                               firstData.getStackTraceWriter().getThrowable().getLocalizedMessage() );
366                 assertEquals( expected.getStackTraceWriter().writeTraceToString(),
367                               firstData.getStackTraceWriter().writeTraceToString() );
368             }
369         }
370 
371         private void assertExpected( String actionCode, String expected )
372             throws IOException, ReporterException
373         {
374             clientReceiveContent();
375             assertEquals( actionCode, getFirstEvent() );
376             final String firstData = (String) reporter.getData().get( 0 );
377             assertEquals( expected, firstData );
378         }
379 
380     }
381 }