View Javadoc
1   package org.apache.maven.plugin.surefire;
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.plugin.surefire.extensions.DefaultStatelessReportMojoConfiguration;
23  import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter;
24  import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
25  import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
26  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
27  import org.apache.maven.plugin.surefire.report.TestSetStats;
28  import org.apache.maven.plugin.surefire.report.WrappedReportEntry;
29  import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
30  import org.apache.maven.surefire.extensions.ConsoleOutputReportEventListener;
31  import org.apache.maven.surefire.extensions.StatelessReportEventListener;
32  import org.apache.maven.surefire.extensions.StatelessTestsetInfoConsoleReportEventListener;
33  import org.apache.maven.surefire.extensions.StatelessTestsetInfoFileReportEventListener;
34  
35  import javax.annotation.Nonnull;
36  import java.io.File;
37  import java.io.PrintStream;
38  import java.nio.charset.Charset;
39  import java.util.Deque;
40  import java.util.Map;
41  import java.util.concurrent.ConcurrentHashMap;
42  
43  import static java.nio.charset.StandardCharsets.UTF_8;
44  import static org.apache.maven.surefire.shared.lang3.StringUtils.trimToNull;
45  import static org.apache.maven.plugin.surefire.SurefireHelper.replaceForkThreadsInPath;
46  import static org.apache.maven.plugin.surefire.report.ConsoleReporter.BRIEF;
47  import static org.apache.maven.plugin.surefire.report.ConsoleReporter.PLAIN;
48  
49  /**
50   * All the parameters used to construct reporters
51   * <br>
52   *
53   * @author Kristian Rosenvold
54   */
55  public final class StartupReportConfiguration
56  {
57      private final PrintStream originalSystemOut;
58  
59      private final PrintStream originalSystemErr;
60  
61      private final boolean useFile;
62  
63      private final boolean printSummary;
64  
65      private final String reportFormat;
66  
67      private final String reportNameSuffix;
68  
69      private final File statisticsFile;
70  
71      private final boolean requiresRunHistory;
72  
73      private final boolean redirectTestOutputToFile;
74  
75      private final File reportsDirectory;
76  
77      private final boolean trimStackTrace;
78  
79      private final int rerunFailingTestsCount;
80  
81      private final String xsdSchemaLocation;
82  
83      private final Map<String, Deque<WrappedReportEntry>> testClassMethodRunHistory = new ConcurrentHashMap<>();
84  
85      private final Charset encoding;
86  
87      private final boolean isForkMode;
88  
89      private final SurefireStatelessReporter xmlReporter;
90  
91      private final SurefireConsoleOutputReporter consoleOutputReporter;
92  
93      private final SurefireStatelessTestsetInfoReporter testsetReporter;
94  
95      private StatisticsReporter statisticsReporter;
96  
97      @SuppressWarnings( "checkstyle:parameternumber" )
98      public StartupReportConfiguration( boolean useFile, boolean printSummary, String reportFormat,
99                 boolean redirectTestOutputToFile,
100                @Nonnull File reportsDirectory, boolean trimStackTrace, String reportNameSuffix,
101                File statisticsFile, boolean requiresRunHistory, int rerunFailingTestsCount,
102                String xsdSchemaLocation, String encoding, boolean isForkMode,
103                SurefireStatelessReporter xmlReporter, SurefireConsoleOutputReporter consoleOutputReporter,
104                SurefireStatelessTestsetInfoReporter testsetReporter )
105     {
106         this.useFile = useFile;
107         this.printSummary = printSummary;
108         this.reportFormat = reportFormat;
109         this.redirectTestOutputToFile = redirectTestOutputToFile;
110         this.reportsDirectory = reportsDirectory;
111         this.trimStackTrace = trimStackTrace;
112         this.reportNameSuffix = reportNameSuffix;
113         this.statisticsFile = statisticsFile;
114         this.requiresRunHistory = requiresRunHistory;
115         this.originalSystemOut = System.out;
116         this.originalSystemErr = System.err;
117         this.rerunFailingTestsCount = rerunFailingTestsCount;
118         this.xsdSchemaLocation = xsdSchemaLocation;
119         String charset = trimToNull( encoding );
120         this.encoding = charset == null ? UTF_8 : Charset.forName( charset );
121         this.isForkMode = isForkMode;
122         this.xmlReporter = xmlReporter;
123         this.consoleOutputReporter = consoleOutputReporter;
124         this.testsetReporter = testsetReporter;
125     }
126 
127     public boolean isUseFile()
128     {
129         return useFile;
130     }
131 
132     public boolean isPrintSummary()
133     {
134         return printSummary;
135     }
136 
137     public String getReportFormat()
138     {
139         return reportFormat;
140     }
141 
142     public String getReportNameSuffix()
143     {
144         return reportNameSuffix;
145     }
146 
147     public boolean isRedirectTestOutputToFile()
148     {
149         return redirectTestOutputToFile;
150     }
151 
152     public File getReportsDirectory()
153     {
154         return reportsDirectory;
155     }
156 
157     public int getRerunFailingTestsCount()
158     {
159         return rerunFailingTestsCount;
160     }
161 
162     public StatelessReportEventListener<WrappedReportEntry, TestSetStats> instantiateStatelessXmlReporter(
163             Integer forkNumber )
164     {
165         assert ( forkNumber == null ) == !isForkMode;
166 
167         // If forking TestNG the suites have same name 'TestSuite' and tend to override report statistics in stateful
168         // reporter, see Surefire1535TestNGParallelSuitesIT. The testClassMethodRunHistory should be isolated.
169         // In the in-plugin execution of parallel JUnit4.7 with rerun the map must be shared because reports and
170         // listeners are in ThreadLocal, see Surefire1122ParallelAndFlakyTestsIT.
171         Map<String, Deque<WrappedReportEntry>> testClassMethodRunHistory
172                 = isForkMode
173                 ? new ConcurrentHashMap<String, Deque<WrappedReportEntry>>()
174                 : this.testClassMethodRunHistory;
175 
176         DefaultStatelessReportMojoConfiguration xmlReporterConfig =
177                 new DefaultStatelessReportMojoConfiguration( resolveReportsDirectory( forkNumber ), reportNameSuffix,
178                         trimStackTrace, rerunFailingTestsCount, xsdSchemaLocation, testClassMethodRunHistory );
179 
180         return xmlReporter.isDisable() ? null : xmlReporter.createListener( xmlReporterConfig );
181     }
182 
183     public StatelessTestsetInfoFileReportEventListener<WrappedReportEntry, TestSetStats> instantiateFileReporter(
184             Integer forkNumber )
185     {
186         return !testsetReporter.isDisable() && isUseFile() && isBriefOrPlainFormat()
187             ? testsetReporter.createListener( resolveReportsDirectory( forkNumber ), reportNameSuffix, encoding )
188             : null;
189     }
190 
191     public StatelessTestsetInfoConsoleReportEventListener<WrappedReportEntry, TestSetStats> instantiateConsoleReporter(
192             ConsoleLogger consoleLogger )
193     {
194         return !testsetReporter.isDisable() && shouldReportToConsole()
195                 ? testsetReporter.createListener( consoleLogger ) : null;
196     }
197 
198     public boolean isBriefOrPlainFormat()
199     {
200         String fmt = getReportFormat();
201         return BRIEF.equals( fmt ) || PLAIN.equals( fmt );
202     }
203 
204     public ConsoleOutputReportEventListener instantiateConsoleOutputFileReporter( Integer forkNum )
205     {
206         ConsoleOutputReportEventListener outputReport = isRedirectTestOutputToFile()
207                 ? consoleOutputReporter.createListener( resolveReportsDirectory( forkNum ), reportNameSuffix, forkNum )
208                 : consoleOutputReporter.createListener( originalSystemOut, originalSystemErr );
209         return consoleOutputReporter.isDisable() ? null : outputReport;
210     }
211 
212     public synchronized StatisticsReporter getStatisticsReporter()
213     {
214         if ( statisticsReporter == null )
215         {
216             statisticsReporter = requiresRunHistory ? new StatisticsReporter( statisticsFile ) : null;
217         }
218         return statisticsReporter;
219     }
220 
221     public File getStatisticsFile()
222     {
223         return statisticsFile;
224     }
225 
226     public boolean isTrimStackTrace()
227     {
228         return trimStackTrace;
229     }
230 
231     public boolean isRequiresRunHistory()
232     {
233         return requiresRunHistory;
234     }
235 
236     public String getXsdSchemaLocation()
237     {
238         return xsdSchemaLocation;
239     }
240 
241     public Charset getEncoding()
242     {
243         return encoding;
244     }
245 
246     public boolean isForkMode()
247     {
248         return isForkMode;
249     }
250 
251     private File resolveReportsDirectory( Integer forkNumber )
252     {
253         return forkNumber == null ? reportsDirectory : replaceForkThreadsInPath( reportsDirectory, forkNumber );
254     }
255 
256     public SurefireStatelessReporter getXmlReporter()
257     {
258         return xmlReporter;
259     }
260 
261     public SurefireConsoleOutputReporter getConsoleOutputReporter()
262     {
263         return consoleOutputReporter;
264     }
265 
266     public SurefireStatelessTestsetInfoReporter getTestsetReporter()
267     {
268         return testsetReporter;
269     }
270 
271     private boolean shouldReportToConsole()
272     {
273         return isUseFile() ? isPrintSummary() : isRedirectTestOutputToFile() || isBriefOrPlainFormat();
274     }
275 }