jakarta-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From milam...@apache.org
Subject svn commit: r1083962 - in /jakarta/jmeter/trunk: bin/ docs/images/screenshots/ docs/images/screenshots/http-config/ src/core/org/apache/jmeter/resources/ src/protocol/http/org/apache/jmeter/protocol/http/config/gui/ src/protocol/http/org/apache/jmeter/...
Date Mon, 21 Mar 2011 21:20:56 GMT
Author: milamber
Date: Mon Mar 21 21:20:56 2011
New Revision: 1083962

URL: http://svn.apache.org/viewvc?rev=1083962&view=rev
Log:
Bug 50943 - Allowing concurrent downloads of embedded resources in html page

Modified:
    jakarta/jmeter/trunk/bin/jmeter.properties
    jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
    jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
    jakarta/jmeter/trunk/xdocs/changes.xml
    jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
    jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml

Modified: jakarta/jmeter/trunk/bin/jmeter.properties
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/bin/jmeter.properties (original)
+++ jakarta/jmeter/trunk/bin/jmeter.properties Mon Mar 21 21:20:56 2011
@@ -682,6 +682,8 @@ beanshell.server.file=../extras/startup.
 #httpsampler.max_redirects=5
 # Maximum frame/iframe nesting depth (default 5)
 #httpsampler.max_frame_depth=5
+# Maximum await termination timeout (secs) when concurrent download embedded resources (default
60)
+#httpsampler.await_termination_timeout=60
 
 # The encoding to be used if none is provided (default ISO-8859-1)
 #sampleresult.default.encoding=ISO-8859-1

Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
Binary files - no diff available.

Modified: jakarta/jmeter/trunk/docs/images/screenshots/http-request.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/docs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
Binary files - no diff available.

Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Mon Mar
21 21:20:56 2011
@@ -1024,6 +1024,7 @@ web_server_domain=Server Name or IP\:
 web_server_port=Port Number\:
 web_testing2_source_ip=Source IP address:
 web_testing2_title=HTTP Request HTTPClient
+web_testing_concurrent_download=Use concurrent pool. Size:
 web_testing_embedded_url_pattern=Embedded URLs must match\:
 web_testing_retrieve_images=Retrieve All Embedded Resources from HTML Files
 web_testing_title=HTTP Request

Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Mon Mar
21 21:20:56 2011
@@ -927,6 +927,7 @@ web_server_timeout_response=R\u00E9ponse
 web_server_timeout_title=D\u00E9lai expiration (ms)
 web_testing2_source_ip=Adresse IP source \:
 web_testing2_title=Requ\u00EAte HTTP HTTPClient
+web_testing_concurrent_download=Utiliser pool unit\u00E9. Nbre \:
 web_testing_embedded_url_pattern=Les URL \u00E0 inclure doivent correspondre \u00E0 \:
 web_testing_retrieve_images=R\u00E9cup\u00E9rer les ressources incluses
 web_testing_title=Requ\u00EAte HTTP

Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
(original)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/config/gui/HttpDefaultsGui.java
Mon Mar 21 21:20:56 2011
@@ -20,15 +20,22 @@ package org.apache.jmeter.protocol.http.
 
 import java.awt.BorderLayout;
 import java.awt.Dimension;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
 
+import javax.swing.BorderFactory;
 import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
 
 import org.apache.jmeter.config.ConfigTestElement;
 import org.apache.jmeter.config.gui.AbstractConfigGui;
+import org.apache.jmeter.gui.util.HorizontalPanel;
 import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
 import org.apache.jmeter.testelement.AbstractTestElement;
 import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.testelement.property.BooleanProperty;
+import org.apache.jmeter.testelement.property.StringProperty;
 import org.apache.jmeter.util.JMeterUtils;
 
 public class HttpDefaultsGui extends AbstractConfigGui {
@@ -36,6 +43,10 @@ public class HttpDefaultsGui extends Abs
     private static final long serialVersionUID = 240L;
 
     private JCheckBox imageParser;
+    
+    private JCheckBox concurrentDwn;
+    
+    private JTextField concurrentPool; 
 
     private UrlConfigGui urlConfig;
 
@@ -70,9 +81,20 @@ public class HttpDefaultsGui extends Abs
         super.configureTestElement(config);
         if (imageParser.isSelected()) {
             config.setProperty(new BooleanProperty(HTTPSamplerBase.IMAGE_PARSER, true));
+            enableConcurrentDwn(true);
         } else {
             config.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
+            enableConcurrentDwn(false);
         }
+        if (concurrentDwn.isSelected()) {
+            config.setProperty(new BooleanProperty(HTTPSamplerBase.CONCURRENT_DWN, true));
+        } else {
+            // The default is false, so we can remove the property to simplify JMX files
+            // This also allows HTTPDefaults to work for this checkbox
+            config.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
+        }
+        config.setProperty(new StringProperty(HTTPSamplerBase.CONCURRENT_POOL, 
+                String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE)));
     }
 
     /**
@@ -83,6 +105,8 @@ public class HttpDefaultsGui extends Abs
         super.clearGui();
         urlConfig.clear();
         imageParser.setSelected(false);
+        concurrentDwn.setSelected(false);
+        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
     }
 
     @Override
@@ -90,6 +114,8 @@ public class HttpDefaultsGui extends Abs
         super.configure(el);
         urlConfig.configure(el);
         imageParser.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.IMAGE_PARSER));
+        concurrentDwn.setSelected(((AbstractTestElement) el).getPropertyAsBoolean(HTTPSamplerBase.CONCURRENT_DWN));
+        concurrentPool.setText(((AbstractTestElement) el).getPropertyAsString(HTTPSamplerBase.CONCURRENT_POOL));
     }
 
     private void init() {
@@ -101,12 +127,58 @@ public class HttpDefaultsGui extends Abs
         urlConfig = new UrlConfigGui(false);
         add(urlConfig, BorderLayout.CENTER);
 
+        // OPTIONAL TASKS
+        final JPanel optionalTasksPanel = new HorizontalPanel();
+        optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
JMeterUtils
+                .getResString("optional_tasks"))); // $NON-NLS-1$
+
+        final JPanel checkBoxPanel = new HorizontalPanel();
         imageParser = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images"));
// $NON-NLS-1$
-        add(imageParser, BorderLayout.SOUTH);
+        checkBoxPanel.add(imageParser);
+        imageParser.addItemListener(new ItemListener() {
+            public void itemStateChanged(final ItemEvent e) {
+                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true);
}
+                else { enableConcurrentDwn(false); }
+            }
+        });
+        // Concurrent resources download
+        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download"));
// $NON-NLS-1$
+        concurrentDwn.addItemListener(new ItemListener() {
+            public void itemStateChanged(final ItemEvent e) {
+                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true);
}
+                else { concurrentPool.setEnabled(false); }
+            }
+        });
+        concurrentPool = new JTextField(2); // 2 columns size
+        concurrentPool.setMaximumSize(new Dimension(30,20));
+        checkBoxPanel.add(concurrentDwn);
+        checkBoxPanel.add(concurrentPool);
+        optionalTasksPanel.add(checkBoxPanel);
+        add(optionalTasksPanel, BorderLayout.SOUTH);
     }
 
     @Override
     public Dimension getPreferredSize() {
         return getMinimumSize();
     }
+    
+    private void enableConcurrentDwn(final boolean enable) {
+        if (enable) {
+            concurrentDwn.setEnabled(true);
+            if (concurrentDwn.isSelected()) {
+                concurrentPool.setEnabled(true);
+            }
+        } else {
+            concurrentDwn.setEnabled(false);
+            concurrentPool.setEnabled(false);
+        }
+    }
+
+    public void itemStateChanged(final ItemEvent event) {
+        if (event.getStateChange() == ItemEvent.SELECTED) {
+            enableConcurrentDwn(true);
+        } else {
+            enableConcurrentDwn(false);
+        }
+    }
 }

Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
(original)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/gui/HttpTestSampleGui.java
Mon Mar 21 21:20:56 2011
@@ -20,10 +20,13 @@ package org.apache.jmeter.protocol.http.
 
 import java.awt.BorderLayout;
 import java.awt.Dimension;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
 
 import javax.swing.BorderFactory;
 import javax.swing.JCheckBox;
 import javax.swing.JPanel;
+import javax.swing.JTextField;
 
 import org.apache.jmeter.gui.util.HorizontalPanel;
 import org.apache.jmeter.gui.util.VerticalPanel;
@@ -41,12 +44,17 @@ import org.apache.jorphan.gui.JLabeledTe
  * HTTP Sampler GUI
  *
  */
