Author: krosenvold
Date: Fri Nov 5 17:43:24 2010
New Revision: 1031678
URL: http://svn.apache.org/viewvc?rev=1031678&view=rev
Log:
[SUREFIRE-658] Removed synchronization on ReporterManager
- TestNG provider retains existing synchronization through wrapper class.
- JUnit4/3 lose synchronization on the reporter manager.
- Junit4.7 run with per-thread instance of ReporterManager.
Added:
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
(with props)
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
(with props)
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/SynchronizedReporterManager.java
(with props)
Modified:
maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/report/ReporterManager.java
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListener.java
maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListenerTest.java
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
Modified:
maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/report/ReporterManager.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/report/ReporterManager.java?rev=1031678&r1=1031677&r2=1031678&view=diff
==============================================================================
---
maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/report/ReporterManager.java
(original)
+++
maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/report/ReporterManager.java
Fri Nov 5 17:43:24 2010
@@ -27,28 +27,14 @@ import java.util.List;
* <p/>
* Synchronization/Threading note:
* <p/>
- * This design is really only good for single-threaded test execution.
Although it is currently
- * used by multi-threaded providers too, the design does not really make sense
(and is probably buggy).
+ * This design is really only good for single-threaded test execution. With
the use of the additional
+ * SynchronizedReporterManager you can get a buggy version that sort-of
supports multithreading.
* <p/>
- * This is because to get correct results, the client basically needs to do
something like this:
- * synchronized( ReporterManger.getClass()){
- * reporterManager.runStarted()
- * reporterManager.testSetStarting()
- * reporterManager.testStarting()
- * reporterManager.testSucceeded()
- * reporterManager.testSetCompleted()
- * reporterManager.runCompleted()
- * }
- * <p/>
- * This is because the underlying providers are singletons and keep state, if
you remove the outer synchronized
- * block, you may get mixups between results from different tests; although
the end result (total test count etc)
- * should probably be correct.
+ * The underlying providers are singletons and keep state per ReporterManager
instance
* <p/>
* The solution to this problem involves making a clearer separation between
test-result collection and reporting,
* preferably removing singleton state approach out of the reporting interface.
* <p/>
- * Please also note that the synchronization requirements of this interface
severely limit the concurrency
- * potential of all the parallel surefire providers, especially when runnning
non-io bound tests,
*/
public class ReporterManager
{
@@ -56,20 +42,28 @@ public class ReporterManager
private final MulticastingReporter multicastingReporter;
- private final SystemStreamCapturer consoleCapturer = new
SystemStreamCapturer();
+ private final SystemStreamCapturer consoleCapturer;
public ReporterManager( List reports, RunStatistics runStatisticsForThis )
{
+ this.consoleCapturer = new SystemStreamCapturer();
multicastingReporter = new MulticastingReporter( reports );
this.runStatisticsForThis = runStatisticsForThis;
}
- public synchronized void writeMessage( String message )
+ protected ReporterManager( ReporterManager other )
+ {
+ this.multicastingReporter = other.multicastingReporter;
+ this.runStatisticsForThis = other.runStatisticsForThis;
+ this.consoleCapturer = other.consoleCapturer;
+ }
+
+ public void writeMessage( String message )
{
multicastingReporter.writeMessage( message );
}
-
- public synchronized void writeConsoleMessage( String message )
+
+ public void writeConsoleMessage( String message )
{
multicastingReporter.writeConsoleMessage( message );
}
@@ -78,12 +72,12 @@ public class ReporterManager
// Run
// ----------------------------------------------------------------------
- public synchronized void runStarting()
+ public void runStarting()
{
multicastingReporter.runStarting();
}
- public synchronized void runCompleted()
+ public void runCompleted()
{
multicastingReporter.runCompleted();
multicastingReporter.writeFooter( "" );
@@ -112,19 +106,19 @@ public class ReporterManager
consoleCapturer.restoreStreams();
}
- public synchronized void writeFooter( String footer )
+ public void writeFooter( String footer )
{
multicastingReporter.writeFooter( footer );
}
- public synchronized void testSetStarting( ReportEntry report )
+ public void testSetStarting( ReportEntry report )
throws ReporterException
{
multicastingReporter.testSetStarting( report );
}
- public synchronized void testSetCompleted( ReportEntry report )
+ public void testSetCompleted( ReportEntry report )
{
multicastingReporter.testSetCompleted( report );
}
@@ -133,24 +127,24 @@ public class ReporterManager
// Test
// ----------------------------------------------------------------------
- public synchronized void testStarting( ReportEntry report )
+ public void testStarting( ReportEntry report )
{
multicastingReporter.testStarting( report );
}
- public synchronized void testSucceeded( ReportEntry report )
+ public void testSucceeded( ReportEntry report )
{
consoleCapturer.clearCapturedContent();
runStatisticsForThis.incrementCompletedCount();
multicastingReporter.testSucceeded( report );
}
- public synchronized void testError( ReportEntry reportEntry )
+ public void testError( ReportEntry reportEntry )
{
testError( reportEntry, consoleCapturer.getStdOutLog(),
consoleCapturer.getStdErrLog() );
}
- public synchronized void testError( ReportEntry reportEntry, String
stdOutLog, String stdErrLog )
+ public void testError( ReportEntry reportEntry, String stdOutLog, String
stdErrLog )
{
multicastingReporter.testError( reportEntry, stdOutLog, stdErrLog );
runStatisticsForThis.incrementErrorsCount();
@@ -159,13 +153,13 @@ public class ReporterManager
consoleCapturer.clearCapturedContent();
}
- public synchronized void testFailed( ReportEntry reportEntry )
+ public void testFailed( ReportEntry reportEntry )
{
testFailed( reportEntry, consoleCapturer.getStdOutLog(),
consoleCapturer.getStdErrLog() );
}
- public synchronized void testFailed( ReportEntry reportEntry, String
stdOutLog, String stdErrLog )
+ public void testFailed( ReportEntry reportEntry, String stdOutLog, String
stdErrLog )
{
multicastingReporter.testFailed( reportEntry, stdOutLog, stdErrLog );
runStatisticsForThis.incrementFailureCount();
@@ -178,7 +172,7 @@ public class ReporterManager
// Counters
// ----------------------------------------------------------------------
- public synchronized void testSkipped( ReportEntry report )
+ public void testSkipped( ReportEntry report )
{
consoleCapturer.clearCapturedContent();
runStatisticsForThis.incrementSkippedCount();
@@ -186,7 +180,7 @@ public class ReporterManager
multicastingReporter.testSkipped( report );
}
- public synchronized void reset()
+ public void reset()
{
multicastingReporter.reset();
}
Added:
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java?rev=1031678&view=auto
==============================================================================
---
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
(added)
+++
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
Fri Nov 5 17:43:24 2010
@@ -0,0 +1,46 @@
+package org.apache.maven.surefire.junitcore;
+/*
+ * 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.ReporterManagerFactory;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+/**
+* @author Kristian Rosenvold
+*/
+public class ClassesParallelRunListener
+ extends ConcurrentReportingRunListener
+{
+ public ClassesParallelRunListener( ReporterManagerFactory reporterFactory )
+ throws TestSetFailedException
+ {
+ super( reporterFactory, false );
+ }
+
+ @Override
+ public void checkIfTestSetCanBeReported( TestSet testSetForTest )
+ throws TestSetFailedException
+ {
+ TestSet currentlyAttached = TestSet.getThreadTestSet();
+ if ( currentlyAttached != null && currentlyAttached != testSetForTest )
+ {
+ currentlyAttached.setAllScheduled( getReporterManager() );
+ }
+ }
+}
Propchange:
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListener.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListener.java?rev=1031678&r1=1031677&r2=1031678&view=diff
==============================================================================
---
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListener.java
(original)
+++
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListener.java
Fri Nov 5 17:43:24 2010
@@ -42,18 +42,24 @@ public abstract class ConcurrentReportin
protected Map<Class, TestSet> classMethodCounts = new
ConcurrentHashMap<Class, TestSet>();
- protected final ReporterManager reporterManager;
+ private final ThreadLocal<ReporterManager> reporterManagerThreadLocal =
new ThreadLocal<ReporterManager>();
protected final boolean reportImmediately;
private final ConcurrentPrintStream out = new ConcurrentPrintStream( true
);
+
private final ConcurrentPrintStream err = new ConcurrentPrintStream( false
);
+ private ReporterManagerFactory reporterFactory;
+
public ConcurrentReportingRunListener( ReporterManagerFactory
reporterFactory, boolean reportImmediately )
throws TestSetFailedException
{
this.reportImmediately = reportImmediately;
- reporterManager = reporterFactory.createReporterManager();
+ this.reporterFactory = reporterFactory;
+ // We must create the first reporterManager here, even though we will
never use it.
+ // There is some room for improvement here
+ this.reporterFactory.createReporterManager();
// Important: We must capture System.out/System.err AFTER the
reportManager captures stdout/stderr
// because we know how to demultiplex correctly. The redirection in
reporterManager is basically
// ignored/unused because we use ConcurrentPrintStream.
@@ -61,6 +67,31 @@ public abstract class ConcurrentReportin
System.setErr( err );
}
+
+ protected ReporterManager getReporterManager()
+ throws TestSetFailedException
+ {
+ ReporterManager reporterManager = reporterManagerThreadLocal.get();
+ if ( reporterManager == null )
+ {
+ reporterManager = reporterFactory.createReporterManager();
+ reporterManagerThreadLocal.set( reporterManager );
+ }
+ return reporterManager;
+ }
+
+ public static ConcurrentReportingRunListener createInstance(
ReporterManagerFactory reporterManagerFactory,
+ boolean
parallelClasses, boolean parallelBoth )
+ throws TestSetFailedException
+ {
+ if ( parallelClasses )
+ {
+ return new ClassesParallelRunListener( reporterManagerFactory );
+ }
+ return new MethodsParallelRunListener( reporterManagerFactory,
!parallelBoth );
+ }
+
+
@Override
public void testRunStarted( Description description )
throws Exception
@@ -74,13 +105,13 @@ public abstract class ConcurrentReportin
{
for ( TestSet testSet : classMethodCounts.values() )
{
- testSet.replay( reporterManager );
+ testSet.replay( getReporterManager() );
}
System.setOut( orgSystemOut );
System.setErr( orgSystemErr );
- out.writeTo( orgSystemOut );
- err.writeTo( orgSystemErr );
+ out.writeTo( orgSystemOut );
+ err.writeTo( orgSystemErr );
}
protected TestMethod getTestMethod()
@@ -102,13 +133,14 @@ public abstract class ConcurrentReportin
public void testFailure( Failure failure )
throws Exception
{
- getOrCreateTestMethod(failure.getDescription()).testFailure( failure );
+ getOrCreateTestMethod( failure.getDescription() ).testFailure( failure
);
}
private TestMethod getOrCreateTestMethod( Description description )
{
TestMethod threadTestMethod = TestMethod.getThreadTestMethod();
- if (threadTestMethod != null){
+ if ( threadTestMethod != null )
+ {
return threadTestMethod;
}
TestSet testSet = getTestSet( description );
@@ -128,7 +160,7 @@ public abstract class ConcurrentReportin
TestSet testSet = getTestSet( description );
TestMethod testMethod = getTestSet( description ).createTestMethod(
description );
testMethod.testIgnored( description );
- testSet.incrementFinishedTests( reporterManager, reportImmediately );
+ testSet.incrementFinishedTests( getReporterManager(),
reportImmediately );
}
@Override
@@ -141,75 +173,17 @@ public abstract class ConcurrentReportin
testSet.attachToThread();
}
- public abstract void checkIfTestSetCanBeReported( TestSet testSetForTest );
+ public abstract void checkIfTestSetCanBeReported( TestSet testSetForTest )
+ throws TestSetFailedException;
@Override
public void testFinished( Description description )
throws Exception
{
getTestMethod().testFinished();
- TestSet.getThreadTestSet().incrementFinishedTests( reporterManager,
reportImmediately );
+ TestSet.getThreadTestSet().incrementFinishedTests(
getReporterManager(), reportImmediately );
detachTestMethodFromThread();
}
- public static ConcurrentReportingRunListener createInstance(
ReporterManagerFactory reporterManagerFactory,
- boolean
parallelClasses, boolean parallelBoth )
- throws TestSetFailedException
- {
- if ( parallelClasses )
- {
- return new ClassesParallelRunListener( reporterManagerFactory );
- }
- return new MethodsParallelRunListener( reporterManagerFactory,
!parallelBoth );
- }
-
- public static class ClassesParallelRunListener
- extends ConcurrentReportingRunListener
- {
- public ClassesParallelRunListener( ReporterManagerFactory
reporterFactory )
- throws TestSetFailedException
- {
- super( reporterFactory, false );
- }
-
- @Override
- public void checkIfTestSetCanBeReported( TestSet testSetForTest )
- {
- TestSet currentlyAttached = TestSet.getThreadTestSet();
- if ( currentlyAttached != null && currentlyAttached !=
testSetForTest )
- {
- currentlyAttached.setAllScheduled( reporterManager );
- }
- }
- }
-
- public static class MethodsParallelRunListener
- extends ConcurrentReportingRunListener
- {
- private volatile TestSet lastStarted;
-
- private final Object lock = new Object();
- public MethodsParallelRunListener( ReporterManagerFactory
reporterFactory, boolean reportImmediately )
- throws TestSetFailedException
- {
- super( reporterFactory, reportImmediately );
- }
-
- @Override
- public void checkIfTestSetCanBeReported( TestSet testSetForTest )
- {
- synchronized ( lock )
- {
- if ( testSetForTest != lastStarted )
- {
- if ( lastStarted != null )
- {
- lastStarted.setAllScheduled( reporterManager );
- }
- lastStarted = testSetForTest;
- }
- }
- }
- }
}
Added:
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java?rev=1031678&view=auto
==============================================================================
---
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
(added)
+++
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
Fri Nov 5 17:43:24 2010
@@ -0,0 +1,56 @@
+package org.apache.maven.surefire.junitcore;
+/*
+ * 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.ReporterManagerFactory;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+/**
+* @author Kristian Rosenvold
+*/
+public class MethodsParallelRunListener
+ extends ConcurrentReportingRunListener
+{
+ private volatile TestSet lastStarted;
+
+ private final Object lock = new Object();
+
+ public MethodsParallelRunListener( ReporterManagerFactory reporterFactory,
boolean reportImmediately )
+ throws TestSetFailedException
+ {
+ super( reporterFactory, reportImmediately );
+ }
+
+ @Override
+ public void checkIfTestSetCanBeReported( TestSet testSetForTest )
+ throws TestSetFailedException
+ {
+ synchronized ( lock )
+ {
+ if ( testSetForTest != lastStarted )
+ {
+ if ( lastStarted != null )
+ {
+ lastStarted.setAllScheduled( getReporterManager() );
+ }
+ lastStarted = testSetForTest;
+ }
+ }
+ }
+}
Propchange:
maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListenerTest.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListenerTest.java?rev=1031678&r1=1031677&r2=1031678&view=diff
==============================================================================
---
maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListenerTest.java
(original)
+++
maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentReportingRunListenerTest.java
Fri Nov 5 17:43:24 2010
@@ -159,15 +159,15 @@ public class ConcurrentReportingRunListe
throws TestSetFailedException
{
ReporterManagerFactory reporterManagerFactory =
createReporterFactory();
- RunStatistics result = runClasses(reporterManagerFactory, new
ConcurrentReportingRunListener.ClassesParallelRunListener(
reporterManagerFactory ), classes);
+ RunStatistics result = runClasses(reporterManagerFactory, new
ClassesParallelRunListener( reporterManagerFactory ), classes);
assertReporter( result, success, ignored ,failure, "classes" );
reporterManagerFactory = createReporterFactory();
- result = runClasses(reporterManagerFactory, new
ConcurrentReportingRunListener.MethodsParallelRunListener(reporterManagerFactory,
true) , classes);
+ result = runClasses(reporterManagerFactory, new
MethodsParallelRunListener(reporterManagerFactory, true) , classes);
assertReporter( result, success, ignored ,failure, "methods" );
reporterManagerFactory = createReporterFactory();
- result = runClasses(reporterManagerFactory, new
ConcurrentReportingRunListener.MethodsParallelRunListener(reporterManagerFactory,
false) , classes);
+ result = runClasses(reporterManagerFactory, new
MethodsParallelRunListener(reporterManagerFactory, false) , classes);
assertReporter( result, success, ignored ,failure, "methods" );
}
@@ -203,7 +203,7 @@ public class ConcurrentReportingRunListe
private ConcurrentReportingRunListener createRunListener(
ReporterManagerFactory reporterFactory )
throws TestSetFailedException
{
- return new ConcurrentReportingRunListener.ClassesParallelRunListener(
reporterFactory );
+ return new ClassesParallelRunListener( reporterFactory );
}
Added:
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/SynchronizedReporterManager.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/SynchronizedReporterManager.java?rev=1031678&view=auto
==============================================================================
---
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/SynchronizedReporterManager.java
(added)
+++
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/SynchronizedReporterManager.java
Fri Nov 5 17:43:24 2010
@@ -0,0 +1,140 @@
+package org.apache.maven.surefire.testng;
+/*
+ * 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.ReportEntry;
+import org.apache.maven.surefire.report.ReporterException;
+import org.apache.maven.surefire.report.ReporterManager;
+
+/**
+ * A proxy that imposes synchronization on the Reporter.
+ * <p/>
+ * <p/>
+ * At the moment this class only provides "compatible" synchronization that
the testng runner can use,
+ * and provides the same (faulty) level of synchronization as the <2.6
versions of surefire.
+ * <p/>
+ * In the "future" when the concurrent junit provider is rid of all problems
of childhood,
+ * it should probably replace the entire reporting secion for testng too.
+ * <p/>
+ * <p/>
+ * <p/>
+ * This design is really only good for single-threaded test execution.
Although it is currently
+ * used by testng provider, the design does not really make sense (and is
buggy).
+ * <p/>
+ * This is because to get correct results, the client basically needs to do
something like this:
+ * synchronized( ReporterManger.getClass()){
+ * reporterManager.runStarted()
+ * reporterManager.testSetStarting()
+ * reporterManager.testStarting()
+ * reporterManager.testSucceeded()
+ * reporterManager.testSetCompleted()
+ * reporterManager.runCompleted()
+ * }
+ * <p/>
+ * This is because the underlying providers are singletons and keep state, if
you remove the outer synchronized
+ * block, you may get mixups between results from different tests; although
the end result (total test count etc)
+ * should probably be correct.
+ * <p/>
+ * <p/>
+ */
+class SynchronizedReporterManager
+ extends ReporterManager
+{
+ public SynchronizedReporterManager( ReporterManager target )
+ {
+ super( target );
+ }
+
+ public synchronized void runStarting()
+ {
+ super.runStarting();
+ }
+
+ public synchronized void runCompleted()
+ {
+ super.runCompleted();
+ }
+
+ public synchronized void testSetStarting( ReportEntry report )
+ throws ReporterException
+ {
+ super.testSetStarting( report );
+ }
+
+ public synchronized void testSetCompleted( ReportEntry report )
+ {
+ super.testSetCompleted( report );
+ }
+
+ public synchronized void testStarting( ReportEntry report )
+ {
+ super.testStarting( report );
+ }
+
+ public synchronized void testSucceeded( ReportEntry report )
+ {
+ super.testSucceeded( report );
+ }
+
+ public synchronized void testError( ReportEntry report, String stdOut,
String stdErr )
+ {
+ super.testError( report, stdOut, stdErr );
+ }
+
+ public synchronized void testFailed( ReportEntry report, String stdOut,
String stdErr )
+ {
+ super.testFailed( report, stdOut, stdErr );
+ }
+
+ public synchronized void testSkipped( ReportEntry report )
+ {
+ super.testSkipped( report );
+ }
+
+ public synchronized void reset()
+ {
+ super.reset();
+ }
+
+ public synchronized void writeMessage( String message )
+ {
+ super.writeMessage( message );
+ }
+
+ public synchronized void writeFooter( String footer )
+ {
+ super.writeFooter( footer );
+ }
+
+ public synchronized void writeConsoleMessage( String message )
+ {
+ super.writeConsoleMessage( message );
+ }
+
+ public synchronized void testError( ReportEntry reportEntry )
+ {
+ super.testError( reportEntry );
+ }
+
+ public synchronized void testFailed( ReportEntry reportEntry )
+ {
+ super.testFailed( reportEntry );
+ }
+}
Propchange:
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/SynchronizedReporterManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java?rev=1031678&r1=1031677&r2=1031678&view=diff
==============================================================================
---
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
(original)
+++
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
Fri Nov 5 17:43:24 2010
@@ -149,7 +149,8 @@ public class TestNGDirectoryTestSuite
junitReportsDirectory = new File( reportsDirectory,
"testng-junit-results");
}
- ReporterManager reporterManager =
reporterManagerFactory.createReporterManager();
+ ReporterManager reporterManager =
+ new SynchronizedReporterManager(
reporterManagerFactory.createReporterManager());
startTestSuite( reporterManager, this );
Class[] testClasses = (Class[]) testNgTestClasses.toArray( new
Class[0] );
Modified:
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
URL:
http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java?rev=1031678&r1=1031677&r2=1031678&view=diff
==============================================================================
---
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
(original)
+++
maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
Fri Nov 5 17:43:24 2010
@@ -89,7 +89,8 @@ public class TestNGXmlTestSuite
{
throw new IllegalStateException( "You must call locateTestSets
before calling execute" );
}
- ReporterManager reporterManager =
reporterManagerFactory.createReporterManager();
+ ReporterManager reporterManager =
+ new SynchronizedReporterManager(
reporterManagerFactory.createReporterManager());
TestNGDirectoryTestSuite.startTestSuite( reporterManager, this );
TestNGExecutor.run( this.suiteFilePaths, this.testSourceDirectory,
this.options, this.version,
this.classifier, reporterManager, this,
reportsDirectory );