diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java | 577 |
1 files changed, 0 insertions, 577 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java deleted file mode 100644 index 2eb357a3..00000000 --- a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java +++ /dev/null @@ -1,577 +0,0 @@ -/* - * 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.tools.ant.taskdefs.optional.testing; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.TaskAdapter; -import org.apache.tools.ant.taskdefs.Parallel; -import org.apache.tools.ant.taskdefs.Sequential; -import org.apache.tools.ant.taskdefs.WaitFor; -import org.apache.tools.ant.taskdefs.condition.Condition; -import org.apache.tools.ant.taskdefs.condition.ConditionBase; -import org.apache.tools.ant.util.WorkerAnt; - -/** - * Task to provide functional testing under Ant, with a fairly complex workflow of: - * - * <ul> - * <li>Conditional execution</li> - * <li>Application to start</li> - * <li>A probe to "waitfor" before running tests</li> - * <li>A tests sequence</li> - * <li>A reporting sequence that runs after the tests have finished</li> - * <li>A "teardown" clause that runs after the rest.</li> - * <li>Automated termination of the program it executes, if a timeout is not met</li> - * <li>Checking of a failure property and automatic raising of a fault - * (with the text in failureText) - * if test shutdown and reporting succeeded</li> - * </ul> - * - * The task is designed to be framework neutral; it will work with JUnit, - * TestNG and other test frameworks That can be - * executed from Ant. It bears a resemblance to the FunctionalTest task from - * SmartFrog, as the attribute names were - * chosen to make migration easier. However, this task benefits from the - * ability to tweak Ant's internals, and so - * simplify the workflow, and from the experience of using the SmartFrog task. - * No code has been shared. - * - * @since Ant 1.8 - */ - -public class Funtest extends Task { - - /** - * A condition that must be true before the tests are run. This makes it - * easier to define complex tests that only - * run if certain conditions are met, such as OS or network state. - */ - - private NestedCondition condition; - - - /** - * Used internally to set the workflow up - */ - private Parallel timedTests; - - /** - * Setup runs if the condition is met. Once setup is complete, teardown - * will be run when the task finishes - */ - private Sequential setup; - - /** - * The application to run - */ - private Sequential application; - - /** - * A block that halts the tests until met. - */ - private BlockFor block; - - /** - * Tests to run - */ - private Sequential tests; - - /** - * Reporting only runs if the tests were executed. If the block stopped - * them, reporting is skipped. - */ - private Sequential reporting; - - /** - * Any teardown operations. - */ - private Sequential teardown; - - /** - * time for the tests to time out - */ - private long timeout; - - private long timeoutUnitMultiplier = WaitFor.ONE_MILLISECOND; - - /** - * time for the execution to time out. - */ - private long shutdownTime = 10 * WaitFor.ONE_SECOND; - - private long shutdownUnitMultiplier = WaitFor.ONE_MILLISECOND; - - /** - * Name of a property to look for - */ - private String failureProperty; - - /** - * Message to send when tests failed - */ - private String failureMessage = "Tests failed"; - - /** - * Flag to set to true if you don't care about any shutdown errors. - * <p/> - * In that situation, errors raised during teardown are logged but not - * turned into BuildFault events. Similar to catching and ignoring - * <code>finally {}</code> clauses in Java/ - */ - private boolean failOnTeardownErrors = true; - - - /** - * What was thrown in the test run (including reporting) - */ - private BuildException testException; - /** - * What got thrown during teardown - */ - private BuildException teardownException; - - /** - * Did the application throw an exception - */ - private BuildException applicationException; - - /** - * Did the task throw an exception - */ - private BuildException taskException; - - /** {@value} */ - public static final String WARN_OVERRIDING = "Overriding previous definition of "; - /** {@value} */ - public static final String APPLICATION_FORCIBLY_SHUT_DOWN = "Application forcibly shut down"; - /** {@value} */ - public static final String SHUTDOWN_INTERRUPTED = "Shutdown interrupted"; - /** {@value} */ - public static final String SKIPPING_TESTS - = "Condition failed -skipping tests"; - /** Application exception : {@value} */ - public static final String APPLICATION_EXCEPTION = "Application Exception"; - /** Teardown exception : {@value} */ - public static final String TEARDOWN_EXCEPTION = "Teardown Exception"; - - /** - * Log if the definition is overriding something - * - * @param name what is being defined - * @param definition what should be null if you don't want a warning - */ - private void logOverride(String name, Object definition) { - if (definition != null) { - log(WARN_OVERRIDING + '<' + name + '>', Project.MSG_INFO); - } - } - - /** - * Add a condition element. - * @return <code>ConditionBase</code>. - * @since Ant 1.6.2 - */ - public ConditionBase createCondition() { - logOverride("condition", condition); - condition = new NestedCondition(); - return condition; - } - - /** - * Add an application. - * @param sequence the application to add. - */ - public void addApplication(Sequential sequence) { - logOverride("application", application); - application = sequence; - } - - /** - * Add a setup sequence. - * @param sequence the setup sequence to add. - */ - public void addSetup(Sequential sequence) { - logOverride("setup", setup); - setup = sequence; - } - - /** - * Add a block. - * @param sequence the block for to add. - */ - public void addBlock(BlockFor sequence) { - logOverride("block", block); - block = sequence; - } - - /** - * add tests. - * @param sequence a sequence to add. - */ - public void addTests(Sequential sequence) { - logOverride("tests", tests); - tests = sequence; - } - - /** - * set reporting sequence of tasks. - * @param sequence a reporting sequence to use. - */ - public void addReporting(Sequential sequence) { - logOverride("reporting", reporting); - reporting = sequence; - } - - /** - * set teardown sequence of tasks. - * @param sequence a teardown sequence to use. - */ - public void addTeardown(Sequential sequence) { - logOverride("teardown", teardown); - teardown = sequence; - } - - /** - * Set the failOnTeardownErrors attribute. - * @param failOnTeardownErrors the value to use. - */ - public void setFailOnTeardownErrors(boolean failOnTeardownErrors) { - this.failOnTeardownErrors = failOnTeardownErrors; - } - - /** - * Set the failureMessage attribute. - * @param failureMessage the value to use. - */ - public void setFailureMessage(String failureMessage) { - this.failureMessage = failureMessage; - } - - /** - * Set the failureProperty attribute. - * @param failureProperty the value to use. - */ - public void setFailureProperty(String failureProperty) { - this.failureProperty = failureProperty; - } - - /** - * Set the shutdownTime attribute. - * @param shutdownTime the value to use. - */ - public void setShutdownTime(long shutdownTime) { - this.shutdownTime = shutdownTime; - } - - /** - * Set the timeout attribute. - * @param timeout the value to use. - */ - public void setTimeout(long timeout) { - this.timeout = timeout; - } - - /** - * Set the timeoutunit attribute. - * @param unit the value to use. - */ - public void setTimeoutUnit(WaitFor.Unit unit) { - timeoutUnitMultiplier = unit.getMultiplier(); - } - - /** - * Set the shutdownunit attribute. - * @param unit the value to use. - */ - public void setShutdownUnit(WaitFor.Unit unit) { - shutdownUnitMultiplier = unit.getMultiplier(); - } - - - /** - * Get the application exception. - * @return the application exception. - */ - public BuildException getApplicationException() { - return applicationException; - } - - /** - * Get the teardown exception. - * @return the teardown exception. - */ - public BuildException getTeardownException() { - return teardownException; - } - - /** - * Get the test exception. - * @return the test exception. - */ - public BuildException getTestException() { - return testException; - } - - /** - * Get the task exception. - * @return the task exception. - */ - public BuildException getTaskException() { - return taskException; - } - - /** - * Bind and initialise a task - * @param task task to bind - */ - private void bind(Task task) { - task.bindToOwner(this); - task.init(); - } - - /** - * Create a newly bound parallel instance - * @param parallelTimeout timeout - * @return a bound and initialised parallel instance. - */ - private Parallel newParallel(long parallelTimeout) { - Parallel par = new Parallel(); - bind(par); - par.setFailOnAny(true); - par.setTimeout(parallelTimeout); - return par; - } - - /** - * Create a newly bound parallel instance with one child - * @param parallelTimeout timeout - * @param child task - * @return a bound and initialised parallel instance. - */ - private Parallel newParallel(long parallelTimeout, Task child) { - Parallel par = newParallel(parallelTimeout); - par.addTask(child); - return par; - } - - /** - * Add any task validation needed to ensure internal code quality - * @param task task - * @param role role of the task - */ - private void validateTask(Task task, String role) { - if (task!=null && task.getProject() == null) { - throw new BuildException(role + " task is not bound to the project" + task); - } - } - - /** - * Run the functional test sequence. - * <p> - * This is a fairly complex workflow -what is going on is that we try to clean up - * no matter how the run ended, and to retain the innermost exception that got thrown - * during cleanup. That is, if teardown fails after the tests themselves failed, it is the - * test failing that is more important. - * @throws BuildException if something was caught during the run or teardown. - */ - public void execute() throws BuildException { - - //validation - validateTask(setup, "setup"); - validateTask(application, "application"); - validateTask(tests, "tests"); - validateTask(reporting, "reporting"); - validateTask(teardown, "teardown"); - - //check the condition - //and bail out if it is defined but not true - if (condition != null && !condition.eval()) { - //we are skipping the test - log(SKIPPING_TESTS); - return; - } - - long timeoutMillis = timeout * timeoutUnitMultiplier; - - //set up the application to run in a separate thread - Parallel applicationRun = newParallel(timeoutMillis); - //with a worker which we can use to manage it - WorkerAnt worker = new WorkerAnt(applicationRun, null); - if (application != null) { - applicationRun.addTask(application); - } - - //The test run consists of the block followed by the tests. - long testRunTimeout = 0; - Sequential testRun = new Sequential(); - bind(testRun); - if (block != null) { - //waitfor is not a task, it needs to be adapted - TaskAdapter ta = new TaskAdapter(block); - ta.bindToOwner(this); - validateTask(ta, "block"); - testRun.addTask(ta); - //add the block time to the total test run timeout - testRunTimeout = block.calculateMaxWaitMillis(); - } - - //add the tests and more delay - if (tests != null) { - testRun.addTask(tests); - testRunTimeout += timeoutMillis; - } - //add the reporting and more delay - if (reporting != null) { - testRun.addTask(reporting); - testRunTimeout += timeoutMillis; - } - - //wrap this in a parallel purely to set up timeouts for the - //test run - timedTests = newParallel(testRunTimeout, testRun); - - try { - //run any setup task - if (setup != null) { - Parallel setupRun = newParallel(timeoutMillis, setup); - setupRun.execute(); - } - //start the worker thread and leave it running - worker.start(); - //start the probe+test sequence - timedTests.execute(); - } catch (BuildException e) { - //Record the exception and continue - testException = e; - } finally { - //teardown always runs; its faults are filed away - if (teardown != null) { - try { - Parallel teardownRun = newParallel(timeoutMillis, teardown); - teardownRun.execute(); - } catch (BuildException e) { - teardownException = e; - } - } - } - - //we get here whether or not the tests/teardown have thrown a BuildException. - //do a forced shutdown of the running application, before processing the faults - - try { - //wait for the worker to have finished - long shutdownTimeMillis = shutdownTime * shutdownUnitMultiplier; - worker.waitUntilFinished(shutdownTimeMillis); - if (worker.isAlive()) { - //then, if it is still running, interrupt it a second time. - log(APPLICATION_FORCIBLY_SHUT_DOWN, Project.MSG_WARN); - worker.interrupt(); - worker.waitUntilFinished(shutdownTimeMillis); - } - } catch (InterruptedException e) { - //success, something interrupted the shutdown. There may be a leaked - //worker; - log(SHUTDOWN_INTERRUPTED, e, Project.MSG_VERBOSE); - } - applicationException = worker.getBuildException(); - - //Now faults are analysed - - processExceptions(); - } - - /** - * Now faults are analysed. - * <p> The priority is - * <ol> - * <li>testexceptions, except those indicating a build timeout when the application itself - failed.<br> - (because often it is the application fault that is more interesting than the probe - failure, which is usually triggered by the application not starting - </li><li> - Application exceptions (above test timeout exceptions) - </li><li> - Teardown exceptions -except when they are being ignored - </li><li> - Test failures as indicated by the failure property - </li></ol> - - */ - protected void processExceptions() { - taskException = testException; - - //look for an application fault - if (applicationException != null) { - if (taskException == null || taskException instanceof BuildTimeoutException) { - taskException = applicationException; - } else { - ignoringThrowable(APPLICATION_EXCEPTION, applicationException); - } - } - - //now look for teardown faults, which may be ignored - if (teardownException != null) { - if (taskException == null && failOnTeardownErrors) { - taskException = teardownException; - } else { - //don't let the cleanup exception get in the way of any other failure - ignoringThrowable(TEARDOWN_EXCEPTION, teardownException); - } - } - - //now, analyse the tests - if (failureProperty != null - && getProject().getProperty(failureProperty) != null) { - //we've failed - log(failureMessage); - if (taskException == null) { - taskException = new BuildException(failureMessage); - } - } - - //at this point taskException is null or not. - //if not, throw the exception - if (taskException != null) { - throw taskException; - } - } - - /** - * log that we are ignoring something rather than rethrowing it. - * @param type name of exception - * @param thrown what was thrown - */ - protected void ignoringThrowable(String type, Throwable thrown) { - log(type + ": " + thrown.toString(), - thrown, - Project.MSG_WARN); - } - - private static class NestedCondition extends ConditionBase implements Condition { - public boolean eval() { - if (countConditions() != 1) { - throw new BuildException( - "A single nested condition is required."); - } - return ((Condition) (getConditions().nextElement())).eval(); - } - } -} |