
com.exadatum.xsuite.xmaven.bash.test.BashUnitMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bash-maven-plugin Show documentation
Show all versions of bash-maven-plugin Show documentation
Bash Maven Plugin is used to generate documentation as well as to run unit test for bash scripts.
package com.exadatum.xsuite.xmaven.bash.test;
/*-
* #%L
* Bash Unit Test Plugin
* %%
* Copyright (C) 2016 - 2017 Exadatum Software Services Pvt. Ltd.
* %%
* 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 java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import com.exadatum.xsuite.xmaven.bash.test.RunListenerDelegate;
/**
* Bash Maven Plugin
*
*/
@Mojo(name = "test")
public class BashUnitMojo extends AbstractMojo {
protected static final String BASH_SCRIPT_TEST_FILE_PREFIX = "test_";
@Component
private MavenProject mavenProject;
@Component
private MavenSession mavenSession;
/**
* Files that has various environment variables declared.
*/
@Parameter
private String envVariableFiles;
/**
* Directory where all bash scripts are stored
*/
@Parameter
private String scriptsSrcDirectory = "src/main/bin";
/**
* Directory where all tests are stored
*/
@Parameter
private String scriptsTestDirectory = "src/test/bin";
/**
* Test shared setup script across all bash tests
*/
@Parameter
private String globalTestSetupScript = "src/test/bin/test-setup.sh";
/**
* Test shared cleanup script across all bash tests
*/
@Parameter
private String globalTestCleanupScript = "src/test/bin/test-cleanup.sh";
/**
* Bash environment variable file extension
*/
@Parameter
private String envFileExtension = ".sh";
/**
* Bash script file extension
*/
@Parameter
private String scriptFileExtension = ".sh";
/**
* Skip execution of all the tests
*/
@Parameter(property = "skipTests", defaultValue = "false")
protected boolean skipTests;
/**
* Skip execution of all the tests
*/
@Parameter(property = "maven.test.skip", defaultValue = "false")
protected boolean mavenSkipTests;
/**
* Directory where test reports are generated
*/
@Parameter
private String reportsDirectory = "target/surefire-reports";
/**
* Flag to check if any of the test cases are failed
*/
private boolean anyTestFailed;
/**
* Comma seperated of JUnit RunListener implementations
*/
@Parameter
private String runListeners = "com.exadatum.sensorium.xmaven.AntXmlRunListener";
/**
* Delegate used to send JUnit RunListener events
*/
private RunListenerDelegate runListenerDelegate;
/**
* The character encoding scheme to be applied when filtering resources.
*/
@Parameter(defaultValue = "${project.build.sourceEncoding}")
private String encoding = "utf-8";;
/**
* The output directory into which to copy the resources if filtering is
* used
*/
@Parameter(defaultValue = "${project.build.directory}")
private File outputDirectory;
/**
* Resources to be copied to the output directory. It is provided to to
* support resource filtering with property substitution.
*/
@Parameter
private List resources = new ArrayList();
@Component(role = MavenResourcesFiltering.class, hint = "default")
protected MavenResourcesFiltering mavenResourcesFiltering;
/**
* Additional properties to be used at the time of resource filtering
*/
@Parameter
private Properties properties;
/**
* Execute.
*
* @throws MojoExecutionException
* the mojo execution exception
* @throws MojoFailureException
* the mojo failure exception
*/
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
try {
if (skipTests || mavenSkipTests) {
return;
}
generateResources();
System.setProperty("reportsDirectory", reportsDirectory);
runListenerDelegate = new RunListenerDelegate(
runListeners.split(","));
Description description = Description
.createSuiteDescription(mavenProject.getArtifactId());
runListenerDelegate.testRunStarted(description);
runBashUnitTests();
runListenerDelegate.testRunFinished(null);
} catch (Exception e) {
throw new MojoExecutionException(
"Failed to execute pig unit tests", e);
}
if (anyTestFailed) {
throw new MojoFailureException("There are test failures");
}
}
private void generateResources() throws MavenFilteringException,
ComponentLookupException {
if (resources.isEmpty()) {
return;
}
MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
// mavenResourcesFiltering.enableLogging(logger);
mavenResourcesExecution.setResources(resources);
mavenResourcesExecution.setMavenProject(mavenProject);
mavenResourcesExecution.setMavenSession(mavenSession);
mavenResourcesExecution.setOutputDirectory(outputDirectory);
mavenResourcesExecution.setEncoding(encoding);
mavenResourcesExecution.setUseDefaultFilterWrappers(true);
mavenResourcesExecution.setFileFilters(new ArrayList());
if (properties != null) {
mavenResourcesExecution.setAdditionalProperties(properties);
}
mavenResourcesFiltering.filterResources(mavenResourcesExecution);
}
/**
* Gets the maven project.
*
* @return the maven project
*/
MavenProject getMavenProject() {
return mavenProject;
}
/**
* Gets the maven session.
*
* @return the maven session
*/
MavenSession getMavenSession() {
return mavenSession;
}
void runBashScriptAllTests(File bashScript, File bashScriptTestsDirectory)
throws Exception {
File[] bashTests = bashScriptTestsDirectory.listFiles(new FileFilter() {
@Override
public boolean accept(File path) {
return path.isFile()
&& path.getName().startsWith(
BASH_SCRIPT_TEST_FILE_PREFIX);
}
});
File scriptsTestOutputFolder = new File(mavenProject.getBuild()
.getDirectory(), "test");
scriptsTestOutputFolder.mkdirs();
File scriptTestOutputFolder = new File(scriptsTestOutputFolder,
bashScript.getName());
if (scriptTestOutputFolder.exists()) {
boolean result = scriptTestOutputFolder.delete();
if (!result) {
throw new IllegalStateException("Failed to delete directory "
+ scriptTestOutputFolder.getAbsolutePath());
}
}
scriptTestOutputFolder.mkdirs();
for (int i = 0; i < bashTests.length; i++) {
File tempMergedScriptTestFile = new File(scriptTestOutputFolder,
bashTests[i].getName());
tempMergedScriptTestFile.setExecutable(true);
BufferedOutputStream outputStream = createAppendableStream(tempMergedScriptTestFile);
globalSetup(outputStream);
runBashScriptSingleTest(bashScript, bashTests[i], outputStream,
tempMergedScriptTestFile);
globalTearDown(outputStream);
outputStream.close();
tempMergedScriptTestFile.setExecutable(true);
executeBashScriptTest(bashScript, tempMergedScriptTestFile);
}
}
private void executeBashScriptTest(File bashScript,
File tempMergedScriptTestFile) throws Exception {
ProcessBuilder builder = new ProcessBuilder().command("/bin/bash",
"-c", tempMergedScriptTestFile.getAbsolutePath())
.redirectErrorStream(true);
Process process = builder.start();
InputStream inputStream = process.getInputStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream));
String line = bufferedReader.readLine();
while (line != null) {
if (line.startsWith("TEST_RESULT=")) {
String[] tokens = line.split("=");
String[] testResultTokens = tokens[1].split("_####_");
Description testDescription = Description
.createTestDescription(bashScript.getName(),
testResultTokens[2]);
runListenerDelegate.testStarted(testDescription);
if (testResultTokens[0].equals("FAILED")) {
anyTestFailed = true;
Failure failure = new Failure(testDescription,
new AssertionError(testResultTokens[1]));
runListenerDelegate.testFailure(failure);
} else if (testResultTokens[0].equals("UNEXPECTED_EXIT")) {
Failure failure = new Failure(testDescription,
new AssertionError("Unexpected exit"));
runListenerDelegate.testFailure(failure);
anyTestFailed = true;
} else if (testResultTokens[0].equals("SUCCESSFUL")) {
// nothing to do.
} else {
throw new IllegalArgumentException("Unknown test result "
+ testResultTokens[0]);
}
runListenerDelegate.testFinished(testDescription);
} else {
System.out.println(line);
}
line = bufferedReader.readLine();
}
}
private static BufferedOutputStream createAppendableStream(File destination)
throws FileNotFoundException {
return new BufferedOutputStream(new FileOutputStream(destination, true));
}
/**
* Test global setup.
*
* @param pigScriptTestsDirectory
* the pig script tests directory
* @param bashTests
* @param bashScript
* @throws Exception
* the exception
*/
private void globalSetup(OutputStream outputStream) throws Exception {
outputStream.write(("\n#START Test Framework\n").getBytes());
InputStream inputStream = BashUnitMojo.class.getClassLoader()
.getResourceAsStream("test-framework.sh");
IOUtils.copy(inputStream, outputStream);
outputStream.write(("\n#END Test Framework\n").getBytes());
outputStream.write(("\n#START Global Environment Setup File\n")
.getBytes());
if (new File(globalTestSetupScript).isFile()) {
IOUtils.copy(new FileInputStream(globalTestSetupScript),
outputStream);
} else {
outputStream.write(("\n#END No Environment Setup File found\n")
.getBytes());
}
outputStream.write(("\n#END Global Environment Setup File\n")
.getBytes());
if (envVariableFiles != null) {
String[] envVariableFilePaths = envVariableFiles.split(",");
outputStream.write(("\n#START Environment Variable Files\n")
.getBytes());
for (int i = 0; i < envVariableFilePaths.length; i++) {
outputStream
.write(("\n#START => " + envVariableFilePaths[i] + "\n")
.getBytes());
IOUtils.copy(new FileInputStream(envVariableFilePaths[i]),
outputStream);
outputStream
.write(("\n#END => " + envVariableFilePaths[i] + "\n")
.getBytes());
}
outputStream.write(("\n#END Environment Variable Files\n")
.getBytes());
}
}
private void globalTearDown(OutputStream outputStream) throws Exception {
outputStream.write(("\n#START Global Environment Cleanup File\n")
.getBytes());
if (new File(globalTestCleanupScript).isFile()) {
IOUtils.copy(new FileInputStream(globalTestCleanupScript),
outputStream);
} else {
outputStream.write(("\n#END No Environment cleanup file found\n")
.getBytes());
}
outputStream.write(("\n#END Global Environment Cleanup File\n")
.getBytes());
}
void runBashScriptSingleTest(File bashScript, File bashScriptTestFie,
BufferedOutputStream outputStream, File tempMergedScriptTestFile)
throws Exception {
outputStream
.write(("\n#START => " + bashScript.getAbsolutePath() + "\n")
.getBytes());
IOUtils.copy(new FileInputStream(bashScript), outputStream);
outputStream.write(("\n#End => " + bashScript.getAbsolutePath() + "\n")
.getBytes());
outputStream.write(("\n#START => "
+ bashScriptTestFie.getAbsolutePath() + "\n").getBytes());
IOUtils.copy(new FileInputStream(bashScriptTestFie), outputStream);
outputStream
.write(("\n#End => " + bashScriptTestFie.getAbsolutePath() + "\n")
.getBytes());
}
/**
* Run pig unit tests.
*
* @throws Exception
* the exception
*/
void runBashUnitTests() throws Exception {
File basedir = mavenProject.getBasedir();
File testResourcesDir = new File(basedir, scriptsTestDirectory);
if (testResourcesDir.exists()) {
File[] scriptTestsDirs = testResourcesDir
.listFiles(new FileFilter() {
@Override
public boolean accept(File path) {
return path.isDirectory()
&& path.getName().endsWith(
scriptFileExtension);
}
});
for (int i = 0; i < scriptTestsDirs.length; i++) {
File script = new File(scriptsSrcDirectory,
scriptTestsDirs[i].getName());
runBashScriptAllTests(script, scriptTestsDirs[i]);
}
}
}
/**
* Sets the maven project.
*
* @param mavenProject
* the new maven project
*/
void setMavenProject(MavenProject mavenProject) {
this.mavenProject = mavenProject;
}
/**
* Sets the maven session.
*
* @param mavenSession
* the new maven session
*/
void setMavenSession(MavenSession mavenSession) {
this.mavenSession = mavenSession;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy