You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2016/12/26 15:28:16 UTC

[8/9] maven-surefire git commit: [SUREFIRE-1322] Surefire and Failsafe should dump critical errors in dump file and console

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/303cc8ac/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java b/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java
index a8466b2..1525e80 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java
@@ -19,21 +19,7 @@ package org.apache.maven.surefire.suite;
  * under the License.
  */
 
-import org.apache.maven.shared.utils.StringUtils;
-import org.apache.maven.shared.utils.io.IOUtil;
-import org.apache.maven.shared.utils.xml.PrettyPrintXMLWriter;
-import org.apache.maven.shared.utils.xml.Xpp3Dom;
-import org.apache.maven.shared.utils.xml.Xpp3DomBuilder;
-import org.apache.maven.shared.utils.xml.Xpp3DomWriter;
-
-import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.PrintWriter;
 
 /**
@@ -79,8 +65,7 @@ public class RunResult
     private static RunResult errorCode( RunResult other, String failure, boolean timeout )
     {
         return new RunResult( other.getCompletedCount(), other.getErrors(), other.getFailures(), other.getSkipped(),
-                              failure, timeout );
-
+                                    failure, timeout );
     }
 
     public RunResult( int completedCount, int errors, int failures, int skipped )
@@ -171,7 +156,12 @@ public class RunResult
     /* Indicates if the tests are error free */
     public boolean isErrorFree()
     {
-        return getFailures() == 0 && getErrors() == 0;
+        return getFailures() == 0 && getErrors() == 0 && !isFailure();
+    }
+
+    public boolean isInternalError()
+    {
+        return getFailures() == 0 && getErrors() == 0 && isFailure();
     }
 
     /* Indicates test timeout or technical failure */
@@ -212,83 +202,6 @@ public class RunResult
         return new RunResult( 0, 0, 0, 0 );
     }
 
