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="§-num;.1.2" width="851"
height="661" screenshot="http-request.png">
+<component name="HTTP Request" index="§-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="§-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: [email protected]
For additional commands, e-mail: [email protected]