~ubuntu-branches/ubuntu/precise/surefire/precise

« back to all changes in this revision

Viewing changes to surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireStarter.java

  • Committer: Bazaar Package Importer
  • Author(s): Miguel Landaeta
  • Date: 2011-10-10 20:42:16 UTC
  • mfrom: (2.2.4 sid)
  • Revision ID: james.westby@ubuntu.com-20111010204216-cemva69wkagf4fay
Tags: 2.10-1
* Team upload.
* New upstream release.
* Refresh and remove unneccesary patches.
* Add Build-Depends on libsurefire-java and
  libmaven-common-artifact-filters-java.
* Drop outdated Maven artifact surefire-junit.
* Provide new Maven artifacts: surefire-junit3, maven-surefire-common,
  common-junit3, common-junit4, surefire-junit47 and surefire-testng-utils.
* Fix clean target to allow "two in a row" builds.
* Update Vcs-Browser field.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.apache.maven.surefire.booter;
 
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.io.PrintStream;
 
23
import org.apache.maven.surefire.providerapi.SurefireProvider;
 
24
import org.apache.maven.surefire.report.ReporterException;
 
25
import org.apache.maven.surefire.suite.RunResult;
 
26
import org.apache.maven.surefire.testset.TestSetFailedException;
 
27
import org.apache.maven.surefire.util.NestedRuntimeException;
 
28
import org.apache.maven.surefire.util.ReflectionUtils;
 
29
 
 
30
/**
 
31
 * Invokes surefire with the correct classloader setup.
 
32
 * <p/>
 
33
 * This part of the booter is always guaranteed to be in the
 
34
 * same vm as the tests will be run in.
 
35
 *
 
36
 * @author Jason van Zyl
 
37
 * @author Brett Porter
 
38
 * @author Emmanuel Venisse
 
39
 * @author Dan Fabulich
 
40
 * @author Kristian Rosenvold
 
41
 * @version $Id$
 
42
 */
 
43
public class SurefireStarter
 
