Coverage Report - org.apache.maven.surefire.junit4.JUnit4Provider
 
Classes in this File Line Coverage Branch Coverage Complexity
JUnit4Provider
9%
9/95
0%
0/36
3,182
 
 1  
 package org.apache.maven.surefire.junit4;
 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 java.lang.reflect.Method;
 23  
 import java.util.Iterator;
 24  
 import java.util.List;
 25  
 
 26  
 import org.apache.maven.shared.utils.io.SelectorUtils;
 27  
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 28  
 import org.apache.maven.surefire.common.junit4.JUnit4RunListenerFactory;
 29  
 import org.apache.maven.surefire.common.junit4.JUnit4TestChecker;
 30  
 import org.apache.maven.surefire.providerapi.AbstractProvider;
 31  
 import org.apache.maven.surefire.providerapi.ProviderParameters;
 32  
 import org.apache.maven.surefire.report.ConsoleOutputCapture;
 33  
 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
 34  
 import org.apache.maven.surefire.report.PojoStackTraceWriter;
 35  
 import org.apache.maven.surefire.report.ReportEntry;
 36  
 import org.apache.maven.surefire.report.ReporterException;
 37  
 import org.apache.maven.surefire.report.ReporterFactory;
 38  
 import org.apache.maven.surefire.report.RunListener;
 39  
 import org.apache.maven.surefire.report.SimpleReportEntry;
 40  
 import org.apache.maven.surefire.suite.RunResult;
 41  
 import org.apache.maven.surefire.testset.TestSetFailedException;
 42  
 import org.apache.maven.surefire.util.RunOrderCalculator;
 43  
 import org.apache.maven.surefire.util.ScanResult;
 44  
 import org.apache.maven.surefire.util.TestsToRun;
 45  
 import org.apache.maven.surefire.util.internal.StringUtils;
 46  
 
 47  
 import org.junit.runner.Request;
 48  
 import org.junit.runner.Result;
 49  
 import org.junit.runner.Runner;
 50  
 import org.junit.runner.notification.RunNotifier;
 51  
 
 52  
 /**
 53  
  * @author Kristian Rosenvold
 54  
  */
 55  
 public class JUnit4Provider
 56  
     extends AbstractProvider
 57  
 {
 58  
     private final ClassLoader testClassLoader;
 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  
     private final RunOrderCalculator runOrderCalculator;
 71  
 
 72  
     private final ScanResult scanResult;
 73  
 
 74  
 
 75  
     public JUnit4Provider( ProviderParameters booterParameters )
 76  1
     {
 77  1
         this.providerParameters = booterParameters;
 78  1
         this.testClassLoader = booterParameters.getTestClassLoader();
 79  1
         this.scanResult = booterParameters.getScanResult();
 80  1
         this.runOrderCalculator = booterParameters.getRunOrderCalculator();
 81  1
         customRunListeners = JUnit4RunListenerFactory.
 82  
             createCustomListeners( booterParameters.getProviderProperties().getProperty( "listener" ) );
 83  1
         jUnit4TestChecker = new JUnit4TestChecker( testClassLoader );
 84  1
         requestedTestMethod = booterParameters.getTestRequest().getRequestedTestMethod();
 85  
 
 86  1
     }
 87  
 
 88  
     public RunResult invoke( Object forkTestSet )
 89  
         throws TestSetFailedException, ReporterException
 90  
     {
 91  0
         if ( testsToRun == null )
 92  
         {
 93  0
             if ( forkTestSet instanceof TestsToRun )
 94  
             {
 95  0
                 testsToRun = (TestsToRun) forkTestSet;
 96  
             }
 97  0
             else if ( forkTestSet instanceof Class )
 98  
             {
 99  0
                 testsToRun = TestsToRun.fromClass( (Class) forkTestSet );
 100  
             }
 101  
             else
 102  
             {
 103  0
                 testsToRun = scanClassPath();
 104  
             }
 105  
         }
 106  
 
 107  0
         upgradeCheck();
 108  
 
 109  0
         final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
 110  
 
 111  0
         final RunListener reporter = reporterFactory.createReporter();
 112  
 
 113  0
         ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporter );
 114  
 
 115  0
         JUnit4RunListener jUnit4TestSetReporter = new JUnit4RunListener( reporter );
 116  
 
 117  0
         Result result = new Result();
 118  0
         RunNotifier runNotifer = getRunNotifer( jUnit4TestSetReporter, result, customRunListeners );
 119  
 
 120  0
         runNotifer.fireTestRunStarted( null );
 121  
 
 122  0
         for ( Class aTestsToRun : testsToRun )
 123  
         {
 124  0
             executeTestSet( aTestsToRun, reporter, runNotifer );
 125  
         }
 126  
 
 127  0
         runNotifer.fireTestRunFinished( result );
 128  
 
 129  0
         JUnit4RunListener.rethrowAnyTestMechanismFailures( result );
 130  
 
 131  0
         closeRunNotifer( jUnit4TestSetReporter, customRunListeners );
 132  
 
 133  0
         return reporterFactory.close();
 134  
     }
 135  
 
 136  
     private void executeTestSet( Class<?> clazz, RunListener reporter, RunNotifier listeners )
 137  
         throws ReporterException, TestSetFailedException
 138  
     {
 139  0
         final ReportEntry report = new SimpleReportEntry( this.getClass().getName(), clazz.getName() );
 140  
 
 141  0
         reporter.testSetStarting( report );
 142  
 
 143  
         try
 144  
         {
 145  0
             if ( !StringUtils.isBlank( this.requestedTestMethod ) )
 146  
             {
 147  0
                 String actualTestMethod = getMethod( clazz, this.requestedTestMethod );//add by rainLee
 148  0
                 String[] testMethods = StringUtils.split( actualTestMethod, "+" );
 149  0
                 execute( clazz, listeners, testMethods );
 150  0
             }
 151  
             else
 152  
             {//the original way
 153  0
                 execute( clazz, listeners, null );
 154  
             }
 155  
         }
 156  0
         catch ( TestSetFailedException e )
 157  
         {
 158  0
             throw e;
 159  
         }
 160  0
         catch ( Throwable e )
 161  
         {
 162  0
             reporter.testError( SimpleReportEntry.withException( report.getSourceName(), report.getName(),
 163  
                                                                  new PojoStackTraceWriter( report.getSourceName(),
 164  
                                                                                            report.getName(), e ) ) );
 165  
         }
 166  
         finally
 167  
         {
 168  0
             reporter.testSetCompleted( report );
 169  0
         }
 170  0
     }
 171  
 
 172  
     private RunNotifier getRunNotifer( org.junit.runner.notification.RunListener main, Result result,
 173  
                                        List<org.junit.runner.notification.RunListener> others )
 174  
     {
 175  0
         RunNotifier fNotifier = new RunNotifier();
 176  0
         fNotifier.addListener( main );
 177  0
         fNotifier.addListener( result.createListener() );
 178  0
         for ( org.junit.runner.notification.RunListener listener : others )
 179  
         {
 180  0
             fNotifier.addListener( listener );
 181  
         }
 182  0
         return fNotifier;
 183  
     }
 184  
 
 185  
     // I am not entierly sure as to why we do this explicit freeing, it's one of those
 186  
     // pieces of code that just seem to linger on in here ;)
 187  
     private void closeRunNotifer( org.junit.runner.notification.RunListener main,
 188  
                                   List<org.junit.runner.notification.RunListener> others )
 189  
     {
 190  0
         RunNotifier fNotifier = new RunNotifier();
 191  0
         fNotifier.removeListener( main );
 192  0
         for ( org.junit.runner.notification.RunListener listener : others )
 193  
         {
 194  0
             fNotifier.removeListener( listener );
 195  
         }
 196  0
     }
 197  
 
 198  
     public Iterator<?> getSuites()
 199  
     {
 200  0
         testsToRun = scanClassPath();
 201  0
         return testsToRun.iterator();
 202  
     }
 203  
 
 204  
     private TestsToRun scanClassPath()
 205  
     {
 206  0
         final TestsToRun scannedClasses = scanResult.applyFilter( jUnit4TestChecker, testClassLoader );
 207  0
         return runOrderCalculator.orderTestClasses( scannedClasses );
 208  
     }
 209  
 
 210  
     @SuppressWarnings("unchecked")
 211  
     private void upgradeCheck()
 212  
         throws TestSetFailedException
 213  
     {
 214  0
         if ( isJunit4UpgradeCheck() )
 215  
         {
 216  0
             List<Class> classesSkippedByValidation =
 217  
                 scanResult.getClassesSkippedByValidation( jUnit4TestChecker, testClassLoader );
 218  0
             if ( !classesSkippedByValidation.isEmpty() )
 219  
             {
 220  0
                 StringBuilder reason = new StringBuilder();
 221  0
                 reason.append( "Updated check failed\n" );
 222  0
                 reason.append( "There are tests that would be run with junit4 / surefire 2.6 but not with [2.7,):\n" );
 223  0
                 for ( Class testClass : classesSkippedByValidation )
 224  
                 {
 225  0
                     reason.append( "   " );
 226  0
                     reason.append( testClass.getName() );
 227  0
                     reason.append( "\n" );
 228  
                 }
 229  0
                 throw new TestSetFailedException( reason.toString() );
 230  
             }
 231  
         }
 232  0
     }
 233  
 
 234  
     private boolean isJunit4UpgradeCheck()
 235  
     {
 236  0
         final String property = System.getProperty( "surefire.junit4.upgradecheck" );
 237  0
         return property != null;
 238  
     }
 239  
 
 240  
 
 241  
     private static void execute( Class<?> testClass, RunNotifier fNotifier, String[] testMethods )
 242  
         throws TestSetFailedException
 243  
     {
 244  0
         if ( null != testMethods )
 245  
         {
 246  0
             Method[] methods = testClass.getMethods();
 247  0
             for ( Method method : methods )
 248  
             {
 249  0
                 for ( String testMethod : testMethods )
 250  
                 {
 251  0
                     if ( SelectorUtils.match( testMethod, method.getName() ) )
 252  
                     {
 253  0
                         Runner junitTestRunner = Request.method( testClass, method.getName() ).getRunner();
 254  0
                         junitTestRunner.run( fNotifier );
 255  
                     }
 256  
 
 257  
                 }
 258  
             }
 259  0
             return;
 260  
         }
 261  
 
 262  0
         Runner junitTestRunner = Request.aClass( testClass ).getRunner();
 263  
 
 264  0
         junitTestRunner.run( fNotifier );
 265  0
     }
 266  
 
 267  
     /**
 268  
      * this method retrive  testMethods from String like "com.xx.ImmutablePairTest#testBasic,com.xx.StopWatchTest#testLang315+testStopWatchSimpleGet"
 269  
      * <br>
 270  
      * and we need to think about cases that 2 or more method in 1 class. we should choose the correct method
 271  
      *
 272  
      * @param testClass     the testclass
 273  
      * @param testMethodStr the test method string
 274  
      * @return a string ;)
 275  
      */
 276  
     private static String getMethod( Class testClass, String testMethodStr )
 277  
     {
 278  0
         String className = testClass.getName();
 279  
 
 280  0
         if ( !testMethodStr.contains( "#" ) && !testMethodStr.contains( "," ) )
 281  
         {//the original way
 282  0
             return testMethodStr;
 283  
         }
 284  0
         testMethodStr += ",";//for the bellow  split code
 285  0
         int beginIndex = testMethodStr.indexOf( className );
 286  0
         int endIndex = testMethodStr.indexOf( ",", beginIndex );
 287  0
         String classMethodStr =
 288  
             testMethodStr.substring( beginIndex, endIndex );//String like "StopWatchTest#testLang315"
 289  
 
 290  0
         int index = classMethodStr.indexOf( '#' );
 291  0
         if ( index >= 0 )
 292  
         {
 293  0
             return classMethodStr.substring( index + 1, classMethodStr.length() );
 294  
         }
 295  0
         return null;
 296  
     }
 297  
 }