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