44
{
 
45
    private final ProviderConfiguration providerConfiguration;
 
46
 
 
47
    private final StartupConfiguration startupConfiguration;
 
48
 
 
49
    private final static String SUREFIRE_TEST_CLASSPATH = "surefire.test.class.path";
 
50
 
 
51
    private final StartupReportConfiguration startupReportConfiguration;
 
52
 
 
53
    public SurefireStarter( StartupConfiguration startupConfiguration, ProviderConfiguration providerConfiguration,
 
54
                            StartupReportConfiguration startupReportConfiguration )
 
55
    {
 
56
        this.providerConfiguration = providerConfiguration;
 
57
        this.startupConfiguration = startupConfiguration;
 
58
        this.startupReportConfiguration = startupReportConfiguration;
 
59
    }
 
60
 
 
61
    public RunResult runSuitesInProcessWhenForked( TypeEncodedValue testSet )
 
62
        throws SurefireExecutionException
 
63
    {
 
64
        writeSurefireTestClasspathProperty();
 
65
        final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
 
66
 
 
67
        // todo: Find out....
 
68
        // Why is the classloader structure created differently when a testSet is specified ?
 
69
        // Smells like a legacy bug. Need to check issue tracker.
 
70
        ClassLoader testsClassLoader = classpathConfiguration.createTestClassLoaderConditionallySystem(
 
71
            startupConfiguration.useSystemClassLoader() );
 
72
 
 
73
        ClassLoader surefireClassLoader = classpathConfiguration.createSurefireClassLoader( testsClassLoader );
 
74
 
 
75
        SurefireReflector surefireReflector = new SurefireReflector( surefireClassLoader );
 
76
 
 
77
        final Object forkingReporterFactory = createForkingReporterFactory( surefireReflector );
 
78
 
 
79
        Object test = testSet.getDecodedValue();
 
80
 
 
81
        return invokeProvider( test, testsClassLoader, surefireClassLoader, forkingReporterFactory );
 
82
    }
 
83
 
 
84
    private Object createForkingReporterFactory( SurefireReflector surefireReflector )
 
85
    {
 
86
        final Boolean trimStackTrace = this.providerConfiguration.getReporterConfiguration().isTrimStackTrace();
 
87
        final PrintStream originalSystemOut =
 
88
            this.providerConfiguration.getReporterConfiguration().getOriginalSystemOut();
 
89
        return surefireReflector.createForkingReporterFactory( trimStackTrace, originalSystemOut );
 
90
    }
 
91
 
 
92
    // todo: Fix duplication in this method and runSuitesInProcess
 
93
    // This should be fixed "at a higher level", because this whole way
 
94
    // of organizing the code stinks.
 
95
 
 
96
    public RunResult runSuitesInProcessWhenForked()
 
97
        throws SurefireExecutionException
 
98
    {
 
99
        ClassLoader testsClassLoader = createInProcessTestClassLoader();
 
100
 
 
101
        ClassLoader surefireClassLoader = createSurefireClassloader( testsClassLoader );
 
102
 
 
103
        SurefireReflector surefireReflector = new SurefireReflector( surefireClassLoader );
 
104
 
 
105
        final Object factory = createForkingReporterFactory( surefireReflector );
 
106
 
 
107
        return invokeProvider( null, testsClassLoader, surefireClassLoader, factory );
 
108
    }
 
109
 
 
110
    public RunResult runSuitesInProcess()
 
111
        throws SurefireExecutionException
 
112
    {
 
113
        // The test classloader must be constructed first to avoid issues with commons-logging until we properly
 
114
        // separate the TestNG classloader
 
115
        ClassLoader testsClassLoader = createInProcessTestClassLoader();
 
116
 
 
117
        ClassLoader surefireClassLoader = createSurefireClassloader( testsClassLoader );
 
118
 
 
119
        SurefireReflector surefireReflector = new SurefireReflector( surefireClassLoader );
 
120
 
 
121
        final Object factory = surefireReflector.createReportingReporterFactory( startupReportConfiguration );
 
122
 
 
123
        return invokeProvider( null, testsClassLoader, surefireClassLoader, factory );
 
124
    }
 
125
 
 
126
    private ClassLoader createSurefireClassloader( ClassLoader testsClassLoader )
 
127
        throws SurefireExecutionException
 
128
    {
 
129
        final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
 
130
 
 
131
        return classpathConfiguration.createSurefireClassLoader( testsClassLoader );
 
132
    }
 
133
 
 
134
    private ClassLoader createInProcessTestClassLoader()
 
135
        throws SurefireExecutionException
 
136
    {
 
137
        writeSurefireTestClasspathProperty();
 
138
        ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
 
139
        if ( startupConfiguration.isManifestOnlyJarRequestedAndUsable() )
 
140
        {
 
141
            ClassLoader testsClassLoader = getClass().getClassLoader(); // ClassLoader.getSystemClassLoader()
 
142
            // SUREFIRE-459, trick the app under test into thinking its classpath was conventional
 
143
            // (instead of a single manifest-only jar)
 
144
            System.setProperty( "surefire.real.class.path", System.getProperty( "java.class.path" ) );
 
145
            classpathConfiguration.getTestClasspath().writeToSystemProperty( "java.class.path" );
 
146
            return testsClassLoader;
 
147
        }
 
148
        else
 
149
        {
 
150
            return classpathConfiguration.createTestClassLoader();
 
151
        }
 
152
    }
 
153
 
 
154
    private void writeSurefireTestClasspathProperty()
 
155
    {
 
156
        ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
 
157
        classpathConfiguration.getTestClasspath().writeToSystemProperty( SUREFIRE_TEST_CLASSPATH );
 
158
    }
 
159
 
 
160
    private RunResult invokeProvider( Object testSet, ClassLoader testsClassLoader, ClassLoader surefireClassLoader,
 
161
                                      Object factory )
 
162
    {
 
163
        final PrintStream orgSystemOut = System.out;
 
164
        final PrintStream orgSystemErr = System.err;
 
165
        // Note that System.out/System.err are also read in the "ReporterConfiguration" instatiation
 
166
        // in createProvider below. These are the same values as here.
 
167
 
 
168
        ProviderFactory providerFactory =
 
169
            new ProviderFactory( startupConfiguration, providerConfiguration, surefireClassLoader, testsClassLoader,
 
170
                                 factory );
 
171
        final SurefireProvider provider = providerFactory.createProvider();
 
172
 
 
173
        try
 
174
        {
 
175
            return provider.invoke( testSet );
 
176
        }
 
177
        catch ( TestSetFailedException e )
 
178
        {
 
179
            throw new NestedRuntimeException( e );
 
180
        }
 
181
        catch ( ReporterException e )
 
182
        {
 
183
            throw new NestedRuntimeException( e );
 
184
        }
 
185
        finally
 
186
        {
 
187
            if ( System.getSecurityManager() == null )
 
188
            {
 
189
                System.setOut( orgSystemOut );
 
190
                System.setErr( orgSystemErr );
 
191
            }
 
192
        }
 
193
    }
 
194
}