refactor(性能测试): 性能测试重构
This commit is contained in:
parent
2908846e90
commit
29efd7f60e
|
@ -1,7 +1,6 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
|
@ -32,5 +31,7 @@ public class TestResourcePool implements Serializable {
|
|||
|
||||
private Boolean performance;
|
||||
|
||||
private Boolean backendListener;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -973,6 +973,66 @@ public class TestResourcePoolExample {
|
|||
addCriterion("performance not between", value1, value2, "performance");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerIsNull() {
|
||||
addCriterion("backend_listener is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerIsNotNull() {
|
||||
addCriterion("backend_listener is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerEqualTo(Boolean value) {
|
||||
addCriterion("backend_listener =", value, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerNotEqualTo(Boolean value) {
|
||||
addCriterion("backend_listener <>", value, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerGreaterThan(Boolean value) {
|
||||
addCriterion("backend_listener >", value, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerGreaterThanOrEqualTo(Boolean value) {
|
||||
addCriterion("backend_listener >=", value, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerLessThan(Boolean value) {
|
||||
addCriterion("backend_listener <", value, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerLessThanOrEqualTo(Boolean value) {
|
||||
addCriterion("backend_listener <=", value, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerIn(List<Boolean> values) {
|
||||
addCriterion("backend_listener in", values, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerNotIn(List<Boolean> values) {
|
||||
addCriterion("backend_listener not in", values, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerBetween(Boolean value1, Boolean value2) {
|
||||
addCriterion("backend_listener between", value1, value2, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andBackendListenerNotBetween(Boolean value1, Boolean value2) {
|
||||
addCriterion("backend_listener not between", value1, value2, "backendListener");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
|
||||
<result column="api" jdbcType="BIT" property="api" />
|
||||
<result column="performance" jdbcType="BIT" property="performance" />
|
||||
<result column="backend_listener" jdbcType="BIT" property="backendListener" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
|
@ -76,7 +77,7 @@
|
|||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, `name`, `type`, description, `status`, create_time, update_time, image, `heap`,
|
||||
gc_algo, create_user, api, performance
|
||||
gc_algo, create_user, api, performance, backend_listener
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestResourcePoolExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -113,12 +114,12 @@
|
|||
description, `status`, create_time,
|
||||
update_time, image, `heap`,
|
||||
gc_algo, create_user, api,
|
||||
performance)
|
||||
performance, backend_listener)
|
||||
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||
#{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
|
||||
#{updateTime,jdbcType=BIGINT}, #{image,jdbcType=VARCHAR}, #{heap,jdbcType=VARCHAR},
|
||||
#{gcAlgo,jdbcType=VARCHAR}, #{createUser,jdbcType=VARCHAR}, #{api,jdbcType=BIT},
|
||||
#{performance,jdbcType=BIT})
|
||||
#{performance,jdbcType=BIT}, #{backendListener,jdbcType=BIT})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestResourcePool">
|
||||
insert into test_resource_pool
|
||||
|
@ -162,6 +163,9 @@
|
|||
<if test="performance != null">
|
||||
performance,
|
||||
</if>
|
||||
<if test="backendListener != null">
|
||||
backend_listener,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -203,6 +207,9 @@
|
|||
<if test="performance != null">
|
||||
#{performance,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="backendListener != null">
|
||||
#{backendListener,jdbcType=BIT},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.TestResourcePoolExample" resultType="java.lang.Long">
|
||||
|
@ -253,6 +260,9 @@
|
|||
<if test="record.performance != null">
|
||||
performance = #{record.performance,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="record.backendListener != null">
|
||||
backend_listener = #{record.backendListener,jdbcType=BIT},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -272,7 +282,8 @@
|
|||
gc_algo = #{record.gcAlgo,jdbcType=VARCHAR},
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||
api = #{record.api,jdbcType=BIT},
|
||||
performance = #{record.performance,jdbcType=BIT}
|
||||
performance = #{record.performance,jdbcType=BIT},
|
||||
backend_listener = #{record.backendListener,jdbcType=BIT}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -316,6 +327,9 @@
|
|||
<if test="performance != null">
|
||||
performance = #{performance,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="backendListener != null">
|
||||
backend_listener = #{backendListener,jdbcType=BIT},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
@ -332,7 +346,8 @@
|
|||
gc_algo = #{gcAlgo,jdbcType=VARCHAR},
|
||||
create_user = #{createUser,jdbcType=VARCHAR},
|
||||
api = #{api,jdbcType=BIT},
|
||||
performance = #{performance,jdbcType=BIT}
|
||||
performance = #{performance,jdbcType=BIT},
|
||||
backend_listener = #{backendListener,jdbcType=BIT}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -33,6 +33,7 @@ public abstract class AbstractEngine implements Engine {
|
|||
protected PerformanceTestService performanceTestService;
|
||||
protected Integer threadNum;
|
||||
protected List<TestResource> resourceList;
|
||||
protected TestResourcePool resourcePool;
|
||||
private final TestResourcePoolService testResourcePoolService;
|
||||
private final TestResourceService testResourceService;
|
||||
|
||||
|
@ -45,9 +46,10 @@ public abstract class AbstractEngine implements Engine {
|
|||
this.startTime = System.currentTimeMillis();
|
||||
this.reportId = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
protected void initApiConfig(RunRequest runRequest) {
|
||||
String resourcePoolId = runRequest.getPoolId();
|
||||
TestResourcePool resourcePool = testResourcePoolService.getResourcePool(resourcePoolId);
|
||||
resourcePool = testResourcePoolService.getResourcePool(resourcePoolId);
|
||||
if (resourcePool == null || StringUtils.equals(resourcePool.getStatus(), ResourceStatusEnum.DELETE.name())) {
|
||||
MSException.throwException("Resource Pool is empty");
|
||||
}
|
||||
|
@ -78,6 +80,7 @@ public abstract class AbstractEngine implements Engine {
|
|||
MSException.throwException("Test Resource is empty");
|
||||
}
|
||||
}
|
||||
|
||||
protected void init(LoadTestWithBLOBs loadTest) {
|
||||
if (loadTest == null) {
|
||||
MSException.throwException("LoadTest is null.");
|
||||
|
@ -91,7 +94,7 @@ public abstract class AbstractEngine implements Engine {
|
|||
if (StringUtils.isBlank(resourcePoolId)) {
|
||||
MSException.throwException("Resource Pool ID is empty");
|
||||
}
|
||||
TestResourcePool resourcePool = testResourcePoolService.getResourcePool(resourcePoolId);
|
||||
resourcePool = testResourcePoolService.getResourcePool(resourcePoolId);
|
||||
if (resourcePool == null || StringUtils.equals(resourcePool.getStatus(), ResourceStatusEnum.DELETE.name())) {
|
||||
MSException.throwException("Resource Pool is empty");
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ public class DockerTestEngine extends AbstractEngine {
|
|||
env.put("HEAP", HEAP);
|
||||
env.put("GC_ALGO", GC_ALGO);
|
||||
env.put("GRANULARITY", performanceTestService.getGranularity(this.getReportId()).toString());
|
||||
env.put("BACKEND_LISTENER", resourcePool.getBackendListener().toString());
|
||||
|
||||
|
||||
StartTestRequest startTestRequest = new StartTestRequest();
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.performance.parse.xml.reader.jmx;
|
|||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.base.domain.TestResourcePool;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.config.KafkaProperties;
|
||||
|
@ -9,6 +10,7 @@ import io.metersphere.i18n.Translator;
|
|||
import io.metersphere.jmeter.utils.ScriptEngineUtils;
|
||||
import io.metersphere.performance.engine.EngineContext;
|
||||
import io.metersphere.performance.parse.xml.reader.DocumentParser;
|
||||
import io.metersphere.service.TestResourcePoolService;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.w3c.dom.Document;
|
||||
|
@ -587,6 +589,11 @@ public class JmeterDocumentParser implements DocumentParser {
|
|||
}
|
||||
|
||||
private void processBackendListener(Element backendListener) {
|
||||
String resourcePoolId = context.getResourcePoolId();
|
||||
TestResourcePool resourcePool = CommonBeanFactory.getBean(TestResourcePoolService.class).getResourcePool(resourcePoolId);
|
||||
if (!BooleanUtils.toBoolean(resourcePool.getBackendListener())) {
|
||||
return;
|
||||
}
|
||||
KafkaProperties kafkaProperties = CommonBeanFactory.getBean(KafkaProperties.class);
|
||||
Document document = backendListener.getOwnerDocument();
|
||||
// 清空child
|
||||
|
@ -647,6 +654,12 @@ public class JmeterDocumentParser implements DocumentParser {
|
|||
}
|
||||
|
||||
private void processCheckoutBackendListener(Element element) {
|
||||
String resourcePoolId = context.getResourcePoolId();
|
||||
TestResourcePool resourcePool = CommonBeanFactory.getBean(TestResourcePoolService.class).getResourcePool(resourcePoolId);
|
||||
if (!BooleanUtils.toBoolean(resourcePool.getBackendListener())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Document document = element.getOwnerDocument();
|
||||
|
||||
Node listenerParent = element.getNextSibling();
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.metersphere.performance.service;
|
|||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import io.metersphere.api.dto.JmxInfoDTO;
|
||||
import io.metersphere.api.dto.automation.ApiScenarioBatchRequest;
|
||||
import io.metersphere.api.dto.automation.ApiScenrioExportJmx;
|
||||
|
@ -16,7 +15,6 @@ import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
|||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.config.JmeterProperties;
|
||||
import io.metersphere.config.KafkaProperties;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
|
@ -30,7 +28,6 @@ import io.metersphere.log.utils.ReflexObjectUtil;
|
|||
import io.metersphere.log.vo.DetailColumn;
|
||||
import io.metersphere.log.vo.OperatingLogDetails;
|
||||
import io.metersphere.log.vo.performance.PerformanceReference;
|
||||
import io.metersphere.performance.base.GranularityData;
|
||||
import io.metersphere.performance.dto.LoadTestExportJmx;
|
||||
import io.metersphere.performance.engine.Engine;
|
||||
import io.metersphere.performance.engine.EngineFactory;
|
||||
|
@ -60,7 +57,6 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
@ -356,11 +352,7 @@ public class PerformanceTestService {
|
|||
}
|
||||
// 启动测试
|
||||
try {
|
||||
engine.start();
|
||||
// 启动正常修改状态 starting
|
||||
loadTest.setStatus(PerformanceTestStatus.Starting.name());
|
||||
loadTestMapper.updateByPrimaryKeySelective(loadTest);
|
||||
// 启动正常插入 report
|
||||
// 启动插入 report
|
||||
testReport.setLoadConfiguration(loadTest.getLoadConfiguration());
|
||||
testReport.setAdvancedConfiguration(loadTest.getAdvancedConfiguration());
|
||||
testReport.setStatus(PerformanceTestStatus.Starting.name());
|
||||
|
@ -369,6 +361,11 @@ public class PerformanceTestService {
|
|||
testReport.setTestName(loadTest.getName());
|
||||
loadTestReportMapper.insertSelective(testReport);
|
||||
|
||||
engine.start();
|
||||
// 启动正常修改状态 starting
|
||||
loadTest.setStatus(PerformanceTestStatus.Starting.name());
|
||||
loadTestMapper.updateByPrimaryKeySelective(loadTest);
|
||||
|
||||
LoadTestReportDetail reportDetail = new LoadTestReportDetail();
|
||||
reportDetail.setContent(HEADERS);
|
||||
reportDetail.setReportId(testReport.getId());
|
||||
|
@ -788,42 +785,16 @@ public class PerformanceTestService {
|
|||
}
|
||||
|
||||
public Integer getGranularity(String reportId) {
|
||||
Integer granularity = CommonBeanFactory.getBean(JmeterProperties.class).getReport().getGranularity();
|
||||
try {
|
||||
LoadTestReportWithBLOBs report = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(report.getTestId());
|
||||
JSONObject advancedConfig = JSON.parseObject(loadTest.getAdvancedConfiguration());
|
||||
if (advancedConfig.getInteger("granularity") != null) {
|
||||
granularity = advancedConfig.getInteger("granularity");
|
||||
return granularity * 1000; // 单位是ms
|
||||
return advancedConfig.getInteger("granularity") * 1000;// 单位是ms
|
||||
}
|
||||
AtomicReference<Integer> maxDuration = new AtomicReference<>(0);
|
||||
List<List<JSONObject>> pressureConfigLists = JSON.parseObject(loadTest.getLoadConfiguration(), new TypeReference<List<List<JSONObject>>>() {
|
||||
});
|
||||
// 按照最长的执行时间来确定
|
||||
pressureConfigLists.forEach(pcList -> {
|
||||
|
||||
Optional<Integer> maxOp = pcList.stream()
|
||||
.filter(pressureConfig -> StringUtils.equalsAnyIgnoreCase(pressureConfig.getString("key"), "hold", "duration"))
|
||||
.map(pressureConfig -> pressureConfig.getInteger("value"))
|
||||
.max(Comparator.naturalOrder());
|
||||
Integer max = maxOp.orElse(0);
|
||||
if (maxDuration.get() < max) {
|
||||
maxDuration.set(max);
|
||||
}
|
||||
});
|
||||
Optional<GranularityData.Data> dataOptional = GranularityData.dataList.stream()
|
||||
.filter(data -> maxDuration.get() >= data.getStart() && maxDuration.get() <= data.getEnd())
|
||||
.findFirst();
|
||||
|
||||
if (dataOptional.isPresent()) {
|
||||
GranularityData.Data data = dataOptional.get();
|
||||
granularity = data.getGranularity();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
return granularity;
|
||||
return -1; // 表示计算报告自己决定
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5b06224daf6b4232613a96c58d03a7f6831f4789
|
||||
Subproject commit 7acb44cc610bbaf08b510c35849c04e4871e223a
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
-- 接口定义增加全局运行环境选择
|
||||
CREATE TABLE IF NOT EXISTS `api_definition_env` (
|
||||
`id` varchar(50) NOT NULL COMMENT 'ID',
|
||||
|
@ -8,3 +7,19 @@ CREATE TABLE IF NOT EXISTS `api_definition_env` (
|
|||
update_time bigint(13) null,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
-- load_test_report_result_part
|
||||
CREATE TABLE `load_test_report_result_part`
|
||||
(
|
||||
`report_id` VARCHAR(50) NOT NULL,
|
||||
`report_key` VARCHAR(64) NOT NULL,
|
||||
`resource_index` INT NOT NULL,
|
||||
`report_value` LONGTEXT,
|
||||
PRIMARY KEY `load_test_report_result_report_id_report_key_index` (`report_id`, `report_key`, `resource_index`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE utf8mb4_general_ci;
|
||||
|
||||
ALTER TABLE test_resource_pool
|
||||
ADD backend_listener TINYINT(1) DEFAULT 1;
|
||||
|
|
|
@ -146,7 +146,7 @@ export default {
|
|||
}
|
||||
|
||||
.infinite-list {
|
||||
height: calc(100vh - 390px);
|
||||
height: calc(100vh - 295px);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
height="calc(100vh - 235px)"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="Requests" min-width="150" align="center">
|
||||
|
|
|
@ -715,7 +715,7 @@ export default {
|
|||
}
|
||||
|
||||
.test-detail {
|
||||
height: calc(100vh - 345px);
|
||||
height: calc(100vh - 285px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,10 @@
|
|||
<el-form-item :label="$t('commons.image')" prop="image">
|
||||
<el-input v-model="form.image"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('test_resource_pool.usage')" prop="image">
|
||||
<el-form-item :label="$t('test_resource_pool.backend_listener')" prop="backendListener">
|
||||
<el-switch v-model="form.backendListener"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('test_resource_pool.usage')" prop="usage">
|
||||
<el-checkbox :label="$t('commons.api')" v-model="form.api"></el-checkbox>
|
||||
<el-checkbox :label="$t('commons.performance')" v-model="form.performance"></el-checkbox>
|
||||
</el-form-item>
|
||||
|
|
|
@ -1736,6 +1736,7 @@ export default {
|
|||
node_selector_invalid: 'nodeSelector must be JSON',
|
||||
pod_thread_limit: 'Maximum number of threads per POD',
|
||||
usage: 'Usage',
|
||||
backend_listener: 'Backend Listener',
|
||||
},
|
||||
system_parameter_setting: {
|
||||
mailbox_service_settings: 'Mailbox Settings',
|
||||
|
|
|
@ -1744,6 +1744,7 @@ export default {
|
|||
node_selector_invalid: 'nodeSelector 必须是有效的JSON',
|
||||
pod_thread_limit: '单POD最大线程数',
|
||||
usage: '用途',
|
||||
backend_listener: '后置监听器',
|
||||
},
|
||||
system_parameter_setting: {
|
||||
mailbox_service_settings: '邮件设置',
|
||||
|
|
|
@ -1744,6 +1744,7 @@ export default {
|
|||
node_selector_invalid: 'nodeSelector 必須是有效的JSON',
|
||||
pod_thread_limit: '單POD最大線程數',
|
||||
usage: '用途',
|
||||
backend_listener: '後置監聽器',
|
||||
},
|
||||
system_parameter_setting: {
|
||||
mailbox_service_settings: '郵件設置',
|
||||
|
|
Loading…
Reference in New Issue