}
private SurefireBooter constructSurefireBooter()
throws MojoExecutionException, MojoFailureException
{
SurefireBooter surefireBooter = new SurefireBooter();
Artifact surefireArtifact = (Artifact) pluginArtifactMap.get( "org.apache.maven.surefire:surefire-booter" );
if ( surefireArtifact == null )
{
throw new MojoExecutionException( "Unable to locate surefire-booter in the list of plugin artifacts" );
}
surefireArtifact.isSnapshot(); // TODO: this is ridiculous, but it fixes getBaseVersion to be -SNAPSHOT if
// needed
Artifact junitArtifact;
Artifact testNgArtifact;
try
{
addArtifact( surefireBooter, surefireArtifact );
junitArtifact = (Artifact) projectArtifactMap.get( junitArtifactName );
// SUREFIRE-378, junit can have an alternate artifact name
if ( junitArtifact == null && "junit:junit".equals( junitArtifactName ) )
{
junitArtifact = (Artifact) projectArtifactMap.get( "junit:junit-dep" );
}
// TODO: this is pretty manual, but I'd rather not require the plugin > dependencies section right now
testNgArtifact = (Artifact) projectArtifactMap.get( testNGArtifactName );
if ( testNgArtifact != null )
{
VersionRange range = VersionRange.createFromVersionSpec( "[4.7,)" );
if ( !range.containsVersion( new DefaultArtifactVersion( testNgArtifact.getVersion() ) ) )
{
throw new MojoFailureException(
"TestNG support requires version 4.7 or above. You have declared version "
+ testNgArtifact.getVersion() );
}
convertTestNGParameters();
if ( this.testClassesDirectory != null )
{
properties.setProperty( "testng.test.classpath", testClassesDirectory.getAbsolutePath() );
}
addArtifact( surefireBooter, testNgArtifact );
// The plugin uses a JDK based profile to select the right testng. We might be explicity using a
// different one since its based on the source level, not the JVM. Prune using the filter.
addProvider( surefireBooter, "surefire-testng", surefireArtifact.getBaseVersion(), testNgArtifact );
}
else if ( junitArtifact != null && junitArtifact.getBaseVersion().startsWith( "4" ) )
{
addProvider( surefireBooter, "surefire-junit4", surefireArtifact.getBaseVersion(), null );
}
else
{
// add the JUnit provider as default - it doesn't require JUnit to be present,
// since it supports POJO tests.
addProvider( surefireBooter, "surefire-junit", surefireArtifact.getBaseVersion(), null );
}
}
catch ( ArtifactNotFoundException e )
{
throw new MojoExecutionException( "Unable to locate required surefire provider dependency: "
+ e.getMessage(), e );
}
catch ( InvalidVersionSpecificationException e )
{
throw new MojoExecutionException( "Error determining the TestNG version requested: " + e.getMessage(), e );
}
catch ( ArtifactResolutionException e )
{
throw new MojoExecutionException( "Error to resolving surefire provider dependency: " + e.getMessage(), e );
}
if ( suiteXmlFiles != null && suiteXmlFiles.length > 0 && test == null )
{
if ( testNgArtifact == null )
{
throw new MojoExecutionException( "suiteXmlFiles is configured, but there is no TestNG dependency" );
}
// TODO: properties should be passed in here too
surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGXmlTestSuite", new Object[] {
suiteXmlFiles, testSourceDirectory.getAbsolutePath(), testNgArtifact.getBaseVersion(),
testNgArtifact.getClassifier(), properties, reportsDirectory } );
}
else
{
List includeList;
List excludeList;
if ( test != null )
{
// Check to see if we are running a single test. The raw parameter will
// come through if it has not been set.
// FooTest -> **/FooTest.java
includeList = new ArrayList();
excludeList = new ArrayList();
if ( failIfNoTests == null )
{
failIfNoTests = Boolean.TRUE;
}
String[] testRegexes = StringUtils.split( test, "," );
for ( int i = 0; i < testRegexes.length; i++ )
{
String testRegex = testRegexes[i];
if ( testRegex.endsWith( ".java" ) )
{
testRegex = testRegex.substring( 0, testRegex.length() - 5 );
}
// Allow paths delimited by '.' or '/'
testRegex = testRegex.replace( '.', '/' );
includeList.add( "**/" + testRegex + ".java" );
}
}
else
{
includeList = this.includes;
excludeList = this.excludes;
// defaults here, qdox doesn't like the end javadoc value
// Have to wrap in an ArrayList as surefire expects an ArrayList instead of a List for some reason
if ( includeList == null || includeList.size() == 0 )
{
includeList =
new ArrayList( Arrays.asList( new String[] { "**/Test*.java", "**/*Test.java",
"**/*TestCase.java" } ) );
}
if ( excludeList == null || excludeList.size() == 0 )
{
excludeList = new ArrayList( Arrays.asList( new String[] { "**/*$*" } ) );
}
}
if ( testNgArtifact != null )
{
surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGDirectoryTestSuite", new Object[] {
testClassesDirectory, includeList, excludeList, testSourceDirectory.getAbsolutePath(),
testNgArtifact.getBaseVersion(), testNgArtifact.getClassifier(), properties, reportsDirectory } );
}
else
{
String junitDirectoryTestSuite;
if ( junitArtifact != null && junitArtifact.getBaseVersion() != null
&& junitArtifact.getBaseVersion().startsWith( "4" ) )
{
junitDirectoryTestSuite = "org.apache.maven.surefire.junit4.JUnit4DirectoryTestSuite";
}
else
{
junitDirectoryTestSuite = "org.apache.maven.surefire.junit.JUnitDirectoryTestSuite";
}
// fall back to JUnit, which also contains POJO support. Also it can run
// classes compiled against JUnit since it has a dependency on JUnit itself.
surefireBooter.addTestSuite( junitDirectoryTestSuite, new Object[] { testClassesDirectory, includeList,
excludeList } );
}
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
getLog().debug( "Test Classpath :" );
// Check if we need to add configured classes/test classes directories here.
// If they are configured, we should remove the default to avoid conflicts.
if ( !project.getBuild().getOutputDirectory().equals( classesDirectory.getAbsolutePath() ) )
{
classpathElements.remove( project.getBuild().getOutputDirectory() );
classpathElements.add( classesDirectory.getAbsolutePath() );
}
if ( !project.getBuild().getTestOutputDirectory().equals( testClassesDirectory.getAbsolutePath() ) )
{
classpathElements.remove( project.getBuild().getTestOutputDirectory() );
classpathElements.add( testClassesDirectory.getAbsolutePath() );
}
for ( Iterator i = classpathElements.iterator(); i.hasNext(); )
{
String classpathElement = (String) i.next();
getLog().debug( " " + classpathElement );
surefireBooter.addClassPathUrl( classpathElement );
}
Toolchain tc = getToolchain();
if ( tc != null )
{
getLog().info( "Toolchain in surefire-plugin: " + tc );
if ( ForkConfiguration.FORK_NEVER.equals( forkMode ) )
{
forkMode = ForkConfiguration.FORK_ONCE;
}
if ( jvm != null )
{
getLog().warn( "Toolchains are ignored, 'executable' parameter is set to " + jvm );
}
else
{
jvm = tc.findTool( "java" ); // NOI18N
}
}
if ( additionalClasspathElements != null )
{
for ( Iterator i = additionalClasspathElements.iterator(); i.hasNext(); )
{
String classpathElement = (String) i.next();
getLog().debug( " " + classpathElement );
surefireBooter.addClassPathUrl( classpathElement );
}
}
// ----------------------------------------------------------------------
// Forking
// ----------------------------------------------------------------------
ForkConfiguration fork = new ForkConfiguration();
// DUNS
if ( project.getPackaging().equals( "nar" ) || ( getNarArtifacts().size() > 0 ) )
{
forkMode = "pertest";
}
fork.setForkMode( forkMode );
processSystemProperties( !fork.isForking() );
if ( getLog().isDebugEnabled() )
{
showMap( systemProperties, "system property" );
}
if ( fork.isForking() )
{
useSystemClassLoader = useSystemClassLoader == null ? Boolean.TRUE : useSystemClassLoader;
fork.setUseSystemClassLoader( useSystemClassLoader.booleanValue() );
fork.setUseManifestOnlyJar( useManifestOnlyJar );
fork.setSystemProperties( systemProperties );
if ( "true".equals( debugForkedProcess ) )
{
debugForkedProcess =
"-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
}
fork.setDebugLine( debugForkedProcess );
if ( jvm == null || "".equals( jvm ) )
{
// use the same JVM as the one used to run Maven (the "java.home" one)
jvm = System.getProperty( "java.home" ) + File.separator + "bin" + File.separator + "java";
getLog().debug( "Using JVM: " + jvm );
}
fork.setJvmExecutable( jvm );
if ( workingDirectory != null )
{
fork.setWorkingDirectory( workingDirectory );
}
else
{
fork.setWorkingDirectory( basedir );
}
// BEGINDUNS
if ( argLine == null )
{
argLine = "";
}
StringBuffer javaLibraryPath = new StringBuffer();
if ( testJNIModule() )
{
// Add libraries to java.library.path for testing
File jniLibraryPathEntry =
getLayout().getLibDirectory( getTargetDirectory(), getMavenProject().getArtifactId(),
getMavenProject().getVersion(), getAOL().toString(), Library.JNI );
if ( jniLibraryPathEntry.exists() )
{
getLog().debug( "Adding library directory to java.library.path: " + jniLibraryPathEntry );
if ( javaLibraryPath.length() > 0 )
{
javaLibraryPath.append( File.pathSeparator );
}
javaLibraryPath.append( jniLibraryPathEntry );
}
File sharedLibraryPathEntry =
getLayout().getLibDirectory( getTargetDirectory(), getMavenProject().getArtifactId(),
getMavenProject().getVersion(), getAOL().toString(), Library.SHARED );
if ( sharedLibraryPathEntry.exists() )
{
getLog().debug( "Adding library directory to java.library.path: " + sharedLibraryPathEntry );
if ( javaLibraryPath.length() > 0 )
{
javaLibraryPath.append( File.pathSeparator );
}
javaLibraryPath.append( sharedLibraryPathEntry );
}
// add jar file to classpath, as one may want to read a
// properties file for artifactId and version
String narFile = "target/" + project.getArtifactId() + "-" + project.getVersion() + ".jar";
getLog().debug( "Adding to surefire test classpath: " + narFile );
surefireBooter.addClassPathUrl( narFile );
}
List dependencies = getNarArtifacts(); // TODO: get seems heavy, not sure if we can push this up to before the fork to use it multiple times.
for ( Iterator i = dependencies.iterator(); i.hasNext(); )
{
NarArtifact dependency = (NarArtifact) i.next();
// FIXME this should be overridable
// NarInfo info = dependency.getNarInfo();
// String binding = info.getBinding(getAOL(), Library.STATIC);
// NOTE: fixed to shared, jni
String[] bindings = { Library.SHARED, Library.JNI };
for ( int j = 0; j < bindings.length; j++ )
{
String binding = bindings[j];
if ( !binding.equals( Library.STATIC ) )
{
File depLibPathEntry =
getLayout().getLibDirectory( getUnpackDirectory(), dependency.getArtifactId(),
dependency.getVersion(), getAOL().toString(), binding );
if ( depLibPathEntry.exists() )
{
getLog().debug( "Adding dependency directory to java.library.path: " + depLibPathEntry );
if ( javaLibraryPath.length() > 0 )
{
javaLibraryPath.append( File.pathSeparator );
}
javaLibraryPath.append( depLibPathEntry );
}
}
}
}
// add final javalibrary path
if ( javaLibraryPath.length() > 0 )
{
// NOTE java.library.path only works for the jni lib itself, and
// not for its dependent shareables.
// NOTE: java.library.path does not work with arguments with
// spaces as
// SureFireBooter splits the line in parts and then quotes
// it wrongly
NarUtil.addLibraryPathToEnv( javaLibraryPath.toString(), environmentVariables, getOS() );
}
// necessary to find WinSxS
if ( getOS().equals( OS.WINDOWS ) )
{
environmentVariables.put( "SystemRoot", NarUtil.getEnv( "SystemRoot", "SystemRoot", "C:\\Windows" ) );
}
// ENDDUNS
fork.setArgLine( argLine );
fork.setEnvironmentVariables( environmentVariables );
if ( getLog().isDebugEnabled() )
{
showMap( environmentVariables, "environment variable" );
fork.setDebug( true );
}
if ( argLine != null )
{
List args = Arrays.asList( argLine.split( " " ) );
if ( args.contains( "-da" ) || args.contains( "-disableassertions" ) )
{
enableAssertions = false;
}
}
}
surefireBooter.setFailIfNoTests( failIfNoTests == null ? false : failIfNoTests.booleanValue() );
surefireBooter.setForkedProcessTimeoutInSeconds( forkedProcessTimeoutInSeconds );
surefireBooter.setRedirectTestOutputToFile( redirectTestOutputToFile );
surefireBooter.setForkConfiguration( fork );
surefireBooter.setChildDelegation( childDelegation );
surefireBooter.setEnableAssertions( enableAssertions );
surefireBooter.setReportsDirectory( reportsDirectory );
addReporters( surefireBooter, fork.isForking() );
return surefireBooter;
}