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.surefire.junit;
20  
21  import java.util.Map;
22  
23  import org.apache.maven.surefire.api.provider.AbstractProvider;
24  import org.apache.maven.surefire.api.provider.ProviderParameters;
25  import org.apache.maven.surefire.api.report.ReporterFactory;
26  import org.apache.maven.surefire.api.report.SimpleReportEntry;
27  import org.apache.maven.surefire.api.report.TestSetReportEntry;
28  import org.apache.maven.surefire.api.suite.RunResult;
29  import org.apache.maven.surefire.api.testset.TestSetFailedException;
30  import org.apache.maven.surefire.api.util.RunOrderCalculator;
31  import org.apache.maven.surefire.api.util.ScanResult;
32  import org.apache.maven.surefire.api.util.TestsToRun;
33  import org.apache.maven.surefire.common.junit3.JUnit3Reflector;
34  import org.apache.maven.surefire.common.junit3.JUnit3TestChecker;
35  
36  import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture;
37  import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
38  import static org.apache.maven.surefire.api.util.ReflectionUtils.instantiate;
39  import static org.apache.maven.surefire.api.util.internal.ObjectUtils.isSecurityManagerSupported;
40  import static org.apache.maven.surefire.api.util.internal.ObjectUtils.systemProps;
41  
42  /**
43   * @author Kristian Rosenvold
44   */
45  public class JUnit3Provider extends AbstractProvider {
46      private final ClassLoader testClassLoader;
47  
48      private final PojoAndJUnit3Checker testChecker;
49  
50      private final JUnit3TestChecker jUnit3TestChecker;
51  
52      private final JUnit3Reflector reflector;
53  
54      private final ProviderParameters providerParameters;
55  
56      private final RunOrderCalculator runOrderCalculator;
57  
58      private final ScanResult scanResult;
59  
60      public JUnit3Provider(ProviderParameters booterParameters) {
61          this.providerParameters = booterParameters;
62          testClassLoader = booterParameters.getTestClassLoader();
63          scanResult = booterParameters.getScanResult();
64          runOrderCalculator = booterParameters.getRunOrderCalculator();
65          reflector = new JUnit3Reflector(testClassLoader);
66          jUnit3TestChecker = new JUnit3TestChecker(testClassLoader);
67          testChecker = new PojoAndJUnit3Checker(jUnit3TestChecker); // Todo; use reflector
68      }
69  
70      @Override
71      public RunResult invoke(Object forkTestSet) throws TestSetFailedException {
72          ReporterFactory reporterFactory = providerParameters.getReporterFactory();
73          JUnit3Reporter reporter = new JUnit3Reporter(reporterFactory.createTestReportListener());
74          reporter.setRunMode(NORMAL_RUN);
75          startCapture(reporter);
76  
77          final TestsToRun testsToRun;
78          if (forkTestSet instanceof TestsToRun) {
79              testsToRun = (TestsToRun) forkTestSet;
80          } else if (forkTestSet instanceof Class) {
81              testsToRun = TestsToRun.fromClass((Class<?>) forkTestSet);
82          } else {
83              testsToRun = scanClassPath();
84          }
85  
86          RunResult runResult;
87          try {
88              Map<String, String> systemProperties = systemProps();
89              setSystemManager(System.getProperty("surefire.security.manager"));
90  
91              for (Class<?> clazz : testsToRun) {
92                  SurefireTestSetExecutor surefireTestSetExecutor = createTestSet(clazz, reporter);
93                  executeTestSet(clazz, surefireTestSetExecutor, reporter, systemProperties);
94              }
95          } finally {
96              runResult = reporterFactory.close();
97          }
98          return runResult;
99      }
100 
101     static void setSystemManager(String smClassName) throws TestSetFailedException {
102         if (smClassName != null) {
103             if (!isSecurityManagerSupported()) {
104                 throw new TestSetFailedException("JDK does not support overriding Security Manager with "
105                         + "a value in system property 'surefire.security.manager'.");
106             }
107             ClassLoader classLoader = JUnit3Provider.class.getClassLoader();
108             SecurityManager sm = instantiate(classLoader, smClassName, SecurityManager.class);
109             System.setSecurityManager(sm);
110         }
111     }
112 
113     private SurefireTestSetExecutor createTestSet(Class<?> clazz, JUnit3Reporter reporter) {
114         return reflector.isJUnit3Available() && jUnit3TestChecker.accept(clazz)
115                 ? new JUnitTestSetExecutor(reflector, reporter)
116                 : new PojoTestSetExecutor(reporter);
117     }
118 
119     private void executeTestSet(
120             Class<?> testSet,
121             SurefireTestSetExecutor testSetExecutor,
122             JUnit3Reporter reporter,
123             Map<String, String> systemProperties)
124             throws TestSetFailedException {
125         String clazz = testSet.getName();
126         long testId = reporter.getClassMethodIndexer().indexClass(clazz);
127 
128         try {
129             TestSetReportEntry started = new SimpleReportEntry(NORMAL_RUN, testId, clazz, null, null, null);
130             reporter.testSetStarting(started);
131             testSetExecutor.execute(testSet, testClassLoader);
132         } finally {
133             TestSetReportEntry completed =
134                     new SimpleReportEntry(NORMAL_RUN, testId, clazz, null, null, null, systemProperties);
135             reporter.testSetCompleted(completed);
136         }
137     }
138 
139     private TestsToRun scanClassPath() {
140         TestsToRun testsToRun = scanResult.applyFilter(testChecker, testClassLoader);
141         return runOrderCalculator.orderTestClasses(testsToRun);
142     }
143 
144     @Override
145     public Iterable<Class<?>> getSuites() {
146         return scanClassPath();
147     }
148 }