-public class HttpTestSampleGui extends AbstractSamplerGui {
+public class HttpTestSampleGui extends AbstractSamplerGui 
+    implements ItemListener {
     private static final long serialVersionUID = 240L;
 
     private MultipartUrlConfigGui urlConfigGui;
 
     private JCheckBox getImages;
+    
+    private JCheckBox concurrentDwn;
+    
+    private JTextField concurrentPool; 
 
     private JCheckBox isMon;
 
@@ -78,6 +86,8 @@ public class HttpTestSampleGui extends A
         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) element;
         urlConfigGui.configure(element);
         getImages.setSelected(samplerBase.isImageParser());
+        concurrentDwn.setSelected(samplerBase.isConcurrentDwn());
+        concurrentPool.setText(samplerBase.getConcurrentPool());
         isMon.setSelected(samplerBase.isMonitor());
         useMD5.setSelected(samplerBase.useMD5());
         embeddedRE.setText(samplerBase.getEmbeddedUrlRE());
@@ -106,11 +116,21 @@ public class HttpTestSampleGui extends A
         final HTTPSamplerBase samplerBase = (HTTPSamplerBase) sampler;
         if (getImages.isSelected()) {
             samplerBase.setImageParser(true);
+            enableConcurrentDwn(true);
         } else {
             // The default is false, so we can remove the property to simplify JMX files
             // This also allows HTTPDefaults to work for this checkbox
             sampler.removeProperty(HTTPSamplerBase.IMAGE_PARSER);
+            enableConcurrentDwn(false);
+        }
+        if (concurrentDwn.isSelected()) {
+            samplerBase.setConcurrentDwn(true);
+        } else {
+            // The default is false, so we can remove the property to simplify JMX files
+            // This also allows HTTPDefaults to work for this checkbox
+            sampler.removeProperty(HTTPSamplerBase.CONCURRENT_DWN);
         }
+        samplerBase.setConcurrentPool(concurrentPool.getText());
         samplerBase.setMonitor(isMon.isSelected());
         samplerBase.setMD5(useMD5.isSelected());
         samplerBase.setEmbeddedUrlRE(embeddedRE.getText());
@@ -143,19 +163,38 @@ public class HttpTestSampleGui extends A
 
     protected JPanel createOptionalTasksPanel() {
         // OPTIONAL TASKS
-        JPanel optionalTasksPanel = new VerticalPanel();
+        final JPanel optionalTasksPanel = new VerticalPanel();
         optionalTasksPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
JMeterUtils
                 .getResString("optional_tasks"))); // $NON-NLS-1$
 
-        JPanel checkBoxPanel = new HorizontalPanel();
+        final JPanel checkBoxPanel = new HorizontalPanel();
         // RETRIEVE IMAGES
         getImages = new JCheckBox(JMeterUtils.getResString("web_testing_retrieve_images"));
