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

org.bitbucket.bradleysmithllc.etlunit.maven.ETLUnitMojo Maven / Gradle / Ivy

There is a newer version: 4.6.0-eu
Show newest version
package org.bitbucket.bradleysmithllc.etlunit.maven;

/*
 * #%L
 * etlunit-maven
 * %%
 * Copyright (C) 2010 - 2014 bradleysmithllc
 * %%
 * 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%
 */

import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.bitbucket.bradleysmithllc.etlunit.*;
import org.bitbucket.bradleysmithllc.etlunit.feature.AbstractFeature;
import org.bitbucket.bradleysmithllc.etlunit.feature.ServiceLocatorFeatureLocator;
import org.bitbucket.bradleysmithllc.etlunit.feature.UserDirectedClassDirectorFeature;
import org.bitbucket.bradleysmithllc.etlunit.feature.debug.ConsoleFeatureModule;
import org.bitbucket.bradleysmithllc.etlunit.feature.debug.RunAllFeatureModule;
import org.bitbucket.bradleysmithllc.etlunit.io.FileBuilder;
import org.bitbucket.bradleysmithllc.etlunit.parser.ETLTestParser;
import org.bitbucket.bradleysmithllc.etlunit.parser.ETLTestValueObject;
import org.bitbucket.bradleysmithllc.etlunit.parser.ParseException;
import org.bitbucket.bradleysmithllc.etlunit.util.IOUtils;
import org.bitbucket.bradleysmithllc.etlunit.util.JSonBuilderProxy;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;

/**
 * Goal to run etlunit tests
 *
 * @goal test
 * @phase test
 * @requiresDependencyResolution compile+runtime
 */
