Author: chirino Date: Wed Jul 7 03:52:03 2010 New Revision: 961092 URL: http://svn.apache.org/viewvc?rev=961092&view=rev Log: enhanced the BaseBrokerPerfSupport test case to generate an html report which keeps track of perf data from previous runs Added: activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/ activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/perf/ activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/perf/report.html Modified: activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/scala/org/apache/activemq/apollo/broker/perf/BaseBrokerPerfSupport.scala activemq/sandbox/activemq-apollo-actor/activemq-util/src/main/java/org/apache/activemq/util/IOHelper.java Added: activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/perf/report.html URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/perf/report.html?rev=961092&view=auto ============================================================================== --- activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/perf/report.html (added) +++ activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/perf/report.html Wed Jul 7 03:52:03 2010 @@ -0,0 +1,191 @@ + + + + + + + +
+ + +
+

+ This report is used to visualize the how the performance of the broker + is changed over time as new code changes are introduced. Click on any data + point in the charts to get the data point's exact value and git + commit version. +

+ +
+
+ +

Partitioned Scaling

+ Compares how well the broker scales as partitioned load is increased on it. Each destination + has only one producer and one consumer attached. +
+ +
+
+ +

Max Producer Rate

+ Compares the maximum producer rate for when there is no attached consumers vs when there is + one attached consumer. +
+ +
+
+ +

Producer Fan In

+ Total producer and consumer rates for when there are many producers on one destination + but only one consumer. The 'producer sd' is standard deviation of the message rate across the + producers. +
+ + +
+
+ +

Consumer Fan Out

+ Total producer and consumer rates for when there are many consumers on one destination + but only one producer. The 'consumer sd' is standard deviation of the message rate across the + consumers. +
+ + +
+
+ +

Producer Fan In and Consumer Fan Out

+ Total producer and consumer rates for when there are many producers and many consumers on one destination. The 'consumer sd' and 'producer sd' + are the standard deviation numbers of the producers and consumers. +
+ +
+
+
+ + + Modified: activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/scala/org/apache/activemq/apollo/broker/perf/BaseBrokerPerfSupport.scala URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/scala/org/apache/activemq/apollo/broker/perf/BaseBrokerPerfSupport.scala?rev=961092&r1=961091&r2=961092&view=diff ============================================================================== --- activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/scala/org/apache/activemq/apollo/broker/perf/BaseBrokerPerfSupport.scala (original) +++ activemq/sandbox/activemq-apollo-actor/activemq-broker/src/test/scala/org/apache/activemq/apollo/broker/perf/BaseBrokerPerfSupport.scala Wed Jul 7 03:52:03 2010 @@ -33,7 +33,8 @@ import org.apache.activemq.apollo.broker import org.scalatest._ import _root_.org.fusesource.hawtbuf._ import java.io.{PrintStream, FileOutputStream, File, IOException} -import org.apache.activemq.util.ProcessSupport +import org.apache.activemq.util.{IOHelper, ProcessSupport} +import scala.util.matching.Regex object BaseBrokerPerfSupport { var PERFORMANCE_SAMPLES = Integer.parseInt(System.getProperty("PERFORMANCE_SAMPLES", "3")) @@ -87,7 +88,7 @@ abstract class BaseBrokerPerfSupport ext val producers = new ArrayList[RemoteProducer]() val consumers = new ArrayList[RemoteConsumer]() - var spread_sheet_stats:List[(String, Any)] = Nil + var spread_sheet_stats:List[(String, AnyRef)] = Nil override protected def beforeEach() = { @@ -126,24 +127,43 @@ abstract class BaseBrokerPerfSupport ext } override protected def afterAll() = { - var basedir = new File(System.getProperty("user.home", ".")) - var csvfile = new File(basedir, "perf-"+getClass.getName+".csv"); - val exists = csvfile.exists - var out = new PrintStream(new FileOutputStream(csvfile, true)); - val version = new String(ProcessSupport.system("git", "rev-list", "--max-count=1", "HEAD").toByteArray).trim - spread_sheet_stats ::= ("Version", version) - if( !exists ) { - out.println(spread_sheet_stats.map(x=>csv_esc(x._1)).mkString(",")) + val basedir = new File(System.getProperty("user.home", ".")) + val csvfile = new File(basedir, "perf-"+getClass.getName+".html"); + + val report_parser = """(?s)(.*// DATA-START\r?\n)(.*)(// DATA-END.*)""".r + + // Load the previous dataset if the file exists + var report_data = "" + if( csvfile.exists ) { + IOHelper.readText(csvfile) match { + case report_parser(_, data, _) => + report_data = data.stripLineEnd + case _ => + println("could not parse existing report file: "+csvfile); + } } - out.println(spread_sheet_stats.map(x=>csv_esc(x._2)).mkString(",")) - out.close - println("Updated: "+csvfile); - } - def csv_esc(value:Any) = { - "\""+value.toString.replace("\"", "\"\"")+"\"" + // Load the report template and parse it.. + val template = IOHelper.readText(classOf[BaseBrokerPerfSupport].getResourceAsStream("report.html")) + template match { + case report_parser(report_header, _, report_footer) => + val version = new String(ProcessSupport.system("git", "rev-list", "--max-count=1", "HEAD").toByteArray).trim + + if( !report_data.isEmpty ) { + report_data += ",\n" + } + report_data += " // version, "+spread_sheet_stats.map(_._1).mkString(", ")+"\n" + report_data += " ['commit "+version+"', "+spread_sheet_stats.map(x=>String.format("%.2f",x._2)).mkString(", ")+"]\n" + + IOHelper.writeText(csvfile, report_header+report_data+report_footer) + case _ => + println("could not parse template report file"); + } + + println("Updated: "+csvfile); } +// def getBrokerWireFormat() = "multi" def getRemoteWireFormat(): String Modified: activemq/sandbox/activemq-apollo-actor/activemq-util/src/main/java/org/apache/activemq/util/IOHelper.java URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-util/src/main/java/org/apache/activemq/util/IOHelper.java?rev=961092&r1=961091&r2=961092&view=diff ============================================================================== --- activemq/sandbox/activemq-apollo-actor/activemq-util/src/main/java/org/apache/activemq/util/IOHelper.java (original) +++ activemq/sandbox/activemq-apollo-actor/activemq-util/src/main/java/org/apache/activemq/util/IOHelper.java Wed Jul 7 03:52:03 2010 @@ -16,16 +16,11 @@ */ package org.apache.activemq.util; -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.lang.reflect.Field; import org.apache.activemq.util.os.CLibrary; +import org.fusesource.hawtbuf.ByteArrayOutputStream; /** */ @@ -156,7 +151,54 @@ public final class IOHelper { FileOutputStream fileDest = new FileOutputStream(dest); copyInputStream(fileSrc, fileDest); } - + + public static String readText(File path) throws IOException { + return readText(path, "UTF-8"); + } + public static String readText(File path, String encoding) throws IOException { + return readText(new FileInputStream(path), encoding); + } + + public static String readText(InputStream in) throws IOException { + return readText(in, "UTF-8"); + } + + public static String readText(InputStream in, String encoding) throws IOException { + return new String(readBytes(in), encoding); + } + + public static byte[] readBytes(File path) throws IOException { + return readBytes(new FileInputStream(path)); + } + + public static byte[] readBytes(InputStream in) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copyInputStream(in, baos); + return baos.toByteArray(); + } + + public static void writeText(File path, String text) throws IOException { + writeText(path, text, "UTF-8"); + } + + public static void writeText(File path, String text, String encoding) throws IOException { + OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(path), encoding); + try { + out.write(text); + } finally { + close(out); + } + } + + public static void writeBinaryFile(File path, byte[] contents) throws IOException { + FileOutputStream out = new FileOutputStream(path); + try { + out.write(contents); + } finally { + close(out); + } + } + public static void copyInputStream(InputStream in, OutputStream out) throws IOException { try { byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; @@ -171,6 +213,13 @@ public final class IOHelper { } } + public static void close(Writer out) { + try { + out.close(); + } catch (IOException e) { + } + } + public static void close(OutputStream out) { try { out.close();