You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@jakarta.apache.org by se...@apache.org on 2010/07/08 01:53:11 UTC
svn commit: r961539 - in /jakarta/jmeter/trunk:
src/core/org/apache/jmeter/samplers/SampleResult.java
src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
xdocs/changes.xml xdocs/usermanual/component_reference.xml
Author: sebb
Date: Wed Jul 7 23:53:10 2010
New Revision: 961539
URL: http://svn.apache.org/viewvc?rev=961539&view=rev
Log:
Bug 49560 - wrong "size in bytes" when following redirections
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.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/usermanual/component_reference.xml
Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java?rev=961539&r1=961538&r2=961539&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java Wed Jul 7 23:53:10 2010
@@ -116,9 +116,11 @@ public class SampleResult implements Ser
private String label = "";// Never return null
- private String resultFileName = ""; // Filename used by ResultSaver
+ /** Filename used by ResultSaver */
+ private String resultFileName = "";
- private String samplerData; // The data used by the sampler
+ /** The data used by the sampler */
+ private String samplerData;
private String threadName = ""; // Never return null
@@ -131,7 +133,8 @@ public class SampleResult implements Ser
private String requestHeaders = "";
// TODO timeStamp == 0 means either not yet initialised or no stamp available (e.g. when loading a results file)
- private long timeStamp = 0;// the time stamp - can be start or end
+ /** the time stamp - can be start or end */
+ private long timeStamp = 0;
private long startTime = 0;
@@ -139,7 +142,8 @@ public class SampleResult implements Ser
private long idleTime = 0;// Allow for non-sample time
- private long pauseTime = 0;// Start of pause (if any)
+ /** Start of pause (if any) */
+ private long pauseTime = 0;
private List<AssertionResult> assertionResults;
@@ -150,7 +154,8 @@ public class SampleResult implements Ser
private boolean success;
//@GuardedBy("this"")
- private final Set<String> files = new HashSet<String>(); // files that this sample has been saved in
+ /** files that this sample has been saved in */
+ private final Set<String> files = new HashSet<String>();
private String dataEncoding;// (is this really the character set?) e.g.
// ISO-8895-1, UTF-8
@@ -161,16 +166,22 @@ public class SampleResult implements Ser
// a reference time from the millisecond clock
private static final long referenceTimeMsClock = System.currentTimeMillis();
- private long time = 0; // elapsed time
+ /** elapsed time */
+ private long time = 0;
- private long latency = 0; // time to first response
+ /** time to first response */
+ private long latency = 0;
- private boolean stopThread = false; // Should thread terminate?
+ /** Should thread terminate? */
+ private boolean stopThread = false;
- private boolean stopTest = false; // Should test terminate?
+ /** Should test terminate? */
+ private boolean stopTest = false;
- private boolean stopTestNow = false; // Should test terminate abruptly?
+ /** Should test terminate abruptly? */
+ private boolean stopTestNow = false;
+ /** Is the sampler acting as a monitor? */
private boolean isMonitor = false;
private int sampleCount = 1;
@@ -202,37 +213,45 @@ public class SampleResult implements Ser
}
/**
- * Construct a 'parent' result for an already-existing result, essentially
- * cloning it
- *
- * @param res
- * existing sample result
+ * Copy constructor.
+ *
+ * @param res existing sample result
*/
public SampleResult(SampleResult res) {
- //TODO - why not just copy all the fields? Do we need the calculations that some of the set() methods perform?
- //TODO - why are the following not copied:
- // assertionResults, bytes, idleTime, latency, parent,pauseTime,resultFileName,sampleCount,samplerData,saveConfig
- // stopTest, stopThread, subResults,threadName
- setStartTime(res.getStartTime());
- setEndTime(res.getStartTime());
- // was setElapsed(0) which is the same as setStartTime=setEndTime=now
-
- setSampleLabel(res.getSampleLabel());
- setRequestHeaders(res.getRequestHeaders());
- setResponseData(res.getResponseData());
- setResponseCode(res.getResponseCode());
- setSuccessful(res.isSuccessful());
- setResponseMessage(res.getResponseMessage());
- setDataType(res.getDataType());
- setResponseHeaders(res.getResponseHeaders());
- setContentType(res.getContentType());
- setDataEncoding(res.getDataEncodingNoDefault());
- setURL(res.getURL());
-
- setGroupThreads(res.getGroupThreads());
- setAllThreads(res.getAllThreads());
-
- addSubResult(res); // this will add res.getTime() to getTime().
+ allThreads = res.allThreads;//OK
+ assertionResults = res.assertionResults;// TODO ??
+ bytes = res.bytes;
+ contentType = res.contentType;//OK
+ dataEncoding = res.dataEncoding;//OK
+ dataType = res.dataType;//OK
+ endTime = res.endTime;//OK
+ // files is created automatically, and applies per instance
+ groupThreads = res.groupThreads;//OK
+ idleTime = res.idleTime;
+ isMonitor = res.isMonitor;
+ label = res.label;//OK
+ latency = res.latency;
+ location = res.location;//OK
+ parent = res.parent; // TODO ??
+ pauseTime = res.pauseTime;
+ requestHeaders = res.requestHeaders;//OK
+ responseCode = res.responseCode;//OK
+ responseData = res.responseData;//OK
+ responseHeaders = res.responseHeaders;//OK
+ responseMessage = res.responseMessage;//OK
+ // Don't copy this; it is per instance resultFileName = res.resultFileName;
+ sampleCount = res.sampleCount;
+ samplerData = res.samplerData;
+ saveConfig = res.saveConfig;
+ startTime = res.startTime;//OK
+ stopTest = res.stopTest;
+ stopTestNow = res.stopTestNow;
+ stopThread = res.stopThread;
+ subResults = res.subResults; // TODO ??
+ success = res.success;//OK
+ threadName = res.threadName;//OK
+ time = res.time;
+ timeStamp = res.timeStamp;
}
public boolean isStampedAtStart() {
@@ -460,21 +479,36 @@ public class SampleResult implements Ser
return assertionResults.toArray(new AssertionResult[0]);
}
+ /**
+ * Add a subresult and adjust the parent byte count and end-time.
+ *
+ * @param subResult
+ */
public void addSubResult(SampleResult subResult) {
String tn = getThreadName();
if (tn.length()==0) {
tn=Thread.currentThread().getName();//TODO do this more efficiently
this.setThreadName(tn);
}
- subResult.setThreadName(tn);
- if (subResults == null) {
- subResults = new ArrayList<SampleResult>();
- }
- subResults.add(subResult);
+ subResult.setThreadName(tn); // TODO is this really necessary?
+
// Extend the time to the end of the added sample
setEndTime(Math.max(getEndTime(), subResult.getEndTime()));
// Include the byte count for the added sample
setBytes(getBytes() + subResult.getBytes());
+ addRawSubResult(subResult);
+ }
+
+ /**
+ * Add a subresult to the collection without updating any parent fields.
+ *
+ * @param subResult
+ */
+ public void addRawSubResult(SampleResult subResult){
+ if (subResults == null) {
+ subResults = new ArrayList<SampleResult>();
+ }
+ subResults.add(subResult);
subResult.setParent(this);
}
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=961539&r1=961538&r2=961539&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 Wed Jul 7 23:53:10 2010
@@ -1038,22 +1038,15 @@ public abstract class HTTPSamplerBase ex
/**
* Download the resources of an HTML page.
- * <p>
- * If createContainerResult is true, the returned result will contain one
- * subsample for each request issued, including the original one that was
- * passed in. It will otherwise look exactly like that original one.
- * <p>
- * If createContainerResult is false, one subsample will be added to the
- * provided result for each requests issued.
- *
+ *
* @param res
* result of the initial request - must contain an HTML response
* @param container
- * for storing the results
+ * for storing the results, if any
* @param frameDepth
* Depth of this target in the frame structure. Used only to
* prevent infinite recursion.
- * @return "Container" result with one subsample per request issued
+ * @return res if no resources exist, otherwise the "Container" result with one subsample per request issued
*/
protected HTTPSampleResult downloadPageResources(HTTPSampleResult res, HTTPSampleResult container, int frameDepth) {
Iterator<URL> urls = null;
@@ -1079,11 +1072,7 @@ public abstract class HTTPSamplerBase ex
// Iterate through the URLs and download each image:
if (urls != null && urls.hasNext()) {
- if (container == null) {
- res = new HTTPSampleResult(res);
- } else {
- res = container;
- }
+ res = container;
// Get the URL matcher
String re=getEmbeddedUrlRE();
@@ -1098,7 +1087,7 @@ public abstract class HTTPSamplerBase ex
}
}
while (urls.hasNext()) {
- Object binURL = urls.next();
+ Object binURL = urls.next(); // See catch clause below
try {
URL url = (URL) binURL;
if (url == null) {
@@ -1123,7 +1112,7 @@ public abstract class HTTPSamplerBase ex
res.addSubResult(binRes);
res.setSuccessful(res.isSuccessful() && binRes.isSuccessful());
}
- } catch (ClassCastException e) {
+ } catch (ClassCastException e) { // TODO can this happen?
res.addSubResult(errorResult(new Exception(binURL + " is not a correct URI"), res));
res.setSuccessful(false);
continue;
@@ -1219,6 +1208,7 @@ public abstract class HTTPSamplerBase ex
*/
protected HTTPSampleResult followRedirects(HTTPSampleResult res, int frameDepth) {
HTTPSampleResult totalRes = new HTTPSampleResult(res);
+ totalRes.addRawSubResult(res);
HTTPSampleResult lastRes = res;
int redirect;
Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=961539&r1=961538&r2=961539&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Wed Jul 7 23:53:10 2010
@@ -79,6 +79,11 @@ JMSConfigGui has been renamed as JMSSamp
This does not affect existing test plans.
</p>
+<p>
+The constructor public SampleResult(SampleResult res) has been changed to become a true "copy constructor".
+It no longer calls addSubResult(). This may possibly affect some 3rd party add-ons.
+</p>
+
<h2>Bug fixes</h2>
<h3>HTTP Samplers and Proxy</h3>
@@ -92,6 +97,7 @@ This does not affect existing test plans
<li>Bug 46901 - HTTP Sampler does not process var/func refs correctly in first file parameter</li>
<li>Bug 43678 - Handle META tag http-equiv charset?</li>
<li>Bug 49294 - Images not downloaded from redirected-to pages</li>
+<li>Bug 49560 - wrong "size in bytes" when following redirections</li>
</ul>
<h3>Other Samplers</h3>
Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=961539&r1=961538&r2=961539&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Wed Jul 7 23:53:10 2010
@@ -193,13 +193,16 @@ https.default.protocol=SSLv3
<property name="Follow Redirects" required="Yes">
This only has any effect if "Redirect Automatically" is not enabled.
If set, the JMeter sampler will check if the response is a redirect and follow it if so.
- The redirect response will appear as an additional sample.
+ The initial redirect and further responses will appear as additional samples.
+ The URL and data fields of the parent sample will be taken from the final (non-redirected)
+ sample, but the parent byte count and elapsed time include all samples.
+ The latency is taken from the initial response (versions of JMeter after 2.3.4 - previously it was zero).
Note that the HttpClient sampler may log the following message:<br/>
"Redirect requested but followRedirects is disabled"<br/>
This can be ignored.
<br/>
In versions after 2.3.4, JMeter will collapse paths of the form '/../segment' in
- both absolute and relative URLs. For example http://host/one/../two => http://host/two.
+ both absolute and relative redirect URLs. For example http://host/one/../two => http://host/two.
If necessary, this behaviour can be suppressed by setting the JMeter property
<code>httpsampler.redirect.removeslashdotdot=false</code>
</property>
@@ -315,7 +318,7 @@ JMeter 2.1.2 introduces the a new proper
If the HTTPResponse.parser property is not set, JMeter reverts to the previous behaviour,
i.e. only text/html responses will be scanned</p>
<b>Emulating slow connections (HttpClient only):</b><br></br>
-The HttpClient version of the sampler supports emulation of slow connections; see the following entries in jmeter.proerties:
+The HttpClient version of the sampler supports emulation of slow connections; see the following entries in jmeter.properties:
<pre>
# Define characters per second > 0 to emulate slow connections
#httpclient.socket.http.cps=0
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
For additional commands, e-mail: notifications-help@jakarta.apache.org