performancetestrunner.java
来自「Java mulitplayer strategy game. Adaptati」· Java 代码 · 共 437 行
JAVA
437 行
/*
* Created on 2005-09-23
* $Id: PerformanceTestRunner.java,v 1.5 2005/10/14 20:26:12 overmindx Exp $
*/
package net.sf.jawp.util.test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* <p>
* A runner for performance test cases. This classes works with implementations
* of {@link TestCase} interfaces.
* </p>
*
* TODO maciek: this class is in design stage and it's API may change!
*
* @author Maciej Malecki
* @version $Revision: 1.5 $
*/
public class PerformanceTestRunner
{
private final int load;
// TODO maciek: this is sort of hack!
private int counter;
/**
* Creates new instance of PerformanceTestRunner.
*
* @param load
* parameter used for load testing
*/
public PerformanceTestRunner(final int load)
{
this.load = load;
}
/**
* Runs specified test case.
*
* @param testCaseClass
* test case to be run
* @return statistics, never null
*/
public Statistics run(final Class<? extends TestCase> testCaseClass)
{
try
{
final TestCase testCase = testCaseClass.newInstance();
final Method[] methods = testCaseClass.getMethods();
final Statistics statistics = new Statistics(testCase.getClass()
.getName());
testCase.init();
try
{
for (Method method : methods)
{
final PerformanceTestMethod ptm = method
.getAnnotation(PerformanceTestMethod.class);
if (ptm != null)
{
testCase.before();
try
{
statistics.add(runMethodThreads(testCase, method,
ptm));
}
finally
{
testCase.after();
}
}
}
}
finally
{
testCase.destroy();
}
return statistics;
}
catch (final InstantiationException e)
{
throw new RuntimeException(e);
}
catch (final IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
private synchronized boolean dec()
{
--counter;
return counter == 0;
}
private void setCounter(final int newCounter)
{
counter = newCounter;
}
private StatisticsItem runMethodThreads(final TestCase testCase,
final Method method, final PerformanceTestMethod ptm)
{
setCounter(load);
if (load <= 1)
{
final long iterations = runMethod(testCase, method, ptm);
return new StatisticsItem(method, ptm, iterations, iterations,
iterations, iterations);
}
final Object monitor = new Object();
final TestThread[] threads = new TestThread[load];
for (int i = 0; i < load; ++i)
{
threads[i] = new TestThread(monitor, testCase, method, ptm);
threads[i].start();
}
sleepAndNotify(monitor);
long total = 0L;
long min = Long.MAX_VALUE;
long max = 0L;
for (TestThread thread : threads)
{
final long iterations = thread.getIterations();
total += iterations;
if (iterations < min)
{
min = iterations;
}
if (iterations > max)
{
max = iterations;
}
}
return new StatisticsItem(method, ptm, total, total / load, min, max);
}
private void sleepAndNotify(final Object monitor)
{
try
{
Thread.sleep(200);
}
catch (final InterruptedException e1)
{
// specjalnie
}
synchronized (monitor)
{
monitor.notifyAll();
try
{
monitor.wait();
}
catch (final InterruptedException e)
{
// specjalnie
}
}
}
private long runMethod(final TestCase testCase, final Method method,
final PerformanceTestMethod ptm)
{
try
{
final long endTime = System.currentTimeMillis() + ptm.time();
long iterations = 0;
while (System.currentTimeMillis() < endTime)
{
method.invoke(testCase);
++iterations;
}
return iterations;
}
catch (final IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (final InvocationTargetException e)
{
throw new RuntimeException(e);
}
}
private final class TestThread extends Thread
{
private final Object monitor;
private final Method method;
private final TestCase testCase;
private final PerformanceTestMethod ptm;
private long iterations = 0;
public TestThread(final Object monitor, final TestCase testCase,
final Method method, final PerformanceTestMethod ptm)
{
this.monitor = monitor;
this.method = method;
this.testCase = testCase;
this.ptm = ptm;
}
/**
* {@inheritDoc}
*/
@Override
public void run()
{
synchronized (monitor)
{
try
{
monitor.wait();
}
catch (final InterruptedException e)
{
// specjalnie
}
}
iterations = runMethod(testCase, method, ptm);
if (dec())
{
// if this is the last thread, notify the runner that it's
// finnished
synchronized (monitor)
{
monitor.notifyAll();
}
}
}
/**
* Returns the iterations.
*
* @return the value of iterations
*/
protected long getIterations()
{
return iterations;
}
}
/**
* This is a statistics object which contains results of performance tests
* for particular test case.
*
* @author maciek
* @version $Revision: 1.5 $
*/
public final class Statistics
{
private final String testCaseClass;
private final List<StatisticsItem> items = new ArrayList<StatisticsItem>();
private Statistics(final String testCaseClass)
{
this.testCaseClass = testCaseClass;
}
/**
*
* @return list of detailed statistics per each test method
*/
public List<StatisticsItem> items()
{
return Collections.unmodifiableList(items);
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
final StringBuffer sb = new StringBuffer();
sb.append("Test case ");
sb.append(testCaseClass);
sb.append("\n");
for (StatisticsItem item : items)
{
sb.append(" ");
sb.append(item.toString());
sb.append("\n");
}
return sb.toString();
}
/**
* Returns the testCaseClass.
*
* @return the value of testCaseClass
*/
public String getTestCaseClass()
{
return testCaseClass;
}
private void add(final StatisticsItem item)
{
items.add(item);
}
}
/**
* A statistic object describing result of performance test for particular
* test method.
*
* @author maciek
* @version $Revision: 1.5 $
*/
public final class StatisticsItem
{
private String methodName;
private String comment;
private long total;
private long average;
private long min;
private long max;
private int threads;
private StatisticsItem(final Method method,
final PerformanceTestMethod ptm, final long total,
final long average, final long min, final long max)
{
this.methodName = method.getName();
this.comment = ptm.comment();
this.total = total;
this.average = average;
this.threads = load;
this.min = min;
this.max = max;
}
/**
* Returns the comment.
*
* @return the value of comment
*/
public String getComment()
{
return comment;
}
/**
* Returns the executions.
*
* @return the value of executions
*/
public long getTotal()
{
return total;
}
/**
* Returns the methodName.
*
* @return the value of methodName
*/
public String getMethodName()
{
return methodName;
}
/**
* Returns the threads.
*
* @return the value of threads
*/
public int getThreads()
{
return threads;
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
final StringBuffer sb = new StringBuffer();
sb.append("Method " + methodName);
sb.append(" (" + comment);
sb.append(") load: " + threads);
sb.append(", total: " + total);
sb.append(", average: " + average);
sb.append(", min: " + min);
sb.append(", max: " + max);
return sb.toString();
}
/**
* Returns the max.
*
* @return the value of max
*/
public long getMax()
{
return max;
}
/**
* Returns the min.
*
* @return the value of min
*/
public long getMin()
{
return min;
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?