解惑

解己之惑,解人之惑

性能测试

上周基于JUnit写了个简单的性能测试框架,其实就是用了下Annotation,发现还是很好用的。

/**
 * Performance test annotation.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PerformanceTest
{
    public String name() default "";
    public int times();
    public boolean stopOnError() default false;
}

/**
 * Base function for performance test.
 */
public class BasePerformanceTest
{
    protected Logger logger = Logger.getLogger(this.getClass());
    List<PerformanceData> performanceData = new ArrayList<PerformanceData>();

    @BeforeClass
    public static void init()
    {
        ServiceUtil.init();
    }

    @AfterClass
    public static void report()
    {
        PerformanceReportManager.generatePerformanceReport();
    }

    private void execute(Method method)
    {
        PerformanceTest performanceTest = method.getAnnotation(PerformanceTest.class);
        String name = performanceTest.name();
        if (name.equals(""))
        {
            name = method.getName();
        }
        logger.debug("Start execute test case"+name);
        int times = performanceTest.times();
        boolean stopOnError = performanceTest.stopOnError();
        PerformanceData data = new PerformanceData(name, times);
        performanceData.add(data);
        for (int i = 0; i < times; i++)
        {
            long start = System.currentTimeMillis();
            boolean error = false;
            try
            {
                method.invoke(this);
            }
            catch (Throwable t)
            {
                logger.error("Execute performance test" + name + " error.", t);
                error = true;
                if (stopOnError)
                {
                    logger.error("Stop execute performance test" + name + " because of error.");
                    return;
                }
            }
            long end = System.currentTimeMillis();
            data.addData(end – start);
            if (error)
            {
                data.addError();
            }
        }
    }

    @Test
    public void doPerformanceTests() throws Throwable
    {
        Class c = this.getClass();
        PerformanceReportManager.addData(c, performanceData);
        Method[] methods = c.getMethods();
        for (Method method : methods)
        {
            if (method.isAnnotationPresent(PerformanceTest.class))
            {
                if (method.getParameterTypes().length == 0)
                {
                    execute(method);
                }
                else
                {
                    logger.warn("Can not support execute performance test method with parameters:" + method);
                }
            }
        }
    }

}

/**
 * Performance data.
 */
public class PerformanceData
{
    private String name;
    private int times;
    private long[] data;
    private int index = 0;
    private long max = Long.MIN_VALUE;
    private long min = Long.MAX_VALUE;
    private long total = 0;
    private int errors;

    public PerformanceData(String name, int times)
    {
        this.name = name;
        this.times = times;
        data = new long[times];
    }

    public String getName()
    {
        return name;
    }

    public int getTimes()
    {
        return times;
    }

    public long[] getData()
    {
        return data;
    }

    public void addData(long data)
    {
        this.data[index++] = data;
        max = Math.max(max, data);
        min = Math.min(min, data);
        total += data;
    }

    public long getMax()
    {
        return max;
    }

    public long getMin()
    {
        return min;
    }

    public long getAveg()
    {
        if (times == 0)
        {
            return 0;
        }
        return getTotal() / times;
    }

    public long getTotal()
    {
        return total;
    }

    public int getErrors()
    {
        return errors;
    }

    public void addError()
    {
        errors++;
    }
}

/**
 * Performance report manager.
 */
public class PerformanceReportManager
{
    private static Map<Class, List<PerformanceData>> allData = new HashMap<Class, List<PerformanceData>>();
    private static PerformanceReporter performanceReporter = new DirectOutputPerformanceReporter();

    public static void addData(Class c, List<PerformanceData> data)
    {
        allData.put(c, data);
    }

    public static void generatePerformanceReport()
    {
        performanceReporter.generateReport(allData);
    }

    public static PerformanceReporter getPerformanceReporter()
    {
        return performanceReporter;
    }

    public static void setPerformanceReporter(PerformanceReporter performanceReporter)
    {
        PerformanceReportManager.performanceReporter = performanceReporter;
    }
}

public interface PerformanceReporter
{
    public void generateReport(Map<Class, List<PerformanceData>> allData);
}

(Visited 206 times, 1 visits today)

1 Comment

  1. :em20: 沙发

发表评论

电子邮件地址不会被公开。 必填项已用*标注

© 2020 解惑

本主题由Anders Noren提供向上 ↑