Modified:
incubator/qpid/trunk/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java?rev=651325&r1=651324&r2=651325&view=diff
==============================================================================
---
incubator/qpid/trunk/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java
(original)
+++
incubator/qpid/trunk/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java
Thu Apr 24 10:49:03 2008
@@ -1,625 +1,625 @@
-/*
- *
- * 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.qpid.junit.extensions;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.junit.extensions.listeners.TKTestListener;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Properties;
-
-/**
- * TKTestResult extends TestResult in order to calculate test timings, to pass
the variable integer parameter for
- * parameterized test cases to those test cases and to introduce an optional
delay before test starts. Interested
- * [EMAIL PROTECTED] TKTestListener}s may be attached to this and will be
informed of all relevant test statistics.
- *
- * <p><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Calculate test timings.
- * <tr><td> Inform timing listeners of timings.
- * <tr><td> Inform memory listeners of memory readings.
- * <tr><td> Inform parameters listeners of parameters.
- * <tr><td> Pass the integer parameter to parameterized test cases.
- * <tr><td> Provide verbose test information on test start and end.
- * </table>
- *
- * @todo Move the verbose test information on test start/end into a test
listener instead. It confuses the intention
- * of this class. Could also move the delay into a listener but that
seems less appropriate as it would be a
- * side-effecting listener. Delay and timing calculation are fundamental
enough to this class.
- *
- * @todo The need for this class to act as a place-holder for the integer
parameter for parameterized test cases is
- * because this behaviour has been factored out into a test decorator
class, see [EMAIL PROTECTED] AsymptoticTestDecorator}.
- * The [EMAIL PROTECTED] AsymptoticTestDecorator#run} method takes a
TestResult as an argument and cannot easily get to the
- * [EMAIL PROTECTED] AsymptoticTestCase} class other than through this
class. The option of using this class as a place hold
- * for this value was chosen. Alternatively this class could provide a
method for decorators to access the
- * underlying test case through and then leave the setting of this
parameter to the decorator which is a more
- * natural home for this behaviour. It would also provide a more general
framework for decorators.
- *
- * @todo The memory usage may need to be moved in closer to the test method
invocation so that as little code as possible
- * exists between it and the test or the results may be obscured. In
fact it certainly does as the teardown method
- * is getting called first. Wouldn't be a bad idea to move the timing
code in closer too.
- *
- * @todo Get rid of the delay logic. Will be replaced by throttle control.
- *
- * @author Rupert Smith
- */
-public class TKTestResult extends TestResult
-{
- /** Used for logging. */
- private static final Logger log = Logger.getLogger(TKTestResult.class);
-
- /** The delay between two tests. */
- private int delay = 0;
-
- /**
- * This flag indicates that the #completeTest method of the timing
controller has been called. Once this has
- * been called once, the end test event for the whole test method should
be ignored because tests have taken
- * charge of outputing their own timings.
- */
- private boolean completeTestUsed = false;
-
- /**
- * Thread locals to hold test start time for non-instrumented tests.
(Instrumented tests hold their own
- * measurement data).
- */
- // private Hashtable threadStartTimeMap = new Hashtable();
- private ThreadLocal<ThreadLocalSettings> threadLocals = new
ThreadLocal<ThreadLocalSettings>();
-
- /** Used to hold the current integer parameter to pass to parameterized
tests. This defaults to 1. */
- private int n = 1;
-
- /** The timing listeners. */
- private Collection<TKTestListener> tkListeners;
-
- /** The test case name. */
- private String testCaseName;
-
- /** Used to hold the current concurrency level, set by the [EMAIL
PROTECTED] ScaledTestDecorator}. */
- private int concurrencyLevel = 1;
-
- /** Flag used to indicate that this test result should attempt to complete
its current tests as soon as possible. */
- private boolean shutdownNow = false;
-
- /** Holds the parametes that the test is run with. */
- private Properties testParameters;
-
- /**
- * Creates a new TKTestResult object.
- *
- * @param delay A delay in milliseconds to introduce before every
test start.
- * @param testCaseName The name of the test case that this is the
TestResult object for.
- */
- public TKTestResult(int delay, String testCaseName)
- {
- super();
-
- /*log.debug("public TKTestResult(PrintStream writer, int " + delay +
", boolean " + verbose + ", String "
- + testCaseName + "): called");*/
-
- // Keep all the parameters that this is created with.
- this.delay = delay;
- this.testCaseName = testCaseName;
- }
-
- /**
- * Callback method use to inform this test result that a test will be
started. Waits for the configured delay time
- * if one has been set, starts the timer, then delegates to the super
class implementation.
- *
- * @param test The test to be started.
- */
- public void startTest(Test test)
- {
- // log.debug("public void startTest(Test test): called");
-
- // If a delay time has been specified then wait for that length of
time.
- if (this.delay > 0)
- {
- try
- {
- Thread.sleep(delay);
- }
- catch (InterruptedException e)
- {
- // Ignore, but restore the interrupted flag.
- Thread.currentThread().interrupt();
- }
- }
-
- // Create the thread local settings for the test.
- ThreadLocalSettings threadLocalSettings = new ThreadLocalSettings();
- threadLocals.set(threadLocalSettings);
-
- // Record the test start time against this thread for calculating the
test timing. (Consider using ThreadLocal
- // instead?)
- Long startTime = System.nanoTime();
- threadLocalSettings.startTime = startTime;
- // log.debug("startTime = " + startTime);
-
- // Check if the test is timing controller aware, in which case set up
a new timing controller and hold it
- // in the thread local settings.
- if (test instanceof TimingControllerAware)
- {
- TimingControllerAware controllerAware = (TimingControllerAware)
test;
- TimingControllerImpl controller =
- new TimingControllerImpl(this, test, startTime,
Thread.currentThread().getId());
- controllerAware.setTimingController(controller);
-
- threadLocalSettings.timingController = controller;
- }
-
- // Delegate to the super method to notify test event listeners.
- super.startTest(test);
- }
-
- /**
- * Callback method use to inform this result that a test was completed.
This calculates how long the test took
- * to run, then delegates to the super class implementation.
- *
- * @param test The test that has ended.
- */
- public void endTest(Test test)
- {
- // log.debug("public void endTest(Test test): called");
-
- long runTime = 0;
-
- // Recover the thread local settings.
- ThreadLocalSettings threadLocalSettings = threadLocals.get();
-
- // Check if the test is an instrumented test and get the timing
information from the instrumentation as this
- // will be more accurate.
- if (test instanceof InstrumentedTest)
- {
- InstrumentedTest iTest = (InstrumentedTest) test;
-
- // Calculate the test run time.
- runTime = iTest.getTestTime();
- // log.debug("runTime = " + runTime);
-
- // Calculate the test memory usage.
- long startMem = iTest.getTestStartMemory();
- long endMem = iTest.getTestEndMemory();
-
- // log.debug("startMem = " + startMem);
- // log.debug("endMem = " + endMem);
-
- // Inform any memory listeners of the test memory.
- if (tkListeners != null)
- {
- for (TKTestListener memoryListener : tkListeners)
- {
- memoryListener.memoryUsed(test, startMem, endMem, null);
- }
- }
- }
- else
- {
- // Calculate the test run time.
- long endTime = System.nanoTime();
- Long startTime = threadLocalSettings.startTime;
- runTime = endTime - startTime;
- // log.debug("runTime = " + runTime);
-
- threadLocals.remove();
- }
-
- // Output end test stats. This is only done when the tests have not
used the timing controller to output
- // mutiple timings.
- if (!completeTestUsed)
- {
- // Check if the test is an asymptotic test case and get its int
parameter if so.
- if (test instanceof AsymptoticTestCase)
- {
- AsymptoticTestCase pTest = (AsymptoticTestCase) test;
-
- // Set the parameter.
- int paramValue = pTest.getN();
-
- // Inform any parameter listeners of the test parameter.
- if (tkListeners != null)
- {
- for (TKTestListener parameterListener : tkListeners)
- {
- parameterListener.parameterValue(test, paramValue,
null);
- }
- }
- }
-
- // Inform any timing listeners of the test timing and concurrency
level.
- if (tkListeners != null)
- {
- for (TKTestListener tkListener : tkListeners)
- {
- TKTestListener next = tkListener;
-
- next.timing(test, runTime, null);
- next.concurrencyLevel(test, concurrencyLevel, null);
- }
- }
-
- // Call the super method to notify test event listeners of the end
event.
- super.endTest(test);
- }
- }
-
- /**
- * Gets the integer parameter to pass to parameterized test cases.
- *
- * @return The value of the integer parameter.
- */
- public int getN()
- {
- return n;
- }
-
- /**
- * Sets the integer parameter to pass to parameterized test cases.
- *
- * @param n The new value of the integer parameter.
- */
- public void setN(int n)
- {
- // log.debug("public void setN(int " + n + "): called");
-
- this.n = n;
- }
-
- /**
- * Adds a timing listener to pass all timing events to.
- *
- * @param listener The timing listener to register.
- */
- public void addTKTestListener(TKTestListener listener)
- {
- // Create the collection to hold the timing listeners if it does not
already exist.
- if (tkListeners == null)
- {
- tkListeners = new ArrayList<TKTestListener>();
- }
-
- // Keep the new timing listener.
- tkListeners.add(listener);
- }
-
- /**
- * Called by the test runner to notify this that a new test batch is being
begun. This method forwards this
- * notification to all batch listeners.
- */
- public void notifyStartBatch()
- {
- if (tkListeners != null)
- {
- for (TKTestListener batchListener : tkListeners)
- {
- batchListener.startBatch();
- }
- }
- }
-
- /**
- * Called by the test runner to notify this that the current test batch
has been ended. This method forwards this
- * notification to all batch listener.
- */
- public void notifyEndBatch()
- {
- // log.debug("public void notifyEndBatch(): called");
-
- if (tkListeners != null)
- {
- for (TKTestListener batchListener : tkListeners)
- {
- batchListener.endBatch(testParameters);
- }
- }
- }
-
- /**
- * Called by the test runner to notify this of the properties that the
test is using.
- *
- * @param properties The tests set/read properties.
- */
- public void notifyTestProperties(Properties properties)
- {
- // log.debug("public void notifyTestProperties(Properties properties):
called");
-
- this.testParameters = properties;
-
- /*
- if (tkListeners != null)
- {
- for (TKTestListener batchListener : tkListeners)
- {
- batchListener.properties(properties);
- }
- }
- */
- }
-
- /**
- * Intercepts the execution of a test case to pass the variable integer
parameter to a test if it is a parameterized
- * test case.
- *
- * @param test The test to run.
- */
- protected void run(final TestCase test)
- {
- // log.debug("protected void run(final TestCase test): called");
-
- // Check if the test case is a parameterized test and set its integer
parameter if so.
- if (test instanceof AsymptoticTestCase)
- {
- AsymptoticTestCase pTest = (AsymptoticTestCase) test;
-
- // Set up the integer parameter.
- pTest.setN(n);
- }
-
- // Delegate to the super method to run the test.
- super.run(test);
- }
-
- /**
- * Helper method that generats a String of verbose information about a
test. This includes the thread name, test
- * class name and test method name.
- *
- * @param test The test to generate the info string for.
- *
- * @return Returns a string with the thread name, test class name and test
method name.
- */
- protected String getTestInfo(Test test)
- {
- // log.debug("protected String getTestInfo(Test test): called");
-
- return "[" + Thread.currentThread().getName() + "@" +
test.getClass().getName() + "."
- + ((test instanceof TestCase) ? ((TestCase) test).getName() : "")
+ "]";
- }
-
- /**
- * Sets the concurrency level to pass into the test result.
- *
- * @param concurrencyLevel The concurrency level the tests are running out.
- */
- public void setConcurrencyLevel(int concurrencyLevel)
- {
- this.concurrencyLevel = concurrencyLevel;
- }
-
- /**
- * Tells this test result that it should stop running tests. Once this
method has been called this test result
- * will not start any new tests, and any tests that use the timing
controller will be passed interrupted exceptions,
- * to indicate that they should end immediately. Usually the caller of
this method will introduce a short wait
- * to allow an opporunity for running tests to complete, before forcing
the shutdown of the JVM.
- */
- public void shutdownNow()
- {
- log.debug("public void shutdownNow(): called on " + this);
-
- shutdownNow = true;
- }
-
- /**
- * Prints a string summary of this class, mainly for debugging purposes.
- *
- * @return A string summary of this class, mainly for debugging purposes.
- */
- public String toString()
- {
- return "TKTestResult@" + Integer.toString(hashCode(), 16) + ": [
testCaseName = " + testCaseName + ", n = " + n
- + ", tkListeners = " + tkListeners + " ]";
- }
-
- /**
- * Holds things that need to be kept on a per thread basis for each test
invocation, such as the test start
- * time and its timing controller.
- */
- private static class ThreadLocalSettings
- {
- /** Holds the test start time. */
- Long startTime;
-
- /** Holds the test threads timing controller. */
- TimingController timingController;
- }
-
- /**
- * Provides an implementation of the [EMAIL PROTECTED] TimingController}
interface that timing aware tests can use to call
- * back to reset timers, and register additional test timings.
- */
- private static class TimingControllerImpl implements TimingController
- {
- /** Holds an explicit reference to the test TKTestResult that created
this. */
- TKTestResult testResult;
-
- /** Holds a reference to the test that this is the timing controller
for. */
- Test test;
-
- /** Holds the start time for this timing controller. This gets reset
to now on each completed test. */
- long startTime;
-
- /**
- * Holds the thread id of the thread that started the test, so that
this controller may be called from other
- * threads but still identify itself correctly to [EMAIL PROTECTED]
TKTestListener}s as being associated with the
- * thread that called the test method.
- */
- long threadId;
-
- /**
- * Creates a timing controller on a specified TKTestResult and a test.
- *
- * @param testResult The TKTestResult that this controller
interacts with.
- * @param test The test that this is the timing controller
for.
- * @param startTime The test start time in nanoseconds.
- * @param threadId The thread id of the thread that is calling
the test method.
- */
- public TimingControllerImpl(TKTestResult testResult, Test test, long
startTime, long threadId)
- {
- this.testResult = testResult;
- this.test = test;
- this.startTime = startTime;
- this.threadId = threadId;
- }
-
- /**
- * Gets the timing controller associated with the current test thread.
Tests that use timing controller should
- * always get the timing controller from this method in the same
thread that called the setUp, tearDown or test
- * method. The controller returned by this method may be called from
any thread because it remembers the thread
- * id of the original test thread.
- *
- * @return The timing controller associated with the current test
thread.
- */
- public TimingController getControllerForCurrentThread()
- {
- // Recover the thread local settings and extract the timing
controller from them.
- ThreadLocalSettings threadLocalSettings =
testResult.threadLocals.get();
-
- return threadLocalSettings.timingController;
- }
-
- /**
- * Not implemented yet.
- *
- * @return Nothing.
- */
- public long suspend()
- {
- throw new RuntimeException("Method not implemented.");
- }
-
- /**
- * Not implemented yet.
- *
- * @return Nothing.
- */
- public long resume()
- {
- throw new RuntimeException("Method not implemented.");
- }
-
- /**
- * Resets the timer start time to now.
- *
- * @return The new value of the start time.
- */
- public long restart()
- {
- startTime = System.nanoTime();
-
- return startTime;
- }
-
- /**
- * Register an additional pass/fail for the current test. The test
result is assumed to apply to a test of
- * 'size' parmeter 1. Use the [EMAIL PROTECTED] #completeTest(boolean,
int)} method to register timings with parameters.
- *
- * @param testPassed Whether or not this timing is for a test pass or
fail.
- *
- * @throws InterruptedException If the test runner decides that
testing should stop it throws this exception to
- * indicate to the test method that it
should stop immediately.
- */
- public void completeTest(boolean testPassed) throws
InterruptedException
- {
- completeTest(testPassed, 1);
- }
-
- /**
- * Register an additional pass/fail for the current test. The test
result is applies to a test of the specified
- * 'size' parmeter.
- *
- * @param testPassed Whether or not this timing is for a test pass or
fail.
- * @param param The test parameter size for parameterized tests.
- *
- * @throws InterruptedException If the test runner decides that
testing should stop it throws this exception to
- * indicate to the test method that it
should stop immediately.
- */
- public void completeTest(boolean testPassed, int param) throws
InterruptedException
- {
- /*log.debug("public long completeTest(boolean testPassed = " +
testPassed + ", int param = " + param
- + "): called");*/
-
- // Calculate the test run time.
- long endTime = System.nanoTime();
- long runTime = endTime - startTime;
- // log.debug("runTime = " + runTime);
-
- // Reset the test start time to now, to reset the timer for the
next result.
- startTime = endTime;
-
- completeTest(testPassed, param, runTime);
- }
-
- /**
- * Register an additional pass/fail for the current test. The test
result is applies to a test of the specified
- * 'size' parmeter and allows the caller to sepecify the timing to log.
- *
- * @param testPassed Whether or not this timing is for a test pass or
fail.
- * @param param The test parameter size for parameterized tests.
- * @param timeNanos The time in nano-seconds to log the test result
with.
- *
- * @throws InterruptedException If the test runner decides that
testing should stop it throws this exception to
- * indicate to the test method that it
should stop immediately.
- */
- public void completeTest(boolean testPassed, int param, long
timeNanos) throws InterruptedException
- {
- log.debug("public void completeTest(boolean testPassed, int param,
long timeNanos): called");
- log.debug("testResult = " + testResult);
-
- // Tell the test result that completeTest has been used, so to not
register end test events for the whole
- // test method.
- testResult.completeTestUsed = true;
-
- // Inform any timing listeners of the test timings and parameters
and send an end test notification using
- // the thread id of the thread that started the test.
- if (testResult.tkListeners != null)
- {
- for (TKTestListener listener : testResult.tkListeners)
- {
- listener.reset(test, threadId);
- listener.timing(test, timeNanos, threadId);
- listener.parameterValue(test, param, threadId);
- listener.concurrencyLevel(test,
testResult.concurrencyLevel, threadId);
-
- if (!testPassed)
- {
- listener.addFailure(test, null, threadId);
- }
-
- listener.endTest(test, threadId);
- }
- }
-
- // log.debug("testResult.shutdownNow = " + testResult.shutdownNow);
-
- // Check if the test runner has been asked to shutdown and raise
an interuppted exception if so.
- if (testResult.shutdownNow)
- {
- // log.debug("The shutdown flag is set.");
-
- throw new InterruptedException("Attempting clean shutdown by
suspending current test.");
- }
- }
- }
-}
+/*
+ *
+ * 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.qpid.junit.extensions;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.junit.extensions.listeners.TKTestListener;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Properties;
+
+/**
+ * TKTestResult extends TestResult in order to calculate test timings, to pass
the variable integer parameter for
+ * parameterized test cases to those test cases and to introduce an optional
delay before test starts. Interested
+ * [EMAIL PROTECTED] TKTestListener}s may be attached to this and will be
informed of all relevant test statistics.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Calculate test timings.
+ * <tr><td> Inform timing listeners of timings.
+ * <tr><td> Inform memory listeners of memory readings.
+ * <tr><td> Inform parameters listeners of parameters.
+ * <tr><td> Pass the integer parameter to parameterized test cases.
+ * <tr><td> Provide verbose test information on test start and end.
+ * </table>
+ *
+ * @todo Move the verbose test information on test start/end into a test
listener instead. It confuses the intention
+ * of this class. Could also move the delay into a listener but that
seems less appropriate as it would be a
+ * side-effecting listener. Delay and timing calculation are fundamental
enough to this class.
+ *
+ * @todo The need for this class to act as a place-holder for the integer
parameter for parameterized test cases is
+ * because this behaviour has been factored out into a test decorator
class, see [EMAIL PROTECTED] AsymptoticTestDecorator}.
+ * The [EMAIL PROTECTED] AsymptoticTestDecorator#run} method takes a
TestResult as an argument and cannot easily get to the
+ * [EMAIL PROTECTED] AsymptoticTestCase} class other than through this
class. The option of using this class as a place hold
+ * for this value was chosen. Alternatively this class could provide a
method for decorators to access the
+ * underlying test case through and then leave the setting of this
parameter to the decorator which is a more
+ * natural home for this behaviour. It would also provide a more general
framework for decorators.
+ *
+ * @todo The memory usage may need to be moved in closer to the test method
invocation so that as little code as possible
+ * exists between it and the test or the results may be obscured. In
fact it certainly does as the teardown method
+ * is getting called first. Wouldn't be a bad idea to move the timing
code in closer too.
+ *
+ * @todo Get rid of the delay logic. Will be replaced by throttle control.
+ *
+ * @author Rupert Smith
+ */
+public class TKTestResult extends TestResult
+{
+ /** Used for logging. */
+ private static final Logger log = Logger.getLogger(TKTestResult.class);
+
+ /** The delay between two tests. */
+ private int delay = 0;
+
+ /**
+ * This flag indicates that the #completeTest method of the timing
controller has been called. Once this has
+ * been called once, the end test event for the whole test method should
be ignored because tests have taken
+ * charge of outputing their own timings.
+ */
+ private boolean completeTestUsed = false;
+
+ /**
+ * Thread locals to hold test start time for non-instrumented tests.
(Instrumented tests hold their own
+ * measurement data).
+ */
+ // private Hashtable threadStartTimeMap = new Hashtable();
+ private ThreadLocal<ThreadLocalSettings> threadLocals = new
ThreadLocal<ThreadLocalSettings>();
+
+ /** Used to hold the current integer parameter to pass to parameterized
tests. This defaults to 1. */
+ private int n = 1;
+
+ /** The timing listeners. */
+ private Collection<TKTestListener> tkListeners;
+
+ /** The test case name. */
+ private String testCaseName;
+
+ /** Used to hold the current concurrency level, set by the [EMAIL
PROTECTED] ScaledTestDecorator}. */
+ private int concurrencyLevel = 1;
+
+ /** Flag used to indicate that this test result should attempt to complete
its current tests as soon as possible. */
+ private boolean shutdownNow = false;
+
+ /** Holds the parametes that the test is run with. */
+ private Properties testParameters;
+
+ /**
+ * Creates a new TKTestResult object.
+ *
+ * @param delay A delay in milliseconds to introduce before every
test start.
+ * @param testCaseName The name of the test case that this is the
TestResult object for.
+ */
+ public TKTestResult(int delay, String testCaseName)
+ {
+ super();
+
+ /*log.debug("public TKTestResult(PrintStream writer, int " + delay +
", boolean " + verbose + ", String "
+ + testCaseName + "): called");*/
+
+ // Keep all the parameters that this is created with.
+ this.delay = delay;
+ this.testCaseName = testCaseName;
+ }
+
+ /**
+ * Callback method use to inform this test result that a test will be
started. Waits for the configured delay time
+ * if one has been set, starts the timer, then delegates to the super
class implementation.
+ *
+ * @param test The test to be started.
+ */
+ public void startTest(Test test)
+ {
+ // log.debug("public void startTest(Test test): called");
+
+ // If a delay time has been specified then wait for that length of
time.
+ if (this.delay > 0)
+ {
+ try
+ {
+ Thread.sleep(delay);
+ }
+ catch (InterruptedException e)
+ {
+ // Ignore, but restore the interrupted flag.
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ // Create the thread local settings for the test.
+ ThreadLocalSettings threadLocalSettings = new ThreadLocalSettings();
+ threadLocals.set(threadLocalSettings);
+
+ // Record the test start time against this thread for calculating the
test timing. (Consider using ThreadLocal
+ // instead?)
+ Long startTime = System.nanoTime();
+ threadLocalSettings.startTime = startTime;
+ // log.debug("startTime = " + startTime);
+
+ // Check if the test is timing controller aware, in which case set up
a new timing controller and hold it
+ // in the thread local settings.
+ if (test instanceof TimingControllerAware)
+ {
+ TimingControllerAware controllerAware = (TimingControllerAware)
test;
+ TimingControllerImpl controller =
+ new TimingControllerImpl(this, test, startTime,
Thread.currentThread().getId());
+ controllerAware.setTimingController(controller);
+
+ threadLocalSettings.timingController = controller;
+ }
+
+ // Delegate to the super method to notify test event listeners.
+ super.startTest(test);
+ }
+
+ /**
+ * Callback method use to inform this result that a test was completed.
This calculates how long the test took
+ * to run, then delegates to the super class implementation.
+ *
+ * @param test The test that has ended.
+ */
+ public void endTest(Test test)
+ {
+ // log.debug("public void endTest(Test test): called");
+
+ long runTime = 0;
+
+ // Recover the thread local settings.
+ ThreadLocalSettings threadLocalSettings = threadLocals.get();
+
+ // Check if the test is an instrumented test and get the timing
information from the instrumentation as this
+ // will be more accurate.
+ if (test instanceof InstrumentedTest)
+ {
+ InstrumentedTest iTest = (InstrumentedTest) test;
+
+ // Calculate the test run time.
+ runTime = iTest.getTestTime();
+ // log.debug("runTime = " + runTime);
+
+ // Calculate the test memory usage.
+ long startMem = iTest.getTestStartMemory();
+ long endMem = iTest.getTestEndMemory();
+
+ // log.debug("startMem = " + startMem);
+ // log.debug("endMem = " + endMem);
+
+ // Inform any memory listeners of the test memory.
+ if (tkListeners != null)
+ {
+ for (TKTestListener memoryListener : tkListeners)
+ {
+ memoryListener.memoryUsed(test, startMem, endMem, null);
+ }
+ }
+ }
+ else
+ {
+ // Calculate the test run time.
+ long endTime = System.nanoTime();
+ Long startTime = threadLocalSettings.startTime;
+ runTime = endTime - startTime;
+ // log.debug("runTime = " + runTime);
+
+ threadLocals.remove();
+ }
+
+ // Output end test stats. This is only done when the tests have not
used the timing controller to output
+ // mutiple timings.
+ if (!completeTestUsed)
+ {
+ // Check if the test is an asymptotic test case and get its int
parameter if so.
+ if (test instanceof AsymptoticTestCase)
+ {
+ AsymptoticTestCase pTest = (AsymptoticTestCase) test;
+
+ // Set the parameter.
+ int paramValue = pTest.getN();
+
+ // Inform any parameter listeners of the test parameter.
+ if (tkListeners != null)
+ {
+ for (TKTestListener parameterListener : tkListeners)
+ {
+ parameterListener.parameterValue(test, paramValue,
null);
+ }
+ }
+ }
+
+ // Inform any timing listeners of the test timing and concurrency
level.
+ if (tkListeners != null)
+ {
+ for (TKTestListener tkListener : tkListeners)
+ {
+ TKTestListener next = tkListener;
+
+ next.timing(test, runTime, null);
+ next.concurrencyLevel(test, concurrencyLevel, null);
+ }
+ }
+
+ // Call the super method to notify test event listeners of the end
event.
+ super.endTest(test);
+ }
+ }
+
+ /**
+ * Gets the integer parameter to pass to parameterized test cases.
+ *
+ * @return The value of the integer parameter.
+ */
+ public int getN()
+ {
+ return n;
+ }
+
+ /**
+ * Sets the integer parameter to pass to parameterized test cases.
+ *
+ * @param n The new value of the integer parameter.
+ */
+ public void setN(int n)
+ {
+ // log.debug("public void setN(int " + n + "): called");
+
+ this.n = n;
+ }
+
+ /**
+ * Adds a timing listener to pass all timing events to.
+ *
+ * @param listener The timing listener to register.
+ */
+ public void addTKTestListener(TKTestListener listener)
+ {
+ // Create the collection to hold the timing listeners if it does not
already exist.
+ if (tkListeners == null)
+ {
+ tkListeners = new ArrayList<TKTestListener>();
+ }
+
+ // Keep the new timing listener.
+ tkListeners.add(listener);
+ }
+
+ /**
+ * Called by the test runner to notify this that a new test batch is being
begun. This method forwards this
+ * notification to all batch listeners.
+ */
+ public void notifyStartBatch()
+ {
+ if (tkListeners != null)
+ {
+ for (TKTestListener batchListener : tkListeners)
+ {
+ batchListener.startBatch();
+ }
+ }
+ }
+
+ /**
+ * Called by the test runner to notify this that the current test batch
has been ended. This method forwards this
+ * notification to all batch listener.
+ */
+ public void notifyEndBatch()
+ {
+ // log.debug("public void notifyEndBatch(): called");
+
+ if (tkListeners != null)
+ {
+ for (TKTestListener batchListener : tkListeners)
+ {
+ batchListener.endBatch(testParameters);
+ }
+ }
+ }
+
+ /**
+ * Called by the test runner to notify this of the properties that the
test is using.
+ *
+ * @param properties The tests set/read properties.
+ */
+ public void notifyTestProperties(Properties properties)
+ {
+ // log.debug("public void notifyTestProperties(Properties properties):
called");
+
+ this.testParameters = properties;
+
+ /*
+ if (tkListeners != null)
+ {
+ for (TKTestListener batchListener : tkListeners)
+ {
+ batchListener.properties(properties);
+ }
+ }
+ */
+ }
+
+ /**
+ * Intercepts the execution of a test case to pass the variable integer
parameter to a test if it is a parameterized
+ * test case.
+ *
+ * @param test The test to run.
+ */
+ protected void run(final TestCase test)
+ {
+ // log.debug("protected void run(final TestCase test): called");
+
+ // Check if the test case is a parameterized test and set its integer
parameter if so.
+ if (test instanceof AsymptoticTestCase)
+ {
+ AsymptoticTestCase pTest = (AsymptoticTestCase) test;
+
+ // Set up the integer parameter.
+ pTest.setN(n);
+ }
+
+ // Delegate to the super method to run the test.
+ super.run(test);
+ }
+
+ /**
+ * Helper method that generats a String of verbose information about a
test. This includes the thread name, test
+ * class name and test method name.
+ *
+ * @param test The test to generate the info string for.
+ *
+ * @return Returns a string with the thread name, test class name and test
method name.
+ */
+ protected String getTestInfo(Test test)
+ {
+ // log.debug("protected String getTestInfo(Test test): called");
+
+ return "[" + Thread.currentThread().getName() + "@" +
test.getClass().getName() + "."
+ + ((test instanceof TestCase) ? ((TestCase) test).getName() : "")
+ "]";
+ }
+
+ /**
+ * Sets the concurrency level to pass into the test result.
+ *
+ * @param concurrencyLevel The concurrency level the tests are running out.
+ */
+ public void setConcurrencyLevel(int concurrencyLevel)
+ {
+ this.concurrencyLevel = concurrencyLevel;
+ }
+
+ /**
+ * Tells this test result that it should stop running tests. Once this
method has been called this test result
+ * will not start any new tests, and any tests that use the timing
controller will be passed interrupted exceptions,
+ * to indicate that they should end immediately. Usually the caller of
this method will introduce a short wait
+ * to allow an opporunity for running tests to complete, before forcing
the shutdown of the JVM.
+ */
+ public void shutdownNow()
+ {
+ log.debug("public void shutdownNow(): called on " + this);
+
+ shutdownNow = true;
+ }
+
+ /**
+ * Prints a string summary of this class, mainly for debugging purposes.
+ *
+ * @return A string summary of this class, mainly for debugging purposes.
+ */
+ public String toString()
+ {
+ return "TKTestResult@" + Integer.toString(hashCode(), 16) + ": [
testCaseName = " + testCaseName + ", n = " + n
+ + ", tkListeners = " + tkListeners + " ]";
+ }
+
+ /**
+ * Holds things that need to be kept on a per thread basis for each test
invocation, such as the test start
+ * time and its timing controller.
+ */
+ private static class ThreadLocalSettings
+ {
+ /** Holds the test start time. */
+ Long startTime;
+
+ /** Holds the test threads timing controller. */
+ TimingController timingController;
+ }
+
+ /**
+ * Provides an implementation of the [EMAIL PROTECTED] TimingController}
interface that timing aware tests can use to call
+ * back to reset timers, and register additional test timings.
+ */
+ private static class TimingControllerImpl implements TimingController
+ {
+ /** Holds an explicit reference to the test TKTestResult that created
this. */
+ TKTestResult testResult;
+
+ /** Holds a reference to the test that this is the timing controller
for. */
+ Test test;
+
+ /** Holds the start time for this timing controller. This gets reset
to now on each completed test. */
+ long startTime;
+
+ /**
+ * Holds the thread id of the thread that started the test, so that
this controller may be called from other
+ * threads but still identify itself correctly to [EMAIL PROTECTED]
TKTestListener}s as being associated with the
+ * thread that called the test method.
+ */
+ long threadId;
+
+ /**
+ * Creates a timing controller on a specified TKTestResult and a test.
+ *
+ * @param testResult The TKTestResult that this controller
interacts with.
+ * @param test The test that this is the timing controller
for.
+ * @param startTime The test start time in nanoseconds.
+ * @param threadId The thread id of the thread that is calling
the test method.
+ */
+ public TimingControllerImpl(TKTestResult testResult, Test test, long
startTime, long threadId)
+ {
+ this.testResult = testResult;
+ this.test = test;
+ this.startTime = startTime;
+ this.threadId = threadId;
+ }
+
+ /**
+ * Gets the timing controller associated with the current test thread.
Tests that use timing controller should
+ * always get the timing controller from this method in the same
thread that called the setUp, tearDown or test
+ * method. The controller returned by this method may be called from
any thread because it remembers the thread
+ * id of the original test thread.
+ *
+ * @return The timing controller associated with the current test
thread.
+ */
+ public TimingController getControllerForCurrentThread()
+ {
+ // Recover the thread local settings and extract the timing
controller from them.
+ ThreadLocalSettings threadLocalSettings =
testResult.threadLocals.get();
+
+ return threadLocalSettings.timingController;
+ }
+
+ /**
+ * Not implemented yet.
+ *
+ * @return Nothing.
+ */
+ public long suspend()
+ {
+ throw new RuntimeException("Method not implemented.");
+ }
+
+ /**
+ * Not implemented yet.
+ *
+ * @return Nothing.
+ */
+ public long resume()
+ {
+ throw new RuntimeException("Method not implemented.");
+ }
+
+ /**
+ * Resets the timer start time to now.
+ *
+ * @return The new value of the start time.
+ */
+ public long restart()
+ {
+ startTime = System.nanoTime();
+
+ return startTime;
+ }
+
+ /**
+ * Register an additional pass/fail for the current test. The test
result is assumed to apply to a test of
+ * 'size' parmeter 1. Use the [EMAIL PROTECTED] #completeTest(boolean,
int)} method to register timings with parameters.
+ *
+ * @param testPassed Whether or not this timing is for a test pass or
fail.
+ *
+ * @throws InterruptedException If the test runner decides that
testing should stop it throws this exception to
+ * indicate to the test method that it
should stop immediately.
+ */
+ public void completeTest(boolean testPassed) throws
InterruptedException
+ {
+ completeTest(testPassed, 1);
+ }
+
+ /**
+ * Register an additional pass/fail for the current test. The test
result is applies to a test of the specified
+ * 'size' parmeter.
+ *
+ * @param testPassed Whether or not this timing is for a test pass or
fail.
+ * @param param The test parameter size for parameterized tests.
+ *
+ * @throws InterruptedException If the test runner decides that
testing should stop it throws this exception to
+ * indicate to the test method that it
should stop immediately.
+ */
+ public void completeTest(boolean testPassed, int param) throws
InterruptedException
+ {
+ /*log.debug("public long completeTest(boolean testPassed = " +
testPassed + ", int param = " + param
+ + "): called");*/
+
+ // Calculate the test run time.
+ long endTime = System.nanoTime();
+ long runTime = endTime - startTime;
+ // log.debug("runTime = " + runTime);
+
+ // Reset the test start time to now, to reset the timer for the
next result.
+ startTime = endTime;
+
+ completeTest(testPassed, param, runTime);
+ }
+
+ /**
+ * Register an additional pass/fail for the current test. The test
result is applies to a test of the specified
+ * 'size' parmeter and allows the caller to sepecify the timing to log.
+ *
+ * @param testPassed Whether or not this timing is for a test pass or
fail.
+ * @param param The test parameter size for parameterized tests.
+ * @param timeNanos The time in nano-seconds to log the test result
with.
+ *
+ * @throws InterruptedException If the test runner decides that
testing should stop it throws this exception to
+ * indicate to the test method that it
should stop immediately.
+ */
+ public void completeTest(boolean testPassed, int param, long
timeNanos) throws InterruptedException
+ {
+ log.debug("public void completeTest(boolean testPassed, int param,
long timeNanos): called");
+ log.debug("testResult = " + testResult);
+
+ // Tell the test result that completeTest has been used, so to not
register end test events for the whole
+ // test method.
+ testResult.completeTestUsed = true;
+
+ // Inform any timing listeners of the test timings and parameters
and send an end test notification using
+ // the thread id of the thread that started the test.
+ if (testResult.tkListeners != null)
+ {
+ for (TKTestListener listener : testResult.tkListeners)
+ {
+ listener.reset(test, threadId);
+ listener.timing(test, timeNanos, threadId);
+ listener.parameterValue(test, param, threadId);
+ listener.concurrencyLevel(test,
testResult.concurrencyLevel, threadId);
+
+ if (!testPassed)
+ {
+ listener.addFailure(test, null, threadId);
+ }
+
+ listener.endTest(test, threadId);
+ }
+ }
+
+ // log.debug("testResult.shutdownNow = " + testResult.shutdownNow);
+
+ // Check if the test runner has been asked to shutdown and raise
an interuppted exception if so.
+ if (testResult.shutdownNow)
+ {
+ // log.debug("The shutdown flag is set.");
+
+ throw new InterruptedException("Attempting clean shutdown by
suspending current test.");
+ }
+ }
+ }
+}
Propchange:
incubator/qpid/trunk/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java
------------------------------------------------------------------------------
svn:eol-style = native