// $NON-NLS-1$
+        // add a listener to activate or not concurrent dwn.
+        getImages.addItemListener(new ItemListener() {
+            public void itemStateChanged(final ItemEvent e) {
+                if (e.getStateChange() == ItemEvent.SELECTED) { enableConcurrentDwn(true);
}
+                else { enableConcurrentDwn(false); }
+            }
+        });
+        // Download concurrent resources
+        concurrentDwn = new JCheckBox(JMeterUtils.getResString("web_testing_concurrent_download"));
// $NON-NLS-1$
+        concurrentDwn.addItemListener(new ItemListener() {
+            public void itemStateChanged(final ItemEvent e) {
+                if (e.getStateChange() == ItemEvent.SELECTED) { concurrentPool.setEnabled(true);
}
+                else { concurrentPool.setEnabled(false); }
+            }
+        });
+        concurrentPool = new JTextField(2); // 2 column size
+        concurrentPool.setMaximumSize(new Dimension(30,20));
         // Is monitor
         isMon = new JCheckBox(JMeterUtils.getResString("monitor_is_title")); // $NON-NLS-1$
         // Use MD5
         useMD5 = new JCheckBox(JMeterUtils.getResString("response_save_as_md5")); // $NON-NLS-1$
 
         checkBoxPanel.add(getImages);
+        checkBoxPanel.add(concurrentDwn);
+        checkBoxPanel.add(concurrentPool);
         checkBoxPanel.add(isMon);
         checkBoxPanel.add(useMD5);
         optionalTasksPanel.add(checkBoxPanel);
@@ -188,6 +227,9 @@ public class HttpTestSampleGui extends A
     public void clearGui() {
         super.clearGui();
         getImages.setSelected(false);
+        concurrentDwn.setSelected(false);
+        concurrentPool.setText(String.valueOf(HTTPSamplerBase.CONCURRENT_POOL_SIZE));
+        enableConcurrentDwn(false);
         isMon.setSelected(false);
         useMD5.setSelected(false);
         urlConfigGui.clear();
@@ -196,4 +238,25 @@ public class HttpTestSampleGui extends A
             sourceIpAddr.setText(""); // $NON-NLS-1$
         }
     }
+    
+    private void enableConcurrentDwn(boolean enable) {
+        if (enable) {
+            concurrentDwn.setEnabled(true);
+            if (concurrentDwn.isSelected()) {
+                concurrentPool.setEnabled(true);
+            }
+        } else {
+            concurrentDwn.setEnabled(false);
+            concurrentPool.setEnabled(false);
+        }
+    }
+
+    public void itemStateChanged(ItemEvent event) {
+        if (event.getStateChange() == ItemEvent.SELECTED) {
+            enableConcurrentDwn(true);
+        } else {
+            enableConcurrentDwn(false);
+        }
+    }
+
 }

Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
(original)
+++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
Mon Mar 21 21:20:56 2011
@@ -28,12 +28,19 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.jmeter.config.Argument;
@@ -48,9 +55,9 @@ import org.apache.jmeter.protocol.http.p
 import org.apache.jmeter.protocol.http.util.ConversionUtils;
 import org.apache.jmeter.protocol.http.util.EncoderCache;
 import org.apache.jmeter.protocol.http.util.HTTPArgument;
+import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
 import org.apache.jmeter.protocol.http.util.HTTPFileArg;
 import org.apache.jmeter.protocol.http.util.HTTPFileArgs;
-import org.apache.jmeter.protocol.http.util.HTTPConstantsInterface;
 import org.apache.jmeter.samplers.AbstractSampler;
 import org.apache.jmeter.samplers.Entry;
 import org.apache.jmeter.samplers.SampleResult;
@@ -139,11 +146,22 @@ public abstract class HTTPSamplerBase ex
     public static final String DO_MULTIPART_POST = "HTTPSampler.DO_MULTIPART_POST"; // $NON-NLS-1$
 
     public static final String BROWSER_COMPATIBLE_MULTIPART  = "HTTPSampler.BROWSER_COMPATIBLE_MULTIPART";
// $NON-NLS-1$
+    
+    public static final String CONCURRENT_DWN = "HTTPSampler.concurrentDwn"; // $NON-NLS-1$
+    
+    public static final String CONCURRENT_POOL = "HTTPSampler.concurrentPool"; // $NON-NLS-1$
 
     //- JMX names
 
     public static final boolean BROWSER_COMPATIBLE_MULTIPART_MODE_DEFAULT = false; // The
default setting to be used (i.e. historic)
     
