/*
* RHQ Management Platform
* Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.server.test;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testng.ITestResult;
import org.rhq.helpers.perftest.support.reporting.PerformanceReportExporter;
import org.rhq.helpers.perftest.support.testng.PerformanceReporting;
/**
* Helper that introduces timing functionality on top of the Abstract EJB tests.
*
* @author Heiko W. Rupp
*/
public class AbstractEJB3PerformanceTest extends AbstractEJB3Test {
private static final Log log = LogFactory.getLog("TIMING_INFO");
private static final String DEFAULT = "-default-";
private Map<String,Long> timings ;
private Map<String,Long> startTime ;
protected void startTiming(String name) {
if (startTime==null) {
System.err.println("startTime is null, setupTimings was not called by TestNG!!");
return;
}
long now = System.currentTimeMillis();
startTime.put(name,now);
}
protected void endTiming(String name) {
boolean found = startTime.containsKey(name);
assert found : "No start time information for name [" + name + "] found - did you call startTiming()?";
long now = System.currentTimeMillis();
long start = startTime.get(name);
long duration = (now - start);
if (timings.containsKey(name)) {
long timing = timings.get(name);
timing+=duration;
timings.put(name,timing);
}
else {
timings.put(name,duration);
}
}
protected void startTiming() {
startTiming(DEFAULT);
}
protected void endTiming() {
endTiming(DEFAULT);
}
protected long getTiming(String name) {
if (timings.containsKey(name)) {
return timings.get(name);
}
else
return -1;
}
protected long getTiming() {
return getTiming(DEFAULT);
}
@Override
protected void afterMethod(ITestResult result, Method meth) {
if (!inContainer()) {
return;
}
printTimings(meth.getName());
Class clazz = meth.getDeclaringClass();
PerformanceReporting pr = (PerformanceReporting) clazz.getAnnotation(PerformanceReporting.class);
if (pr != null) {
String file = pr.baseFilename();
Class<? extends PerformanceReportExporter> exporterClazz = pr.exporter();
try {
PerformanceReportExporter exporter = exporterClazz.newInstance();
exporter.setBaseFile(file);
exporter.setRolling(pr.rolling());
exporter.export(timings,result);
}
catch (Throwable e) {
System.err.println("Error writing to reporting file " + file +" : " + e.getMessage());
e.printStackTrace();
}
}
System.out.flush();
System.err.flush();
timings.clear();
startTime.clear();
}
// @BeforeMethod
protected void setupTimings(Method meth) {
timings = new HashMap<String, Long>();
startTime = new HashMap<String, Long>();
}
protected void printTimings(String testName) {
System.out.println("=== " + testName + " ===");
Set<Map.Entry<String,Long>> data = timings.entrySet();
SortedSet <Map.Entry<String,Long>> sorted = new TreeSet<Map.Entry<String,Long>>(new Comparator<Map.Entry<String,Long>>() {
public int compare(Map.Entry<String,Long> item1, Map.Entry<String,Long> item2) {
return item1.getKey().compareTo(item2.getKey());
}
});
sorted.addAll(data);
long summaryTime = 0L;
for (Map.Entry<String,Long> item : sorted) {
log.info(":| " + item.getKey() + " => " + item.getValue());
System.out.println(":| " + item.getKey() + " => " + item.getValue());
summaryTime += item.getValue();
}
System.out.println("Total: " + summaryTime + " ms");
}
protected void assertTiming(String name, long maxDuration) {
boolean found = timings.containsKey(name);
assert found : "No timing information for name [" + name + "] found";
long duration = timings.get(name);
assert duration < maxDuration : "Execution took longer than given max ( " + duration + " > " + maxDuration + ")";
}
protected void assertTiming(long maxDuration) {
assertTiming(DEFAULT,maxDuration);
}
/**
* Make sure the passed value is within a band of <code>[0.80* x, 1.2*x]</code> with
* <code>x = ( ref * multiplier )</code>.
* @param ref base value to calculate the reference from
* @param value value to compare to the band
* @param multiplier multiplier for the base value of the band.
* @param text text to prepend to a line if check fails.
*/
protected void assertLinear(long ref,long value, double multiplier, String text ) {
System.out.println(">>> assertLinear " + text + " " + ref + ", " + value + ", " + multiplier );
long low = (long) (ref * multiplier * 0.80);
long hi = (long) (ref * multiplier * 1.2);
// comment out the low check for now TODO reenable when we know more
// assert value >= low : text + " [low] Val2 (" + value + ") is not > " + low;
// assert value <= hi : text + " [hi] Val2 (" + value + ") is not < " + hi;
}
}