diff --git a/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java b/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java index 8fb08517a9..d3d0e6c317 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java @@ -59,6 +59,7 @@ public class ApiExecutionQueueService { @Resource private ApiScenarioReportResultMapper apiScenarioReportResultMapper; + @Transactional(propagation = Propagation.REQUIRES_NEW) public DBTestQueue add(Object runObj, String poolId, String type, String reportId, String reportType, String runMode, RunModeConfigDTO config) { ApiExecutionQueue executionQueue = new ApiExecutionQueue(); diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueue.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueue.java new file mode 100644 index 0000000000..57b9cdbbc7 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueue.java @@ -0,0 +1,19 @@ +package io.metersphere.base.domain; + +import java.io.Serializable; +import lombok.Data; + +@Data +public class TestPlanExecutionQueue implements Serializable { + private String id; + + private String reportId; + + private String runMode; + + private Long createTime; + + private String testPlanId; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueueExample.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueueExample.java new file mode 100644 index 0000000000..e870bc43eb --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanExecutionQueueExample.java @@ -0,0 +1,540 @@ +package io.metersphere.base.domain; + +import java.util.ArrayList; +import java.util.List; + +public class TestPlanExecutionQueueExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public TestPlanExecutionQueueExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andIdIsNull() { + addCriterion("id is null"); + return (Criteria) this; + } + + public Criteria andIdIsNotNull() { + addCriterion("id is not null"); + return (Criteria) this; + } + + public Criteria andIdEqualTo(String value) { + addCriterion("id =", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotEqualTo(String value) { + addCriterion("id <>", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThan(String value) { + addCriterion("id >", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThanOrEqualTo(String value) { + addCriterion("id >=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThan(String value) { + addCriterion("id <", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThanOrEqualTo(String value) { + addCriterion("id <=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLike(String value) { + addCriterion("id like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotLike(String value) { + addCriterion("id not like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdIn(List values) { + addCriterion("id in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdNotIn(List values) { + addCriterion("id not in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdBetween(String value1, String value2) { + addCriterion("id between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andIdNotBetween(String value1, String value2) { + addCriterion("id not between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andReportIdIsNull() { + addCriterion("report_id is null"); + return (Criteria) this; + } + + public Criteria andReportIdIsNotNull() { + addCriterion("report_id is not null"); + return (Criteria) this; + } + + public Criteria andReportIdEqualTo(String value) { + addCriterion("report_id =", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdNotEqualTo(String value) { + addCriterion("report_id <>", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdGreaterThan(String value) { + addCriterion("report_id >", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdGreaterThanOrEqualTo(String value) { + addCriterion("report_id >=", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdLessThan(String value) { + addCriterion("report_id <", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdLessThanOrEqualTo(String value) { + addCriterion("report_id <=", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdLike(String value) { + addCriterion("report_id like", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdNotLike(String value) { + addCriterion("report_id not like", value, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdIn(List values) { + addCriterion("report_id in", values, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdNotIn(List values) { + addCriterion("report_id not in", values, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdBetween(String value1, String value2) { + addCriterion("report_id between", value1, value2, "reportId"); + return (Criteria) this; + } + + public Criteria andReportIdNotBetween(String value1, String value2) { + addCriterion("report_id not between", value1, value2, "reportId"); + return (Criteria) this; + } + + public Criteria andRunModeIsNull() { + addCriterion("run_mode is null"); + return (Criteria) this; + } + + public Criteria andRunModeIsNotNull() { + addCriterion("run_mode is not null"); + return (Criteria) this; + } + + public Criteria andRunModeEqualTo(String value) { + addCriterion("run_mode =", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeNotEqualTo(String value) { + addCriterion("run_mode <>", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeGreaterThan(String value) { + addCriterion("run_mode >", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeGreaterThanOrEqualTo(String value) { + addCriterion("run_mode >=", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeLessThan(String value) { + addCriterion("run_mode <", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeLessThanOrEqualTo(String value) { + addCriterion("run_mode <=", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeLike(String value) { + addCriterion("run_mode like", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeNotLike(String value) { + addCriterion("run_mode not like", value, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeIn(List values) { + addCriterion("run_mode in", values, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeNotIn(List values) { + addCriterion("run_mode not in", values, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeBetween(String value1, String value2) { + addCriterion("run_mode between", value1, value2, "runMode"); + return (Criteria) this; + } + + public Criteria andRunModeNotBetween(String value1, String value2) { + addCriterion("run_mode not between", value1, value2, "runMode"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNull() { + addCriterion("create_time is null"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNotNull() { + addCriterion("create_time is not null"); + return (Criteria) this; + } + + public Criteria andCreateTimeEqualTo(Long value) { + addCriterion("create_time =", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotEqualTo(Long value) { + addCriterion("create_time <>", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThan(Long value) { + addCriterion("create_time >", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) { + addCriterion("create_time >=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThan(Long value) { + addCriterion("create_time <", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThanOrEqualTo(Long value) { + addCriterion("create_time <=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeIn(List values) { + addCriterion("create_time in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotIn(List values) { + addCriterion("create_time not in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeBetween(Long value1, Long value2) { + addCriterion("create_time between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotBetween(Long value1, Long value2) { + addCriterion("create_time not between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andTestPlanIdIsNull() { + addCriterion("test_plan_id is null"); + return (Criteria) this; + } + + public Criteria andTestPlanIdIsNotNull() { + addCriterion("test_plan_id is not null"); + return (Criteria) this; + } + + public Criteria andTestPlanIdEqualTo(String value) { + addCriterion("test_plan_id =", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdNotEqualTo(String value) { + addCriterion("test_plan_id <>", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdGreaterThan(String value) { + addCriterion("test_plan_id >", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdGreaterThanOrEqualTo(String value) { + addCriterion("test_plan_id >=", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdLessThan(String value) { + addCriterion("test_plan_id <", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdLessThanOrEqualTo(String value) { + addCriterion("test_plan_id <=", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdLike(String value) { + addCriterion("test_plan_id like", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdNotLike(String value) { + addCriterion("test_plan_id not like", value, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdIn(List values) { + addCriterion("test_plan_id in", values, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdNotIn(List values) { + addCriterion("test_plan_id not in", values, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdBetween(String value1, String value2) { + addCriterion("test_plan_id between", value1, value2, "testPlanId"); + return (Criteria) this; + } + + public Criteria andTestPlanIdNotBetween(String value1, String value2) { + addCriterion("test_plan_id not between", value1, value2, "testPlanId"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanWithBLOBs.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanWithBLOBs.java index d0126eb81d..885c05d9db 100644 --- a/backend/src/main/java/io/metersphere/base/domain/TestPlanWithBLOBs.java +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanWithBLOBs.java @@ -15,5 +15,7 @@ public class TestPlanWithBLOBs extends TestPlan implements Serializable { private String reportConfig; + private String request; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.java b/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.java new file mode 100644 index 0000000000..f284cb627a --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.java @@ -0,0 +1,30 @@ +package io.metersphere.base.mapper; + +import io.metersphere.base.domain.TestPlanExecutionQueue; +import io.metersphere.base.domain.TestPlanExecutionQueueExample; +import java.util.List; +import org.apache.ibatis.annotations.Param; + +public interface TestPlanExecutionQueueMapper { + long countByExample(TestPlanExecutionQueueExample example); + + int deleteByExample(TestPlanExecutionQueueExample example); + + int deleteByPrimaryKey(String id); + + int insert(TestPlanExecutionQueue record); + + int insertSelective(TestPlanExecutionQueue record); + + List selectByExample(TestPlanExecutionQueueExample example); + + TestPlanExecutionQueue selectByPrimaryKey(String id); + + int updateByExampleSelective(@Param("record") TestPlanExecutionQueue record, @Param("example") TestPlanExecutionQueueExample example); + + int updateByExample(@Param("record") TestPlanExecutionQueue record, @Param("example") TestPlanExecutionQueueExample example); + + int updateByPrimaryKeySelective(TestPlanExecutionQueue record); + + int updateByPrimaryKey(TestPlanExecutionQueue record); +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.xml new file mode 100644 index 0000000000..66aff003a0 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanExecutionQueueMapper.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + id, report_id, run_mode, create_time, test_plan_id + + + + + delete from test_plan_execution_queue + where id = #{id,jdbcType=VARCHAR} + + + delete from test_plan_execution_queue + + + + + + insert into test_plan_execution_queue (id, report_id, run_mode, + create_time, test_plan_id) + values (#{id,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR}, #{runMode,jdbcType=VARCHAR}, + #{createTime,jdbcType=BIGINT}, #{testPlanId,jdbcType=VARCHAR}) + + + insert into test_plan_execution_queue + + + id, + + + report_id, + + + run_mode, + + + create_time, + + + test_plan_id, + + + + + #{id,jdbcType=VARCHAR}, + + + #{reportId,jdbcType=VARCHAR}, + + + #{runMode,jdbcType=VARCHAR}, + + + #{createTime,jdbcType=BIGINT}, + + + #{testPlanId,jdbcType=VARCHAR}, + + + + + + update test_plan_execution_queue + + + id = #{record.id,jdbcType=VARCHAR}, + + + report_id = #{record.reportId,jdbcType=VARCHAR}, + + + run_mode = #{record.runMode,jdbcType=VARCHAR}, + + + create_time = #{record.createTime,jdbcType=BIGINT}, + + + test_plan_id = #{record.testPlanId,jdbcType=VARCHAR}, + + + + + + + + update test_plan_execution_queue + set id = #{record.id,jdbcType=VARCHAR}, + report_id = #{record.reportId,jdbcType=VARCHAR}, + run_mode = #{record.runMode,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + test_plan_id = #{record.testPlanId,jdbcType=VARCHAR} + + + + + + update test_plan_execution_queue + + + report_id = #{reportId,jdbcType=VARCHAR}, + + + run_mode = #{runMode,jdbcType=VARCHAR}, + + + create_time = #{createTime,jdbcType=BIGINT}, + + + test_plan_id = #{testPlanId,jdbcType=VARCHAR}, + + + where id = #{id,jdbcType=VARCHAR} + + + update test_plan_execution_queue + set report_id = #{reportId,jdbcType=VARCHAR}, + run_mode = #{runMode,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + test_plan_id = #{testPlanId,jdbcType=VARCHAR} + where id = #{id,jdbcType=VARCHAR} + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestPlanMapper.xml index 80166f2507..fae46fd22e 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestPlanMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanMapper.xml @@ -27,6 +27,7 @@ + @@ -88,12 +89,12 @@ id, workspace_id, report_id, `name`, description, `status`, stage, test_case_match_rule, - executor_match_rule, create_time, update_time, planned_start_time, planned_end_time, - actual_start_time, actual_end_time, creator, project_id, execution_times, automatic_status_update, + executor_match_rule, create_time, update_time, planned_start_time, planned_end_time, + actual_start_time, actual_end_time, creator, project_id, execution_times, automatic_status_update, repeat_case - tags, report_summary, report_config + tags, report_summary, report_config, request @@ -384,6 +393,9 @@ report_config = #{record.reportConfig,jdbcType=LONGVARCHAR}, + + request = #{record.request,jdbcType=LONGVARCHAR}, + @@ -413,7 +425,8 @@ repeat_case = #{record.repeatCase,jdbcType=BIT}, tags = #{record.tags,jdbcType=LONGVARCHAR}, report_summary = #{record.reportSummary,jdbcType=LONGVARCHAR}, - report_config = #{record.reportConfig,jdbcType=LONGVARCHAR} + report_config = #{record.reportConfig,jdbcType=LONGVARCHAR}, + request = #{record.request,jdbcType=LONGVARCHAR} @@ -513,6 +526,9 @@ report_config = #{reportConfig,jdbcType=LONGVARCHAR}, + + request = #{request,jdbcType=LONGVARCHAR}, + where id = #{id,jdbcType=VARCHAR} @@ -539,7 +555,8 @@ repeat_case = #{repeatCase,jdbcType=BIT}, tags = #{tags,jdbcType=LONGVARCHAR}, report_summary = #{reportSummary,jdbcType=LONGVARCHAR}, - report_config = #{reportConfig,jdbcType=LONGVARCHAR} + report_config = #{reportConfig,jdbcType=LONGVARCHAR}, + request = #{request,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=VARCHAR} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.java new file mode 100644 index 0000000000..7a0251ebaf --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueMapper.java @@ -0,0 +1,12 @@ +package io.metersphere.base.mapper.ext; + +import io.metersphere.base.domain.TestPlanExecutionQueue; +import org.apache.ibatis.annotations.InsertProvider; + +import java.util.List; + +public interface ExtTestPlanExecutionQueueMapper { + + @InsertProvider(type = ExtTestPlanExecutionQueueProvider.class, method = "insertListSql") + void sqlInsert(List list); +} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueProvider.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueProvider.java new file mode 100644 index 0000000000..c7e2528caa --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanExecutionQueueProvider.java @@ -0,0 +1,30 @@ +package io.metersphere.base.mapper.ext; + +import io.metersphere.base.domain.TestPlanExecutionQueue; + +import java.util.List; + +public class ExtTestPlanExecutionQueueProvider { + public String insertListSql(List list) { + StringBuffer sqlList = new StringBuffer(); + sqlList.append("insert into test_plan_execution_queue (id,report_id, run_mode, create_time) values "); + for (int i = 0; i < list.size(); i++) { + TestPlanExecutionQueue result = list.get(i); + sqlList.append(" (") + .append("'") + .append(result.getId()) + .append("','") + .append(result.getReportId()) + .append("','") + .append(result.getRunMode()) + .append("','") + .append(result.getCreateTime()) + .append("'") + .append(")"); + if (i < list.size() - 1) { + sqlList.append(","); + } + } + return sqlList.toString(); + } +} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.java index 4ee4fb721f..8ad038f8b7 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.java @@ -1,7 +1,9 @@ package io.metersphere.base.mapper.ext; +import io.metersphere.base.domain.TestPlanReport; import io.metersphere.track.dto.TestPlanReportDTO; import io.metersphere.track.request.report.QueryTestPlanReportRequest; +import org.apache.ibatis.annotations.InsertProvider; import org.springframework.data.repository.query.Param; import java.util.List; diff --git a/backend/src/main/java/io/metersphere/job/sechedule/TestPlanTestJob.java b/backend/src/main/java/io/metersphere/job/sechedule/TestPlanTestJob.java index 589fbf9812..80151c7742 100644 --- a/backend/src/main/java/io/metersphere/job/sechedule/TestPlanTestJob.java +++ b/backend/src/main/java/io/metersphere/job/sechedule/TestPlanTestJob.java @@ -56,7 +56,7 @@ public class TestPlanTestJob extends MsScheduleJob { @Override public void run() { LogUtil.info("Start test_plan_scehdule. test_plan_id:" + runResourceId); - testPlanService.run(runResourceId, runProjectId, runUserId, ReportTriggerMode.SCHEDULE.name(),config); + testPlanService.run(runResourceId, runProjectId, runUserId, ReportTriggerMode.SCHEDULE.name(),null,config); } }); thread.start(); diff --git a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java index 0c17de4437..bf8c5125a0 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java @@ -7,12 +7,10 @@ import com.github.pagehelper.PageHelper; import io.metersphere.api.dto.datacount.request.ScheduleInfoRequest; import io.metersphere.api.service.ApiAutomationService; import io.metersphere.base.domain.*; -import io.metersphere.commons.constants.NoticeConstants; -import io.metersphere.commons.constants.OperLogConstants; -import io.metersphere.commons.constants.OperLogModule; -import io.metersphere.commons.constants.PermissionConstants; +import io.metersphere.commons.constants.*; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; +import io.metersphere.dto.MsExecResponseDTO; import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.notice.annotation.SendNotice; import io.metersphere.service.CheckPermissionService; @@ -194,7 +192,7 @@ public class TestPlanController { api.setOnSampleError(false); api.setReportType("iddReport"); String apiRunConfig = JSONObject.toJSONString(api); - return testPlanService.run(testplanRunRequest.getTestPlanId(), testplanRunRequest.getProjectId(), testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), apiRunConfig); + return testPlanService.run(testplanRunRequest.getTestPlanId(), testplanRunRequest.getProjectId(), testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(),null, apiRunConfig); } @PostMapping("/copy/{id}") @@ -223,6 +221,13 @@ public class TestPlanController { return testPlanService.runPlan(testplanRunRequest); } + @PostMapping(value = "/run/batch") + @MsAuditLog(module = OperLogModule.TRACK_TEST_PLAN, type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.ids)", msClass = TestPlanService.class) + public List runBatch(@RequestBody TestplanRunRequest request) { + request.setTriggerMode(TriggerMode.BATCH.name()); + return testPlanService.runBatch(request); + } + @GetMapping("/report/export/{planId}") public void exportHtmlReport(@PathVariable String planId, HttpServletResponse response) throws UnsupportedEncodingException { testPlanService.exportPlanReport(planId, response); @@ -299,4 +304,5 @@ public class TestPlanController { public ScheduleDTO updateTestPlanBySchedule(@RequestBody ScheduleInfoRequest request) { return testPlanService.updateTestPlanBySchedule(request); } + } diff --git a/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java b/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java index de53ee6e90..85ed386228 100644 --- a/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testplan/TestplanRunRequest.java @@ -1,8 +1,11 @@ package io.metersphere.track.request.testplan; +import io.metersphere.track.dto.TestPlanScheduleReportInfoDTO; import lombok.Getter; import lombok.Setter; + +import java.util.List; import java.util.Map; @Getter @@ -20,5 +23,8 @@ public class TestplanRunRequest { private Map envMap; private String environmentType; private String environmentGroupId; + private List testPlanIds; + private Boolean isAll; + private TestPlanScheduleReportInfoDTO planScheduleReportInfoDTO; } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java index e306a25e76..f29e257d2f 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java @@ -29,6 +29,7 @@ import io.metersphere.track.request.report.QueryTestPlanReportRequest; import io.metersphere.track.request.report.TestPlanReportSaveRequest; import io.metersphere.track.request.testcase.QueryTestPlanRequest; import io.metersphere.track.request.testplan.LoadCaseRequest; +import io.metersphere.track.request.testplan.TestplanRunRequest; import org.apache.commons.beanutils.BeanMap; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -37,8 +38,6 @@ import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -100,6 +99,8 @@ public class TestPlanReportService { private ApiDefinitionExecResultService apiDefinitionExecResultService; @Resource private ApiScenarioReportService apiScenarioReportService; + @Resource + private TestPlanExecutionQueueMapper testPlanExecutionQueueMapper; public List list(QueryTestPlanReportRequest request) { List list = new ArrayList<>(); @@ -218,7 +219,7 @@ public class TestPlanReportService { } } - public TestPlanScheduleReportInfoDTO genTestPlanReportBySchedule(String projectID, String planId, String userId, String triggerMode) { + public TestPlanScheduleReportInfoDTO genTestPlanReportBySchedule(String projectID, String planReportId, String planId, String userId, String triggerMode) { Map planScenarioIdMap = new LinkedHashMap<>(); Map planTestCaseIdMap = new LinkedHashMap<>(); Map performanceIdMap = new LinkedHashMap<>(); @@ -236,7 +237,7 @@ public class TestPlanReportService { for (TestPlanLoadCaseDTO dto : testPlanLoadCaseDTOList) { performanceIdMap.put(dto.getId(), dto.getLoadCaseId()); } - String planReportId = UUID.randomUUID().toString(); + Map apiCaseInfoMap = new HashMap<>(); for (String id : planTestCaseIdMap.keySet()) { @@ -250,10 +251,21 @@ public class TestPlanReportService { for (String id : performanceIdMap.values()) { performanceInfoMap.put(id, TestPlanApiExecuteStatus.PREPARE.name()); } + + if(StringUtils.isBlank(planReportId)){ + planReportId = UUID.randomUUID().toString(); + } + TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(planReportId, planId, userId, triggerMode, planTestCaseIdMap.size() > 0, planScenarioIdMap.size() > 0, performanceIdMap.size() > 0, apiCaseInfoMap, scenarioInfoMap, performanceInfoMap); - TestPlanScheduleReportInfoDTO returnDTO = this.genTestPlanReport(saveRequest); + TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO(); + TestPlanReport testPlanReport = this.getTestPlanReport(planReportId); + if(testPlanReport==null){ + returnDTO = this.genTestPlanReport(saveRequest); + }else{ + returnDTO.setTestPlanReport(testPlanReport); + } returnDTO.setPlanScenarioIdMap(planScenarioIdMap); returnDTO.setApiTestCaseDataMap(planTestCaseIdMap); returnDTO.setPerformanceIdMap(performanceIdMap); @@ -446,7 +458,6 @@ public class TestPlanReportService { testPlanReport.setUpdateTime(endTime); } - TestPlanReportContentExample contentExample = new TestPlanReportContentExample(); contentExample.createCriteria().andTestPlanReportIdEqualTo(testPlanReportId); List contents = testPlanReportContentMapper.selectByExampleWithBLOBs(contentExample); @@ -527,6 +538,26 @@ public class TestPlanReportService { testPlanReport.setIsScenarioExecuting(false); testPlanReport.setIsPerformanceExecuting(false); testPlanReport = this.update(testPlanReport); + TestPlanExecutionQueueExample testPlanExecutionQueueExample = new TestPlanExecutionQueueExample(); + testPlanExecutionQueueExample.createCriteria().andReportIdEqualTo(testPlanReportId); + List planExecutionQueues = testPlanExecutionQueueMapper.selectByExample(testPlanExecutionQueueExample); + String runMode=null; + if(planExecutionQueues!=null&&planExecutionQueues.size()>0){ + runMode = planExecutionQueues.get(0).getRunMode(); + testPlanExecutionQueueMapper.deleteByExample(testPlanExecutionQueueExample); + } + if(runMode!=null&&StringUtils.equalsIgnoreCase(runMode,"serial")){ + TestPlanExecutionQueueExample queueExample = new TestPlanExecutionQueueExample(); + queueExample.createCriteria().andReportIdIsNotNull(); + List planExecutionQueueList = testPlanExecutionQueueMapper.selectByExample(testPlanExecutionQueueExample); + TestPlanExecutionQueue testPlanExecutionQueue = planExecutionQueueList.get(0); + TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(testPlanExecutionQueue.getTestPlanId()); + JSONObject jsonObject = JSONObject.parseObject(testPlan.getRequest()); + TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject,TestplanRunRequest.class); + TestPlanScheduleReportInfoDTO testPlanScheduleReportInfoDTO = this.genTestPlanReportBySchedule(null, testPlanExecutionQueue.getReportId(), testPlanExecutionQueue.getTestPlanId(), runRequest.getUserId(), runRequest.getTriggerMode()); + runRequest.setPlanScheduleReportInfoDTO(testPlanScheduleReportInfoDTO); + testPlanService.runPlan(runRequest); + } } return testPlanReport; } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index f84b4a557c..014f7741c1 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -43,10 +43,7 @@ import io.metersphere.track.domain.ReportComponent; import io.metersphere.track.dto.*; import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest; import io.metersphere.track.request.testcase.QueryTestPlanRequest; -import io.metersphere.track.request.testplan.AddTestPlanRequest; -import io.metersphere.track.request.testplan.LoadCaseReportRequest; -import io.metersphere.track.request.testplan.LoadCaseRequest; -import io.metersphere.track.request.testplan.TestplanRunRequest; +import io.metersphere.track.request.testplan.*; import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest; import io.metersphere.utils.LoggerUtil; import org.apache.commons.beanutils.BeanMap; @@ -179,6 +176,11 @@ public class TestPlanService { private LoadTestMapper loadTestMapper; @Resource private ProjectService projectService; + @Resource + private ExtTestPlanExecutionQueueMapper extTestPlanExecutionQueueMapper; + + + public synchronized TestPlan addTestPlan(AddTestPlanRequest testPlan) { if (getTestPlanByName(testPlan.getName()).size() > 0) { @@ -1008,11 +1010,11 @@ public class TestPlanService { @Transactional(propagation = Propagation.NOT_SUPPORTED) TestPlanScheduleReportInfoDTO genTestPlanReport(String projectID, String planId, String userId, String triggerMode) { - TestPlanScheduleReportInfoDTO reportInfoDTO = testPlanReportService.genTestPlanReportBySchedule(projectID, planId, userId, triggerMode); + TestPlanScheduleReportInfoDTO reportInfoDTO = testPlanReportService.genTestPlanReportBySchedule(projectID,null, planId, userId, triggerMode); return reportInfoDTO; } - public String run(String testPlanID, String projectID, String userId, String triggerMode, String apiRunConfig) { + public String run(String testPlanID, String projectID, String userId, String triggerMode, TestPlanScheduleReportInfoDTO reportInfoDTO,String apiRunConfig) { RunModeConfigDTO runModeConfig = null; try { runModeConfig = JSONObject.parseObject(apiRunConfig, RunModeConfigDTO.class); @@ -1030,10 +1032,10 @@ public class TestPlanService { runModeConfig.setEnvMap(new HashMap<>()); } } - //创建测试报告,然后返回的ID重新赋值为resourceID,作为后续的参数 - TestPlanScheduleReportInfoDTO reportInfoDTO = this.genTestPlanReport(projectID, testPlanID, userId, triggerMode); - + if(reportInfoDTO==null){ + reportInfoDTO = this.genTestPlanReport(projectID, testPlanID, userId, triggerMode); + } //测试计划准备执行,取消测试计划的实际结束时间 extTestPlanMapper.updateActualEndTimeIsNullById(testPlanID); @@ -1913,12 +1915,13 @@ public class TestPlanService { String environmentGroupId = testplanRunRequest.getEnvironmentGroupId(); RunModeConfigDTO runModeConfig = new RunModeConfigDTO(); runModeConfig.setEnvironmentType(testplanRunRequest.getEnvironmentType()); + String testPlanId = testplanRunRequest.getTestPlanId(); if (StringUtils.equals(envType, EnvironmentType.JSON.name()) && !envMap.isEmpty()) { runModeConfig.setEnvMap(testplanRunRequest.getEnvMap()); - this.setPlanCaseEnv(testplanRunRequest.getTestPlanId(), runModeConfig); + this.setPlanCaseEnv(testPlanId, runModeConfig); } else if (StringUtils.equals(envType, EnvironmentType.GROUP.name()) && StringUtils.isNotBlank(environmentGroupId)) { runModeConfig.setEnvironmentGroupId(testplanRunRequest.getEnvironmentGroupId()); - this.setPlanCaseEnv(testplanRunRequest.getTestPlanId(), runModeConfig); + this.setPlanCaseEnv(testPlanId, runModeConfig); } runModeConfig.setMode(testplanRunRequest.getMode()); @@ -1930,8 +1933,18 @@ public class TestPlanService { runModeConfig.setReportType(testplanRunRequest.getReportType()); } String apiRunConfig = JSONObject.toJSONString(runModeConfig); - return this.run(testplanRunRequest.getTestPlanId(), testplanRunRequest.getProjectId(), - testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), apiRunConfig); + String request = JSON.toJSONString(testplanRunRequest); + TestPlanWithBLOBs testPlanWithBLOBs = testPlanMapper.selectByPrimaryKey(testPlanId); + testPlanWithBLOBs.setRequest(request); + testPlanMapper.updateByPrimaryKeyWithBLOBs(testPlanWithBLOBs); + if(testplanRunRequest.getPlanScheduleReportInfoDTO()!=null){ + return this.run(testPlanId, testplanRunRequest.getProjectId(), + testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(),testplanRunRequest.getPlanScheduleReportInfoDTO(), apiRunConfig); + }else{ + return this.run(testPlanId, testplanRunRequest.getProjectId(), + testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(),null, apiRunConfig); + } + } public void setPlanCaseEnv(String planId, RunModeConfigDTO runModeConfig) { @@ -2099,4 +2112,100 @@ public class TestPlanService { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); return extTestPlanMapper.list(request); } + + public List runBatch(TestplanRunRequest request) { + List ids = request.getTestPlanIds(); + if (CollectionUtils.isEmpty(ids)&&!request.getIsAll()) { + return new LinkedList<>(); + } + LoggerUtil.debug("开始查询测试计划"); + List planList = getTestPlanWithBLOBs(request, ids); + + Map testPlanMap = planList.stream().collect(Collectors.toMap(TestPlan::getId, a -> a,(k1,k2)->k1)); + Map executeQueue = new LinkedHashMap<>(); + List responseDTOS = new LinkedList<>(); + Map planScheduleReportInfoDTOMap = new LinkedHashMap<>(); + for (TestPlanWithBLOBs testPlan : planList) { + if(StringUtils.isBlank(testPlan.getRequest())){ + MSException.throwException("请保存["+testPlan.getName()+"]的运行配置"); + } + //创建测试报告,然后返回的ID重新赋值为resourceID,作为后续的参数 + TestPlanScheduleReportInfoDTO reportInfoDTO = this.genTestPlanReport(testPlan.getProjectId(), testPlan.getId(), request.getUserId(), request.getTriggerMode()); + + //测试计划准备执行,取消测试计划的实际结束时间 + extTestPlanMapper.updateActualEndTimeIsNullById(testPlan.getId()); + + String planReportId = reportInfoDTO.getTestPlanReport().getId(); + testPlanLog.info("ReportId[" + planReportId + "] created. TestPlanID:[" + testPlan.getId() + "] "); + + executeQueue.put(testPlan.getId(), reportInfoDTO.getTestPlanReport()); + responseDTOS.add(new MsExecResponseDTO(testPlan.getId(), reportInfoDTO.getTestPlanReport().getId(), request.getTriggerMode())); + planScheduleReportInfoDTOMap.put(testPlan.getId(),reportInfoDTO); + } + + LoggerUtil.debug("开始生成测试计划队列"); + + List planExecutionQueues = getTestPlanExecutionQueues(request, executeQueue); + + if (CollectionUtils.isNotEmpty(planExecutionQueues)) { + extTestPlanExecutionQueueMapper.sqlInsert(planExecutionQueues); + } + // 开始选择执行模式 + runByMode(request, testPlanMap, planScheduleReportInfoDTOMap, planExecutionQueues); + + return responseDTOS; + } + + private List getTestPlanExecutionQueues(TestplanRunRequest request, Map executeQueue) { + ListplanExecutionQueues = new ArrayList<>(); + executeQueue.forEach((k, v)->{ + TestPlanExecutionQueue executionQueue = new TestPlanExecutionQueue(); + executionQueue.setId(UUID.randomUUID().toString()); + executionQueue.setCreateTime(System.currentTimeMillis()); + executionQueue.setReportId(v.getId()); + executionQueue.setTestPlanId(k); + executionQueue.setRunMode(request.getMode()); + planExecutionQueues.add(executionQueue); + }); + return planExecutionQueues; + } + + private void runByMode(TestplanRunRequest request, Map testPlanMap, Map planScheduleReportInfoDTOMap, List planExecutionQueues) { + if (planExecutionQueues != null&& planExecutionQueues.size()>0) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + Thread.currentThread().setName("TEST_PLAN_BATCH:" + System.currentTimeMillis()); + if(StringUtils.equalsIgnoreCase(request.getMode(),"serial")){ + TestPlanExecutionQueue planExecutionQueue = planExecutionQueues.get(0); + TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); + JSONObject jsonObject = JSONObject.parseObject(testPlan.getRequest()); + TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject,TestplanRunRequest.class); + runRequest.setPlanScheduleReportInfoDTO(planScheduleReportInfoDTOMap.get(planExecutionQueue.getTestPlanId())); + runPlan(runRequest); + }else { + for (TestPlanExecutionQueue planExecutionQueue : planExecutionQueues) { + TestPlanWithBLOBs testPlan = testPlanMap.get(planExecutionQueue.getTestPlanId()); + JSONObject jsonObject = JSONObject.parseObject(testPlan.getRequest()); + TestplanRunRequest runRequest = JSON.toJavaObject(jsonObject,TestplanRunRequest.class); + runRequest.setPlanScheduleReportInfoDTO(planScheduleReportInfoDTOMap.get(planExecutionQueue.getTestPlanId())); + runPlan(runRequest); + } + } + } + }); + thread.start(); + } + } + + private List getTestPlanWithBLOBs(TestplanRunRequest request, List ids) { + TestPlanExample example = new TestPlanExample(); + if(CollectionUtils.isNotEmpty(ids)){ + example.createCriteria().andIdIn(ids); + } + example.createCriteria().andProjectIdEqualTo(request.getProjectId()); + List planList = testPlanMapper.selectByExampleWithBLOBs(example); + return planList; + } + } diff --git a/backend/src/main/resources/db/migration/V115__1.20__release.sql b/backend/src/main/resources/db/migration/V115__1.20__release.sql index d6ac2f04fa..ad69c8b6cc 100644 --- a/backend/src/main/resources/db/migration/V115__1.20__release.sql +++ b/backend/src/main/resources/db/migration/V115__1.20__release.sql @@ -123,6 +123,8 @@ END// DELIMITER ; CALL schema_change(); +ALTER TABLE `test_plan` ADD COLUMN `request` LONGTEXT COMMENT 'request (JSON format)'; + -- INSERT INTO user_group_permission (id, group_id, permission_id, module_id) VALUES (UUID(), 'project_admin', 'PROJECT_UI_SCENARIO:READ+DEBUG', 'PROJECT_UI_SCENARIO'); @@ -165,3 +167,16 @@ CREATE INDEX test_case_node_project_id_index CREATE INDEX test_case_node_id_index ON test_case(node_id); +CREATE TABLE IF NOT EXISTS `test_plan_execution_queue` +( + `id` varchar(50) NOT NULL COMMENT 'ID', + `report_id` varchar(100) COMMENT '测试计划报告', + `run_mode` varchar(100) COMMENT '执行模式/scenario/api/test_paln_api/test_pan_scenario', + create_time bigint(13) NULL COMMENT '创建时间', + `test_plan_id` varchar(100) COMMENT 'testPlanId', + PRIMARY KEY (`id`), + KEY `report_id_idx` (`report_id`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; + + + diff --git a/backend/src/main/resources/generatorConfig.xml b/backend/src/main/resources/generatorConfig.xml index b58b6d1975..544a85d454 100644 --- a/backend/src/main/resources/generatorConfig.xml +++ b/backend/src/main/resources/generatorConfig.xml @@ -86,7 +86,7 @@ - +