/*
* Licensed 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.ngrinder.model;
import com.google.gson.annotations.Expose;
import net.grinder.common.GrinderProperties;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;
import org.hibernate.annotations.Type;
import org.ngrinder.common.util.DateUtils;
import org.ngrinder.common.util.PathUtils;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
import static org.ngrinder.common.util.AccessUtils.getSafe;
/**
* Performance Test Entity.
*/
@SuppressWarnings({"JpaDataSourceORMInspection", "UnusedDeclaration", "JpaAttributeTypeInspection"})
@Entity
@Table(name = "PERF_TEST")
public class PerfTest extends BaseModel<PerfTest> {
private static final int MARGIN_FOR_ABBREVIATION = 8;
private static final int MAX_LONG_STRING_SIZE = 2048;
private static final long serialVersionUID = 1369809450686098944L;
private static final int MAX_STRING_SIZE = 2048;
public PerfTest() {
}
/**
* Constructor.
*
* @param createdUser crested user.
*/
public PerfTest(User createdUser) {
this.setCreatedUser(createdUser);
}
@Expose
@Cloneable
@Column(name = "name")
private String testName;
@Expose
@Cloneable
@Column(name = "tag_string")
private String tagString;
@Expose
@Cloneable
@Column(length = MAX_LONG_STRING_SIZE)
private String description;
@Expose
@Enumerated(EnumType.STRING)
@Column(name = "status")
private Status status;
@Expose
@Cloneable
/** ignoreSampleCount value, default to 0. */
@Column(name = "ignore_sample_count")
private Integer ignoreSampleCount;
@Expose
/** the scheduled time of this test. */
@Column(name = "scheduled_time")
@Index(name = "scheduled_time_index")
private Date scheduledTime;
@Expose
/** the start time of this test. */
@Column(name = "start_time")
private Date startTime;
@Expose
/** the finish time of this test. */
@Column(name = "finish_time")
private Date finishTime;
/**
* the target host to test.
*/
@Expose
@Cloneable
@Column(name = "target_hosts")
private String targetHosts;
/**
* The send mail code.
*/
@Expose
@Cloneable
@Column(name = "send_mail", columnDefinition = "char(1)")
@Type(type = "true_false")
private Boolean sendMail;
/**
* Use rampUp or not.
*/
@Expose
@Cloneable
@Column(name = "use_rampup", columnDefinition = "char(1)")
@Type(type = "true_false")
private Boolean useRampUp;
public RampUp getRampUpType() {
return rampUpType;
}
public void setRampUpType(RampUp rampUpType) {
this.rampUpType = rampUpType;
}
/**
* Use rampUp or not.
*/
@Expose
@Cloneable
@Column(name = "ramp_up_type")
@Enumerated(EnumType.STRING)
private RampUp rampUpType;
/**
* The threshold code, R for run count; D for duration.
*/
@Expose
@Cloneable
@Column(name = "threshold")
private String threshold;
@Expose
@Cloneable
@Column(name = "script_name")
private String scriptName;
@Expose
@Cloneable
@Column(name = "duration")
private Long duration;
@Expose
@Cloneable
@Column(name = "run_count")
private Integer runCount;
@Expose
@Cloneable
@Column(name = "agent_count")
private Integer agentCount;
@Expose
@Cloneable
@Column(name = "vuser_per_agent")
private Integer vuserPerAgent;
@Expose
@Cloneable
@Column(name = "processes")
private Integer processes;
@Expose
@Cloneable
@Column(name = "ramp_up_init_count")
private Integer rampUpInitCount;
@Expose
@Cloneable
@Column(name = "ramp_up_init_sleep_time")
private Integer rampUpInitSleepTime;
@Expose
@Cloneable
@Column(name = "ramp_up_step")
private Integer rampUpStep;
@Expose
@Cloneable
@Column(name = "ramp_up_increment_interval")
private Integer rampUpIncrementInterval;
@Expose
@Cloneable
@Column(name = "threads")
private Integer threads;
// followings are test result members
@Expose
@Column(name = "tests")
private Long tests;
@Expose
@Column(name = "errors")
private Long errors;
@Expose
@Column(name = "mean_test_time")
private Double meanTestTime;
@Expose
@Column(name = "test_time_standard_deviation")
private Double testTimeStandardDeviation;
@Expose
@Column(name = "tps")
private Double tps;
@Expose
@Column(name = "peak_tps")
private Double peakTps;
/**
* Console port for this test. This is the identifier for console
*/
@Column(name = "port")
private Integer port;
@Expose
@Column(name = "test_error_cause")
@Enumerated(EnumType.STRING)
private Status testErrorCause;
@Column(name = "distribution_path")
/** The path used for file distribution */
private String distributionPath;
@Expose
@Column(name = "progress_message", length = MAX_STRING_SIZE)
private String progressMessage;
@Column(name = "last_progress_message", length = MAX_STRING_SIZE)
private String lastProgressMessage;
@Expose
@Column(name = "test_comment", length = MAX_STRING_SIZE)
private String testComment;
@Expose
@Column(name = "script_revision")
private Long scriptRevision;
@Expose
@Column(name = "stop_request")
@Type(type = "true_false")
private Boolean stopRequest;
@Expose
@Cloneable
@Column(name = "region")
private String region;
@Column(name = "safe_distribution")
@Cloneable
@Type(type = "true_false")
private Boolean safeDistribution;
@Transient
private String dateString;
@Transient
private GrinderProperties grinderProperties;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinTable(name = "PERF_TEST_TAG", /** join column */
joinColumns = @JoinColumn(name = "perf_test_id"), /** inverse join column */
inverseJoinColumns = @JoinColumn(name = "tag_id"))
@Sort(comparator = Tag.class, type = SortType.COMPARATOR)
private SortedSet<Tag> tags;
@Column(name = "running_sample", length = 9990)
private String runningSample;
@Column(name = "agent_stat", length = 9990)
private String agentState;
@Column(name = "monitor_stat", length = 2000)
private String monitorState;
@Expose
@Cloneable
@Column(name = "sampling_interval")
private Integer samplingInterval;
@Expose
@Cloneable
@Column(name = "param")
private String param;
@PrePersist
@PreUpdate
public void init() {
this.status = getSafe(this.status, Status.SAVED);
this.agentCount = getSafe(this.agentCount);
this.port = getSafe(this.port);
this.processes = getSafe(this.processes, 1);
this.threads = getSafe(this.threads, 1);
this.scriptName = getSafe(this.scriptName, "");
this.testName = getSafe(this.testName, "");
this.progressMessage = getSafe(this.progressMessage, "");
this.lastProgressMessage = getSafe(this.lastProgressMessage, "");
this.testComment = getSafe(this.testComment, "");
this.threshold = getSafe(this.threshold, "D");
if (isThresholdRunCount()) {
this.setIgnoreSampleCount(0);
} else {
this.ignoreSampleCount = getSafe(this.ignoreSampleCount);
}
this.runCount = getSafe(this.runCount);
this.duration = getSafe(this.duration, 60000L);
this.samplingInterval = getSafe(this.samplingInterval, 2);
this.scriptRevision = getSafe(this.scriptRevision, -1L);
this.param = getSafe(this.param, "");
this.region = getSafe(this.region, "NONE");
this.targetHosts = getSafe(this.targetHosts, "");
this.description = getSafe(this.description, "");
this.tagString = getSafe(this.tagString, "");
this.vuserPerAgent = getSafe(this.vuserPerAgent, 1);
this.safeDistribution = getSafe(this.safeDistribution, false);
this.useRampUp = getSafe(this.useRampUp, false);
this.rampUpInitCount = getSafe(this.rampUpInitCount, 0);
this.rampUpStep = getSafe(this.rampUpStep, 1);
this.rampUpInitSleepTime = getSafe(this.rampUpInitSleepTime, 0);
this.rampUpIncrementInterval = getSafe(this.rampUpIncrementInterval, 1000);
this.rampUpType = getSafe(this.rampUpType, RampUp.PROCESS);
}
public String getTestIdentifier() {
return "perftest_" + getId() + "_" + getLastModifiedUser().getUserId();
}
/**
* Get total required run count. This is calculated by multiplying agent count, threads,
* processes, run count.
*
* @return run count
*/
public long getTotalRunCount() {
return getAgentCount() * getThreads() * getProcesses() * (long) getRunCount();
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
public Date getScheduledTime() {
return scheduledTime;
}
public void setScheduledTime(Date scheduledTime) {
this.scheduledTime = scheduledTime;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getFinishTime() {
return finishTime;
}
public void setFinishTime(Date finishTime) {
this.finishTime = finishTime;
}
public Integer getRunCount() {
return runCount;
}
public void setRunCount(Integer runCount) {
this.runCount = runCount;
}
public Long getDuration() {
return duration;
}
public void setDuration(Long duration) {
this.duration = duration;
}
public String getScriptName() {
return scriptName;
}
public void setScriptName(String scriptName) {
this.scriptName = scriptName;
}
public Integer getIgnoreSampleCount() {
return ignoreSampleCount;
}
public void setIgnoreSampleCount(Integer ignoreSampleCount) {
this.ignoreSampleCount = ignoreSampleCount;
}
public String getScriptNameInShort() {
return PathUtils.getShortPath(scriptName);
}
public String getDescription() {
return StringUtils.abbreviate(description, MAX_LONG_STRING_SIZE - MARGIN_FOR_ABBREVIATION);
}
public String getLastModifiedDateToStr() {
return DateUtils.dateToString(getLastModifiedDate());
}
public void setDescription(String description) {
this.description = description;
}
public String getTargetHosts() {
return targetHosts;
}
/**
* Get ip address of target hosts. if target hosts 'a.com:1.1.1.1' add ip: '1.1.1.1' if target
* hosts ':1.1.1.1' add ip: '1.1.1.1' if target hosts '1.1.1.1' add ip: '1.1.1.1'
* if www.test.com:0:0:0:0:0:ffff:3d87:a969 add ip: '0:0:0:0:0:ffff:3d87:a969'
*
* @return host ip list
*/
public List<String> getTargetHostIP() {
List<String> targetIPList = new ArrayList<String>();
String[] hostsList = StringUtils.split(StringUtils.trimToEmpty(targetHosts), ",");
for (String hosts : hostsList) {
String[] addresses = StringUtils.split(hosts, ":");
if (addresses.length <= 2) {
targetIPList.add(addresses[addresses.length - 1]);
} else {
targetIPList.add(hosts.substring(hosts.indexOf(":") + 1, hosts.length()));
}
}
return targetIPList;
}
public void setTargetHosts(String theTarget) {
this.targetHosts = theTarget;
}
public String getThreshold() {
return threshold;
}
public Boolean isThresholdDuration() {
return "D".equals(getThreshold());
}
public Boolean isThresholdRunCount() {
return "R".equals(getThreshold());
}
public void setThreshold(String threshold) {
this.threshold = threshold;
}
public void setGrinderProperties(GrinderProperties properties) {
this.grinderProperties = properties;
}
public GrinderProperties getGrinderProperties() {
return grinderProperties;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public Integer getAgentCount() {
return agentCount;
}
public void setAgentCount(Integer agentCount) {
this.agentCount = agentCount;
}
public Integer getVuserPerAgent() {
return vuserPerAgent;
}
public void setVuserPerAgent(Integer vuserPerAgent) {
this.vuserPerAgent = vuserPerAgent;
}
public Integer getProcesses() {
return processes;
}
public void setProcesses(Integer processes) {
this.processes = processes;
}
public Integer getRampUpInitCount() {
return rampUpInitCount;
}
public void setRampUpInitCount(Integer initProcesses) {
this.rampUpInitCount = initProcesses;
}
public Integer getRampUpInitSleepTime() {
return rampUpInitSleepTime;
}
public void setRampUpInitSleepTime(Integer initSleepTime) {
this.rampUpInitSleepTime = initSleepTime;
}
public Integer getRampUpStep() {
return rampUpStep;
}
public void setRampUpStep(Integer processIncrement) {
this.rampUpStep = processIncrement;
}
public Integer getRampUpIncrementInterval() {
return rampUpIncrementInterval;
}
public void setRampUpIncrementInterval(Integer processIncrementInterval) {
this.rampUpIncrementInterval = processIncrementInterval;
}
public Integer getThreads() {
return threads;
}
public void setThreads(Integer threads) {
this.threads = threads;
}
public Long getTests() {
return tests;
}
public void setTests(Long tests) {
this.tests = tests;
}
public Long getErrors() {
return errors;
}
public void setErrors(Long errors) {
this.errors = errors;
}
public Double getMeanTestTime() {
return meanTestTime;
}
public void setMeanTestTime(Double meanTestTime) {
this.meanTestTime = meanTestTime;
}
public Double getTestTimeStandardDeviation() {
return testTimeStandardDeviation;
}
public void setTestTimeStandardDeviation(Double testTimeStandardDeviation) {
this.testTimeStandardDeviation = testTimeStandardDeviation;
}
public Double getTps() {
return tps;
}
public void setTps(Double tps) {
this.tps = tps;
}
public Double getPeakTps() {
return peakTps;
}
public void setPeakTps(Double peakTps) {
this.peakTps = peakTps;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public Status getTestErrorCause() {
return testErrorCause;
}
public void setTestErrorCause(Status errorCause) {
this.testErrorCause = errorCause;
}
public String getDistributionPath() {
return distributionPath;
}
public void setDistributionPath(String distributionPath) {
this.distributionPath = distributionPath;
}
/**
* Get Duration time in HH:MM:SS style.
*
* @return formatted duration string
*/
public String getDurationStr() {
return DateUtils.ms2Time(this.duration);
}
/**
* Get Running time in HH:MM:SS style.
*
* @return formatted runtime string
*/
public String getRuntimeStr() {
long ms = (this.finishTime == null || this.startTime == null) ? 0 : this.finishTime.getTime()
- this.startTime.getTime();
return DateUtils.ms2Time(ms);
}
@Override
public String toString() {
return ReflectionToStringBuilder.toStringExclude(this, "tags");
}
public String getProgressMessage() {
return progressMessage;
}
public void setProgressMessage(String progressMessage) {
this.progressMessage = StringUtils.defaultIfEmpty(StringUtils.right(progressMessage, MAX_STRING_SIZE), "");
}
public Boolean getStopRequest() {
return stopRequest;
}
public void setStopRequest(Boolean stopRequest) {
this.stopRequest = stopRequest;
}
public String getLastProgressMessage() {
return lastProgressMessage;
}
/**
* Clear the last progress message.
*/
public void clearLastProgressMessage() {
this.lastProgressMessage = "";
}
/**
* Set the last progress message.
*
* @param lastProgressMessage message
*/
public void setLastProgressMessage(String lastProgressMessage) {
if (StringUtils.isEmpty(lastProgressMessage)) {
return;
}
if (!StringUtils.equals(this.lastProgressMessage, lastProgressMessage)) {
setProgressMessage(getProgressMessage() + this.lastProgressMessage + "\n");
}
this.lastProgressMessage = lastProgressMessage;
}
public String getTestComment() {
return testComment;
}
public void setTestComment(String testComment) {
this.testComment = StringUtils.trimToEmpty(StringUtils.right(testComment, MAX_STRING_SIZE));
}
public Long getScriptRevision() {
return scriptRevision;
}
public void setScriptRevision(Long scriptRevision) {
this.scriptRevision = scriptRevision;
}
public String getDateString() {
return dateString;
}
public void setDateString(String dateString) {
this.dateString = dateString;
}
/**
* Clear all messages.
*/
public void clearMessages() {
clearLastProgressMessage();
setProgressMessage("");
}
public Boolean getUseRampUp() {
return useRampUp;
}
public void setUseRampUp(Boolean useRampUp) {
this.useRampUp = useRampUp;
}
public Boolean getSendMail() {
return sendMail;
}
public void setSendMail(Boolean sendMail) {
this.sendMail = sendMail;
}
public String getTagString() {
return tagString;
}
public void setTagString(String tagString) {
this.tagString = tagString;
}
public SortedSet<Tag> getTags() {
return tags;
}
public void setTags(SortedSet<Tag> tags) {
this.tags = tags;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public Boolean getSafeDistribution() {
return safeDistribution == null ? Boolean.FALSE : safeDistribution;
}
public void setSafeDistribution(Boolean safeDistribution) {
this.safeDistribution = safeDistribution;
}
public String getRunningSample() {
return runningSample;
}
public void setRunningSample(String runningSample) {
this.runningSample = runningSample;
}
public String getAgentState() {
return agentState;
}
public void setAgentState(String agentStatus) {
this.agentState = agentStatus;
}
public String getMonitorState() {
return monitorState;
}
public void setMonitorState(String monitorStatus) {
this.monitorState = monitorStatus;
}
public Integer getSamplingInterval() {
return samplingInterval;
}
public void setSamplingInterval(Integer samplingInterval) {
this.samplingInterval = samplingInterval;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public void prepare(boolean isClone) {
if (isClone) {
this.setId(null);
this.setTestComment("");
}
this.useRampUp = getSafe(this.useRampUp);
this.safeDistribution = getSafe(this.safeDistribution);
}
}