View Javadoc

1   package org.apache.maven.surefire.junitcore;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Map;
23  import org.apache.maven.surefire.report.ConsoleLogger;
24  import org.apache.maven.surefire.report.ConsoleOutputReceiver;
25  import org.apache.maven.surefire.report.ReportEntry;
26  import org.apache.maven.surefire.report.ReporterFactory;
27  import org.apache.maven.surefire.report.RunListener;
28  import org.apache.maven.surefire.testset.TestSetFailedException;
29  
30  /**
31   * @author Kristian Rosenvold
32   */
33  public abstract class ConcurrentReporterManager
34      implements RunListener, ConsoleOutputReceiver
35  {
36      private final Map<String, TestSet> classMethodCounts;
37      // private final ReporterConfiguration reporterConfiguration;
38  
39      private final ThreadLocal<RunListener> reporterManagerThreadLocal = new ThreadLocal<RunListener>();
40  
41      private final boolean reportImmediately;
42  
43      private final ReporterFactory reporterFactory;
44  
45      private final ConsoleLogger consoleLogger;
46  
47      ConcurrentReporterManager( ReporterFactory reporterFactory, ConsoleLogger consoleLogger, boolean reportImmediately,
48                                 Map<String, TestSet> classMethodCounts )
49          throws TestSetFailedException
50      {
51          this.reportImmediately = reportImmediately;
52          this.reporterFactory = reporterFactory;
53          this.classMethodCounts = classMethodCounts;
54          this.consoleLogger = consoleLogger;
55      }
56  
57      public void testSetStarting( ReportEntry description )
58      {
59      }
60  
61      public void testSetCompleted( ReportEntry result )
62      {
63          final RunListener reporterManager = getRunListener();
64          for ( TestSet testSet : classMethodCounts.values() )
65          {
66              testSet.replay( reporterManager );
67          }
68      }
69  
70      public void testFailed( ReportEntry failure )
71      {
72          getOrCreateTestMethod( failure ).testFailure( failure );
73      }
74  
75      public void testError( ReportEntry failure )
76      {
77          getOrCreateTestMethod( failure ).testError( failure );
78      }
79  
80      public void testSkipped( ReportEntry description )
81      {
82          TestSet testSet = getTestSet( description );
83          TestMethod testMethod = getTestSet( description ).createTestMethod( description );
84          testMethod.testIgnored( description );
85          testSet.incrementFinishedTests( getRunListener(), reportImmediately );
86      }
87  
88      public void testAssumptionFailure( ReportEntry failure )
89      {
90          getOrCreateTestMethod( failure ).testIgnored( failure );
91      }
92  
93      public void testStarting( ReportEntry description )
94      {
95          TestSet testSet = getTestSet( description );
96          final TestMethod testMethod = testSet.createTestMethod( description );
97          testMethod.attachToThread();
98  
99          checkIfTestSetCanBeReported( testSet );
100         testSet.attachToThread();
101     }
102 
103     public void testSucceeded( ReportEntry report )
104     {
105         getTestMethod().testFinished();
106         TestSet.getThreadTestSet().incrementFinishedTests( getRunListener(), reportImmediately );
107         detachTestMethodFromThread();
108     }
109 
110     private TestMethod getOrCreateTestMethod( ReportEntry description )
111     {
112         TestMethod threadTestMethod = TestMethod.getThreadTestMethod();
113         if ( threadTestMethod != null )
114         {
115             return threadTestMethod;
116         }
117         TestSet testSet = getTestSet( description );
118         return testSet.createTestMethod( description );
119     }
120 
121     protected abstract void checkIfTestSetCanBeReported( TestSet testSetForTest );
122 
123     TestMethod getTestMethod()
124     {
125         return TestMethod.getThreadTestMethod();
126     }
127 
128     void detachTestMethodFromThread()
129     {
130         TestMethod.detachFromCurrentThread();
131     }
132 
133     TestSet getTestSet( ReportEntry description )
134     {
135         return classMethodCounts.get( description.getSourceName() );
136     }
137 
138     RunListener getRunListener()
139     {
140         RunListener runListener = reporterManagerThreadLocal.get();
141         if ( runListener == null )
142         {
143             runListener = reporterFactory.createReporter();
144             reporterManagerThreadLocal.set( runListener );
145         }
146         return runListener;
147     }
148 
149     public static ConcurrentReporterManager createInstance( Map<String, TestSet> classMethodCounts,
150                                                             ReporterFactory reporterManagerFactory,
151                                                             boolean parallelClasses, boolean parallelBoth,
152                                                             ConsoleLogger consoleLogger )
153         throws TestSetFailedException
154     {
155         if ( parallelClasses )
156         {
157             return new ClassesParallelRunListener( classMethodCounts, reporterManagerFactory, consoleLogger );
158         }
159         return new MethodsParallelRunListener( classMethodCounts, reporterManagerFactory, !parallelBoth,
160                                                consoleLogger );
161     }
162 
163 
164     public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
165     {
166         TestMethod threadTestMethod = TestMethod.getThreadTestMethod();
167         if ( threadTestMethod != null )
168         {
169             final LogicalStream logicalStream = threadTestMethod.getLogicalStream();
170             logicalStream.write( stdout, buf, off, len );
171         }
172         else
173         {
174             // Not able to assocaite output with any thread. Just dump to console
175             consoleLogger.info( new String( buf, off, len ) );
176         }
177     }
178 
179 }