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