org.codehaus.mojo.chronos.jmeter.JMeterSAXFileHandler Maven / Gradle / Ivy
/*
* The MIT License
*
* Original work sponsored and donated by National Board of e-Health (NSI), Denmark (http://www.nsi.dk)
* Further enhancement before move to Codehaus sponsored and donated by Lakeside A/S (http://www.lakeside.dk)
*
* Copyright (c) to all contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* $HeadURL: https://svn.codehaus.org/mojo/tags/chronos-1.1.0/chronos-jmeter-maven-plugin/src/main/java/org/codehaus/mojo/chronos/jmeter/JMeterSAXFileHandler.java $
* $Id: JMeterSAXFileHandler.java 17280 2012-08-09 11:55:34Z soelvpil $
*/
package org.codehaus.mojo.chronos.jmeter;
import org.apache.commons.math.stat.descriptive.rank.Min;
import org.codehaus.mojo.chronos.common.model.ResponsetimeSample;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* SAXHandler for JMeter xml logs.
*
* @author [email protected]
* @author Dragisa Krsmanovic
*/
public final class JMeterSAXFileHandler
extends DefaultHandler
{
private static final String JUNIT_SAMPLER_20 = "org.apache.jmeter.protocol.java.sampler.JUnitSampler";
private final Collector collector = new Collector();
private Properties sampleAttributes;
private boolean inProperty = false;
private boolean insideSample = false;
private StringBuffer testMethodNameSB = new StringBuffer();
private Properties parentSampleAttributes;
/**
* @param uri See {@link DefaultHandler#startElement(String, String, String, Attributes)}
* @param localName See {@link DefaultHandler#startElement(String, String, String, Attributes)}
* @param qName See {@link DefaultHandler#startElement(String, String, String, Attributes)}
* @param attributes See {@link DefaultHandler#startElement(String, String, String, Attributes)}
* @throws SAXException See {@link DefaultHandler#startElement(String, String, String, Attributes)}
* @see DefaultHandler#startElement(String, String, String, Attributes)
*/
public void startElement( String uri, String localName, String qName, Attributes attributes )
throws SAXException
{
if ( "sampleResult".equals( qName ) )
{
// jtl20
Properties props = new Properties();
for ( int i = 0; i < attributes.getLength(); i++ )
{
props.put( attributes.getQName( i ), attributes.getValue( i ) );
}
sampleAttributes = props;
insideSample = true;
}
else if ( "property".equals( qName ) )
{
// jtl20
// TODO be sure that log cannot contain other types of character
// data under junitSamples properties
inProperty = true;
}
else if ( "httpSample".equals( qName ) || "sample".equals( qName ) )
{
// jtl21
if ( insideSample )
{
parentSampleAttributes = sampleAttributes;
}
Properties props = new Properties();
for ( int i = 0; i < attributes.getLength(); i++ )
{
props.put( attributes.getQName( i ), attributes.getValue( i ) );
}
sampleAttributes = props;
insideSample = true;
}
}
/**
* this method can be called multiple times in one element if there's enough chars.
*
* @param ch See {@link DefaultHandler#characters(char[], int, int)}
* @param start See {@link DefaultHandler#characters(char[], int, int)}
* @param length See {@link DefaultHandler#characters(char[], int, int)}
* @see DefaultHandler#characters(char[], int, int)
*/
public void characters( char[] ch, int start, int length )
{
if ( insideSample && inProperty )
{
testMethodNameSB.append( new String( ch, start, length ) );
}
}
/**
* @param uri See {@link DefaultHandler#endElement(String, String, String)}
* @param localName See {@link DefaultHandler#endElement(String, String, String)}
* @param qName See {@link DefaultHandler#endElement(String, String, String)}
* @throws SAXException See {@link DefaultHandler#endElement(String, String, String)}
* @see DefaultHandler#endElement(String, String, String)
*/
public void endElement( String uri, String localName, String qName )
throws SAXException
{
if ( "property".equals( qName ) )
{
inProperty = false;
}
else if ( "sampleResult".equals( qName ) )
{
// jtl20
String embeddedPropertyValue = testMethodNameSB.toString();
collectJtl20( embeddedPropertyValue, sampleAttributes );
reset();
}
else if ( "httpSample".equals( qName ) || "sample".equals( qName ) )
{
// jtl21
if ( !insideSample )
{
sampleAttributes = parentSampleAttributes;
}
collectJtl21(sampleAttributes);
reset();
}
}
private void collectJtl20( String embeddedPropertyValue, final Properties sampleAttributes )
{
final String sampleName;
// it seems like when generated from Jmeter 2.1, the label will always
// contain the String
// 'org.apache.jmeter.protocol.java.sampler.JUnitSampler'
String label = sampleAttributes.getProperty( "label" );
if ( JUNIT_SAMPLER_20.equals( label ) && !"".equals( embeddedPropertyValue ) )
{
sampleName = embeddedPropertyValue;
}
else
{
sampleName = label;
}
int responsetime = Integer.parseInt( sampleAttributes.getProperty( "time" ) );
long timestamp = Long.parseLong( sampleAttributes.getProperty( "timeStamp" ) );
boolean success = "true".equals( sampleAttributes.getProperty( "success" ) );
String threadId = sampleAttributes.getProperty( "threadName" ).intern();
collector.collect( sampleName, responsetime, timestamp, success, threadId );
}
private void collectJtl21( final Properties sampleAttributes )
{
String sampleName = sampleAttributes.getProperty( "lb" );
int responsetime = Integer.parseInt( sampleAttributes.getProperty( "t" ) );
long timestamp = Long.parseLong( sampleAttributes.getProperty( "ts" ) );
boolean success = "true".equals( sampleAttributes.getProperty( "s" ) );
String threadId = sampleAttributes.getProperty( "tn" ).intern();
collector.collect( sampleName, responsetime, timestamp, success, threadId );
}
private void reset()
{
testMethodNameSB.setLength( 0 );
insideSample = false;
sampleAttributes = null;
}
private static class Collector
{
private final SortedMap> sampleGroupsByName = new TreeMap>();
/**
* int
representing the number of succeeded samples.
*/
protected int succeeded;
protected final Min testStart = new Min();
private void collect(String sampleName, int responsetime, long timestamp, boolean success, String threadId)
{
testStart.increment( timestamp );
if ( success )
{
succeeded++;
}
List groupElement = sampleGroupsByName.get(sampleName);
if ( groupElement == null )
{
groupElement = new ArrayList( );
sampleGroupsByName.put(sampleName, groupElement);
}
groupElement.add(new ResponsetimeSample(responsetime, timestamp, success, threadId));
}
/**
* Writes XML document using StAX
*/
void writeTo(XMLStreamWriter writer) throws XMLStreamException {
writer.writeStartElement("groupedresponsetimesamples");
writer.writeAttribute("succeeded", Integer.toString(succeeded));
writer.writeAttribute( "starttime", Long.toString( (long) testStart.getResult()));
writer.writeAttribute( "dateformat", "HH:mm:ss" );
int index = 1;
for ( String groupName : sampleGroupsByName.keySet() )
{
List samples = sampleGroupsByName.get( groupName );
writer.writeStartElement( "responsetimesamplegroup" );
writer.writeAttribute( "name", groupName );
writer.writeAttribute( "index", Integer.toString( index ) );
for (ResponsetimeSample sample : samples) {
writer.writeEmptyElement( "sample" );
long relativeStartTime = sample.getStartTime() - (long) testStart.getResult();
writer.writeAttribute( "timestamp", Long.toString( relativeStartTime ) );
writer.writeAttribute( "responsetime", Integer.toString( sample.getResponsetime() ) );
writer.writeAttribute( "success", Boolean.toString( sample.isSuccess() ) );
writer.writeAttribute( "threadId", sample.getThreadId() );
}
writer.writeEndElement();
index++;
}
writer.writeEndElement();
}
}
/**
* Writes XML document using StAX.
*/
void writeTo(XMLStreamWriter writer) throws XMLStreamException {
collector.writeTo(writer);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy