1 package org.apache.maven.surefire.junit4;
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.surefire.Surefire;
23 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
24 import org.apache.maven.surefire.common.junit4.JUnit4RunListenerFactory;
25 import org.apache.maven.surefire.common.junit4.JUnit4TestChecker;
26 import org.apache.maven.surefire.providerapi.AbstractProvider;
27 import org.apache.maven.surefire.providerapi.ProviderParameters;
28 import org.apache.maven.surefire.report.PojoStackTraceWriter;
29 import org.apache.maven.surefire.report.RunListener;
30 import org.apache.maven.surefire.report.ReportEntry;
31 import org.apache.maven.surefire.report.ReporterException;
32 import org.apache.maven.surefire.report.ReporterFactory;
33 import org.apache.maven.surefire.report.SimpleReportEntry;
34 import org.apache.maven.surefire.suite.RunResult;
35 import org.apache.maven.surefire.testset.TestSetFailedException;
36 import org.apache.maven.surefire.util.DefaultDirectoryScanner;
37 import org.apache.maven.surefire.util.DirectoryScanner;
38 import org.apache.maven.surefire.util.TestsToRun;
39
40 import org.junit.runner.notification.RunNotifier;
41
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.ResourceBundle;
45
46
47
48
49
50 @SuppressWarnings( { "UnusedDeclaration" } )
51 public class JUnit4Provider extends AbstractProvider
52 {
53
54 private static ResourceBundle bundle = ResourceBundle.getBundle( Surefire.SUREFIRE_BUNDLE_NAME );
55
56 private final ClassLoader testClassLoader;
57
58 private final DirectoryScanner directoryScanner;
59
60 private final List<org.junit.runner.notification.RunListener> customRunListeners;
61
62 private final JUnit4TestChecker jUnit4TestChecker;
63
64 private final String requestedTestMethod;
65
66 private TestsToRun testsToRun;
67
68 private final ProviderParameters providerParameters;
69
70 public JUnit4Provider( ProviderParameters booterParameters )
71 {
72 this.providerParameters = booterParameters;
73 this.testClassLoader = booterParameters.getTestClassLoader();
74 this.directoryScanner = booterParameters.getDirectoryScanner();
75 customRunListeners = JUnit4RunListenerFactory.
76 createCustomListeners( booterParameters.getProviderProperties().getProperty( "listener" ) );
77 jUnit4TestChecker = new JUnit4TestChecker( testClassLoader );
78 requestedTestMethod = booterParameters.getTestRequest().getRequestedTestMethod();
79
80 }
81
82 @SuppressWarnings( { "UnnecessaryUnboxing" } )
83 public RunResult invoke( Object forkTestSet )
84 throws TestSetFailedException, ReporterException
85 {
86 if ( testsToRun == null )
87 {
88 testsToRun = forkTestSet == null ? scanClassPath() : TestsToRun.fromClass( (Class) forkTestSet );
89 }
90
91 upgradeCheck();
92
93 final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
94
95 RunListener reporter = reporterFactory.createReporter();
96 JUnit4RunListener jUnit4TestSetReporter = new JUnit4RunListener( reporter );
97 RunNotifier runNotifer = getRunNotifer( jUnit4TestSetReporter, customRunListeners );
98
99 for ( Class clazz : testsToRun.getLocatedClasses() )
100 {
101 executeTestSet( clazz, reporter, testClassLoader, runNotifer );
102 }
103
104 closeRunNotifer( jUnit4TestSetReporter, customRunListeners );
105
106 return reporterFactory.close();
107
108 }
109
110 private void executeTestSet( Class clazz, RunListener reporter, ClassLoader classLoader, RunNotifier listeners )
111 throws ReporterException, TestSetFailedException
112 {
113 final ReportEntry report = new SimpleReportEntry( this.getClass().getName(), clazz.getName() );
114
115 reporter.testSetStarting( report );
116
117 try
118 {
119 JUnit4TestSet.execute( clazz, listeners, this.requestedTestMethod );
120 }
121 catch ( TestSetFailedException e )
122 {
123 throw e;
124 }
125 catch ( Throwable e )
126 {
127 reporter.testError( new SimpleReportEntry( report.getSourceName(), report.getName(),
128 new PojoStackTraceWriter( report.getSourceName(),
129 report.getName(), e ) ) );
130 }
131 finally
132 {
133 reporter.testSetCompleted( report );
134 }
135 }
136
137 private RunNotifier getRunNotifer( org.junit.runner.notification.RunListener main, List<org.junit.runner.notification.RunListener> others )
138 {
139 RunNotifier fNotifier = new RunNotifier();
140 fNotifier.addListener( main );
141 for ( org.junit.runner.notification.RunListener listener : others )
142 {
143 fNotifier.addListener( listener );
144 }
145 return fNotifier;
146 }
147
148
149
150 private void closeRunNotifer( org.junit.runner.notification.RunListener main, List<org.junit.runner.notification.RunListener> others )
151 {
152 RunNotifier fNotifier = new RunNotifier();
153 fNotifier.removeListener( main );
154 for ( org.junit.runner.notification.RunListener listener : others )
155 {
156 fNotifier.removeListener( listener );
157 }
158 }
159
160 public Iterator getSuites()
161 {
162 testsToRun = scanClassPath();
163 return testsToRun.iterator();
164 }
165
166 private TestsToRun scanClassPath()
167 {
168 return directoryScanner.locateTestClasses( testClassLoader, jUnit4TestChecker );
169 }
170
171 private void upgradeCheck()
172 throws TestSetFailedException
173 {
174 if ( isJunit4UpgradeCheck()
175 && ( (DefaultDirectoryScanner) directoryScanner ).getClassesSkippedByValidation().size() > 0 )
176 {
177 StringBuilder reason = new StringBuilder();
178 reason.append( "Updated check failed\n" );
179 reason.append( "There are tests that would be run with junit4 / surefire 2.6 but not with [2.7,):\n" );
180
181 for ( Class testClass : (List<Class>) ( (DefaultDirectoryScanner) directoryScanner ).getClassesSkippedByValidation() )
182 {
183 reason.append( " " );
184 reason.append( testClass.getCanonicalName() );
185 reason.append( "\n" );
186 }
187 throw new TestSetFailedException( reason.toString() );
188 }
189 }
190
191 private boolean isJunit4UpgradeCheck()
192 {
193 final String property = System.getProperty( "surefire.junit4.upgradecheck" );
194 return property != null;
195 }
196
197 public Boolean isRunnable()
198 {
199 return Boolean.TRUE;
200 }
201 }