| package org.testng; |
| |
| |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.DirectoryScanner; |
| import org.apache.tools.ant.Project; |
| import org.apache.tools.ant.Target; |
| import org.apache.tools.ant.Task; |
| import org.apache.tools.ant.taskdefs.Execute; |
| import org.apache.tools.ant.taskdefs.ExecuteWatchdog; |
| import org.apache.tools.ant.taskdefs.LogStreamHandler; |
| import org.apache.tools.ant.types.Commandline; |
| import org.apache.tools.ant.types.CommandlineJava; |
| import org.apache.tools.ant.types.Environment; |
| import org.apache.tools.ant.types.FileSet; |
| import org.apache.tools.ant.types.Path; |
| import org.apache.tools.ant.types.PropertySet; |
| import org.apache.tools.ant.types.Reference; |
| import org.apache.tools.ant.types.selectors.FilenameSelector; |
| import org.testng.collections.Lists; |
| import org.testng.internal.Utils; |
| |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.text.CharacterIterator; |
| import java.text.StringCharacterIterator; |
| import java.util.Enumeration; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.StringTokenizer; |
| |
| /** |
| * TestNG settings: |
| * <ul> |
| * <li>classfileset (inner)</li> |
| * <li>classfilesetref (attribute)</li> |
| * <li>xmlfileset (inner)</li> |
| * <li>xmlfilesetref (attribute)</li> |
| * <li>enableAssert (attribute)</li> |
| * <li>excludedGroups (attribute)</li> |
| * <li>groups (attribute)</li> |
| * <li>junit (attribute)</li> |
| * <li>listener (attribute)</li> |
| * <li>outputdir (attribute)</li> |
| * <li>parallel (attribute)</li> |
| * <li>reporter (attribute)</li> |
| * <li>sourcedir (attribute)</li> |
| * <li>sourcedirref (attribute)</li> |
| * <li>suitename (attribute)</li> |
| * <li>suiterunnerclass (attribute)</li> |
| * <li>target (attribute)</li> |
| * <li>testjar (attribute)</li> |
| * <li>testname (attribute)</li> |
| * <li>threadcount (attribute)</li> |
| * <li>dataproviderthreadcount (attribute)</li> |
| * <li>verbose (attribute)</li> |
| * <li>testrunfactory (attribute)</li> |
| * <li>configFailurepolicy (attribute)</li> |
| * |
| * </ul> |
| * |
| * Ant settings: |
| * <ul> |
| * <li>classpath (inner)</li> |
| * <li>classpathref (attribute)</li> |
| * <li>jvm (attribute)</li> |
| * <li>workingDir (attribute)</li> |
| * <li>env (inner)</li> |
| * <li>sysproperty (inner)</li> |
| * <li>propertyset (inner)</li> |
| * <li>jvmarg (inner)</li> |
| * <li>timeout (attribute)</li> |
| * <li>haltonfailure (attribute)</li> |
| * <li>onHaltTarget (attribute)</li> |
| * <li>failureProperty (attribute)</li> |
| * <li>haltonFSP (attribute)</li> |
| * <li>FSPproperty (attribute)</li> |
| * <li>haltonskipped (attribute)</li> |
| * <li>skippedProperty (attribute)</li> |
| * <li>testRunnerFactory (attribute)</li> |
| * </ul> |
| * |
| * Debug information: |
| * <ul> |
| * <li>dumpCommand (boolean)</li> |
| * <li>dumpEnv (boolean)</li> |
| * <li>dumpSys (boolean)</li> |
| * </ul> |
| * |
| * @author <a href="mailto:the_mindstorm@evolva.ro">Alexandru Popescu</a> |
| * @author Cedric Beust |
| */ |
| public class TestNGAntTask extends Task { |
| |
| protected CommandlineJava m_javaCommand; |
| |
| protected List<FileSet> m_xmlFilesets= Lists.newArrayList(); |
| protected List<FileSet> m_classFilesets= Lists.newArrayList(); |
| protected File m_outputDir; |
| protected File m_testjar; |
| protected File m_workingDir; |
| private Integer m_timeout; |
| protected Boolean m_isJUnit; |
| private List<String> m_listeners= Lists.newArrayList(); |
| private String m_objectFactory; |
| protected String m_testRunnerFactory; |
| private boolean m_delegateCommandSystemProperties = false; |
| |
| protected Environment m_environment= new Environment(); |
| |
| /** The suite runner name (defaults to TestNG.class.getName(). */ |
| protected String m_mainClass = TestNG.class.getName(); |
| |
| /** True if the temporary file created by the Ant Task for command line parameters |
| * to TestNG should be preserved after execution. */ |
| protected boolean m_dump; |
| private boolean m_dumpEnv; |
| private boolean m_dumpSys; |
| |
| protected boolean m_assertEnabled= true; |
| protected boolean m_haltOnFailure; |
| protected String m_onHaltTarget; |
| protected String m_failurePropertyName; |
| protected boolean m_haltOnSkipped; |
| protected String m_skippedPropertyName; |
| protected boolean m_haltOnFSP; |
| protected String m_fspPropertyName; |
| protected String m_includedGroups; |
| protected String m_excludedGroups; |
| protected String m_parallelMode; |
| protected String m_threadCount; |
| protected String m_dataproviderthreadCount; |
| protected String m_configFailurePolicy; |
| public String m_useDefaultListeners; |
| private String m_suiteName="Ant suite"; |
| private String m_testName="Ant test"; |
| private Boolean m_skipFailedInvocationCounts; |
| private String m_methods; |
| |
| /** |
| * The list of report listeners added via <reporter> sub-element of the Ant task |
| */ |
| private List<ReporterConfig> reporterConfigs = Lists.newArrayList(); |
| |
| private String m_testNames = ""; |
| |
| public void setParallel(String parallel) { |
| m_parallelMode= parallel; |
| } |
| |
| public void setThreadCount(String threadCount) { |
| m_threadCount= threadCount; |
| } |
| |
| public void setDataProviderThreadCount(String dataproviderthreadCount) { |
| m_dataproviderthreadCount = dataproviderthreadCount; |
| } |
| |
| public void setUseDefaultListeners(String f) { |
| m_useDefaultListeners= f; |
| } |
| |
| // Ant task settings |
| public void setHaltonfailure(boolean value) { |
| m_haltOnFailure= value; |
| } |
| |
| public void setOnHaltTarget(String targetName) { |
| m_onHaltTarget= targetName; |
| } |
| |
| public void setFailureProperty(String propertyName) { |
| m_failurePropertyName= propertyName; |
| } |
| |
| public void setHaltonskipped(boolean value) { |
| m_haltOnSkipped= value; |
| } |
| |
| public void setSkippedProperty(String propertyName) { |
| m_skippedPropertyName= propertyName; |
| } |
| |
| public void setHaltonFSP(boolean value) { |
| m_haltOnFSP= value; |
| } |
| |
| public void setFSPProperty(String propertyName) { |
| m_fspPropertyName= propertyName; |
| } |
| |
| public void setDelegateCommandSystemProperties(boolean value){ |
| m_delegateCommandSystemProperties = value; |
| } |
| |
| /** |
| * Sets the flag to log the command line. When verbose is set to true |
| * the command line parameters are stored in a temporary file stored |
| * in the user's default temporary file directory. The file created is |
| * prefixed with "testng". |
| */ |
| public void setDumpCommand(boolean verbose) { |
| m_dump = verbose; |
| } |
| |
| /** |
| * Sets the flag to write on <code>System.out</code> the Ant |
| * Environment properties. |
| * |
| * @param verbose <tt>true</tt> for printing |
| */ |
| public void setDumpEnv(boolean verbose) { |
| m_dumpEnv= verbose; |
| } |
| |
| /** |
| * Sets te flag to write on <code>System.out</code> the system properties. |
| * @param verbose <tt>true</tt> for dumping the info |
| */ |
| public void setDumpSys(boolean verbose) { |
| m_dumpSys= verbose; |
| } |
| |
| public void setEnableAssert(boolean flag) { |
| m_assertEnabled= flag; |
| } |
| |
| /** |
| * The directory to invoke the VM in. |
| * @param workingDir the directory to invoke the JVM from. |
| */ |
| public void setWorkingDir(File workingDir) { |
| m_workingDir= workingDir; |
| } |
| |
| /** |
| * Sets a particular JVM to be used. Default is 'java' and is solved |
| * by <code>Runtime.exec()</code>. |
| * |
| * @param jvm the new jvm |
| */ |
| public void setJvm(String jvm) { |
| getJavaCommand().setVm(jvm); |
| } |
| |
| /** |
| * Set the timeout value (in milliseconds). |
| * |
| * <p>If the tests are running for more than this value, the tests |
| * will be canceled. |
| * |
| * </p> |
| * @param value the maximum time (in milliseconds) allowed before declaring the test as 'timed-out' |
| */ |
| public void setTimeout(Integer value) { |
| m_timeout= value; |
| } |
| |
| public Commandline.Argument createJvmarg() { |
| return getJavaCommand().createVmArgument(); |
| } |
| |
| public void addSysproperty(Environment.Variable sysp) { |
| getJavaCommand().addSysproperty(sysp); |
| } |
| |
| /** |
| * Adds an environment variable; used when forking. |
| */ |
| public void addEnv(Environment.Variable var) { |
| m_environment.addVariable(var); |
| } |
| |
| /** |
| * Adds path to classpath used for tests. |
| * |
| * @return reference to the classpath in the embedded java command line |
| */ |
| public Path createClasspath() { |
| return getJavaCommand().createClasspath(getProject()).createPath(); |
| } |
| |
| /** |
| * Adds a path to the bootclasspath. |
| * @return reference to the bootclasspath in the embedded java command line |
| */ |
| public Path createBootclasspath() { |
| return getJavaCommand().createBootclasspath(getProject()).createPath(); |
| } |
| |
| /** |
| * Set the classpath to be used when running the Java class |
| * |
| * @param s an Ant Path object containing the classpath. |
| */ |
| public void setClasspath(Path s) { |
| createClasspath().append(s); |
| } |
| |
| /** |
| * Classpath to use, by reference. |
| * |
| * @param r a reference to an existing classpath |
| */ |
| public void setClasspathRef(Reference r) { |
| createClasspath().setRefid(r); |
| } |
| |
| public void addXmlfileset(FileSet fs) { |
| m_xmlFilesets.add(fs); |
| } |
| |
| public void setXmlfilesetRef(Reference ref) { |
| m_xmlFilesets.add(createFileSet(ref)); |
| } |
| |
| public void addClassfileset(FileSet fs) { |
| m_classFilesets.add(appendClassSelector(fs)); |
| } |
| |
| public void setClassfilesetRef(Reference ref) { |
| m_classFilesets.add(createFileSet(ref)); |
| } |
| |
| public void setTestNames(String testNames) { |
| m_testNames = testNames; |
| } |
| |
| /** |
| * Sets the suite runner class to invoke |
| * @param s the name of the suite runner class |
| */ |
| public void setSuiteRunnerClass(String s) { |
| m_mainClass= s; |
| } |
| |
| /** |
| * Sets the suite name |
| * @param s the name of the suite |
| */ |
| public void setSuiteName(String s) { |
| m_suiteName= s; |
| } |
| |
| /** |
| * Sets the test name |
| * @param s the name of the test |
| */ |
| public void setTestName(String s) { |
| m_testName= s; |
| } |
| |
| // TestNG settings |
| public void setJUnit(boolean value) { |
| m_isJUnit= Boolean.valueOf(value); |
| } |
| |
| /** |
| * Sets the test output directory |
| * @param dir the name of directory |
| */ |
| public void setOutputDir(File dir) { |
| m_outputDir= dir; |
| } |
| |
| /** |
| * Sets the test jar |
| * @param s the name of test jar |
| */ |
| public void setTestJar(File s) { |
| m_testjar= s; |
| } |
| |
| public void setGroups(String groups) { |
| m_includedGroups= groups; |
| } |
| |
| public void setExcludedGroups(String groups) { |
| m_excludedGroups= groups; |
| } |
| |
| private Integer m_verbose= null; |
| |
| private Integer m_suiteThreadPoolSize; |
| |
| public void setVerbose(Integer verbose) { |
| m_verbose= verbose; |
| } |
| |
| public void setReporter(String listener) { |
| m_listeners.add(listener); |
| } |
| |
| public void setObjectFactory(String className) { |
| m_objectFactory = className; |
| } |
| |
| public void setTestRunnerFactory(String testRunnerFactory) { |
| m_testRunnerFactory = testRunnerFactory; |
| } |
| |
| public void setSuiteThreadPoolSize(Integer n) { |
| m_suiteThreadPoolSize = n; |
| } |
| |
| /** |
| * @deprecated Use "listeners" |
| */ |
| @Deprecated |
| public void setListener(String listener) { |
| m_listeners.add(listener); |
| } |
| |
| public void setListeners(String listeners) { |
| StringTokenizer st= new StringTokenizer(listeners, " ,"); |
| while(st.hasMoreTokens()) { |
| m_listeners.add(st.nextToken()); |
| } |
| } |
| |
| public void setConfigFailurePolicy(String failurePolicy) { |
| m_configFailurePolicy = failurePolicy; |
| } |
| |
| public void setMethods(String methods) { |
| m_methods = methods; |
| } |
| |
| /** |
| * Launches TestNG in a new JVM. |
| * |
| * {@inheritDoc} |
| */ |
| @Override |
| public void execute() throws BuildException { |
| validateOptions(); |
| |
| CommandlineJava cmd = getJavaCommand(); |
| |
| cmd.setClassname(m_mainClass); |
| |
| List<String> argv= Lists.newArrayList(); |
| |
| if (null != m_isJUnit) { |
| if(m_isJUnit.booleanValue()) { |
| argv.add(CommandLineArgs.JUNIT); |
| } |
| } |
| |
| if (null != m_skipFailedInvocationCounts) { |
| if(m_skipFailedInvocationCounts.booleanValue()) { |
| argv.add(CommandLineArgs.SKIP_FAILED_INVOCATION_COUNTS); |
| } |
| } |
| |
| if (m_delegateCommandSystemProperties) { |
| delegateCommandSystemProperties(); |
| } |
| |
| if(null != m_verbose) { |
| argv.add(CommandLineArgs.LOG); |
| argv.add(m_verbose.toString()); |
| } |
| |
| if(m_assertEnabled) { |
| cmd.createVmArgument().setValue("-ea"); |
| } |
| |
| if(m_useDefaultListeners != null) { |
| String useDefaultListeners = "false"; |
| if ("yes".equalsIgnoreCase(m_useDefaultListeners) |
| || "true".equalsIgnoreCase(m_useDefaultListeners)) |
| { |
| useDefaultListeners = "true"; |
| } |
| argv.add(CommandLineArgs.USE_DEFAULT_LISTENERS); |
| argv.add(useDefaultListeners); |
| } |
| |
| if((null != m_outputDir)) { |
| if(!m_outputDir.exists()) { |
| m_outputDir.mkdirs(); |
| } |
| if(m_outputDir.isDirectory()) { |
| argv.add(CommandLineArgs.OUTPUT_DIRECTORY); |
| argv.add(m_outputDir.getAbsolutePath()); |
| } |
| else { |
| throw new BuildException("Output directory is not a directory: " + m_outputDir); |
| } |
| } |
| |
| if((null != m_testjar) && m_testjar.isFile()) { |
| argv.add(CommandLineArgs.TEST_JAR); |
| argv.add(m_testjar.getAbsolutePath()); |
| } |
| |
| if((null != m_includedGroups) && !"".equals(m_includedGroups)) { |
| argv.add(CommandLineArgs.GROUPS); |
| argv.add(m_includedGroups); |
| } |
| |
| if((null != m_excludedGroups) && !"".equals(m_excludedGroups)) { |
| argv.add(CommandLineArgs.EXCLUDED_GROUPS); |
| argv.add(m_excludedGroups); |
| } |
| |
| if (m_classFilesets.size() > 0) { |
| List<String> files = fileset(m_classFilesets); |
| if (files.size() > 0) { |
| argv.add(CommandLineArgs.TEST_CLASS); |
| StringBuffer testClasses = new StringBuffer(); |
| for (String file : files) { |
| testClasses.append(file); |
| testClasses.append(','); |
| } |
| testClasses.setLength(testClasses.length() - 1); |
| argv.add(testClasses.toString()); |
| } |
| } |
| |
| if(m_listeners != null && m_listeners.size() > 0) { |
| argv.add(CommandLineArgs.LISTENER); |
| StringBuffer listeners= new StringBuffer(); |
| for(int i= 0; i < m_listeners.size(); i++) { |
| listeners.append(m_listeners.get(i)); |
| if(i < m_listeners.size() - 1) listeners.append(';'); |
| } |
| argv.add(listeners.toString()); |
| } |
| |
| if(m_objectFactory != null) { |
| argv.add(CommandLineArgs.OBJECT_FACTORY); |
| argv.add(m_objectFactory); |
| } |
| |
| if (m_testRunnerFactory != null) { |
| argv.add(CommandLineArgs.TEST_RUNNER_FACTORY); |
| argv.add(m_testRunnerFactory); |
| } |
| |
| if(m_parallelMode != null) { |
| argv.add(CommandLineArgs.PARALLEL); |
| argv.add(m_parallelMode); |
| } |
| |
| if (m_configFailurePolicy != null) { |
| argv.add(CommandLineArgs.CONFIG_FAILURE_POLICY); |
| argv.add(m_configFailurePolicy); |
| } |
| |
| if(m_threadCount != null) { |
| argv.add(CommandLineArgs.THREAD_COUNT); |
| argv.add(m_threadCount); |
| } |
| |
| if(m_dataproviderthreadCount != null) { |
| argv.add(CommandLineArgs.DATA_PROVIDER_THREAD_COUNT); |
| argv.add(m_dataproviderthreadCount); |
| } |
| |
| if(!"".equals(m_suiteName)) { |
| argv.add(CommandLineArgs.SUITE_NAME); |
| argv.add(m_suiteName); |
| } |
| |
| if(!"".equals(m_testName)) { |
| argv.add(CommandLineArgs.TEST_NAME); |
| argv.add(m_testName); |
| } |
| |
| if (! Utils.isStringEmpty(m_testNames)) { |
| argv.add(CommandLineArgs.TEST_NAMES); |
| argv.add(m_testNames); |
| } |
| |
| if (! Utils.isStringEmpty(m_methods)) { |
| argv.add("-methods"); |
| argv.add(m_methods); |
| } |
| |
| if (!reporterConfigs.isEmpty()) { |
| for (ReporterConfig reporterConfig : reporterConfigs) { |
| argv.add(CommandLineArgs.REPORTER); |
| argv.add(reporterConfig.serialize()); |
| } |
| } |
| |
| if (m_suiteThreadPoolSize != null) { |
| argv.add(CommandLineArgs.SUITE_THREAD_POOL_SIZE); |
| argv.add(m_suiteThreadPoolSize.toString()); |
| } |
| |
| if(m_xmlFilesets.size() > 0) { |
| for(String file : fileset(m_xmlFilesets)) { |
| argv.add(file); |
| } |
| } |
| |
| String fileName= ""; |
| FileWriter fw= null; |
| BufferedWriter bw= null; |
| try { |
| File f= File.createTempFile("testng", ""); |
| fileName= f.getAbsolutePath(); |
| |
| // If the user asked to see the command, preserve the file |
| if(!m_dump) { |
| f.deleteOnExit(); |
| } |
| fw= new FileWriter(f); |
| bw= new BufferedWriter(fw); |
| for(String arg : argv) { |
| bw.write(arg); |
| bw.newLine(); |
| } |
| bw.flush(); |
| } |
| catch(IOException e) { |
| e.printStackTrace(); |
| } |
| finally { |
| try { |
| if(bw != null) { |
| bw.close(); |
| } |
| if(fw != null) { |
| fw.close(); |
| } |
| } |
| catch(IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| printDebugInfo(fileName); |
| |
| createClasspath().setLocation(findJar()); |
| |
| cmd.createArgument().setValue("@" + fileName); |
| |
| ExecuteWatchdog watchdog= createWatchdog(); |
| boolean wasKilled= false; |
| int exitValue= executeAsForked(cmd, watchdog); |
| if(null != watchdog) { |
| wasKilled= watchdog.killedProcess(); |
| } |
| |
| actOnResult(exitValue, wasKilled); |
| } |
| |
| private void delegateCommandSystemProperties() { |
| // Iterate over command-line args and pass them through as sysproperty |
| // exclude any built-in properties that start with "ant." |
| for (Object propKey : getProject().getUserProperties().keySet()) { |
| String propName = (String) propKey; |
| String propVal = getProject().getUserProperty(propName); |
| if (propName.startsWith("ant.")) { |
| log("Excluding ant property: " + propName + ": " + propVal, Project.MSG_DEBUG); |
| } else { |
| log("Including user property: " + propName + ": " + propVal, Project.MSG_DEBUG); |
| Environment.Variable var = new Environment.Variable(); |
| var.setKey(propName); |
| var.setValue(propVal); |
| addSysproperty(var); |
| } |
| } |
| } |
| |
| private void printDebugInfo(String fileName) { |
| if(m_dumpSys) { |
| System.out.println("* SYSTEM PROPERTIES *"); |
| Properties props= System.getProperties(); |
| Enumeration en= props.propertyNames(); |
| while(en.hasMoreElements()) { |
| String key= (String) en.nextElement(); |
| System.out.println(key + ": " + props.getProperty(key)); |
| } |
| System.out.println(""); |
| } |
| if(m_dumpEnv) { |
| String[] vars= m_environment.getVariables(); |
| if(null != vars && vars.length > 0) { |
| System.out.println("* ENVIRONMENT *"); |
| for(String v: vars) { |
| System.out.println(v); |
| } |
| System.out.println(""); |
| } |
| } |
| if(m_dump) { |
| dumpCommand(fileName); |
| } |
| } |
| |
| private void ppp(String string) { |
| System.out.println("[TestNGAntTask] " + string); |
| } |
| |
| protected void actOnResult(int exitValue, boolean wasKilled) { |
| if(exitValue == -1) { |
| executeHaltTarget(exitValue); |
| throw new BuildException("an error occured when running TestNG tests"); |
| } |
| |
| if((exitValue & TestNG.HAS_NO_TEST) == TestNG.HAS_NO_TEST) { |
| if(m_haltOnFailure) { |
| executeHaltTarget(exitValue); |
| throw new BuildException("No tests were run"); |
| } |
| else { |
| if(null != m_failurePropertyName) { |
| getProject().setNewProperty(m_failurePropertyName, "true"); |
| } |
| |
| log("TestNG haven't found any tests to be run", Project.MSG_DEBUG); |
| } |
| } |
| |
| boolean failed= ((exitValue & TestNG.HAS_FAILURE) == TestNG.HAS_FAILURE) || wasKilled; |
| if(failed) { |
| final String msg= wasKilled ? "The tests timed out and were killed." : "The tests failed."; |
| if(m_haltOnFailure) { |
| executeHaltTarget(exitValue); |
| throw new BuildException(msg); |
| } |
| else { |
| if(null != m_failurePropertyName) { |
| getProject().setNewProperty(m_failurePropertyName, "true"); |
| } |
| |
| log(msg, Project.MSG_INFO); |
| } |
| } |
| |
| if((exitValue & TestNG.HAS_SKIPPED) == TestNG.HAS_SKIPPED) { |
| if(m_haltOnSkipped) { |
| executeHaltTarget(exitValue); |
| throw new BuildException("There are TestNG SKIPPED tests"); |
| } |
| else { |
| if(null != m_skippedPropertyName) { |
| getProject().setNewProperty(m_skippedPropertyName, "true"); |
| } |
| |
| log("There are TestNG SKIPPED tests", Project.MSG_DEBUG); |
| } |
| } |
| |
| if((exitValue & TestNG.HAS_FSP) == TestNG.HAS_FSP) { |
| if(m_haltOnFSP) { |
| executeHaltTarget(exitValue); |
| throw new BuildException("There are TestNG FAILED WITHIN SUCCESS PERCENTAGE tests"); |
| } |
| else { |
| if(null != m_fspPropertyName) { |
| getProject().setNewProperty(m_fspPropertyName, "true"); |
| } |
| |
| log("There are TestNG FAILED WITHIN SUCCESS PERCENTAGE tests", Project.MSG_DEBUG); |
| } |
| } |
| } |
| |
| /** Executes the target, if any, that user designates executing before failing the test */ |
| private void executeHaltTarget(int exitValue) { |
| if(m_onHaltTarget != null) { |
| if(m_outputDir != null) { |
| getProject().setProperty("testng.outputdir", m_outputDir.getAbsolutePath()); |
| } |
| getProject().setProperty("testng.returncode", String.valueOf(exitValue)); |
| Target t= (Target) getProject().getTargets().get(m_onHaltTarget); |
| if(t != null) { |
| t.execute(); |
| } |
| } |
| } |
| |
| /** |
| * Executes the command line as a new process. |
| * |
| * @param cmd the command to execute |
| * @param watchdog |
| * @return the exit status of the subprocess or INVALID. |
| */ |
| protected int executeAsForked(CommandlineJava cmd, ExecuteWatchdog watchdog) { |
| Execute execute= new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), |
| watchdog); |
| execute.setCommandline(cmd.getCommandline()); |
| execute.setAntRun(getProject()); |
| if(m_workingDir != null) { |
| if(m_workingDir.exists() && m_workingDir.isDirectory()) { |
| execute.setWorkingDirectory(m_workingDir); |
| } |
| else { |
| log("Ignoring invalid working directory : " + m_workingDir, Project.MSG_WARN); |
| } |
| } |
| |
| String[] environment= m_environment.getVariables(); |
| if(null != environment) { |
| for(String envEntry : environment) { |
| log("Setting environment variable: " + envEntry, Project.MSG_VERBOSE); |
| } |
| } |
| |
| execute.setEnvironment(environment); |
| |
| log(cmd.describeCommand(), Project.MSG_VERBOSE); |
| int retVal; |
| try { |
| retVal= execute.execute(); |
| } |
| catch(IOException e) { |
| throw new BuildException("Process fork failed.", e, getLocation()); |
| } |
| |
| return retVal; |
| } |
| |
| /** |
| * Creates or returns the already created <CODE>CommandlineJava</CODE>. |
| */ |
| protected CommandlineJava getJavaCommand() { |
| if(null == m_javaCommand) { |
| m_javaCommand = new CommandlineJava(); |
| } |
| |
| return m_javaCommand; |
| } |
| |
| /** |
| * @return <tt>null</tt> if there is no timeout value, otherwise the |
| * watchdog instance. |
| * |
| * @throws BuildException under unspecified circumstances |
| * @since Ant 1.2 |
| */ |
| protected ExecuteWatchdog createWatchdog() /*throws BuildException*/ { |
| if(m_timeout == null) { |
| return null; |
| } |
| |
| return new ExecuteWatchdog(m_timeout.longValue()); |
| } |
| |
| protected void validateOptions() throws BuildException { |
| if (m_xmlFilesets.size() == 0 |
| && m_classFilesets.size() == 0 |
| && Utils.isStringEmpty(m_methods) |
| && ((null == m_testjar) || !m_testjar.isFile())) { |
| throw new BuildException("No suites, classes, methods or jar file was specified."); |
| } |
| |
| if((null != m_includedGroups) && (m_classFilesets.size() == 0 && m_xmlFilesets.size() == 0)) { |
| throw new BuildException("No class filesets or xml file sets specified while using groups"); |
| } |
| |
| if(m_onHaltTarget != null) { |
| if(!getProject().getTargets().containsKey(m_onHaltTarget)) { |
| throw new BuildException("Target " + m_onHaltTarget + " not found in this project"); |
| } |
| } |
| |
| } |
| |
| private FileSet createFileSet(Reference ref) { |
| FileSet fs= new FileSet(); |
| fs.setRefid(ref); |
| fs.setProject(getProject()); |
| |
| return fs; |
| } |
| |
| private FileSet appendClassSelector(FileSet fs) { |
| FilenameSelector selector= new FilenameSelector(); |
| selector.setName("**/*.class"); |
| selector.setProject(getProject()); |
| fs.appendSelector(selector); |
| |
| return fs; |
| } |
| |
| private File findJar() { |
| Class thisClass= getClass(); |
| String resource= thisClass.getName().replace('.', '/') + ".class"; |
| URL url= thisClass.getClassLoader().getResource(resource); |
| |
| if(null != url) { |
| String u= url.toString(); |
| if(u.startsWith("jar:file:")) { |
| int pling= u.indexOf("!"); |
| String jarName= u.substring(4, pling); |
| |
| return new File(fromURI(jarName)); |
| } |
| else if(u.startsWith("file:")) { |
| int tail= u.indexOf(resource); |
| String dirName= u.substring(0, tail); |
| |
| return new File(fromURI(dirName)); |
| } |
| } |
| |
| return null; |
| } |
| |
| private String fromURI(String uri) { |
| URL url= null; |
| try { |
| url= new URL(uri); |
| } |
| catch(MalformedURLException murle) { |
| } |
| if((null == url) || !("file".equals(url.getProtocol()))) { |
| throw new IllegalArgumentException("Can only handle valid file: URIs"); |
| } |
| |
| StringBuffer buf= new StringBuffer(url.getHost()); |
| if(buf.length() > 0) { |
| buf.insert(0, File.separatorChar).insert(0, File.separatorChar); |
| } |
| |
| String file= url.getFile(); |
| int queryPos= file.indexOf('?'); |
| buf.append((queryPos < 0) ? file : file.substring(0, queryPos)); |
| |
| uri= buf.toString().replace('/', File.separatorChar); |
| |
| if((File.pathSeparatorChar == ';') && uri.startsWith("\\") && (uri.length() > 2) |
| && Character.isLetter(uri.charAt(1)) && (uri.lastIndexOf(':') > -1)) { |
| uri= uri.substring(1); |
| } |
| |
| StringBuffer sb= new StringBuffer(); |
| CharacterIterator iter= new StringCharacterIterator(uri); |
| for(char c= iter.first(); c != CharacterIterator.DONE; c= iter.next()) { |
| if(c == '%') { |
| char c1= iter.next(); |
| if(c1 != CharacterIterator.DONE) { |
| int i1= Character.digit(c1, 16); |
| char c2= iter.next(); |
| if(c2 != CharacterIterator.DONE) { |
| int i2= Character.digit(c2, 16); |
| sb.append((char) ((i1 << 4) + i2)); |
| } |
| } |
| } |
| else { |
| sb.append(c); |
| } |
| } |
| |
| return sb.toString(); |
| } |
| |
| /** |
| * Returns the list of files corresponding to the filesets |
| * |
| * @param filesets |
| * @return the list of files corresponding to the filesets |
| * @throws BuildException |
| */ |
| private List<String> fileset(List<FileSet> filesets) throws BuildException { |
| List<String> files= Lists.newArrayList(); |
| |
| for(Iterator<FileSet> iterator= filesets.iterator(); iterator.hasNext();) { |
| FileSet fileset= iterator.next(); |
| DirectoryScanner ds= fileset.getDirectoryScanner(getProject()); |
| |
| for(String file : ds.getIncludedFiles()) { |
| files.add(ds.getBasedir() + File.separator + file); |
| } |
| } |
| |
| return files; |
| } |
| |
| /** |
| * Adds double quotes to the command line argument if it contains spaces. |
| * @param pCommandLineArg the command line argument |
| * @return pCommandLineArg in double quotes if it contains space. |
| * |
| */ |
| private static String doubleQuote(String pCommandLineArg) { |
| if(pCommandLineArg.indexOf(" ") != -1 && !(pCommandLineArg.startsWith("\"") && pCommandLineArg.endsWith("\""))) { |
| return "\"" + pCommandLineArg + '\"'; |
| } |
| |
| return pCommandLineArg; |
| } |
| |
| /** |
| * Creates a string representation of the path. |
| */ |
| private String createPathString(Path path, String sep) { |
| if(path == null) { |
| return null; |
| } |
| |
| final StringBuffer buf= new StringBuffer(); |
| |
| for(int i= 0; i < path.list().length; i++) { |
| File file= getProject().resolveFile(path.list()[i]); |
| |
| if(!file.exists()) { |
| log("Classpath entry not found: " + file, Project.MSG_WARN); |
| } |
| |
| buf.append(file.getAbsolutePath()).append(sep); |
| } |
| |
| if(path.list().length > 0) { // cut the last ; |
| buf.deleteCharAt(buf.length() - 1); |
| } |
| |
| return buf.toString(); |
| } |
| |
| private void dumpCommand(String fileName) { |
| ppp("TESTNG PASSED @" + fileName + " WHICH CONTAINS:"); |
| readAndPrintFile(fileName); |
| } |
| |
| private void readAndPrintFile(String fileName) { |
| File file = new File(fileName); |
| try { |
| BufferedReader br = new BufferedReader(new FileReader(file)); |
| String line = br.readLine(); |
| while (line != null) { |
| System.out.println(" " + line); |
| line = br.readLine(); |
| } |
| } |
| catch(IOException ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| public void addConfiguredReporter(ReporterConfig reporterConfig) { |
| reporterConfigs.add(reporterConfig); |
| } |
| |
| public void setSkipFailedInvocationCounts(boolean skip) { |
| m_skipFailedInvocationCounts = Boolean.valueOf(skip); |
| } |
| |
| /** |
| * Add the referenced property set as system properties for the TestNG JVM. |
| * |
| * @param sysPropertySet A PropertySet of system properties. |
| */ |
| public void addConfiguredPropertySet(PropertySet sysPropertySet) { |
| Properties properties = sysPropertySet.getProperties(); |
| log(properties.keySet().size() + " properties found in nested propertyset", Project.MSG_VERBOSE); |
| for (Object propKeyObj : properties.keySet()) { |
| String propKey = (String) propKeyObj; |
| Environment.Variable sysProp = new Environment.Variable(); |
| sysProp.setKey(propKey); |
| if (properties.get(propKey) instanceof String) { |
| String propVal = (String) properties.get(propKey); |
| sysProp.setValue(propVal); |
| getJavaCommand().addSysproperty(sysProp); |
| log("Added system property " + propKey + " with value " + propVal, Project.MSG_VERBOSE); |
| } else { |
| log("Ignoring non-String property " + propKey, Project.MSG_WARN); |
| } |
| } |
| } |
| } |