feat: 从场景测试转换的性能测试支持一键更新

This commit is contained in:
chenjianxing 2021-06-23 16:01:20 +08:00 committed by jianxing
parent 723133d0a0
commit 8c6208563f
21 changed files with 456 additions and 38 deletions

View File

@ -10,6 +10,7 @@ import java.util.List;
public class ApiScenrioExportJmx {
private String name;
private String jmx;
private Integer version;
List<String> files;
public ApiScenrioExportJmx(String name, String jmx) {

View File

@ -40,6 +40,8 @@ public class SaveApiScenarioRequest {
private String description;
private Integer version;
private MsTestElement scenarioDefinition;
List<String> bodyFileRequestIds;

View File

@ -244,6 +244,7 @@ public class ApiAutomationService {
checkNameExist(request);
checkScenarioNum(request);
final ApiScenarioWithBLOBs scenario = buildSaveScenario(request);
scenario.setVersion(0);
scenario.setCreateTime(System.currentTimeMillis());
scenario.setNum(getNextNum(request.getProjectId()));
@ -325,6 +326,14 @@ public class ApiAutomationService {
esbApiParamService.checkScenarioRequests(request);
final ApiScenarioWithBLOBs scenario = buildSaveScenario(request);
Integer version = apiScenarioMapper.selectByPrimaryKey(request.getId()).getVersion();
if (version == null) {
scenario.setVersion(0);
} else {
scenario.setVersion(version + 1);
}
deleteUpdateBodyFile(scenario);
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenario);
scenario.setUseUrl(JSONArray.toJSONString(useUrl));
@ -1544,7 +1553,7 @@ public class ApiAutomationService {
}
public JmxInfoDTO genPerformanceTestJmx(RunScenarioRequest request) throws Exception {
public JmxInfoDTO genPerformanceTestJmx(RunScenarioRequest request) {
List<ApiScenarioWithBLOBs> apiScenarios = null;
List<String> ids = request.getIds();
apiScenarios = extApiScenarioMapper.selectIds(ids);
@ -1753,6 +1762,7 @@ public class ApiAutomationService {
scenrioExportJmx.setFiles(fileList);
}
}
scenrioExportJmx.setVersion(item.getVersion());
resList.add(scenrioExportJmx);
}
}

View File

@ -49,5 +49,7 @@ public class ApiScenario implements Serializable {
private String createUser;
private Integer version;
private static final long serialVersionUID = 1L;
}

View File

@ -1603,6 +1603,66 @@ public class ApiScenarioExample {
addCriterion("create_user not between", value1, value2, "createUser");
return (Criteria) this;
}
public Criteria andVersionIsNull() {
addCriterion("version is null");
return (Criteria) this;
}
public Criteria andVersionIsNotNull() {
addCriterion("version is not null");
return (Criteria) this;
}
public Criteria andVersionEqualTo(Integer value) {
addCriterion("version =", value, "version");
return (Criteria) this;
}
public Criteria andVersionNotEqualTo(Integer value) {
addCriterion("version <>", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThan(Integer value) {
addCriterion("version >", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThanOrEqualTo(Integer value) {
addCriterion("version >=", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThan(Integer value) {
addCriterion("version <", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThanOrEqualTo(Integer value) {
addCriterion("version <=", value, "version");
return (Criteria) this;
}
public Criteria andVersionIn(List<Integer> values) {
addCriterion("version in", values, "version");
return (Criteria) this;
}
public Criteria andVersionNotIn(List<Integer> values) {
addCriterion("version not in", values, "version");
return (Criteria) this;
}
public Criteria andVersionBetween(Integer value1, Integer value2) {
addCriterion("version between", value1, value2, "version");
return (Criteria) this;
}
public Criteria andVersionNotBetween(Integer value1, Integer value2) {
addCriterion("version not between", value1, value2, "version");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -1,8 +1,7 @@
package io.metersphere.base.domain;
import lombok.Data;
import java.io.Serializable;
import lombok.Data;
@Data
public class LoadTest implements Serializable {
@ -28,5 +27,9 @@ public class LoadTest implements Serializable {
private String createUser;
private Integer scenarioVersion;
private String scenarioId;
private static final long serialVersionUID = 1L;
}

View File

@ -843,6 +843,136 @@ public class LoadTestExample {
addCriterion("create_user not between", value1, value2, "createUser");
return (Criteria) this;
}
public Criteria andScenarioVersionIsNull() {
addCriterion("scenario_version is null");
return (Criteria) this;
}
public Criteria andScenarioVersionIsNotNull() {
addCriterion("scenario_version is not null");
return (Criteria) this;
}
public Criteria andScenarioVersionEqualTo(Integer value) {
addCriterion("scenario_version =", value, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionNotEqualTo(Integer value) {
addCriterion("scenario_version <>", value, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionGreaterThan(Integer value) {
addCriterion("scenario_version >", value, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionGreaterThanOrEqualTo(Integer value) {
addCriterion("scenario_version >=", value, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionLessThan(Integer value) {
addCriterion("scenario_version <", value, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionLessThanOrEqualTo(Integer value) {
addCriterion("scenario_version <=", value, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionIn(List<Integer> values) {
addCriterion("scenario_version in", values, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionNotIn(List<Integer> values) {
addCriterion("scenario_version not in", values, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionBetween(Integer value1, Integer value2) {
addCriterion("scenario_version between", value1, value2, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioVersionNotBetween(Integer value1, Integer value2) {
addCriterion("scenario_version not between", value1, value2, "scenarioVersion");
return (Criteria) this;
}
public Criteria andScenarioIdIsNull() {
addCriterion("scenario_id is null");
return (Criteria) this;
}
public Criteria andScenarioIdIsNotNull() {
addCriterion("scenario_id is not null");
return (Criteria) this;
}
public Criteria andScenarioIdEqualTo(String value) {
addCriterion("scenario_id =", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdNotEqualTo(String value) {
addCriterion("scenario_id <>", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdGreaterThan(String value) {
addCriterion("scenario_id >", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdGreaterThanOrEqualTo(String value) {
addCriterion("scenario_id >=", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdLessThan(String value) {
addCriterion("scenario_id <", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdLessThanOrEqualTo(String value) {
addCriterion("scenario_id <=", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdLike(String value) {
addCriterion("scenario_id like", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdNotLike(String value) {
addCriterion("scenario_id not like", value, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdIn(List<String> values) {
addCriterion("scenario_id in", values, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdNotIn(List<String> values) {
addCriterion("scenario_id not in", values, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdBetween(String value1, String value2) {
addCriterion("scenario_id between", value1, value2, "scenarioId");
return (Criteria) this;
}
public Criteria andScenarioIdNotBetween(String value1, String value2) {
addCriterion("scenario_id not between", value1, value2, "scenarioId");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -24,6 +24,7 @@
<result column="original_state" jdbcType="VARCHAR" property="originalState" />
<result column="custom_num" jdbcType="VARCHAR" property="customNum" />
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
<result column="version" jdbcType="INTEGER" property="version" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiScenarioWithBLOBs">
<result column="scenario_definition" jdbcType="LONGVARCHAR" property="scenarioDefinition" />
@ -91,7 +92,8 @@
<sql id="Base_Column_List">
id, project_id, tags, user_id, api_scenario_module_id, module_path, `name`, `level`,
`status`, principal, step_total, follow_people, schedule, create_time, update_time,
pass_rate, last_result, report_id, num, original_state, custom_num, create_user
pass_rate, last_result, report_id, num, original_state, custom_num, create_user,
version
</sql>
<sql id="Blob_Column_List">
scenario_definition, description, use_url
@ -152,8 +154,8 @@
schedule, create_time, update_time,
pass_rate, last_result, report_id,
num, original_state, custom_num,
create_user, scenario_definition, description,
use_url)
create_user, version, scenario_definition,
description, use_url)
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{tags,jdbcType=VARCHAR},
#{userId,jdbcType=VARCHAR}, #{apiScenarioModuleId,jdbcType=VARCHAR}, #{modulePath,jdbcType=VARCHAR},
#{name,jdbcType=VARCHAR}, #{level,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
@ -161,8 +163,8 @@
#{schedule,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{passRate,jdbcType=VARCHAR}, #{lastResult,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
#{num,jdbcType=INTEGER}, #{originalState,jdbcType=VARCHAR}, #{customNum,jdbcType=VARCHAR},
#{createUser,jdbcType=VARCHAR}, #{scenarioDefinition,jdbcType=LONGVARCHAR}, #{description,jdbcType=LONGVARCHAR},
#{useUrl,jdbcType=LONGVARCHAR})
#{createUser,jdbcType=VARCHAR}, #{version,jdbcType=INTEGER}, #{scenarioDefinition,jdbcType=LONGVARCHAR},
#{description,jdbcType=LONGVARCHAR}, #{useUrl,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
insert into api_scenario
@ -233,6 +235,9 @@
<if test="createUser != null">
create_user,
</if>
<if test="version != null">
version,
</if>
<if test="scenarioDefinition != null">
scenario_definition,
</if>
@ -310,6 +315,9 @@
<if test="createUser != null">
#{createUser,jdbcType=VARCHAR},
</if>
<if test="version != null">
#{version,jdbcType=INTEGER},
</if>
<if test="scenarioDefinition != null">
#{scenarioDefinition,jdbcType=LONGVARCHAR},
</if>
@ -396,6 +404,9 @@
<if test="record.createUser != null">
create_user = #{record.createUser,jdbcType=VARCHAR},
</if>
<if test="record.version != null">
version = #{record.version,jdbcType=INTEGER},
</if>
<if test="record.scenarioDefinition != null">
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
</if>
@ -434,6 +445,7 @@
original_state = #{record.originalState,jdbcType=VARCHAR},
custom_num = #{record.customNum,jdbcType=VARCHAR},
create_user = #{record.createUser,jdbcType=VARCHAR},
version = #{record.version,jdbcType=INTEGER},
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
description = #{record.description,jdbcType=LONGVARCHAR},
use_url = #{record.useUrl,jdbcType=LONGVARCHAR}
@ -464,7 +476,8 @@
num = #{record.num,jdbcType=INTEGER},
original_state = #{record.originalState,jdbcType=VARCHAR},
custom_num = #{record.customNum,jdbcType=VARCHAR},
create_user = #{record.createUser,jdbcType=VARCHAR}
create_user = #{record.createUser,jdbcType=VARCHAR},
version = #{record.version,jdbcType=INTEGER}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -535,6 +548,9 @@
<if test="createUser != null">
create_user = #{createUser,jdbcType=VARCHAR},
</if>
<if test="version != null">
version = #{version,jdbcType=INTEGER},
</if>
<if test="scenarioDefinition != null">
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
</if>
@ -570,6 +586,7 @@
original_state = #{originalState,jdbcType=VARCHAR},
custom_num = #{customNum,jdbcType=VARCHAR},
create_user = #{createUser,jdbcType=VARCHAR},
version = #{version,jdbcType=INTEGER},
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
description = #{description,jdbcType=LONGVARCHAR},
use_url = #{useUrl,jdbcType=LONGVARCHAR}
@ -597,7 +614,8 @@
num = #{num,jdbcType=INTEGER},
original_state = #{originalState,jdbcType=VARCHAR},
custom_num = #{customNum,jdbcType=VARCHAR},
create_user = #{createUser,jdbcType=VARCHAR}
create_user = #{createUser,jdbcType=VARCHAR},
version = #{version,jdbcType=INTEGER}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -13,6 +13,8 @@
<result column="user_id" jdbcType="VARCHAR" property="userId" />
<result column="num" jdbcType="INTEGER" property="num" />
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
<result column="scenario_version" jdbcType="INTEGER" property="scenarioVersion" />
<result column="scenario_id" jdbcType="VARCHAR" property="scenarioId" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.LoadTestWithBLOBs">
<result column="load_configuration" jdbcType="LONGVARCHAR" property="loadConfiguration" />
@ -78,7 +80,7 @@
</sql>
<sql id="Base_Column_List">
id, project_id, `name`, description, create_time, update_time, `status`, test_resource_pool_id,
user_id, num, create_user
user_id, num, create_user, scenario_version, scenario_id
</sql>
<sql id="Blob_Column_List">
load_configuration, advanced_configuration
@ -135,13 +137,15 @@
insert into load_test (id, project_id, `name`,
description, create_time, update_time,
`status`, test_resource_pool_id, user_id,
num, create_user, load_configuration,
advanced_configuration)
num, create_user, scenario_version,
scenario_id, load_configuration, advanced_configuration
)
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{description,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{status,jdbcType=VARCHAR}, #{testResourcePoolId,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR},
#{num,jdbcType=INTEGER}, #{createUser,jdbcType=VARCHAR}, #{loadConfiguration,jdbcType=LONGVARCHAR},
#{advancedConfiguration,jdbcType=LONGVARCHAR})
#{num,jdbcType=INTEGER}, #{createUser,jdbcType=VARCHAR}, #{scenarioVersion,jdbcType=INTEGER},
#{scenarioId,jdbcType=VARCHAR}, #{loadConfiguration,jdbcType=LONGVARCHAR}, #{advancedConfiguration,jdbcType=LONGVARCHAR}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.LoadTestWithBLOBs">
insert into load_test
@ -179,6 +183,12 @@
<if test="createUser != null">
create_user,
</if>
<if test="scenarioVersion != null">
scenario_version,
</if>
<if test="scenarioId != null">
scenario_id,
</if>
<if test="loadConfiguration != null">
load_configuration,
</if>
@ -220,6 +230,12 @@
<if test="createUser != null">
#{createUser,jdbcType=VARCHAR},
</if>
<if test="scenarioVersion != null">
#{scenarioVersion,jdbcType=INTEGER},
</if>
<if test="scenarioId != null">
#{scenarioId,jdbcType=VARCHAR},
</if>
<if test="loadConfiguration != null">
#{loadConfiguration,jdbcType=LONGVARCHAR},
</if>
@ -270,6 +286,12 @@
<if test="record.createUser != null">
create_user = #{record.createUser,jdbcType=VARCHAR},
</if>
<if test="record.scenarioVersion != null">
scenario_version = #{record.scenarioVersion,jdbcType=INTEGER},
</if>
<if test="record.scenarioId != null">
scenario_id = #{record.scenarioId,jdbcType=VARCHAR},
</if>
<if test="record.loadConfiguration != null">
load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR},
</if>
@ -294,6 +316,8 @@
user_id = #{record.userId,jdbcType=VARCHAR},
num = #{record.num,jdbcType=INTEGER},
create_user = #{record.createUser,jdbcType=VARCHAR},
scenario_version = #{record.scenarioVersion,jdbcType=INTEGER},
scenario_id = #{record.scenarioId,jdbcType=VARCHAR},
load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR},
advanced_configuration = #{record.advancedConfiguration,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
@ -312,7 +336,9 @@
test_resource_pool_id = #{record.testResourcePoolId,jdbcType=VARCHAR},
user_id = #{record.userId,jdbcType=VARCHAR},
num = #{record.num,jdbcType=INTEGER},
create_user = #{record.createUser,jdbcType=VARCHAR}
create_user = #{record.createUser,jdbcType=VARCHAR},
scenario_version = #{record.scenarioVersion,jdbcType=INTEGER},
scenario_id = #{record.scenarioId,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -350,6 +376,12 @@
<if test="createUser != null">
create_user = #{createUser,jdbcType=VARCHAR},
</if>
<if test="scenarioVersion != null">
scenario_version = #{scenarioVersion,jdbcType=INTEGER},
</if>
<if test="scenarioId != null">
scenario_id = #{scenarioId,jdbcType=VARCHAR},
</if>
<if test="loadConfiguration != null">
load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR},
</if>
@ -371,6 +403,8 @@
user_id = #{userId,jdbcType=VARCHAR},
num = #{num,jdbcType=INTEGER},
create_user = #{createUser,jdbcType=VARCHAR},
scenario_version = #{scenarioVersion,jdbcType=INTEGER},
scenario_id = #{scenarioId,jdbcType=VARCHAR},
load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR},
advanced_configuration = #{advancedConfiguration,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
@ -386,7 +420,9 @@
test_resource_pool_id = #{testResourcePoolId,jdbcType=VARCHAR},
user_id = #{userId,jdbcType=VARCHAR},
num = #{num,jdbcType=INTEGER},
create_user = #{createUser,jdbcType=VARCHAR}
create_user = #{createUser,jdbcType=VARCHAR},
scenario_version = #{scenarioVersion,jdbcType=INTEGER},
scenario_id = #{scenarioId,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -144,7 +144,7 @@
</select>
<select id="list" resultMap="BaseResultMap">
select api_scenario.id, api_scenario.project_id, api_scenario.tags, api_scenario.user_id, api_scenario.num,
api_scenario.custom_num,
api_scenario.custom_num, api_scenario.version,
api_scenario.api_scenario_module_id,api_scenario.module_path, api_scenario.name, api_scenario.level,
api_scenario.status, api_scenario.principal, api_scenario.step_total, api_scenario.follow_people,
api_scenario.last_result,api_scenario.pass_rate,api_scenario.report_id,

View File

@ -73,6 +73,11 @@ public class FileUtils {
}
}
public static File getFileByName(String name) {
String path = BODY_FILE_DIR + "/" + name;
return new File(path);
}
public static void copyBdyFile(String originId, String toId) {
try {
FileUtil.copyDir(new File(FileUtils.BODY_FILE_DIR + "/" + originId),

View File

@ -11,4 +11,5 @@ public class LoadTestDTO extends LoadTest {
private String projectName;
private String userName;
private Schedule schedule;
private Boolean isNeedUpdate;
}

View File

@ -5,7 +5,6 @@ import com.github.pagehelper.PageHelper;
import io.metersphere.base.domain.FileMetadata;
import io.metersphere.base.domain.LoadTest;
import io.metersphere.base.domain.Schedule;
import io.metersphere.base.domain.UserGroup;
import io.metersphere.commons.constants.OperLogConstants;
import io.metersphere.commons.constants.PermissionConstants;
import io.metersphere.commons.utils.PageUtils;
@ -23,7 +22,6 @@ import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.service.CheckPermissionService;
import io.metersphere.service.FileService;
import io.metersphere.track.request.testplan.FileOperationRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@ -32,10 +30,8 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@RestController
@RequestMapping(value = "performance")
@ -87,6 +83,12 @@ public class PerformanceTestController {
return performanceTestService.save(request, files);
}
@PostMapping(value = "/sync/scenario")
@RequiresPermissions(PermissionConstants.PROJECT_PERFORMANCE_TEST_READ_CREATE)
public void syncScenario(@RequestBody EditTestPlanRequest request) {
performanceTestService.syncScenario(request);
}
@PostMapping(value = "/edit", consumes = {"multipart/form-data"})
@MsAuditLog(module = "performance_test", type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.id)", title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = PerformanceTestService.class)
@RequiresPermissions(PermissionConstants.PROJECT_PERFORMANCE_TEST_READ_EDIT)

View File

@ -26,6 +26,10 @@ public class TestPlanRequest {
private String runtimeConfiguration;
private Integer scenarioVersion;
private String scenarioId;
private Schedule schedule;
private String testResourcePoolId;

View File

@ -1,6 +1,9 @@
package io.metersphere.performance.service;
import com.alibaba.fastjson.JSON;
import io.metersphere.api.dto.automation.ApiScenarioBatchRequest;
import io.metersphere.api.dto.automation.ApiScenrioExportJmx;
import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtLoadTestMapper;
@ -8,10 +11,7 @@ import io.metersphere.base.mapper.ext.ExtLoadTestReportDetailMapper;
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.commons.utils.*;
import io.metersphere.config.KafkaProperties;
import io.metersphere.controller.request.OrderRequest;
import io.metersphere.controller.request.QueryScheduleRequest;
@ -36,12 +36,15 @@ import io.metersphere.service.ScheduleService;
import io.metersphere.track.service.TestCaseService;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.util.FileUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
@ -86,6 +89,8 @@ public class PerformanceTestService {
private TestResourcePoolMapper testResourcePoolMapper;
@Resource
private LoadTestProducer loadTestProducer;
@Resource
private ApiAutomationService apiAutomationService;
public List<LoadTestDTO> list(QueryTestPlanRequest request) {
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
@ -212,6 +217,8 @@ public class PerformanceTestService {
loadTest.setAdvancedConfiguration(request.getAdvancedConfiguration());
loadTest.setStatus(PerformanceTestStatus.Saved.name());
loadTest.setNum(getNextNum(request.getProjectId()));
loadTest.setScenarioVersion(request.getScenarioVersion());
loadTest.setScenarioId(request.getScenarioId());
loadTestMapper.insert(loadTest);
return loadTest;
}
@ -258,6 +265,8 @@ public class PerformanceTestService {
loadTest.setAdvancedConfiguration(request.getAdvancedConfiguration());
loadTest.setTestResourcePoolId(request.getTestResourcePoolId());
loadTest.setStatus(PerformanceTestStatus.Saved.name());
loadTest.setScenarioVersion(request.getScenarioVersion());
loadTest.setScenarioId(request.getScenarioId());
loadTestMapper.updateByPrimaryKeySelective(loadTest);
return testId;
@ -395,6 +404,7 @@ public class PerformanceTestService {
List<LoadTestDTO> testDTOS = extLoadTestMapper.list(request);
if (!CollectionUtils.isEmpty(testDTOS)) {
LoadTestDTO loadTestDTO = testDTOS.get(0);
isNeedUpdate(loadTestDTO);
Schedule schedule = scheduleService.getScheduleByResource(loadTestDTO.getId(), ScheduleGroup.PERFORMANCE_TEST.name());
loadTestDTO.setSchedule(schedule);
return loadTestDTO;
@ -402,6 +412,21 @@ public class PerformanceTestService {
return null;
}
public void isNeedUpdate(LoadTestDTO loadTestDTO) {
String scenarioId = loadTestDTO.getScenarioId();
if (StringUtils.isNotBlank(scenarioId)) {
ApiScenarioWithBLOBs apiScenario = apiAutomationService.getApiScenario(scenarioId);
if (apiScenario == null) {
loadTestDTO.setScenarioId(null);
} else {
if (apiScenario.getVersion() != null && loadTestDTO.getScenarioVersion() != null
&& apiScenario.getVersion() > loadTestDTO.getScenarioVersion()) {
loadTestDTO.setIsNeedUpdate(true);
}
}
}
}
public String getAdvancedConfiguration(String testId) {
LoadTestWithBLOBs loadTestWithBLOBs = loadTestMapper.selectByPrimaryKey(testId);
return Optional.ofNullable(loadTestWithBLOBs).orElse(new LoadTestWithBLOBs()).getAdvancedConfiguration();
@ -636,4 +661,79 @@ public class PerformanceTestService {
}
return null;
}
public void syncScenario(EditTestPlanRequest request) {
ApiScenarioBatchRequest scenarioRequest = new ApiScenarioBatchRequest();
scenarioRequest.setIds(Arrays.asList(request.getScenarioId()));
List<ApiScenrioExportJmx> apiScenrioExportJmxes = apiAutomationService.exportJmx(scenarioRequest);
ApiScenrioExportJmx apiScenrioExportJmx = apiScenrioExportJmxes.get(0);
String testId = request.getId();
LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(testId);
if (loadTest == null) {
MSException.throwException(Translator.get("edit_load_test_not_found") + testId);
}
if (StringUtils.containsAny(loadTest.getStatus(), PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name())) {
MSException.throwException(Translator.get("cannot_edit_load_test_running"));
}
loadTest.setScenarioVersion(apiScenrioExportJmx.getVersion());
loadTest.setUpdateTime(System.currentTimeMillis());
loadTestMapper.updateByPrimaryKeySelective(loadTest);
deleteLoadTestFiles(testId);
saveJmxFile(apiScenrioExportJmx, loadTest.getProjectId(), loadTest.getId());
saveOtherFile(apiScenrioExportJmx.getFiles(), loadTest.getId());
}
private void saveJmxFile(ApiScenrioExportJmx apiScenrioExportJmx, String projectId, String loadTestId) {
String jmx = apiScenrioExportJmx.getJmx();
byte[] jmxBytes = jmx.getBytes(StandardCharsets.UTF_8);
String jmxName = apiScenrioExportJmx.getName() + "_" + System.currentTimeMillis() + ".jmx";
FileMetadata fileMetadata = fileService.saveFile(jmxBytes, jmxName, (long) jmxBytes.length);
fileMetadata.setProjectId(projectId);
saveLoadTestFile(fileMetadata, loadTestId, 0);
}
private void saveOtherFile(List<String> fileNames, String loadTestId) {
List<String> files = fileNames;
for (int i = 0; i < files.size(); i++) {
String fileName = files.get(i);
File file = FileUtils.getFileByName(fileName);
saveUploadFile(file, loadTestId, i + 1);
}
}
private void deleteLoadTestFiles(String testId) {
List<FileMetadata> originFiles = getFileMetadataByTestId(testId);
List<String> originFileIds = originFiles.stream().map(FileMetadata::getId).collect(Collectors.toList());
LoadTestFileExample example = new LoadTestFileExample();
example.createCriteria()
.andTestIdEqualTo(testId);
loadTestFileMapper.deleteByExample(example);
fileService.deleteFileByIds(originFileIds);
}
private void saveUploadFile(File file, String loadTestId, int sort) {
if (file != null) {
FileMetadata fileMetadata = null;
try {
fileMetadata = fileService.saveFile(file, FileUtil.readAsByteArray(file));
} catch (IOException e) {
e.printStackTrace();
}
saveLoadTestFile(fileMetadata, loadTestId, sort);
}
}
private void saveLoadTestFile(FileMetadata fileMetadata, String loadTestId, int sort) {
if (fileMetadata != null) {
LoadTestFile loadTestFile = new LoadTestFile();
loadTestFile.setTestId(loadTestId);
loadTestFile.setFileId(fileMetadata.getId());
loadTestFile.setSort(sort);
loadTestFileMapper.insert(loadTestFile);
}
}
}

View File

@ -0,0 +1,6 @@
-- 添加版本号
ALTER TABLE api_scenario ADD version INT(10) DEFAULT 0 NULL COMMENT '版本号';
ALTER TABLE load_test ADD scenario_version INT(10) DEFAULT 0 NULL COMMENT '关联的接口自动化版本号';
ALTER TABLE load_test ADD scenario_id varchar(255) NULL COMMENT '关联的场景自动化ID';

View File

@ -63,6 +63,7 @@ export default {
jmxObj.attachFiles = response.data.attachFiles;
jmxObj.attachByteFiles = response.data.attachByteFiles;
jmxObj.scenarioId = row.id;
jmxObj.version = row.version;
this.$store.commit('setTest', {
name: row.name,
jmx: jmxObj

View File

@ -102,7 +102,7 @@
.schedule-config {
float: right;
width: 250px;
/*width: 250px;*/
height: 15px;
line-height: 25px;
}

View File

@ -4,14 +4,17 @@
placement="bottom"
:enterable="false"
:effect="effect">
<el-button @click="exec()"
@click.stop="clickStop"
@keydown.enter.native.prevent
circle
:disabled="disabled"
:type="type"
:icon="icon"
:size="size"/>
<span class="tooltip-btn">
<el-button @click="exec()"
@click.stop="clickStop"
@keydown.enter.native.prevent
circle
:plain="plain"
:disabled="disabled"
:type="type"
:icon="icon"
:size="size"/>
</span>
</el-tooltip>
</template>
@ -40,7 +43,8 @@
disabled: {
type: Boolean,
default: false
}
},
plain: Boolean
},
methods: {
exec() {
@ -54,5 +58,7 @@
</script>
<style scoped>
.tooltip-btn+.tooltip-btn {
margin-left: 10px;
}
</style>

View File

@ -29,6 +29,15 @@
<ms-schedule-config :schedule="test.schedule" :save="saveCronExpression" @scheduleChange="saveSchedule"
v-permission="['PROJECT_PERFORMANCE_TEST:READ+SCHEDULE']"
:check-open="checkScheduleEdit" :test-id="testId" :custom-validate="durationValidate"/>
<ms-tip-button v-if="test.scenarioId"
class="sync-btn" type="primary" size="small" circle
icon="el-icon-connection"
@click="syncScenario"
:plain="!test.isNeedUpdate"
:disabled="!test.isNeedUpdate"
:tip="'同步场景测试最新变更'"/>
</el-col>
</el-row>
@ -65,10 +74,14 @@ import MsMainContainer from "../../common/components/MsMainContainer";
import {getCurrentProjectID, hasPermission} from "@/common/js/utils";
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
import MsChangeHistory from "../../history/ChangeHistory";
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
import MsTipButton from "@/business/components/common/components/MsTipButton";
export default {
name: "EditPerformanceTest",
components: {
MsTipButton,
MsTableOperatorButton,
MsScheduleConfig,
PerformancePressureConfig,
PerformanceBasicConfig,
@ -141,6 +154,8 @@ export default {
if (apiTest.jmx.scenarioId) {
this.$refs.basicConfig.importScenario(apiTest.jmx.scenarioId);
this.$refs.basicConfig.handleUpload();
this.$set(this.test, "scenarioId", apiTest.jmx.scenarioId);
this.$set(this.test, "scenarioVersion", apiTest.jmx.version);
}
if (apiTest.jmx.caseId) {
this.$refs.basicConfig.importCase(apiTest.jmx);
@ -237,6 +252,16 @@ export default {
}
};
},
syncScenario() {
let param = {
id: this.test.id,
scenarioId: this.test.scenarioId
};
this.result = this.$post('/performance/sync/scenario', param, () => {
this.getTest(this.$route.params.testId);
this.$success('更新成功');
});
},
cancel() {
this.$router.push({path: '/performance/test/all'});
},
@ -375,4 +400,10 @@ export default {
height: calc(100vh - 265px);
overflow: auto;
}
.sync-btn {
float: right;
margin-right: 25px;
margin-top: 5px;
}
</style>