Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
5c8b5be24f
|
@ -18,6 +18,7 @@
|
||||||
tplc.test_plan_id,
|
tplc.test_plan_id,
|
||||||
tplc.load_case_id,
|
tplc.load_case_id,
|
||||||
lt.status,
|
lt.status,
|
||||||
|
tplc.status as caseStatus,
|
||||||
lt.name as caseName,
|
lt.name as caseName,
|
||||||
tplc.load_report_id,
|
tplc.load_report_id,
|
||||||
p.name as projectName
|
p.name as projectName
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class PerformanceNoticeTask {
|
||||||
if (StringUtils.equalsAny(loadTestReportFromDatabase.getStatus(),
|
if (StringUtils.equalsAny(loadTestReportFromDatabase.getStatus(),
|
||||||
PerformanceTestStatus.Completed.name(), PerformanceTestStatus.Error.name())) {
|
PerformanceTestStatus.Completed.name(), PerformanceTestStatus.Error.name())) {
|
||||||
sendNotice(loadTestReportFromDatabase);
|
sendNotice(loadTestReportFromDatabase);
|
||||||
isRunning = false;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
//查询定时任务是否关闭
|
//查询定时任务是否关闭
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.track.controller;
|
||||||
import com.github.pagehelper.Page;
|
import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.base.domain.LoadTest;
|
import io.metersphere.base.domain.LoadTest;
|
||||||
|
import io.metersphere.base.domain.TestPlanLoadCase;
|
||||||
import io.metersphere.commons.utils.PageUtils;
|
import io.metersphere.commons.utils.PageUtils;
|
||||||
import io.metersphere.commons.utils.Pager;
|
import io.metersphere.commons.utils.Pager;
|
||||||
import io.metersphere.track.dto.TestPlanLoadCaseDTO;
|
import io.metersphere.track.dto.TestPlanLoadCaseDTO;
|
||||||
|
@ -57,4 +58,9 @@ public class TestPlanLoadCaseController {
|
||||||
public void batchDelete(@RequestBody List<String> ids) {
|
public void batchDelete(@RequestBody List<String> ids) {
|
||||||
testPlanLoadCaseService.batchDelete(ids);
|
testPlanLoadCaseService.batchDelete(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/update")
|
||||||
|
public void update(@RequestBody TestPlanLoadCase testPlanLoadCase) {
|
||||||
|
testPlanLoadCaseService.update(testPlanLoadCase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,4 +10,5 @@ public class TestPlanLoadCaseDTO extends TestPlanLoadCase {
|
||||||
private String userName;
|
private String userName;
|
||||||
private String caseName;
|
private String caseName;
|
||||||
private String projectName;
|
private String projectName;
|
||||||
|
private String caseStatus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.TestPlanLoadCase;
|
||||||
|
import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||||
|
import io.metersphere.base.mapper.TestPlanLoadCaseMapper;
|
||||||
|
import io.metersphere.commons.constants.PerformanceTestStatus;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PreDestroy;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LoadReportStatusTask {
|
||||||
|
@Resource
|
||||||
|
private LoadTestReportMapper loadTestReportMapper;
|
||||||
|
@Resource
|
||||||
|
private TestPlanLoadCaseMapper testPlanLoadCaseMapper;
|
||||||
|
|
||||||
|
private final ExecutorService executorService = Executors.newFixedThreadPool(20);
|
||||||
|
|
||||||
|
private boolean isRunning = false;
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void preDestroy() {
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerReportIsEndTask(String id, String reportId) {
|
||||||
|
isRunning = true;
|
||||||
|
// todo 手动创建线程池
|
||||||
|
executorService.submit(() -> {
|
||||||
|
while (isRunning) {
|
||||||
|
LoadTestReportWithBLOBs report = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||||
|
if (StringUtils.equalsAny(report.getStatus(), PerformanceTestStatus.Completed.name(), PerformanceTestStatus.Error.name())) {
|
||||||
|
updateLoadCaseStatus(id, report.getStatus());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
//查询定时任务是否关闭
|
||||||
|
Thread.sleep(1000 * 10);// 检查 loadtest 的状态
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLoadCaseStatus(String testPlanLoadCaseId, String status) {
|
||||||
|
TestPlanLoadCase testPlanLoadCase = new TestPlanLoadCase();
|
||||||
|
testPlanLoadCase.setId(testPlanLoadCaseId);
|
||||||
|
String result = "";
|
||||||
|
if (StringUtils.equals(PerformanceTestStatus.Error.name(), status)) {
|
||||||
|
result = "error";
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(PerformanceTestStatus.Completed.name(), status)) {
|
||||||
|
result = "success";
|
||||||
|
}
|
||||||
|
testPlanLoadCase.setStatus(result);
|
||||||
|
testPlanLoadCaseMapper.updateByPrimaryKeySelective(testPlanLoadCase);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -39,6 +40,8 @@ public class TestPlanLoadCaseService {
|
||||||
private LoadTestReportMapper loadTestReportMapper;
|
private LoadTestReportMapper loadTestReportMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private LoadTestMapper loadTestMapper;
|
private LoadTestMapper loadTestMapper;
|
||||||
|
@Resource
|
||||||
|
private LoadReportStatusTask loadReportStatusTask;
|
||||||
|
|
||||||
public List<LoadTest> relevanceList(LoadCaseRequest request) {
|
public List<LoadTest> relevanceList(LoadCaseRequest request) {
|
||||||
List<String> ids = extTestPlanLoadCaseMapper.selectIdsNotInPlan(request.getProjectId(), request.getTestPlanId());
|
List<String> ids = extTestPlanLoadCaseMapper.selectIdsNotInPlan(request.getProjectId(), request.getTestPlanId());
|
||||||
|
@ -82,6 +85,7 @@ public class TestPlanLoadCaseService {
|
||||||
testPlanLoadCase.setId(request.getTestPlanLoadId());
|
testPlanLoadCase.setId(request.getTestPlanLoadId());
|
||||||
testPlanLoadCase.setLoadReportId(reportId);
|
testPlanLoadCase.setLoadReportId(reportId);
|
||||||
testPlanLoadCaseMapper.updateByPrimaryKeySelective(testPlanLoadCase);
|
testPlanLoadCaseMapper.updateByPrimaryKeySelective(testPlanLoadCase);
|
||||||
|
loadReportStatusTask.registerReportIsEndTask(request.getTestPlanLoadId(), reportId);
|
||||||
return reportId;
|
return reportId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,4 +126,10 @@ public class TestPlanLoadCaseService {
|
||||||
example.createCriteria().andIdIn(ids);
|
example.createCriteria().andIdIn(ids);
|
||||||
testPlanLoadCaseMapper.deleteByExample(example);
|
testPlanLoadCaseMapper.deleteByExample(example);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void update(TestPlanLoadCase testPlanLoadCase) {
|
||||||
|
if (!StringUtils.isEmpty(testPlanLoadCase.getId())) {
|
||||||
|
testPlanLoadCaseMapper.updateByPrimaryKeySelective(testPlanLoadCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<ms-table-operator-button :isTesterPermission="isTesterPermission" :tip="tip1" icon="el-icon-edit" @exec="editClick" @click.stop="editClickStop"/>
|
<ms-table-operator-button :isTesterPermission="isTesterPermission" :tip="tip1" icon="el-icon-edit" @exec="editClick" @click.stop="editClickStop"/>
|
||||||
<slot name="middle"></slot>
|
<slot name="middle"></slot>
|
||||||
<ms-table-operator-button :isTesterPermission="isTesterPermission" :tip="tip2" icon="el-icon-delete" type="danger" @exec="deleteClick" @click.stop="deleteClickStop"/>
|
<ms-table-operator-button :isTesterPermission="isTesterPermission" :tip="tip2" icon="el-icon-delete" type="danger" @exec="deleteClick" @click.stop="deleteClickStop"/>
|
||||||
<slot name="beheind"></slot>
|
<slot name="behind"></slot>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -65,6 +65,19 @@
|
||||||
<ms-performance-test-status :row="row"/>
|
<ms-performance-test-status :row="row"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="caseStatus"
|
||||||
|
label="执行状态">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<el-tag size="mini" type="danger" v-if="row.caseStatus === 'error'">
|
||||||
|
{{ row.caseStatus }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="success" v-else-if="row.caseStatus === 'success'">
|
||||||
|
{{ row.caseStatus }}
|
||||||
|
</el-tag>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="报告"
|
label="报告"
|
||||||
show-overflow-tooltip>
|
show-overflow-tooltip>
|
||||||
|
@ -187,6 +200,7 @@ export default {
|
||||||
if (arr.length > 0) {
|
if (arr.length > 0) {
|
||||||
this.initTable();
|
this.initTable();
|
||||||
} else {
|
} else {
|
||||||
|
setTimeout(this.initTable, 3000);
|
||||||
clearInterval(this.refreshScheduler);
|
clearInterval(this.refreshScheduler);
|
||||||
}
|
}
|
||||||
}, 4000);
|
}, 4000);
|
||||||
|
@ -233,10 +247,15 @@ export default {
|
||||||
},
|
},
|
||||||
handleRunBatch() {
|
handleRunBatch() {
|
||||||
this.selectRows.forEach(loadCase => {
|
this.selectRows.forEach(loadCase => {
|
||||||
this.run(loadCase);
|
this._run(loadCase);
|
||||||
})
|
})
|
||||||
|
this.refreshStatus();
|
||||||
},
|
},
|
||||||
run(loadCase) {
|
run(loadCase) {
|
||||||
|
this._run(loadCase);
|
||||||
|
this.refreshStatus();
|
||||||
|
},
|
||||||
|
_run(loadCase) {
|
||||||
this.$post('/test/plan/load/case/run', {
|
this.$post('/test/plan/load/case/run', {
|
||||||
id: loadCase.loadCaseId,
|
id: loadCase.loadCaseId,
|
||||||
testPlanLoadId: loadCase.id,
|
testPlanLoadId: loadCase.id,
|
||||||
|
@ -249,12 +268,15 @@ export default {
|
||||||
});
|
});
|
||||||
this.initTable();
|
this.initTable();
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
//todo 用例出错
|
||||||
|
this.$post('/test/plan/load/case/update', {id: loadCase.id, status: "error"},() => {
|
||||||
|
this.initTable();
|
||||||
|
});
|
||||||
this.$notify.error({
|
this.$notify.error({
|
||||||
title: loadCase.caseName,
|
title: loadCase.caseName,
|
||||||
message: '用例执行错误,请单独调试该用例!'
|
message: '用例执行错误,请单独调试该用例!'
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
this.refreshStatus();
|
|
||||||
},
|
},
|
||||||
handleDelete(loadCase) {
|
handleDelete(loadCase) {
|
||||||
this.result = this.$get('/test/plan/load/case/delete/' + loadCase.id, () => {
|
this.result = this.$get('/test/plan/load/case/delete/' + loadCase.id, () => {
|
||||||
|
|
Loading…
Reference in New Issue