+ * This property is applied on all BatchTest (batchtest) and JUnitTest (test)
+ * however it can possibly be overridden by their own properties.
+ *
+ *
+ * @param value
+ * false if it should not filter, otherwise true
+ *
+ * @since Ant 1.5
+ */
+ public void setFiltertrace(boolean value) {
+ this.filterTrace = value;
+ }
+
+ /**
+ * If true, stop the build process when there is an error in a test. This
+ * property is applied on all BatchTest (batchtest) and JUnitTest (test)
+ * however it can possibly be overridden by their own properties.
+ *
+ * @param value
+ * true if it should halt, otherwise false
+ *
+ * @since Ant 1.2
+ */
+ public void setHaltonerror(boolean value) {
+ this.haltOnError = value;
+ }
+
+ /**
+ * Property to set to "true" if there is a error in a test.
+ *
+ *
+ * This property is applied on all BatchTest (batchtest) and JUnitTest (test),
+ * however, it can possibly be overriden by their own properties.
+ *
+ *
+ * @param propertyName
+ * the name of the property to set in the event of an error.
+ *
+ * @since Ant 1.4
+ */
+ public void setErrorProperty(String propertyName) {
+ this.errorProperty = propertyName;
+ }
+
+ /**
+ * If true, stop the build process if a test fails (errors are considered
+ * failures as well). This property is applied on all BatchTest (batchtest)
+ * and JUnitTest (test) however it can possibly be overridden by their own
+ * properties.
+ *
+ * @param value
+ * true if it should halt, otherwise false
+ *
+ * @since Ant 1.2
+ */
+ public void setHaltonfailure(boolean value) {
+ this.haltOnFail = value;
+ }
+
+ /**
+ * Property to set to "true" if there is a failure in a test.
+ *
+ *
+ * This property is applied on all BatchTest (batchtest) and JUnitTest (test),
+ * however, it can possibly be overriden by their own properties.
+ *
+ *
+ * @param propertyName
+ * the name of the property to set in the event of an failure.
+ *
+ * @since Ant 1.4
+ */
+ public void setFailureProperty(String propertyName) {
+ this.failureProperty = propertyName;
+ }
+
+ /**
+ * If true, JVM should be forked for each test.
+ *
+ *
+ * It avoids interference between testcases and possibly avoids hanging the
+ * build. this property is applied on all BatchTest (batchtest) and JUnitTest
+ * (test) however it can possibly be overridden by their own properties.
+ *
+ *
+ * @param value
+ * true if a JVM should be forked, otherwise
+ * false
+ * @see #setTimeout
+ *
+ * @since Ant 1.2
+ */
+ public void setFork(boolean value) {
+ this.fork = value;
+ }
+
+ /**
+ * If true, print one-line statistics for each test, or "withOutAndErr" to
+ * also show standard output and error.
+ *
+ * Can take the values on, off, and withOutAndErr.
+ *
+ * @param value
+ * true to print a summary, withOutAndErr to
+ * include the test's output as well, false
+ * otherwise.
+ * @see SummaryJUnitResultFormatter
+ *
+ * @since Ant 1.2
+ */
+ public void setPrintsummary(SummaryAttribute value) {
+ summaryValue = value.getValue();
+ summary = value.asBoolean();
+ }
+
+ /**
+ * Print summary enumeration values.
+ */
+ public static class SummaryAttribute extends EnumeratedAttribute {
+ /**
+ * list the possible values
+ *
+ * @return array of allowed values
+ */
+ public String[] getValues() {
+ return new String[] { "true", "yes", "false", "no", "on", "off",
+ "withOutAndErr" };
+ }
+
+ /**
+ * gives the boolean equivalent of the authorized values
+ *
+ * @return boolean equivalent of the value
+ */
+ public boolean asBoolean() {
+ String v = getValue();
+ return "true".equals(v) || "on".equals(v) || "yes".equals(v)
+ || "withOutAndErr".equals(v);
+ }
+ }
+
+ /**
+ * Set the timeout value (in milliseconds).
+ *
+ *
+ * If the test is running for more than this value, the test will be canceled.
+ * (works only when in 'fork' mode).
+ *
+ *
+ * @param value
+ * the maximum time (in milliseconds) allowed before declaring the
+ * test as 'timed-out'
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public void setTimeout(Integer value) {
+ timeout = value;
+ }
+
+ /**
+ * Set the maximum memory to be used by all forked JVMs.
+ *
+ * @param max
+ * the value as defined by -mx or -Xmx in the
+ * java command line options.
+ *
+ * @since Ant 1.2
+ */
+ public void setMaxmemory(String max) {
+ getCommandLine().setMaxmemory(max);
+ }
+
+ /**
+ * The command used to invoke the Java Virtual Machine, default is 'java'. The
+ * command is resolved by java.lang.Runtime.exec(). Ignored if fork is
+ * disabled.
+ *
+ * @param value
+ * the new VM to use instead of java
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public void setJvm(String value) {
+ getCommandLine().setVm(value);
+ }
+
+ /**
+ * Adds a JVM argument; ignored if not forking.
+ *
+ * @return create a new JVM argument so that any argument can be passed to the
+ * JVM.
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public Commandline.Argument createJvmarg() {
+ return getCommandLine().createVmArgument();
+ }
+
+ /**
+ * The directory to invoke the VM in. Ignored if no JVM is forked.
+ *
+ * @param dir
+ * the directory to invoke the JVM from.
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public void setDir(File dir) {
+ this.dir = dir;
+ }
+
+ /**
+ * Adds a system property that tests can access. This might be useful to
+ * tranfer Ant properties to the testcases when JVM forking is not enabled.
+ *
+ * @param sysp
+ * new environment variable to add
+ * @since Ant 1.6
+ */
+ public void addConfiguredSysproperty(Environment.Variable sysp) {
+ // get a build exception if there is a missing key or value
+ // see bugzilla report 21684
+ String testString = sysp.getContent();
+ getProject().log("sysproperty added : " + testString, Project.MSG_DEBUG);
+ getCommandLine().addSysproperty(sysp);
+ }
+
+ /**
+ * Adds a set of properties that will be used as system properties that tests
+ * can access.
+ *
+ * This might be useful to tranfer Ant properties to the testcases when JVM
+ * forking is not enabled.
+ *
+ * @param sysp
+ * set of properties to be added
+ * @since Ant 1.6
+ */
+ public void addSyspropertyset(PropertySet sysp) {
+ getCommandLine().addSyspropertyset(sysp);
+ }
+
+ /**
+ * Adds path to classpath used for tests.
+ *
+ * @return reference to the classpath in the embedded java command line
+ * @since Ant 1.2
+ */
+ public Path createClasspath() {
+ return getCommandLine().createClasspath(getProject()).createPath();
+ }
+
+ /**
+ * Adds an environment variable; used when forking.
+ *
+ *
+ * Will be ignored if we are not forking a new VM.
+ *
+ *
+ * @param var
+ * environment variable to be added
+ * @since Ant 1.5
+ */
+ public void addEnv(Environment.Variable var) {
+ env.addVariable(var);
+ }
+
+ /**
+ * If true, use a new environment when forked.
+ *
+ *
+ * Will be ignored if we are not forking a new VM.
+ *
+ *
+ * @param newenv
+ * boolean indicating if setting a new environment is wished
+ * @since Ant 1.5
+ */
+ public void setNewenvironment(boolean newenv) {
+ newEnvironment = newenv;
+ }
+
+ /**
+ * Preset the attributes of the test before configuration in the build script.
+ * This allows attributes in the task be be defaults for the tests,
+ * but allows individual tests to override the defaults.
+ */
+ private void preConfigure(BaseTest test) {
+ test.setFiltertrace(filterTrace);
+ test.setHaltonerror(haltOnError);
+ if (errorProperty != null) {
+ test.setErrorProperty(errorProperty);
+ }
+ test.setHaltonfailure(haltOnFail);
+ if (failureProperty != null) {
+ test.setFailureProperty(failureProperty);
+ }
+ test.setFork(fork);
+ }
+
+ /**
+ * Add a new single testcase.
+ *
+ * @param test
+ * a new single testcase
+ * @see JUnitTest
+ *
+ * @since Ant 1.2
+ */
+ public void addTest(JUnitTest test) {
+ tests.addElement(test);
+ preConfigure(test);
+ }
+
+ /**
+ * Adds a set of tests based on pattern matching.
+ *
+ * @return a new instance of a batch test.
+ * @see BatchTest
+ *
+ * @since Ant 1.2
+ */
+ public BatchTest createBatchTest() {
+ BatchTest test = new BatchTest(getProject());
+ batchTests.addElement(test);
+ preConfigure(test);
+ return test;
+ }
+
+ /**
+ * Add a new formatter to all tests of this task.
+ *
+ * @param fe
+ * formatter element
+ * @since Ant 1.2
+ */
+ public void addFormatter(FormatterElement fe) {
+ formatters.addElement(fe);
+ }
+
+ /**
+ * If true, include ant.jar, optional.jar and junit.jar in the forked VM.
+ *
+ * @param b
+ * include ant run time yes or no
+ * @since Ant 1.5
+ */
+ public void setIncludeantruntime(boolean b) {
+ includeAntRuntime = b;
+ }
+
+ /**
+ * If true, send any output generated by tests to Ant's logging system as well
+ * as to the formatters. By default only the formatters receive the output.
+ *
+ *
+ * Output will always be passed to the formatters and not by shown by default.
+ * This option should for example be set for tests that are interactive and
+ * prompt the user to do something.
+ *
+ *
+ * @param showOutput
+ * if true, send output to Ant's logging system too
+ * @since Ant 1.5
+ */
+ public void setShowOutput(boolean showOutput) {
+ this.showOutput = showOutput;
+ }
+
+ /**
+ * If true, send any output generated by tests to the formatters.
+ *
+ * @param outputToFormatters
+ * if true, send output to formatters (Default is true).
+ * @since Ant 1.7.0
+ */
+ public void setOutputToFormatters(boolean outputToFormatters) {
+ this.outputToFormatters = outputToFormatters;
+ }
+
+ /**
+ * Assertions to enable in this program (if fork=true)
+ *
+ * @since Ant 1.6
+ * @param asserts
+ * assertion set
+ */
+ public void addAssertions(Assertions asserts) {
+ if (getCommandLine().getAssertions() != null) {
+ throw new BuildException("Only one assertion declaration is allowed");
+ }
+ getCommandLine().setAssertions(asserts);
+ }
+
+ /**
+ * Sets the permissions for the application run inside the same JVM.
+ *
+ * @since Ant 1.6
+ * @return .
+ */
+ public Permissions createPermissions() {
+ if (perm == null) {
+ perm = new Permissions();
+ }
+ return perm;
+ }
+
+ /**
+ * If set, system properties will be copied to the cloned VM - as well as the
+ * bootclasspath unless you have explicitly specified a bootclaspath.
+ *
+ *
+ * Doesn't have any effect unless fork is true.
+ *
+ *
+ * @param cloneVm
+ * a boolean value.
+ * @since Ant 1.7
+ */
+ public void setCloneVm(boolean cloneVm) {
+ getCommandLine().setCloneVm(cloneVm);
+ }
+
+ /**
+ * Creates a new JUnitRunner and enables fork of a new Java VM.
+ *
+ * @throws Exception
+ * under ??? circumstances
+ * @since Ant 1.2
+ */
+ public GridUnitTask() throws Exception {
+ getCommandLine().setClassname(
+ "org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner");
+ }
+
+ /**
+ * Where Ant should place temporary files.
+ *
+ * @param tmpDir
+ * location where temporary files should go to
+ * @since Ant 1.6
+ */
+ public void setTempdir(File tmpDir) {
+ if (tmpDir != null) {
+ if (!tmpDir.exists() || !tmpDir.isDirectory()) {
+ throw new BuildException(tmpDir.toString()
+ + " is not a valid temp directory");
+ }
+ }
+ this.tmpDir = tmpDir;
+ }
+
+ private final class SplitLoader extends AntClassLoader {
+
+ public SplitLoader(ClassLoader parent, Path path) {
+ super(parent, getProject(), path, true);
+ }
+
+ // forceLoadClass is not convenient here since it would not
+ // properly deal with inner classes of these classes.
+ protected synchronized Class loadClass(String classname, boolean resolve)
+ throws ClassNotFoundException {
+ Class theClass = findLoadedClass(classname);
+ if (theClass != null) {
+ return theClass;
+ }
+ if (isSplit(classname)) {
+ theClass = findClass(classname);
+ if (resolve) {
+ resolveClass(theClass);
+ }
+ return theClass;
+ } else {
+ return super.loadClass(classname, resolve);
+ }
+ }
+
+ private final String[] splitClasses = { "BriefJUnitResultFormatter",
+ "JUnitResultFormatter", "JUnitTaskMirrorImpl", "JUnitTestRunner",
+ "JUnitVersionHelper", "OutErrSummaryJUnitResultFormatter",
+ "PlainJUnitResultFormatter", "SummaryJUnitResultFormatter",
+ "XMLJUnitResultFormatter", };
+
+ private boolean isSplit(String classname) {
+ String simplename = classname.substring(classname.lastIndexOf('.') + 1);
+ for (int i = 0; i < splitClasses.length; i++) {
+ if (simplename.equals(splitClasses[i])
+ || simplename.startsWith(splitClasses[i] + '$')) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }
+
+ /**
+ * Sets up the delegate that will actually run the tests.
+ *
+ *
+ * Will be invoked implicitly once the delegate is needed.
+ *
+ *
+ * @since Ant 1.7.1
+ */
+
+ protected void setupJUnitDelegate() {
+ ClassLoader myLoader = GridUnitTask.class.getClassLoader();
+ if (splitJunit) {
+ Path path = new Path(getProject());
+ path.add(antRuntimeClasses);
+ Path extra = getCommandLine().getClasspath();
+ if (extra != null) {
+ path.add(extra);
+ }
+ mirrorLoader = new SplitLoader(myLoader, path);
+ } else {
+ mirrorLoader = myLoader;
+ }
+ // delegate = createMirror(this, mirrorLoader);
+ }
+
+ protected Collection executeOrQueue(Enumeration testList) {
+ Map testConfigurations = new HashMap();
+ while (testList.hasMoreElements()) {
+ JUnitTest test = (JUnitTest) testList.nextElement();
+ if (test.shouldRun(getProject())) {
+ execute(test);
+ }
+ }
+ return testConfigurations.values();
+ }
+
+ /**
+ * Runs the testcase.
+ *
+ * @throws BuildException
+ * in case of test failures or errors
+ * @since Ant 1.2
+ */
+
+ public void execute() throws BuildException {
+ setupJUnitDelegate();
+ List testLists = new ArrayList();
+ testLists.addAll(executeOrQueue(getIndividualTests()));
+ try {
+ Iterator iter = testLists.iterator();
+ while (iter.hasNext()) {
+ List l = (List) iter.next();
+ if (l.size() == 1) {
+ execute((JUnitTest) l.get(0));
+ } else {
+ execute(l);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ pw.close();
+
+ List args = new ArrayList();
+ args.add(0, inputfile);
+ args.add(1, outputfile);
+
+ for (int i = 0; i < args.size(); i++) {
+
+ System.out.println(args.get(i));
+ }
+
+ HadoopUnit hu = new HadoopUnit(dir, dfspath, jarFileName);
+
+ try {
+ String[] arguments = { inputfile, outputfile };
+ hu.run(arguments);
+ } catch (Exception e) { // TODO Auto-generated catch
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Run the tests.
+ *
+ * @param arg
+ * one JunitTest
+ * @throws BuildException
+ * in case of test failures or errors
+ */
+ protected void execute(JUnitTest arg) throws BuildException {
+ JUnitTest test = (JUnitTest) arg.clone();
+ if (test.getTodir() == null) {
+ test.setTodir(getProject().resolveFile("."));
+ }
+
+ if (test.getOutfile() == null) {
+ test.setOutfile("TEST-" + test.getName());
+ }
+ // execute the test and get the return code
+ TestResultHolder result = null;
+ // Destroys a process running for too long
+ ExecuteWatchdog watchdog = createWatchdog();
+ result = executeAsForked(test, watchdog, null);
+ }
+
+ protected void execute(List testList) throws BuildException {
+ JUnitTest test = null;
+ try {
+ Iterator iter = testList.iterator();
+ while (iter.hasNext()) {
+ test = (JUnitTest) iter.next();
+ }
+ // execute the test and get the return code
+ ExecuteWatchdog watchdog = createWatchdog();
+ TestResultHolder result = executeAsForked(test, watchdog, null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Execute a testcase by forking a new JVM. The command will block until it
+ * finishes. To know if the process was destroyed or not or whether the forked
+ * Java VM exited abnormally, use the attributes of the returned holder
+ * object.
+ *
+ * @param test
+ * the testcase to execute.
+ * @param watchdog
+ * the watchdog in charge of cancelling the test if it exceeds a
+ * certain amount of time. Can be null, in this case the
+ * test could probably hang forever.
+ * @param casesFile
+ * list of test cases to execute. Can be null, in this
+ * case only one test is executed.
+ * @return the test results from the JVM itself.
+ * @throws BuildException
+ * in case of error creating a temporary property file, or if the
+ * junit process can not be forked
+ */
+ private TestResultHolder executeAsForked(JUnitTest test,
+ ExecuteWatchdog watchdog, File casesFile) throws BuildException {
+
+ if (perm != null) {
+ log("Permissions ignored when running in forked mode!", Project.MSG_WARN);
+ }
+
+ CommandlineJava cmd;
+ try {
+ cmd = (CommandlineJava) (getCommandLine().clone());
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException("This shouldn't happen", e, getLocation());
+ }
+ cmd
+ .setClassname("org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner");
+ if (casesFile == null) {
+ cmd.createArgument().setValue(test.getName());
+ } else {
+ log("Running multiple tests in the same VM", Project.MSG_VERBOSE);
+ cmd.createArgument().setValue(TESTSFILE + casesFile);
+ }
+
+ cmd.createArgument().setValue(FILTERTRACE + test.getFiltertrace());
+ cmd.createArgument().setValue(HALT_ON_ERROR + test.getHaltonerror());
+ cmd.createArgument().setValue(HALT_ON_FAILURE + test.getHaltonfailure());
+ // checkIncludeAntRuntime(cmd);
+ // checkIncludeJavaPath(cmd);
+
+ checkIncludeSummary(cmd);
+
+ cmd.createArgument().setValue(SHOWOUTPUT + String.valueOf(showOutput));
+ cmd.createArgument().setValue(
+ OUTPUT_TO_FORMATTERS + String.valueOf(outputToFormatters));
+ cmd.createArgument().setValue(LOGTESTLISTENEREVENTS + "true"); // #31885
+
+ File vmWatcher = createTempPropertiesFile("junitvmwatcher");
+ File propsFile = createTempPropertiesFile("junit");
+ Hashtable p = getProject().getProperties();
+ Properties props = new Properties();
+ for (Enumeration e = p.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ props.put(key, p.get(key));
+ }
+ try {
+ FileOutputStream outstream = new FileOutputStream(propsFile);
+ props.store(outstream, "Ant JUnitTask generated properties file");
+ outstream.close();
+ } catch (java.io.IOException e) {
+ propsFile.delete();
+ throw new BuildException(
+ "Error creating temporary properties " + "file.", e, getLocation());
+ }
+ TestResultHolder result = new TestResultHolder();
+
+ cmd.setVm("java");
+
+ log(cmd.describeCommand(), Project.MSG_VERBOSE);
+
+ checkForkedPath(cmd);
+
+ String str = cmd.toString();
+
+ // Number of times the cmd needs to be generated
+ if (numberOfRuns > 1) {
+ for (int i = 0; i < numberOfRuns; i++) {
+ pw.println(str);
+ }
+ } else
+ pw.println(str);
+
+ return result;
+ }
+
+ /**
+ * check for the parameter being "withoutanderr" in a locale-independent way.
+ *
+ * @param summaryOption
+ * the summary option -can be null
+ * @return true if the run should be withoutput and error
+ */
+
+ private boolean equalsWithOutAndErr(String summaryOption) {
+ return summaryOption != null
+ && "withoutanderr".equals(summaryOption.toLowerCase(Locale.ENGLISH));
+ }
+
+ private void checkIncludeSummary(CommandlineJava cmd) {
+ if (summary) {
+ String prefix = "";
+ if (equalsWithOutAndErr(summaryValue)) {
+ prefix = "OutErr";
+ }
+ cmd.createArgument().setValue(
+ FORMATTER + "org.apache.tools.ant.taskdefs.optional.junit." + prefix
+ + "SummaryJUnitResultFormatter");
+ }
+ }
+
+ /**
+ * Check the path for multiple different versions of ant.
+ *
+ * @param cmd
+ * command to execute
+ */
+ private void checkForkedPath(CommandlineJava cmd) {
+ if (forkedPathChecked) {
+ return;
+ }
+ forkedPathChecked = true;
+ AntClassLoader loader = new AntClassLoader(getProject(), cmd
+ .createClasspath(getProject()));
+ String projectResourceName = LoaderUtils.classNameToResource(Project.class
+ .getName());
+ URL previous = null;
+ try {
+ for (Enumeration e = loader.getResources(projectResourceName); e
+ .hasMoreElements();) {
+ URL current = (URL) e.nextElement();
+ if (previous != null && !current.equals(previous)) {
+ log("WARNING: multiple versions of ant detected "
+ + "in path for junit " + LINE_SEP + " " + previous
+ + LINE_SEP + " and " + current, Project.MSG_WARN);
+ return;
+ }
+ previous = current;
+ }
+ } catch (Exception ex) {
+ // Ignore exception
+ }
+ }
+
+ /**
+ * Create a temporary file to pass the properties to a new process. Will
+ * auto-delete on (graceful) exit. The file will be in the project basedir
+ * unless tmpDir declares something else.
+ *
+ * @param prefix
+ * @return created file
+ */
+
+ private File createTempPropertiesFile(String prefix) {
+ /*
+ * File propsFile = FILE_UTILS.createTempFile(prefix, ".properties", tmpDir !=
+ * null ? tmpDir : getProject().getBaseDir(), true, true);
+ */
+
+ File propsFile = FILE_UTILS.createTempFile(prefix, ".properties",
+ tmpDir != null ? tmpDir : getProject().getBaseDir(), true);
+
+ return propsFile;
+ }
+
+ JUnitTaskMirror.JUnitResultFormatterMirror createFormatter()
+ throws BuildException {
+ return createFormatter(null);
+ }
+
+ /**
+ * @since Ant 1.6
+ */
+ JUnitTaskMirror.JUnitResultFormatterMirror createFormatter(ClassLoader loader)
+ throws BuildException {
+
+ if (classname == null) {
+ throw new BuildException("you must specify type or classname");
+ }
+ // although this code appears to duplicate that of
+ // ClasspathUtils.newInstance,
+ // we cannot use that because this formatter may run in a forked
+ // process,
+ // without that class.
+ Class f = null;
+ try {
+ if (loader == null) {
+ f = Class.forName(classname);
+ } else {
+ f = Class.forName(classname, true, loader);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("Using loader " + loader + " on class "
+ + classname + ": " + e, e);
+ } catch (NoClassDefFoundError e) {
+ throw new BuildException("Using loader " + loader + " on class "
+ + classname + ": " + e, e);
+ }
+
+ Object o = null;
+ try {
+ o = f.newInstance();
+ } catch (InstantiationException e) {
+ throw new BuildException(e);
+ } catch (IllegalAccessException e) {
+ throw new BuildException(e);
+ }
+
+ if (!(o instanceof JUnitTaskMirror.JUnitResultFormatterMirror)) {
+ throw new BuildException(classname + " is not a JUnitResultFormatter");
+ }
+ JUnitTaskMirror.JUnitResultFormatterMirror r = (JUnitTaskMirror.JUnitResultFormatterMirror) o;
+ if (useFile && outFile != null) {
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(outFile));
+ } catch (java.io.IOException e) {
+ throw new BuildException("Unable to open file " + outFile, e);
+ }
+ }
+ r.setOutput(out);
+ return r;
+ }
+
+ /**
+ * @return null if there is a timeout value, otherwise the watchdog
+ * instance.
+ *
+ * @throws BuildException
+ * under unspecified circumstances
+ * @since Ant 1.2
+ */
+ protected ExecuteWatchdog createWatchdog() throws BuildException {
+ if (timeout == null) {
+ return null;
+ }
+ return new ExecuteWatchdog((long) timeout.intValue());
+ }
+
+ /**
+ * Merge all individual tests from the batchtest with all individual tests and
+ * return an enumeration over all JUnitTest.
+ *
+ * @return enumeration over individual tests
+ * @since Ant 1.3
+ */
+ protected Enumeration getIndividualTests() {
+ final int count = batchTests.size();
+ final Enumeration[] enums = new Enumeration[count + 1];
+ for (int i = 0; i < count; i++) {
+ BatchTest batchtest = (BatchTest) batchTests.elementAt(i);
+ enums[i] = batchtest.elements();
+ }
+ enums[enums.length - 1] = tests.elements();
+ return Enumerations.fromCompound(enums);
+ }
+
+ /**
+ * return an enumeration listing each test, then each batchtest
+ *
+ * @return enumeration
+ * @since Ant 1.3
+ */
+ protected Enumeration allTests() {
+ Enumeration[] enums = { tests.elements(), batchTests.elements() };
+ return Enumerations.fromCompound(enums);
+ }
+
+ /**
+ * A value class that contains the result of a test.
+ */
+ protected class TestResultHolder {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** the exit code of the test. */
+ public int exitCode = JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS;
+ /** true if the test timed out */
+ public boolean timedOut = false;
+ /** true if the test crashed */
+ public boolean crashed = false;
+ // CheckStyle:VisibilityModifier ON
+ }
+}
Index: src/ant/org/apache/hadoop/ant/HadoopUnit.java
===================================================================
--- src/ant/org/apache/hadoop/ant/HadoopUnit.java (revision 0)
+++ src/ant/org/apache/hadoop/ant/HadoopUnit.java (revision 0)
@@ -0,0 +1,271 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.hadoop.ant;
+
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.mapred.FileInputFormat;
+import org.apache.hadoop.mapred.FileOutputFormat;
+import org.apache.hadoop.mapred.JobClient;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.hadoop.mapred.MapReduceBase;
+import org.apache.hadoop.mapred.Mapper;
+import org.apache.hadoop.mapred.OutputCollector;
+import org.apache.hadoop.mapred.Reducer;
+import org.apache.hadoop.mapred.Reporter;
+import org.apache.hadoop.filecache.DistributedCache;
+import org.apache.hadoop.mapred.*;
+import org.apache.hadoop.mapred.lib.*;
+import org.apache.hadoop.util.*;
+
+public class HadoopUnit extends Configured implements Tool {
+ private static File basedir;
+ private static File dfsPath;
+ private static String jarfile;
+ private static final String TIME_OUT_KEY = "time_out";
+ private static final int TIME_OUT_VAL = 5;
+ private static final String JOB_NAME = "HadoopUnit";
+
+ static List arguments = new ArrayList();
+
+ HadoopUnit() {
+
+ }
+
+ HadoopUnit(File file, File dfspath, String jarfile) {
+ basedir = file;
+ this.dfsPath = dfspath;
+ this.jarfile = jarfile;
+ }
+
+ public static class MapClass extends MapReduceBase implements
+ Mapper {
+
+ private String originalPath = "";
+ private String changedPath = "";
+
+ public void configure(JobConf job) {
+ Path[] pt = null;
+
+ /*
+ try {
+ //pt = DistributedCache.getLocalCacheArchives(job);
+ } catch (IOException e) {
+
+ e.printStackTrace();
+ }
+
+ //changedPath = pt[0].toString();
+ */
+
+ }
+
+ public void map(LongWritable key, Text value,
+ OutputCollector output, Reporter reporter)
+ throws IOException {
+
+ String line = value.toString();
+ String outputStr = "";
+ String testName = "";
+ String[] tname = line.split(" ");
+ for (int i = 0; i < tname.length; i++) {
+ if (tname[i].contains(".Test")) {
+ testName = tname[i];
+ }
+ }
+ //line = line.replaceAll(basedir.toString(), changedPath);
+ try {
+
+ String javaHome = System.getenv("JAVA_HOME");
+ Process p = Runtime.getRuntime().exec(javaHome + "/bin/" + line);
+ InputStreamReader isr = new InputStreamReader(p.getInputStream());
+ BufferedReader br = new BufferedReader(isr);
+ String thisLine;
+ while ((thisLine = br.readLine()) != null) {
+ outputStr += thisLine + "\n";
+ }
+ } catch (IOException e) {
+ System.out.println(e);
+ }
+
+ Pattern pattern = Pattern
+ .compile("Tests run: (\\d+), " +
+ "Failures: (\\d+), Errors: (\\d+), " +
+ "Time elapsed: (\\d+\\.\\d+) sec");
+ Matcher matcher = pattern.matcher(outputStr);
+
+ //matcher.find();
+ Stats statistics = new Stats();
+
+ if (matcher.find()) {
+
+ String testRuns = matcher.group(1);
+ int numRuns = Integer.parseInt(testRuns);
+ String strFailures = matcher.group(2);
+ int numFail = Integer.parseInt(strFailures);
+ String strErrors = matcher.group(3);
+ int errros = Integer.parseInt(strErrors);
+ String strTime = matcher.group(4);
+ double time = Double.parseDouble(strTime);
+
+ statistics = new Stats(numRuns, numFail, errros, time);
+ } else
+ System.out.println("No results");
+
+ output.collect(new Text(testName), statistics);
+
+ }
+ }
+
+ public static class Stats implements Writable {
+ private int _numErrors;
+ private int _numFailures;
+
+ private int _numTestRuns;
+ private double _Time;
+
+ Stats() {
+ };
+
+ Stats(int numTestRuns, int numFailures, int numErrors, double time) {
+
+ _numErrors = numErrors;
+ _numFailures = numFailures;
+ _numTestRuns = numTestRuns;
+ _Time = time;
+
+ }
+
+ public void write(DataOutput out) throws IOException {
+
+ out.writeInt(_numErrors);
+ out.writeInt(_numFailures);
+ out.writeInt(_numTestRuns);
+ out.writeDouble(_Time);
+ }
+
+ public void readFields(DataInput in) throws IOException {
+ _numErrors = in.readInt();
+ _numFailures = in.readInt();
+ _numTestRuns = in.readInt();
+ _Time = in.readInt();
+
+ }
+
+ public static Stats read(DataInput in) throws IOException {
+ Stats s = new Stats();
+ s.readFields(in);
+ return s;
+ }
+
+ public String toString() {
+ String result = "";
+
+ result = result + "\n" + "Test runs: " + _numTestRuns + "\n"
+ + "Number of Failures: " + _numFailures + "\n" + "Errors: "
+ + _numErrors + "\n" + "Time: " + _Time + "\n";
+ return result;
+ }
+ }
+
+ /**
+ * A reducer class that just emits combined output.
+ */
+ public static class Reduce extends MapReduceBase implements
+ Reducer {
+
+ public void reduce(Text key, Iterator values,
+ OutputCollector output, Reporter reporter)
+ throws IOException {
+
+ Stats stat = (Stats) values.next();
+ output.collect(key, stat);
+
+ }
+ }
+
+ static int printUsage() {
+ System.out
+ .println("HadoopUnit [-m ] [-r ] " +
+ "