View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.surefire;
20  
21  import javax.annotation.Nonnull;
22  
23  import java.io.File;
24  import java.io.PrintStream;
25  import java.nio.charset.Charset;
26  import java.util.Deque;
27  import java.util.Map;
28  import java.util.concurrent.ConcurrentHashMap;
29  
30  import org.apache.maven.plugin.surefire.extensions.DefaultStatelessReportMojoConfiguration;
31  import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter;
32  import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
33  import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
34  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
35  import org.apache.maven.plugin.surefire.report.TestSetStats;
36  import org.apache.maven.plugin.surefire.report.WrappedReportEntry;
37  import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
38  import org.apache.maven.surefire.extensions.ConsoleOutputReportEventListener;
39  import org.apache.maven.surefire.extensions.StatelessReportEventListener;
40  import org.apache.maven.surefire.extensions.StatelessTestsetInfoConsoleReportEventListener;
41  import org.apache.maven.surefire.extensions.StatelessTestsetInfoFileReportEventListener;
42  
43  import static java.nio.charset.StandardCharsets.UTF_8;
44  import static org.apache.maven.plugin.surefire.SurefireHelper.replaceForkThreadsInPath;
45  import static org.apache.maven.plugin.surefire.report.ConsoleReporter.BRIEF;
46  import static org.apache.maven.plugin.surefire.report.ConsoleReporter.PLAIN;
47  import static org.apache.maven.surefire.shared.lang3.StringUtils.trimToNull;
48  
49  /**
50   * All the parameters used to construct reporters
51   * <br>
52   *
53   * @author Kristian Rosenvold
54   */
55  public final class StartupReportConfiguration {
56      private final PrintStream originalSystemOut;
57  
58      private final PrintStream originalSystemErr;
59  
60      private final boolean useFile;
61  
62      private final boolean printSummary;
63  
64      private final String reportFormat;
65  
66      private final String reportNameSuffix;
67  
68      private final File statisticsFile;
69  
70      private final boolean requiresRunHistory;
71  
72      private final boolean redirectTestOutputToFile;
73  
74      private final File reportsDirectory;
75  
76      private final boolean trimStackTrace;
77  
78      private final int rerunFailingTestsCount;
79  
80      private final String xsdSchemaLocation;
81  
82      private final Map<String, Deque<WrappedReportEntry>> testClassMethodRunHistory = new ConcurrentHashMap<>();
83  
84      private final Charset encoding;
85  
86      private final boolean isForking;
87  
88      private final boolean enableOutErrElements;
89  
90      private final boolean enablePropertiesElement;
91  
92      private final SurefireStatelessReporter xmlReporter;
93  
94      private final SurefireConsoleOutputReporter consoleOutputReporter;
95  
96      private final SurefireStatelessTestsetInfoReporter testsetReporter;
97  
98      private StatisticsReporter statisticsReporter;
99  
100     /**
101      * @since 3.3.1
102      */
103     @SuppressWarnings("checkstyle:parameternumber")
104     public StartupReportConfiguration(
105             boolean useFile,
106             boolean printSummary,
107             String reportFormat,
108             boolean redirectTestOutputToFile,
109             @Nonnull File reportsDirectory,
110             boolean trimStackTrace,
111             String reportNameSuffix,
112             File statisticsFile,
113             boolean requiresRunHistory,
114             int rerunFailingTestsCount,
115             String xsdSchemaLocation,
116             String encoding,
117             boolean isForking,
118             boolean enableOutErrElements,
119             boolean enablePropertiesElement,
120             SurefireStatelessReporter xmlReporter,
121             SurefireConsoleOutputReporter consoleOutputReporter,
122             SurefireStatelessTestsetInfoReporter testsetReporter) {
123         this.useFile = useFile;
124         this.printSummary = printSummary;
125         this.reportFormat = reportFormat;
126         this.redirectTestOutputToFile = redirectTestOutputToFile;
127         this.reportsDirectory = reportsDirectory;
128         this.trimStackTrace = trimStackTrace;
129         this.reportNameSuffix = reportNameSuffix;
130         this.statisticsFile = statisticsFile;
131         this.requiresRunHistory = requiresRunHistory;
132         this.originalSystemOut = System.out;
133         this.originalSystemErr = System.err;
134         this.rerunFailingTestsCount = rerunFailingTestsCount;
135         this.xsdSchemaLocation = xsdSchemaLocation;
136         String charset = trimToNull(encoding);
137         this.encoding = charset == null ? UTF_8 : Charset.forName(charset);
138         this.isForking = isForking;
139         this.enableOutErrElements = enableOutErrElements;
140         this.enablePropertiesElement = enablePropertiesElement;
141         this.xmlReporter = xmlReporter;
142         this.consoleOutputReporter = consoleOutputReporter;
143         this.testsetReporter = testsetReporter;
144     }
145 
146     @SuppressWarnings("checkstyle:parameternumber")
147     @Deprecated
148     public StartupReportConfiguration(
149             boolean useFile,
150             boolean printSummary,
151             String reportFormat,
152             boolean redirectTestOutputToFile,
153             @Nonnull File reportsDirectory,
154             boolean trimStackTrace,
155             String reportNameSuffix,
156             File statisticsFile,
157             boolean requiresRunHistory,
158             int rerunFailingTestsCount,
159             String xsdSchemaLocation,
160             String encoding,
161             boolean isForking,
162             SurefireStatelessReporter xmlReporter,
163             SurefireConsoleOutputReporter consoleOutputReporter,
164             SurefireStatelessTestsetInfoReporter testsetReporter) {
165         this(
166                 useFile,
167                 printSummary,
168                 reportFormat,
169                 redirectTestOutputToFile,
170                 reportsDirectory,
171                 trimStackTrace,
172                 reportNameSuffix,
173                 statisticsFile,
174                 requiresRunHistory,
175                 rerunFailingTestsCount,
176                 xsdSchemaLocation,
177                 encoding,
178                 isForking,
179                 true,
180                 true,
181                 xmlReporter,
182                 consoleOutputReporter,
183                 testsetReporter);
184     }
185 
186     public boolean isUseFile() {
187         return useFile;
188     }
189 
190     public boolean isPrintSummary() {
191         return printSummary;
192     }
193 
194     public String getReportFormat() {
195         return reportFormat;
196     }
197 
198     public String getReportNameSuffix() {
199         return reportNameSuffix;
200     }
201 
202     public boolean isRedirectTestOutputToFile() {
203         return redirectTestOutputToFile;
204     }
205 
206     public File getReportsDirectory() {
207         return reportsDirectory;
208     }
209 
210     public int getRerunFailingTestsCount() {
211         return rerunFailingTestsCount;
212     }
213 
214     public StatelessReportEventListener<WrappedReportEntry, TestSetStats> instantiateStatelessXmlReporter(
215             Integer forkNumber) {
216         assert (forkNumber == null) == !isForking;
217 
218         // If forking TestNG the suites have same name 'TestSuite' and tend to override report statistics in stateful
219         // reporter, see Surefire1535TestNGParallelSuitesIT. The testClassMethodRunHistory should be isolated.
220         // In the in-plugin execution of parallel JUnit4.7 with rerun the map must be shared because reports and
221         // listeners are in ThreadLocal, see Surefire1122ParallelAndFlakyTestsIT.
222         Map<String, Deque<WrappedReportEntry>> testClassMethodRunHistory =
223                 isForking ? new ConcurrentHashMap<String, Deque<WrappedReportEntry>>() : this.testClassMethodRunHistory;
224 
225         DefaultStatelessReportMojoConfiguration xmlReporterConfig = new DefaultStatelessReportMojoConfiguration(
226                 resolveReportsDirectory(forkNumber),
227                 reportNameSuffix,
228                 trimStackTrace,
229                 rerunFailingTestsCount,
230                 xsdSchemaLocation,
231                 enableOutErrElements,
232                 enablePropertiesElement,
233                 testClassMethodRunHistory);
234 
235         return xmlReporter.isDisable() ? null : xmlReporter.createListener(xmlReporterConfig);
236     }
237 
238     public StatelessTestsetInfoFileReportEventListener<WrappedReportEntry, TestSetStats> instantiateFileReporter(
239             Integer forkNumber) {
240         return !testsetReporter.isDisable() && isUseFile() && isBriefOrPlainFormat()
241                 ? testsetReporter.createListener(resolveReportsDirectory(forkNumber), reportNameSuffix, encoding)
242                 : null;
243     }
244 
245     public StatelessTestsetInfoConsoleReportEventListener<WrappedReportEntry, TestSetStats> instantiateConsoleReporter(
246             ConsoleLogger consoleLogger) {
247         return !testsetReporter.isDisable() && shouldReportToConsole()
248                 ? testsetReporter.createListener(consoleLogger)
249                 : null;
250     }
251 
252     public boolean isBriefOrPlainFormat() {
253         String fmt = getReportFormat();
254         return BRIEF.equals(fmt) || PLAIN.equals(fmt);
255     }
256 
257     public ConsoleOutputReportEventListener instantiateConsoleOutputFileReporter(Integer forkNum) {
258         ConsoleOutputReportEventListener outputReport = isRedirectTestOutputToFile()
259                 ? consoleOutputReporter.createListener(resolveReportsDirectory(forkNum), reportNameSuffix, forkNum)
260                 : consoleOutputReporter.createListener(originalSystemOut, originalSystemErr);
261         return consoleOutputReporter.isDisable() ? null : outputReport;
262     }
263 
264     public synchronized StatisticsReporter getStatisticsReporter() {
265         if (statisticsReporter == null) {
266             statisticsReporter = requiresRunHistory ? new StatisticsReporter(statisticsFile) : null;
267         }
268         return statisticsReporter;
269     }
270 
271     public File getStatisticsFile() {
272         return statisticsFile;
273     }
274 
275     public boolean isTrimStackTrace() {
276         return trimStackTrace;
277     }
278 
279     public boolean isRequiresRunHistory() {
280         return requiresRunHistory;
281     }
282 
283     public String getXsdSchemaLocation() {
284         return xsdSchemaLocation;
285     }
286 
287     public Charset getEncoding() {
288         return encoding;
289     }
290 
291     public boolean isForking() {
292         return isForking;
293     }
294 
295     public boolean isEnableOutErrElements() {
296         return enableOutErrElements;
297     }
298 
299     public boolean isEnablePropertiesElement() {
300         return enablePropertiesElement;
301     }
302 
303     private File resolveReportsDirectory(Integer forkNumber) {
304         return forkNumber == null ? reportsDirectory : replaceForkThreadsInPath(reportsDirectory, forkNumber);
305     }
306 
307     public SurefireStatelessReporter getXmlReporter() {
308         return xmlReporter;
309     }
310 
311     public SurefireConsoleOutputReporter getConsoleOutputReporter() {
312         return consoleOutputReporter;
313     }
314 
315     public SurefireStatelessTestsetInfoReporter getTestsetReporter() {
316         return testsetReporter;
317     }
318 
319     private boolean shouldReportToConsole() {
320         return isUseFile() ? isPrintSummary() : isRedirectTestOutputToFile() || isBriefOrPlainFormat();
321     }
322 }