| package org.apache.maven.plugin.surefire.report; |
| |
| /* |
| * 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 java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.apache.maven.plugin.surefire.log.api.ConsoleLogger; |
| import org.apache.maven.plugin.surefire.runorder.StatisticsReporter; |
| import org.apache.maven.surefire.report.ConsoleOutputReceiver; |
| import org.apache.maven.surefire.report.ReportEntry; |
| import org.apache.maven.surefire.report.RunListener; |
| import org.apache.maven.surefire.report.TestSetReportEntry; |
| |
| import static org.apache.maven.plugin.surefire.report.ReportEntryType.ERROR; |
| import static org.apache.maven.plugin.surefire.report.ReportEntryType.FAILURE; |
| import static org.apache.maven.plugin.surefire.report.ReportEntryType.SKIPPED; |
| import static org.apache.maven.plugin.surefire.report.ReportEntryType.SUCCESS; |
| |
| /** |
| * Reports data for a single test set. |
| * <br> |
| * |
| * @author Kristian Rosenvold |
| */ |
| public class TestSetRunListener |
| implements RunListener, ConsoleOutputReceiver, ConsoleLogger |
| { |
| private final TestSetStats detailsForThis; |
| |
| private List<TestMethodStats> testMethodStats; |
| |
| private Utf8RecodingDeferredFileOutputStream testStdOut = initDeferred( "stdout" ); |
| |
| private Utf8RecodingDeferredFileOutputStream testStdErr = initDeferred( "stderr" ); |
| |
| private Utf8RecodingDeferredFileOutputStream initDeferred( String channel ) |
| { |
| return new Utf8RecodingDeferredFileOutputStream( channel ); |
| } |
| |
| private final TestcycleConsoleOutputReceiver consoleOutputReceiver; |
| |
| private final boolean briefOrPlainFormat; |
| |
| private final StatelessXmlReporter simpleXMLReporter; |
| |
| private final ConsoleReporter consoleReporter; |
| |
| private final FileReporter fileReporter; |
| |
| private final StatisticsReporter statisticsReporter; |
| |
| @SuppressWarnings( "checkstyle:parameternumber" ) |
| public TestSetRunListener( ConsoleReporter consoleReporter, FileReporter fileReporter, |
| StatelessXmlReporter simpleXMLReporter, |
| TestcycleConsoleOutputReceiver consoleOutputReceiver, |
| StatisticsReporter statisticsReporter, boolean trimStackTrace, |
| boolean isPlainFormat, boolean briefOrPlainFormat ) |
| { |
| this.consoleReporter = consoleReporter; |
| this.fileReporter = fileReporter; |
| this.statisticsReporter = statisticsReporter; |
| this.simpleXMLReporter = simpleXMLReporter; |
| this.consoleOutputReceiver = consoleOutputReceiver; |
| this.briefOrPlainFormat = briefOrPlainFormat; |
| detailsForThis = new TestSetStats( trimStackTrace, isPlainFormat ); |
| testMethodStats = new ArrayList<TestMethodStats>(); |
| } |
| |
| @Override |
| public boolean isDebugEnabled() |
| { |
| return consoleReporter.getConsoleLogger().isDebugEnabled(); |
| } |
| |
| @Override |
| public void debug( String message ) |
| { |
| consoleReporter.getConsoleLogger().debug( trimTrailingNewLine( message ) ); |
| } |
| |
| @Override |
| public boolean isInfoEnabled() |
| { |
| return consoleReporter.getConsoleLogger().isInfoEnabled(); |
| } |
| |
| @Override |
| public void info( String message ) |
| { |
| consoleReporter.getConsoleLogger().info( trimTrailingNewLine( message ) ); |
| } |
| |
| @Override |
| public boolean isWarnEnabled() |
| { |
| return consoleReporter.getConsoleLogger().isWarnEnabled(); |
| } |
| |
| @Override |
| public void warning( String message ) |
| { |
| consoleReporter.getConsoleLogger().warning( trimTrailingNewLine( message ) ); |
| } |
| |
| @Override |
| public boolean isErrorEnabled() |
| { |
| return consoleReporter.getConsoleLogger().isErrorEnabled(); |
| } |
| |
| @Override |
| public void error( String message ) |
| { |
| consoleReporter.getConsoleLogger().error( trimTrailingNewLine( message ) ); |
| } |
| |
| @Override |
| public void error( String message, Throwable t ) |
| { |
| consoleReporter.getConsoleLogger().error( message, t ); |
| } |
| |
| @Override |
| public void error( Throwable t ) |
| { |
| consoleReporter.getConsoleLogger().error( t ); |
| } |
| |
| @Override |
| public void writeTestOutput( byte[] buf, int off, int len, boolean stdout ) |
| { |
| try |
| { |
| if ( stdout ) |
| { |
| testStdOut.write( buf, off, len ); |
| } |
| else |
| { |
| testStdErr.write( buf, off, len ); |
| } |
| consoleOutputReceiver.writeTestOutput( buf, off, len, stdout ); |
| } |
| catch ( IOException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| } |
| |
| @Override |
| public void testSetStarting( TestSetReportEntry report ) |
| { |
| detailsForThis.testSetStart(); |
| consoleReporter.testSetStarting( report ); |
| consoleOutputReceiver.testSetStarting( report ); |
| } |
| |
| private void clearCapture() |
| { |
| testStdOut = initDeferred( "stdout" ); |
| testStdErr = initDeferred( "stderr" ); |
| } |
| |
| @Override |
| public void testSetCompleted( TestSetReportEntry report ) |
| { |
| final WrappedReportEntry wrap = wrapTestSet( report ); |
| final List<String> testResults = |
| briefOrPlainFormat ? detailsForThis.getTestResults() : Collections.<String>emptyList(); |
| fileReporter.testSetCompleted( wrap, detailsForThis, testResults ); |
| simpleXMLReporter.testSetCompleted( wrap, detailsForThis ); |
| statisticsReporter.testSetCompleted(); |
| consoleReporter.testSetCompleted( wrap, detailsForThis, testResults ); |
| consoleOutputReceiver.testSetCompleted( wrap ); |
| consoleReporter.reset(); |
| |
| wrap.getStdout().free(); |
| wrap.getStdErr().free(); |
| |
| addTestMethodStats(); |
| detailsForThis.reset(); |
| clearCapture(); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Test |
| // ---------------------------------------------------------------------- |
| |
| @Override |
| public void testStarting( ReportEntry report ) |
| { |
| detailsForThis.testStart(); |
| } |
| |
| @Override |
| public void testSucceeded( ReportEntry reportEntry ) |
| { |
| WrappedReportEntry wrapped = wrap( reportEntry, SUCCESS ); |
| detailsForThis.testSucceeded( wrapped ); |
| statisticsReporter.testSucceeded( reportEntry ); |
| clearCapture(); |
| } |
| |
| @Override |
| public void testError( ReportEntry reportEntry ) |
| { |
| WrappedReportEntry wrapped = wrap( reportEntry, ERROR ); |
| detailsForThis.testError( wrapped ); |
| statisticsReporter.testError( reportEntry ); |
| clearCapture(); |
| } |
| |
| @Override |
| public void testFailed( ReportEntry reportEntry ) |
| { |
| WrappedReportEntry wrapped = wrap( reportEntry, FAILURE ); |
| detailsForThis.testFailure( wrapped ); |
| statisticsReporter.testFailed( reportEntry ); |
| clearCapture(); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Counters |
| // ---------------------------------------------------------------------- |
| |
| @Override |
| public void testSkipped( ReportEntry reportEntry ) |
| { |
| WrappedReportEntry wrapped = wrap( reportEntry, SKIPPED ); |
| detailsForThis.testSkipped( wrapped ); |
| statisticsReporter.testSkipped( reportEntry ); |
| clearCapture(); |
| } |
| |
| @Override |
| public void testExecutionSkippedByUser() |
| { |
| } |
| |
| @Override |
| public void testAssumptionFailure( ReportEntry report ) |
| { |
| testSkipped( report ); |
| } |
| |
| private WrappedReportEntry wrap( ReportEntry other, ReportEntryType reportEntryType ) |
| { |
| int estimatedElapsed = 0; |
| if ( reportEntryType != SKIPPED ) |
| { |
| Integer etime = other.getElapsed(); |
| estimatedElapsed = etime == null ? detailsForThis.getElapsedSinceLastStart() : etime; |
| } |
| |
| return new WrappedReportEntry( other, reportEntryType, estimatedElapsed, testStdOut, testStdErr ); |
| } |
| |
| private WrappedReportEntry wrapTestSet( TestSetReportEntry other ) |
| { |
| return new WrappedReportEntry( other, null, other.getElapsed() != null |
| ? other.getElapsed() |
| : detailsForThis.getElapsedSinceTestSetStart(), testStdOut, testStdErr, other.getSystemProperties() ); |
| } |
| |
| public void close() |
| { |
| consoleOutputReceiver.close(); |
| } |
| |
| private void addTestMethodStats() |
| { |
| for ( WrappedReportEntry reportEntry : detailsForThis.getReportEntries() ) |
| { |
| TestMethodStats methodStats = |
| new TestMethodStats( reportEntry.getClassMethodName(), reportEntry.getReportEntryType(), |
| reportEntry.getStackTraceWriter() ); |
| testMethodStats.add( methodStats ); |
| } |
| } |
| |
| public List<TestMethodStats> getTestMethodStats() |
| { |
| return testMethodStats; |
| } |
| |
| private static String trimTrailingNewLine( final String message ) |
| { |
| final int e = message == null ? 0 : lineBoundSymbolWidth( message ); |
| return message != null && e != 0 ? message.substring( 0, message.length() - e ) : message; |
| } |
| |
| private static int lineBoundSymbolWidth( String message ) |
| { |
| return message.endsWith( "\n" ) || message.endsWith( "\r" ) ? 1 : ( message.endsWith( "\r\n" ) ? 2 : 0 ); |
| } |
| } |