You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ps...@apache.org on 2008/03/22 23:52:57 UTC

svn commit: r640114 - in /commons/sandbox/performance/trunk/src: java/org/apache/commons/performance/ java/org/apache/commons/performance/dbcp/ java/org/apache/commons/performance/http/ java/org/apache/commons/performance/pool/ test/org/apache/commons/...

Author: psteitz
Date: Sat Mar 22 15:52:54 2008
New Revision: 640114

URL: http://svn.apache.org/viewvc?rev=640114&view=rev
Log:
Modified LoadGenerator, ClientThread to support aggregation of custom
statistics. Added cleanUp (after each iteration) and finalize (end of run)
hooks.

Added:
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java
    commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java
Modified:
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/LoadGenerator.java
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpClientThread.java
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpSoak.java
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java
    commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolSoak.java
    commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java Sat Mar 22 15:52:54 2008
@@ -17,13 +17,11 @@
 
 package org.apache.commons.performance;
 
-import java.util.List;
 import java.util.logging.Logger;
 
 import org.apache.commons.math.random.RandomData;
 import org.apache.commons.math.random.RandomDataImpl;
 import org.apache.commons.math.stat.descriptive.SummaryStatistics;
-import org.apache.commons.math.stat.descriptive.SummaryStatisticsImpl;
 
 /**
  * <p>Base for performance / load test clients. 
@@ -84,10 +82,8 @@
     
     /** Random data generator */
     protected RandomData randomData = new RandomDataImpl();
-    /** Statistics accumulator */
-    protected SummaryStatistics stats = new SummaryStatisticsImpl();
-    /** List of statistics to which to append stats for this client */
-    protected List <SummaryStatistics> statsList = null;
+    /** Statistics container */
+    protected Statistics stats = new Statistics();
     /** Logger shared by client threads */
     protected Logger logger = null;
     
@@ -110,7 +106,7 @@
             double sigma, String delayType, long rampPeriod, long peakPeriod,
             long troughPeriod, String cycleType,
             String rampType, Logger logger,
-            List <SummaryStatistics> statsList) {
+            Statistics stats) {
         this.iterations = iterations;
         this.minDelay = minDelay;
         this.maxDelay = maxDelay;
@@ -122,7 +118,7 @@
         this.cycleType = cycleType;
         this.rampType = rampType;
         this.logger = logger;
-        this.statsList = statsList;
+        this.stats = stats;
     }
     
     public void run() {
@@ -140,6 +136,7 @@
         long numErrors = 0;
         periodStart = System.currentTimeMillis();
         lastMean = (double) maxDelay; // Ramp up, if any, starts here
+        SummaryStatistics responseStats = new SummaryStatistics();
         for (int i = 0; i < iterations; i++) {
             try {
                 setUp();
@@ -165,7 +162,7 @@
                 numErrors++;
             } finally {
                 try {
-                    stats.addValue(System.currentTimeMillis() - start);
+                    responseStats.addValue(System.currentTimeMillis() - start);
                     lastStart = start;
                     cleanUp();
                 } catch (Exception e) {
@@ -174,11 +171,20 @@
             }
         }
         
+        try {
+            finalize();
+        } catch (Exception ex) {
+            logger.severe("finalize failed.");
+            ex.printStackTrace();
+            return;
+        }
+        
         // Report statistics
         logger.info(stats.toString() + 
           "Number of misses: " + numMisses + "\n" +
           "Number or errors: " + numErrors + "\n");
-        statsList.add(stats);
+        stats.addStatistics(
+                responseStats, Thread.currentThread().getName(), "latency");
     }
     
     /** Executed once at the beginning of the run */
@@ -190,9 +196,13 @@
     /** Executed in finally block of iteration try-catch */
     protected void cleanUp() throws Exception {}
     
-    /** Core iteration code.  Timings are based on this,
+    /** Executed once after the run finishes */
+    protected void finalize() throws Exception {}
+    
+    /** 
+     * Core iteration code.  Timings are based on this,
      *  so keep it tight.
-     *  */
+     */
     public abstract void execute() throws Exception;
     
     /**

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/LoadGenerator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/LoadGenerator.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/LoadGenerator.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/LoadGenerator.java Sat Mar 22 15:52:54 2008
@@ -18,15 +18,12 @@
 package org.apache.commons.performance;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Iterator;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.Logger;
 import org.apache.commons.digester.Digester;
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
-import org.apache.commons.math.stat.descriptive.SummaryStatisticsImpl;
  
 /**
  * <p>Base class for load / peformance test runners.
@@ -57,10 +54,13 @@
  *
  */
 public abstract class LoadGenerator {
+    
+    /** logger */
     protected static final Logger logger = 
         Logger.getLogger(LoadGenerator.class.getName());
-    private static List <SummaryStatistics> statsList =
-        new ArrayList <SummaryStatistics>();
+    
+    /** Statistics aggregator */
+    private static Statistics stats = new Statistics();
     
     // Client thread properties
     protected long minDelay;
@@ -94,14 +94,14 @@
      */
     public void execute() throws Exception {
         configure();
-        digester.parse(new File(configFile));
+        parseConfigFile();
         init();
         // Spawn and execute client threads
 		ExecutorService ex = Executors.newFixedThreadPool((int)numClients);
 		for (int i = 0; i < numClients; i++) {
             ClientThread clientThread = makeClientThread(iterations, minDelay,
                     maxDelay, sigma, delayType, rampPeriod, peakPeriod,
-                    troughPeriod, cycleType, rampType, logger, statsList);
+                    troughPeriod, cycleType, rampType, logger, stats);
 			ex.execute(clientThread);
 		} 
         ex.shutdown();
@@ -109,33 +109,28 @@
         // TODO: make this configurable
         ex.awaitTermination(60 * 60 * 24, TimeUnit.SECONDS);
         
-        // Compute summary statistics
-        SummaryStatistics meanSummary = new SummaryStatisticsImpl();
-        SummaryStatistics stdSummary = new SummaryStatisticsImpl();
-        SummaryStatistics minSummary = new SummaryStatisticsImpl();
-        SummaryStatistics maxSummary = new SummaryStatisticsImpl();
-        for (int i = 0; i < statsList.size(); i++) {
-            SummaryStatistics stats = (SummaryStatistics) statsList.get(i);
-            meanSummary.addValue(stats.getMean());
-            stdSummary.addValue(stats.getStandardDeviation());
-            minSummary.addValue(stats.getMin());
-            maxSummary.addValue(stats.getMax());
+        // Compute and log summary statistics for accumulated metrics
+        Iterator<String> metricsIterator = stats.getTypes().iterator();
+        while (metricsIterator.hasNext()) {
+            String metric = metricsIterator.next();
+            logger.info("********** " + metric.toUpperCase() + " **********");
+            logger.info("Overall statistics for the mean " + metric);
+            logger.info(stats.getMeanSummary(metric).toString());
+            logger.info("Overall statistics for the standard deviation " 
+                    + metric);
+            logger.info(stats.getStdSummary(metric).toString());
+            logger.info("Overall statistics for the min " + metric);
+            logger.info(stats.getMinSummary(metric).toString());
+            logger.info("Overall statistics for the max " + metric);
+            logger.info(stats.getMaxSummary(metric).toString());      
         }
-        logger.info("Overall statistics for the mean");
-        logger.info(meanSummary.toString());
-        logger.info("Overall statistics for the standard deviation");
-        logger.info(stdSummary.toString());
-        logger.info("Overall statistics for the min");
-        logger.info(minSummary.toString());
-        logger.info("Overall statistics for the max");
-        logger.info(maxSummary.toString());
 	}
     
     protected abstract ClientThread makeClientThread(
             long iterations, long minDelay, long maxDelay, double sigma,
             String delayType, long rampPeriod, long peakPeriod,
             long troughPeriod, String cycleType, String rampType,
-            Logger logger, List <SummaryStatistics> statsList);
+            Logger logger, Statistics stats);
     
     /**
      * This method is invoked by {@link #execute()} after {@link #configure()}
@@ -208,8 +203,12 @@
         digester.addCallParam(
                 "configuration/run/trough-period", 9);
         digester.addCallParam(
-                "configuration/run/cycle-type", 10);
-        
+                "configuration/run/cycle-type", 10);    
+    }
+    
+    protected void parseConfigFile() throws Exception {
+        // TODO: get rid of File spec
+        digester.parse(new File(configFile));
     }
 
     /**
@@ -231,5 +230,12 @@
      */
     public Digester getDigester() {
         return digester;
+    }
+    
+    /**
+     * @return statistics
+     */
+    public Statistics getStatistics() {
+        return stats;
     }
 }

Added: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java?rev=640114&view=auto
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java (added)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java Sat Mar 22 15:52:54 2008
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.performance;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.math.stat.descriptive.SummaryStatistics;
+
+/**
+ * <p>Container for {@link SummaryStatistics} accumulated during 
+ * {@link ClientThread} executions.</p>
+ * 
+ * <p>Maintains a HashMap of SummaryStatistics instances with a composite
+ * key of the form <process,type>.  "Process" typically identifies the client
+ * thread and "type" identifies the metric - e.g., "latency", "numActive."</p>
+ * 
+ * <p>NOTE: None of the methods of this class are synchronized.  For general
+ * use outside of Commons Performance, synchronization (if necessary) must be
+ * handled by client code.</p>
+ *
+ */
+public class Statistics {
+    private HashMap<StatisticsKey,SummaryStatistics> data = 
+        new HashMap <StatisticsKey,SummaryStatistics>();
+   
+    /**
+     * Adds a SummaryStatistics instance with key = <process,type>
+     * 
+     * @param stats the SummaryStatistics to add
+     * @param process name of the associated process
+     * @param type description of the associated metric
+     */
+    public void addStatistics(SummaryStatistics stats, String process, String type) {
+        StatisticsKey key = new StatisticsKey(process, type);
+        data.put(key, stats);
+    }
+    
+    /**
+     * Retrieves the SummaryStatistics instance corresponding to the given
+     * process and type, if such an instance exists; null otherwise.
+     * 
+     * @param process name of the associated process
+     * @param type description of the associated metric
+     * @return SummaryStatistics for the given <process,type>; null if there is
+     * no such element in the container
+     */
+    public SummaryStatistics getStatistics(String process, String type) {
+        return data.get(new StatisticsKey(process, type));
+    }
+    
+    /**
+     * Returns the full list of SummaryStatistics instances corresponding to
+     * the given <code>type</code> - i.e, the list of statistics of the 
+     * given type across processes.  For example, 
+     * <code>getStatistics("latency")</code> will return a list of latency
+     * summaries, one for each process, assuming "latency" is the name of 
+     * an accumulated metric.
+     * 
+     * @param type the type value to get statistics for
+     * @return the List of SummmaryStatistics stored under the given type
+     */
+    public List<SummaryStatistics> getStatistics(String type) {
+        ArrayList<SummaryStatistics> result = new ArrayList<SummaryStatistics>();
+        Iterator<StatisticsKey> it = data.keySet().iterator();
+        while (it.hasNext()) {
+            StatisticsKey key = it.next();
+            if (key.type.equals(type)) {
+                result.add(data.get(key));
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Returns SummaryStatistics for the mean of the given metric across
+     * processes - i.e., the "mean of the means", the "min of the means"
+     * etc. More precisely, the returned SummaryStatistics instance describes
+     * the distribution of the individual process means for the given metric.
+     * The same results could be obtained by iterating over the result of 
+     * {{@link #getStatistics(String)} for the given <code>type</code>,
+     * extracting the mean and adding its value to a SummaryStatistics
+     * instance.
+     * 
+     * @param type the metric to get summary mean statistics for
+     * @return a SummaryStatistics instance describing the process means for
+     * the given metric
+     */
+    public SummaryStatistics getMeanSummary(String type) {
+        SummaryStatistics result = new SummaryStatistics();
+        Iterator<StatisticsKey> it = data.keySet().iterator();
+        while (it.hasNext()) {
+            StatisticsKey key = it.next();
+            if (key.type.equals(type)) {
+                result.addValue(data.get(key).getMean());
+            }
+        }
+        return result; 
+    }
+    
+    /**
+     * Returns SummaryStatistics for the standard deviation of the given metric
+     * across processes.
+     * 
+     * @param type the metric to get summary standard deviation statistics for
+     * @return a SummaryStatistics instance describing the process standard
+     * deviations for the given metric
+     * @see #getMeanSummary(String)
+     */
+    public SummaryStatistics getStdSummary(String type) {
+        SummaryStatistics result = new SummaryStatistics();
+        Iterator<StatisticsKey> it = data.keySet().iterator();
+        while (it.hasNext()) {
+            StatisticsKey key = it.next();
+            if (key.type.equals(type)) {
+                result.addValue(data.get(key).getStandardDeviation());
+            }
+        }
+        return result; 
+    }
+    
+    /**
+     * Returns SummaryStatistics for the minimum of the given metric across
+     * processes.
+     * 
+     * @param type the metric to get summary minimum statistics for
+     * @return a SummaryStatistics instance describing the process minima
+     * for the given metric
+     * @see #getMeanSummary(String)
+     */
+    public SummaryStatistics getMinSummary(String type) {
+        SummaryStatistics result = new SummaryStatistics();
+        Iterator<StatisticsKey> it = data.keySet().iterator();
+        while (it.hasNext()) {
+            StatisticsKey key = it.next();
+            if (key.type.equals(type)) {
+                result.addValue(data.get(key).getMin());
+            }
+        }
+        return result; 
+    }
+    
+    /**
+     * Returns SummaryStatistics for the maximum of the given metric across
+     * processes.
+     * 
+     * @param type the metric to get summary maximum statistics for
+     * @return a SummaryStatistics instance describing the process maxima
+     * for the given metric
+     * @see #getMeanSummary(String)
+     */
+    public SummaryStatistics getMaxSummary(String type) {
+        SummaryStatistics result = new SummaryStatistics();
+        Iterator<StatisticsKey> it = data.keySet().iterator();
+        while (it.hasNext()) {
+            StatisticsKey key = it.next();
+            if (key.type.equals(type)) {
+                result.addValue(data.get(key).getMax());
+            }
+        }
+        return result; 
+    }
+    
+    /**
+     * Returns the List of processes corresponding to statistics.
+     * 
+     * @return List of processes represented in the container
+     */
+    public List<String> getProcesses() {
+        ArrayList<String> result = new ArrayList<String>();
+        Iterator<StatisticsKey> it = data.keySet().iterator();
+        while (it.hasNext()) {
+            String currProcess = it.next().process;
+            if (!result.contains(currProcess)) {
+                result.add(currProcess);
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Returns the List of types corresponding to statistics.
+     * 
+     * @return List of types represented in the container
+     */
+    public List<String> getTypes() {
+        ArrayList<String> result = new ArrayList<String>();
+        Iterator<StatisticsKey> it = data.keySet().iterator();
+        while (it.hasNext()) {
+            String currType = it.next().type;
+            if (!result.contains(currType)) {
+                result.add(currType);
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Composite key (<process,type>).
+     */
+    private static class StatisticsKey {
+        public StatisticsKey(String process, String type) {
+            this.process = process;
+            this.type = type;
+        }
+        private String process = null;
+        private String type = null;
+        public boolean equals(Object obj) {
+            if (!(obj instanceof StatisticsKey) || obj == null) {
+                return false;
+            } else {
+                StatisticsKey other = (StatisticsKey) obj;
+                return other.process == this.process &&
+                    other.type == this.type;  
+            }
+        }
+        public int hashCode() {
+            return 7 + 11 * process.hashCode() + 17 * type.hashCode();
+        } 
+        public String getType() {
+            return type;
+        }
+        public String getProcess() {
+            return process;
+        }
+    }
+
+}

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java Sat Mar 22 15:52:54 2008
@@ -20,12 +20,11 @@
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.Statement;
-import java.util.List;
 import java.util.logging.Logger;
 import javax.sql.DataSource;
 
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 import org.apache.commons.performance.ClientThread;
+import org.apache.commons.performance.Statistics;
 
 /**
  * Client thread that executes requests in a loop using a configured
@@ -63,17 +62,17 @@
      * @param rampType type of ramp (linear or random jumps)
      * @param logger common logger shared by all clients
      * @param dataSource DataSource for connections
-     * @param statsList List of SummaryStatistics to add results to
+     * @param stats Statistics container
      */
     public DBCPClientThread(long iterations, long minDelay, long maxDelay,
             double sigma, String delayType, String queryType, long rampPeriod,
             long peakPeriod, long troughPeriod, String cycleType,
             String rampType, Logger logger, DataSource dataSource,
-            List <SummaryStatistics> statsList) {
+            Statistics stats) {
         
         super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
                 peakPeriod, troughPeriod, cycleType, rampType, logger,
-                statsList);
+                stats);
         
         this.dataSource = dataSource;
         

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java Sat Mar 22 15:52:54 2008
@@ -22,7 +22,6 @@
 import java.sql.Driver;
 import java.sql.DriverManager;
 import java.sql.Statement;
-import java.util.List;
 import java.util.Properties;
 import java.util.logging.Logger;
 import org.apache.commons.dbcp.AbandonedConfig;
@@ -39,10 +38,10 @@
 import org.apache.commons.pool.impl.GenericObjectPool;
 import org.apache.commons.math.random.RandomData;
 import org.apache.commons.math.random.RandomDataImpl;
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 import org.apache.commons.performance.ConfigurationException;
 import org.apache.commons.performance.ClientThread;
 import org.apache.commons.performance.LoadGenerator;
+import org.apache.commons.performance.Statistics;
  
 /**
  * Configurable load / performance tester for commons dbcp.
@@ -173,12 +172,12 @@
             long iterations, long minDelay, long maxDelay, double sigma,
             String delayType, long rampPeriod, long peakPeriod,
             long troughPeriod, String cycleType, String rampType,
-            Logger logger, List <SummaryStatistics> statsList) {
+            Logger logger, Statistics stats) {
         
         return new DBCPClientThread(iterations, minDelay, maxDelay,
             sigma, delayType, queryType, rampPeriod, peakPeriod, 
             troughPeriod, cycleType, rampType, logger, dataSource,
-            statsList);
+            stats);
     }
     
     // ------------------------------------------------------------------------

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpClientThread.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpClientThread.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpClientThread.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpClientThread.java Sat Mar 22 15:52:54 2008
@@ -17,7 +17,6 @@
 
 package org.apache.commons.performance.http;
 
-import java.util.List;
 import java.util.logging.Logger;
 
 import org.apache.commons.httpclient.HttpClient;
@@ -27,8 +26,8 @@
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
 
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 import org.apache.commons.performance.ClientThread;
+import org.apache.commons.performance.Statistics;
 
 /**
  * Client thread that executes http requests in a loop against a configured
@@ -48,12 +47,12 @@
             double sigma, String delayType, long rampPeriod,
             long peakPeriod, long troughPeriod, String cycleType,
             String rampType, Logger logger,
-            List <SummaryStatistics> statsList, String url, String method,
+            Statistics stats, String url, String method,
             int socketTimeout, String successKey)  {
         
         super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
                 peakPeriod, troughPeriod, cycleType, rampType, logger,
-                statsList);
+                stats);
         
         httpClient.getParams().setSoTimeout(socketTimeout);
         if (method.trim().toUpperCase().equals("POST")) {

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpSoak.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpSoak.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpSoak.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/http/HttpSoak.java Sat Mar 22 15:52:54 2008
@@ -17,12 +17,11 @@
 
 package org.apache.commons.performance.http;
 
-import java.util.List;
 import java.util.logging.Logger;
 
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 import org.apache.commons.performance.ClientThread;
 import org.apache.commons.performance.LoadGenerator;
+import org.apache.commons.performance.Statistics;
 
 /**
  * Simple http load / performance tester, providing another LoadGenerator
@@ -47,12 +46,12 @@
             long iterations, long minDelay, long maxDelay, double sigma,
             String delayType, long rampPeriod, long peakPeriod,
             long troughPeriod, String cycleType, String rampType,
-            Logger logger, List <SummaryStatistics> statsList) {
+            Logger logger, Statistics stats) {
         
         return new HttpClientThread(iterations, minDelay, maxDelay,
             sigma, delayType, rampPeriod, peakPeriod, 
             troughPeriod, cycleType, rampType, logger,
-            statsList, url, method, socketTimeout, successKey);
+            stats, url, method, socketTimeout, successKey);
     }
     
     /**

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java Sat Mar 22 15:52:54 2008
@@ -23,10 +23,10 @@
 
 import org.apache.commons.pool.ObjectPool;
 import org.apache.commons.pool.KeyedObjectPool;
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 import org.apache.commons.math.random.RandomData;
 import org.apache.commons.math.random.RandomDataImpl;
 import org.apache.commons.performance.ClientThread;
+import org.apache.commons.performance.Statistics;
 
 /**
  * Client thread that borrows and returns objects from a pool in a loop.
@@ -55,17 +55,17 @@
      * @param cycleType type of cycle for mean delay
      * @param rampType type of ramp (linear or random jumps)
      * @param logger common logger shared by all clients
-     * @param statsList List of SummaryStatistics to add results to
+     * @param stats Statistics container
      * @param pool ObjectPool
      */
     public PoolClientThread(long iterations, long minDelay, long maxDelay,
             double sigma, String delayType, long rampPeriod, long peakPeriod,
             long troughPeriod, String cycleType, String rampType, Logger logger, 
-            List <SummaryStatistics> statsList, ObjectPool pool) {
+            Statistics stats, ObjectPool pool) {
         
         super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
                 peakPeriod, troughPeriod, cycleType,rampType, logger, 
-                statsList); 
+                stats); 
         this.pool = pool;
         this.keyed = false;
     }
@@ -83,17 +83,18 @@
      * @param cycleType type of cycle for mean delay
      * @param rampType type of ramp (linear or random jumps)
      * @param logger common logger shared by all clients
-     * @param statsList List of SummaryStatistics to add results to
+     * @param stats Statistics container 
      * @param keyedPool KeyedObjectPool
      */
     public PoolClientThread(long iterations, long minDelay, long maxDelay,
             double sigma, String delayType, long rampPeriod, long peakPeriod,
             long troughPeriod, String cycleType, String rampType, Logger logger, 
-            List <SummaryStatistics> statsList, KeyedObjectPool keyedPool) {
+            Statistics stats, KeyedObjectPool keyedPool) {
         
         super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
                 peakPeriod, troughPeriod, cycleType,rampType, logger, 
-                statsList); 
+                stats); 
+        
         this.keyedPool = keyedPool;
         this.keyed = true;
         keys = new ArrayList<Integer>();
@@ -115,5 +116,13 @@
            waiter.doWait();
            pool.returnObject(waiter);
        }
+    }
+    
+    protected void cleanUp() throws Exception {
+         // Capture pool metrics here periodically
+    }
+    
+    protected void finalize() throws Exception {
+        // Add pool metrics statistics to stats
     }
 }

Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolSoak.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolSoak.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolSoak.java (original)
+++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolSoak.java Sat Mar 22 15:52:54 2008
@@ -32,6 +32,7 @@
 import org.apache.commons.performance.ConfigurationException;
 import org.apache.commons.performance.ClientThread;
 import org.apache.commons.performance.LoadGenerator;
+import org.apache.commons.performance.Statistics;
  
 /**
  * Configurable load / performance tester for commons pool.
@@ -236,35 +237,34 @@
     protected ClientThread makeClientThread(long iterations, long minDelay,
             long maxDelay, double sigma, String delayType, long rampPeriod,
             long peakPeriod, long troughPeriod, String cycleType, 
-            String rampType, Logger logger, 
-            List <SummaryStatistics> statsList) {
+            String rampType, Logger logger, Statistics stats) {
         if (poolType.equals("GenericObjectPool")) {
             return new PoolClientThread(iterations, minDelay, maxDelay,
                     sigma, delayType, rampPeriod, peakPeriod, troughPeriod,
-                    cycleType, rampType, logger, statsList, genericObjectPool);
+                    cycleType, rampType, logger, stats, genericObjectPool);
         }
         if (poolType.equals("GenericKeyedObjectPool")) {
             return new PoolClientThread(iterations, minDelay, maxDelay,
                     sigma, delayType, rampPeriod, peakPeriod, troughPeriod,
-                    cycleType, rampType, logger, statsList,
+                    cycleType, rampType, logger, stats,
                     genericKeyedObjectPool);
         }
         if (poolType.equals("StackKeyedObjectPool")) {
             return new PoolClientThread(iterations, minDelay, maxDelay,
                     sigma, delayType, rampPeriod, peakPeriod, troughPeriod,
-                    cycleType, rampType, logger, statsList,
+                    cycleType, rampType, logger, stats,
                     stackKeyedObjectPool);
         }
         if (poolType.equals("StackObjectPool")) {
             return new PoolClientThread(iterations, minDelay, maxDelay,
                     sigma, delayType, rampPeriod, peakPeriod, troughPeriod,
-                    cycleType, rampType, logger, statsList,
+                    cycleType, rampType, logger, stats,
                     stackObjectPool);
         }
         if (poolType.equals("SoftReferenceObjectPool")) {
             return new PoolClientThread(iterations, minDelay, maxDelay,
                     sigma, delayType, rampPeriod, peakPeriod, troughPeriod,
-                    cycleType, rampType, logger, statsList,
+                    cycleType, rampType, logger, stats,
                     softReferenceObjectPool);
         }
         return null;

Modified: commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java?rev=640114&r1=640113&r2=640114&view=diff
==============================================================================
--- commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java (original)
+++ commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java Sat Mar 22 15:52:54 2008
@@ -16,10 +16,7 @@
  */
 package org.apache.commons.performance;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.logging.Logger;
-import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -28,8 +25,7 @@
     
   protected ClientThread clientThread = null;
   protected static Logger logger = Logger.getLogger(LoadGenerator.class.getName());
-  protected static List <SummaryStatistics> statsList =
-        new ArrayList <SummaryStatistics>();
+  protected static Statistics stats = new Statistics();
   
   // Dummy ClientThread concrete class to instantiate in tests
   class nullClientThread extends ClientThread {
@@ -37,10 +33,10 @@
               double sigma, String delayType, long rampPeriod,
               long peakPeriod, long troughPeriod, String cycleType,
               String rampType, Logger logger,
-              List <SummaryStatistics> statsList) {    
+              Statistics stats) {    
           super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
                   peakPeriod, troughPeriod, cycleType, rampType, logger,
-                  statsList);
+                  stats);
       }
       public void execute() {}
   }
@@ -67,7 +63,7 @@
             3000, // trough period
             "oscillating", // cycle type
             "linear", // ramp type
-            logger, statsList);
+            logger, stats);
   }
 
   // ======================================================

