package org.programmerplanet.ant.taskdefs.jmeter;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
import org.apache.tools.ant.types.CommandlineJava;
import org.apache.tools.ant.types.FileSet;
/**
* Runs one or more JMeter test plans sequentially.
*
* @author <a href="mailto:jfifield@programmerplanet.org">Joseph Fifield</a>
*/
public class JMeterTask extends Task
{
/**
* The JMeter installation directory.
*/
private File jmeterHome;
/**
* The test plan to execute.
*/
private File testPlan;
/**
* The file to log results to.
*/
private File resultLog;
/**
* A collection of FileSets specifying test plans to execute.
*/
private ArrayList testPlans = new ArrayList();
/**
* The main JMeter jar.
*/
private File jmeterJar;
/**
* Array of arguments to be passed to the JVM that will run JMeter.
*/
private ArrayList jvmArgs = new ArrayList();
/**
* @see org.apache.tools.ant.Task#execute()
*/
public void execute() throws BuildException
{
jmeterJar = new File(jmeterHome.getAbsolutePath() + File.separator + "bin" + File.separator + "ApacheJMeter.jar");
validate();
log("Using JMeter Home: " + jmeterHome.getAbsolutePath(), Project.MSG_VERBOSE);
log("Using JMeter Jar: " + jmeterJar.getAbsolutePath(), Project.MSG_VERBOSE);
// execute the single test plan if specified
if (testPlan != null) {
executeTestPlan(testPlan);
}
// execute each of the test plans specified in each of the "testplans" FileSets
Iterator testPlanIter = testPlans.iterator();
while (testPlanIter.hasNext())
{
FileSet fileSet = (FileSet)testPlanIter.next();
DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject());
File baseDir = scanner.getBasedir();
String[] files = scanner.getIncludedFiles();
for (int i = 0; i < files.length; i++)
{
String testPlanFile = baseDir + File.separator + files[i];
executeTestPlan(new File(testPlanFile));
}
}
}
/**
* Validate the task attributes.
*/
private void validate() throws BuildException
{
if (jmeterHome == null || !jmeterHome.isDirectory()) {
throw new BuildException("You must set jmeterhome to your JMeter install directory.", location);
}
if (!(jmeterJar.exists() && jmeterJar.isFile())) {
throw new BuildException("jmeterhome does not appear to contain a valid JMeter installation.", location);
}
if (resultLog == null) {
throw new BuildException("You must set resultLog.", location);
}
}
/**
* Execute a JMeter test plan.
*/
private void executeTestPlan(File testPlanFile) {
log("Executing test plan: " + testPlanFile, Project.MSG_INFO);
CommandlineJava cmd = new CommandlineJava();
cmd.setJar(jmeterJar.getAbsolutePath());
// Set the JVM args
Iterator jvmArgIterator = jvmArgs.iterator();
while (jvmArgIterator.hasNext()) {
Arg jvmArg = (Arg) jvmArgIterator.next();
cmd.createVmArgument().setValue(jvmArg.getValue());
}
// non-gui mode
cmd.createArgument().setValue("-n");
// the test plan file
cmd.createArgument().setValue("-t");
cmd.createArgument().setValue(testPlanFile.getAbsolutePath());
// the result log file
cmd.createArgument().setValue("-l");
cmd.createArgument().setValue(resultLog.getAbsolutePath());
Execute execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN));
execute.setCommandline(cmd.getCommandline());
execute.setAntRun(getProject());
execute.setWorkingDirectory(new File(jmeterHome.getAbsolutePath() + File.separator + "bin"));
log(cmd.describeCommand(), Project.MSG_VERBOSE);
try {
execute.execute();
}
catch (IOException e) {
throw new BuildException("JMeter execution failed.", e, location);
}
}
public void setJmeterHome(File jmeterHome)
{
this.jmeterHome = jmeterHome;
}
public File getJmeterHome()
{
return jmeterHome;
}
public void setTestPlan(File testPlan)
{
this.testPlan = testPlan;
}
public File getTestPlan()
{
return testPlan;
}
public void setResultLog(File resultLog)
{
this.resultLog = resultLog;
}
public File getResultLog()
{
return resultLog;
}
public void addTestPlans(FileSet set) {
testPlans.add(set);
}
public void addJvmarg(Arg arg) {
jvmArgs.add(arg);
}
}