View Javadoc

1   package org.apache.maven.surefire.report;
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 org.apache.maven.surefire.util.internal.ByteBuffer;
23  
24  import java.util.ArrayList;
25  import java.util.Collections;
26  import java.util.Iterator;
27  import java.util.List;
28  
29  /**
30   * Reports data for a single test set.
31   * <p/>
32   * Synchronization/Threading note:
33   * <p/>
34   * This design is really only good for single-threaded test execution. With the use of the additional
35   * SynchronizedReporterManager you can get a buggy version that sort-of supports multithreading.
36   * <p/>
37   * The underlying providers are singletons and keep state per ReporterManager instance
38   * <p/>
39   * The solution to this problem involves making a clearer separation between test-result collection and reporting,
40   * preferably removing singleton state approach out of the reporting interface.
41   * <p/>
42   */
43  public class TestSetRunListener
44      implements RunListener, RunReporter, Reporter, ConsoleOutputReceiver
45  {
46      private final RunStatistics globalStats;
47  
48      private final MulticastingReporter multicastingReporter;
49  
50      private final List testStdOut = Collections.synchronizedList( new ArrayList() );
51  
52      private final List testStdErr = Collections.synchronizedList( new ArrayList() );
53  
54  
55      public TestSetRunListener( List reports, RunStatistics globalStats )
56      {
57          multicastingReporter = new MulticastingReporter( reports );
58          this.globalStats = globalStats;
59      }
60  
61      public void writeMessage( String message )
62      {
63          multicastingReporter.writeMessage( message );
64      }
65  
66      public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
67      {
68          ByteBuffer byteBuffer = new ByteBuffer( buf, off, len );
69          if ( stdout )
70          {
71              testStdOut.add( byteBuffer );
72          }
73          else
74          {
75              testStdErr.add( byteBuffer );
76          }
77          multicastingReporter.writeMessage( new String( buf, off, len ) );
78      }
79  
80      public void writeDetailMessage( String message )
81      {
82          multicastingReporter.writeDetailMessage( message );
83      }
84  
85      // ----------------------------------------------------------------------
86      // Run
87      // ----------------------------------------------------------------------
88  
89      public void runStarting()
90      {
91          multicastingReporter.runStarting();
92      }
93  
94      public void runCompleted()
95      {
96          multicastingReporter.runCompleted();
97          multicastingReporter.writeFooter( "" );
98          multicastingReporter.writeFooter( "Results :" );
99          multicastingReporter.writeFooter( "" );
100         if ( globalStats.hadFailures() )
101         {
102             multicastingReporter.writeFooter( "Failed tests: " );
103             for ( Iterator iterator = this.globalStats.getFailureSources().iterator(); iterator.hasNext(); )
104             {
105                 multicastingReporter.writeFooter( "  " + iterator.next() );
106             }
107             multicastingReporter.writeFooter( "" );
108         }
109         if ( globalStats.hadErrors() )
110         {
111             writeFooter( "Tests in error: " );
112             for ( Iterator iterator = this.globalStats.getErrorSources().iterator(); iterator.hasNext(); )
113             {
114                 multicastingReporter.writeFooter( "  " + iterator.next() );
115             }
116             multicastingReporter.writeFooter( "" );
117         }
118         multicastingReporter.writeFooter( globalStats.getSummary() );
119         multicastingReporter.writeFooter( "" );
120     }
121 
122     public void writeFooter( String footer )
123     {
124         multicastingReporter.writeFooter( footer );
125     }
126 
127 
128     public void testSetStarting( ReportEntry report )
129         throws ReporterException
130     {
131         multicastingReporter.testSetStarting( report );
132     }
133 
134     public void testSetCompleted( ReportEntry report )
135     {
136         multicastingReporter.testSetCompleted( report );
137         multicastingReporter.reset();
138     }
139 
140     // ----------------------------------------------------------------------
141     // Test
142     // ----------------------------------------------------------------------
143 
144     public void testStarting( ReportEntry report )
145     {
146         multicastingReporter.testStarting( report );
147     }
148 
149     public void testSucceeded( ReportEntry report )
150     {
151         clearCapturedContent();
152         globalStats.incrementCompletedCount();
153         multicastingReporter.testSucceeded( report );
154     }
155 
156     public void testError( ReportEntry reportEntry )
157     {
158         testError( reportEntry, getAsString( testStdOut ), getAsString( testStdErr ) );
159     }
160 
161     public void testError( ReportEntry reportEntry, String stdOutLog, String stdErrLog )
162     {
163         multicastingReporter.testError( reportEntry, stdOutLog, stdErrLog );
164         globalStats.incrementErrorsCount();
165         globalStats.incrementCompletedCount();
166         globalStats.addErrorSource( reportEntry.getName(), reportEntry.getStackTraceWriter() );
167         clearCapturedContent();
168     }
169 
170     public void testFailed( ReportEntry reportEntry )
171     {
172         testFailed( reportEntry, getAsString( testStdOut ), getAsString( testStdErr ) );
173     }
174 
175     public void testFailed( ReportEntry reportEntry, String stdOutLog, String stdErrLog )
176     {
177         multicastingReporter.testFailed( reportEntry, stdOutLog, stdErrLog );
178         globalStats.incrementFailureCount();
179         globalStats.incrementCompletedCount();
180         globalStats.addFailureSource( reportEntry.getName(), reportEntry.getStackTraceWriter() );
181         clearCapturedContent();
182     }
183 
184     // ----------------------------------------------------------------------
185     // Counters
186     // ----------------------------------------------------------------------
187 
188     public void testSkipped( ReportEntry report )
189     {
190         clearCapturedContent();
191         globalStats.incrementSkippedCount();
192         globalStats.incrementCompletedCount();
193         multicastingReporter.testSkipped( report );
194     }
195 
196     public void testAssumptionFailure( ReportEntry report )
197     {
198         testSkipped( report );
199     }
200 
201     public void reset()
202     {
203         multicastingReporter.reset();
204     }
205 
206     public String getAsString( List byteBufferList )
207     {
208         StringBuffer stringBuffer = new StringBuffer();
209         for ( Iterator iter = byteBufferList.iterator(); iter.hasNext(); )
210         {
211             ByteBuffer byteBuffer = (ByteBuffer) iter.next();
212             stringBuffer.append( byteBuffer.toString() );
213         }
214         return stringBuffer.toString();
215     }
216 
217     public void clearCapturedContent()
218     {
219         testStdErr.clear();
220         testStdOut.clear();
221     }
222 
223 
224 }