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  
38  import java.io.ByteArrayOutputStream;
39  import java.io.IOException;
40  import java.io.PrintStream;
41  import java.nio.charset.Charset;
42  import java.util.List;
43  import java.util.Properties;
44  import java.util.StringTokenizer;
45  
46  import static org.hamcrest.MatcherAssert.assertThat;
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          ReportEntry 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         ReportEntry 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         final Properties testVmSystemProperties = new Properties();
225         NullConsoleLogger log = new NullConsoleLogger();
226         ForkClient forkStreamClient = new ForkClient( providerReporterFactory, testVmSystemProperties,
227                                                       new MockNotifiableTestStream(), log );
228 
229         forkStreamClient.consumeMultiLineContent( content.toString( "utf-8" ) );
230 
231         assertThat( testVmSystemProperties.size(), is( greaterThan( 1 ) ) );
232     }
233 
234     public void testMultipleEntries()
235         throws ReporterException, IOException
236     {
237 
238         final StandardTestRun standardTestRun = new StandardTestRun();
239         standardTestRun.run();
240 
241         reset();
242         RunListener forkingReporter = createForkingRunListener( defaultChannel );
243 
244         ReportEntry reportEntry = createDefaultReportEntry();
245         forkingReporter.testSetStarting( reportEntry );
246         forkingReporter.testStarting( reportEntry );
247         forkingReporter.testSucceeded( reportEntry );
248         forkingReporter.testSetCompleted( reportEntry );
249 
250         TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
251         NullConsoleLogger log = new NullConsoleLogger();
252         ForkClient forkStreamClient = new ForkClient( providerReporterFactory, new Properties(),
253                                                       new MockNotifiableTestStream(), log );
254 
255         forkStreamClient.consumeMultiLineContent( content.toString( "utf-8" ) );
256 
257         final MockReporter reporter = (MockReporter) forkStreamClient.getReporter();
258         final List<String> events = reporter.getEvents();
259         assertEquals( MockReporter.SET_STARTING, events.get( 0 ) );
260         assertEquals( MockReporter.TEST_STARTING, events.get( 1 ) );
261         assertEquals( MockReporter.TEST_SUCCEEDED, events.get( 2 ) );
262         assertEquals( MockReporter.SET_COMPLETED, events.get( 3 ) );
263     }
264 
265     public void test2DifferentChannels()
266         throws ReporterException, IOException
267     {
268         reset();
269         ReportEntry expected = createDefaultReportEntry();
270         final SimpleReportEntry secondExpected = createAnotherDefaultReportEntry();
271 
272         new ForkingRunListener( printStream, defaultChannel, false )
273                 .testStarting( expected );
274 
275         new ForkingRunListener( anotherPrintStream, anotherChannel, false )
276                 .testSkipped( secondExpected );
277 
278         TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
279         Properties vmProps = new Properties();
280         NotifiableTestStream notifiableTestStream = new MockNotifiableTestStream();
281         NullConsoleLogger log = new NullConsoleLogger();
282 
283         ForkClient forkStreamClient = new ForkClient( providerReporterFactory, vmProps, notifiableTestStream, log );
284         forkStreamClient.consumeMultiLineContent( content.toString( "utf-8" ) );
285 
286         MockReporter reporter = (MockReporter) forkStreamClient.getReporter();
287         Assert.assertEquals( MockReporter.TEST_STARTING, reporter.getFirstEvent() );
288         Assert.assertEquals( expected, reporter.getFirstData() );
289         Assert.assertEquals( 1, reporter.getEvents().size() );
290 
291         forkStreamClient = new ForkClient( providerReporterFactory, vmProps, notifiableTestStream, log );
292         forkStreamClient.consumeMultiLineContent( anotherContent.toString( "utf-8" ) );
293         MockReporter reporter2 = (MockReporter) forkStreamClient.getReporter();
294         Assert.assertEquals( MockReporter.TEST_SKIPPED, reporter2.getFirstEvent() );
295         Assert.assertEquals( secondExpected, reporter2.getFirstData() );
296         Assert.assertEquals( 1, reporter2.getEvents().size() );
297     }
298 
299     // Todo: Test weird characters
300 
301     private SimpleReportEntry createDefaultReportEntry()
302     {
303         return new SimpleReportEntry( "com.abc.TestClass", "testMethod", 22 );
304     }
305 
306     private SimpleReportEntry createAnotherDefaultReportEntry()
307     {
308         return new SimpleReportEntry( "com.abc.AnotherTestClass", "testAnotherMethod", 42 );
309     }
310 
311     private SimpleReportEntry createReportEntryWithStackTrace()
312     {
313         try
314         {
315             throw new RuntimeException();
316         }
317         catch ( RuntimeException e )
318         {
319             StackTraceWriter stackTraceWriter =
320                 new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
321             return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
322         }
323     }
324 
325     private SimpleReportEntry createReportEntryWithSpecialMessage( String message )
326     {
327         try
328         {
329             throw new RuntimeException( message );
330         }
331         catch ( RuntimeException e )
332         {
333             StackTraceWriter stackTraceWriter =
334                 new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
335             return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
336         }
337     }
338 
339     private RunListener createForkingRunListener( Integer testSetChannel )
340     {
341         return new ForkingRunListener( printStream, testSetChannel, false );
342     }
343 
344     private class StandardTestRun
345     {
346         private MockReporter reporter;
347 
348         public RunListener run()
349             throws ReporterException
350         {
351             reset();
352             return createForkingRunListener( defaultChannel );
353         }
354 
355         public void clientReceiveContent()
356             throws ReporterException, IOException
357         {
358             TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
359             NullConsoleLogger log = new NullConsoleLogger();
360             final ForkClient forkStreamClient = new ForkClient( providerReporterFactory, new Properties(),
361                                                                 new MockNotifiableTestStream(), log );
362             forkStreamClient.consumeMultiLineContent( content.toString( ) );
363             reporter = (MockReporter) forkStreamClient.getReporter();
364         }
365 
366         public String getFirstEvent()
367         {
368             return reporter.getEvents().get( 0 );
369         }
370 
371         public ReportEntry getFirstData()
372         {
373             return (ReportEntry) reporter.getData().get( 0 );
374         }
375 
376         private void assertExpected( String actionCode, ReportEntry expected )
377             throws IOException, ReporterException
378         {
379             clientReceiveContent();
380             assertEquals( actionCode, getFirstEvent() );
381             final ReportEntry firstData = getFirstData();
382             assertEquals( expected.getSourceName(), firstData.getSourceName() );
383             assertEquals( expected.getName(), firstData.getName() );
384             //noinspection deprecation
385             assertEquals( expected.getElapsed(), firstData.getElapsed() );
386             assertEquals( expected.getGroup(), firstData.getGroup() );
387             if ( expected.getStackTraceWriter() != null )
388             {
389                 //noinspection ThrowableResultOfMethodCallIgnored
390                 assertEquals( expected.getStackTraceWriter().getThrowable().getLocalizedMessage(),
391                               firstData.getStackTraceWriter().getThrowable().getLocalizedMessage() );
392                 assertEquals( expected.getStackTraceWriter().writeTraceToString(),
393                               firstData.getStackTraceWriter().writeTraceToString() );
394             }
395         }
396 
397         private void assertExpected( String actionCode, String expected )
398             throws IOException, ReporterException
399         {
400             clientReceiveContent();
401             assertEquals( actionCode, getFirstEvent() );
402             final String firstData = (String) reporter.getData().get( 0 );
403             assertEquals( expected, firstData );
404         }
405 
406     }
407 }