http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2a944f06/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java ---------------------------------------------------------------------- diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java index 77f41be..d481bb2 100644 --- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java +++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java @@ -23,6 +23,8 @@ import org.apache.maven.surefire.booter.ProviderParameterNames; import org.apache.maven.surefire.cli.CommandLineOption; import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.testng.conf.Configurator; +import org.apache.maven.surefire.testng.utils.FailFastListener; +import org.apache.maven.surefire.testng.utils.Stoppable; import org.apache.maven.surefire.testset.TestListResolver; import org.apache.maven.surefire.testset.TestSetFailedException; import org.apache.maven.surefire.util.ReflectionUtils; @@ -44,6 +46,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static org.apache.maven.surefire.util.ReflectionUtils.instantiate; + /** * Contains utility methods for executing TestNG. * @@ -69,7 +73,7 @@ public class TestNGExecutor public static void run( Class<?>[] testClasses, String testSourceDirectory, Map<String, String> options, // string,string because TestNGMapConfigurator#configure() RunListener reportManager, TestNgTestSuite suite, File reportsDirectory, - TestListResolver methodFilter, List<CommandLineOption> mainCliOptions ) + TestListResolver methodFilter, List<CommandLineOption> mainCliOptions, boolean isFailFast ) throws TestSetFailedException { TestNG testng = new TestNG( true ); @@ -119,7 +123,7 @@ public class TestNGExecutor testng.setXmlSuites( xmlSuites ); configurator.configure( testng, options ); - postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory ); + postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory, isFailFast ); testng.run(); } @@ -260,13 +264,14 @@ public class TestNGExecutor public static void run( List<String> suiteFiles, String testSourceDirectory, Map<String, String> options, // string,string because TestNGMapConfigurator#configure() - RunListener reportManager, TestNgTestSuite suite, File reportsDirectory ) + RunListener reportManager, TestNgTestSuite suite, File reportsDirectory, + boolean isFailFast ) throws TestSetFailedException { TestNG testng = new TestNG( true ); Configurator configurator = getConfigurator( options.get( "testng.configurator" ) ); configurator.configure( testng, options ); - postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory ); + postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory, isFailFast ); testng.setTestSuites( suiteFiles ); testng.run(); } @@ -291,8 +296,8 @@ public class TestNGExecutor } } - private static void postConfigure( TestNG testNG, String sourcePath, RunListener reportManager, - TestNgTestSuite suite, File reportsDirectory ) + private static void postConfigure( TestNG testNG, String sourcePath, final RunListener reportManager, + TestNgTestSuite suite, File reportsDirectory, boolean skipAfterFailure ) throws TestSetFailedException { // turn off all TestNG output @@ -301,7 +306,22 @@ public class TestNGExecutor TestNGReporter reporter = createTestNGReporter( reportManager, suite ); testNG.addListener( (Object) reporter ); - // FIXME: use classifier to decide if we need to pass along the source dir (onyl for JDK14) + if ( skipAfterFailure ) + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + testNG.addListener( instantiate( cl, "org.apache.maven.surefire.testng.utils.FailFastNotifier", + Object.class ) ); + Stoppable stoppable = new Stoppable() + { + public void pleaseStop() + { + reportManager.testExecutionSkippedByUser(); + } + }; + testNG.addListener( new FailFastListener( stoppable ) ); + } + + // FIXME: use classifier to decide if we need to pass along the source dir (only for JDK14) if ( sourcePath != null ) { testNG.setSourcePath( sourcePath );
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2a944f06/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java ---------------------------------------------------------------------- diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java index d28d6ac..8777ceb 100644 --- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java +++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java @@ -24,12 +24,16 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import org.apache.maven.surefire.booter.Command; +import org.apache.maven.surefire.booter.MasterProcessListener; +import org.apache.maven.surefire.booter.MasterProcessReader; import org.apache.maven.surefire.cli.CommandLineOption; import org.apache.maven.surefire.providerapi.AbstractProvider; import org.apache.maven.surefire.providerapi.ProviderParameters; import org.apache.maven.surefire.report.ReporterConfiguration; import org.apache.maven.surefire.report.ReporterFactory; import org.apache.maven.surefire.suite.RunResult; +import org.apache.maven.surefire.testng.utils.FailFastEventsSingleton; import org.apache.maven.surefire.testset.TestListResolver; import org.apache.maven.surefire.testset.TestRequest; import org.apache.maven.surefire.testset.TestSetFailedException; @@ -37,6 +41,8 @@ import org.apache.maven.surefire.util.RunOrderCalculator; import org.apache.maven.surefire.util.ScanResult; import org.apache.maven.surefire.util.TestsToRun; +import static org.apache.maven.surefire.booter.MasterProcessCommand.SKIP_SINCE_NEXT_TEST; + /** * @author Kristian Rosenvold * @noinspection UnusedDeclaration @@ -58,12 +64,16 @@ public class TestNGProvider private final RunOrderCalculator runOrderCalculator; - private List<CommandLineOption> mainCliOptions; + private final List<CommandLineOption> mainCliOptions; + + private final MasterProcessReader commandsReader; private TestsToRun testsToRun; public TestNGProvider( ProviderParameters booterParameters ) { + // don't start a thread in MasterProcessReader while we are in in-plugin process + commandsReader = booterParameters.isInsideFork() ? MasterProcessReader.getReader() : null; providerParameters = booterParameters; testClassLoader = booterParameters.getTestClassLoader(); runOrderCalculator = booterParameters.getRunOrderCalculator(); @@ -77,44 +87,55 @@ public class TestNGProvider public RunResult invoke( Object forkTestSet ) throws TestSetFailedException { - - final ReporterFactory reporterFactory = providerParameters.getReporterFactory(); - - if ( isTestNGXmlTestSuite( testRequest ) ) + try { - TestNGXmlTestSuite testNGXmlTestSuite = getXmlSuite(); - testNGXmlTestSuite.locateTestSets( testClassLoader ); - if ( forkTestSet != null && testRequest == null ) + if ( isFailFast() && commandsReader != null ) { - testNGXmlTestSuite.execute( (String) forkTestSet, reporterFactory ); + registerPleaseStopListener(); } - else - { - testNGXmlTestSuite.execute( reporterFactory ); - } - } - else - { - if ( testsToRun == null ) + + final ReporterFactory reporterFactory = providerParameters.getReporterFactory(); + + if ( isTestNGXmlTestSuite( testRequest ) ) { - if ( forkTestSet instanceof TestsToRun ) + TestNGXmlTestSuite testNGXmlTestSuite = newXmlSuite(); + testNGXmlTestSuite.locateTestSets( testClassLoader ); + if ( forkTestSet != null && testRequest == null ) { - testsToRun = (TestsToRun) forkTestSet; + testNGXmlTestSuite.execute( (String) forkTestSet, reporterFactory ); } - else if ( forkTestSet instanceof Class ) + else { - testsToRun = TestsToRun.fromClass( (Class) forkTestSet ); + testNGXmlTestSuite.execute( reporterFactory ); } - else + } + else + { + if ( testsToRun == null ) { - testsToRun = scanClassPath(); + if ( forkTestSet instanceof TestsToRun ) + { + testsToRun = (TestsToRun) forkTestSet; + } + else if ( forkTestSet instanceof Class ) + { + testsToRun = TestsToRun.fromClass( (Class) forkTestSet ); + } + else + { + testsToRun = scanClassPath(); + } } + TestNGDirectoryTestSuite suite = newDirectorySuite(); + suite.execute( testsToRun, reporterFactory ); } - TestNGDirectoryTestSuite suite = getDirectorySuite(); - suite.execute( testsToRun, reporterFactory ); - } - return reporterFactory.close(); + return reporterFactory.close(); + } + finally + { + closeCommandsReader(); + } } boolean isTestNGXmlTestSuite( TestRequest testSuiteDefinition ) @@ -123,18 +144,45 @@ public class TestNGProvider return suiteXmlFiles != null && !suiteXmlFiles.isEmpty() && !hasSpecificTests(); } - private TestNGDirectoryTestSuite getDirectorySuite() + private boolean isFailFast() + { + return providerParameters.getSkipAfterFailureCount() > 0; + } + + private void closeCommandsReader() + { + if ( commandsReader != null ) + { + commandsReader.stop(); + } + } + + private MasterProcessListener registerPleaseStopListener() + { + MasterProcessListener listener = new MasterProcessListener() + { + public void update( Command command ) + { + FailFastEventsSingleton.getInstance().setSkipOnNextTest(); + } + }; + commandsReader.addListener( SKIP_SINCE_NEXT_TEST, listener ); + return listener; + } + + private TestNGDirectoryTestSuite newDirectorySuite() { return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory().toString(), providerProperties, reporterConfiguration.getReportsDirectory(), createMethodFilter(), - runOrderCalculator, scanResult, mainCliOptions ); + runOrderCalculator, scanResult, mainCliOptions, isFailFast() ); } - private TestNGXmlTestSuite getXmlSuite() + private TestNGXmlTestSuite newXmlSuite() { - return new TestNGXmlTestSuite( testRequest.getSuiteXmlFiles(), testRequest.getTestSourceDirectory().toString(), + return new TestNGXmlTestSuite( testRequest.getSuiteXmlFiles(), + testRequest.getTestSourceDirectory().toString(), providerProperties, - reporterConfiguration.getReportsDirectory() ); + reporterConfiguration.getReportsDirectory(), isFailFast() ); } @SuppressWarnings( "unchecked" ) @@ -144,7 +192,7 @@ public class TestNGProvider { try { - return getXmlSuite().locateTestSets( testClassLoader ).keySet(); + return newXmlSuite().locateTestSets( testClassLoader ).keySet(); } catch ( TestSetFailedException e ) { http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2a944f06/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java ---------------------------------------------------------------------- diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java index 552e482..bf105fe 100644 --- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java +++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java @@ -49,6 +49,8 @@ public class TestNGXmlTestSuite private final File reportsDirectory; + private final boolean isFailFast; + // Not really used private Map<File, String> testSets; @@ -57,15 +59,13 @@ public class TestNGXmlTestSuite * xml file(s). The XML files are suite definitions files according to TestNG DTD. */ public TestNGXmlTestSuite( List<File> suiteFiles, String testSourceDirectory, Map<String, String> confOptions, - File reportsDirectory ) + File reportsDirectory, boolean isFailFast ) { this.suiteFiles = suiteFiles; - this.options = confOptions; - this.testSourceDirectory = testSourceDirectory; - this.reportsDirectory = reportsDirectory; + this.isFailFast = isFailFast; } public void execute( ReporterFactory reporterManagerFactory ) @@ -80,8 +80,8 @@ public class TestNGXmlTestSuite ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporter ); TestNGDirectoryTestSuite.startTestSuite( reporter, this ); - TestNGExecutor.run( this.suiteFilePaths, this.testSourceDirectory, this.options, reporter, this, - reportsDirectory ); + TestNGExecutor.run( suiteFilePaths, testSourceDirectory, options, reporter, this, reportsDirectory, + isFailFast ); TestNGDirectoryTestSuite.finishTestSuite( reporter, this ); }