package org.apache.maven.plugin.surefire.booterclient;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.NotifiableTestStream;
import org.apache.maven.plugin.surefire.booterclient.output.ForkClient;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
import org.apache.maven.surefire.booter.ForkingRunListener;
import org.apache.maven.surefire.report.CategorizedReportEntry;
import org.apache.maven.surefire.report.ConsoleOutputReceiver;
import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
import org.apache.maven.surefire.report.ReportEntry;
import org.apache.maven.surefire.report.ReporterException;
import org.apache.maven.surefire.report.RunListener;
import org.apache.maven.surefire.report.SimpleReportEntry;
import org.apache.maven.surefire.report.StackTraceWriter;
import org.apache.maven.surefire.report.TestSetReportEntry;
import org.hamcrest.MatcherAssert;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.StringTokenizer;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
/**
* @author Kristian Rosenvold
*/
public class ForkingRunListenerTest
extends TestCase
{
private final ByteArrayOutputStream content, anotherContent;
private final PrintStream printStream, anotherPrintStream;
final int defaultChannel = 17;
final int anotherChannel = 18;
public ForkingRunListenerTest()
{
content = new ByteArrayOutputStream();
printStream = new PrintStream( content );
anotherContent = new ByteArrayOutputStream();
anotherPrintStream = new PrintStream( anotherContent );
}
private void reset()
{
printStream.flush();
content.reset();
}
public void testHeaderCreation()
{
final byte[] header = ForkingRunListener.createHeader( (byte) 'F', 0xCAFE );
String asString = new String( header );
assertEquals( "F,cafe," + Charset.defaultCharset().name() + ",", asString );
}
public void testHeaderCreationShort()
{
final byte[] header = ForkingRunListener.createHeader( (byte) 'F', 0xE );
String asString = new String( header );
assertEquals( "F,e," + Charset.defaultCharset().name() + ",", asString );
}
public void testSetStarting()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
TestSetReportEntry expected = createDefaultReportEntry();
standardTestRun.run().testSetStarting( expected );
standardTestRun.assertExpected( MockReporter.SET_STARTING, expected );
}
public void testSetCompleted()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
TestSetReportEntry expected = createDefaultReportEntry();
standardTestRun.run().testSetCompleted( expected );
standardTestRun.assertExpected( MockReporter.SET_COMPLETED, expected );
}
public void testStarting()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createDefaultReportEntry();
standardTestRun.run().testStarting( expected );
standardTestRun.assertExpected( MockReporter.TEST_STARTING, expected );
}
public void testStringTokenizer()
{
String test = "5,11,com.abc.TestClass,testMethod,null,22,,,";
StringTokenizer tok = new StringTokenizer( test, "," );
assertEquals( "5", tok.nextToken() );
assertEquals( "11", tok.nextToken() );
assertEquals( "com.abc.TestClass", tok.nextToken() );
assertEquals( "testMethod", tok.nextToken() );
assertEquals( "null", tok.nextToken() );
assertEquals( "22", tok.nextToken() );
assertFalse( tok.hasMoreTokens() );
}
public void testSucceded()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createDefaultReportEntry();
standardTestRun.run().testSucceeded( expected );
standardTestRun.assertExpected( MockReporter.TEST_SUCCEEDED, expected );
}
public void testFailed()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createReportEntryWithStackTrace();
standardTestRun.run().testFailed( expected );
standardTestRun.assertExpected( MockReporter.TEST_FAILED, expected );
}
public void testFailedWithCommaInMessage()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createReportEntryWithSpecialMessage( "We, the people" );
standardTestRun.run().testFailed( expected );
standardTestRun.assertExpected( MockReporter.TEST_FAILED, expected );
}
public void testFailedWithUnicodeEscapeInMessage()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createReportEntryWithSpecialMessage( "We, \\u0177 people" );
standardTestRun.run().testFailed( expected );
standardTestRun.assertExpected( MockReporter.TEST_FAILED, expected );
}
public void testFailure()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createDefaultReportEntry();
standardTestRun.run().testError( expected );
standardTestRun.assertExpected( MockReporter.TEST_ERROR, expected );
}
public void testSkipped()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createDefaultReportEntry();
standardTestRun.run().testSkipped( expected );
standardTestRun.assertExpected( MockReporter.TEST_SKIPPED, expected );
}
public void testAssumptionFailure()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ReportEntry expected = createDefaultReportEntry();
standardTestRun.run().testAssumptionFailure( expected );
standardTestRun.assertExpected( MockReporter.TEST_ASSUMPTION_FAIL, expected );
}
public void testConsole()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ConsoleLogger directConsoleReporter = (ConsoleLogger) standardTestRun.run();
directConsoleReporter.info( "HeyYou" );
standardTestRun.assertExpected( MockReporter.CONSOLE_OUTPUT, "HeyYou" );
}
public void testConsoleOutput()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
ConsoleOutputReceiver directConsoleReporter = (ConsoleOutputReceiver) standardTestRun.run();
directConsoleReporter.writeTestOutput( "HeyYou".getBytes(), 0, 6, true );
standardTestRun.assertExpected( MockReporter.STDOUT, "HeyYou" );
}
public void testSystemProperties()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
standardTestRun.run();
reset();
createForkingRunListener( defaultChannel );
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
NullConsoleLogger log = new NullConsoleLogger();
ForkClient forkStreamClient = new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log );
forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
MatcherAssert.assertThat( forkStreamClient.getTestVmSystemProperties().size(), is( greaterThan( 1 ) ) );
}
public void testMultipleEntries()
throws ReporterException, IOException
{
final StandardTestRun standardTestRun = new StandardTestRun();
standardTestRun.run();
reset();
RunListener forkingReporter = createForkingRunListener( defaultChannel );
TestSetReportEntry reportEntry = createDefaultReportEntry();
forkingReporter.testSetStarting( reportEntry );
forkingReporter.testStarting( reportEntry );
forkingReporter.testSucceeded( reportEntry );
forkingReporter.testSetCompleted( reportEntry );
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
NullConsoleLogger log = new NullConsoleLogger();
ForkClient forkStreamClient = new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log );
forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
final MockReporter reporter = (MockReporter) forkStreamClient.getReporter();
final List<String> events = reporter.getEvents();
assertEquals( MockReporter.SET_STARTING, events.get( 0 ) );
assertEquals( MockReporter.TEST_STARTING, events.get( 1 ) );
assertEquals( MockReporter.TEST_SUCCEEDED, events.get( 2 ) );
assertEquals( MockReporter.SET_COMPLETED, events.get( 3 ) );
}
public void test2DifferentChannels()
throws ReporterException, IOException
{
reset();
ReportEntry expected = createDefaultReportEntry();
final SimpleReportEntry secondExpected = createAnotherDefaultReportEntry();
new ForkingRunListener( printStream, defaultChannel, false )
.testStarting( expected );
new ForkingRunListener( anotherPrintStream, anotherChannel, false )
.testSkipped( secondExpected );
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
NotifiableTestStream notifiableTestStream = new MockNotifiableTestStream();
NullConsoleLogger log = new NullConsoleLogger();
ForkClient forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log );
forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
MockReporter reporter = (MockReporter) forkStreamClient.getReporter();
Assert.assertEquals( MockReporter.TEST_STARTING, reporter.getFirstEvent() );
Assert.assertEquals( expected, reporter.getFirstData() );
Assert.assertEquals( 1, reporter.getEvents().size() );
forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log );
forkStreamClient.consumeMultiLineContent( anotherContent.toString( "UTF-8" ) );
MockReporter reporter2 = (MockReporter) forkStreamClient.getReporter();
Assert.assertEquals( MockReporter.TEST_SKIPPED, reporter2.getFirstEvent() );
Assert.assertEquals( secondExpected, reporter2.getFirstData() );
Assert.assertEquals( 1, reporter2.getEvents().size() );
}
// Todo: Test weird characters
private SimpleReportEntry createDefaultReportEntry()
{
return new SimpleReportEntry( "com.abc.TestClass", "testMethod", 22 );
}
private SimpleReportEntry createAnotherDefaultReportEntry()
{
return new SimpleReportEntry( "com.abc.AnotherTestClass", "testAnotherMethod", 42 );
}
private SimpleReportEntry createReportEntryWithStackTrace()
{
try
{
throw new RuntimeException();
}
catch ( RuntimeException e )
{
StackTraceWriter stackTraceWriter =
new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
}
}
private SimpleReportEntry createReportEntryWithSpecialMessage( String message )
{
try
{
throw new RuntimeException( message );
}
catch ( RuntimeException e )
{
StackTraceWriter stackTraceWriter =
new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
}
}
private RunListener createForkingRunListener( Integer testSetChannel )
{
return new ForkingRunListener( printStream, testSetChannel, false );
}
private class StandardTestRun
{
private MockReporter reporter;
public RunListener run()
throws ReporterException
{
reset();
return createForkingRunListener( defaultChannel );
}
public void clientReceiveContent()
throws ReporterException, IOException
{
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
NullConsoleLogger log = new NullConsoleLogger();
final ForkClient forkStreamClient = new ForkClient( providerReporterFactory,
new MockNotifiableTestStream(), log );
forkStreamClient.consumeMultiLineContent( content.toString( ) );
reporter = (MockReporter) forkStreamClient.getReporter();
}
public String getFirstEvent()
{
return reporter.getEvents().get( 0 );
}
public ReportEntry getFirstData()
{
return (ReportEntry) reporter.getData().get( 0 );
}
private void assertExpected( String actionCode, ReportEntry expected )
throws IOException, ReporterException
{
clientReceiveContent();
assertEquals( actionCode, getFirstEvent() );
final ReportEntry firstData = getFirstData();
assertEquals( expected.getSourceName(), firstData.getSourceName() );
assertEquals( expected.getName(), firstData.getName() );
//noinspection deprecation
assertEquals( expected.getElapsed(), firstData.getElapsed() );
assertEquals( expected.getGroup(), firstData.getGroup() );
if ( expected.getStackTraceWriter() != null )
{
//noinspection ThrowableResultOfMethodCallIgnored
assertEquals( expected.getStackTraceWriter().getThrowable().getLocalizedMessage(),
firstData.getStackTraceWriter().getThrowable().getLocalizedMessage() );
assertEquals( expected.getStackTraceWriter().writeTraceToString(),
firstData.getStackTraceWriter().writeTraceToString() );
}
}
private void assertExpected( String actionCode, String expected )
throws IOException, ReporterException
{
clientReceiveContent();
assertEquals( actionCode, getFirstEvent() );
final String firstData = (String) reporter.getData().get( 0 );
assertEquals( expected, firstData );
}
}
}