All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.maven_nar.NarTestMojo Maven / Gradle / Ivy

Go to download

This plugin compiles native code and publishes native artifacts in the form of nar files.

There is a newer version: 3.10.1
Show newest version
/*
 * #%L
 * Native ARchive plugin for Maven
 * %%
 * Copyright (C) 2002 - 2014 NAR Maven Plugin developers.
 * %%
 * Licensed 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.
 * #L%
 */
package com.github.maven_nar;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
import org.codehaus.plexus.util.StringUtils;

/**
 * Tests NAR files. Runs Native Tests and executables if produced.
 *
 * @author Mark Donszelmann
 */
@Mojo(name = "nar-test", defaultPhase = LifecyclePhase.TEST, requiresProject = true,
  requiresDependencyResolution = ResolutionScope.TEST)
public class NarTestMojo extends AbstractCompileMojo {
  /**
   * The classpath elements of the project being tested.
   */
  @Parameter(defaultValue = "${project.testClasspathElements}", required = true, readonly = true)
  private List classpathElements;

  /**
   * Directory for test resources. Defaults to src/test/resources
   */
  @Parameter(defaultValue = "${basedir}/src/test/resources", required = true)
  private File testResourceDirectory;

  private String[] generateEnvironment(Map environmentVariables) throws MojoExecutionException, MojoFailureException {
    List env = new ArrayList<>();

    // Add the default configured environment
    Collections.addAll(env, generateEnvironment());

    // Add manually specified environment variables
    for (Map.Entry envVar : environmentVariables.entrySet()) {
      getLog().debug("Adding environment variable: " + envVar.getKey() + " with value: " + envVar.getValue());
      env.add(envVar.getKey() + "=" + envVar.getValue());
    }

    return env.toArray(new String[env.size()]);
  }

  private String[] generateEnvironment() throws MojoExecutionException, MojoFailureException {
    final List env = new ArrayList();

    final Set/*  */sharedPaths = new HashSet();

    // add all shared libraries of this package
    for (final Object element : getLibraries()) {
      final Library lib = (Library) element;
      if (lib.getType().equals(Library.SHARED)) {
        final 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
    final String classifier = getAOL() + "-shared";
    final List narArtifacts = getNarArtifacts();
    final List dependencies = getNarManager().getAttachedNarDependencies(narArtifacts, classifier);
    for (final Object dependency1 : dependencies) {
      final Artifact dependency = (Artifact) dependency1;
      getLog().debug("Looking for dependency " + dependency);

      // FIXME reported to maven developer list, isSnapshot
      // changes behaviour
      // of getBaseVersion, called in pathOf.
      dependency.isSnapshot();

      final File libDirectory = getLayout()
          .getLibDirectory(getUnpackDirectory(), dependency.getArtifactId(), dependency.getBaseVersion(),
              getAOL().toString(), Library.SHARED);
      sharedPaths.add(libDirectory);
    }

    // set environment
    if (sharedPaths.size() > 0) {
      String sharedPath = "";
      for (final Iterator i = sharedPaths.iterator(); i.hasNext();) {
        sharedPath += ((File) i.next()).getPath();
        if (i.hasNext()) {
          sharedPath += File.pathSeparator;
        }
      }

      final 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(this.classpathElements.iterator(), File.pathSeparator));

    return env.size() > 0 ? (String[]) env.toArray(new String[env.size()]) : new String[]{};
  }

  /**
   * List the dependencies needed for tests executions and for executables
   * executions, those dependencies are used
   * to declare the paths of shared libraries for execution.
   */
  @Override
  protected ScopeFilter getArtifactScopeFilter() {
    return new ScopeFilter( Artifact.SCOPE_TEST, null );
  }

  @Override
  protected File getUnpackDirectory() {
    return getTestUnpackDirectory() == null ? super.getUnpackDirectory() : getTestUnpackDirectory();
  }

  @Override
  public final void narExecute() throws MojoExecutionException, MojoFailureException {
    if (this.skipTests) {
      getLog().info("Tests are skipped");
    } else {

      // run all tests
      for (final Object o : getTests()) {
        runTest((Test) o);
      }

      for (final Object element : getLibraries()) {
        runExecutable((Library) element);
      }
    }
  }

  private void runExecutable(final Library library) throws MojoExecutionException, MojoFailureException {
    if (library.getType().equals(Library.EXECUTABLE) && library.shouldRun()) {
      final MavenProject project = getMavenProject();
      // FIXME NAR-90, we could make sure we get the final name from layout
      final String extension = getOS().equals(OS.WINDOWS) ? ".exe" : "";
      final 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);
      final List args = library.getArgs();
      final 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 void runTest(final Test test) throws MojoExecutionException, MojoFailureException {
    // run if requested
    if (test.shouldRun()) {
      // NOTE should we use layout here ?
      final 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;
      }

      final File workingDir = new File(getTestTargetDirectory(), "test-reports");
      workingDir.mkdirs();

      // Copy test resources
      try {
        int copied = 0;
        if (this.testResourceDirectory.exists()) {
          copied += NarUtil.copyDirectoryStructure(this.testResourceDirectory, workingDir, null,
              NarUtil.DEFAULT_EXCLUDES);
        }
        getLog().info("Copied " + copied + " test resources");
      } catch (final IOException e) {
        throw new MojoExecutionException("NAR: Could not copy test resources", e);
      }

      getLog().info("Running test " + name + " in " + workingDir);

      final List args = test.getArgs();
      final int result = NarUtil.runCommand(path.toString(), (String[]) args.toArray(new String[args.size()]),
          workingDir, generateEnvironment(test.getEnvironmentVariables()), getLog());
      if (result != 0) {
        throw new MojoFailureException("Test " + name + " failed with exit code: " + result + " 0x"
            + Integer.toHexString(result));
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy