📄 sampleresult.java
字号:
/*
* 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.jmeter.samplers;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.jmeter.assertions.AssertionResult;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.log.Logger;
// For unit tests, @see TestSampleResult
/**
* This is a nice packaging for the various information returned from taking a
* sample of an entry.
*
*/
public class SampleResult implements Serializable {
public static final String DEFAULT_HTTP_ENCODING = "ISO-8859-1"; // $NON-NLS-1$
// Needs to be accessible from Test code
static final Logger log = LoggingManager.getLoggerForClass();
// Bug 33196 - encoding ISO-8859-1 is only suitable for Western countries
// However the suggested System.getProperty("file.encoding") is Cp1252 on
// Windows
// So use a new property with the original value as default
// needs to be accessible from test code
static final String DEFAULT_ENCODING
= JMeterUtils.getPropDefault("sampleresult.default.encoding", // $NON-NLS-1$
DEFAULT_HTTP_ENCODING);
/**
* Data type value indicating that the response data is text.
*
* @see #getDataType
* @see #setDataType(java.lang.String)
*/
public final static String TEXT = "text"; // $NON-NLS-1$
/**
* Data type value indicating that the response data is binary.
*
* @see #getDataType
* @see #setDataType(java.lang.String)
*/
public final static String BINARY = "bin"; // $NON-NLS-1$
/* empty arrays which can be returned instead of null */
private static final byte[] EMPTY_BA = new byte[0];
private static final SampleResult[] EMPTY_SR = new SampleResult[0];
private static final AssertionResult[] EMPTY_AR = new AssertionResult[0];
private SampleSaveConfiguration saveConfig;
private SampleResult parent = null;
/**
* @param propertiesToSave
* The propertiesToSave to set.
*/
public void setSaveConfig(SampleSaveConfiguration propertiesToSave) {
this.saveConfig = propertiesToSave;
}
public SampleSaveConfiguration getSaveConfig() {
return saveConfig;
}
private byte[] responseData = EMPTY_BA;
private String responseCode = "";// Never return null
private String label = "";// Never return null
private String resultFileName = ""; // Filename used by ResultSaver
private String samplerData;
private String threadName = ""; // Never return null
private String responseMessage = "";
private String responseHeaders = ""; // Never return null
private String contentType = ""; // e.g. text/html; charset=utf-8
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
private long startTime = 0;
private long endTime = 0;
private long idleTime = 0;// Allow for non-sample time
private long pauseTime = 0;// Start of pause (if any)
private List assertionResults;
private List subResults;
private String dataType=""; // Don't return null if not set
private boolean success;
private Set files; // files that this sample has been saved in
private String dataEncoding;// (is this really the character set?) e.g.
// ISO-8895-1, UTF-8
private long time = 0; // elapsed time
private long latency = 0; // time to first response
private boolean stopThread = false; // Should thread terminate?
private boolean stopTest = false; // Should test terminate?
private boolean isMonitor = false;
private int sampleCount = 1;
private int bytes = 0;
private volatile int groupThreads = 0; // Active threads in this thread group
private volatile int allThreads = 0; // Active threads in all thread groups
// TODO do contentType and/or dataEncoding belong in HTTPSampleResult instead?
private final static String TOTAL_TIME = "totalTime"; // $NON-NLS-1$
private static final boolean startTimeStamp
= JMeterUtils.getPropDefault("sampleresult.timestamp.start", false); // $NON-NLS-1$
static {
if (startTimeStamp) {
log.info("Note: Sample TimeStamps are START times");
} else {
log.info("Note: Sample TimeStamps are END times");
}
log.info("sampleresult.default.encoding is set to " + DEFAULT_ENCODING);
}
public SampleResult() {
time = 0;
}
/**
* Construct a 'parent' result for an already-existing result, essentially
* cloning it
*
* @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().
}
public boolean isStampedAtStart() {
return startTimeStamp;
}
/**
* Create a sample with a specific elapsed time but don't allow the times to
* be changed later
*
* (only used by HTTPSampleResult)
*
* @param elapsed
* time
* @param atend
* create the sample finishing now, else starting now
*/
protected SampleResult(long elapsed, boolean atend) {
long now = System.currentTimeMillis();
if (atend) {
setTimes(now - elapsed, now);
} else {
setTimes(now, now + elapsed);
}
}
/**
* Create a sample with specific start and end times for test purposes, but
* don't allow the times to be changed later
*
* (used by StatVisualizerModel.Test)
*
* @param start
* start time
* @param end
* end time
*/
public static SampleResult createTestSample(long start, long end) {
SampleResult res = new SampleResult();
res.setStartTime(start);
res.setEndTime(end);
return res;
}
/**
* Create a sample with a specific elapsed time for test purposes, but don't
* allow the times to be changed later
*
* @param elapsed -
* desired elapsed time
*/
public static SampleResult createTestSample(long elapsed) {
long now = System.currentTimeMillis();
return createTestSample(now, now + elapsed);
}
/**
* Allow users to create a sample with specific timestamp and elapsed times
* for cloning purposes, but don't allow the times to be changed later
*
* Currently used by OldSaveService, CSVSaveService and StatisticalSampleResult
*
* @param stamp -
* this may be a start time or an end time
* @param elapsed
*/
public SampleResult(long stamp, long elapsed) {
stampAndTime(stamp, elapsed);
}
// Helper method to maintain timestamp relationships
private void stampAndTime(long stamp, long elapsed) {
if (startTimeStamp) {
startTime = stamp;
endTime = stamp + elapsed;
} else {
startTime = stamp - elapsed;
endTime = stamp;
}
timeStamp = stamp;
time = elapsed;
}
/*
* For use by SaveService only.
*
* @param stamp -
* this may be a start time or an end time
* @param elapsed
*/
public void setStampAndTime(long stamp, long elapsed) {
if (startTime != 0 || endTime != 0){
throw new RuntimeException("Calling setStampAndTime() after start/end times have been set");
}
stampAndTime(stamp, elapsed);
}
/**
* Method to set the elapsed time for a sample. Retained for backward
* compatibility with 3rd party add-ons.
* It is assumed that the method is only called at the end of a sample
* and that timeStamps are end-times
*
* Also used by SampleResultConverter when creating results from files.
*
* Must not be used in conjunction with sampleStart()/End()
*
* @deprecated use sampleStart() and sampleEnd() instead
* @param elapsed
* time in milliseconds
*/
public void setTime(long elapsed) {
if (startTime != 0 || endTime != 0){
throw new RuntimeException("Calling setTime() after start/end times have been set");
}
long now = System.currentTimeMillis();
setTimes(now - elapsed, now);
}
public void setMarked(String filename) {
if (files == null) {
files = new HashSet();
}
files.add(filename);
}
public boolean isMarked(String filename) {
return files != null && files.contains(filename);
}
public String getResponseCode() {
return responseCode;
}
private static final String OK = Integer.toString(HttpURLConnection.HTTP_OK);
/**
* Set response code to OK, i.e. "200"
*
*/
public void setResponseCodeOK(){
responseCode=OK;
}
public void setResponseCode(String code) {
responseCode = code;
}
public boolean isResponseCodeOK(){
return responseCode.equals(OK);
}
public String getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(String msg) {
responseMessage = msg;
}
public void setResponseMessageOK() {
responseMessage = "OK"; // $NON-NLS-1$
}
public String getThreadName() {
return threadName;
}
public void setThreadName(String threadName) {
this.threadName = threadName;
}
/**
* Get the sample timestamp, which may be either the start time or the end time.
*
* @see #getStartTime()
* @see #getEndTime()
*
* @return timeStamp in milliseconds
*/
public long getTimeStamp() {
return timeStamp;
}
public String getSampleLabel() {
return label;
}
public void setSampleLabel(String label) {
this.label = label;
}
public void addAssertionResult(AssertionResult assertResult) {
if (assertionResults == null) {
assertionResults = new ArrayList();
}
assertionResults.add(assertResult);
}
/**
* Gets the assertion results associated with this sample.
*
* @return an array containing the assertion results for this sample.
* Returns empty array if there are no assertion results.
*/
public AssertionResult[] getAssertionResults() {
if (assertionResults == null) {
return EMPTY_AR;
}
return (AssertionResult[]) assertionResults.toArray(new AssertionResult[0]);
}
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();
}
subResults.add(subResult);
// Extend the time to the end of the added sample
setEndTime(subResult.getEndTime());
// Include the byte count for the added sample
setBytes(getBytes() + subResult.getBytes());
subResult.setParent(this);
}
/**
* Add a subresult read from a results file.
*
* As for addSubResult(), except that the fields don't need to be accumulated
*
* @param subResult
*/
public void storeSubResult(SampleResult subResult) {
if (subResults == null) {
subResults = new ArrayList();
}
subResults.add(subResult);
subResult.setParent(this);
}
/**
* Gets the subresults associated with this sample.
*
* @return an array containing the subresults for this sample. Returns an
* empty array if there are no subresults.
*/
public SampleResult[] getSubResults() {
if (subResults == null) {
return EMPTY_SR;
}
return (SampleResult[]) subResults.toArray(new SampleResult[0]);
}
public void configure(Configuration info) {
time = info.getAttributeAsLong(TOTAL_TIME, 0L);
}
/**
* Sets the responseData attribute of the SampleResult object.
*
* If the parameter is null, then the responseData is set to an empty byte array.
* This ensures that getResponseData() can never be null.
*
* @param response
* the new responseData value
*/
public void setResponseData(byte[] response) {
responseData = response == null ? EMPTY_BA : response;
}
/**
* Sets the responseData attribute of the SampleResult object.
*
* @param response
* the new responseData value (String)
*
* @deprecated - only intended for use from BeanShell code
*/
public void setResponseData(String response) {
responseData = response.getBytes();
}
/**
* Gets the responseData attribute of the SampleResult object.
*
* @return the responseData value (cannot be null)
*/
public byte[] getResponseData() {
return responseData;
}
/**
* Gets the responseData of the SampleResult object as a String
*
* @return the responseData value as a String, converted according to the encoding
*/
public String getResponseDataAsString() {
try {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -