activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r961092 - in /activemq/sandbox/activemq-apollo-actor: activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/ activemq-broker/src/test/resources/org/apache/activemq/apollo/broker/perf/ activemq-broker/src/test/scala/org/apache...
Date Wed, 07 Jul 2010 03:52:03 GMT
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 @@
+<html>
+  <head>
+    <style type='text/css'>
+      body { font-family:Verdana; font-size:12px; color:#666666; }
+      #header {
+        margin: 0; padding: 2em; text-align:center; background: #baccd8;
+      }
+      #header h1 {
+        margin: 0; padding: 0; font-size: 180%; line-height: 1em; color: #333;
+      }
+      #wrap {
+        width: 60em; margin: 0 auto; padding: 2em;
+        background: #dae3e9;
+      }
+      #content {
+        width: 60em;
+        padding: 2em 0;
+      }
+      .chart-graph {
+        float:right; width: 66%; height: 15em;  margin: 1em 0 1em 1em;
+      }
+      .chart-section { clear:both; margin-top: 1em; }
+      .clear { clear:both; }
+    </style>
+    <script type='text/javascript' src='http://www.google.com/jsapi'></script>
+    <script type='text/javascript'>
+      var cols_index_map = {}
+      var data = null;
+      google.load('visualization', '1', {'packages':['linechart']});
+      google.setOnLoadCallback(function() {
+        data = new google.visualization.DataTable();
+        data.addColumn('string', 'version');
+        data.addColumn('number', '1->1->0 producer');
+        data.addColumn('number', '1->1->1 producer');
+        data.addColumn('number', '1->1->1 consumer');
+        data.addColumn('number', '2->2->2 producer');
+        data.addColumn('number', '2->2->2 producer sd');
+        data.addColumn('number', '2->2->2 consumer');
+        data.addColumn('number', '2->2->2 consumer sd');
+        data.addColumn('number', '10->1->10 producer');
+        data.addColumn('number', '10->1->10 producer sd');
+        data.addColumn('number', '10->1->10 consumer');
+        data.addColumn('number', '10->1->10 consumer sd');
+        data.addColumn('number', '10->1->1 producer');
+        data.addColumn('number', '10->1->1 producer sd');
+        data.addColumn('number', '10->1->1 consumer');
+        data.addColumn('number', '1->1->10 producer');
+        data.addColumn('number', '1->1->10 consumer');
+        data.addColumn('number', '1->1->10 consumer sd');
+        data.addColumn('number', '10->10->10 producer');
+        data.addColumn('number', '10->10->10 producer sd');
+        data.addColumn('number', '10->10->10 consumer');
+        data.addColumn('number', '10->10->10 consumer sd');
+        data.addColumn('number', '1->1->[1 slow,1 fast] producer');
+        data.addColumn('number', '1->1->[1 slow,1 fast] producer sd');
+        data.addColumn('number', '1->1->[1 slow,1 fast] consumer');
+        data.addColumn('number', '1->1->[1 slow,1 fast] consumer sd');
+        data.addColumn('number', '2->2->[1,1 selecting] producer');
+        data.addColumn('number', '2->2->[1,1 selecting] producer sd');
+        data.addColumn('number', '2->2->[1,1 selecting] consumer');
+        data.addColumn('number', '2->2->[1,1 selecting] consumer sd');
+
+        for( var i=0; i <  data.getNumberOfColumns(); i ++) {
+          cols_index_map[data.getColumnLabel(i)] = i;
+        }
+
+        var data_array = [
+// DATA-START
+      ['555b061e6782136a1a49926f3d1f6b6ab716fdbb', 151405.66, 11196.00, 13107.33, 16008.33,
5532.50, 14253.00, 2875.50, 622.00, 152.36, 3214.00, 1031.43, 4872.33, 696.11, 4779.67, 2176.27,
20076.31, 69.34, 8170.94, 92.81, 8493.50, 421.33, 103.67, 155.50, 19.67, 29.50, 12049.98,
123.00, 12020.66, 18.00],
+      ['555b061e6782136a1a49926f3d1f6b6ab716fdbb', 140957.00, 14202.33, 14158.67, 12854.67,
622.00, 14241.33, 1423.00, 6833.06, 1155.71, 8560.15, 1052.10, 9759.91, 1442.56, 6537.13,
2590.80, 26000.33, 127.60, 13044.33, 535.73, 13001.67, 629.49, 1450.85, 0.00, 19.66, 29.50,
13612.00, 3198.00, 13327.33, 3027.00]
+// DATA-END
+        ];
+        try {
+          data.addRows(data_array);
+        } catch (er) {
+          alert(er);
+        }
+      });
+
+      // Helpers
+      function chart(id, cols, options) {
+        var c = new google.visualization.LineChart(document.getElementById(id));
+        var view = new google.visualization.DataView(data);
+        var col_indexes = new Array(cols.length);
+        for (var i = 0; i < cols.length; i++) {
+          col_indexes[i] = cols_index_map[cols[i]];
+        }
+        view.setColumns(col_indexes);
+        c.draw(view, options);
+      }
+    </script>
+  </head>
+  <body>
+    <div id='wrap'>
+      <div id='header'>
+        <h1>Broker Performance Evolution</h1>
+      </div>
+
+      <div id='content' >
+        <p>
+          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.
+        </p>
+
+        <div class='chart-section'>
+          <div id='partioned_scaling' class='chart-graph'></div>
+          <script type='text/javascript'>
+            google.setOnLoadCallback(function() {
+              chart('partioned_scaling',
+                ['version', '1->1->1 consumer', '2->2->2 consumer', '10->10->10
consumer'],
+                {showCategories:false, legend: 'bottom', smoothLine:true, titleX:'changes
over time', titleY:'messages/sec', enableTooltip:true }
+              );
+            });
+          </script>
+          <h2>Partitioned Scaling</h2>
+          Compares how well the broker scales as partitioned load is increased on it.  Each
destination
+          has only one producer and one consumer attached.
+        </div>
+
+        <div class='chart-section'>
+          <div id='raw_producer_rate' class='chart-graph'></div>
+          <script type='text/javascript'>
+            google.setOnLoadCallback(function() {
+              chart('raw_producer_rate',
+                ['version', '1->1->0 producer'],
+                {showCategories:false, legend: 'bottom', smoothLine:true, titleX:'changes
over time', titleY:'messages/sec', enableTooltip:true }
+              );
+            });
+          </script>
+          <h2>Max Producer Rate</h2>
+          Compares the maximum producer rate for when there is no attached consumers vs when
there is
+          one attached consumer.
+        </div>
+
+        <div class='chart-section'>
+          <div id='fan_in_rate' class='chart-graph'></div>
+          <script type='text/javascript'>
+            google.setOnLoadCallback(function() {
+              chart('fan_in_rate',
+                ['version', '10->1->1 producer', '10->1->1 consumer', '10->1->1
producer sd'],
+                {showCategories:false, legend: 'bottom', smoothLine:true, titleX:'changes
over time', titleY:'messages/sec', enableTooltip:true }
+              );
+            });
+          </script>
+          <h2>Producer Fan In</h2>
+          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.
+        </div>
+
+
+        <div class='chart-section'>
+          <div id='fan_out_rate' class='chart-graph'></div>
+          <script type='text/javascript'>
+            google.setOnLoadCallback(function() {
+              chart('fan_out_rate',
+                ['version', '1->1->10 producer', '1->1->10 consumer', '1->1->10
consumer sd'],
+                {showCategories:false, legend: 'bottom', smoothLine:true, titleX:'changes
over time', titleY:'messages/sec', enableTooltip:true }
+              );
+            });
+          </script>
+          <h2>Consumer Fan Out</h2>
+          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.
+        </div>
+
+
+        <div class='chart-section'>
+          <div id='fan_inout_rate' class='chart-graph'></div>
+          <script type='text/javascript'>
+            google.setOnLoadCallback(function() {
+              chart('fan_inout_rate',
+                ['version', '10->1->10 producer', '10->1->10 consumer', '10->1->10
producer sd', '10->1->10 consumer sd'],
+                {showCategories:false, legend: 'bottom', smoothLine:true, titleX:'changes
over time', titleY:'messages/sec', enableTooltip:true }
+              );
+            });
+          </script>
+          <h2>Producer Fan In and Consumer Fan Out</h2>
+          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.
+        </div>
+
+        <div class="clear"></div>
+      </div>
+    </div>
+  </body>
+</html>
+

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();



Mime
View raw message