-    private Xpp3Dom create( String node, String value )
-    {
-        Xpp3Dom dom = new Xpp3Dom( node );
-        dom.setValue( value );
-        return dom;
-    }
-
-    private Xpp3Dom create( String node, int value )
-    {
-        return create( node, Integer.toString( value ) );
-    }
-
-    Xpp3Dom asXpp3Dom()
-    {
-        Xpp3Dom dom = new Xpp3Dom( "failsafe-summary" );
-        Integer failsafeCode = getFailsafeCode();
-        if ( failsafeCode != null )
-        {
-            dom.setAttribute( "result", Integer.toString( failsafeCode ) );
-        }
-        dom.setAttribute( "timeout", Boolean.toString( this.timeout ) );
-        dom.addChild( create( "completed", this.completedCount ) );
-        dom.addChild( create( "errors", this.errors ) );
-        dom.addChild( create( "failures", this.failures ) );
-        dom.addChild( create( "skipped", this.skipped ) );
-        dom.addChild( create( "failureMessage", this.failure ) );
-        return dom;
-    }
-
-    public static RunResult fromInputStream( InputStream inputStream, String encoding )
-        throws FileNotFoundException
-    {
-        Xpp3Dom dom = Xpp3DomBuilder.build( inputStream, encoding );
-        boolean timeout = Boolean.parseBoolean( dom.getAttribute( "timeout" ) );
-        int completed = Integer.parseInt( dom.getChild( "completed" ).getValue() );
-        int errors = Integer.parseInt( dom.getChild( "errors" ).getValue() );
-        int failures = Integer.parseInt( dom.getChild( "failures" ).getValue() );
-        int skipped = Integer.parseInt( dom.getChild( "skipped" ).getValue() );
-        String failureMessage1 = dom.getChild( "failureMessage" ).getValue();
-        String failureMessage = StringUtils.isEmpty( failureMessage1 ) ? null : failureMessage1;
-        return new RunResult( completed, errors, failures, skipped, failureMessage, timeout );
-    }
-
-    public void writeSummary( File summaryFile, boolean inProgress, String encoding )
-        throws IOException
-    {
-        if ( !summaryFile.getParentFile().isDirectory() )
-        {
-            //noinspection ResultOfMethodCallIgnored
-            summaryFile.getParentFile().mkdirs();
-        }
-
-        FileInputStream fin = null;
-        FileWriter writer = null;
-        try
-        {
-            RunResult mergedSummary = this;
-            if ( summaryFile.exists() && inProgress )
-            {
-                fin = new FileInputStream( summaryFile );
-
-                RunResult runResult = RunResult.fromInputStream( new BufferedInputStream( fin ), encoding );
-                mergedSummary = mergedSummary.aggregate( runResult );
-            }
-
-            writer = new FileWriter( summaryFile );
-            writer.write( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
-            PrettyPrintXMLWriter prettyPrintXMLWriter = new PrettyPrintXMLWriter( writer );
-            Xpp3DomWriter.write( prettyPrintXMLWriter, mergedSummary.asXpp3Dom() );
-        }
-        finally
-        {
-            IOUtil.close( fin );
-            IOUtil.close( writer );
-        }
-    }
-
     @SuppressWarnings( "RedundantIfStatement" )
     public boolean equals( Object o )
     {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/303cc8ac/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java
new file mode 100644
index 0000000..47a1386
--- /dev/null
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java
@@ -0,0 +1 @@
+package org.apache.maven.surefire.util.internal;

/*
 * 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 org.apache.maven.surefire.report.ReporterConfiguration;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOE
 xception;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Dumps a text or exception in dump file.
 * Each call logs a date when it was written to the dump file.
 *
 * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
 * @since 2.19.2
 */
public final class DumpFileUtils
{
    private DumpFileUtils()
    {
        throw new IllegalStateException( "no instantiable constructor" );
    }

    /**
     * New dump file. Synchronized object appears in main memory and perfectly visible in other threads.
     */
    public static synchronized File newDumpFile( String dumpFileName, ReporterConfiguration configuration )
    {
        return new File( configuration.getReportsDirectory(), dumpFileName );
    }

    public static void dumpException( Throwable t, File dumpFile )
    {
        dumpException( t, null, dumpFile );
    }

    public static void dumpException
 ( Throwable t, String msg, File dumpFile )
    {
        try
        {
            if ( t != null && dumpFile != null && ( dumpFile.exists() || dumpFile.createNewFile() ) )
            {
                Writer fw = createWriter( dumpFile );
                if ( msg != null )
                {
                    fw.append( msg )
                            .append( StringUtils.NL );
                }
                PrintWriter pw = new PrintWriter( fw );
                t.printStackTrace( pw );
                pw.flush();
                fw.append( StringUtils.NL )
                        .append( StringUtils.NL );
                fw.flush();
                fw.close();
            }
        }
        catch ( Exception e )
        {
            // do nothing
        }
    }

    public static void dumpText( String msg, File dumpFile )
    {
        try
        {
            if ( msg != null && dumpFile != null && ( dumpFile.exists() || dumpFile.createNewFile() ) )
            {
   
              Writer fw = createWriter( dumpFile )
                        .append( msg )
                        .append( StringUtils.NL )
                        .append( StringUtils.NL );
                fw.flush();
                fw.close();
            }
        }
        catch ( Exception e )
        {
            // do nothing
        }
    }

    public static String newFormattedDateFileName()
    {
        return new SimpleDateFormat( "yyyy-MM-dd'T'hh-mm-ss_SSS" ).format( new Date() );
    }

    private static Writer createWriter( File dumpFile ) throws IOException
    {
        return new OutputStreamWriter( new FileOutputStream( dumpFile, true ), "UTF-8" )
                       .append( "# Created on " )
                       .append( new SimpleDateFormat( "yyyy-MM-dd'T'hh:mm:ss.SSS" ).format( new Date() ) )
                       .append( StringUtils.NL );
    }
}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/303cc8ac/surefire-api/src/test/java/org/apache/maven/surefire/suite/RunResultTest.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/suite/RunResultTest.java b/surefire-api/src/test/java/org/apache/maven/surefire/suite/RunResultTest.java
index 007a26c..e888ca2 100644
--- a/surefire-api/src/test/java/org/apache/maven/surefire/suite/RunResultTest.java
+++ b/surefire-api/src/test/java/org/apache/maven/surefire/suite/RunResultTest.java
@@ -19,22 +19,13 @@ package org.apache.maven.surefire.suite;
  * under the License.
  */
 
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.StringWriter;
-import org.apache.maven.shared.utils.xml.PrettyPrintXMLWriter;
-import org.apache.maven.shared.utils.xml.Xpp3DomWriter;
-
 import junit.framework.TestCase;
 
 /**
  * @author Kristian Rosenvold
  */
 public class RunResultTest
-    extends TestCase
+        extends TestCase
 {
 
     public void testEmptySummaryShouldBeErrorFree()
@@ -49,76 +40,4 @@ public class RunResultTest
         RunResult resultTwo = new RunResult( 20, 0, 0, 0 );
         assertFalse( resultOne.aggregate( resultTwo ).isErrorFree() );
     }
-
-
-    public void testAggregatedValues()
-    {
-        RunResult simple = getSimpleAggregate();
-        assertEquals( 20, simple.getCompletedCount() );
-        assertEquals( 3, simple.getErrors() );
-        assertEquals( 7, simple.getFailures() );
-        assertEquals( 4, simple.getSkipped() );
-        assertEquals( 2, simple.getFlakes() );
-
-    }
-
-    public void testSerialization()
-        throws FileNotFoundException
-    {
-        writeReadCheck( getSimpleAggregate() );
-    }
-
-    public void testFailures()
-        throws FileNotFoundException
-    {
-        writeReadCheck( new RunResult( 0, 1, 2, 3, "stacktraceHere", false ) );
-    }
-
-    public void testSkipped()
-        throws FileNotFoundException
-    {
-        writeReadCheck( new RunResult( 3, 2, 1, 0, null, true ) );
-    }
-
-    public void testAppendSerialization()
-        throws IOException
-    {
-        RunResult simpleAggregate = getSimpleAggregate();
-        RunResult additional = new RunResult( 2, 1, 2, 2, null, true );
-        File summary = File.createTempFile( "failsafe", "test" );
-        simpleAggregate.writeSummary( summary, false, "utf-8" );
-        additional.writeSummary( summary, true, "utf-8" );
-
-        RunResult actual = RunResult.fromInputStream( new FileInputStream( summary ), "utf-8" );
-        RunResult expected = simpleAggregate.aggregate( additional );
-        assertEquals( expected, actual );
-        //noinspection ResultOfMethodCallIgnored
-        summary.delete();
-
-    }
-
-    private void writeReadCheck( RunResult simpleAggregate )
-        throws FileNotFoundException
-    {
-        StringWriter writer = getStringWriter( simpleAggregate );
-
-        RunResult actual =
-            RunResult.fromInputStream( new ByteArrayInputStream( writer.getBuffer().toString().getBytes() ), "UTF-8" );
-        assertEquals( simpleAggregate, actual );
-    }
-
-    private StringWriter getStringWriter( RunResult simpleAggregate )
-    {
-        StringWriter writer = new StringWriter();
-        PrettyPrintXMLWriter wr = new PrettyPrintXMLWriter( writer );
-        Xpp3DomWriter.write( wr, simpleAggregate.asXpp3Dom() );
-        return writer;
-    }
-
-    private RunResult getSimpleAggregate()
-    {
-        RunResult resultOne = new RunResult( 10, 1, 3, 2, 1 );
-        RunResult resultTwo = new RunResult( 10, 2, 4, 2, 1 );
-        return resultOne.aggregate( resultTwo );
-    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/303cc8ac/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
index 98040db..29047f2 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
@@ -19,8 +19,17 @@ package org.apache.maven.surefire.booter;
  * under the License.
  */
 
+import org.apache.maven.surefire.providerapi.ProviderParameters;
+import org.apache.maven.surefire.providerapi.SurefireProvider;
+import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
+import org.apache.maven.surefire.report.ReporterFactory;
+import org.apache.maven.surefire.report.StackTraceWriter;
+import org.apache.maven.surefire.suite.RunResult;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.PrintStream;
 import java.lang.reflect.InvocationTargetException;
@@ -30,30 +39,24 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.maven.surefire.providerapi.ProviderParameters;
-import org.apache.maven.surefire.providerapi.SurefireProvider;
-import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
-import org.apache.maven.surefire.report.ReporterFactory;
-import org.apache.maven.surefire.report.StackTraceWriter;
-import org.apache.maven.surefire.suite.RunResult;
-import org.apache.maven.surefire.testset.TestSetFailedException;
-
 import static java.lang.System.err;
 import static java.lang.System.out;
 import static java.lang.System.setErr;
 import static java.lang.System.setOut;
 import static java.lang.Thread.currentThread;
+import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.apache.maven.surefire.booter.CommandReader.getReader;
-import static org.apache.maven.surefire.booter.Shutdown.EXIT;
-import static org.apache.maven.surefire.booter.Shutdown.KILL;
 import static org.apache.maven.surefire.booter.ForkingRunListener.BOOTERCODE_BYE;
 import static org.apache.maven.surefire.booter.ForkingRunListener.BOOTERCODE_ERROR;
 import static org.apache.maven.surefire.booter.ForkingRunListener.encode;
+import static org.apache.maven.surefire.booter.Shutdown.EXIT;
+import static org.apache.maven.surefire.booter.Shutdown.KILL;
 import static org.apache.maven.surefire.booter.SystemPropertyManager.setSystemProperties;
 import static org.apache.maven.surefire.util.ReflectionUtils.instantiateOneArg;
 import static org.apache.maven.surefire.util.internal.DaemonThreadFactory.newDaemonThreadFactory;
+import static org.apache.maven.surefire.util.internal.DumpFileUtils.dumpException;
+import static org.apache.maven.surefire.util.internal.DumpFileUtils.newDumpFile;
 import static org.apache.maven.surefire.util.internal.StringUtils.encodeStringForForkCommunication;
-import static java.util.concurrent.TimeUnit.SECONDS;
 
 /**
  * The part of the booter that is unique to a forked vm.
@@ -70,6 +73,8 @@ public final class ForkedBooter
     private static final long DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS = 30;
     private static final long PING_TIMEOUT_IN_SECONDS = 20;
     private static final ScheduledExecutorService JVM_TERMINATOR = createJvmTerminator();
+    private static final String DUMP_FILE_EXT = ".dump";
+    private static final String DUMPSTREAM_FILE_EXT = ".dumpstream";
 
     private static volatile long systemExitTimeoutInSeconds = DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS;
 
@@ -84,22 +89,31 @@ public final class ForkedBooter
         final CommandReader reader = startupMasterProcessReader();
         final ScheduledFuture<?> pingScheduler = listenToShutdownCommands( reader );
         final PrintStream originalOut = out;
+        File dumpFile = null;
         try
         {
-            if ( args.length > 1 )
+            final String tmpDir = args[0];
+            final String dumpFileName = args[1];
+            final String surefirePropsFileName = args[2];
+
+            BooterDeserializer booterDeserializer =
+                    new BooterDeserializer( createSurefirePropertiesIfFileExists( tmpDir, surefirePropsFileName ) );
+            if ( args.length > 3 )
             {
-                setSystemProperties( new File( args[1] ) );
+                final String effectiveSystemPropertiesFileName = args[3];
+                setSystemProperties( new File( tmpDir, effectiveSystemPropertiesFileName ) );
             }
 
-            File surefirePropertiesFile = new File( args[0] );
-            InputStream stream = surefirePropertiesFile.exists() ? new FileInputStream( surefirePropertiesFile ) : null;
-            BooterDeserializer booterDeserializer = new BooterDeserializer( stream );
-            ProviderConfiguration providerConfiguration = booterDeserializer.deserialize();
+            final ProviderConfiguration providerConfiguration = booterDeserializer.deserialize();
+
+            dumpFile = createDumpFile( dumpFileName, providerConfiguration );
+            reader.setDumpFile( createDumpstreamFile( dumpFileName, providerConfiguration ) );
+
             final StartupConfiguration startupConfiguration = booterDeserializer.getProviderConfiguration();
             systemExitTimeoutInSeconds =
                     providerConfiguration.systemExitTimeout( DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS );
-            TypeEncodedValue forkedTestSet = providerConfiguration.getTestForFork();
-            boolean readTestsFromInputStream = providerConfiguration.isReadTestsFromInStream();
+            final TypeEncodedValue forkedTestSet = providerConfiguration.getTestForFork();
+            final boolean readTestsFromInputStream = providerConfiguration.isReadTestsFromInStream();
 
             final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
             if ( startupConfiguration.isManifestOnlyJarRequestedAndUsable() )
@@ -107,7 +121,7 @@ public final class ForkedBooter
                 classpathConfiguration.trickClassPathWhenManifestOnlyClasspath();
             }
 
-            ClassLoader classLoader = currentThread().getContextClassLoader();
+            final ClassLoader classLoader = currentThread().getContextClassLoader();
             classLoader.setDefaultAssertionStatus( classpathConfiguration.isEnableAssertions() );
             startupConfiguration.writeSurefireTestClasspathProperty();
 
@@ -131,6 +145,7 @@ public final class ForkedBooter
             }
             catch ( InvocationTargetException t )
             {
+                dumpException( t, dumpFile );
                 StackTraceWriter stackTraceWriter =
                     new LegacyPojoStackTraceWriter( "test subsystem", "no method", t.getTargetException() );
                 StringBuilder stringBuilder = new StringBuilder();
@@ -139,6 +154,7 @@ public final class ForkedBooter
             }
             catch ( Throwable t )
             {
+                dumpException( t, dumpFile );
                 StackTraceWriter stackTraceWriter = new LegacyPojoStackTraceWriter( "test subsystem", "no method", t );
                 StringBuilder stringBuilder = new StringBuilder();
                 encode( stringBuilder, stackTraceWriter, false );
@@ -152,6 +168,7 @@ public final class ForkedBooter
         }
         catch ( Throwable t )
         {
+            dumpException( t, dumpFile );
             // Just throwing does getMessage() and a local trace - we want to call printStackTrace for a full trace
             // noinspection UseOfSystemOutOrSystemErr
             t.printStackTrace( err );
@@ -330,4 +347,21 @@ public final class ForkedBooter
         String providerClass = startupConfiguration.getActualClassName();
         return (SurefireProvider) instantiateOneArg( classLoader, providerClass, ProviderParameters.class, bpf );
     }
+
+    private static InputStream createSurefirePropertiesIfFileExists( String tmpDir, String propFileName )
+            throws FileNotFoundException
+    {
+        File surefirePropertiesFile = new File( tmpDir, propFileName );
+        return surefirePropertiesFile.exists() ? new FileInputStream( surefirePropertiesFile ) : null;
+    }
+
+    private static File createDumpFile( String dumpFileName, ProviderConfiguration providerConfiguration )
+    {
+        return newDumpFile( dumpFileName + DUMP_FILE_EXT, providerConfiguration.getReporterConfiguration() );
+    }
+
+    private static File createDumpstreamFile( String dumpFileName, ProviderConfiguration providerConfiguration )
+    {
+        return newDumpFile( dumpFileName + DUMPSTREAM_FILE_EXT, providerConfiguration.getReporterConfiguration() );
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/303cc8ac/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgExecuteErrorIT.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgExecuteErrorIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgExecuteErrorIT.java
index ce90b3b..2d03900 100644
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgExecuteErrorIT.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgExecuteErrorIT.java
@@ -23,6 +23,11 @@ import org.apache.maven.surefire.its.fixture.OutputValidator;
 import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
 import org.junit.Test;
 
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static org.fest.assertions.Assertions.assertThat;
+
 
 /**
  * Test for checking that the output from a forked suite is properly captured even if the suite encounters a severe error.
@@ -37,7 +42,26 @@ public class CheckTestNgExecuteErrorIT
     public void executionError()
         throws Exception
     {
-        OutputValidator outputValidator = unpack( "/testng-execute-error" ).maven().withFailure().executeTest();
-        outputValidator.verifyTextInLog( "at org.apache.maven.surefire.testng.TestNGExecutor.run" );
+        OutputValidator outputValidator = unpack( "/testng-execute-error" )
+                                                  .maven()
+                                                  .showErrorStackTraces()
+                                                  .withFailure()
+                                                  .executeTest();
+
+        File reportDir = outputValidator.getSurefireReportsDirectory();
+        String[] dumpFiles = reportDir.list( new FilenameFilter()
+                                             {
+                                                 @Override
+                                                 public boolean accept( File dir, String name )
+                                                 {
+                                                     return name.endsWith( ".dump" );
+                                                 }
+                                             });
+        assertThat( dumpFiles ).isNotEmpty();
+        for ( String dump : dumpFiles )
+        {
+            outputValidator.getSurefireReportsFile( dump )
+                    .assertContainsText( "at org.apache.maven.surefire.testng.TestNGExecutor.run" );
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/303cc8ac/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
index 8184abe..afd6493 100644
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/OutputValidator.java
@@ -184,16 +184,21 @@ public class OutputValidator
 
     public TestFile getSurefireReportsFile( String fileName )
     {
-        File targetDir = getSubFile( "target/surefire-reports" );
+        File targetDir = getSurefireReportsDirectory();
         return new TestFile( new File( targetDir, fileName ), this );
     }
 
     public TestFile getSurefireReportsXmlFile( String fileName )
     {
-        File targetDir = getSubFile( "target/surefire-reports" );
+        File targetDir = getSurefireReportsDirectory();
         return new TestFile( new File( targetDir, fileName ), Charset.forName("UTF-8"), this );
     }
 
+    public File getSurefireReportsDirectory()
+    {
+        return getSubFile( "target/surefire-reports" );
+    }
+
     public TestFile getSiteFile( String fileName )
     {
         File targetDir = getSubFile( "target/site" );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/303cc8ac/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire141PluggableProvidersIT.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire141PluggableProvidersIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire141PluggableProvidersIT.java
index ecf01a8..fdc10a8 100644
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire141PluggableProvidersIT.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire141PluggableProvidersIT.java
@@ -20,11 +20,16 @@ package org.apache.maven.surefire.its.jiras;
  */
 
 import org.apache.maven.it.VerificationException;
+import org.apache.maven.surefire.its.fixture.OutputValidator;
 import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static org.fest.assertions.Assertions.assertThat;
+
 /**
  * SUREFIRE-613 Asserts proper test counts when running in parallel
  *
@@ -83,12 +88,28 @@ public class Surefire141PluggableProvidersIT
     public void constructorRuntimeException()
         throws Exception
     {
-        unpack( "surefire-141-pluggableproviders" )
-            .sysProp( "constructorCrash", "runtimeException" )
-            .maven()
-            .withFailure()
-            .executeTest()
-            .verifyTextInLog( "Let's fail with a runtimeException" );
+        OutputValidator validator = unpack( "surefire-141-pluggableproviders" )
+                                            .sysProp( "constructorCrash", "runtimeException" )
+                                            .maven()
+                                            .withFailure()
+                                            .executeTest()
+                                            .verifyTextInLog( "Let's fail with a runtimeException" );
+
+        File reportDir = validator.getSurefireReportsDirectory();
+        String[] dumpFiles = reportDir.list( new FilenameFilter()
+                        {
+                            @Override
+                            public boolean accept( File dir, String name )
+                            {
+                                return name.endsWith( ".dump" );
+                            }
+                        });
+        assertThat( dumpFiles ).isNotEmpty();
+        for ( String dump : dumpFiles )
+        {
+            validator.getSurefireReportsFile( dump )
+                    .assertContainsText( "Let's fail with a runtimeException" );
+        }
     }
 
 }
\ No newline at end of file