package org.apache.jmeter.samplers;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.jmeter.assertions.AssertionResult;
import org.apache.jmeter.gui.Searchable;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.util.JOrphanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SampleResult implements Serializable, Cloneable, Searchable {
private static final long serialVersionUID = 241L;
static Logger log = LoggerFactory.getLogger(SampleResult.class);
public static final String DEFAULT_HTTP_ENCODING;
private static final String OK_CODE;
private static final String OK_MSG = "OK";
protected static final String DEFAULT_ENCODING;
private static final String DEFAULT_CHARSET;
public static final String TEXT = "text";
public static final String BINARY = "bin";
private static final String[] BINARY_TYPES;
private static final String[] NON_BINARY_TYPES;
private static final byte[] EMPTY_BA;
private static final SampleResult[] EMPTY_SR;
private static final AssertionResult[] EMPTY_AR;
private static final boolean GETBYTES_BODY_REALSIZE;
private static final boolean GETBYTES_HEADERS_SIZE;
private static final boolean GETBYTES_NETWORK_SIZE;
private static final boolean START_TIMESTAMP;
private static final boolean USE_NANO_TIME;
private static final long NANOTHREAD_SLEEP;
private SampleSaveConfiguration saveConfig;
private SampleResult parent;
private byte[] responseData;
private String responseCode;
private String label;
private String resultFileName;
private String samplerData;
private String threadName;
private String responseMessage;
private String responseHeaders;
private String requestHeaders;
private long timeStamp;
private long startTime;
private long endTime;
private long idleTime;
private long pauseTime;
private List<AssertionResult> assertionResults;
private List<SampleResult> subResults;
private String dataType;
private boolean success;
private final Set<String> files;
private String dataEncoding;
private String contentType;
private long elapsedTime;
private long latency;
private long connectTime;
private boolean startNextThreadLoop;
private boolean stopThread;
private boolean stopTest;
private boolean stopTestNow;
private int sampleCount;
private long bytes;
private int headersSize;
private long bodySize;
private volatile int groupThreads;
private volatile int allThreads;
private final long nanoTimeOffset;
final boolean useNanoTime;
final long nanoThreadSleep;
private long sentBytes;
private URL location;
private transient volatile String responseDataAsString;
public SampleResult() {
this(USE_NANO_TIME, NANOTHREAD_SLEEP);
}
SampleResult(boolean nanoTime) {
this(nanoTime, NANOTHREAD_SLEEP);
}
SampleResult(boolean nanoTime, long nanoThreadSleep) {
this.responseData = EMPTY_BA;
this.responseCode = "";
this.label = "";
this.resultFileName = "";
this.threadName = "";
this.responseMessage = "";
this.responseHeaders = "";
this.requestHeaders = "";
this.timeStamp = 0L;
this.startTime = 0L;
this.endTime = 0L;
this.idleTime = 0L;
this.pauseTime = 0L;
this.dataType = "";
this.files = new HashSet(3);
this.contentType = "";
this.elapsedTime = 0L;
this.latency = 0L;
this.connectTime = 0L;
this.startNextThreadLoop = false;
this.stopThread = false;
this.stopTest = false;
this.stopTestNow = false;
this.sampleCount = 1;
this.bytes = 0L;
this.headersSize = 0;
this.bodySize = 0L;
this.groupThreads = 0;
this.allThreads = 0;
this.elapsedTime = 0L;
this.useNanoTime = nanoTime;
this.nanoThreadSleep = nanoThreadSleep;
this.nanoTimeOffset = this.initOffset();
}
public SampleResult(SampleResult res) {
this();
this.allThreads = res.allThreads;
this.assertionResults = res.assertionResults;
this.bytes = res.bytes;
this.headersSize = res.headersSize;
this.bodySize = res.bodySize;
this.contentType = res.contentType;
this.dataEncoding = res.dataEncoding;
this.dataType = res.dataType;
this.endTime = res.endTime;
this.groupThreads = res.groupThreads;
this.idleTime = res.idleTime;
this.label = res.label;
this.latency = res.latency;
this.connectTime = res.connectTime;
this.location = res.location;
this.parent = res.parent;
this.pauseTime = res.pauseTime;
this.requestHeaders = res.requestHeaders;
this.responseCode = res.responseCode;
this.responseData = res.responseData;
this.responseDataAsString = null;
this.responseHeaders = res.responseHeaders;
this.responseMessage = res.responseMessage;
this.sampleCount = res.sampleCount;
this.samplerData = res.samplerData;
this.saveConfig = res.saveConfig;
this.sentBytes = res.sentBytes;
this.startTime = res.startTime;
this.stopTest = res.stopTest;
this.stopTestNow = res.stopTestNow;
this.stopThread = res.stopThread;
this.startNextThreadLoop = res.startNextThreadLoop;
this.subResults = res.subResults;
this.success = res.success;
this.threadName = res.threadName;
this.elapsedTime = res.elapsedTime;
this.timeStamp = res.timeStamp;
}
protected SampleResult(long elapsed, boolean atend) {
this();
long now = this.currentTimeInMillis();
if (atend) {
this.setTimes(now - elapsed, now);
} else {
this.setTimes(now, now + elapsed);
}
}
public SampleResult(long stamp, long elapsed) {
this();
this.stampAndTime(stamp, elapsed);
}
private long initOffset() {
if (this.useNanoTime) {
return this.nanoThreadSleep > 0L ? SampleResult.NanoOffset.getNanoOffset() : System.currentTimeMillis() - sampleNsClockInMs();
} else {
return -9223372036854775808L;
}
}
public void setSaveConfig(SampleSaveConfiguration propertiesToSave) {
this.saveConfig = propertiesToSave;
}
public SampleSaveConfiguration getSaveConfig() {
return this.saveConfig;
}
public boolean isStampedAtStart() {
return START_TIMESTAMP;
}
public static SampleResult createTestSample(long start, long end) {
SampleResult res = new SampleResult();
res.setStartTime(start);
res.setEndTime(end);
return res;
}
public static SampleResult createTestSample(long elapsed) {
long now = System.currentTimeMillis();
return createTestSample(now, now + elapsed);
}
private static long sampleNsClockInMs() {
return System.nanoTime() / 1000000L;
}
public long currentTimeInMillis() {
if (this.useNanoTime) {
if (this.nanoTimeOffset == -9223372036854775808L) {
throw new RuntimeException("Invalid call; nanoTimeOffset as not been set");
} else {
return sampleNsClockInMs() + this.nanoTimeOffset;
}
} else {
return System.currentTimeMillis();
}
}
private void stampAndTime(long stamp, long elapsed) {
if (START_TIMESTAMP) {
this.startTime = stamp;
this.endTime = stamp + elapsed;
} else {
this.startTime = stamp - elapsed;
this.endTime = stamp;
}
this.timeStamp = stamp;
this.elapsedTime = elapsed;
}
public void setStampAndTime(long stamp, long elapsed) {
if (this.startTime == 0L && this.endTime == 0L) {
this.stampAndTime(stamp, elapsed);
} else {
throw new RuntimeException("Calling setStampAndTime() after start/end times have been set");
}
}
public synchronized boolean markFile(String filename) {
return !this.files.add(filename);
}
public String getResponseCode() {
return this.responseCode;
}
public void setResponseCodeOK() {
this.responseCode = OK_CODE;
}
public void setResponseCode(String code) {
this.responseCode = code;
}
public boolean isResponseCodeOK() {
return this.responseCode.equals(OK_CODE);
}
public String getResponseMessage() {
return this.responseMessage;
}
public void setResponseMessage(String msg) {
this.responseMessage = msg;
}
public void setResponseMessageOK() {
this.responseMessage = "OK";
}
public void setResponseOK() {
this.setResponseCodeOK();
this.setResponseMessageOK();
this.setSuccessful(true);
}
public String getThreadName() {
return this.threadName;
}
public void setThreadName(String threadName) {
this.threadName = threadName;
}
public long getTimeStamp() {
return this.timeStamp;
}
public String getSampleLabel() {
return this.label;
}
public String getSampleLabel(boolean includeGroup) {
if (includeGroup) {
StringBuilder sb = new StringBuilder(this.threadName.substring(0, this.threadName.lastIndexOf(32)));
return sb.append(":").append(this.label).toString();
} else {
return this.label;
}
}
public void setSampleLabel(String label) {
this.label = label;
}
public void addAssertionResult(AssertionResult assertResult) {
if (this.assertionResults == null) {
this.assertionResults = new ArrayList();
}
this.assertionResults.add(assertResult);
}
public AssertionResult[] getAssertionResults() {
return this.assertionResults == null ? EMPTY_AR : (AssertionResult[])this.assertionResults.toArray(new AssertionResult[this.assertionResults.size()]);
}
public void addSubResult(SampleResult subResult) {
if (subResult != null) {
String tn = this.getThreadName();
if (tn.length() == 0) {
tn = Thread.currentThread().getName();
this.setThreadName(tn);
}
subResult.setThreadName(tn);
this.setEndTime(Math.max(this.getEndTime(), subResult.getEndTime() + this.nanoTimeOffset - subResult.nanoTimeOffset));
this.setBytes(this.getBytesAsLong() + subResult.getBytesAsLong());
this.setSentBytes(this.getSentBytes() + subResult.getSentBytes());
this.setHeadersSize(this.getHeadersSize() + subResult.getHeadersSize());
this.setBodySize(this.getBodySizeAsLong() + subResult.getBodySizeAsLong());
this.addRawSubResult(subResult);
}
}
public void addRawSubResult(SampleResult subResult) {
this.storeSubResult(subResult);
}
public void storeSubResult(SampleResult subResult) {
if (this.subResults == null) {
this.subResults = new ArrayList();
}
this.subResults.add(subResult);
subResult.setParent(this);
}
public SampleResult[] getSubResults() {
return this.subResults == null ? EMPTY_SR : (SampleResult[])this.subResults.toArray(new SampleResult[this.subResults.size()]);
}
public void setResponseData(byte[] response) {
this.responseDataAsString = null;
this.responseData = response == null ? EMPTY_BA : response;
}
/** @deprecated */
@Deprecated
public void setResponseData(String response) {
this.responseDataAsString = null;
try {
this.responseData = response.getBytes(this.getDataEncodingWithDefault());
} catch (UnsupportedEncodingException var3) {
log.warn("Could not convert string, using default encoding. " + var3.getLocalizedMessage());
this.responseData = response.getBytes(Charset.defaultCharset());
}
}
public void setResponseData(String response, String encoding) {
this.responseDataAsString = null;
String encodeUsing = encoding != null ? encoding : DEFAULT_CHARSET;
try {
this.responseData = response.getBytes(encodeUsing);
this.setDataEncoding(encodeUsing);
} catch (UnsupportedEncodingException var5) {
log.warn("Could not convert string using '" + encodeUsing + "', using default encoding: " + DEFAULT_CHARSET, var5);
this.responseData = response.getBytes(Charset.defaultCharset());
this.setDataEncoding(DEFAULT_CHARSET);
}
}
public byte[] getResponseData() {
return this.responseData;
}
public String getResponseDataAsString() {
try {
if (this.responseDataAsString == null) {
this.responseDataAsString = new String(this.responseData, this.getDataEncodingWithDefault());
}
return this.responseDataAsString;
} catch (UnsupportedEncodingException var2) {
log.warn("Using platform default as " + this.getDataEncodingWithDefault() + " caused " + var2);
return new String(this.responseData, Charset.defaultCharset());
}
}
public void setSamplerData(String s) {
this.samplerData = s;
}
public String getSamplerData() {
return this.samplerData;
}
public long getTime() {
return this.elapsedTime;
}
public boolean isSuccessful() {
return this.success;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getDataType() {
return this.dataType;
}
public void setEncodingAndType(String ct) {
if (ct != null) {
String charsetPrefix = "charset=";
int cset = ct.toLowerCase(Locale.ENGLISH).indexOf("charset=");
if (cset >= 0) {
String charSet = ct.substring(cset + "charset=".length());
int semiColon = charSet.indexOf(59);
if (semiColon >= 0) {
charSet = charSet.substring(0, semiColon);
}
if (!charSet.startsWith("\"") && !charSet.startsWith("'")) {
this.setDataEncoding(charSet);
} else {
this.setDataEncoding(charSet.substring(1, charSet.length() - 1));
}
}
if (isBinaryType(ct)) {
this.setDataType("bin");
} else {
this.setDataType("text");
}
}
}
private static boolean isBinaryType(String ct) {
String[] var1 = NON_BINARY_TYPES;
int var2 = var1.length;
int var3;
String binaryType;
for(var3 = 0; var3 < var2; ++var3) {
binaryType = var1[var3];
if (ct.startsWith(binaryType)) {
return false;
}
}
var1 = BINARY_TYPES;
var2 = var1.length;
for(var3 = 0; var3 < var2; ++var3) {
binaryType = var1[var3];
if (ct.startsWith(binaryType)) {
return true;
}
}
return false;
}
public void setSuccessful(boolean success) {
this.success = success;
}
public String toString() {
return this.getSampleLabel();
}
public String getDataEncodingWithDefault() {
return this.getDataEncodingWithDefault(DEFAULT_ENCODING);
}
protected String getDataEncodingWithDefault(String defaultEncoding) {
return this.dataEncoding != null && this.dataEncoding.length() > 0 ? this.dataEncoding : defaultEncoding;
}
public String getDataEncodingNoDefault() {
return this.dataEncoding;
}
public void setDataEncoding(String dataEncoding) {
this.dataEncoding = dataEncoding;
}
public boolean isStopTest() {
return this.stopTest;
}
public boolean isStopTestNow() {
return this.stopTestNow;
}
public boolean isStopThread() {
return this.stopThread;
}
public void setStopTest(boolean b) {
this.stopTest = b;
}
public void setStopTestNow(boolean b) {
this.stopTestNow = b;
}
public void setStopThread(boolean b) {
this.stopThread = b;
}
public String getRequestHeaders() {
return this.requestHeaders;
}
public String getResponseHeaders() {
return this.responseHeaders;
}
public void setRequestHeaders(String string) {
this.requestHeaders = string;
}
public void setResponseHeaders(String string) {
this.responseHeaders = string;
}
public String getContentType() {
return this.contentType;
}
public String getMediaType() {
return JOrphanUtils.trim(this.contentType, " ;").toLowerCase(Locale.ENGLISH);
}
public void setContentType(String string) {
this.contentType = string;
}
public long getIdleTime() {
return this.idleTime;
}
public long getEndTime() {
return this.endTime;
}
public long getStartTime() {
return this.startTime;
}
protected final void setStartTime(long start) {
this.startTime = start;
if (START_TIMESTAMP) {
this.timeStamp = this.startTime;
}
}
public void setEndTime(long end) {
this.endTime = end;
if (!START_TIMESTAMP) {
this.timeStamp = this.endTime;
}
if (this.startTime == 0L) {
log.error("setEndTime must be called after setStartTime", new Throwable("Invalid call sequence"));
} else {
this.elapsedTime = this.endTime - this.startTime - this.idleTime;
}
}
public void setIdleTime(long idle) {
this.idleTime = idle;
}
private void setTimes(long start, long end) {
this.setStartTime(start);
this.setEndTime(end);
}
public void sampleStart() {
if (this.startTime == 0L) {
this.setStartTime(this.currentTimeInMillis());
} else {
log.error("sampleStart called twice", new Throwable("Invalid call sequence"));
}
}
public void sampleEnd() {
if (this.endTime == 0L) {
this.setEndTime(this.currentTimeInMillis());
} else {
log.error("sampleEnd called twice", new Throwable("Invalid call sequence"));
}
}
public void samplePause() {
if (this.pauseTime != 0L) {
log.error("samplePause called twice", new Throwable("Invalid call sequence"));
}
this.pauseTime = this.currentTimeInMillis();
}
public void sampleResume() {
if (this.pauseTime == 0L) {
log.error("sampleResume without samplePause", new Throwable("Invalid call sequence"));
}
this.idleTime += this.currentTimeInMillis() - this.pauseTime;
this.pauseTime = 0L;
}
/** @deprecated */
@Deprecated
public void setMonitor(boolean monitor) {
}
/** @deprecated */
@Deprecated
public boolean isMonitor() {
return false;
}
public void setSampleCount(int count) {
this.sampleCount = count;
}
public int getSampleCount() {
return this.sampleCount;
}
public int getErrorCount() {
return this.success ? 0 : 1;
}
public void setErrorCount(int i) {
}
public void setBytes(long length) {
this.bytes = length;
}
/** @deprecated */
@Deprecated
public void setBytes(int length) {
this.setBytes((long)length);
}
public void setSentBytes(long sentBytesCount) {
this.sentBytes = sentBytesCount;
}
public long getSentBytes() {
return this.sentBytes;
}
/** @deprecated */
@Deprecated
public int getBytes() {
return (int)this.getBytesAsLong();
}
public long getBytesAsLong() {
if (GETBYTES_NETWORK_SIZE) {
long tmpSum = (long)this.getHeadersSize() + this.getBodySizeAsLong();
return tmpSum == 0L ? this.bytes : tmpSum;
} else if (GETBYTES_HEADERS_SIZE) {
return (long)this.getHeadersSize();
} else if (GETBYTES_BODY_REALSIZE) {
return this.getBodySizeAsLong();
} else {
return this.bytes == 0L ? (long)this.responseData.length : this.bytes;
}
}
public long getLatency() {
return this.latency;
}
public void latencyEnd() {
this.latency = this.currentTimeInMillis() - this.startTime - this.idleTime;
}
public void setLatency(long latency) {
this.latency = latency;
}
public long getConnectTime() {
return this.connectTime;
}
public void connectEnd() {
this.connectTime = this.currentTimeInMillis() - this.startTime - this.idleTime;
}
public void setConnectTime(long time) {
this.connectTime = time;
}
public void setTimeStamp(long timeStamp) {
this.timeStamp = timeStamp;
}
public void setURL(URL location) {
this.location = location;
}
public URL getURL() {
return this.location;
}
public String getUrlAsString() {
return this.location == null ? "" : this.location.toExternalForm();
}
public SampleResult getParent() {
return this.parent;
}
public void setParent(SampleResult parent) {
this.parent = parent;
}
public String getResultFileName() {
return this.resultFileName;
}
public void setResultFileName(String resultFileName) {
this.resultFileName = resultFileName;
}
public int getGroupThreads() {
return this.groupThreads;
}
public void setGroupThreads(int n) {
this.groupThreads = n;
}
public int getAllThreads() {
return this.allThreads;
}
public void setAllThreads(int n) {
this.allThreads = n;
}
public void removeAssertionResults() {
this.assertionResults = null;
}
public void removeSubResults() {
this.subResults = null;
}
public void setHeadersSize(int size) {
this.headersSize = size;
}
public int getHeadersSize() {
return this.headersSize;
}
/** @deprecated */
@Deprecated
public int getBodySize() {
return (int)this.getBodySizeAsLong();
}
public long getBodySizeAsLong() {
return this.bodySize == 0L ? (long)this.responseData.length : this.bodySize;
}
public void setBodySize(long bodySize) {
this.bodySize = bodySize;
}
/** @deprecated */
@Deprecated
public void setBodySize(int bodySize) {
this.bodySize = (long)bodySize;
}
public boolean isStartNextThreadLoop() {
return this.startNextThreadLoop;
}
public void setStartNextThreadLoop(boolean startNextThreadLoop) {
this.startNextThreadLoop = startNextThreadLoop;
}
public void cleanAfterSample() {
this.responseDataAsString = null;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException var2) {
throw new IllegalStateException("This should not happen");
}
}
public List<String> getSearchableTokens() throws Exception {
List<String> datasToSearch = new ArrayList(4);
datasToSearch.add(this.getSampleLabel());
datasToSearch.add(this.getResponseDataAsString());
datasToSearch.add(this.getRequestHeaders());
datasToSearch.add(this.getResponseHeaders());
return datasToSearch;
}
static {
DEFAULT_HTTP_ENCODING = StandardCharsets.ISO_8859_1.name();
OK_CODE = Integer.toString(200);
DEFAULT_ENCODING = JMeterUtils.getPropDefault("sampleresult.default.encoding", DEFAULT_HTTP_ENCODING);
DEFAULT_CHARSET = Charset.defaultCharset().name();
BINARY_TYPES = new String[]{"image/", "audio/", "video/"};
NON_BINARY_TYPES = new String[]{"audio/x-mpegurl", "video/f4m"};
EMPTY_BA = new byte[0];
EMPTY_SR = new SampleResult[0];
EMPTY_AR = new AssertionResult[0];
GETBYTES_BODY_REALSIZE = JMeterUtils.getPropDefault("sampleresult.getbytes.body_real_size", true);
GETBYTES_HEADERS_SIZE = JMeterUtils.getPropDefault("sampleresult.getbytes.headers_size", true);
GETBYTES_NETWORK_SIZE = GETBYTES_HEADERS_SIZE && GETBYTES_BODY_REALSIZE;
START_TIMESTAMP = JMeterUtils.getPropDefault("sampleresult.timestamp.start", false);
USE_NANO_TIME = JMeterUtils.getPropDefault("sampleresult.useNanoTime", true);
NANOTHREAD_SLEEP = (long)JMeterUtils.getPropDefault("sampleresult.nanoThreadSleep", 5000);
if (START_TIMESTAMP) {
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);
log.info("sampleresult.useNanoTime=" + USE_NANO_TIME);
log.info("sampleresult.nanoThreadSleep=" + NANOTHREAD_SLEEP);
if (USE_NANO_TIME && NANOTHREAD_SLEEP > 0L) {
SampleResult.NanoOffset.nanoOffset = System.currentTimeMillis() - sampleNsClockInMs();
SampleResult.NanoOffset nanoOffset = new SampleResult.NanoOffset();
nanoOffset.setDaemon(true);
nanoOffset.setName("NanoOffset");
nanoOffset.start();
}
}
private static class NanoOffset extends Thread {
private static volatile long nanoOffset;
private NanoOffset() {
}
static long getNanoOffset() {
return nanoOffset;
}
public void run() {
getOffset(30L);
while(true) {
getOffset(SampleResult.NANOTHREAD_SLEEP);
}
}
private static void getOffset(long wait) {
try {
TimeUnit.MILLISECONDS.sleep(wait);
long clock = System.currentTimeMillis();
long nano = SampleResult.sampleNsClockInMs();
nanoOffset = clock - nano;
} catch (InterruptedException var6) {
Thread.currentThread().interrupt();
}
}
}
}
网友评论