1 package org.apache.maven.plugin.surefire;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.execution.MavenExecutionRequest;
23 import org.apache.maven.execution.MavenSession;
24 import org.apache.maven.plugin.MojoExecutionException;
25 import org.apache.maven.plugin.MojoFailureException;
26 import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
27 import org.apache.maven.surefire.cli.CommandLineOption;
28 import org.apache.maven.surefire.suite.RunResult;
29 import org.apache.maven.surefire.testset.TestSetFailedException;
30 import org.apache.maven.surefire.util.internal.DumpFileUtils;
31
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.List;
37
38 import static java.util.Collections.unmodifiableList;
39 import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
40 import static org.apache.maven.surefire.booter.DumpErrorSingleton.DUMPSTREAM_FILE_EXT;
41 import static org.apache.maven.surefire.booter.DumpErrorSingleton.DUMP_FILE_EXT;
42 import static org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_DEBUG;
43 import static org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_ERROR;
44 import static org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_INFO;
45 import static org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_WARN;
46 import static org.apache.maven.surefire.cli.CommandLineOption.SHOW_ERRORS;
47
48
49
50
51 public final class SurefireHelper
52 {
53 private static final String DUMP_FILE_DATE = DumpFileUtils.newFormattedDateFileName();
54
55 public static final String DUMP_FILE_PREFIX = DUMP_FILE_DATE + "-jvmRun";
56
57 public static final String DUMPSTREAM_FILENAME_FORMATTER = DUMP_FILE_PREFIX + "%d" + DUMPSTREAM_FILE_EXT;
58
59
60
61
62
63
64
65
66
67
68
69
70 private static final int MAX_PATH_LENGTH_WINDOWS = 247;
71
72 private static final String[] DUMP_FILES_PRINT =
73 {
74 "[date]-jvmRun[N]" + DUMP_FILE_EXT,
75 "[date]" + DUMPSTREAM_FILE_EXT,
76 "[date]-jvmRun[N]" + DUMPSTREAM_FILE_EXT
77 };
78
79
80
81
82 private SurefireHelper()
83 {
84 throw new IllegalAccessError( "Utility class" );
85 }
86
87 public static String[] getDumpFilesToPrint()
88 {
89 return DUMP_FILES_PRINT.clone();
90 }
91
92 public static void reportExecution( SurefireReportParameters reportParameters, RunResult result,
93 PluginConsoleLogger log, Exception firstForkException )
94 throws MojoFailureException, MojoExecutionException
95 {
96 if ( firstForkException == null && !result.isTimeout() && result.isErrorFree() )
97 {
98 if ( result.getCompletedCount() == 0 && failIfNoTests( reportParameters ) )
99 {
100 throw new MojoFailureException( "No tests were executed! "
101 + "(Set -DfailIfNoTests=false to ignore this error.)" );
102 }
103 return;
104 }
105
106 if ( reportParameters.isTestFailureIgnore() )
107 {
108 log.error( createErrorMessage( reportParameters, result, firstForkException ) );
109 }
110 else
111 {
112 throwException( reportParameters, result, firstForkException );
113 }
114 }
115
116 public static List<CommandLineOption> commandLineOptions( MavenSession session, PluginConsoleLogger log )
117 {
118 List<CommandLineOption> cli = new ArrayList<CommandLineOption>();
119 if ( log.isErrorEnabled() )
120 {
121 cli.add( LOGGING_LEVEL_ERROR );
122 }
123
124 if ( log.isWarnEnabled() )
125 {
126 cli.add( LOGGING_LEVEL_WARN );
127 }
128
129 if ( log.isInfoEnabled() )
130 {
131 cli.add( LOGGING_LEVEL_INFO );
132 }
133
134 if ( log.isDebugEnabled() )
135 {
136 cli.add( LOGGING_LEVEL_DEBUG );
137 }
138
139 try
140 {
141 Method getRequestMethod = session.getClass().getMethod( "getRequest" );
142 MavenExecutionRequest request = (MavenExecutionRequest) getRequestMethod.invoke( session );
143
144 if ( request.isShowErrors() )
145 {
146 cli.add( SHOW_ERRORS );
147 }
148
149 String f = getFailureBehavior( request );
150 if ( f != null )
151 {
152
153 cli.add( CommandLineOption.valueOf( f.startsWith( "REACTOR_" ) ? f : "REACTOR_" + f ) );
154 }
155 }
156 catch ( Exception e )
157 {
158
159 }
160 return unmodifiableList( cli );
161 }
162
163 public static void logDebugOrCliShowErrors( String s, PluginConsoleLogger log, Collection<CommandLineOption> cli )
164 {
165 if ( cli.contains( LOGGING_LEVEL_DEBUG ) )
166 {
167 log.debug( s );
168 }
169 else if ( cli.contains( SHOW_ERRORS ) )
170 {
171 if ( log.isDebugEnabled() )
172 {
173 log.debug( s );
174 }
175 else
176 {
177 log.info( s );
178 }
179 }
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 public static String escapeToPlatformPath( String path )
196 {
197 if ( IS_OS_WINDOWS && path.length() > MAX_PATH_LENGTH_WINDOWS )
198 {
199 path = path.startsWith( "\\\\" ) ? "\\\\?\\UNC\\" + path.substring( 2 ) : "\\\\?\\" + path;
200 }
201 return path;
202 }
203
204 private static String getFailureBehavior( MavenExecutionRequest request )
205 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
206 {
207 try
208 {
209 return request.getFailureBehavior();
210 }
211 catch ( NoSuchMethodError e )
212 {
213 return (String) request.getClass()
214 .getMethod( "getReactorFailureBehavior" )
215 .invoke( request );
216 }
217 }
218
219 private static boolean failIfNoTests( SurefireReportParameters reportParameters )
220 {
221 return reportParameters.getFailIfNoTests() != null && reportParameters.getFailIfNoTests();
222 }
223
224 private static boolean isFatal( Exception firstForkException )
225 {
226 return firstForkException != null && !( firstForkException instanceof TestSetFailedException );
227 }
228
229 private static void throwException( SurefireReportParameters reportParameters, RunResult result,
230 Exception firstForkException )
231 throws MojoFailureException, MojoExecutionException
232 {
233 if ( isFatal( firstForkException ) || result.isInternalError() )
234 {
235 throw new MojoExecutionException( createErrorMessage( reportParameters, result, firstForkException ),
236 firstForkException );
237 }
238 else
239 {
240 throw new MojoFailureException( createErrorMessage( reportParameters, result, firstForkException ),
241 firstForkException );
242 }
243 }
244
245 private static String createErrorMessage( SurefireReportParameters reportParameters, RunResult result,
246 Exception firstForkException )
247 {
248 StringBuilder msg = new StringBuilder( 512 );
249
250 if ( result.isTimeout() )
251 {
252 msg.append( "There was a timeout or other error in the fork" );
253 }
254 else
255 {
256 msg.append( "There are test failures.\n\nPlease refer to " )
257 .append( reportParameters.getReportsDirectory() )
258 .append( " for the individual test results." )
259 .append( '\n' )
260 .append( "Please refer to dump files (if any exist) " )
261 .append( DUMP_FILES_PRINT[0] )
262 .append( ", " )
263 .append( DUMP_FILES_PRINT[1] )
264 .append( " and " )
265 .append( DUMP_FILES_PRINT[2] )
266 .append( "." );
267 }
268
269 if ( firstForkException != null && firstForkException.getLocalizedMessage() != null )
270 {
271 msg.append( '\n' )
272 .append( firstForkException.getLocalizedMessage() );
273 }
274
275 if ( result.isFailure() )
276 {
277 msg.append( '\n' )
278 .append( result.getFailure() );
279 }
280
281 return msg.toString();
282 }
283
284 }