Author: [email protected]
Date: Tue Mar 22 10:23:46 2011
New Revision: 892

Log:
[AMDATU-332] Improved automated performance test

Modified:
   trunk/etc/performancetest/pom.xml
   
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ReportSummary.java
   
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/Statistics.java
   
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ZSamples.java
   
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/main/Main.java
   
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/runtest/AmdatuLauncher.java

Modified: trunk/etc/performancetest/pom.xml
==============================================================================
--- trunk/etc/performancetest/pom.xml   (original)
+++ trunk/etc/performancetest/pom.xml   Tue Mar 22 10:23:46 2011
@@ -29,15 +29,19 @@
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.2.1</version>
         <configuration>
           <archive>
             <manifest>
               <addClasspath>true</addClasspath>
-              <mainClass>org.amdatu.test.performance.Main</mainClass>
+              <mainClass>org.amdatu.test.performance.main.Main</mainClass>
             </manifest>
           </archive>
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+          <appendAssemblyId>false</appendAssemblyId>
         </configuration>
       </plugin>
     </plugins>

Modified: 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ReportSummary.java
==============================================================================
--- 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ReportSummary.java
     (original)
+++ 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ReportSummary.java
     Tue Mar 22 10:23:46 2011
@@ -20,6 +20,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -33,10 +34,12 @@
  */
 public class ReportSummary {
     private String m_resultDir;
+    private int m_omit;
     private List<JMeterPlanReport> m_reports = new 
ArrayList<JMeterPlanReport>();
     
-    public ReportSummary(String resultDir) {
+    public ReportSummary(String resultDir, int omit) {
         m_resultDir = resultDir;
+        m_omit = omit;
     }
     
     public void mergeAndAdd(JMeterResultsParser x, JMeterResultsParser y) 
throws IOException, MathException {
@@ -46,12 +49,16 @@
         for (String key : resultsX.keySet()) {
             List<XYSample> samplesX = resultsX.get(key);
             List<XYSample> samplesY = resultsY.get(key);
-            ZSamples mergedReport = new ZSamples(m_resultDir, samplesX, 
samplesY);
+            ZSamples mergedReport = new ZSamples(m_resultDir, samplesX, 
samplesY, m_omit);
             report.addSampleResult(mergedReport);
         }
         report.setThroughput(x.getThroughput(), y.getThroughput());
         m_reports.add(report);
     }
+    
+    public List<JMeterPlanReport> getReports() {
+        return m_reports;
+    }
 
     public void toConsole() {
         System.out.println("------------------------");
@@ -78,7 +85,7 @@
         }
     }
 
-    public void toHtmlFile(String fileName) throws IOException {
+    public void toHtmlFile(String fileName, int testLoops) throws IOException {
         FileOutputStream fos = null;
         PrintWriter pw = null;
         try {
@@ -99,51 +106,145 @@
             pw.println("</style>");
             pw.println("</head><body>");
             pw.println("<h1>Performance test results</h1>");
-            pw.println("<h2>Legend</h2>");
-            pw.println("<p>JMeter samples drawn from version X: 
X<sub>0</sub>,...,X<sub>n</sub><br/>");
-            pw.println("JMeter samples drawn from version Y: 
Y<sub>0</sub>,...,Y<sub>n</sub><br/>");
-            pw.println("Version X represents the new version, compared against 
the original version Y</br/>");
-            pw.println("Z<sub>0</sub>,...,Z<sub>n</sub> := 
(X<sub>0</sub>-Y<sub>0</sub>),...,(X<sub>n</sub>-Y<sub>0</sub>)<br/>");
-            pw.println("Null hypothesis H<sub>0</sub> := &micro;<sub>z</sub> = 
0</p><p>");
-            pw.println("<table><tr>" + good("good") + "</tr>");
-            pw.println("<tr>" + reallyGood("really good") + "</tr>");
-            pw.println("<tr>" + bad("bad") + "</tr>");
-            pw.println("<tr>" + reallyBad("really bad") + "</tr></table>");
-            pw.println("</p><hr>");
+            addLegend(pw);
+            pw.println("<hr>");
             for (JMeterPlanReport report : m_reports) {
                 pw.println("<h2>Results for JMeter plan '" + report.getName() 
+ "'</h2>");
-                pw.println("<p><table><tr><td>Throughput X</td><td>" + 
report.getThroughputX() + " req/s</td></tr>");
+                pw.println("<p><table border=\"1\">");
+                pw.println("<tr><td>#Processors</td><td>" + 
Runtime.getRuntime().availableProcessors() + "</td></tr>");
+                pw.println("<tr><td>Memory</td><td>" + 
toMegaBytes(Runtime.getRuntime().freeMemory()) + " free of available " + 
toMegaBytes(Runtime.getRuntime().maxMemory()) + "</td></tr>");
+                pw.println("<tr><td>Test loops</td><td>" + testLoops + 
"</td></tr>");
+                pw.println("<tr><td>Throughput X</td><td>" + 
report.getThroughputX() + " req/s</td></tr>");
                 pw.println("<tr><td>Throughput Y</td><td>" + 
report.getThroughputY() + " req/s</td></tr></table>");
                 pw.println("<br/>");
                 pw.println("<table>");
+                
+                // Print headers
+                pw.println("<tr><th/>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<th>" + sample.name+ "</th>");
+                }
+                pw.println("</tr>");
+                
+                // Sample mean size (m)
+                pw.println("<tr><td>m</td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + sample.sampleMeanSize + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // Sample size (n)
+                pw.println("<tr><td>n</td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + sample.sampleSize + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // Mean of X
+                pw.println("<tr><td>M<sub>x</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + round(sample.sampleMeanX) + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // Mean of Y
+                pw.println("<tr><td>M<sub>y</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + round(sample.sampleMeanY) + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // Mean of Z
+                pw.println("<tr><td>M<sub>z</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + round(sample.sampleMean) + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // Standard deviation of Z
+                pw.println("<tr><td>S<sub>z</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + round(sample.sampleSD) + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // t-value of Z
+                pw.println("<tr><td>t<sub>z</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + round(sample.t) + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // Probability of t-value
+                pw.println("<tr><td>Pt<sub>z</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + round(sample.p) + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // [power] difference between X and Y
+                pw.println("<tr><td>D<sub>z</sub></td>");
                 for (ZSamples sample : report.getSamples()) {
-                    boolean H0 = sample.H0;
-                    pw.println("<tr><th align=\"left\" colspan=\"2\">Results 
for Sample '" + sample.name + "'</th></tr>");
-                    pw.println("<tr><td><td>Sample size</td><td>" + 
sample.sampleSize + "</td></tr>");
-                    pw.println("<tr><td><td>&micro;<sub>z</sub></td>" + 
(sample.sampleMean > 0 ? bad(sample.sampleMean) : good(sample.sampleMean)) + 
"</tr>");
-                    pw.println("<tr><td><td>&sigma<sub>z</sub></td><td>" + 
sample.sampleSD + "</td></tr>");
-                    pw.println("<tr><td><td>t<sub>z</sub></td><td>" + sample.t 
+ "</td></tr>");
-                    pw.println("<tr><td><td>Pt<sub>z</sub></td><td>" + 
sample.p + "</td></tr>");
-                    pw.println("<tr><td><td>D<sub>z</sub></td><td>" + sample.D 
+ "</td></tr>");
-                    if (H0) {
-                        pw.println("<tr><td><td>H<sub>0</sub></td>" + 
reallyGood("accepted") + "</tr>");
+                    if (sample.D < 0) {
+                        pw.println(good(round(sample.D)));
                     } else {
-                        pw.println("<tr><td><td>H<sub>0</sub></td>" + 
reallyBad("rejected") + "</td></tr>");
+                        pw.println(bad(round(sample.D)));
                     }
+                    
+                }
+                pw.println("</tr>");
+                
+                // Percentile [power] difference between X and Y
+                pw.println("<tr><td>&Delta;<sub>z</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    if (sample.delta < -0.05) {
+                        pw.println(reallyGood(round(100*sample.delta) + "%"));
+                    } else if (sample.delta <= 0) {
+                        pw.println(good(round(100*sample.delta) + "%"));
+                    } else if (sample.delta < 0.05) {
+                        pw.println(bad(round(100*sample.delta) + "%"));
+                    } else {
+                        pw.println(reallyBad(round(100*sample.delta) + "%"));
+                    }
+                }
+                pw.println("</tr>");
+                
+                // H0 hypothesis
+                pw.println("<tr><td>H<sub>0</sub></td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + (sample.H0 ? "accepted" : "rejected") 
+ "</td>");
+                }
+                pw.println("</tr>");
+                
+                // H0 hypothesis power
+                pw.println("<tr><td>H<sub>0</sub> power</td>");
+                for (ZSamples sample : report.getSamples()) {
+                    pw.println("<td>" + sample.power + "</td>");
+                }
+                pw.println("</tr>");
+                
+                // Success rate X
+                pw.println("<tr><td>Success rate X</td>");
+                for (ZSamples sample : report.getSamples()) {
                     if (sample.successRateX != 1) {
-                        pw.println("<tr><td><td>Success rate X</td>" + 
reallyBad(100*sample.successRateX + "%") + "</tr>");
+                        pw.println(reallyBad(round(100*sample.successRateX) + 
"%"));
                     } else {
-                        pw.println("<tr><td><td>Success rate X</td><td>" + 
100*sample.successRateX + "%</td></tr>");
+                        pw.println("<td>" + round(100*sample.successRateX) + 
"%</td>");
                     }
+                }
+                pw.println("</tr>");
+                
+                // Success rate Y
+                pw.println("<tr><td>Success rate Y</td>");
+                for (ZSamples sample : report.getSamples()) {
                     if (sample.successRateY != 1) {
-                        pw.println("<tr><td><td>Success rate Y</td>" + 
reallyBad(00*sample.successRateY + "%") + "</tr>");
+                        pw.println(reallyBad(round(100*sample.successRateY) + 
"%"));
                     } else {
-                        pw.println("<tr><td><td>Success rate Y</td><td>" + 
100*sample.successRateY + "%</td></tr>");
+                        pw.println("<td>" + round(100*sample.successRateY) + 
"%</td>");
                     }
-                        
-                    pw.println("<tr><td colspan=\"2\"></td></tr>");
-                    pw.println("<tr><td colspan=\"2\"></td></tr>");
                 }
+                pw.println("</tr>");
+               
                 pw.println("</table></p>");
             }    
             pw.println("</body></html>");
@@ -160,6 +261,38 @@
             }
         }
     }
+    
+    private String toMegaBytes(long bytes) {
+        long mb = bytes/(1024*1024);
+        return mb + " Mb";
+    }
+    
+    private void addLegend(PrintWriter pw) {
+        pw.println("<h2>Legend</h2>");
+        pw.println("Version X represents the new version, compared against the 
original version Y</br/><p>");
+        pw.println("JMeter samples drawn from version X: 
X<sub>0</sub>,...,X<sub>n</sub> &nbsp; sample mean: M<sub>x</sub> &nbsp; sample 
standard deviation: S<sub>x</sub><br/>");
+        pw.println("JMeter samples drawn from version Y: 
Y<sub>0</sub>,...,Y<sub>n</sub> &nbsp; sample mean: M<sub>y</sub> &nbsp; sample 
standard deviation: S<sub>y</sub><br/>");
+        pw.println("Generated difference sample Z: 
Z<sub>0</sub>,...,Z<sub>n</sub> := 
(X<sub>0</sub>-Y<sub>0</sub>),...,(X<sub>n</sub>-Y<sub>0</sub>) &nbsp; sample 
mean: M<sub>z</sub> &nbsp; sample standard deviation: S<sub>z</sub><br/>");
+        pw.println("Test statistic T<sub>z</sub> := 
M<sub>z</sub>&radic;n/S<sub>z</sub><br/>");
+        pw.println("Sample value of T := t<sub>z</sub><br/>");
+        pw.println("Probability of meastured value Pt<sub>z</sub> := 
P[T<sub>z</sub>] <= t<sub>z</sub><br/>"); 
+        pw.println("Under the assumption that X has a distribution with mean 
&micro;<sub>x</sub> and Y has a dsitribution with mean &micro;<sub>y</sub>");
+        pw.println(", we define the null hypothesis:<br/> H<sub>0</sub> := 
&micro;<sub>z</sub> = 0, where &micro;<sub>z</sub> := &micro;<sub>x</sub> - 
&micro;<sub>y</sub><br/>");
+        pw.println("We define D<sub>z</sub> to be the value of D for which 
P[t<sub>dz</sub>] >= 0.01, where t<sub>dz</sub> := 
(M<sub>z</sub>-D)&radic;n/S<sub>z</sub><br/>"); 
+        pw.println("In other words, this value D tells us that the difference 
between &micro;<sub>x</sub> and &micro;<sub>y</sub> is at least D<sub>z</sub>, 
with 99% accuracy</br/>");
+        pw.println("&Delta;<sub>z</sub> := D<sub>z</sub>/M<sub>y</sub>");
+        pw.println("<p><table><tr>" + good("good") + "</tr>");
+        pw.println("<tr>" + reallyGood("really good") + "</tr>");
+        pw.println("<tr>" + bad("bad") + "</tr>");
+        pw.println("<tr>" + reallyBad("really bad") + "</tr></table>");
+        pw.println("</p>");
+    }
+    
+    private String round(double d) {
+        DecimalFormat df = new DecimalFormat("####0.00");
+        return df.format(d);
+
+    }
 
     private String good(Object value) {
         return "<td class=\"good\">" + value + "</td>";

Modified: 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/Statistics.java
==============================================================================
--- 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/Statistics.java
        (original)
+++ 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/Statistics.java
        Tue Mar 22 10:23:46 2011
@@ -39,14 +39,15 @@
  */
 public class Statistics {
     private String m_resultsDir;
+    private ReportSummary m_report;
     
     public Statistics(String resultsDir) {
         m_resultsDir = resultsDir;
     }
     
-    public void analyze() throws ParserConfigurationException, SAXException, 
IOException, MathException {
+    public void analyze(int omit) throws ParserConfigurationException, 
SAXException, IOException, MathException {
         // Analyze
-        ReportSummary report = new ReportSummary(m_resultsDir);
+        m_report = new ReportSummary(m_resultsDir, omit);
         for (String sample : getJMeterReports()) {
             File reportX = new File(sample + "X");
             File reportY = new File(sample + "Y");
@@ -58,12 +59,22 @@
             sax.parse(reportY, resultsY);
             
             // Merge and add the JMeter results to the overall report
-            report.mergeAndAdd(resultsX, resultsY);
+            m_report.mergeAndAdd(resultsX, resultsY);
         }
-        
+    }
+    
+    public void print(int n) throws IOException {
         // Print the result to the console
-        report.toConsole();
-        report.toHtmlFile(m_resultsDir + File.separator + "report.html");
+        m_report.toConsole();
+        printHtml(n);
+    }
+    
+    public void printHtml(int n) throws IOException {
+        m_report.toHtmlFile(m_resultsDir + File.separator + "report-testloop_" 
+ n + ".html", n);
+    }
+    
+    public ReportSummary getReport() {
+        return m_report;
     }
     
     private List<String> getJMeterReports() {

Modified: 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ZSamples.java
==============================================================================
--- 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ZSamples.java
  (original)
+++ 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/analysis/ZSamples.java
  Tue Mar 22 10:23:46 2011
@@ -32,116 +32,106 @@
  *
  */
 public class ZSamples {
-    private List<XYSample> m_samplesX;
-    private List<XYSample> m_samplesY;
+    //private List<XYSample> m_samplesX;
+    //private List<XYSample> m_samplesY;
+    private List<Double> m_samplesX;
+    private List<Double> m_samplesY;
     
     String name;
-    boolean H0; // H0 := mean(X) = mean(Y)
-    boolean H1; // H1 := mean(X) < mean(Y)
-    boolean H2; // H2 := mean(X) > mean(Y)
-    boolean H3; // H3 := mean(X) - mean(Y) >= mean with P 99%
+    public boolean H0; // H0 := mean(X) = mean(Y)
+    double power = 0.9999;
     double successRateX;
     double successRateY;
+    double sampleMeanX;
+    double sampleMeanY;
     double sampleMean;
     double sampleSD;
     double t;
     double p;
     double D;
+    double delta;
+    int sampleMeanSize = 0;
     int sampleSize = 0;
     private String m_resultsDir;
-    
-    public ZSamples(String resultsDir, List<XYSample> x, List<XYSample> y) 
throws IOException, MathException {
-        m_samplesX = x;
-        m_samplesY = y;
-        name =  m_samplesX.get(0).name;
+    private int m_omit;
+
+    public ZSamples(String resultsDir, List<XYSample> x, List<XYSample> y, int 
omit) throws IOException, MathException {
         m_resultsDir = resultsDir;
-        
+        m_omit = omit;
+
+        preProcess(x, y);
+
         calculate();
     }
-    
+
     public void calculate() throws IOException, MathException {
         // First calculate the sample observation Z
-        List<Integer> diffs = getZ();
+        List<Double> diffs = getZ();
         double total = 0;
-        for (int diff : diffs) {
+        for (double diff : diffs) {
             total += diff;
             sampleSize++;
         }
+
         sampleMean = total/sampleSize;
-        
+
         sampleSD = 0;
-        for (int diff : diffs) {
+        for (double diff : diffs) {
             sampleSD += Math.pow(diff - sampleMean, 2);
         }
         sampleSD = Math.sqrt(sampleSD/(sampleSize -1));
-        
+
         // Calculate the measured value of the test statistic T
         t = (sampleMean/sampleSD)*Math.sqrt(sampleSize);
-        
+
         // Now T has a Student distribution with (sampleSize-1) degrees of 
freedom
         TDistributionImpl tDistribution = new TDistributionImpl(sampleSize-1);
         if (t <= 0) {
-            // If t < 0 we define H1: mean(x) < mean(y) 
             // Calculate P[T(n-1)] <= t
             p = tDistribution.cumulativeProbability(t);
         } else {
-            // If t > 0 we define H2: mean(x) < mean(y) 
             // Calculate P[T(n-1)] >= t
             p = (1-tDistribution.cumulativeProbability(t));
         }
-        
-        // Null hypotheses is that X and Y are equally distributed. Under the 
assumption that the diffs
-        // are normally distributed, a 95% probability interval of the mean is 
[mean-2sd, mean+2sd].
-        H0 = sampleMean-2*sampleSD <= 0 && sampleMean+2*sampleSD >=0;
-        
-        H1 = (tDistribution.cumulativeProbability(t) >= 0.01);
-        H2 = (1-tDistribution.cumulativeProbability(t) >= 0.01);
+
+        // We accept the null hypothesis (X and Y have the same mean) when p 
>= (1-power). 
+        H0 = (p >= (1-power));
 
         // Now we calculate the maximum value of D, for which is true that:
-        // P[((mean(X)-D)/sd)*sqrt(n)] >= 0.01
-        // Effectively this tell us that 'with probability 99% we can ensure 
that the difference in means 
+        // P[((mean(X)-D)/sd)*sqrt(n)] >= (1-power)
+        // Effectively this tell us that 'with probability [power] we can 
ensure that the difference in means 
         // between X and Y is at least D'
         if (t <= 0) {
-            double valueOfT = tDistribution.inverseCumulativeProbability(0.01);
+            double valueOfT = 
tDistribution.inverseCumulativeProbability(1-power);
             D = sampleMean-(sampleSD*valueOfT)/Math.sqrt(sampleSize);
         } else {
-            double valueOfT = tDistribution.inverseCumulativeProbability(0.99);
+            double valueOfT = 
tDistribution.inverseCumulativeProbability(power);
             D = sampleMean-(sampleSD*valueOfT)/Math.sqrt(sampleSize);
         }
-        
-        // Calculate success rate
-        successRateX = 0;
-        successRateY = 0;
-        for (XYSample r : m_samplesX) {
-            successRateX += r.success ? 1 : 0;
-        }
-        successRateX /= m_samplesX.size();
-        
-        for (XYSample r : m_samplesY) {
-            successRateY += r.success ? 1 : 0;
-        }
-        successRateY /= m_samplesY.size();
+
+        delta = D/sampleMeanY;
     }
-    
-    private List<Integer> getZ() throws IOException {
-        List<Integer> results = new ArrayList<Integer>();
-        
+
+    private List<Double> getZ() throws IOException {
+        List<Double> results = new ArrayList<Double>();
+
         File samplesZOutput = new File(m_resultsDir, name + "-samples.Z");
         FileOutputStream fos = null;
         PrintWriter pw = null;
         try {
             fos = new FileOutputStream(samplesZOutput);
             pw = new PrintWriter(fos);
-           
+            sampleMeanX = 0;
+            sampleMeanY = 0;
             for (int i=0; i<m_samplesX.size(); i++) {
-                if (i < m_samplesY.size()) {
-                    int zi = m_samplesX.get(i).responseTime - 
m_samplesY.get(i).responseTime;
-                    results.add(zi);
-                    pw.write(zi + "\n");
-                } else {
-                    System.err.println("Mismatch in sample sizes: X=" + 
m_samplesX.size() + ", Y=" + m_samplesY.size());
-                }
+                double zi = m_samplesX.get(i) - m_samplesY.get(i);
+                sampleMeanX += m_samplesX.get(i);
+                sampleMeanY += m_samplesY.get(i);
+                results.add(zi);
+                pw.write(zi + "\n");
             }
+            sampleMeanX /= m_samplesX.size();
+            sampleMeanY /= m_samplesY.size();
         } finally {
             try {
                 if (pw != null) {
@@ -153,11 +143,54 @@
                 }
             }
         }
-        
-        
+
         return results;
-    } 
+    }
     
+    private int getSampleSize(double samples) {
+        sampleMeanSize = (int) Math.min(150, Math.round(samples/1000));
+        return sampleMeanSize;
+    }
+
+    private void preProcess(List<XYSample> x, List<XYSample> y) {
+        if (x.size() != y.size()) {
+            System.err.println("Mismatch in sample sizes: X=" + x.size() + ", 
Y=" + y.size());
+        }
+        name =  x.get(0).name;
+
+        // Generate new sample means
+        int newSampleSize = getSampleSize(x.size());
+        m_samplesX = new ArrayList<Double>();
+        m_samplesY = new ArrayList<Double>();
+        successRateX = 0;
+        successRateY = 0;
+        double meanX = 0, meanY = 0;
+        int count = 0;
+        for (int i=m_omit; i<Math.min(x.size(), y.size()); i++) {
+            if (count > 0 && count == newSampleSize) {
+                m_samplesX.add(meanX / newSampleSize);
+                m_samplesY.add(meanY / newSampleSize);
+                count = 0;
+                meanX = 0;
+                meanY = 0;
+            }
+            meanX += x.get(i).responseTime;
+            meanY += y.get(i).responseTime;
+            count++;
+            
+            // Calculate success rate
+            successRateX += x.get(i).success ? 1 : 0;
+            successRateY += y.get(i).success ? 1 : 0;
+        }
+        if (count > 0 && count == newSampleSize) {
+            m_samplesX.add(meanX / newSampleSize);
+            m_samplesY.add(meanY / newSampleSize);
+            count = 0;
+            meanX = 0;
+            meanY = 0;
+        }
     
-   
+        successRateX /= (x.size() - m_omit);
+        successRateY /= (y.size() - m_omit);        
+    }
 }

Modified: 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/main/Main.java
==============================================================================
--- 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/main/Main.java
  (original)
+++ 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/main/Main.java
  Tue Mar 22 10:23:46 2011
@@ -22,7 +22,9 @@
 import java.util.List;
 import java.util.Map;
 
+import org.amdatu.test.performance.analysis.JMeterPlanReport;
 import org.amdatu.test.performance.analysis.Statistics;
+import org.amdatu.test.performance.analysis.ZSamples;
 import org.amdatu.test.performance.runtest.AmdatuLauncher;
 import org.amdatu.test.performance.runtest.JMeterRunner;
 
@@ -32,13 +34,18 @@
  * @author ivol
  */
 public class Main {
+    private final static int TEST_LOOPS = 4;
+    
     private static String VERBOSE_ARG = "-verbose";
     private static String ANALYZE_ARG = "-analyze";
     private static String RUNTEST_ARG = "-runtest";
+    private static String NOEXAMPLES_ARG = "-noexamples";
     private static String AMDATU_X_ARG = "-amdatuVersionX";
     private static String AMDATU_Y_ARG = "-amdatuVersionY";
     private static String JMETERPLANSDIR_ARG = "-jmeterplansdir";
     private static String RESULTSDIR_ARG = "-resultsdir";
+    private static String TESTLOOPS_ARG = "-testloops";
+    private static String OMIT_ARG = "-omit";
 
     // Wordy arguments
     private final static List<String> BOOLEAN_ARGS = new ArrayList<String>();
@@ -46,6 +53,7 @@
         BOOLEAN_ARGS.add(VERBOSE_ARG);
         BOOLEAN_ARGS.add(ANALYZE_ARG);
         BOOLEAN_ARGS.add(RUNTEST_ARG);
+        BOOLEAN_ARGS.add(NOEXAMPLES_ARG);
     }
 
     // File arguments
@@ -61,7 +69,13 @@
         DIR_ARGS.add(JMETERPLANSDIR_ARG);
         DIR_ARGS.add(RESULTSDIR_ARG);
     }
-
+    
+    // Other arguments
+    private final static List<String> OTHER_ARGS = new ArrayList<String>();
+    static {
+        OTHER_ARGS.add(TESTLOOPS_ARG);
+        OTHER_ARGS.add(OMIT_ARG);
+    }
     public static void main(String[] args) {
         try {
             int i=0;
@@ -97,6 +111,13 @@
                     } else {
                         System.err.println(arg + " requires an existing 
directory name");
                     }
+                } else if (OTHER_ARGS.contains(arg)) {
+                    if (i < args.length) {
+                        arguments.put(arg, args[i]);
+                        i++;
+                    } else {
+                        System.err.println(arg + " requires a value");
+                    }
                 }
             }
 
@@ -112,30 +133,77 @@
             }
             
             File rootTmpDir = getRootTmpDir();
-
+            int n = 1;
             if (Boolean.TRUE.equals(arguments.get(RUNTEST_ARG))) {
                 if (verifyRunTest(arguments)) {
                     String amdatuX = arguments.get(AMDATU_X_ARG).toString();
                     String amdatuY = arguments.get(AMDATU_Y_ARG).toString();
                     String jmeterPlanDir = 
arguments.get(JMETERPLANSDIR_ARG).toString();
                     String resultsDir = 
arguments.get(RESULTSDIR_ARG).toString();
-                    AmdatuLauncher launcherX = new AmdatuLauncher(amdatuX, 
rootTmpDir);
-                    try {
-                        launcherX.start();
-                        JMeterRunner jmeter = new JMeterRunner(jmeterPlanDir, 
"X", resultsDir, rootTmpDir);
-                        jmeter.run();
-                    } finally {
-                        launcherX.stop();
+                    boolean noExamples = 
Boolean.TRUE.equals(arguments.get(NOEXAMPLES_ARG));
+                    int omit = arguments.containsKey(OMIT_ARG) ? 
Integer.parseInt(arguments.get(OMIT_ARG).toString()) : 0;
+                    AmdatuLauncher launcherX = new AmdatuLauncher(amdatuX, 
"X", rootTmpDir, noExamples);
+                    AmdatuLauncher launcherY = new AmdatuLauncher(amdatuY, 
"Y", rootTmpDir, noExamples);
+                    JMeterRunner jmeterX = new JMeterRunner(jmeterPlanDir, 
"X", resultsDir, rootTmpDir);
+                    JMeterRunner jmeterY = new JMeterRunner(jmeterPlanDir, 
"Y", resultsDir, rootTmpDir);
+                    
+                    int loops = TEST_LOOPS;
+                    boolean testLoopAuto = false;
+                    Object testLoops = arguments.get(TESTLOOPS_ARG);
+                    if (testLoops != null && !testLoops.toString().isEmpty()) {
+                        if ("auto".equals(testLoops)) {
+                            testLoopAuto = true;
+                            loops = 1;
+                        } else {
+                            loops = Integer.parseInt(testLoops.toString());
+                        }
                     }
-
-                    AmdatuLauncher launcherY = new AmdatuLauncher(amdatuY, 
rootTmpDir);
-                    try {
-                        launcherY.start();
-                        JMeterRunner jmeter = new JMeterRunner(jmeterPlanDir, 
"Y", resultsDir, rootTmpDir);
-                        jmeter.run();
-                    } finally {
-                        launcherY.stop();
+                    for (n=1; n<=loops; n++) {
+                        
System.out.println("*************************************************************");
+                        if (!testLoopAuto) {
+                            System.out.println("Running test loop " + n + " of 
" + loops + "...");
+                        } else {
+                            System.out.println("Running test loop " + n + " of 
<auto>...");
+                        }
+                        try {
+                            launcherX.start();
+                            jmeterX.run();
+                        } finally {
+                            launcherX.stop();
+                        }
+                        
+                        try {
+                            launcherY.start();
+                            jmeterY.run();
+                        } finally {
+                            launcherY.stop();
+                        }
+                        
+                        if (testLoopAuto) {
+                            int h0Count = 0;
+                            int h0Accepted = 0;
+                            Statistics stats = new Statistics(resultsDir);
+                            stats.analyze(omit);
+                            stats.printHtml(n);
+                            for (JMeterPlanReport report : 
stats.getReport().getReports()) {
+                                for (ZSamples sample : report.getSamples()) {
+                                    h0Count++;
+                                    if (sample.H0) {
+                                        h0Accepted++;
+                                    }
+                                    
+                                }
+                            }
+                            if (h0Count != h0Accepted) {
+                                System.out.println("Continuing test loops, " + 
h0Accepted + " out of " + h0Count + " null hypothesis were accepted");
+                                loops++;
+                            }
+                        }
                     }
+                    
+                    launcherX.kill();
+                    launcherY.kill();
+                    
                     System.out.println("Amdatu performance test completed.");
                 }
             }
@@ -143,8 +211,11 @@
                 if (!arguments.containsKey(RESULTSDIR_ARG)) {
                     printUsage();
                 } else {
+                    int omit = arguments.containsKey(OMIT_ARG) ? 
Integer.parseInt(arguments.get(OMIT_ARG).toString()) : 0;
                     String resultsDir = 
arguments.get(RESULTSDIR_ARG).toString();
-                    new Statistics(resultsDir).analyze();
+                    Statistics stats = new Statistics(resultsDir);
+                    stats.analyze(omit);
+                    stats.print(n);
                     System.out.println("Amdatu performance test analysis 
completed.");
                 }
             }

Modified: 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/runtest/AmdatuLauncher.java
==============================================================================
--- 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/runtest/AmdatuLauncher.java
     (original)
+++ 
trunk/etc/performancetest/src/main/java/org/amdatu/test/performance/runtest/AmdatuLauncher.java
     Tue Mar 22 10:23:46 2011
@@ -18,6 +18,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.util.ArrayList;
@@ -37,27 +38,36 @@
         "http://localhost:8080/dashboard/jsp/dashboard.jsp";,
         "http://localhost:8080/rest/authorization/status";
     };
-    
+        
     private String m_releaseZip;
+    private String m_version;
+    private boolean m_noExamples;
     private File m_rootTmpDir;
     private File m_tmpDir;
     private Process m_amdatuProcess;
 
-    public AmdatuLauncher(String releaseZip, File rootTmpDir) {
+    public AmdatuLauncher(String releaseZip, String version, File rootTmpDir, 
boolean noExamples) {
         m_releaseZip = releaseZip;
         m_rootTmpDir = rootTmpDir;
+        m_noExamples = noExamples;
+        m_version = version;
     }
 
-    public void start() throws IOException {
+    public void start() throws IOException, InterruptedException {
         // First unzip the file to the java io tmpdir
         File zipFile = new File(m_releaseZip);
         
-        String amdatuDir = zipFile.getName();
+        String amdatuDir = zipFile.getName() + "-" + m_version;
         m_tmpDir = new File(m_rootTmpDir, amdatuDir);
-        m_tmpDir.mkdir();
-        System.out.println("Extracting '" + zipFile.getName() + "' to '" + 
m_tmpDir.getAbsolutePath() + "'");
-
-        Utils.unzip(zipFile, m_tmpDir);
+        if (!m_tmpDir.exists()) {
+            // This is the first startup: setup Amdatu
+            m_tmpDir.mkdir();
+            System.out.println("Extracting '" + zipFile.getName() + "' to '" + 
m_tmpDir.getAbsolutePath() + "'");
+            Utils.unzip(zipFile, m_tmpDir);
+            if (m_noExamples) {
+                removeExamples();
+            }
+        }
 
         // Start the Amdatu server in a separate process
         List<String> command = new ArrayList<String>();
@@ -87,6 +97,11 @@
         if (!ok) {
             throw new IllegalStateException("Amdatu could not be launched from 
'" + m_tmpDir + "'. Aborting test.");
         }
+        
+        // For safety, additional wait for 5 seconds
+        System.out.println("Amdatu seems up and running, waiting another 3 
seconds...");
+        Thread.sleep(3000);
+        
         long diff = System.currentTimeMillis() - before;
         System.out.println("Amdatu startup completed in " + diff + " ms, 
running JMeter test plans");
     }
@@ -95,13 +110,42 @@
         // Kill it instantly, no nice shutdown needed
         System.out.println("Stopping Amdatu...");
         if (m_amdatuProcess != null && amdatuProcessRunning()) {
-            m_amdatuProcess.destroy();
+            // Send shutdown event
+            System.out.println("Sending shutdown event");
+            OutputStream os = m_amdatuProcess.getOutputStream();
+            os.write("shutdown\n".getBytes());
+            os.close();
+            
             m_amdatuProcess.waitFor();
         }
        
+        System.out.println("Amdatu shutdown completed");
+    }
+    
+    public void kill() throws IOException, InterruptedException {
+        // Kill it instantly, no nice shutdown needed
+        stop();
+       
+        System.out.println("Removing Amdatu work directory");
         FileUtils.deleteDirectory(m_tmpDir);
+    }
+    
+    private void removeExamples() throws IOException {
+        // Remove all jar files in amdatu-examples
+        File exampleDir = new File (m_tmpDir, "amdatu-examples");
+        FileUtils.deleteDirectory(exampleDir);
         
-        System.out.println("Amdatu shutdown completed");
+        // Remove from Felix config properties
+        File felixConfig = new File(m_tmpDir, "conf/felix-config.properties");
+        List<String> lines = FileUtils.readLines(felixConfig);
+        List<String> newLines = new ArrayList<String>();
+        for (String line : lines) {
+            if 
(line.indexOf("reference:file:amdatu-examples/org.amdatu.example.") == -1) {
+                newLines.add(line);
+            }
+        }
+        felixConfig.delete();
+        FileUtils.writeLines(felixConfig, newLines);
     }
 
     private boolean waitForURL(URL url, int responseCode, int timeout) throws 
IOException {
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to