public class                                                                                                                                                                          ETLUnitMojo
		extends AbstractMojo {
	/**
	 * @parameter expression="${project}" default-value="${project}"
	 */
	protected MavenProject mavenProject;

	/**
	 * @parameter expression="${project.version}" default-value="${project.version}"
	 */
	protected String projectVersion;

	/**
	 * @parameter expression="${project.name}" default-value="${project.name}"
	 */
	protected String projectName;

	/**
	 * @parameter expression="${etlunit.override.configuration}"
	 */
	protected String etlunitOverrideConfiguration;

	/**
	 * @parameter expression="${maven.test.skip}"
	 */
	protected String skip;

	/**
	 * @parameter expression="${skipTests}"
	 */
	protected String skipTests;

	/**
	 * @parameter expression="${etlunit.skipTests}"
	 */
	protected String etlunitSkipTests;

	/**
	 * @parameter expression="${rootDirectory}" default-value="${basedir}"
	 */
	protected File baseDirectory;

	public void execute()
			throws MojoExecutionException {
		if (skip != null || skipTests != null || etlunitSkipTests != null) {
			// skip testing
			getLog().info("Tests skipped");
			return;
		}

		if (etlunitOverrideConfiguration != null)
		{
			System.setProperty("etlunit.override.configuration", etlunitOverrideConfiguration);
		}
		else
		{
			System.clearProperty("etlunit.override.configuration");
		}

		File src = getEtlunitSourceDirectoryRoot(baseDirectory);

		if (!src.exists()) {
			src.mkdirs();
		}

		try {
			List classpathFiles = mavenProject.getTestClasspathElements();

			URL[] urls = new URL[classpathFiles.size()];

			getLog().debug("" + classpathFiles.size());

			// create a classpath system property that can be used downstream
			StringBuilder builder = new StringBuilder();

			for (int i = 0; i < classpathFiles.size(); ++i) {
				getLog().debug((String) classpathFiles.get(i));
				File path = new File((String) classpathFiles.get(i));
				urls[i] = path.toURL();

				if (builder.length() != 0)
				{
					builder.append(File.pathSeparator);
				}

				builder.append(path.getCanonicalPath());
			}

			System.setProperty("etlunit.maven.plugin.classpath", builder.toString());

			URLClassLoader ucl = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());

			Thread.currentThread().setContextClassLoader(ucl);
			ServiceLocatorFeatureLocator loc = new ServiceLocatorFeatureLocator(ucl);

			Configuration con = loadConfiguration(baseDirectory, projectName, projectVersion, ucl);

			final ETLTestVM vm = new ETLTestVM(loc, con);

			// look for a test specification
			String testSpec = System.getProperty("etlunit-test");

			if (testSpec != null)
			{
				getLog().debug("Using test selector: " + testSpec);
				vm.addFeature(new UserDirectedClassDirectorFeature("maven-test-selector", testSpec));
			}

			// 'activate' the console output
			ConsoleFeatureModule console = new ConsoleFeatureModule();
			vm.addFeature(console);

			// install a dummy feature so a director can be installed which will accept all tests
			vm.addFeature(new RunAllFeatureModule());

			// install a feature to create surefire reports
			vm.addFeature(new AbstractFeature() {
				private final StatusReporter statusReporter = new SurefireStatusReporter(vm.getRuntimeSupport().getReportDirectory("surefire"));

				public String getFeatureName() {
					return "surefire-reporter";
				}

				@Override
				public long getPriorityLevel() {
					return 1L;
				}

				@Override
				public StatusReporter getStatusReporter() {
					return statusReporter;
				}
			});

			vm.installFeatures();

			//TEST!
			TestResults results = vm.runTests();

			// clean the temp directory
			getLog().info("Clearing temporary files . . .");
			FileUtils.deleteQuietly(vm.getRuntimeSupport().getTempRoot());

			TestResultMetrics metrics = results.getMetrics();

			if (metrics.getNumberOfErrors() > 0 || metrics.getNumberOfAssertionFailures() > 0) {
				throw new MojoExecutionException("Build failed with test errors");
			}

			if (metrics.getNumberOfTestsPassed() == 0) {
				throw new MojoExecutionException("Build failed with no tests to run");
			}
		} catch (Exception e) {
			throw new MojoExecutionException("", e);
		}
	}

	/**
	 * These methods from here on are helpers for other modules which are operating in the maven project model
	 * and want to locate standard artifacts without having to spread that information all around the other modules.
	 *
	 * @return
	 */
	public static File getSourceDirectoryRoot(File project_root) {
		return new FileBuilder(project_root).subdir("src").mkdirs().file();
	}

	public static Configuration loadConfiguration(
			File basedir,
			String projectName,
			String projectVersion,
			ClassLoader urlLoader
	) throws IOException {
		File src = new File(basedir, "src");
		File main = new File(src, "main");

		File test = new File(src, "test");

		File testResources = new File(test, "resources");
		File mainResources = new File(main, "resources");

		File testCfg = new File(testResources, "config");
		File mainCfg = new File(mainResources, "config");

		final Configuration con;
		try {
			ETLTestValueObject base =
					ETLTestParser.loadObject(
							new JSonBuilderProxy()
									.object()
									.key("project-root-directory")
									.value(basedir.getAbsolutePath())
									.key("vendor-binary-directory")
									.value(getBinDirectoryRoot(basedir).getAbsolutePath())
									.key("test-sources-directory")
									.value(getEtlunitSourceDirectoryRoot(basedir))
									.key("generated-source-directory")
									.value(getGeneratedSourceDirectoryRoot(basedir))
									.key("temp-directory")
									.value(getTempDirectoryRoot(basedir))
									.key("reports-directory")
									.value(getReportsDirectoryRoot(basedir))
									.key("resource-directory")
									.value(getResourceDirectory(basedir))
									.key("reference-directory")
									.value(getReferenceDirectory(basedir))
									.key("configuration-directory")
									.value(getConfigurationRoot(basedir))
									.key("project-version")
									.value(projectVersion)
									.key("project-name")
									.value(projectName)
									.key("project-user")
									.value(System.getProperty("user.name"))
									.endObject()
									.toString()
			);

			// check for an override in the system properties.  Default is none
			String override = System.getProperty("etlunit.override.configuration");

			// merge together, preferring the override
			con = Configuration.loadFromEnvironment(new File [] {mainCfg, testCfg}, override, urlLoader, base);


			// save off the resulting config file for reference
			File configTarget = new FileBuilder(getGeneratedSourceDirectoryRoot(basedir)).subdir("config").mkdirs().name("effective_configuration.json").file();

			IOUtils.writeBufferToFile(configTarget, new StringBuffer(con.getRoot().getJsonNode().toString()));

			return con;
		} catch (ParseException e) {
			throw new IOException(e);
		}
	}

	protected static File getResourceDirectory(File basedir) {
		return getMainDirectory(basedir);
	}

	public static File getEtlunitSourceDirectoryRoot(File basedir) {
		return new FileBuilder(getTestDirectory(basedir)).subdir("etlunit").mkdirs().file();
	}

	public static File getBuildDirectoryRoot(File project_root) {
		return new FileBuilder(project_root).subdir("target").mkdirs().file();
	}

	public static File getGeneratedSourceDirectoryRoot(File project_root) {
		return new FileBuilder(getBuildDirectoryRoot(project_root)).subdir("generated-sources").mkdirs().file();
	}

	public static File getBinDirectoryRoot(File project_root) {
		return new FileBuilder(project_root).subdir("target").subdir("etlunit-bin").mkdirs().file();
	}

	public static File getReportsDirectoryRoot(File project_root) {
		return new FileBuilder(project_root).subdir("target").mkdirs().file();
	}

	public static File getLibDirectoryRoot(File project_root) {
		return new FileBuilder(project_root).subdir("target").subdir("etlunit-lib").mkdirs().file();
	}

	public static File getTempDirectoryRoot(File project_root) {
		return new FileBuilder(project_root).subdir("target").subdir("etlunit-temp").mkdirs().file();
	}

	public static File getEtlunitConfiguration(File project_root) {
		return new FileBuilder(getConfigurationRoot(project_root)).mkdirs().name("etlunit.json").file();
	}

	public static File getConfigurationRoot(File project_root) {
		return new FileBuilder(getTestDirectory(project_root)).subdir("resources").subdir("config").mkdirs().file();
	}

	public static File getFeatureSource(File project_root, String feature) {
		return new FileBuilder(getSourceDirectoryRoot(project_root)).subdir("main").subdir(feature).mkdirs().file();
	}

	public static File getMainDirectory(File project_root) {
		return new FileBuilder(getSourceDirectoryRoot(project_root)).subdir("main").mkdirs().file();
	}

	public static File getReferenceDirectory(File project_root) {
		return new FileBuilder(getMainDirectory(project_root)).subdir("reference").mkdirs().file();
	}

	public static File getTestDirectory(File project_root) {
		return new FileBuilder(getSourceDirectoryRoot(project_root)).subdir("test").mkdirs().file();
	}

	public static File getFeatureConfiguration(File project_root, String feature) {
		return new FileBuilder(getConfigurationRoot(project_root)).subdir(feature).mkdirs().file();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy