fix(接口测试): 修复失败停止功能不生效问题

--bug=1009551 --user=赵勇 【接口测试】批量执行接口用例、场景,失败停止没有生效 https://www.tapd.cn/55049933/s/1091264
This commit is contained in:
fit2-zhao 2022-01-13 12:52:54 +08:00 committed by fit2-zhao
parent 6d28e5cac0
commit cd1296c59c
12 changed files with 170 additions and 22 deletions

View File

@ -16,13 +16,11 @@ import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.service.EnvironmentGroupProjectService;
import io.metersphere.track.service.TestPlanReportService;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@ -104,7 +102,7 @@ public class ApiCaseExecuteService {
String reportType = request.getConfig().getReportType();
String poolId = request.getConfig().getResourcePoolId();
String runMode = StringUtils.equals(request.getTriggerMode(), TriggerMode.MANUAL.name()) ? ApiRunMode.API_PLAN.name() : ApiRunMode.SCHEDULE_API_PLAN.name();
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig().getEnvMap());
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.API_PLAN.name(), request.getPlanReportId(), reportType, runMode, request.getConfig().getEnvMap(), request.getConfig().isOnSampleError());
// 开始选择执行模式
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
@ -159,6 +157,7 @@ public class ApiCaseExecuteService {
list.forEach(caseWithBLOBs -> {
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.initBase(caseWithBLOBs.getId(), APITestStatus.Running.name(), null, request.getConfig());
report.setStatus(status);
report.setName(caseWithBLOBs.getName());
batchMapper.insert(report);
executeQueue.put(caseWithBLOBs.getId(), report);
responseDTOS.add(new MsExecResponseDTO(caseWithBLOBs.getId(), report.getId(), request.getTriggerMode()));
@ -170,7 +169,7 @@ public class ApiCaseExecuteService {
String reportType = request.getConfig().getReportType();
String poolId = request.getConfig().getResourcePoolId();
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), null, reportType, ApiRunMode.DEFINITION.name(), request.getConfig().getEnvMap());
DBTestQueue deQueue = apiExecutionQueueService.add(executeQueue, poolId, ApiRunMode.DEFINITION.name(), null, reportType, ApiRunMode.DEFINITION.name(), request.getConfig().getEnvMap(), request.getConfig().isOnSampleError());
// 开始选择执行模式
if (request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
LoggerUtil.debug("开始串行执行");

View File

@ -9,6 +9,7 @@ import java.util.Map;
@Data
public class DBTestQueue extends ApiExecutionQueue {
private String nowReportId;
private ApiExecutionQueueDetail queue;
private Map<String, String> detailMap = new HashMap<>();
}

View File

@ -24,7 +24,10 @@ import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*;
import io.metersphere.commons.utils.FileUtils;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.JmeterRunRequestDTO;
import io.metersphere.dto.MsExecResponseDTO;
@ -32,7 +35,6 @@ import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.service.EnvironmentGroupProjectService;
import io.metersphere.track.service.TestPlanReportService;
import io.metersphere.track.service.TestPlanScenarioCaseService;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.beanutils.BeanComparator;
@ -163,7 +165,11 @@ public class ApiScenarioExecuteService {
// 开始执行
if (executeQueue != null && executeQueue.size() > 0) {
String reportType = request.getConfig().getReportType();
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId(), ApiRunMode.SCENARIO.name(), serialReportId, reportType, request.getRunMode(), request.getConfig().getEnvMap());
String planReportId = StringUtils.isNotEmpty(request.getTestPlanReportId()) ? request.getTestPlanReportId() : serialReportId;
DBTestQueue executionQueue = apiExecutionQueueService.add(executeQueue, request.getConfig().getResourcePoolId()
, ApiRunMode.SCENARIO.name(), planReportId, reportType, request.getRunMode(), request.getConfig().getEnvMap()
, request.getConfig().isOnSampleError());
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
if (StringUtils.isNotEmpty(serialReportId)) {
apiScenarioReportStructureService.save(apiScenarios, serialReportId, request.getConfig() != null ? request.getConfig().getReportType() : null);

View File

@ -10,7 +10,9 @@ import io.metersphere.base.mapper.ApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
import io.metersphere.base.mapper.ApiExecutionQueueMapper;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ext.ExtApiExecutionQueueMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.TestPlanReportStatus;
import io.metersphere.commons.utils.BeanUtils;
@ -47,14 +49,20 @@ public class ApiExecutionQueueService {
private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
@Resource
private ExtApiScenarioReportMapper extApiScenarioReportMapper;
@Resource
private ExtApiExecutionQueueMapper extApiExecutionQueueMapper;
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, Map<String, String> envMap) {
public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, Map<String, String> envMap, boolean failure) {
ApiExecutionQueue executionQueue = new ApiExecutionQueue();
executionQueue.setId(UUID.randomUUID().toString());
executionQueue.setCreateTime(System.currentTimeMillis());
executionQueue.setPoolId(poolId);
executionQueue.setFailure(failure);
executionQueue.setReportId(reportId);
executionQueue.setReportType(StringUtils.isNotEmpty(reportType) ? reportType : RunModeConstants.INDEPENDENCE.toString());
executionQueue.setRunMode(runMode);
@ -129,6 +137,7 @@ public class ApiExecutionQueueService {
if (CollectionUtils.isNotEmpty(queues)) {
List<ApiExecutionQueueDetail> list = queues.stream().filter(item -> StringUtils.equals(item.getTestId(), testId)).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(list)) {
queue.setNowReportId(list.get(0).getReportId());
executionQueueDetailMapper.deleteByPrimaryKey(list.get(0).getId());
queues.remove(list.get(0));
BeanUtils.copyBean(queue, executionQueue);
@ -151,6 +160,42 @@ public class ApiExecutionQueueService {
public void queueNext(ResultDTO dto) {
DBTestQueue executionQueue = this.edit(dto.getQueueId(), dto.getTestId());
if (executionQueue != null) {
if (executionQueue.getFailure()) {
LoggerUtil.info("进入失败停止处理:" + executionQueue.getId());
boolean isError = false;
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCENARIO.name(),
ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(),
ApiRunMode.SCHEDULE_SCENARIO.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(executionQueue.getNowReportId());
if (report != null && StringUtils.equalsIgnoreCase(report.getStatus(), "Error")) {
isError = true;
}
} else {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(executionQueue.getNowReportId());
if (result != null && StringUtils.equalsIgnoreCase(result.getStatus(), "Error")) {
isError = true;
}
}
if (isError) {
ApiExecutionQueueDetailExample example = new ApiExecutionQueueDetailExample();
example.createCriteria().andQueueIdEqualTo(dto.getQueueId());
if (StringUtils.isNotEmpty(dto.getTestPlanReportId())) {
CommonBeanFactory.getBean(TestPlanReportService.class).finishedTestPlanReport(dto.getTestPlanReportId(), "Stopped");
}
// 更新未执行的报告状态
List<ApiExecutionQueueDetail> details = executionQueueDetailMapper.selectByExample(example);
List<String> reportIds = details.stream().map(ApiExecutionQueueDetail::getReportId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(reportIds)) {
extApiDefinitionExecResultMapper.update(reportIds);
extApiScenarioReportMapper.update(reportIds);
}
// 清除队列
executionQueueDetailMapper.deleteByExample(example);
queueMapper.deleteByPrimaryKey(executionQueue.getId());
return;
}
}
LoggerUtil.info("开始处理执行队列:" + executionQueue.getId());
if (executionQueue.getQueue() != null && StringUtils.isNotEmpty(executionQueue.getQueue().getTestId())) {
if (StringUtils.equals(dto.getRunType(), RunModeConstants.SERIAL.toString())) {

View File

@ -1,8 +1,9 @@
package io.metersphere.base.domain;
import java.io.Serializable;
import lombok.Data;
import java.io.Serializable;
@Data
public class ApiExecutionQueue implements Serializable {
private String id;
@ -17,5 +18,7 @@ public class ApiExecutionQueue implements Serializable {
private Long createTime;
private Boolean failure;
private static final long serialVersionUID = 1L;
}

View File

@ -513,6 +513,66 @@ public class ApiExecutionQueueExample {
addCriterion("create_time not between", value1, value2, "createTime");
return (Criteria) this;
}
public Criteria andFailureIsNull() {
addCriterion("failure is null");
return (Criteria) this;
}
public Criteria andFailureIsNotNull() {
addCriterion("failure is not null");
return (Criteria) this;
}
public Criteria andFailureEqualTo(Boolean value) {
addCriterion("failure =", value, "failure");
return (Criteria) this;
}
public Criteria andFailureNotEqualTo(Boolean value) {
addCriterion("failure <>", value, "failure");
return (Criteria) this;
}
public Criteria andFailureGreaterThan(Boolean value) {
addCriterion("failure >", value, "failure");
return (Criteria) this;
}
public Criteria andFailureGreaterThanOrEqualTo(Boolean value) {
addCriterion("failure >=", value, "failure");
return (Criteria) this;
}
public Criteria andFailureLessThan(Boolean value) {
addCriterion("failure <", value, "failure");
return (Criteria) this;
}
public Criteria andFailureLessThanOrEqualTo(Boolean value) {
addCriterion("failure <=", value, "failure");
return (Criteria) this;
}
public Criteria andFailureIn(List<Boolean> values) {
addCriterion("failure in", values, "failure");
return (Criteria) this;
}
public Criteria andFailureNotIn(List<Boolean> values) {
addCriterion("failure not in", values, "failure");
return (Criteria) this;
}
public Criteria andFailureBetween(Boolean value1, Boolean value2) {
addCriterion("failure between", value1, value2, "failure");
return (Criteria) this;
}
public Criteria andFailureNotBetween(Boolean value1, Boolean value2) {
addCriterion("failure not between", value1, value2, "failure");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -8,6 +8,7 @@
<result column="run_mode" jdbcType="VARCHAR" property="runMode" />
<result column="pool_id" jdbcType="VARCHAR" property="poolId" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="failure" jdbcType="BIT" property="failure" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -68,7 +69,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, report_id, report_type, run_mode, pool_id, create_time
id, report_id, report_type, run_mode, pool_id, create_time, failure
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueExample" resultMap="BaseResultMap">
select
@ -102,11 +103,11 @@
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.ApiExecutionQueue">
insert into api_execution_queue (id, report_id, report_type,
run_mode, pool_id, create_time
)
run_mode, pool_id, create_time,
failure)
values (#{id,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR}, #{reportType,jdbcType=VARCHAR},
#{runMode,jdbcType=VARCHAR}, #{poolId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}
)
#{runMode,jdbcType=VARCHAR}, #{poolId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
#{failure,jdbcType=BIT})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiExecutionQueue">
insert into api_execution_queue
@ -129,6 +130,9 @@
<if test="createTime != null">
create_time,
</if>
<if test="failure != null">
failure,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -149,6 +153,9 @@
<if test="createTime != null">
#{createTime,jdbcType=BIGINT},
</if>
<if test="failure != null">
#{failure,jdbcType=BIT},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.ApiExecutionQueueExample" resultType="java.lang.Long">
@ -178,6 +185,9 @@
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
<if test="record.failure != null">
failure = #{record.failure,jdbcType=BIT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -190,7 +200,8 @@
report_type = #{record.reportType,jdbcType=VARCHAR},
run_mode = #{record.runMode,jdbcType=VARCHAR},
pool_id = #{record.poolId,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT}
create_time = #{record.createTime,jdbcType=BIGINT},
failure = #{record.failure,jdbcType=BIT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -213,6 +224,9 @@
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
</if>
<if test="failure != null">
failure = #{failure,jdbcType=BIT},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -222,7 +236,8 @@
report_type = #{reportType,jdbcType=VARCHAR},
run_mode = #{runMode,jdbcType=VARCHAR},
pool_id = #{poolId,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT}
create_time = #{createTime,jdbcType=BIGINT},
failure = #{failure,jdbcType=BIT}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -32,4 +32,7 @@ public interface ExtApiDefinitionExecResultMapper {
List<ApiDefinitionExecResult> selectApiResultByProjectId(String projectId);
List<PlanReportCaseDTO> selectForPlanReport(@Param("ids") List<String> apiReportIds);
void update(@Param("ids") List<String> ids);
}

View File

@ -124,4 +124,10 @@
</foreach>
</select>
<update id="update" parameterType="java.util.List">
update api_definition_exec_result set status="STOP" where id in
<foreach collection="ids" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</update>
</mapper>

View File

@ -37,4 +37,6 @@ public interface ExtApiScenarioReportMapper {
List<ApiScenarioReport> selectReportByProjectId(String projectId);
List<PlanReportCaseDTO> selectForPlanReport(@Param("ids") List<String> reportIds);
void update(@Param("ids") List<String> ids);
}

View File

@ -252,18 +252,18 @@
SELECT id AS id,create_time AS createTime, scenario_id AS scenario_id FROM api_scenario_report
WHERE execute_type = 'Saved' AND scenario_id in
<foreach collection="scenarioIdList" item="value" separator="," open="(" close=")">
#{value}
</foreach>
#{value}
</foreach>
UNION
SELECT report.id AS id,report.create_time AS createTime,planScenario.api_scenario_id AS scenario_id FROM
api_scenario_report report
INNER JOIN test_plan_api_scenario planScenario ON report.scenario_id = planScenario.id
WHERE report.execute_type = 'Saved' AND planScenario.api_scenario_id in
<foreach collection="scenarioIdList" item="value" separator="," open="(" close=")">
#{value}
</foreach>
ORDER BY createTime DESC
) a GROUP BY a.scenario_id
#{value}
</foreach>
ORDER BY createTime DESC
) a GROUP BY a.scenario_id
) orderData ON orderData.id = report.id;
</select>
@ -309,4 +309,11 @@
#{value}
</foreach>
</select>
<update id="update" parameterType="java.util.List">
update api_scenario_report set status="STOP" where id in
<foreach collection="ids" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</update>
</mapper>

View File

@ -1,6 +1,7 @@
ALTER TABLE test_plan_report_content ADD plan_scenario_report_struct longtext NULL;
ALTER TABLE test_plan_report_content ADD plan_api_case_report_struct longtext NULL;
ALTER TABLE test_plan_report_content ADD plan_load_case_report_struct longtext NULL;
ALTER TABLE api_execution_queue ADD failure TINYINT(1);
CREATE INDEX api_scenario_report_result_report_id_IDX ON api_scenario_report_result (report_id);