/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.perf.test;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.text.NumberFormat;
import javax.naming.InitialContext;
import org.jboss.test.perf.interfaces.Probe;
import org.jboss.test.perf.interfaces.ProbeHome;
import org.jboss.test.perf.interfaces.TxSession;
import org.jboss.test.perf.interfaces.TxSessionHome;
/** An MBean that tests intra-VM EJB call invocation overhead. The runTests
*operation accepts the number of iterations and returns a simple html report
*showing the output of each test run.
@author Scott.Stark@jboss.org
@version $Revision: 81036 $
*/
public class PerfTest implements PerfTestMBean
{
private static NumberFormat fmt = NumberFormat.getInstance();
static
{
fmt.setMinimumFractionDigits(3);
fmt.setMaximumFractionDigits(3);
}
int iterationCount;
public String runTests(int iterationCount)
{
StringBuffer results = new StringBuffer("<h1>PerfTest.results</h1><pre>\n");
this.iterationCount = iterationCount;
int testCount = 0;
int failureCount = 0;
// Print out some codebase info
URL thisURL = getClass().getProtectionDomain().getCodeSource().getLocation();
results.append("\nPertTest.ClassLoader="+getClass().getClassLoader());
results.append("\nPertTest.codebase="+thisURL);
try
{
testCount ++;
testTimings(results);
}
catch(Throwable e)
{
failureCount ++;
formatException(e, "testTimings", results);
}
results.append('\n');
try
{
testCount ++;
testTimingsCMT(results);
}
catch(Throwable e)
{
failureCount ++;
formatException(e, "testTimingsCMT", results);
}
results.append('\n');
try
{
testCount ++;
testTxTimings(results);
}
catch(Throwable e)
{
failureCount ++;
formatException(e, "testTxTimings", results);
}
results.append("\nTotal tests: "+testCount);
results.append("\nTotal failures: "+failureCount);
results.append("\n<pre>");
return results.toString();
}
public void testTimings(StringBuffer results) throws Exception
{
results.append("\n+++ testTimings()");
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(ProbeHome.class.getClassLoader());
try
{
Object obj = new InitialContext().lookup("perf.Probe");
// Print out some codebase info for the ProbeHome
Class homeClass = obj.getClass();
ClassLoader cl = homeClass.getClassLoader();
results.append("\nProbeHome.ClassLoader="+cl);
ClassLoader parent = cl;
while( parent != null )
{
results.append("\n.."+parent);
if( parent instanceof URLClassLoader )
{
URLClassLoader ucl = (URLClassLoader) parent;
URL[] urls = ucl.getURLs();
int length = urls != null ? urls.length : 0;
for(int u = 0; u < length; u ++)
{
results.append("\n...."+urls[u]);
}
}
if( parent != null )
parent = parent.getParent();
}
results.append("\nProbeHome Interfaces:");
Class[] ifaces = homeClass.getInterfaces();
for(int i = 0; i < ifaces.length; i ++)
{
results.append("\n++"+ifaces[i]);
ProtectionDomain pd = ifaces[i].getProtectionDomain();
CodeSource cs = pd.getCodeSource();
if( cs != null )
results.append("\n++++CodeSource: "+cs);
else
results.append("\n++++Null CodeSource");
}
CodeSource homeCS = ProbeHome.class.getProtectionDomain().getCodeSource();
if( homeCS != null )
results.append("\nPerfTest ProbHome CodeSource: "+homeCS);
else
results.append("\nPerfTest ProbHome CodeSource is NULL");
ProbeHome home = (ProbeHome) obj;
results.append("\n\nFound ProbeHome @ jndiName=Probe");
Probe bean = home.create();
results.append("\nCreated Probe");
warmup(bean, results);
noop(bean, results);
ping(bean, results);
echo(bean, results);
}
finally
{
Thread.currentThread().setContextClassLoader(oldCl);
} // end of finally
}
public void testTimingsCMT(StringBuffer results) throws Exception
{
results.append("\n+++ testTimingsCMT()");
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(ProbeHome.class.getClassLoader());
try
{
Object obj = new InitialContext().lookup("perf.ProbeCMT");
ProbeHome home = (ProbeHome) obj;
results.append("\nFound ProbeHome @ jndiName=ProbeCMT");
Probe bean = home.create();
results.append("\nCreated ProbeCMT");
warmup(bean, results);
noop(bean, results);
ping(bean, results);
echo(bean, results);
}
finally
{
Thread.currentThread().setContextClassLoader(oldCl);
} // end of finally
}
public void testTxTimings(StringBuffer results) throws Exception
{
results.append("\n+++ testTxTimings()");
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(TxSessionHome.class.getClassLoader());
try
{
Object obj = new InitialContext().lookup("perf.TxSession");
TxSessionHome home = (TxSessionHome) obj;
results.append("\nFound TxSession @ jndiName=TxSession");
TxSession bean = home.create();
results.append("\nCreated TxSession");
txRequired(bean, results);
txRequiresNew(bean, results);
txSupports(bean, results);
txNotSupported(bean, results);
requiredToSupports(bean, results);
requiredToMandatory(bean, results);
requiredToRequiresNew(bean, results);
}
finally
{
Thread.currentThread().setContextClassLoader(oldCl);
} // end of finally
}
private void warmup(Probe bean, StringBuffer results) throws Exception
{
bean.noop();
bean.ping("Ping");
bean.echo("Echo");
}
private void noop(Probe bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" noop() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
bean.noop();
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" noop() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/noop");
}
private void ping(Probe bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" ping(PING) invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
bean.ping("PING");
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" ping() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/ping");
}
private void echo(Probe bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" echo(ECHO) invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.echo("ECHO");
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" echo() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/echo");
}
private void txRequired(TxSession bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" txRequired() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.txRequired();
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" txRequired() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/txRequired");
}
private void txRequiresNew(TxSession bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" txRequired() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.txRequiresNew();
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" txRequiresNew() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/txRequiresNew");
}
private void txSupports(TxSession bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" txSupports() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.txSupports();
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" txSupports() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/txSupports");
}
private void txNotSupported(TxSession bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" txNotSupported() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.txNotSupported();
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" txNotSupported() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/txNotSupported");
}
private void requiredToSupports(TxSession bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" requiredToSupports() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.requiredToSupports();
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" requiredToSupports() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/requiredToSupports");
}
private void requiredToMandatory(TxSession bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" requiredToMandatory() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.requiredToMandatory();
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" requiredToMandatory() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/requiredToMandatory");
}
private void requiredToRequiresNew(TxSession bean, StringBuffer results) throws Exception
{
results.append("\nStarting "+iterationCount+" requiredToRequiresNew() invocations");
long start = System.currentTimeMillis();
for(int n = 0; n < iterationCount; n ++)
{
String echo = bean.requiredToRequiresNew();
}
long end = System.currentTimeMillis();
long elapsed = end - start;
float avgTime = elapsed;
avgTime /= iterationCount;
results.append("\n"+iterationCount+" requiredToRequiresNew() invocations = "+elapsed+" ms, "
+ fmt.format(avgTime)+" ms/requiredToRequiresNew");
}
private void formatException(Throwable t, String testName, StringBuffer results)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
results.append("\n"+testName+" failed:\n");
results.append(sw.toString());
}
}