You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ek...@apache.org on 2005/08/12 17:23:08 UTC

svn commit: r232310 [45/92] - in /beehive/trunk/controls/test: common/ infra/gtlf/ infra/gtlf/xsl/ infra/mantis/ infra/tch/ infra/tch/messages/ infra/tch/runtime/ infra/tch/schema/ perf/ perf/bin/ perf/cases/ perf/ctlsrc/org/apache/beehive/controls/per...

Modified: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/compose/internal/context/BaseTestContext.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/compose/internal/context/BaseTestContext.java?rev=232310&r1=232309&r2=232310&view=diff
==============================================================================
--- beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/compose/internal/context/BaseTestContext.java (original)
+++ beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/compose/internal/context/BaseTestContext.java Fri Aug 12 08:12:28 2005
@@ -1,618 +1,618 @@
-package org.apache.beehive.test.tools.tch.compose.internal.context;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Vector;
-
-import org.apache.beehive.test.tools.tch.DebugLevels;
-import org.apache.beehive.test.tools.tch.ParameterConstants;
-import org.apache.beehive.test.tools.tch.TestHelper;
-import org.apache.beehive.test.tools.tch.common.util.AggregateKey;
-import org.apache.beehive.test.tools.tch.compose.Parameters;
-import org.apache.beehive.test.tools.tch.compose.TestAbortedException;
-import org.apache.beehive.test.tools.tch.compose.TestContext;
-import org.apache.beehive.test.tools.tch.compose.internal.TestNode;
-import org.apache.beehive.test.tools.tch.core.process.ProcessEngine;
-import org.apache.beehive.test.tools.tch.core.test.ResultHandler;
-import org.apache.beehive.test.tools.tch.util.AssertionError;
-import org.apache.beehive.test.tools.tch.util.TchConstants;
-import org.apache.beehive.test.tools.tch.util.TestResultAdapter;
-import org.apache.beehive.test.tools.tch.util.TestResultBean;
-
-/**
- * Base class for various test contexts. See (presently non-existent)* 
- * architecture documentation for a fuller explanation.
- * <P>
- * NOTE: when adding any new state to this class, consider carefully
- * whether it should be cloned or reset in the clone() method (see
- * clone()) if you don't add anything to clone(), you will get a
- * shallow copy which most likely is wrong. Basically, if the state
- * is associated with a particular test, such as the vector of
- * Helpers, it should be reset in clone whereas other state, such as
- * the list of subtests needs to be deeply cloned.
- *
-*/
-public abstract class BaseTestContext
-  implements ParameterConstants, TestNode, TchConstants
-{
-
-  // ============================================================
-  // Variables
-
-  protected boolean debug = false;
-
-  // =================================================================
-  // Constant state of TestNode -- things that are set when the
-  // TestNode is constructed and which do not change.
-
-  /**
-   * The parameters passed explicitly to this test. The getParam()
-   * methods will walk up the parent chain to find parameters if they
-   * aren't found at a given level. (So parameters are essentially
-   * dynamically scoped whithin the parent-child hierarchy established
-   * at runtime.)
-   */
-  private Parameters mParameters;
-
-  /**
-   * The location of this test (i.e. the names of it's parents) used
-   * in logging. The parent is responsible for setting this correctly
-   * before calling run().
-   */
-  protected String location;
-
-  /**
-   * The object responsible for logging the results. This object is
-   * created by a factory.
-   */
-  private ResultHandler mResultHandler;
-
-  /**
-   * Tch Process Management
-   */
-  private ProcessEngine mProcessEngine = null;
-
-  /**
-   * How many tests we are expecting to run
-   */
-  protected int numTestMethods = 0;
-
-  // let's try to make these private
-
-  /**
-   * The name of this test (instance), used in logging.
-   */
-  protected String name;
-
-  /**
-   * The list of TestHelpers and AggregateKeys (for shared helpers)
-   * which we have dispensed to our test.
-   */
-  transient private Vector allHelpers; //  = new Vector();
-
-  private String realName;
-
-  private String logicalName;
-  private int codeCoverageEnabled = CODECOV_OFF;
-
-  // =================================================================
-  // Static variables
-
-  /**
-   * The shared helper manager shared between all instances of
-   * BaseTestContext.
-   */
-  private static SharedHelperManager sharedHelperMgr =
-    new SharedHelperManager();
-
-  /**
-   * The knob to twiddle to control how much debugging output a given
-   * test emits. Its value is grabbed out of the magic parameter
-   * debugLevel and set to one of the values in org.apache.beehive.test.tools.tch.DebugLevels
-   * (ALL, SOME, FEW and NONE).
-   * This is a magic parameter.
-   */
-  protected static int debugLevel;
-
-  // =================================================================
-  // Constructor
-
-  public BaseTestContext(Parameters inParameters)
-  {
-    mParameters = inParameters;
-  }
-
-  // ============================================================
-  // TestContext implementation
-
-  public final Parameters getParameters()
-  {
-    return mParameters;
-  }
-
-  // ============================================================
-  // TestNode implementation
-
-  private Vector getHelpers()
-  {
-    if (allHelpersCleared)
-    {
-      throw new AssertionError("Trying to getHelpers after clearHelpers have been called");
-    }
-    if (allHelpers == null)
-      allHelpers = new Vector();
-    return allHelpers;
-  }
-  transient boolean allHelpersCleared = false;
-  private void clearHelpers()
-  {
-    allHelpers = null;
-    allHelpersCleared = true;
-  }
-
-  // =================================================================
-  // org.apache.beehive.test.tools.tch.TestNode implementation.
-
-  public abstract void run();
-
-  public String getFullName()
-  {
-    return getName();
-  }
-
-  public final void setLocation(String location)
-  {
-    this.location = location;
-  }
-
-  public final String getLocation()
-  {
-    return location;
-  }
-
-  public final int getDebugLevel()
-  {
-    return debugLevel;
-  }
-
-  public final void setDebugLevel(int inDebugLevel)
-  {
-    debugLevel = inDebugLevel;
-  }
-
-  // Default implementations
-
-  public void logTestsAs(int resultType, String message)
-  {
-  }
-
-  public void logTestsAs(int resultType, String message, Exception th)
-  {
-  }
-
-  public int getNumTests()
-  {
-    return 1;
-  }
-
-  public void notifyTimeout()
-  {
-  }
-
-  public List getTestMethods()
-  {
-    return null;
-  }
-
-  // ============================================================
-  // Old-school TestContext implementation  
-
-  private TestNode currentTest = null;
-
-  public void setCurrentTest(TestNode t)
-  {
-    currentTest = t;
-  }
-  public TestNode getCurrentTest()
-  {
-    return currentTest == null ? this : currentTest.getCurrentTest();
-  }
-
-  private boolean done = false;
-
-  protected final synchronized void setDone()
-  {
-    setDone(false);
-  }
-
-  protected final synchronized void setDone(boolean timedOut)
-  {
-    done = true;
-    if (!timedOut)
-    {
-      //      reportResults(results);
-      cleanupHelpers();
-    }
-    notifyAll(); // The timeout may be waiting on us.
-  }
-
-  // purify name removes all packages from class name
-  // example: 'org.apache.beehive.test.tools.tch.test' becomes 'test'
-  protected String purifyName(String n)
-  {
-    String purified = n;
-    int index = n.lastIndexOf(".");
-    if (index > -1)
-    {
-      purified = n.substring(index + 1);
-    }
-    return purified;
-  }
-
-  public boolean isDone()
-  {
-    return done;
-  }
-
-  // =================================================================
-  // Timeout mechanism.
-
-  /**
-   * Down-call used by the various report* methods to let the context
-   * no that progress is being made. Presently this is only overridden
-   * in AtomicTestContext which uses it to reset the time-out timer.
-   */
-  protected void progressMade()
-  {
-    ;
-  }
-
-  // End timeout mechanism.
-  // =================================================================
-
-  // =================================================================
-  // Random stuff.
-
-  public final void setRealName(String name)
-  {
-    this.realName = name;
-  }
-  public final String getRealName()
-  {
-    return realName;
-  }
-  public final void setName(String name)
-  {
-    this.name = name;
-    // also set 'real name' if it has not been set yet
-    if (this.realName == null)
-    {
-      this.realName = name;
-    }
-  }
-
-  protected void log(TestResultBean inResult)
-  {
-    getResultHandler().submitResult(inResult);
-  }
-
-  public final String getName()
-  {
-    return name;
-  }
-
-  public final ResultHandler getResultHandler()
-  {
-    return mResultHandler;
-  }
-
-  public void setResultHandler(ResultHandler in)
-  {
-    mResultHandler = in;
-  }
-
-  // Make clone public and deep -- some TestNodes such as
-  // ParallelTestNode need to be able to clone their subtests so
-  // they can run multiple copies simultaneously.
-  public Object clone()
-  {
-
-    BaseTestContext btc = null;
-    try
-    {
-      btc = (BaseTestContext)super.clone();
-    }
-    catch (CloneNotSupportedException cnse)
-    {
-      throw new AssertionError(cnse + "");
-    }
-    return btc;
-  }
-
-  // End org.apache.beehive.test.tools.tch.Test implementation.
-  // =================================================================
-
-  // =================================================================
-  // Informational methods.
-
-  public void inform(String msg)
-  {
-    progressMade();
-    TestResultAdapter tr = new TestResultAdapter(INFORM_LEVEL_INT);
-    tr.setOutputMsg(msg);
-    log(tr);
-
-  }
-
-  public final void debugMostVisible(String msg)
-  {
-    debug(DebugLevels.MOST_VISIBLE, msg);
-  }
-
-  public final void debugHalfVisible(String msg)
-  {
-    debug(DebugLevels.HALF_VISIBLE, msg);
-  }
-
-  public final void debugLeastVisible(String msg)
-  {
-    debug(DebugLevels.LEAST_VISIBLE, msg);
-  }
-
-  public void debug(int level, String msg)
-  {
-    progressMade();
-    TestResultAdapter tr = new TestResultAdapter(DEBUG_LEVEL_INT);
-    tr.setDebugLevel(level);
-    tr.setOutputMsg(msg);
-    log(tr);
-  }
-
-  // =================================================================
-
-  // =================================================================
-  // Helpers.
-
-  public final static Class[] NEW_HELPER_TYPES =
-    new Class[] { TestContext.class },
-    NEW_ADMIN_HELPER_TYPES = new Class[] { TestContext.class, String.class };
-
-  /**
-   * Get a TestHelper of a specific type.
-   */
-  public TestHelper getHelper(Class helperClass)
-  {
-    return getHelper(helperClass, false); // not shared
-  }
-  /**
-   * Get a TestHelper of a specific type for connection to adminServer.
-   */
-  public TestHelper getHelperForAdmin(Class helperClass, String host)
-  {
-    return getHelperForAdmin(helperClass, false, host); // not shared
-  }
-
-  /**
-   * Get a helper of a specific type with a specific name. Tests that
-   * request the same name and type of helper will get the same one.
-   * It is constructed with the TestContext of the first test to
-   * request it so will use that test's parameters. Thus tests should
-   * only share a helper if they have the same parameters.
-   */
-  public TestHelper getSharedHelper(String name, Class helperClass)
-  {
-    TestHelper helper =
-      sharedHelperMgr.getSharedHelper(name, helperClass, this);
-    getHelpers().addElement(new AggregateKey(name, helperClass));
-    return helper;
-  }
-
-  /*package*/
-  TestHelper getHelper(Class helperClass, boolean shared)
-  {
-    try
-    {
-      TestHelper h;
-      {
-        Constructor cons;
-        // try to get one with a new-style constructor.  
-        cons = helperClass.getConstructor(NEW_HELPER_TYPES);
-        Object[] helperArgs = new Object[] { this };
-        h = (TestHelper)cons.newInstance(helperArgs);
-      }
-      if (!shared)
-        getHelpers().addElement(h);
-      return h;
-    }
-    catch (IllegalAccessException iae)
-    {
-      iae.printStackTrace();
-      throw new TestAbortedException(iae);
-    }
-    catch (NoSuchMethodException nsme)
-    {
-      nsme.printStackTrace();
-      throw new TestAbortedException(nsme);
-    }
-    catch (InstantiationException ie)
-    {
-      ie.printStackTrace();
-      throw new TestAbortedException(ie);
-    }
-    catch (InvocationTargetException ite)
-    {
-      ite.getTargetException().printStackTrace();
-      throw new TestAbortedException(ite.getTargetException());
-    }
-  }
-
-  /*package*/
-  TestHelper getHelperForAdmin(Class helperClass, boolean shared, String host)
-  {
-    try
-    {
-      TestHelper h;
-      {
-        Constructor cons;
-
-        // try to get one with a new-style constructor.  
-        cons = helperClass.getConstructor(NEW_ADMIN_HELPER_TYPES);
-        Object[] helperArgs = new Object[] { this, host };
-        //inform("Getting " + helperClass.getName() + " helper with " + this);
-        h = (TestHelper)cons.newInstance(helperArgs);
-      }
-      if (!shared)
-        getHelpers().addElement(h);
-      return h;
-    }
-    catch (IllegalAccessException iae)
-    {
-      iae.printStackTrace();
-      throw new TestAbortedException(iae);
-    }
-    catch (NoSuchMethodException nsme)
-    {
-      nsme.printStackTrace();
-      throw new TestAbortedException(nsme);
-    }
-    catch (InstantiationException ie)
-    {
-      ie.printStackTrace();
-      throw new TestAbortedException(ie);
-    }
-    catch (InvocationTargetException ite)
-    {
-      ite.getTargetException().printStackTrace();
-      throw new TestAbortedException(ite.getTargetException());
-    }
-  }
-
-  /**
-   * Cleans up all the helpers dispensed by this TestContext. In the
-   * case of shared helpers, the sharedHelperMgr keeps track of
-   * reference counts and only actually cleans up the helper when all
-   * of the TestContexts that dispensed it have cleaned it up.
-   */
-  private void cleanupHelpers()
-  {
-    Vector helpers = getHelpers();
-    for (int i = 0, len = helpers.size(); i < len; i++)
-    {
-      Object o = helpers.elementAt(i);
-      if (o instanceof TestHelper)
-      {
-        TestHelper h = (TestHelper)o;
-        h.cleanup();
-      }
-      else if (o instanceof AggregateKey)
-      {
-        sharedHelperMgr.cleanup((AggregateKey)o);
-      }
-    }
-    clearHelpers();
-  }
-
-  // =================================================================
-
-  public String toString()
-  {
-    return getFullName() + "<" + objID() + ">";
-  }
-
-  public String objID()
-  {
-    return getClass().getName() + "@" + System.identityHashCode(this);
-  }
-
-  // =================================================================
-  // Helper classes.
-
-  /**
-   * Helper class that manages shared helpers. There's a single
-   * SharedHelperManager stored in the static variable
-   * sharedHelperMgr.
-   */
-  private static class SharedHelperManager
-  {
-
-    private Hashtable helpers = new Hashtable();
-
-    public SharedHelperManager()
-    {
-    }
-
-    public synchronized TestHelper getSharedHelper(
-      String name,
-      Class helperClass,
-      BaseTestContext btc)
-    {
-      synchronized (helpers)
-      {
-        Object key = new AggregateKey(name, helperClass);
-        HelperWrapper helperWrapper = (HelperWrapper)helpers.get(key);
-        if (helperWrapper == null)
-        {
-          TestHelper helper = btc.getHelper(helperClass, true);
-          helperWrapper = new HelperWrapper(helper);
-          helpers.put(key, helperWrapper);
-        }
-        else
-        {
-          helperWrapper.refcount++;
-        }
-        return helperWrapper.helper;
-      }
-    }
-
-    public synchronized void cleanup(AggregateKey key)
-    {
-      HelperWrapper helperWrapper = (HelperWrapper)helpers.get(key);
-
-      helperWrapper.refcount--;
-      if (helperWrapper.refcount == 0)
-      {
-        helperWrapper.helper.cleanup();
-      }
-    }
-
-    private static class HelperWrapper
-    {
-      TestHelper helper;
-      int refcount = 1;
-      HelperWrapper(TestHelper helper)
-      {
-        this.helper = helper;
-      }
-    }
-  }
-
-  public void setProcessEngine(ProcessEngine in)
-  {
-    mProcessEngine = in;
-  }
-
-  public ProcessEngine getProcessEngine()
-  {
-    return mProcessEngine;
-  }
-
-  public void setLogicalName(String name)
-  {
-    this.logicalName = name;
-  }
-  public String getLogicalName()
-  {
-    return logicalName;
-  }
-  // Used so we may pass the code coverage flag in to the test
-  public void setCodeCoverageEnabled(int mode)
-  {
-    codeCoverageEnabled = mode;
-  }
-  public int getCodeCoverageEnabled()
-  {
-    return codeCoverageEnabled;
-  }
-}
+package org.apache.beehive.test.tools.tch.compose.internal.context;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.beehive.test.tools.tch.DebugLevels;
+import org.apache.beehive.test.tools.tch.ParameterConstants;
+import org.apache.beehive.test.tools.tch.TestHelper;
+import org.apache.beehive.test.tools.tch.common.util.AggregateKey;
+import org.apache.beehive.test.tools.tch.compose.Parameters;
+import org.apache.beehive.test.tools.tch.compose.TestAbortedException;
+import org.apache.beehive.test.tools.tch.compose.TestContext;
+import org.apache.beehive.test.tools.tch.compose.internal.TestNode;
+import org.apache.beehive.test.tools.tch.core.process.ProcessEngine;
+import org.apache.beehive.test.tools.tch.core.test.ResultHandler;
+import org.apache.beehive.test.tools.tch.util.AssertionError;
+import org.apache.beehive.test.tools.tch.util.TchConstants;
+import org.apache.beehive.test.tools.tch.util.TestResultAdapter;
+import org.apache.beehive.test.tools.tch.util.TestResultBean;
+
+/**
+ * Base class for various test contexts. See (presently non-existent)* 
+ * architecture documentation for a fuller explanation.
+ * <P>
+ * NOTE: when adding any new state to this class, consider carefully
+ * whether it should be cloned or reset in the clone() method (see
+ * clone()) if you don't add anything to clone(), you will get a
+ * shallow copy which most likely is wrong. Basically, if the state
+ * is associated with a particular test, such as the vector of
+ * Helpers, it should be reset in clone whereas other state, such as
+ * the list of subtests needs to be deeply cloned.
+ *
+*/
+public abstract class BaseTestContext
+  implements ParameterConstants, TestNode, TchConstants
+{
+
+  // ============================================================
+  // Variables
+
+  protected boolean debug = false;
+
+  // =================================================================
+  // Constant state of TestNode -- things that are set when the
+  // TestNode is constructed and which do not change.
+
+  /**
+   * The parameters passed explicitly to this test. The getParam()
+   * methods will walk up the parent chain to find parameters if they
+   * aren't found at a given level. (So parameters are essentially
+   * dynamically scoped whithin the parent-child hierarchy established
+   * at runtime.)
+   */
+  private Parameters mParameters;
+
+  /**
+   * The location of this test (i.e. the names of it's parents) used
+   * in logging. The parent is responsible for setting this correctly
+   * before calling run().
+   */
+  protected String location;
+
+  /**
+   * The object responsible for logging the results. This object is
+   * created by a factory.
+   */
+  private ResultHandler mResultHandler;
+
+  /**
+   * Tch Process Management
+   */
+  private ProcessEngine mProcessEngine = null;
+
+  /**
+   * How many tests we are expecting to run
+   */
+  protected int numTestMethods = 0;
+
+  // let's try to make these private
+
+  /**
+   * The name of this test (instance), used in logging.
+   */
+  protected String name;
+
+  /**
+   * The list of TestHelpers and AggregateKeys (for shared helpers)
+   * which we have dispensed to our test.
+   */
+  transient private Vector allHelpers; //  = new Vector();
+
+  private String realName;
+
+  private String logicalName;
+  private int codeCoverageEnabled = CODECOV_OFF;
+
+  // =================================================================
+  // Static variables
+
+  /**
+   * The shared helper manager shared between all instances of
+   * BaseTestContext.
+   */
+  private static SharedHelperManager sharedHelperMgr =
+    new SharedHelperManager();
+
+  /**
+   * The knob to twiddle to control how much debugging output a given
+   * test emits. Its value is grabbed out of the magic parameter
+   * debugLevel and set to one of the values in org.apache.beehive.test.tools.tch.DebugLevels
+   * (ALL, SOME, FEW and NONE).
+   * This is a magic parameter.
+   */
+  protected static int debugLevel;
+
+  // =================================================================
+  // Constructor
+
+  public BaseTestContext(Parameters inParameters)
+  {
+    mParameters = inParameters;
+  }
+
+  // ============================================================
+  // TestContext implementation
+
+  public final Parameters getParameters()
+  {
+    return mParameters;
+  }
+
+  // ============================================================
+  // TestNode implementation
+
+  private Vector getHelpers()
+  {
+    if (allHelpersCleared)
+    {
+      throw new AssertionError("Trying to getHelpers after clearHelpers have been called");
+    }
+    if (allHelpers == null)
+      allHelpers = new Vector();
+    return allHelpers;
+  }
+  transient boolean allHelpersCleared = false;
+  private void clearHelpers()
+  {
+    allHelpers = null;
+    allHelpersCleared = true;
+  }
+
+  // =================================================================
+  // org.apache.beehive.test.tools.tch.TestNode implementation.
+
+  public abstract void run();
+
+  public String getFullName()
+  {
+    return getName();
+  }
+
+  public final void setLocation(String location)
+  {
+    this.location = location;
+  }
+
+  public final String getLocation()
+  {
+    return location;
+  }
+
+  public final int getDebugLevel()
+  {
+    return debugLevel;
+  }
+
+  public final void setDebugLevel(int inDebugLevel)
+  {
+    debugLevel = inDebugLevel;
+  }
+
+  // Default implementations
+
+  public void logTestsAs(int resultType, String message)
+  {
+  }
+
+  public void logTestsAs(int resultType, String message, Exception th)
+  {
+  }
+
+  public int getNumTests()
+  {
+    return 1;
+  }
+
+  public void notifyTimeout()
+  {
+  }
+
+  public List getTestMethods()
+  {
+    return null;
+  }
+
+  // ============================================================
+  // Old-school TestContext implementation  
+
+  private TestNode currentTest = null;
+
+  public void setCurrentTest(TestNode t)
+  {
+    currentTest = t;
+  }
+  public TestNode getCurrentTest()
+  {
+    return currentTest == null ? this : currentTest.getCurrentTest();
+  }
+
+  private boolean done = false;
+
+  protected final synchronized void setDone()
+  {
+    setDone(false);
+  }
+
+  protected final synchronized void setDone(boolean timedOut)
+  {
+    done = true;
+    if (!timedOut)
+    {
+      //      reportResults(results);
+      cleanupHelpers();
+    }
+    notifyAll(); // The timeout may be waiting on us.
+  }
+
+  // purify name removes all packages from class name
+  // example: 'org.apache.beehive.test.tools.tch.test' becomes 'test'
+  protected String purifyName(String n)
+  {
+    String purified = n;
+    int index = n.lastIndexOf(".");
+    if (index > -1)
+    {
+      purified = n.substring(index + 1);
+    }
+    return purified;
+  }
+
+  public boolean isDone()
+  {
+    return done;
+  }
+
+  // =================================================================
+  // Timeout mechanism.
+
+  /**
+   * Down-call used by the various report* methods to let the context
+   * no that progress is being made. Presently this is only overridden
+   * in AtomicTestContext which uses it to reset the time-out timer.
+   */
+  protected void progressMade()
+  {
+    ;
+  }
+
+  // End timeout mechanism.
+  // =================================================================
+
+  // =================================================================
+  // Random stuff.
+
+  public final void setRealName(String name)
+  {
+    this.realName = name;
+  }
+  public final String getRealName()
+  {
+    return realName;
+  }
+  public final void setName(String name)
+  {
+    this.name = name;
+    // also set 'real name' if it has not been set yet
+    if (this.realName == null)
+    {
+      this.realName = name;
+    }
+  }
+
+  protected void log(TestResultBean inResult)
+  {
+    getResultHandler().submitResult(inResult);
+  }
+
+  public final String getName()
+  {
+    return name;
+  }
+
+  public final ResultHandler getResultHandler()
+  {
+    return mResultHandler;
+  }
+
+  public void setResultHandler(ResultHandler in)
+  {
+    mResultHandler = in;
+  }
+
+  // Make clone public and deep -- some TestNodes such as
+  // ParallelTestNode need to be able to clone their subtests so
+  // they can run multiple copies simultaneously.
+  public Object clone()
+  {
+
+    BaseTestContext btc = null;
+    try
+    {
+      btc = (BaseTestContext)super.clone();
+    }
+    catch (CloneNotSupportedException cnse)
+    {
+      throw new AssertionError(cnse + "");
+    }
+    return btc;
+  }
+
+  // End org.apache.beehive.test.tools.tch.Test implementation.
+  // =================================================================
+
+  // =================================================================
+  // Informational methods.
+
+  public void inform(String msg)
+  {
+    progressMade();
+    TestResultAdapter tr = new TestResultAdapter(INFORM_LEVEL_INT);
+    tr.setOutputMsg(msg);
+    log(tr);
+
+  }
+
+  public final void debugMostVisible(String msg)
+  {
+    debug(DebugLevels.MOST_VISIBLE, msg);
+  }
+
+  public final void debugHalfVisible(String msg)
+  {
+    debug(DebugLevels.HALF_VISIBLE, msg);
+  }
+
+  public final void debugLeastVisible(String msg)
+  {
+    debug(DebugLevels.LEAST_VISIBLE, msg);
+  }
+
+  public void debug(int level, String msg)
+  {
+    progressMade();
+    TestResultAdapter tr = new TestResultAdapter(DEBUG_LEVEL_INT);
+    tr.setDebugLevel(level);
+    tr.setOutputMsg(msg);
+    log(tr);
+  }
+
+  // =================================================================
+
+  // =================================================================
+  // Helpers.
+
+  public final static Class[] NEW_HELPER_TYPES =
+    new Class[] { TestContext.class },
+    NEW_ADMIN_HELPER_TYPES = new Class[] { TestContext.class, String.class };
+
+  /**
+   * Get a TestHelper of a specific type.
+   */
+  public TestHelper getHelper(Class helperClass)
+  {
+    return getHelper(helperClass, false); // not shared
+  }
+  /**
+   * Get a TestHelper of a specific type for connection to adminServer.
+   */
+  public TestHelper getHelperForAdmin(Class helperClass, String host)
+  {
+    return getHelperForAdmin(helperClass, false, host); // not shared
+  }
+
+  /**
+   * Get a helper of a specific type with a specific name. Tests that
+   * request the same name and type of helper will get the same one.
+   * It is constructed with the TestContext of the first test to
+   * request it so will use that test's parameters. Thus tests should
+   * only share a helper if they have the same parameters.
+   */
+  public TestHelper getSharedHelper(String name, Class helperClass)
+  {
+    TestHelper helper =
+      sharedHelperMgr.getSharedHelper(name, helperClass, this);
+    getHelpers().addElement(new AggregateKey(name, helperClass));
+    return helper;
+  }
+
+  /*package*/
+  TestHelper getHelper(Class helperClass, boolean shared)
+  {
+    try
+    {
+      TestHelper h;
+      {
+        Constructor cons;
+        // try to get one with a new-style constructor.  
+        cons = helperClass.getConstructor(NEW_HELPER_TYPES);
+        Object[] helperArgs = new Object[] { this };
+        h = (TestHelper)cons.newInstance(helperArgs);
+      }
+      if (!shared)
+        getHelpers().addElement(h);
+      return h;
+    }
+    catch (IllegalAccessException iae)
+    {
+      iae.printStackTrace();
+      throw new TestAbortedException(iae);
+    }
+    catch (NoSuchMethodException nsme)
+    {
+      nsme.printStackTrace();
+      throw new TestAbortedException(nsme);
+    }
+    catch (InstantiationException ie)
+    {
+      ie.printStackTrace();
+      throw new TestAbortedException(ie);
+    }
+    catch (InvocationTargetException ite)
+    {
+      ite.getTargetException().printStackTrace();
+      throw new TestAbortedException(ite.getTargetException());
+    }
+  }
+
+  /*package*/
+  TestHelper getHelperForAdmin(Class helperClass, boolean shared, String host)
+  {
+    try
+    {
+      TestHelper h;
+      {
+        Constructor cons;
+
+        // try to get one with a new-style constructor.  
+        cons = helperClass.getConstructor(NEW_ADMIN_HELPER_TYPES);
+        Object[] helperArgs = new Object[] { this, host };
+        //inform("Getting " + helperClass.getName() + " helper with " + this);
+        h = (TestHelper)cons.newInstance(helperArgs);
+      }
+      if (!shared)
+        getHelpers().addElement(h);
+      return h;
+    }
+    catch (IllegalAccessException iae)
+    {
+      iae.printStackTrace();
+      throw new TestAbortedException(iae);
+    }
+    catch (NoSuchMethodException nsme)
+    {
+      nsme.printStackTrace();
+      throw new TestAbortedException(nsme);
+    }
+    catch (InstantiationException ie)
+    {
+      ie.printStackTrace();
+      throw new TestAbortedException(ie);
+    }
+    catch (InvocationTargetException ite)
+    {
+      ite.getTargetException().printStackTrace();
+      throw new TestAbortedException(ite.getTargetException());
+    }
+  }
+
+  /**
+   * Cleans up all the helpers dispensed by this TestContext. In the
+   * case of shared helpers, the sharedHelperMgr keeps track of
+   * reference counts and only actually cleans up the helper when all
+   * of the TestContexts that dispensed it have cleaned it up.
+   */
+  private void cleanupHelpers()
+  {
+    Vector helpers = getHelpers();
+    for (int i = 0, len = helpers.size(); i < len; i++)
+    {
+      Object o = helpers.elementAt(i);
+      if (o instanceof TestHelper)
+      {
+        TestHelper h = (TestHelper)o;
+        h.cleanup();
+      }
+      else if (o instanceof AggregateKey)
+      {
+        sharedHelperMgr.cleanup((AggregateKey)o);
+      }
+    }
+    clearHelpers();
+  }
+
+  // =================================================================
+
+  public String toString()
+  {
+    return getFullName() + "<" + objID() + ">";
+  }
+
+  public String objID()
+  {
+    return getClass().getName() + "@" + System.identityHashCode(this);
+  }
+
+  // =================================================================
+  // Helper classes.
+
+  /**
+   * Helper class that manages shared helpers. There's a single
+   * SharedHelperManager stored in the static variable
+   * sharedHelperMgr.
+   */
+  private static class SharedHelperManager
+  {
+
+    private Hashtable helpers = new Hashtable();
+
+    public SharedHelperManager()
+    {
+    }
+
+    public synchronized TestHelper getSharedHelper(
+      String name,
+      Class helperClass,
+      BaseTestContext btc)
+    {
+      synchronized (helpers)
+      {
+        Object key = new AggregateKey(name, helperClass);
+        HelperWrapper helperWrapper = (HelperWrapper)helpers.get(key);
+        if (helperWrapper == null)
+        {
+          TestHelper helper = btc.getHelper(helperClass, true);
+          helperWrapper = new HelperWrapper(helper);
+          helpers.put(key, helperWrapper);
+        }
+        else
+        {
+          helperWrapper.refcount++;
+        }
+        return helperWrapper.helper;
+      }
+    }
+
+    public synchronized void cleanup(AggregateKey key)
+    {
+      HelperWrapper helperWrapper = (HelperWrapper)helpers.get(key);
+
+      helperWrapper.refcount--;
+      if (helperWrapper.refcount == 0)
+      {
+        helperWrapper.helper.cleanup();
+      }
+    }
+
+    private static class HelperWrapper
+    {
+      TestHelper helper;
+      int refcount = 1;
+      HelperWrapper(TestHelper helper)
+      {
+        this.helper = helper;
+      }
+    }
+  }
+
+  public void setProcessEngine(ProcessEngine in)
+  {
+    mProcessEngine = in;
+  }
+
+  public ProcessEngine getProcessEngine()
+  {
+    return mProcessEngine;
+  }
+
+  public void setLogicalName(String name)
+  {
+    this.logicalName = name;
+  }
+  public String getLogicalName()
+  {
+    return logicalName;
+  }
+  // Used so we may pass the code coverage flag in to the test
+  public void setCodeCoverageEnabled(int mode)
+  {
+    codeCoverageEnabled = mode;
+  }
+  public int getCodeCoverageEnabled()
+  {
+    return codeCoverageEnabled;
+  }
+}