+    private static final long KEEPALIVETIME = 0; // for Thread Pool for resources but no
need to use a special value?
+    
+    private static final long AWAIT_TERMINATION_TIMEOUT = 
+        JMeterUtils.getPropDefault("httpsampler.await_termination_timeout", 60); // $NON-NLS-1$
// default value: 60 secs 
+    
+    public static final int CONCURRENT_POOL_SIZE = 4; // Default concurrent pool size for
download embedded resources
+    
     
     public static final String DEFAULT_METHOD = GET; // $NON-NLS-1$
     // Supported methods:
@@ -1107,6 +1125,10 @@ public abstract class HTTPSamplerBase ex
                     log.warn("Ignoring embedded URL match string: "+e.getMessage());
                 }
             }
+            
+            // For concurrent get resources
+            final ArrayList<ASyncSample> liste = new ArrayList<ASyncSample>();
+            
             while (urls.hasNext()) {
                 Object binURL = urls.next(); // See catch clause below
                 try {
@@ -1129,9 +1151,17 @@ public abstract class HTTPSamplerBase ex
                         if (pattern != null && localMatcher != null && !localMatcher.matches(urlStrEnc,
pattern)) {
                             continue; // we have a pattern and the URL does not match, so
skip it
                         }
-                        HTTPSampleResult binRes = sample(url, GET, false, frameDepth + 1);
-                        res.addSubResult(binRes);
-                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
+                        
+                        if (isConcurrentDwn()) {
+                            // if concurrent download emb. resources, add to a list for async
gets later
+                            liste.add(new ASyncSample(url, GET, false, frameDepth + 1));
+                        } else {
+                            // default: serial download embedded resources
+                            HTTPSampleResult binRes = sample(url, GET, false, frameDepth
+ 1);
+                            res.addSubResult(binRes);
+                            res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
+                        }
+
                     }
                 } catch (ClassCastException e) { // TODO can this happen?
                     res.addSubResult(errorResult(new Exception(binURL + " is not a correct
URI"), res));
@@ -1139,6 +1169,42 @@ public abstract class HTTPSamplerBase ex
                     continue;
                 }
             }
+            
+            // IF for download concurrent embedded resources
+            if (isConcurrentDwn()) {
+                int poolSize = CONCURRENT_POOL_SIZE; // init with default value
+                try {
+                    poolSize = Integer.parseInt(getConcurrentPool());
+                } catch (NumberFormatException nfe) {
+                    log.warn("Concurrent download resources selected, "// $NON-NLS-1$
+                            + "but pool size value is bad. Use default value");// $NON-NLS-1$
+                }
+                // Thread pool Executor to get resources 
+                // use a LinkedBlockingQueue, note: max pool size doesn't effect
+                final ThreadPoolExecutor exec = new ThreadPoolExecutor(
+                        poolSize, poolSize, KEEPALIVETIME, TimeUnit.SECONDS,
+                        new LinkedBlockingQueue<Runnable>());
+
+                try {
+                    // sample all resources with threadpool
+                    final List<Future<HTTPSampleResult>> retExec = exec.invokeAll(liste);
+                    // call normal shutdown (wait ending all tasks)
+                    exec.shutdown();
+                    // put a timeout if tasks couldn't terminate
+                    exec.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS);
+
+                    // add result to main sampleResult
+                    for (Future<HTTPSampleResult> future : retExec) {
+                        final HTTPSampleResult binRes = future.get();
+                        res.addSubResult(binRes);
+                        res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
+                    }
+                } catch (InterruptedException ie) {
+                    log.warn("Interruped fetching embedded resources", ie); // $NON-NLS-1$
+                } catch (ExecutionException ee) {
+                    log.warn("Execution issue when fetching embedded resources", ee); //
$NON-NLS-1$
+                }
+            }
         }
         return res;
     }
@@ -1565,5 +1631,53 @@ public abstract class HTTPSamplerBase ex
     public String getIpSource() {
         return getPropertyAsString(IP_SOURCE,"");
     }
