package org.apache.maven.plugin.nar; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.StringUtils; /** * Tests NAR files. Runs Native Tests and executables if produced. * * @goal nar-test * @phase test * @requiresProject * @requiresDependencyResolution test * @author Mark Donszelmann */ public class NarTestMojo extends AbstractCompileMojo { /** * The classpath elements of the project being tested. * * @parameter expression="${project.testClasspathElements}" * @required * @readonly */ private List classpathElements; public final void narExecute() throws MojoExecutionException, MojoFailureException { // run all tests for ( Iterator i = getTests().iterator(); i.hasNext(); ) { runTest( (Test) i.next() ); } for ( Iterator i = getLibraries().iterator(); i.hasNext(); ) { runExecutable( (Library) i.next() ); } } private void runTest( Test test ) throws MojoExecutionException, MojoFailureException { // run if requested if ( test.shouldRun() ) { // NOTE should we use layout here ? String name = test.getName() + (getOS().equals( OS.WINDOWS ) ? ".exe" : ""); File path = new File( getTestTargetDirectory(), "bin" ); path = new File( path, getAOL().toString() ); path = new File( path, name ); if ( !path.exists() ) { getLog().warn( "Skipping non-existing test " + path ); return; } File workingDir = new File( getTestTargetDirectory(), "test-reports" ); workingDir.mkdirs(); getLog().info( "Running test " + name + " in " + workingDir ); List args = test.getArgs(); int result = NarUtil.runCommand( path.toString(), (String[]) args.toArray( new String[args.size()] ), workingDir, generateEnvironment(), getLog() ); if ( result != 0 ) { throw new MojoFailureException( "Test " + name + " failed with exit code: " + result + " 0x" + Integer.toHexString( result ) ); } } } private void runExecutable( Library library ) throws MojoExecutionException, MojoFailureException { if ( library.getType().equals( Library.EXECUTABLE ) && library.shouldRun() ) { MavenProject project = getMavenProject(); // FIXME NAR-90, we could make sure we get the final name from layout String extension = getOS().equals( OS.WINDOWS ) ? ".exe" : ""; File executable = new File( getLayout().getBinDirectory( getTargetDirectory(), getMavenProject().getArtifactId(), getMavenProject().getVersion(), getAOL().toString() ), project.getArtifactId() + extension ); if ( !executable.exists() ) { getLog().warn( "Skipping non-existing executable " + executable ); return; } getLog().info( "Running executable " + executable ); List args = library.getArgs(); int result = NarUtil.runCommand( executable.getPath(), (String[]) args.toArray( new String[args.size()] ), null, generateEnvironment(), getLog() ); if ( result != 0 ) { throw new MojoFailureException( "Test " + executable + " failed with exit code: " + result + " 0x" + Integer.toHexString( result ) ); } } } private String[] generateEnvironment() throws MojoExecutionException, MojoFailureException { List env = new ArrayList(); Set/* <File> */sharedPaths = new HashSet(); // add all shared libraries of this package for ( Iterator i = getLibraries().iterator(); i.hasNext(); ) { Library lib = (Library) i.next(); if ( lib.getType().equals( Library.SHARED ) ) { File path = getLayout().getLibDirectory( getTargetDirectory(), getMavenProject().getArtifactId(), getMavenProject().getVersion(), getAOL().toString(), lib.getType() ); getLog().debug( "Adding path to shared library: " + path ); sharedPaths.add( path ); } } // add dependent shared libraries String classifier = getAOL() + "-shared"; List narArtifacts = getNarManager().getNarDependencies( "test" ); List dependencies = getNarManager().getAttachedNarDependencies( narArtifacts, classifier ); for ( Iterator d = dependencies.iterator(); d.hasNext(); ) { Artifact dependency = (Artifact) d.next(); getLog().debug( "Looking for dependency " + dependency ); // FIXME reported to maven developer list, isSnapshot // changes behaviour // of getBaseVersion, called in pathOf. dependency.isSnapshot(); File libDirectory = getLayout().getLibDirectory( getTestTargetDirectory(), dependency.getArtifactId(), dependency.getVersion(), getAOL().toString(), Library.SHARED ); sharedPaths.add( libDirectory ); } // set environment if ( sharedPaths.size() > 0 ) { String sharedPath = ""; for ( Iterator i = sharedPaths.iterator(); i.hasNext(); ) { sharedPath += ( (File) i.next() ).getPath(); if ( i.hasNext() ) { sharedPath += File.pathSeparator; } } String sharedEnv = NarUtil.addLibraryPathToEnv( sharedPath, null, getOS() ); env.add( sharedEnv ); } // necessary to find WinSxS if ( getOS().equals( OS.WINDOWS ) ) { env.add( "SystemRoot=" + NarUtil.getEnv( "SystemRoot", "SystemRoot", "C:\\Windows" ) ); } // add CLASSPATH env.add( "CLASSPATH=" + StringUtils.join( classpathElements.iterator(), File.pathSeparator ) ); return env.size() > 0 ? (String[]) env.toArray( new String[env.size()] ) : null; } }