Propchange: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/compose/internal/context/BaseTestContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/core/AbstractExecutionTask.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/core/AbstractExecutionTask.java?rev=232310&r1=232309&r2=232310&view=diff
==============================================================================
--- beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/core/AbstractExecutionTask.java (original)
+++ beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/core/AbstractExecutionTask.java Fri Aug 12 08:12:28 2005
@@ -1,746 +1,746 @@
-package org.apache.beehive.test.tools.tch.core;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-
-import org.apache.beehive.test.tools.tch.compose.Parameters;
-import org.apache.beehive.test.tools.tch.core.configuration.NonfatalValidationException;
-import org.apache.beehive.test.tools.tch.core.configuration.ProcessManagementConfigurationException;
-import org.apache.beehive.test.tools.tch.core.process.ProcessEngine;
-import org.apache.beehive.test.tools.tch.core.process.ProcessRegistry;
-import org.apache.beehive.test.tools.tch.core.process.ResolveProcessPropertiesHelper;
-import org.apache.beehive.test.tools.tch.core.test.DetailAddingResultHandler;
-import org.apache.beehive.test.tools.tch.core.test.InternalParameters;
-import org.apache.beehive.test.tools.tch.core.test.ResultHandler;
-import org.apache.beehive.test.tools.tch.core.test.TestLogicTask;
-import org.apache.beehive.test.tools.tch.core.test.TestRegistry;
-import org.apache.beehive.test.tools.tch.core.test.TimeoutResultHandler;
-import org.apache.beehive.test.tools.tch.util.TchConstants;
-import org.apache.beehive.test.tools.tch.util.TestResultAdapter;
-import org.apache.beehive.test.tools.tch.util.TestResultBean;
-import org.apache.beehive.test.tools.tch.util.TimeoutTimer;
-import org.apache.beehive.test.tools.tch.util.ValueHandler;
-
-/**
- * Abstract base class which must be extended by any tasks which are meant to
- * implement a type of test, and which will run inside a &lt;test&gt; element
- * (e.g. javatest). This class provides
- * facilities for the task writer for process management, subtest support,
- * timeout support, and test parameters.
- * <p>
- * Subtests are basically a unit of a test that logs a single result. A single
- * test class that extends this base class may actually log multiple results.
- * For example, javatest logs a single result for each test method in the test
- * class which it runs. Keep this in mind since the terminology may be confusing
- * in some areas.
- * <p>
- * This should only be extended if we are implementing a truly new type
- * of test which is not handled by any existing test types
- * (javatest, junit, cmdline, etc.)
- * 
- */
-public abstract class AbstractExecutionTask
-  extends BaseTwoPassTask
-  implements ExecutionTask, PropertyReferencer
-{
-  private static Boolean globalTestVehiclePropsValidatedOk = null;
-
-  private ExecutionTaskHelper helper = null;
-
-  // decorate regular result handler with this if we're running
-  // tests with timeout.
-  private TimeoutResultHandler timeoutResultHandler = null;
-  private Integer testTimeoutSeconds = null;
-
-  private Collection subtestNamesConfiguredToRun = null;
-
-  //for skipping
-  private boolean doSkip = false;
-  private boolean skipChecked = false;
-  private String skipMessage = null;
-  private int skipResultType = -1;
-
-  /**
-   * Get the ExecutionTaskHelper associated with the instance of the current
-   * task.
-   * 
-   * @return helper for the task
-   */
-  private final ExecutionTaskHelper getHelper()
-  {
-    return helper;
-  }
-
-  /**
-   * Set the timeout for the current test task
-   * 
-   * @param in number of seconds before the test will time out
-   */
-  public final void setTestTimeoutSeconds(Integer in)
-  {
-    testTimeoutSeconds = in;
-  }
-
-  /**
-   * Set the helper for the current task instance
-   * 
-   * @param in helper class
-   */
-  public final void setHelper(ExecutionTaskHelper in)
-  {
-    helper = in;
-  }
-
-  /**
-   * This method should return the name this test is 'an instance' of.
-   * For example, for javatest, this is classname.methodname 
-   * 
-   * This default implementation just returns the logical test name.
-   */
-  public String getTestCaseName()
-  {
-    return getHelper().getTestTask().getShortName();
-  }
-
-  private final boolean toSkip()
-  {
-    if (!skipChecked)
-    {
-      skipChecked = true;
-      getHelper().getTestTask().checkSkip();
-      // FIXME:  This will call back on this instance, since the test task already has reference to this.
-      // This is ugly, back to both-way referencing.   Clean up at some point.
-    }
-    return doSkip;
-  }
-
-  public final void setSkip(String message)
-  {
-    setSkipCommon(message, TchConstants.SKIP_LEVEL_INT);
-  }
-
-  public final void setValidationSkip(String message)
-  {
-    setSkipCommon(message, TchConstants.VALIDATION_SKIP_LEVEL_INT);
-  }
-
-  public final void setNestedSkip(String message)
-  {
-    setSkipCommon(message, TchConstants.NESTED_SKIP_LEVEL_INT);
-  }
-
-  private void setSkipCommon(String message, int skipLevel)
-  {
-    doSkip = true;
-    skipMessage = message;
-    skipResultType = skipLevel;
-  }
-
-  private boolean willRunSubtests()
-  {
-    return (getSubtestsConfiguredToRun() != null);
-  }
-
-  /**
-   * This is being called during init-mode; execution tasks should report fatal setup related 
-   * problems here (by throwing a ExecutionTaskValidationException).
-   * For example, for javatest, this could be: could not find testclass foo.foo
-   */
-  public abstract void validate() throws ExecutionTaskValidationException;
-
-  public abstract TestLogicTask getTestLogicTask();
-
-  protected final ResultHandler getResultHandler()
-  
-  {
-    return getHelper().getResultHandler();
-  }
-
-  /**
-   * Get all parameters which are mapped to the current test
-   * 
-   * @return Parameters object containing the mapped parameters
-   */
-  protected final Parameters getParameters()
-  {
-    return prepareParameters(getHelper().getParameters());
-  }
-
-  /**
-   * @return Same parameters as getParameters(), with a few more hooks
-   */
-  protected final InternalParameters getInternalParameters()
-  {
-    return prepareParameters(getHelper().getParameters());
-  }
-
-  /**
-   * This is a hack, for sure. Similar logic needs to be integrated with 
-   * BaseTask.handleValue. The problem we have here is that 
-   * when running a subset of tests, we are recycling the 
-   * init-mode logical test instances, for which the processinfo
-   * props have not been resolved.
-   * So we are resolving them here manually. Even worse, we are
-   * only resolving for test parameters
-   */
-  private InternalParameters prepareParameters(InternalParameters in)
-  {
-    if (AntProperties.isIndividualTestModeOn() && !DirtyClass.isFirstPass())
-    {
-      Map params = in.getProperties();
-      ValueHandler handler =
-        new ValueHandler(
-          ProcessRegistry.getAttributesForActiveProcessesWithPrefix());
-      ResolveProcessPropertiesHelper.resolveAndSetProcessInfoProperties(
-        null,
-        params,
-        handler);
-    }
-    return in;
-  }
-
-  /**
-   * The subtest names that will actually execute at test run time.
-   * 
-   * Execution tasks that log more than a single result should call this at 
-   * run-time to determine which subtests to run.
-   * 
-   * @return Collection. Collection of Strings, all subtest names configured 
-   * to run. 
-   */
-  public final Collection getSubtestsConfiguredToRun()
-  {
-    // since this may get called often and the subtest names do not change,
-    // we cache the collection 
-    if (subtestNamesConfiguredToRun == null)
-    {
-      subtestNamesConfiguredToRun = getInternalSubtestsConfiguredToRun();
-      if (subtestNamesConfiguredToRun == null)
-        subtestNamesConfiguredToRun = getAllSubtestNames();
-      if (subtestNamesConfiguredToRun != null)
-        subtestNamesConfiguredToRun =
-          Collections.unmodifiableCollection(subtestNamesConfiguredToRun);
-    }
-    return subtestNamesConfiguredToRun;
-  }
-
-  /**
-   * Returns the subtest names configured to run in the TestRegistry.
-   * 
-   * Note that this will not return anything meaningful at init-time. 
-   */
-  private Collection getInternalSubtestsConfiguredToRun()
-  {
-    if (!getTestTask().isTestNode())
-      return null;
-
-    //Sring name = getHelper().getTestTask().getName();
-    //TestRegistry.Entry entry = getHelper().getTestTask().getTestRegistry().getTestEntry(name);
-    return getTestRegistryEntry().getSubtestsConfiguredToRun();
-  }
-
-  /**
-   * If Tch wants this execution task to run a specific subtest, or specific
-   * subtests, returns true. Typically this happens when the user sets 
-   * tch.test-names on the command line, and specifies specific subtest.
-   * <p>
-   * Note that this method can only be called at run time (not at init-time).
-   * <p>
-   * @return boolean. 'true' if the engine wants this execution task to run
-   * specific subtests. 'false' otherwise (the execution task has control over
-   * what to run)
-   */
-  public final boolean forceSubtests()
-  {
-    return getInternalSubtestsConfiguredToRun() != null;
-  }
-
-  /**
-   * Hook to override by execution task if it needs to add information to results it does not log itself.
-   * (SKIP, ABORT)
-   */
-  protected void handleResult(TestResultBean result)
-  {
-  }
-
-  /**
-   * Returns all subtest names this execution task is able to run. 
-   * ExecutionTasks that return more than a single result need to override 
-   * this.
-   * 
-   * @return Collection. Collection of Strings, all subtest names. 
-   * Returning null indicates that this execution task only submits 
-   * a single result. 
-   */
-  public Collection getAllSubtestNames()
-  {
-    return null;
-  }
-
-  /**
-   * This is one of the hooks that execution task subclasses may call
-   * in order to deal with test problems that should result in an invalidation
-   * of the test. It automatically creates 
-   * the correct type of NonfatatValidationException
-   * 
-   * @param ex the exception associated with the problem
-   */
-  protected final void invalidateTest(Exception ex)
-  {
-    getHelper().getTestTask().invalidate(
-      new NonfatalValidationException(
-        ex,
-        ErrorMessageConstants.EXEC_TASK_WRAPPED_ERROR_CODE));
-  }
-
-  /**
-   * This is one of the hooks that execution task subclasses may call
-   * in order to deal with test problems that should result in an invalidation
-   * of the test. It automatically creates 
-   * the correct type of NonfatatValidationException
-   * 
-   * @param message the textual message associated with the problem
-   */
-  protected final void invalidateTest(String message)
-  {
-    invalidateTest(
-      new NonfatalValidationException(
-        ErrorMessageConstants.EXEC_TASK_ERROR_CODE,
-        ErrorMessageConstants.MESSAGE,
-        message));
-  }
-
-  /**
-   * Called in order to log the same result for all subtests which are configured
-   * to run.
-   * 
-   * @param type the result type
-   * @param message message associated with the result
-   * @param ex exception associated with the result
-   */
-  private void reportTestAs(int type, String message, Exception ex)
-  {
-    if (willRunSubtests())
-      for (Iterator iter = getSubtestsConfiguredToRun().iterator();
-        iter.hasNext();
-        )
-        submitResult(type, (String)iter.next(), message, ex);
-    else
-      submitResult(type, message, ex);
-  }
-
-  protected final File getTestDir()
-  {
-    return getHelper().getTestTask().getTestSuiteCall().getAbsolutePath();
-  }
-
-  protected final TestTask getTestTask()
-  {
-    return getHelper().getTestTask();
-  }
-
-  private void submitResult(int type, String message, Exception ex)
-  {
-    submitResult(type, null, message, ex);
-  }
-
-  private void submitResult(
-    int type,
-    String subtestName,
-    String message,
-    Exception ex)
-  {
-    TestResultAdapter result = new TestResultAdapter(type);
-    result.setOutputMsg(message);
-    result.setThrowableWithFilter(ex, getHelper().getFilterThrowable());
-    handleResult(result);
-    if (subtestName == null)
-      getResultHandler().submitResult(result);
-    else
-      getResultHandler().submitResult(result, subtestName);
-  }
-
-  /**
-   * Returns number of outcome results this execution task will submit
-   * during its lifecycle. 
-   *
-   * @return the number of outcome results this execution task will submit.
-   */
-  public final int getNumOutcomes()
-  {
-    if (willRunSubtests())
-      return getSubtestsConfiguredToRun().size();
-    else
-      return 1;
-  }
-
-  public final void abortTest(String message)
-  {
-    abortTest(message, null);
-  }
-
-  /**
-   * Abort the current test. Logs an ABORT result for all subtests which
-   * are configured to run.
-   * 
-   * @param message text associated with the ABORT
-   * @param ex exception associated with the ABORT
-   */
-  public final void abortTest(String message, Exception ex)
-  {
-    reportTestAs(TchConstants.ABORT_LEVEL_INT, message, ex);
-  }
-
-  protected boolean preInitialize()
-  {
-    if (super.preInitialize())
-    {
-      try
-      {
-        //this requires that all parallel process tasks have initialized
-        //FIXME, kind of a hack that we have to finalize this here
-        //with an idempotent method that will be called again and again
-        getHelper().getTestTask().setDefaultProcessTask();
-      }
-      catch (ProcessManagementConfigurationException ex)
-      {
-        throw new BuildException(
-          "Error with preInitialize for " + this +":  ",
-          ex,
-          getLocation());
-      }
-      return true;
-    }
-    else
-      return false;
-  }
-
-  /*
-   * Validation to detect when global-test-vehicle-process is set, but
-   * global-test-vehicle is not. Also checks the referenced process has 
-   * been registered.
-   * These are all fatal errors.
-   * 
-   * We want to log validation errors only once (not once per AET instance),
-   * because they are global in nature. We can do this without worrying
-   * about failfast-validation=false, because they are all fatal, and will
-   * always cause the run to stop after the validation step
-   */
-  private void validateGlobalTestVehicleAntProperties()
-    throws NonfatalValidationException
-  {
-    String testVehicleProcess = AntProperties.getGlobalTestVehicleProcess();
-    if (testVehicleProcess != null)
-    {
-      if (!AntProperties.isGlobalTestVehicleSet())
-      {
-        throw new NonfatalValidationException(
-          ErrorMessageConstants.MANDATORY_GLOBAL_TEST_VEHICLE_ERROR_CODE);
-      }
-      // also check that the referenced process is valid
-      try
-      {
-        ProcessRegistry.Entry entry =
-          getHelper().getTestTask().getProcessRegistry().getProcessEntry(
-            testVehicleProcess);
-        // activate this process (it is likely that this process has not been "mapped"
-        // explicitly, so we need to activate it)
-        entry.getProcess().activate();
-      }
-      catch (NonfatalValidationException ex)
-      {
-        // create more specific validation error
-        throw new NonfatalValidationException(
-          ErrorMessageConstants
-            .GLOBAL_TEST_VEHICLE_PROCESS_NOT_REGISTERED_ERROR_CODE,
-          ErrorMessageConstants.PROCESS,
-          testVehicleProcess);
-      }
-    }
-    else if (AntProperties.isGlobalTestVehicleSet())
-    {
-      throw new NonfatalValidationException(
-        ErrorMessageConstants.MANDATORY_GLOBAL_TEST_VEHICLE_PROCESS_ERROR_CODE);
-    }
-  }
-
-  protected boolean initialize()
-  {
-    if (super.initialize())
-    {
-      // we did not validate the props yet
-      if (globalTestVehiclePropsValidatedOk == null)
-      {
-        try
-        {
-          // FIXME
-          // we're only doing this once, not once per instance
-          // of AET. This bit of logic should live somewhere else,
-          // perhaps where we validate prop names.
-          validateGlobalTestVehicleAntProperties();
-          globalTestVehiclePropsValidatedOk = new Boolean(true);
-        }
-        catch (NonfatalValidationException ex)
-        {
-          invalidateTest(ex);
-          globalTestVehiclePropsValidatedOk = new Boolean(false);
-          return true;
-        }
-      }
-      else if (!globalTestVehiclePropsValidatedOk.booleanValue())
-        return true;
-
-      // The helper should already have the test vehicle type that is set by the
-      // TestVehicleTask
-      // two try-catch blocks since we want to report validation failures for both (if any)
-      try
-      {
-        initializeAndRegisterTestVehicle();
-        //getHelper().setTestVehicleType(getTestVehicleType());
-        getHelper().validateTestVehicleType();
-      }
-      catch (NonfatalValidationException ex)
-      {
-        invalidateTest(ex);
-      }
-      try
-      {
-        initializeTestVehicle();
-        //getHelper().setTestVehicleType(getTestVehicleType());
-        getHelper().validateTestVehicleProcessName();
-      }
-      catch (NonfatalValidationException ex)
-      {
-        invalidateTest(ex);
-      }
-      return true;
-    }
-    else
-      return false;
-  }
-
-  protected final boolean preRun()
-  {
-    if (super.preRun())
-    {
-      if (!toSkip())
-      {
-        try
-        {
-          //this requires that all parallel process tasks have initialized
-          //FIXME, kind of a hack that we have to finalize this here
-          //with an idempotent method that will be called again and again
-          getHelper().getTestTask().setDefaultProcessTask();
-          getHelper().getTestTask().getHelper().setProcessEngine(
-            getHelper().getTestTask());
-
-        }
-        catch (ProcessManagementConfigurationException ex)
-        {
-          throw new BuildException(
-            "Error with preRun for " + this +":  ",
-            ex,
-            getLocation());
-        }
-        getHelper().setExecutionTask(this);
-
-        if (AntProperties.isLogInformAsDetails())
-        {
-          // this will cause all informs to get logged as details
-          getHelper().setResultHandler(
-            new DetailAddingResultHandler(getHelper().getResultHandler()));
-        }
-      }
-      return true;
-    }
-    else
-      return false;
-  }
-
-  protected final boolean run()
-  {
-    if (super.run())
-    {
-      if (toSkip())
-      {
-        reportTestAs(skipResultType, skipMessage, null);
-        return false; //doesn't affect anything right now
-      }
-      else //run the test
-        {
-        org.apache.beehive.test.tools.tch.util.DebugLogger.log(
-          "Inside AbstractExecutionTask.run()",
-          getLocation());
-
-        if (AntProperties.isVerboseOn())
-        {
-          log(String.valueOf(new java.util.Date()));
-          log(
-            "Will run test: "
-              + getHelper().getTestTask().getName()
-              + " with params: "
-              + getHelper().getParameters());
-          if (willRunSubtests())
-            log("  with these subtests: " + getSubtestsConfiguredToRun());
-        }
-
-        if (isTestTimeoutEnabled())
-        {
-          runWithTimeout();
-        }
-        else
-        {
-          if (AntProperties.isVerboseOn())
-            log("Running without timeout");
-          runWithoutTimeout();
-        }
-        return true;
-      }
-    }
-    else
-      return false;
-  }
-
-  protected final Task getParentTask()
-  {
-    return getTestTask();
-  }
-
-  protected final ProcessEngine getProcessEngine()
-  {
-    return getHelper().getProcessEngine();
-  }
-
-  private boolean isTestTimeoutEnabled()
-  {
-    return AntProperties.isTestTimeoutEnabled();
-  }
-
-  private int getTestTimeoutSeconds()
-  {
-    if (testTimeoutSeconds != null)
-      return testTimeoutSeconds.intValue();
-    else
-      return AntProperties.getTestTimeoutSeconds();
-  }
-
-  /**
-   * gets called if this test timed out
-   */
-  private void timedOut()
-  {
-    if (AntProperties.isVerboseOn())
-      log("Test timed out at " + new java.util.Date());
-
-    timeoutResultHandler.setTimedOut();
-
-    getHelper().notifyTimeout(getTestLogicTask());
-  }
-
-  private void runWithoutTimeout()
-  {
-    // what test vehicle will we run with? all validation has happened at this
-    // point, so that we don't need to check for null
-
-    // if a test-vehicle is explicitly specified in the test, the proper test vehicle
-    // and process should already have been set in the helper.
-    //getHelper().setTestVehicleType(getTestVehicleType());
-    //getHelper().setTestVehicleProcessName(getTestVehicleProcessName());
-
-    // this will make sure that the global test vehicle is set on the helper
-    // if no test vehicle was explicitly specified
-    initializeTestVehicle();
-
-    getHelper().runTestLogic();
-  }
-
-  private void runWithTimeout()
-  {
-    // timeout
-    // make a new timeout thread, and a new thread to run the test
-    // logic task in
-    timeoutResultHandler =
-      new TimeoutResultHandler(
-        getHelper().getResultHandler(),
-        getTestTimeoutSeconds(),
-        getSubtestsConfiguredToRun(),
-        willRunSubtests());
-    getHelper().setResultHandler(timeoutResultHandler);
-    Thread testLogicThread = new Thread()
-    {
-      public void run()
-      {
-        runWithoutTimeout();
-      }
-    };
-    if (AntProperties.isVerboseOn())
-    {
-      log("Timeout for test is: " + getTestTimeoutSeconds() + " seconds");
-    }
-    TimeoutTimer timer = new TimeoutTimer(getTestTimeoutSeconds() * 1000);
-    timer.setWatchedThread(testLogicThread);
-    testLogicThread.start();
-    timer.start();
-    if (timer.expired())
-    {
-      timedOut();
-    }
-  }
-
-  /**
-   * Set the test vehicle type to the proper value for domain gen purposes
-   */
-  private void initializeAndRegisterTestVehicle()
-  {
-    // just call the same method used for test execution. This will
-    // set the right things on the helper
-    initializeTestVehicle();
-    // adding to the registry for domain gen purposes. This is not
-    // used for test execution.
-    getHelper().registerTestVehicleWithTestRegistry();
-  }
-
-  /**
-   * Set the test vehicle type to the proper value for test execution purposes
-   * @return
-   */
-  private void initializeTestVehicle()
-  {
-    String explicitTestVehicleType = getHelper().getTestVehicleType();
-    String explicitTestVehicleProcessName =
-      getHelper().getTestVehicleProcessName();
-    // if no test vehicle has been explicitly specified, we expect to read the
-    // global test vehicle settings
-    if (explicitTestVehicleType == null)
-    {
-      String testVehicleType = AntProperties.getGlobalTestVehicle();
-      String testVehicleProcess = AntProperties.getGlobalTestVehicleProcess();
-      getHelper().setTestVehicleType(testVehicleType);
-      getHelper().setTestVehicleProcessName(testVehicleProcess);
-    }
-  }
-
-  // helper methods for accessing the test-registery and the test-vehicle 
-  // registry
-
-  public final String getLogicalTestName()
-  {
-    return getTestTask().getLogicalTest().getName();
-  }
-
-  private TestRegistry getTestRegistry()
-  {
-    return getTestTask().getTestRegistry();
-  }
-
-  private TestRegistry.Entry getTestRegistryEntry()
-  {
-    return getTestRegistry().getLogicalTestEntry(getTestTask().getKey());
-  }
-}
+package org.apache.beehive.test.tools.tch.core;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+import org.apache.beehive.test.tools.tch.compose.Parameters;
+import org.apache.beehive.test.tools.tch.core.configuration.NonfatalValidationException;
+import org.apache.beehive.test.tools.tch.core.configuration.ProcessManagementConfigurationException;
+import org.apache.beehive.test.tools.tch.core.process.ProcessEngine;
+import org.apache.beehive.test.tools.tch.core.process.ProcessRegistry;
+import org.apache.beehive.test.tools.tch.core.process.ResolveProcessPropertiesHelper;
+import org.apache.beehive.test.tools.tch.core.test.DetailAddingResultHandler;
+import org.apache.beehive.test.tools.tch.core.test.InternalParameters;
+import org.apache.beehive.test.tools.tch.core.test.ResultHandler;
+import org.apache.beehive.test.tools.tch.core.test.TestLogicTask;
+import org.apache.beehive.test.tools.tch.core.test.TestRegistry;
+import org.apache.beehive.test.tools.tch.core.test.TimeoutResultHandler;
+import org.apache.beehive.test.tools.tch.util.TchConstants;
+import org.apache.beehive.test.tools.tch.util.TestResultAdapter;
+import org.apache.beehive.test.tools.tch.util.TestResultBean;
+import org.apache.beehive.test.tools.tch.util.TimeoutTimer;
+import org.apache.beehive.test.tools.tch.util.ValueHandler;
+
+/**
+ * Abstract base class which must be extended by any tasks which are meant to
+ * implement a type of test, and which will run inside a &lt;test&gt; element
+ * (e.g. javatest). This class provides
+ * facilities for the task writer for process management, subtest support,
+ * timeout support, and test parameters.
+ * <p>
+ * Subtests are basically a unit of a test that logs a single result. A single
+ * test class that extends this base class may actually log multiple results.
+ * For example, javatest logs a single result for each test method in the test
+ * class which it runs. Keep this in mind since the terminology may be confusing
+ * in some areas.
+ * <p>
+ * This should only be extended if we are implementing a truly new type
+ * of test which is not handled by any existing test types
+ * (javatest, junit, cmdline, etc.)
+ * 
+ */
+public abstract class AbstractExecutionTask
+  extends BaseTwoPassTask
+  implements ExecutionTask, PropertyReferencer
+{
+  private static Boolean globalTestVehiclePropsValidatedOk = null;
+
+  private ExecutionTaskHelper helper = null;
+
+  // decorate regular result handler with this if we're running
+  // tests with timeout.
+  private TimeoutResultHandler timeoutResultHandler = null;
+  private Integer testTimeoutSeconds = null;
+
+  private Collection subtestNamesConfiguredToRun = null;
+
+  //for skipping
+  private boolean doSkip = false;
+  private boolean skipChecked = false;
+  private String skipMessage = null;
+  private int skipResultType = -1;
+
+  /**
+   * Get the ExecutionTaskHelper associated with the instance of the current
+   * task.
+   * 
+   * @return helper for the task
+   */
+  private final ExecutionTaskHelper getHelper()
+  {
+    return helper;
+  }
+
+  /**
+   * Set the timeout for the current test task
+   * 
+   * @param in number of seconds before the test will time out
+   */
+  public final void setTestTimeoutSeconds(Integer in)
+  {
+    testTimeoutSeconds = in;
+  }
+
+  /**
+   * Set the helper for the current task instance
+   * 
+   * @param in helper class
+   */
+  public final void setHelper(ExecutionTaskHelper in)
+  {
+    helper = in;
+  }
+
+  /**
+   * This method should return the name this test is 'an instance' of.
+   * For example, for javatest, this is classname.methodname 
+   * 
+   * This default implementation just returns the logical test name.
+   */
+  public String getTestCaseName()
+  {
+    return getHelper().getTestTask().getShortName();
+  }
+
+  private final boolean toSkip()
+  {
+    if (!skipChecked)
+    {
+      skipChecked = true;
+      getHelper().getTestTask().checkSkip();
+      // FIXME:  This will call back on this instance, since the test task already has reference to this.
+      // This is ugly, back to both-way referencing.   Clean up at some point.
+    }
+    return doSkip;
+  }
+
+  public final void setSkip(String message)
+  {
+    setSkipCommon(message, TchConstants.SKIP_LEVEL_INT);
+  }
+
+  public final void setValidationSkip(String message)
+  {
+    setSkipCommon(message, TchConstants.VALIDATION_SKIP_LEVEL_INT);
+  }
+
+  public final void setNestedSkip(String message)
+  {
+    setSkipCommon(message, TchConstants.NESTED_SKIP_LEVEL_INT);
+  }
+
+  private void setSkipCommon(String message, int skipLevel)
+  {
+    doSkip = true;
+    skipMessage = message;
+    skipResultType = skipLevel;
+  }
+
+  private boolean willRunSubtests()
+  {
+    return (getSubtestsConfiguredToRun() != null);
+  }
+
+  /**
+   * This is being called during init-mode; execution tasks should report fatal setup related 
+   * problems here (by throwing a ExecutionTaskValidationException).
+   * For example, for javatest, this could be: could not find testclass foo.foo
+   */
+  public abstract void validate() throws ExecutionTaskValidationException;
+
+  public abstract TestLogicTask getTestLogicTask();
+
+  protected final ResultHandler getResultHandler()
+  
+  {
+    return getHelper().getResultHandler();
+  }
+
+  /**
+   * Get all parameters which are mapped to the current test
+   * 
+   * @return Parameters object containing the mapped parameters
+   */
+  protected final Parameters getParameters()
+  {
+    return prepareParameters(getHelper().getParameters());
+  }
+
+  /**
+   * @return Same parameters as getParameters(), with a few more hooks
+   */
+  protected final InternalParameters getInternalParameters()
+  {
+    return prepareParameters(getHelper().getParameters());
+  }
+
+  /**
+   * This is a hack, for sure. Similar logic needs to be integrated with 
+   * BaseTask.handleValue. The problem we have here is that 
+   * when running a subset of tests, we are recycling the 
+   * init-mode logical test instances, for which the processinfo
+   * props have not been resolved.
+   * So we are resolving them here manually. Even worse, we are
+   * only resolving for test parameters
+   */
+  private InternalParameters prepareParameters(InternalParameters in)
+  {
+    if (AntProperties.isIndividualTestModeOn() && !DirtyClass.isFirstPass())
+    {
+      Map params = in.getProperties();
+      ValueHandler handler =
+        new ValueHandler(
+          ProcessRegistry.getAttributesForActiveProcessesWithPrefix());
+      ResolveProcessPropertiesHelper.resolveAndSetProcessInfoProperties(
+        null,
+        params,
+        handler);
+    }
+    return in;
+  }
+
+  /**
+   * The subtest names that will actually execute at test run time.
+   * 
+   * Execution tasks that log more than a single result should call this at 
+   * run-time to determine which subtests to run.
+   * 
+   * @return Collection. Collection of Strings, all subtest names configured 
+   * to run. 
+   */
+  public final Collection getSubtestsConfiguredToRun()
+  {
+    // since this may get called often and the subtest names do not change,
+    // we cache the collection 
+    if (subtestNamesConfiguredToRun == null)
+    {
+      subtestNamesConfiguredToRun = getInternalSubtestsConfiguredToRun();
+      if (subtestNamesConfiguredToRun == null)
+        subtestNamesConfiguredToRun = getAllSubtestNames();
+      if (subtestNamesConfiguredToRun != null)
+        subtestNamesConfiguredToRun =
+          Collections.unmodifiableCollection(subtestNamesConfiguredToRun);
+    }
+    return subtestNamesConfiguredToRun;
+  }
+
+  /**
+   * Returns the subtest names configured to run in the TestRegistry.
+   * 
+   * Note that this will not return anything meaningful at init-time. 
+   */
+  private Collection getInternalSubtestsConfiguredToRun()
+  {
+    if (!getTestTask().isTestNode())
+      return null;
+
+    //Sring name = getHelper().getTestTask().getName();
+    //TestRegistry.Entry entry = getHelper().getTestTask().getTestRegistry().getTestEntry(name);
+    return getTestRegistryEntry().getSubtestsConfiguredToRun();
+  }
+
+  /**
+   * If Tch wants this execution task to run a specific subtest, or specific
+   * subtests, returns true. Typically this happens when the user sets 
+   * tch.test-names on the command line, and specifies specific subtest.
+   * <p>
+   * Note that this method can only be called at run time (not at init-time).
+   * <p>
+   * @return boolean. 'true' if the engine wants this execution task to run
+   * specific subtests. 'false' otherwise (the execution task has control over
+   * what to run)
+   */
+  public final boolean forceSubtests()
+  {
+    return getInternalSubtestsConfiguredToRun() != null;
+  }
+
+  /**
+   * Hook to override by execution task if it needs to add information to results it does not log itself.
+   * (SKIP, ABORT)
+   */
+  protected void handleResult(TestResultBean result)
+  {
+  }
+
+  /**
+   * Returns all subtest names this execution task is able to run. 
+   * ExecutionTasks that return more than a single result need to override 
+   * this.
+   * 
+   * @return Collection. Collection of Strings, all subtest names. 
+   * Returning null indicates that this execution task only submits 
+   * a single result. 
+   */
+  public Collection getAllSubtestNames()
+  {
+    return null;
+  }
+
+  /**
+   * This is one of the hooks that execution task subclasses may call
+   * in order to deal with test problems that should result in an invalidation
+   * of the test. It automatically creates 
+   * the correct type of NonfatatValidationException
+   * 
+   * @param ex the exception associated with the problem
+   */
+  protected final void invalidateTest(Exception ex)
+  {
+    getHelper().getTestTask().invalidate(
+      new NonfatalValidationException(
+        ex,
+        ErrorMessageConstants.EXEC_TASK_WRAPPED_ERROR_CODE));
+  }
+
+  /**
+   * This is one of the hooks that execution task subclasses may call
+   * in order to deal with test problems that should result in an invalidation
+   * of the test. It automatically creates 
+   * the correct type of NonfatatValidationException
+   * 
+   * @param message the textual message associated with the problem
+   */
+  protected final void invalidateTest(String message)
+  {
+    invalidateTest(
+      new NonfatalValidationException(
+        ErrorMessageConstants.EXEC_TASK_ERROR_CODE,
+        ErrorMessageConstants.MESSAGE,
+        message));
+  }
+
+  /**
+   * Called in order to log the same result for all subtests which are configured
+   * to run.
+   * 
+   * @param type the result type
+   * @param message message associated with the result
+   * @param ex exception associated with the result
+   */
+  private void reportTestAs(int type, String message, Exception ex)
+  {
+    if (willRunSubtests())
+      for (Iterator iter = getSubtestsConfiguredToRun().iterator();
+        iter.hasNext();
+        )
+        submitResult(type, (String)iter.next(), message, ex);
+    else
+      submitResult(type, message, ex);
+  }
+
+  protected final File getTestDir()
+  {
+    return getHelper().getTestTask().getTestSuiteCall().getAbsolutePath();
+  }
+
+  protected final TestTask getTestTask()
+  {
+    return getHelper().getTestTask();
+  }
+
+  private void submitResult(int type, String message, Exception ex)
+  {
+    submitResult(type, null, message, ex);
+  }
+
+  private void submitResult(
+    int type,
+    String subtestName,
+    String message,
+    Exception ex)
+  {
+    TestResultAdapter result = new TestResultAdapter(type);
+    result.setOutputMsg(message);
+    result.setThrowableWithFilter(ex, getHelper().getFilterThrowable());
+    handleResult(result);
+    if (subtestName == null)
+      getResultHandler().submitResult(result);
+    else
+      getResultHandler().submitResult(result, subtestName);
+  }
+
+  /**
+   * Returns number of outcome results this execution task will submit
+   * during its lifecycle. 
+   *
+   * @return the number of outcome results this execution task will submit.
+   */
+  public final int getNumOutcomes()
+  {
+    if (willRunSubtests())
+      return getSubtestsConfiguredToRun().size();
+    else
+      return 1;
+  }
+
+  public final void abortTest(String message)
+  {
+    abortTest(message, null);
+  }
+
+  /**
+   * Abort the current test. Logs an ABORT result for all subtests which
+   * are configured to run.
+   * 
+   * @param message text associated with the ABORT
+   * @param ex exception associated with the ABORT
+   */
+  public final void abortTest(String message, Exception ex)
+  {
+    reportTestAs(TchConstants.ABORT_LEVEL_INT, message, ex);
+  }
+
+  protected boolean preInitialize()
+  {
+    if (super.preInitialize())
+    {
+      try
+      {
+        //this requires that all parallel process tasks have initialized
+        //FIXME, kind of a hack that we have to finalize this here
+        //with an idempotent method that will be called again and again
+        getHelper().getTestTask().setDefaultProcessTask();
+      }
+      catch (ProcessManagementConfigurationException ex)
+      {
+        throw new BuildException(
+          "Error with preInitialize for " + this +":  ",
+          ex,
+          getLocation());
+      }
+      return true;
+    }
+    else
+      return false;
+  }
+
+  /*
+   * Validation to detect when global-test-vehicle-process is set, but
+   * global-test-vehicle is not. Also checks the referenced process has 
+   * been registered.
+   * These are all fatal errors.
+   * 
+   * We want to log validation errors only once (not once per AET instance),
+   * because they are global in nature. We can do this without worrying
+   * about failfast-validation=false, because they are all fatal, and will
+   * always cause the run to stop after the validation step
+   */
+  private void validateGlobalTestVehicleAntProperties()
+    throws NonfatalValidationException
+  {
+    String testVehicleProcess = AntProperties.getGlobalTestVehicleProcess();
+    if (testVehicleProcess != null)
+    {
+      if (!AntProperties.isGlobalTestVehicleSet())
+      {
+        throw new NonfatalValidationException(
+          ErrorMessageConstants.MANDATORY_GLOBAL_TEST_VEHICLE_ERROR_CODE);
+      }
+      // also check that the referenced process is valid
+      try
+      {
+        ProcessRegistry.Entry entry =
+          getHelper().getTestTask().getProcessRegistry().getProcessEntry(
+            testVehicleProcess);
+        // activate this process (it is likely that this process has not been "mapped"
+        // explicitly, so we need to activate it)
+        entry.getProcess().activate();
+      }
+      catch (NonfatalValidationException ex)
+      {
+        // create more specific validation error
+        throw new NonfatalValidationException(
+          ErrorMessageConstants
+            .GLOBAL_TEST_VEHICLE_PROCESS_NOT_REGISTERED_ERROR_CODE,
+          ErrorMessageConstants.PROCESS,
+          testVehicleProcess);
+      }
+    }
+    else if (AntProperties.isGlobalTestVehicleSet())
+    {
+      throw new NonfatalValidationException(
+        ErrorMessageConstants.MANDATORY_GLOBAL_TEST_VEHICLE_PROCESS_ERROR_CODE);
+    }
+  }
+
+  protected boolean initialize()
+  {
+    if (super.initialize())
+    {
+      // we did not validate the props yet
+      if (globalTestVehiclePropsValidatedOk == null)
+      {
+        try
+        {
+          // FIXME
+          // we're only doing this once, not once per instance
+          // of AET. This bit of logic should live somewhere else,
+          // perhaps where we validate prop names.
+          validateGlobalTestVehicleAntProperties();
+          globalTestVehiclePropsValidatedOk = new Boolean(true);
+        }
+        catch (NonfatalValidationException ex)
+        {
+          invalidateTest(ex);
+          globalTestVehiclePropsValidatedOk = new Boolean(false);
+          return true;
+        }
+      }
+      else if (!globalTestVehiclePropsValidatedOk.booleanValue())
+        return true;
+
+      // The helper should already have the test vehicle type that is set by the
+      // TestVehicleTask
+      // two try-catch blocks since we want to report validation failures for both (if any)
+      try
+      {
+        initializeAndRegisterTestVehicle();
+        //getHelper().setTestVehicleType(getTestVehicleType());
+        getHelper().validateTestVehicleType();
+      }
+      catch (NonfatalValidationException ex)
+      {
+        invalidateTest(ex);
+      }
+      try
+      {
+        initializeTestVehicle();
+        //getHelper().setTestVehicleType(getTestVehicleType());
+        getHelper().validateTestVehicleProcessName();
+      }
+      catch (NonfatalValidationException ex)
+      {
+        invalidateTest(ex);
+      }
+      return true;
+    }
+    else
+      return false;
+  }
+
+  protected final boolean preRun()
+  {
+    if (super.preRun())
+    {
+      if (!toSkip())
+      {
+        try
+        {
+          //this requires that all parallel process tasks have initialized
+          //FIXME, kind of a hack that we have to finalize this here
+          //with an idempotent method that will be called again and again
+          getHelper().getTestTask().setDefaultProcessTask();
+          getHelper().getTestTask().getHelper().setProcessEngine(
+            getHelper().getTestTask());
+
+        }
+        catch (ProcessManagementConfigurationException ex)
+        {
+          throw new BuildException(
+            "Error with preRun for " + this +":  ",
+            ex,
+            getLocation());
+        }
+        getHelper().setExecutionTask(this);
+
+        if (AntProperties.isLogInformAsDetails())
+        {
+          // this will cause all informs to get logged as details
+          getHelper().setResultHandler(
+            new DetailAddingResultHandler(getHelper().getResultHandler()));
+        }
+      }
+      return true;
+    }
+    else
+      return false;
+  }
+
+  protected final boolean run()
+  {
+    if (super.run())
+    {
+      if (toSkip())
+      {
+        reportTestAs(skipResultType, skipMessage, null);
+        return false; //doesn't affect anything right now
+      }
+      else //run the test
+        {
+        org.apache.beehive.test.tools.tch.util.DebugLogger.log(
+          "Inside AbstractExecutionTask.run()",
+          getLocation());
+
+        if (AntProperties.isVerboseOn())
+        {
+          log(String.valueOf(new java.util.Date()));
+          log(
+            "Will run test: "
+              + getHelper().getTestTask().getName()
+              + " with params: "
+              + getHelper().getParameters());
+          if (willRunSubtests())
+            log("  with these subtests: " + getSubtestsConfiguredToRun());
+        }
+
+        if (isTestTimeoutEnabled())
+        {
+          runWithTimeout();
+        }
+        else
+        {
+          if (AntProperties.isVerboseOn())
+            log("Running without timeout");
+          runWithoutTimeout();
+        }
+        return true;
+      }
+    }
+    else
+      return false;
+  }
+
+  protected final Task getParentTask()
+  {
+    return getTestTask();
+  }
+
+  protected final ProcessEngine getProcessEngine()
+  {
+    return getHelper().getProcessEngine();
+  }
+
+  private boolean isTestTimeoutEnabled()
+  {
+    return AntProperties.isTestTimeoutEnabled();
+  }
+
+  private int getTestTimeoutSeconds()
+  {
+    if (testTimeoutSeconds != null)
+      return testTimeoutSeconds.intValue();
+    else
+      return AntProperties.getTestTimeoutSeconds();
+  }
+
+  /**
+   * gets called if this test timed out
+   */
+  private void timedOut()
+  {
+    if (AntProperties.isVerboseOn())
+      log("Test timed out at " + new java.util.Date());
+
+    timeoutResultHandler.setTimedOut();
+
+    getHelper().notifyTimeout(getTestLogicTask());
+  }
+
+  private void runWithoutTimeout()
+  {
+    // what test vehicle will we run with? all validation has happened at this
+    // point, so that we don't need to check for null
+
+    // if a test-vehicle is explicitly specified in the test, the proper test vehicle
+    // and process should already have been set in the helper.
+    //getHelper().setTestVehicleType(getTestVehicleType());
+    //getHelper().setTestVehicleProcessName(getTestVehicleProcessName());
+
+    // this will make sure that the global test vehicle is set on the helper
+    // if no test vehicle was explicitly specified
+    initializeTestVehicle();
+
+    getHelper().runTestLogic();
+  }
+
+  private void runWithTimeout()
+  {
+    // timeout
+    // make a new timeout thread, and a new thread to run the test
+    // logic task in
+    timeoutResultHandler =
+      new TimeoutResultHandler(
+        getHelper().getResultHandler(),
+        getTestTimeoutSeconds(),
+        getSubtestsConfiguredToRun(),
+        willRunSubtests());
+    getHelper().setResultHandler(timeoutResultHandler);
+    Thread testLogicThread = new Thread()
+    {
+      public void run()
+      {
+        runWithoutTimeout();
+      }
+    };
+    if (AntProperties.isVerboseOn())
+    {
+      log("Timeout for test is: " + getTestTimeoutSeconds() + " seconds");
+    }
+    TimeoutTimer timer = new TimeoutTimer(getTestTimeoutSeconds() * 1000);
+    timer.setWatchedThread(testLogicThread);
+    testLogicThread.start();
+    timer.start();
+    if (timer.expired())
+    {
+      timedOut();
+    }
+  }
+
+  /**
+   * Set the test vehicle type to the proper value for domain gen purposes
+   */
+  private void initializeAndRegisterTestVehicle()
+  {
+    // just call the same method used for test execution. This will
+    // set the right things on the helper
+    initializeTestVehicle();
+    // adding to the registry for domain gen purposes. This is not
+    // used for test execution.
+    getHelper().registerTestVehicleWithTestRegistry();
+  }
+
+  /**
+   * Set the test vehicle type to the proper value for test execution purposes
+   * @return
+   */
+  private void initializeTestVehicle()
+  {
+    String explicitTestVehicleType = getHelper().getTestVehicleType();
+    String explicitTestVehicleProcessName =
+      getHelper().getTestVehicleProcessName();
+    // if no test vehicle has been explicitly specified, we expect to read the
+    // global test vehicle settings
+    if (explicitTestVehicleType == null)
+    {
+      String testVehicleType = AntProperties.getGlobalTestVehicle();
+      String testVehicleProcess = AntProperties.getGlobalTestVehicleProcess();
+      getHelper().setTestVehicleType(testVehicleType);
+      getHelper().setTestVehicleProcessName(testVehicleProcess);
+    }
+  }
+
+  // helper methods for accessing the test-registery and the test-vehicle 
+  // registry
+
+  public final String getLogicalTestName()
+  {
+    return getTestTask().getLogicalTest().getName();
+  }
+
+  private TestRegistry getTestRegistry()
+  {
+    return getTestTask().getTestRegistry();
+  }
+
+  private TestRegistry.Entry getTestRegistryEntry()
+  {
+    return getTestRegistry().getLogicalTestEntry(getTestTask().getKey());
+  }
+}

Propchange: beehive/trunk/controls/test/tools/tch/src/java/org/apache/beehive/test/tools/tch/core/AbstractExecutionTask.java
------------------------------------------------------------------------------
    svn:eol-style = native