+    
+    /**
+     * Return if used a concurrent thread pool to get embedded resources.
+     *
+     * @return true if used
+     */
+    public boolean isConcurrentDwn() {
+        return getPropertyAsBoolean(CONCURRENT_DWN);
+    }
+
+    public void setConcurrentDwn(boolean concurrentDwn) {
+        setProperty(new BooleanProperty(CONCURRENT_DWN, concurrentDwn));
+    }
+    /**
+     * Get the pool size for concurrent thread pool to get embedded resources.
+     *
+     * @return the pool size
+     */
+    public String getConcurrentPool() {
+        return getPropertyAsString(CONCURRENT_POOL,"4");
+    }
+
+    public void setConcurrentPool(String poolSize) {
+        setProperty(new StringProperty(CONCURRENT_POOL, poolSize));
+    }
+
+    /**
+     * Callable class to sample asynchronously resources embedded
+     *
+     */
+    public class ASyncSample implements Callable<HTTPSampleResult> {
+        final private URL url;
+        final private String method;
+        final private boolean areFollowingRedirect;
+        final private int depth;
+
+        public ASyncSample(URL url, String method,
+                boolean areFollowingRedirect, int depth){
+            this.url = url;
+            this.method = method;
+            this.areFollowingRedirect = areFollowingRedirect;
+            this.depth = depth;
+        }
+
+        public HTTPSampleResult call() {
+            return sample(url, method, areFollowingRedirect, depth);
+        }
+    }
 }
 

Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Mar 21 21:20:56 2011
@@ -147,6 +147,7 @@ Fixed RMI startup to provide location of
 <li>AJP Sampler now implements Interruptible</li>
 <li>Allow HTTP implementation to be selected at run-time</li>
 <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart
POST</li>
+<li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
 </ul>
 
 <h3>Other samplers</h3>

Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-config/http-request-defaults.png?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
Binary files - no diff available.

Modified: jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/http-request.png?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
Binary files - no diff available.

Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1083962&r1=1083961&r2=1083962&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Mar 21 21:20:56 2011
@@ -81,7 +81,7 @@ Latency is set to the time it takes to l
 
 </component>
 
-<component name="HTTP Request" index="&sect-num;.1.2"  width="851" height="661" screenshot="http-request.png">
+<component name="HTTP Request" index="&sect-num;.1.2" screenshot="http-request.png">
 
 <description>
         <p>This sampler lets you send an HTTP/HTTPS request to a web server.  It
@@ -271,6 +271,8 @@ and send HTTP/HTTPS requests for all ima
         So if you only want to download embedded resources from http://example.com/, use
the expression:
         http://example\.com/.*
         </property>
+        <property name="Use concurrent pool" required="No">Use a pool of concurrent
connections to get embedded resources.</property>
+        <property name="Size" required="No">Pool size for concurrent connections used
to get embedded resources.</property>
         <property name="Source IP address:" required="No">
         [Only for HTTP Request HTTPClient] 
         Override the default local IP address for this sample.
@@ -3076,7 +3078,7 @@ cookie table entries.</property>
 </component>
 
 <component name="HTTP Request Defaults" index="&sect-num;.4.5" 
-         width="678" height="447" screenshot="http-config/http-request-defaults.png">
+         screenshot="http-config/http-request-defaults.png">
 <description><p>This element lets you set default values that your HTTP Request
controllers use.  For example, if you are
 creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent
to the same server,
 you could add a single HTTP Request Defaults element with the "Server Name or IP" field filled
in.  Then, when
@@ -3118,6 +3120,8 @@ JMeter 2.3 and later treat all port valu
         <property name="Retrieve All Embedded Resources from HTML Files" required="No">Tell
JMeter to parse the HTML file
 and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSSs, etc. referenced
in the file.
         </property>
+        <property name="Use concurrent pool" required="No">Use a pool of concurrent
connections to get embedded resources.</property>
+        <property name="Size" required="No">Pool size for concurrent connections used
to get embedded resources.</property>
 </properties>
 </component>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
For additional commands, e-mail: notifications-help@jakarta.apache.org


Mime
View raw message