Added: commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java?rev=640114&view=auto
==============================================================================
--- commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java (added)
+++ commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java Sat Mar 22 15:52:54 2008
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.performance;
+
+import java.util.logging.Logger;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.commons.math.stat.descriptive.SummaryStatistics;
+import org.apache.commons.math.random.RandomData;
+import org.apache.commons.math.random.RandomDataImpl;
+
+public class LoadGeneratorTest extends TestCase {
+    
+  protected TestLoadGenerator generator = null;
+  protected static Logger logger = Logger.getLogger(LoadGenerator.class.getName());
+  protected static Statistics stats = new Statistics();
+  
+  class TestClientThread extends ClientThread {
+      private long latency = 50;
+      private double metricOne = 10d;
+      private double metricTwo = 20d;
+      private SummaryStatistics oneStats = new SummaryStatistics();
+      private SummaryStatistics twoStats = new SummaryStatistics();
+      private SummaryStatistics randomStats = new SummaryStatistics();
+      private RandomData randomData = new RandomDataImpl();
+      public TestClientThread(long iterations, long minDelay, long maxDelay,
+              double sigma, String delayType, long rampPeriod,
+              long peakPeriod, long troughPeriod, String cycleType,
+              String rampType, Logger logger,
+              Statistics stats) {    
+          super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
+                  peakPeriod, troughPeriod, cycleType, rampType, logger,
+                  stats);
+      }
+      public void setLatency(long latency) {
+          this.latency = latency;
+      }
+      public void execute() throws Exception {
+          Thread.sleep(latency);
+      }
+      protected void cleanUp() {
+          oneStats.addValue(metricOne);
+          twoStats.addValue(metricTwo);
+          randomStats.addValue(randomData.nextUniform(0d, 1d));
+      }
+      protected void finalize() {
+          stats.addStatistics(
+                  oneStats, Thread.currentThread().getName(), "one");
+          stats.addStatistics(
+                  twoStats, Thread.currentThread().getName(), "two");
+          stats.addStatistics(
+                  randomStats, Thread.currentThread().getName(), "random");   
+      }
+  }
+  
+  class TestLoadGenerator extends LoadGenerator {
+      protected ClientThread makeClientThread(long iterations, long minDelay,
+              long maxDelay, double sigma, String delayType, long rampPeriod,
+              long peakPeriod, long troughPeriod, String cycleType, 
+              String rampType, Logger logger, Statistics stats) {
+          return new TestClientThread(iterations, minDelay,
+              maxDelay, sigma, delayType, rampPeriod,
+              peakPeriod, troughPeriod, cycleType, 
+              rampType, logger, stats);
+      }
+      protected void parseConfigFile() throws Exception {
+          getDigester().parse(this.getClass().getResourceAsStream(
+                  "/org/apache/commons/performance/pool/config-pool.xml"));
+      }
+  }
+  
+
+  public LoadGeneratorTest(String name) {
+    super(name);
+  }
+
+
+  public static Test suite() {
+    return new TestSuite(LoadGeneratorTest.class);
+  }
+  
+  public void setUp() throws Exception {
+     generator = new TestLoadGenerator();
+  }
+
+  public void testStatistics() throws Exception {
+      generator.execute();
+      Statistics statistics = generator.getStatistics();
+      SummaryStatistics stats = null;
+      stats = statistics.getMeanSummary("latency");
+      assertEquals(50, stats.getMean(), 3.0);
+      stats = statistics.getMeanSummary("one");
+      assertEquals(10, stats.getMean(), 1.0);
+      stats = statistics.getMeanSummary("two");
+      assertEquals(20, stats.getMean(), 1.0);
+      stats = statistics.getMeanSummary("random");
+      assertEquals(0.5, stats.getMean(), 0.25);
+  }
+  
+}